Updated to 2.049

This commit is contained in:
Alexey Prokhin
2010-09-30 21:54:45 +04:00
parent 93ddf8112b
commit df87607ba2
113 changed files with 81689 additions and 74271 deletions

View File

@@ -10,11 +10,14 @@ syntax: glob
*.so
*.swp
*.rej
*~
Makefile
CMakeFiles
CMakeCache.txt
cmake_install.cmake
.DS_Store
CMakeLists.txt.user
.directory
syntax: regexp
^obj/

View File

@@ -1,425 +1,425 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "root.h"
#include "rmem.h"
#include "enum.h"
#include "aggregate.h"
#include "init.h"
#include "attrib.h"
#include "scope.h"
#include "id.h"
#include "mtype.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "module.h"
#define LOG 0
/* Code to do access checks
*/
int hasPackageAccess(Scope *sc, Dsymbol *s);
/****************************************
* Return PROT access for Dsymbol smember in this declaration.
*/
enum PROT AggregateDeclaration::getAccess(Dsymbol *smember)
{
return PROTpublic;
}
enum PROT StructDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+StructDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
return access_ret;
}
enum PROT ClassDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else
{
enum PROT access;
int i;
if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
for (i = 0; i < baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)baseclasses.data[i];
access = b->base->getAccess(smember);
switch (access)
{
case PROTnone:
break;
case PROTprivate:
access = PROTnone; // private members of base class not accessible
break;
case PROTpackage:
case PROTprotected:
case PROTpublic:
case PROTexport:
// If access is to be tightened
if (b->protection < access)
access = b->protection;
// Pick path with loosest access
if (access > access_ret)
access_ret = access;
break;
default:
assert(0);
}
}
}
#if LOG
printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n",
toChars(), smember->toChars(), access_ret);
#endif
return access_ret;
}
/********************************************************
* Helper function for ClassDeclaration::accessCheck()
* Returns:
* 0 no access
* 1 access
*/
static int accessCheckX(
Dsymbol *smember,
Dsymbol *sfunc,
AggregateDeclaration *dthis,
AggregateDeclaration *cdscope)
{
assert(dthis);
#if 0
printf("accessCheckX for %s.%s in function %s() in scope %s\n",
dthis->toChars(), smember->toChars(),
sfunc ? sfunc->toChars() : "NULL",
cdscope ? cdscope->toChars() : "NULL");
#endif
if (dthis->hasPrivateAccess(sfunc) ||
dthis->isFriendOf(cdscope))
{
if (smember->toParent() == dthis)
return 1;
else
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
enum PROT access;
access = b->base->getAccess(smember);
if (access >= PROTprotected ||
accessCheckX(smember, sfunc, b->base, cdscope)
)
return 1;
}
}
}
}
else
{
if (smember->toParent() != dthis)
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
if (accessCheckX(smember, sfunc, b->base, cdscope))
return 1;
}
}
}
}
return 0;
}
/*******************************
* Do access check for member of this class, this class being the
* type of the 'this' pointer used to access smember.
*/
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember)
{
int result;
FuncDeclaration *f = sc->func;
AggregateDeclaration *cdscope = sc->getStructClassScope();
enum PROT access;
#if LOG
printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n",
toChars(), smember->toChars(),
f ? f->toChars() : NULL,
cdscope ? cdscope->toChars() : NULL);
#endif
Dsymbol *smemberparent = smember->toParent();
if (!smemberparent || !smemberparent->isAggregateDeclaration())
{
#if LOG
printf("not an aggregate member\n");
#endif
return; // then it is accessible
}
// BUG: should enable this check
//assert(smember->parent->isBaseOf(this, NULL));
if (smemberparent == this)
{ enum PROT access = smember->prot();
result = access >= PROTpublic ||
hasPrivateAccess(f) ||
isFriendOf(cdscope) ||
(access == PROTpackage && hasPackageAccess(sc, this));
#if LOG
printf("result1 = %d\n", result);
#endif
}
else if ((access = this->getAccess(smember)) >= PROTpublic)
{
result = 1;
#if LOG
printf("result2 = %d\n", result);
#endif
}
else if (access == PROTpackage && hasPackageAccess(sc, this))
{
result = 1;
#if LOG
printf("result3 = %d\n", result);
#endif
}
else
{
result = accessCheckX(smember, f, this, cdscope);
#if LOG
printf("result4 = %d\n", result);
#endif
}
if (!result)
{
error(loc, "member %s is not accessible", smember->toChars());
halt();
}
}
/****************************************
* Determine if this is the same or friend of cd.
*/
int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd)
{
#if LOG
printf("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd->toChars() : "null");
#endif
if (this == cd)
return 1;
// Friends if both are in the same module
//if (toParent() == cd->toParent())
if (cd && getModule() == cd->getModule())
{
#if LOG
printf("\tin same module\n");
#endif
return 1;
}
#if LOG
printf("\tnot friend\n");
#endif
return 0;
}
/****************************************
* Determine if scope sc has package level access to s.
*/
int hasPackageAccess(Scope *sc, Dsymbol *s)
{
#if LOG
printf("hasPackageAccess(s = '%s', sc = '%p')\n", s->toChars(), sc);
#endif
for (; s; s = s->parent)
{
if (s->isPackage() && !s->isModule())
break;
}
#if LOG
if (s)
printf("\tthis is in package '%s'\n", s->toChars());
#endif
if (s && s == sc->module->parent)
{
#if LOG
printf("\ts is in same package as sc\n");
#endif
return 1;
}
#if LOG
printf("\tno package access\n");
#endif
return 0;
}
/**********************************
* Determine if smember has access to private members of this declaration.
*/
int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember)
{
if (smember)
{ AggregateDeclaration *cd = NULL;
Dsymbol *smemberparent = smember->toParent();
if (smemberparent)
cd = smemberparent->isAggregateDeclaration();
#if LOG
printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n",
toChars(), smember->toChars());
#endif
if (this == cd) // smember is a member of this class
{
#if LOG
printf("\tyes 1\n");
#endif
return 1; // so we get private access
}
// If both are members of the same module, grant access
while (1)
{ Dsymbol *sp = smember->toParent();
if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
smember = sp;
else
break;
}
if (!cd && toParent() == smember->toParent())
{
#if LOG
printf("\tyes 2\n");
#endif
return 1;
}
if (!cd && getModule() == smember->getModule())
{
#if LOG
printf("\tyes 3\n");
#endif
return 1;
}
}
#if LOG
printf("\tno\n");
#endif
return 0;
}
/****************************************
* Check access to d for expression e.d
*/
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
{
#if LOG
if (e)
{ printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars());
printf("\te->type = %s\n", e->type->toChars());
}
else
{
//printf("accessCheck(%s)\n", d->toChars());
}
#endif
if (!e)
{
if (d->getModule() != sc->module)
if (d->prot() == PROTprivate ||
d->prot() == PROTpackage && !hasPackageAccess(sc, d))
error(loc, "%s %s.%s is not accessible from %s",
d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars());
}
else if (e->type->ty == Tclass)
{ // Do access check
ClassDeclaration *cd;
cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
#if 1
if (e->op == TOKsuper)
{ ClassDeclaration *cd2;
cd2 = sc->func->toParent()->isClassDeclaration();
if (cd2)
cd = cd2;
}
#endif
cd->accessCheck(loc, sc, d);
}
else if (e->type->ty == Tstruct)
{ // Do access check
StructDeclaration *cd;
cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
cd->accessCheck(loc, sc, d);
}
}
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "root.h"
#include "rmem.h"
#include "enum.h"
#include "aggregate.h"
#include "init.h"
#include "attrib.h"
#include "scope.h"
#include "id.h"
#include "mtype.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "module.h"
#define LOG 0
/* Code to do access checks
*/
int hasPackageAccess(Scope *sc, Dsymbol *s);
/****************************************
* Return PROT access for Dsymbol smember in this declaration.
*/
enum PROT AggregateDeclaration::getAccess(Dsymbol *smember)
{
return PROTpublic;
}
enum PROT StructDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+StructDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
return access_ret;
}
enum PROT ClassDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else
{
enum PROT access;
int i;
if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
for (i = 0; i < baseclasses->dim; i++)
{ BaseClass *b = (BaseClass *)baseclasses->data[i];
access = b->base->getAccess(smember);
switch (access)
{
case PROTnone:
break;
case PROTprivate:
access = PROTnone; // private members of base class not accessible
break;
case PROTpackage:
case PROTprotected:
case PROTpublic:
case PROTexport:
// If access is to be tightened
if (b->protection < access)
access = b->protection;
// Pick path with loosest access
if (access > access_ret)
access_ret = access;
break;
default:
assert(0);
}
}
}
#if LOG
printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n",
toChars(), smember->toChars(), access_ret);
#endif
return access_ret;
}
/********************************************************
* Helper function for ClassDeclaration::accessCheck()
* Returns:
* 0 no access
* 1 access
*/
static int accessCheckX(
Dsymbol *smember,
Dsymbol *sfunc,
AggregateDeclaration *dthis,
AggregateDeclaration *cdscope)
{
assert(dthis);
#if 0
printf("accessCheckX for %s.%s in function %s() in scope %s\n",
dthis->toChars(), smember->toChars(),
sfunc ? sfunc->toChars() : "NULL",
cdscope ? cdscope->toChars() : "NULL");
#endif
if (dthis->hasPrivateAccess(sfunc) ||
dthis->isFriendOf(cdscope))
{
if (smember->toParent() == dthis)
return 1;
else
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses->dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses->data[i];
enum PROT access;
access = b->base->getAccess(smember);
if (access >= PROTprotected ||
accessCheckX(smember, sfunc, b->base, cdscope)
)
return 1;
}
}
}
}
else
{
if (smember->toParent() != dthis)
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses->dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses->data[i];
if (accessCheckX(smember, sfunc, b->base, cdscope))
return 1;
}
}
}
}
return 0;
}
/*******************************
* Do access check for member of this class, this class being the
* type of the 'this' pointer used to access smember.
*/
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember)
{
int result;
FuncDeclaration *f = sc->func;
AggregateDeclaration *cdscope = sc->getStructClassScope();
enum PROT access;
#if LOG
printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n",
toChars(), smember->toChars(),
f ? f->toChars() : NULL,
cdscope ? cdscope->toChars() : NULL);
#endif
Dsymbol *smemberparent = smember->toParent();
if (!smemberparent || !smemberparent->isAggregateDeclaration())
{
#if LOG
printf("not an aggregate member\n");
#endif
return; // then it is accessible
}
// BUG: should enable this check
//assert(smember->parent->isBaseOf(this, NULL));
if (smemberparent == this)
{ enum PROT access = smember->prot();
result = access >= PROTpublic ||
hasPrivateAccess(f) ||
isFriendOf(cdscope) ||
(access == PROTpackage && hasPackageAccess(sc, this));
#if LOG
printf("result1 = %d\n", result);
#endif
}
else if ((access = this->getAccess(smember)) >= PROTpublic)
{
result = 1;
#if LOG
printf("result2 = %d\n", result);
#endif
}
else if (access == PROTpackage && hasPackageAccess(sc, this))
{
result = 1;
#if LOG
printf("result3 = %d\n", result);
#endif
}
else
{
result = accessCheckX(smember, f, this, cdscope);
#if LOG
printf("result4 = %d\n", result);
#endif
}
if (!result)
{
error(loc, "member %s is not accessible", smember->toChars());
halt();
}
}
/****************************************
* Determine if this is the same or friend of cd.
*/
int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd)
{
#if LOG
printf("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd->toChars() : "null");
#endif
if (this == cd)
return 1;
// Friends if both are in the same module
//if (toParent() == cd->toParent())
if (cd && getModule() == cd->getModule())
{
#if LOG
printf("\tin same module\n");
#endif
return 1;
}
#if LOG
printf("\tnot friend\n");
#endif
return 0;
}
/****************************************
* Determine if scope sc has package level access to s.
*/
int hasPackageAccess(Scope *sc, Dsymbol *s)
{
#if LOG
printf("hasPackageAccess(s = '%s', sc = '%p')\n", s->toChars(), sc);
#endif
for (; s; s = s->parent)
{
if (s->isPackage() && !s->isModule())
break;
}
#if LOG
if (s)
printf("\tthis is in package '%s'\n", s->toChars());
#endif
if (s && s == sc->module->parent)
{
#if LOG
printf("\ts is in same package as sc\n");
#endif
return 1;
}
#if LOG
printf("\tno package access\n");
#endif
return 0;
}
/**********************************
* Determine if smember has access to private members of this declaration.
*/
int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember)
{
if (smember)
{ AggregateDeclaration *cd = NULL;
Dsymbol *smemberparent = smember->toParent();
if (smemberparent)
cd = smemberparent->isAggregateDeclaration();
#if LOG
printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n",
toChars(), smember->toChars());
#endif
if (this == cd) // smember is a member of this class
{
#if LOG
printf("\tyes 1\n");
#endif
return 1; // so we get private access
}
// If both are members of the same module, grant access
while (1)
{ Dsymbol *sp = smember->toParent();
if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
smember = sp;
else
break;
}
if (!cd && toParent() == smember->toParent())
{
#if LOG
printf("\tyes 2\n");
#endif
return 1;
}
if (!cd && getModule() == smember->getModule())
{
#if LOG
printf("\tyes 3\n");
#endif
return 1;
}
}
#if LOG
printf("\tno\n");
#endif
return 0;
}
/****************************************
* Check access to d for expression e.d
*/
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
{
#if LOG
if (e)
{ printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars());
printf("\te->type = %s\n", e->type->toChars());
}
else
{
//printf("accessCheck(%s)\n", d->toChars());
}
#endif
if (!e)
{
if (d->getModule() != sc->module)
if (d->prot() == PROTprivate ||
d->prot() == PROTpackage && !hasPackageAccess(sc, d))
error(loc, "%s %s.%s is not accessible from %s",
d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars());
}
else if (e->type->ty == Tclass)
{ // Do access check
ClassDeclaration *cd;
cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
#if 1
if (e->op == TOKsuper)
{ ClassDeclaration *cd2;
cd2 = sc->func->toParent()->isClassDeclaration();
if (cd2)
cd = cd2;
}
#endif
cd->accessCheck(loc, sc, d);
}
else if (e->type->ty == Tstruct)
{ // Do access check
StructDeclaration *cd;
cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
cd->accessCheck(loc, sc, d);
}
}

View File

@@ -1,325 +1,350 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_AGGREGATE_H
#define DMD_AGGREGATE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
#if IN_LLVM
#include <vector>
#include <set>
#include <map>
#endif
struct Identifier;
struct Type;
struct TypeFunction;
struct Expression;
struct FuncDeclaration;
struct CtorDeclaration;
struct DtorDeclaration;
struct InvariantDeclaration;
struct NewDeclaration;
struct DeleteDeclaration;
struct InterfaceDeclaration;
struct ClassInfoDeclaration;
struct VarDeclaration;
struct dt_t;
#if IN_LLVM
namespace llvm
{
class Type;
class Value;
class Constant;
class ConstantStruct;
class GlobalVariable;
}
#endif
struct AggregateDeclaration : ScopeDsymbol
{
Type *type;
unsigned storage_class;
enum PROT protection;
Type *handle; // 'this' type
unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes
unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields
Array fields; // VarDeclaration fields
unsigned sizeok; // set when structsize contains valid data
// 0: no size
// 1: size is correct
// 2: cannot determine size; fwd referenced
int isdeprecated; // !=0 if deprecated
Scope *scope; // !=NULL means context to use
int isnested; // !=0 if is nested
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
// Special member functions
InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
DeleteDeclaration *aggDelete; // deallocator
#if DMDV2
//CtorDeclaration *ctor;
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
CtorDeclaration *defaultCtor; // default constructor
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
#endif
FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor
#ifdef IN_GCC
Array methods; // flat list of all methods for debug information
#endif
AggregateDeclaration(Loc loc, Identifier *id);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
unsigned size(Loc loc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
Type *getType();
void addField(Scope *sc, VarDeclaration *v);
int isDeprecated(); // is aggregate deprecated?
FuncDeclaration *buildDtor(Scope *sc);
int isNested();
void emitComment(Scope *sc);
void toDocBuffer(OutBuffer *buf);
// For access checking
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
int isFriendOf(AggregateDeclaration *cd);
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
enum PROT prot();
#if IN_DMD
// Back end
Symbol *stag; // tag symbol for debug data
Symbol *sinit;
Symbol *toInitializer();
#endif
AggregateDeclaration *isAggregateDeclaration() { return this; }
#if IN_LLVM
// Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
bool availableExternally;
#endif
};
struct AnonymousAggregateDeclaration : AggregateDeclaration
{
AnonymousAggregateDeclaration()
: AggregateDeclaration(0, NULL)
{
}
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
};
struct StructDeclaration : AggregateDeclaration
{
int zeroInit; // !=0 if initialize with 0 fill
#if DMDV2
int hasIdentityAssign; // !=0 if has identity opAssign
FuncDeclaration *cpctor; // generated copy-constructor, if any
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit
#endif
StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
int needOpAssign();
FuncDeclaration *buildOpAssign(Scope *sc);
FuncDeclaration *buildPostBlit(Scope *sc);
FuncDeclaration *buildCpCtor(Scope *sc);
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
void toDt(dt_t **pdt);
void toDebug(); // to symbolic debug info
#endif
StructDeclaration *isStructDeclaration() { return this; }
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct UnionDeclaration : StructDeclaration
{
UnionDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
const char *kind();
UnionDeclaration *isUnionDeclaration() { return this; }
};
// warning: two classes with the same base class share the same
// BaseClass instance.
struct BaseClass
{
Type *type; // (before semantic processing)
enum PROT protection; // protection for the base interface
ClassDeclaration *base;
int offset; // 'this' pointer offset
Array vtbl; // for interfaces: Array of FuncDeclaration's
// making up the vtbl[]
int baseInterfaces_dim;
BaseClass *baseInterfaces; // if BaseClass is an interface, these
// are a copy of the InterfaceDeclaration::interfaces
BaseClass();
BaseClass(Type *type, enum PROT protection);
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
void copyBaseInterfaces(BaseClasses *);
};
#if DMDV2
#define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#endif
struct ClassDeclaration : AggregateDeclaration
{
static ClassDeclaration *object;
static ClassDeclaration *classinfo;
ClassDeclaration *baseClass; // NULL only if this is Object
FuncDeclaration *staticCtor;
FuncDeclaration *staticDtor;
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
BaseClasses baseclasses; // Array of BaseClass's; first is super,
// rest are Interface's
int interfaces_dim;
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
// (does not include baseClass)
BaseClasses *vtblInterfaces; // array of base interfaces that have
// their own vtbl[]
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
int com; // !=0 if this is a COM class (meaning
// it derives from IUnknown)
int isauto; // !=0 if this is an auto class
int isabstract; // !=0 if abstract class
int inuse; // to prevent recursive attempts
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
Dsymbol *search(Loc, Identifier *ident, int flags);
#if DMDV2
int isFuncHidden(FuncDeclaration *fd);
#endif
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
int isCOMclass();
virtual int isCOMinterface();
#if DMDV2
virtual int isCPPinterface();
#endif
int isAbstract();
virtual int vtblOffset();
const char *kind();
char *mangle();
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
void addLocalClass(ClassDeclarations *);
#if IN_DMD
// Back end
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
unsigned baseVtblOffset(BaseClass *bc);
Symbol *toSymbol();
Symbol *toVtblSymbol();
void toDt(dt_t **pdt);
void toDt2(dt_t **pdt, ClassDeclaration *cd);
Symbol *vtblsym;
#endif
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
#if IN_LLVM
virtual void codegen(Ir*);
#endif
};
struct InterfaceDeclaration : ClassDeclaration
{
#if DMDV2
int cpp; // !=0 if this is a C++ interface
#endif
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
int isBaseOf(ClassDeclaration *cd, int *poffset);
int isBaseOf(BaseClass *bc, int *poffset);
const char *kind();
int vtblOffset();
#if DMDV2
int isCPPinterface();
#endif
virtual int isCOMinterface();
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
Symbol *toSymbol();
#endif
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
#if IN_LLVM
void codegen(Ir*);
#endif
};
#endif /* DMD_AGGREGATE_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_AGGREGATE_H
#define DMD_AGGREGATE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
#if IN_LLVM
#include <vector>
#include <set>
#include <map>
#endif
struct Identifier;
struct Type;
struct TypeFunction;
struct Expression;
struct FuncDeclaration;
struct CtorDeclaration;
struct DtorDeclaration;
struct InvariantDeclaration;
struct NewDeclaration;
struct DeleteDeclaration;
struct InterfaceDeclaration;
struct TypeInfoClassDeclaration;
struct VarDeclaration;
struct dt_t;
#if IN_LLVM
namespace llvm
{
class Type;
class Value;
class Constant;
class ConstantStruct;
class GlobalVariable;
}
#endif
struct AggregateDeclaration : ScopeDsymbol
{
Type *type;
StorageClass storage_class;
enum PROT protection;
Type *handle; // 'this' type
unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes
unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields
Array fields; // VarDeclaration fields
unsigned sizeok; // set when structsize contains valid data
// 0: no size
// 1: size is correct
// 2: cannot determine size; fwd referenced
int isdeprecated; // !=0 if deprecated
Scope *scope; // !=NULL means context to use
#if DMDV2
int isnested; // !=0 if is nested
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
#endif
// Special member functions
InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
DeleteDeclaration *aggDelete; // deallocator
#if DMDV2
//CtorDeclaration *ctor;
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
CtorDeclaration *defaultCtor; // default constructor
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
#endif
FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor
#ifdef IN_GCC
Array methods; // flat list of all methods for debug information
#endif
AggregateDeclaration(Loc loc, Identifier *id);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
unsigned size(Loc loc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
Type *getType();
void addField(Scope *sc, VarDeclaration *v);
int isDeprecated(); // is aggregate deprecated?
FuncDeclaration *buildDtor(Scope *sc);
int isNested();
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
void toDocBuffer(OutBuffer *buf);
// For access checking
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
int isFriendOf(AggregateDeclaration *cd);
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
enum PROT prot();
#if IN_DMD
// Back end
Symbol *stag; // tag symbol for debug data
Symbol *sinit;
Symbol *toInitializer();
#endif
AggregateDeclaration *isAggregateDeclaration() { return this; }
#if IN_LLVM
// Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
bool availableExternally;
#endif
};
struct AnonymousAggregateDeclaration : AggregateDeclaration
{
AnonymousAggregateDeclaration()
: AggregateDeclaration(0, NULL)
{
}
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
};
struct StructDeclaration : AggregateDeclaration
{
int zeroInit; // !=0 if initialize with 0 fill
#if DMDV2
int hasIdentityAssign; // !=0 if has identity opAssign
FuncDeclaration *cpctor; // generated copy-constructor, if any
FuncDeclaration *eq; // bool opEquals(ref const T), if any
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit
#endif
StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
Dsymbol *search(Loc, Identifier *ident, int flags);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
#if DMDV1
Expression *cloneMembers();
#endif
#if DMDV2
int needOpAssign();
int needOpEquals();
FuncDeclaration *buildOpAssign(Scope *sc);
FuncDeclaration *buildOpEquals(Scope *sc);
FuncDeclaration *buildPostBlit(Scope *sc);
FuncDeclaration *buildCpCtor(Scope *sc);
#endif
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
void toDt(dt_t **pdt);
void toDebug(); // to symbolic debug info
#endif
StructDeclaration *isStructDeclaration() { return this; }
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct UnionDeclaration : StructDeclaration
{
UnionDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
const char *kind();
UnionDeclaration *isUnionDeclaration() { return this; }
};
// warning: two classes with the same base class share the same
// BaseClass instance.
struct BaseClass
{
Type *type; // (before semantic processing)
enum PROT protection; // protection for the base interface
ClassDeclaration *base;
int offset; // 'this' pointer offset
Array vtbl; // for interfaces: Array of FuncDeclaration's
// making up the vtbl[]
int baseInterfaces_dim;
BaseClass *baseInterfaces; // if BaseClass is an interface, these
// are a copy of the InterfaceDeclaration::interfaces
BaseClass();
BaseClass(Type *type, enum PROT protection);
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
void copyBaseInterfaces(BaseClasses *);
};
#if DMDV2
#define CLASSINFO_SIZE_64 0x98 // value of ClassInfo.size
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#endif
struct ClassDeclaration : AggregateDeclaration
{
static ClassDeclaration *object;
static ClassDeclaration *classinfo;
ClassDeclaration *baseClass; // NULL only if this is Object
#if DMDV1
CtorDeclaration *ctor;
CtorDeclaration *defaultCtor; // default constructor
#endif
FuncDeclaration *staticCtor;
FuncDeclaration *staticDtor;
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
BaseClasses *baseclasses; // Array of BaseClass's; first is super,
// rest are Interface's
int interfaces_dim;
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
// (does not include baseClass)
BaseClasses *vtblInterfaces; // array of base interfaces that have
// their own vtbl[]
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
int com; // !=0 if this is a COM class (meaning
// it derives from IUnknown)
int isscope; // !=0 if this is an auto class
int isabstract; // !=0 if abstract class
#if DMDV1
int isnested; // !=0 if is nested
VarDeclaration *vthis; // 'this' parameter if this class is nested
#endif
int inuse; // to prevent recursive attempts
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
virtual int isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags);
#if DMDV2
int isFuncHidden(FuncDeclaration *fd);
#endif
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
#if DMDV1
int isNested();
#endif
int isCOMclass();
virtual int isCOMinterface();
#if DMDV2
virtual int isCPPinterface();
#endif
int isAbstract();
virtual int vtblOffset();
const char *kind();
char *mangle();
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
void addLocalClass(ClassDeclarations *);
#if IN_DMD
// Back end
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
unsigned baseVtblOffset(BaseClass *bc);
Symbol *toSymbol();
Symbol *toVtblSymbol();
void toDt(dt_t **pdt);
void toDt2(dt_t **pdt, ClassDeclaration *cd);
Symbol *vtblsym;
#endif
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
#if IN_LLVM
virtual void codegen(Ir*);
#endif
};
struct InterfaceDeclaration : ClassDeclaration
{
#if DMDV2
int cpp; // !=0 if this is a C++ interface
#endif
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
int isBaseOf(ClassDeclaration *cd, int *poffset);
int isBaseOf(BaseClass *bc, int *poffset);
const char *kind();
int isBaseInfoComplete();
int vtblOffset();
#if DMDV2
int isCPPinterface();
#endif
virtual int isCOMinterface();
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
Symbol *toSymbol();
#endif
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
#if IN_LLVM
void codegen(Ir*);
#endif
};
#endif /* DMD_AGGREGATE_H */

View File

@@ -1,72 +1,72 @@
// Compiler implementation of the D programming language
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "identifier.h"
#include "aliasthis.h"
#include "scope.h"
#include "aggregate.h"
#include "dsymbol.h"
#if DMDV2
AliasThis::AliasThis(Loc loc, Identifier *ident)
: Dsymbol(NULL) // it's anonymous (no identifier)
{
this->loc = loc;
this->ident = ident;
}
Dsymbol *AliasThis::syntaxCopy(Dsymbol *s)
{
assert(!s);
/* Since there is no semantic information stored here,
* we don't need to copy it.
*/
return this;
}
void AliasThis::semantic(Scope *sc)
{
Dsymbol *parent = sc->parent;
if (parent)
parent = parent->pastMixin();
AggregateDeclaration *ad = NULL;
if (parent)
ad = parent->isAggregateDeclaration();
if (ad)
{
if (ad->aliasthis)
error("there can be only one alias this");
assert(ad->members);
Dsymbol *s = ad->search(loc, ident, 0);
ad->aliasthis = s;
}
else
error("alias this can only appear in struct or class declaration, not %s", parent ? parent->toChars() : "nowhere");
}
const char *AliasThis::kind()
{
return "alias this";
}
void AliasThis::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("alias ");
buf->writestring(ident->toChars());
buf->writestring(" this;\n");
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "identifier.h"
#include "aliasthis.h"
#include "scope.h"
#include "aggregate.h"
#include "dsymbol.h"
#if DMDV2
AliasThis::AliasThis(Loc loc, Identifier *ident)
: Dsymbol(NULL) // it's anonymous (no identifier)
{
this->loc = loc;
this->ident = ident;
}
Dsymbol *AliasThis::syntaxCopy(Dsymbol *s)
{
assert(!s);
/* Since there is no semantic information stored here,
* we don't need to copy it.
*/
return this;
}
void AliasThis::semantic(Scope *sc)
{
Dsymbol *parent = sc->parent;
if (parent)
parent = parent->pastMixin();
AggregateDeclaration *ad = NULL;
if (parent)
ad = parent->isAggregateDeclaration();
if (ad)
{
if (ad->aliasthis)
error("there can be only one alias this");
assert(ad->members);
Dsymbol *s = ad->search(loc, ident, 0);
ad->aliasthis = s;
}
else
error("alias this can only appear in struct or class declaration, not %s", parent ? parent->toChars() : "nowhere");
}
const char *AliasThis::kind()
{
return "alias this";
}
void AliasThis::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("alias ");
buf->writestring(ident->toChars());
buf->writestring(" this;\n");
}
#endif

View File

@@ -1,41 +1,41 @@
// Compiler implementation of the D programming language
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ALIASTHIS_H
#define DMD_ALIASTHIS_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "mars.h"
#include "dsymbol.h"
/**************************************************************/
#if DMDV2
struct AliasThis : Dsymbol
{
// alias Identifier this;
Identifier *ident;
AliasThis(Loc loc, Identifier *ident);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
AliasThis *isAliasThis() { return this; }
};
#endif
#endif
// Compiler implementation of the D programming language
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ALIASTHIS_H
#define DMD_ALIASTHIS_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "mars.h"
#include "dsymbol.h"
/**************************************************************/
#if DMDV2
struct AliasThis : Dsymbol
{
// alias Identifier this;
Identifier *ident;
AliasThis(Loc loc, Identifier *ident);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
AliasThis *isAliasThis() { return this; }
};
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +1,51 @@
// Compiler implementation of the D programming language
// Copyright (c) 2006-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ARRAYTYPES_H
#define DMD_ARRAYTYPES_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
struct Expression;
struct Statement;
struct BaseClass;
struct TemplateParameter;
struct FuncDeclaration;
struct Identifier;
struct Initializer;
struct TemplateParameters : Array { };
struct Expressions : Array { };
struct Statements : Array { };
struct BaseClasses : Array { };
struct ClassDeclarations : Array { };
struct Dsymbols : Array { };
struct Objects : Array { };
struct FuncDeclarations : Array { };
struct Arguments : Array { };
struct Identifiers : Array { };
struct Initializers : Array { };
#endif
// Compiler implementation of the D programming language
// Copyright (c) 2006-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ARRAYTYPES_H
#define DMD_ARRAYTYPES_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
struct Expression;
struct Statement;
struct BaseClass;
struct TemplateParameter;
struct FuncDeclaration;
struct Identifier;
struct Initializer;
struct TemplateParameters : Array { };
struct Expressions : Array { };
struct Statements : Array { };
struct BaseClasses : Array { };
struct ClassDeclarations : Array { };
struct Dsymbols : Array { };
struct Objects : Array { };
struct FuncDeclarations : Array { };
struct Parameters : Array { };
struct Identifiers : Array { };
struct Initializers : Array { };
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +1,202 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ATTRIB_H
#define DMD_ATTRIB_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Expression;
struct Statement;
struct LabelDsymbol;
struct Initializer;
struct Module;
struct Condition;
#ifdef _DH
struct HdrGenState;
#endif
/**************************************************************/
struct AttribDeclaration : Dsymbol
{
Array *decl; // array of Dsymbol's
AttribDeclaration(Array *decl);
virtual Array *include(Scope *sc, ScopeDsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semanticNewSc(Scope *sc,
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semantic(Scope *sc);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
void addComment(unsigned char *comment);
void emitComment(Scope *sc);
const char *kind();
int oneMember(Dsymbol **ps);
int hasPointers();
void checkCtorConstInit();
void addLocalClass(ClassDeclarations *);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
AttribDeclaration *isAttribDeclaration() { return this; }
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
#endif
#if IN_LLVM
virtual void codegen(Ir*);
#endif
};
struct StorageClassDeclaration: AttribDeclaration
{
unsigned stc;
StorageClassDeclaration(unsigned stc, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void stcToCBuffer(OutBuffer *buf, int stc);
};
struct LinkDeclaration : AttribDeclaration
{
enum LINK linkage;
LinkDeclaration(enum LINK p, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void semantic3(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *toChars();
};
struct ProtDeclaration : AttribDeclaration
{
enum PROT protection;
ProtDeclaration(enum PROT p, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void protectionToCBuffer(OutBuffer *buf, enum PROT protection);
};
struct AlignDeclaration : AttribDeclaration
{
unsigned salign;
AlignDeclaration(Loc loc, unsigned sa, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
struct AnonDeclaration : AttribDeclaration
{
int isunion;
int sem; // 1 if successful semantic()
AnonDeclaration(Loc loc, int isunion, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
};
struct PragmaDeclaration : AttribDeclaration
{
Expressions *args; // array of Expression's
PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void setScope(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
#endif
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct ConditionalDeclaration : AttribDeclaration
{
Condition *condition;
Array *elsedecl; // array of Dsymbol's for else block
ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
int oneMember(Dsymbol **ps);
void emitComment(Scope *sc);
Array *include(Scope *sc, ScopeDsymbol *s);
void addComment(unsigned char *comment);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
struct StaticIfDeclaration : ConditionalDeclaration
{
ScopeDsymbol *sd;
int addisdone;
StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
const char *kind();
};
// Mixin declarations
struct CompileDeclaration : AttribDeclaration
{
Expression *exp;
ScopeDsymbol *sd;
int compiled;
CompileDeclaration(Loc loc, Expression *exp);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
void compileIt(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
#endif /* DMD_ATTRIB_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ATTRIB_H
#define DMD_ATTRIB_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Expression;
struct Statement;
struct LabelDsymbol;
struct Initializer;
struct Module;
struct Condition;
#ifdef _DH
struct HdrGenState;
#endif
/**************************************************************/
struct AttribDeclaration : Dsymbol
{
Dsymbols *decl; // array of Dsymbol's
AttribDeclaration(Dsymbols *decl);
virtual Dsymbols *include(Scope *sc, ScopeDsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semanticNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semantic(Scope *sc);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
void addComment(unsigned char *comment);
void emitComment(Scope *sc);
const char *kind();
int oneMember(Dsymbol **ps);
int hasPointers();
void checkCtorConstInit();
void addLocalClass(ClassDeclarations *);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toJsonBuffer(OutBuffer *buf);
AttribDeclaration *isAttribDeclaration() { return this; }
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
#endif
#if IN_LLVM
virtual void codegen(Ir*);
#endif
};
struct StorageClassDeclaration: AttribDeclaration
{
StorageClass stc;
StorageClassDeclaration(StorageClass stc, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
};
struct LinkDeclaration : AttribDeclaration
{
enum LINK linkage;
LinkDeclaration(enum LINK p, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void semantic3(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *toChars();
};
struct ProtDeclaration : AttribDeclaration
{
enum PROT protection;
ProtDeclaration(enum PROT p, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void importAll(Scope *sc);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void protectionToCBuffer(OutBuffer *buf, enum PROT protection);
};
struct AlignDeclaration : AttribDeclaration
{
unsigned salign;
AlignDeclaration(Loc loc, unsigned sa, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
struct AnonDeclaration : AttribDeclaration
{
int isunion;
int sem; // 1 if successful semantic()
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
};
struct PragmaDeclaration : AttribDeclaration
{
Expressions *args; // array of Expression's
PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void setScope(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
#endif
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct ConditionalDeclaration : AttribDeclaration
{
Condition *condition;
Dsymbols *elsedecl; // array of Dsymbol's for else block
ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
int oneMember(Dsymbol **ps);
void emitComment(Scope *sc);
Dsymbols *include(Scope *sc, ScopeDsymbol *s);
void addComment(unsigned char *comment);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toJsonBuffer(OutBuffer *buf);
void importAll(Scope *sc);
void setScope(Scope *sc);
};
struct StaticIfDeclaration : ConditionalDeclaration
{
ScopeDsymbol *sd;
int addisdone;
StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
void importAll(Scope *sc);
void setScope(Scope *sc);
const char *kind();
};
// Mixin declarations
struct CompileDeclaration : AttribDeclaration
{
Expression *exp;
ScopeDsymbol *sd;
int compiled;
CompileDeclaration(Loc loc, Expression *exp);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
void compileIt(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
#endif /* DMD_ATTRIB_H */

View File

@@ -1,42 +0,0 @@
The Software is not generally available software. It has not undergone
testing and may contain errors. The Software was not designed to operate
after December 31, 1999. It may be incomplete and it may not function
properly. No support or maintenance is provided with this Software. Do
not install or distribute the Software if
you are not accustomed to using or distributing experimental software.
Do not use this software for life critical applications, or applications
that could cause significant harm or property damage.
Digital Mars licenses the Software to you on an "AS IS" basis, without
warranty of any kind. DIGITAL MARS AND SYMANTEC HEREBY EXPRESSLY DISCLAIM
ALL WARRANTIES AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY,
NONINFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. You are solely
responsible for determining the appropriateness of using this Software and
assume all risks associated with the use of this Software, including but not
limited to the risks of program errors, damage
to or loss of data, programs or equipment, unavailability or interruption of
operations and third party claims. You agree to defend, indemnify and hold
Digital Mars and Symantec, its subsidiaries, affiliates, directors, officers,
employees and agents harmless from all claims or demands made against them
(and any related losses, damages, expenses
and costs) arising out of your use of the Software. DIGITAL MARS AND SYMANTEC
WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, INCIDENTAL, OR
INDIRECT DAMAGES OR FOR ANY ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING
LOST PROFITS OR SAVINGS), EVEN IF DIGITAL MARS OR SYMANTEC HAS BEEN ADVISED
OF THE POSSIBILITY OF SUCH DAMAGES.
Digital Mars and Symantec will not be liable for the loss of, or damage to,
your records or data, the records or
data of any third party, or any damages claimed by you based on a third party
claim.
If you send any messages to Digital Mars, on either the Digital Mars
newsgroups, the Digital Mars mailing list, or via email, you agree not
to make any claims of intellectual
property rights over the contents of those messages.
The Software is copyrighted and comes with a single user license,
and may not be redistributed. If you wish to obtain a redistribution license,
please contact Digital Mars.

View File

@@ -1,116 +1,127 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include "mars.h"
#include "declaration.h"
#include "attrib.h"
#include "expression.h"
#include "scope.h"
#include "mtype.h"
#include "aggregate.h"
#include "identifier.h"
#include "id.h"
#include "module.h"
#if DMDV2
/**********************************
* Determine if function is a builtin one that we can
* evaluate at compile time.
*/
enum BUILTIN FuncDeclaration::isBuiltin()
{
static const char FeZe[] = "FNaNbeZe"; // pure nothrow real function(real)
//printf("FuncDeclaration::isBuiltin() %s\n", toChars());
if (builtin == BUILTINunknown)
{
builtin = BUILTINnot;
if (parent && parent->isModule())
{
// If it's in the std.math package
if (parent->ident == Id::math &&
parent->parent && parent->parent->ident == Id::std &&
!parent->parent->parent)
{
//printf("deco = %s\n", type->deco);
if (strcmp(type->deco, FeZe) == 0)
{
if (ident == Id::sin)
builtin = BUILTINsin;
else if (ident == Id::cos)
builtin = BUILTINcos;
else if (ident == Id::tan)
builtin = BUILTINtan;
else if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
else if (ident == Id::fabs)
builtin = BUILTINfabs;
//printf("builtin = %d\n", builtin);
}
// if float or double versions
else if (strcmp(type->deco, "FNaNbdZd") == 0 ||
strcmp(type->deco, "FNaNbfZf") == 0)
{
if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
}
}
}
}
return builtin;
}
/**************************************
* Evaluate builtin function.
* Return result; NULL if cannot evaluate it.
*/
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments)
{
assert(arguments && arguments->dim);
Expression *arg0 = (Expression *)arguments->data[0];
Expression *e = NULL;
switch (builtin)
{
case BUILTINsin:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sinl(arg0->toReal()), arg0->type);
break;
case BUILTINcos:
if (arg0->op == TOKfloat64)
e = new RealExp(0, cosl(arg0->toReal()), arg0->type);
break;
case BUILTINtan:
if (arg0->op == TOKfloat64)
e = new RealExp(0, tanl(arg0->toReal()), arg0->type);
break;
case BUILTINsqrt:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type);
break;
case BUILTINfabs:
if (arg0->op == TOKfloat64)
e = new RealExp(0, fabsl(arg0->toReal()), arg0->type);
break;
}
return e;
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include <math.h>
#if __FreeBSD__
extern "C"
{
long double sinl(long double);
long double cosl(long double);
long double tanl(long double);
long double sqrtl(long double);
}
#endif
#include "mars.h"
#include "declaration.h"
#include "attrib.h"
#include "expression.h"
#include "scope.h"
#include "mtype.h"
#include "aggregate.h"
#include "identifier.h"
#include "id.h"
#include "module.h"
#if DMDV2
/**********************************
* Determine if function is a builtin one that we can
* evaluate at compile time.
*/
enum BUILTIN FuncDeclaration::isBuiltin()
{
static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real)
static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real)
//printf("FuncDeclaration::isBuiltin() %s\n", toChars());
if (builtin == BUILTINunknown)
{
builtin = BUILTINnot;
if (parent && parent->isModule())
{
// If it's in the std.math package
if (parent->ident == Id::math &&
parent->parent && parent->parent->ident == Id::std &&
!parent->parent->parent)
{
//printf("deco = %s\n", type->deco);
if (strcmp(type->deco, FeZe) == 0 || strcmp(type->deco, FeZe2) == 0)
{
if (ident == Id::sin)
builtin = BUILTINsin;
else if (ident == Id::cos)
builtin = BUILTINcos;
else if (ident == Id::tan)
builtin = BUILTINtan;
else if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
else if (ident == Id::fabs)
builtin = BUILTINfabs;
//printf("builtin = %d\n", builtin);
}
// if float or double versions
else if (strcmp(type->deco, "FNaNbNfdZd") == 0 ||
strcmp(type->deco, "FNaNbNffZf") == 0)
{
if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
}
}
}
}
return builtin;
}
/**************************************
* Evaluate builtin function.
* Return result; NULL if cannot evaluate it.
*/
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments)
{
assert(arguments && arguments->dim);
Expression *arg0 = (Expression *)arguments->data[0];
Expression *e = NULL;
switch (builtin)
{
case BUILTINsin:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sinl(arg0->toReal()), arg0->type);
break;
case BUILTINcos:
if (arg0->op == TOKfloat64)
e = new RealExp(0, cosl(arg0->toReal()), arg0->type);
break;
case BUILTINtan:
if (arg0->op == TOKfloat64)
e = new RealExp(0, tanl(arg0->toReal()), arg0->type);
break;
case BUILTINsqrt:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type);
break;
case BUILTINfabs:
if (arg0->op == TOKfloat64)
e = new RealExp(0, fabsl(arg0->toReal()), arg0->type);
break;
}
return e;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +1,74 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright and Burton Radons
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_COMPLEX_T_H
#define DMD_COMPLEX_T_H
/* Roll our own complex type for compilers that don't support complex
*/
struct complex_t
{
long double re;
long double im;
complex_t() { this->re = 0; this->im = 0; }
complex_t(long double re) { this->re = re; this->im = 0; }
complex_t(long double re, long double im) { this->re = re; this->im = im; }
complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; }
complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; }
complex_t operator - () { complex_t r; r.re = -re; r.im = -im; return r; }
complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); }
complex_t operator / (complex_t y)
{
long double abs_y_re = y.re < 0 ? -y.re : y.re;
long double abs_y_im = y.im < 0 ? -y.im : y.im;
long double r, den;
if (abs_y_re < abs_y_im)
{
r = y.re / y.im;
den = y.im + r * y.re;
return complex_t((re * r + im) / den,
(im * r - re) / den);
}
else
{
r = y.im / y.re;
den = y.re + r * y.im;
return complex_t((re + r * im) / den,
(im - r * re) / den);
}
}
operator bool () { return re || im; }
int operator == (complex_t y) { return re == y.re && im == y.im; }
int operator != (complex_t y) { return re != y.re || im != y.im; }
};
inline complex_t operator * (long double x, complex_t y) { return complex_t(x) * y; }
inline complex_t operator * (complex_t x, long double y) { return x * complex_t(y); }
inline complex_t operator / (complex_t x, long double y) { return x / complex_t(y); }
inline long double creall(complex_t x)
{
return x.re;
}
inline long double cimagl(complex_t x)
{
return x.im;
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright and Burton Radons
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_COMPLEX_T_H
#define DMD_COMPLEX_T_H
/* Roll our own complex type for compilers that don't support complex
*/
struct complex_t
{
long double re;
long double im;
complex_t() { this->re = 0; this->im = 0; }
complex_t(long double re) { this->re = re; this->im = 0; }
complex_t(long double re, long double im) { this->re = re; this->im = im; }
complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; }
complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; }
complex_t operator - () { complex_t r; r.re = -re; r.im = -im; return r; }
complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); }
complex_t operator / (complex_t y)
{
long double abs_y_re = y.re < 0 ? -y.re : y.re;
long double abs_y_im = y.im < 0 ? -y.im : y.im;
long double r, den;
if (abs_y_re < abs_y_im)
{
r = y.re / y.im;
den = y.im + r * y.re;
return complex_t((re * r + im) / den,
(im * r - re) / den);
}
else
{
r = y.im / y.re;
den = y.re + r * y.im;
return complex_t((re + r * im) / den,
(im - r * re) / den);
}
}
operator bool () { return re || im; }
int operator == (complex_t y) { return re == y.re && im == y.im; }
int operator != (complex_t y) { return re != y.re || im != y.im; }
};
inline complex_t operator * (long double x, complex_t y) { return complex_t(x) * y; }
inline complex_t operator * (complex_t x, long double y) { return x * complex_t(y); }
inline complex_t operator / (complex_t x, long double y) { return x / complex_t(y); }
inline long double creall(complex_t x)
{
return x.re;
}
inline long double cimagl(complex_t x)
{
return x.im;
}
#endif

View File

@@ -1,406 +1,406 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "id.h"
#include "init.h"
#include "declaration.h"
#include "identifier.h"
#include "expression.h"
#include "cond.h"
#include "module.h"
#include "template.h"
#include "lexer.h"
#ifdef _DH
#include "mtype.h"
#include "scope.h"
#endif
int findCondition(Array *ids, Identifier *ident)
{
if (ids)
{
for (int i = 0; i < ids->dim; i++)
{
const char *id = (const char *)ids->data[i];
if (strcmp(id, ident->toChars()) == 0)
return TRUE;
}
}
return FALSE;
}
/* ============================================================ */
Condition::Condition(Loc loc)
{
this->loc = loc;
inc = 0;
}
/* ============================================================ */
DVCondition::DVCondition(Module *mod, unsigned level, Identifier *ident)
: Condition(0)
{
this->mod = mod;
this->level = level;
this->ident = ident;
}
Condition *DVCondition::syntaxCopy()
{
return this; // don't need to copy
}
/* ============================================================ */
void DebugCondition::setGlobalLevel(unsigned level)
{
global.params.debuglevel = level;
}
void DebugCondition::addGlobalIdent(const char *ident)
{
if (!global.params.debugids)
global.params.debugids = new Array();
global.params.debugids->push((void *)ident);
}
DebugCondition::DebugCondition(Module *mod, unsigned level, Identifier *ident)
: DVCondition(mod, level, ident)
{
}
int DebugCondition::include(Scope *sc, ScopeDsymbol *s)
{
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
if (inc == 0)
{
inc = 2;
if (ident)
{
if (findCondition(mod->debugids, ident))
inc = 1;
else if (findCondition(global.params.debugids, ident))
inc = 1;
else
{ if (!mod->debugidsNot)
mod->debugidsNot = new Array();
mod->debugidsNot->push(ident->toChars());
}
}
else if (level <= global.params.debuglevel || level <= mod->debuglevel)
inc = 1;
}
return (inc == 1);
}
void DebugCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (ident)
buf->printf("debug (%s)", ident->toChars());
else
buf->printf("debug (%u)", level);
}
/* ============================================================ */
void VersionCondition::setGlobalLevel(unsigned level)
{
global.params.versionlevel = level;
}
void VersionCondition::checkPredefined(Loc loc, const char *ident)
{
static const char* reserved[] =
{
"DigitalMars", "X86", "X86_64",
"Windows", "Win32", "Win64",
"linux",
#if DMDV2
/* Although Posix is predefined by D1, disallowing its
* redefinition breaks makefiles and older builds.
*/
"Posix",
"D_NET",
#endif
"OSX", "FreeBSD",
"Solaris",
"LittleEndian", "BigEndian",
"all",
"none",
#if IN_LLVM
"LLVM", "LDC", "LLVM64",
"PPC", "PPC64",
"darwin","solaris","freebsd"
#endif
};
for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
{
if (strcmp(ident, reserved[i]) == 0)
goto Lerror;
}
if (ident[0] == 'D' && ident[1] == '_')
goto Lerror;
return;
Lerror:
error(loc, "version identifier '%s' is reserved and cannot be set", ident);
}
void VersionCondition::addGlobalIdent(const char *ident)
{
checkPredefined(0, ident);
addPredefinedGlobalIdent(ident);
}
void VersionCondition::addPredefinedGlobalIdent(const char *ident)
{
if (!global.params.versionids)
global.params.versionids = new Array();
global.params.versionids->push((void *)ident);
}
VersionCondition::VersionCondition(Module *mod, unsigned level, Identifier *ident)
: DVCondition(mod, level, ident)
{
}
int VersionCondition::include(Scope *sc, ScopeDsymbol *s)
{
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
//if (ident) printf("\tident = '%s'\n", ident->toChars());
if (inc == 0)
{
inc = 2;
if (ident)
{
if (findCondition(mod->versionids, ident))
inc = 1;
else if (findCondition(global.params.versionids, ident))
inc = 1;
else
{
if (!mod->versionidsNot)
mod->versionidsNot = new Array();
mod->versionidsNot->push(ident->toChars());
}
}
else if (level <= global.params.versionlevel || level <= mod->versionlevel)
inc = 1;
}
return (inc == 1);
}
void VersionCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (ident)
buf->printf("version (%s)", ident->toChars());
else
buf->printf("version (%u)", level);
}
/**************************** StaticIfCondition *******************************/
StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
: Condition(loc)
{
this->exp = exp;
}
Condition *StaticIfCondition::syntaxCopy()
{
return new StaticIfCondition(loc, exp->syntaxCopy());
}
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
{
#if 0
printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
if (s)
{
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
}
#endif
if (inc == 0)
{
if (!sc)
{
error(loc, "static if conditional cannot be at global scope");
inc = 2;
return 0;
}
sc = sc->push(sc->scopesym);
sc->sd = s; // s gets any addMember()
sc->flags |= SCOPEstaticif;
Expression *e = exp->semantic(sc);
sc->pop();
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(TRUE))
inc = 1;
else if (e->isBool(FALSE))
inc = 2;
else
{
e->error("expression %s is not constant or does not evaluate to a bool", e->toChars());
inc = 2;
}
}
return (inc == 1);
}
void StaticIfCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("static if(");
exp->toCBuffer(buf, hgs);
buf->writeByte(')');
}
/**************************** IftypeCondition *******************************/
IftypeCondition::IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec)
: Condition(loc)
{
this->targ = targ;
this->id = id;
this->tok = tok;
this->tspec = tspec;
}
Condition *IftypeCondition::syntaxCopy()
{
return new IftypeCondition(loc,
targ->syntaxCopy(),
id,
tok,
tspec ? tspec->syntaxCopy() : NULL);
}
int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
{
//printf("IftypeCondition::include()\n");
if (inc == 0)
{
if (!sc)
{
error(loc, "iftype conditional cannot be at global scope");
inc = 2;
return 0;
}
Type *t = targ->trySemantic(loc, sc);
if (t)
targ = t;
else
inc = 2; // condition is false
if (!t)
{
}
else if (id && tspec)
{
/* Evaluate to TRUE if targ matches tspec.
* If TRUE, declare id as an alias for the specialized type.
*/
MATCH m;
TemplateTypeParameter tp(loc, id, NULL, NULL);
TemplateParameters parameters;
parameters.setDim(1);
parameters.data[0] = (void *)&tp;
Objects dedtypes;
dedtypes.setDim(1);
m = targ->deduceType(NULL, tspec, &parameters, &dedtypes);
if (m == MATCHnomatch ||
(m != MATCHexact && tok == TOKequal))
inc = 2;
else
{
inc = 1;
Type *tded = (Type *)dedtypes.data[0];
if (!tded)
tded = targ;
Dsymbol *s = new AliasDeclaration(loc, id, tded);
s->semantic(sc);
sc->insert(s);
if (sd)
s->addMember(sc, sd, 1);
}
}
else if (id)
{
/* Declare id as an alias for type targ. Evaluate to TRUE
*/
Dsymbol *s = new AliasDeclaration(loc, id, targ);
s->semantic(sc);
sc->insert(s);
if (sd)
s->addMember(sc, sd, 1);
inc = 1;
}
else if (tspec)
{
/* Evaluate to TRUE if targ matches tspec
*/
tspec = tspec->semantic(loc, sc);
//printf("targ = %s\n", targ->toChars());
//printf("tspec = %s\n", tspec->toChars());
if (tok == TOKcolon)
{ if (targ->implicitConvTo(tspec))
inc = 1;
else
inc = 2;
}
else /* == */
{ if (targ->equals(tspec))
inc = 1;
else
inc = 2;
}
}
else
inc = 1;
//printf("inc = %d\n", inc);
}
return (inc == 1);
}
void IftypeCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("iftype(");
targ->toCBuffer(buf, id, hgs);
if (tspec)
{
if (tok == TOKcolon)
buf->writestring(" : ");
else
buf->writestring(" == ");
tspec->toCBuffer(buf, NULL, hgs);
}
buf->writeByte(')');
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "id.h"
#include "init.h"
#include "declaration.h"
#include "identifier.h"
#include "expression.h"
#include "cond.h"
#include "module.h"
#include "template.h"
#include "lexer.h"
#ifdef _DH
#include "mtype.h"
#include "scope.h"
#endif
int findCondition(Array *ids, Identifier *ident)
{
if (ids)
{
for (int i = 0; i < ids->dim; i++)
{
const char *id = (const char *)ids->data[i];
if (strcmp(id, ident->toChars()) == 0)
return TRUE;
}
}
return FALSE;
}
/* ============================================================ */
Condition::Condition(Loc loc)
{
this->loc = loc;
inc = 0;
}
/* ============================================================ */
DVCondition::DVCondition(Module *mod, unsigned level, Identifier *ident)
: Condition(0)
{
this->mod = mod;
this->level = level;
this->ident = ident;
}
Condition *DVCondition::syntaxCopy()
{
return this; // don't need to copy
}
/* ============================================================ */
void DebugCondition::setGlobalLevel(unsigned level)
{
global.params.debuglevel = level;
}
void DebugCondition::addGlobalIdent(const char *ident)
{
if (!global.params.debugids)
global.params.debugids = new Array();
global.params.debugids->push((void *)ident);
}
DebugCondition::DebugCondition(Module *mod, unsigned level, Identifier *ident)
: DVCondition(mod, level, ident)
{
}
int DebugCondition::include(Scope *sc, ScopeDsymbol *s)
{
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
if (inc == 0)
{
inc = 2;
if (ident)
{
if (findCondition(mod->debugids, ident))
inc = 1;
else if (findCondition(global.params.debugids, ident))
inc = 1;
else
{ if (!mod->debugidsNot)
mod->debugidsNot = new Array();
mod->debugidsNot->push(ident->toChars());
}
}
else if (level <= global.params.debuglevel || level <= mod->debuglevel)
inc = 1;
}
return (inc == 1);
}
void DebugCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (ident)
buf->printf("debug (%s)", ident->toChars());
else
buf->printf("debug (%u)", level);
}
/* ============================================================ */
void VersionCondition::setGlobalLevel(unsigned level)
{
global.params.versionlevel = level;
}
void VersionCondition::checkPredefined(Loc loc, const char *ident)
{
static const char* reserved[] =
{
"DigitalMars", "X86", "X86_64",
"Windows", "Win32", "Win64",
"linux",
#if DMDV2
/* Although Posix is predefined by D1, disallowing its
* redefinition breaks makefiles and older builds.
*/
"Posix",
"D_NET",
#endif
"OSX", "FreeBSD",
"Solaris",
"LittleEndian", "BigEndian",
"all",
"none",
#if IN_LLVM
"LLVM", "LDC", "LLVM64",
"PPC", "PPC64",
"darwin","solaris","freebsd"
#endif
};
for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
{
if (strcmp(ident, reserved[i]) == 0)
goto Lerror;
}
if (ident[0] == 'D' && ident[1] == '_')
goto Lerror;
return;
Lerror:
error(loc, "version identifier '%s' is reserved and cannot be set", ident);
}
void VersionCondition::addGlobalIdent(const char *ident)
{
checkPredefined(0, ident);
addPredefinedGlobalIdent(ident);
}
void VersionCondition::addPredefinedGlobalIdent(const char *ident)
{
if (!global.params.versionids)
global.params.versionids = new Array();
global.params.versionids->push((void *)ident);
}
VersionCondition::VersionCondition(Module *mod, unsigned level, Identifier *ident)
: DVCondition(mod, level, ident)
{
}
int VersionCondition::include(Scope *sc, ScopeDsymbol *s)
{
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
//if (ident) printf("\tident = '%s'\n", ident->toChars());
if (inc == 0)
{
inc = 2;
if (ident)
{
if (findCondition(mod->versionids, ident))
inc = 1;
else if (findCondition(global.params.versionids, ident))
inc = 1;
else
{
if (!mod->versionidsNot)
mod->versionidsNot = new Array();
mod->versionidsNot->push(ident->toChars());
}
}
else if (level <= global.params.versionlevel || level <= mod->versionlevel)
inc = 1;
}
return (inc == 1);
}
void VersionCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (ident)
buf->printf("version (%s)", ident->toChars());
else
buf->printf("version (%u)", level);
}
/**************************** StaticIfCondition *******************************/
StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
: Condition(loc)
{
this->exp = exp;
}
Condition *StaticIfCondition::syntaxCopy()
{
return new StaticIfCondition(loc, exp->syntaxCopy());
}
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
{
#if 0
printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
if (s)
{
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
}
#endif
if (inc == 0)
{
if (!sc)
{
error(loc, "static if conditional cannot be at global scope");
inc = 2;
return 0;
}
sc = sc->push(sc->scopesym);
sc->sd = s; // s gets any addMember()
sc->flags |= SCOPEstaticif;
Expression *e = exp->semantic(sc);
sc->pop();
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(TRUE))
inc = 1;
else if (e->isBool(FALSE))
inc = 2;
else
{
e->error("expression %s is not constant or does not evaluate to a bool", e->toChars());
inc = 2;
}
}
return (inc == 1);
}
void StaticIfCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("static if(");
exp->toCBuffer(buf, hgs);
buf->writeByte(')');
}
/**************************** IftypeCondition *******************************/
IftypeCondition::IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec)
: Condition(loc)
{
this->targ = targ;
this->id = id;
this->tok = tok;
this->tspec = tspec;
}
Condition *IftypeCondition::syntaxCopy()
{
return new IftypeCondition(loc,
targ->syntaxCopy(),
id,
tok,
tspec ? tspec->syntaxCopy() : NULL);
}
int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
{
//printf("IftypeCondition::include()\n");
if (inc == 0)
{
if (!sc)
{
error(loc, "iftype conditional cannot be at global scope");
inc = 2;
return 0;
}
Type *t = targ->trySemantic(loc, sc);
if (t)
targ = t;
else
inc = 2; // condition is false
if (!t)
{
}
else if (id && tspec)
{
/* Evaluate to TRUE if targ matches tspec.
* If TRUE, declare id as an alias for the specialized type.
*/
MATCH m;
TemplateTypeParameter tp(loc, id, NULL, NULL);
TemplateParameters parameters;
parameters.setDim(1);
parameters.data[0] = (void *)&tp;
Objects dedtypes;
dedtypes.setDim(1);
m = targ->deduceType(NULL, tspec, &parameters, &dedtypes);
if (m == MATCHnomatch ||
(m != MATCHexact && tok == TOKequal))
inc = 2;
else
{
inc = 1;
Type *tded = (Type *)dedtypes.data[0];
if (!tded)
tded = targ;
Dsymbol *s = new AliasDeclaration(loc, id, tded);
s->semantic(sc);
sc->insert(s);
if (sd)
s->addMember(sc, sd, 1);
}
}
else if (id)
{
/* Declare id as an alias for type targ. Evaluate to TRUE
*/
Dsymbol *s = new AliasDeclaration(loc, id, targ);
s->semantic(sc);
sc->insert(s);
if (sd)
s->addMember(sc, sd, 1);
inc = 1;
}
else if (tspec)
{
/* Evaluate to TRUE if targ matches tspec
*/
tspec = tspec->semantic(loc, sc);
//printf("targ = %s\n", targ->toChars());
//printf("tspec = %s\n", tspec->toChars());
if (tok == TOKcolon)
{ if (targ->implicitConvTo(tspec))
inc = 1;
else
inc = 2;
}
else /* == */
{ if (targ->equals(tspec))
inc = 1;
else
inc = 2;
}
}
else
inc = 1;
//printf("inc = %d\n", inc);
}
return (inc == 1);
}
void IftypeCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("iftype(");
targ->toCBuffer(buf, id, hgs);
if (tspec)
{
if (tok == TOKcolon)
buf->writestring(" : ");
else
buf->writestring(" == ");
tspec->toCBuffer(buf, NULL, hgs);
}
buf->writeByte(')');
}

View File

@@ -30,9 +30,9 @@ int findCondition(Array *ids, Identifier *ident);
struct Condition
{
Loc loc;
int inc; // 0: not computed yet
// 1: include
// 2: do not include
int inc; // 0: not computed yet
// 1: include
// 2: do not include
Condition(Loc loc);
@@ -92,9 +92,9 @@ struct IftypeCondition : Condition
/* iftype (targ id tok tspec)
*/
Type *targ;
Identifier *id; // can be NULL
enum TOK tok; // ':' or '=='
Type *tspec; // can be NULL
Identifier *id; // can be NULL
enum TOK tok; // ':' or '=='
Type *tspec; // can be NULL
IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec);
Condition *syntaxCopy();

File diff suppressed because it is too large Load Diff

View File

@@ -1,381 +1,389 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "dsymbol.h"
#include "mtype.h"
#include "scope.h"
#include "init.h"
#include "expression.h"
#include "attrib.h"
#include "declaration.h"
#include "template.h"
#include "id.h"
#include "enum.h"
#include "import.h"
#include "aggregate.h"
#if CPP_MANGLE
/* Do mangling for C++ linkage.
* Follows Itanium C++ ABI 1.86
* No attempt is made to support mangling of templates, operator
* overloading, or special functions.
*
* So why don't we use the C++ ABI for D name mangling?
* Because D supports a lot of things (like modules) that the C++
* ABI has no concept of. These affect every D mangled name,
* so nothing would be compatible anyway.
*/
struct CppMangleState
{
static Array components;
int substitute(OutBuffer *buf, void *p);
};
Array CppMangleState::components;
void writeBase36(OutBuffer *buf, unsigned i)
{
if (i >= 36)
{
writeBase36(buf, i / 36);
i %= 36;
}
if (i < 10)
buf->writeByte(i + '0');
else if (i < 36)
buf->writeByte(i - 10 + 'A');
else
assert(0);
}
int CppMangleState::substitute(OutBuffer *buf, void *p)
{
for (size_t i = 0; i < components.dim; i++)
{
if (p == components.data[i])
{
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
*/
buf->writeByte('S');
if (i)
writeBase36(buf, i - 1);
buf->writeByte('_');
return 1;
}
}
components.push(p);
return 0;
}
void source_name(OutBuffer *buf, Dsymbol *s)
{
char *name = s->ident->toChars();
buf->printf("%d%s", strlen(name), name);
}
void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
if (!cms->substitute(buf, s))
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
prefix_name(buf, cms, p);
}
source_name(buf, s);
}
}
void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
buf->writeByte('N');
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd->isConst())
buf->writeByte('K');
prefix_name(buf, cms, p);
source_name(buf, s);
buf->writeByte('E');
}
else
source_name(buf, s);
}
char *cpp_mangle(Dsymbol *s)
{
/*
* <mangled-name> ::= _Z <encoding>
* <encoding> ::= <function name> <bare-function-type>
* ::= <data name>
* ::= <special-name>
*/
CppMangleState cms;
memset(&cms, 0, sizeof(cms));
cms.components.setDim(0);
OutBuffer buf;
#if MACHOBJ
buf.writestring("__Z");
#else
buf.writestring("_Z");
#endif
cpp_mangle_name(&buf, &cms, s);
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ // add <bare-function-type>
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
Argument::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
}
buf.writeByte(0);
return (char *)buf.extractData();
}
/* ============= Type Encodings ============================================= */
void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
/* Make this the 'vendor extended type' when there is no
* C++ analog.
* u <source-name>
*/
if (!cms->substitute(buf, this))
{ assert(deco);
buf->printf("u%d%s", strlen(deco), deco);
}
}
void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ char c;
char p = 0;
/* ABI spec says:
* v void
* w wchar_t
* b bool
* c char
* a signed char
* h unsigned char
* s short
* t unsigned short
* i int
* j unsigned int
* l long
* m unsigned long
* x long long, __int64
* y unsigned long long, __int64
* n __int128
* o unsigned __int128
* f float
* d double
* e long double, __float80
* g __float128
* z ellipsis
* u <source-name> # vendor extended type
*/
switch (ty)
{
case Tvoid: c = 'v'; break;
case Tint8: c = 'a'; break;
case Tuns8: c = 'h'; break;
case Tint16: c = 's'; break;
case Tuns16: c = 't'; break;
case Tint32: c = 'i'; break;
case Tuns32: c = 'j'; break;
case Tfloat32: c = 'f'; break;
case Tint64: c = 'x'; break;
case Tuns64: c = 'y'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break;
case Tdchar: c = 'w'; break;
case Timaginary32: p = 'G'; c = 'f'; break;
case Timaginary64: p = 'G'; c = 'd'; break;
case Timaginary80: p = 'G'; c = 'e'; break;
case Tcomplex32: p = 'C'; c = 'f'; break;
case Tcomplex64: p = 'C'; c = 'd'; break;
case Tcomplex80: p = 'C'; c = 'e'; break;
default: assert(0);
}
if (p)
{
if (cms->substitute(buf, this))
return;
buf->writeByte(p);
}
buf->writeByte(c);
}
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->printf("A%ju_", dim ? dim->toInteger() : 0);
next->toCppMangle(buf, cms);
}
}
void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('P');
next->toCppMangle(buf, cms);
}
}
void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('R');
next->toCppMangle(buf, cms);
}
}
void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ /*
* <function-type> ::= F [Y] <bare-function-type> E
* <bare-function-type> ::= <signature type>+
* # types are possible return type, then parameter types
*/
/* ABI says:
"The type of a non-static member function is considered to be different,
for the purposes of substitution, from the type of a namespace-scope or
static member function whose type appears similar. The types of two
non-static member functions are considered to be different, for the
purposes of substitution, if the functions are members of different
classes. In other words, for the purposes of substitution, the class of
which the function is a member is considered part of the type of
function."
BUG: Right now, types of functions are never merged, so our simplistic
component matcher always finds them to be different.
We should use Type::equals on these, and use different
TypeFunctions for non-static member functions, and non-static
member functions of different classes.
*/
if (!cms->substitute(buf, this))
{
buf->writeByte('F');
if (linkage == LINKc)
buf->writeByte('Y');
next->toCppMangle(buf, cms);
Argument::argsCppMangle(buf, cms, parameters, varargs);
buf->writeByte('E');
}
}
void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('P');
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
}
void Argument::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs)
{ int n = 0;
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Argument *arg = (Argument *)arguments->data[i];
Type *t = arg->type;
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
else if (arg->storageClass & STClazy)
{ // Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{ // Mangle static arrays as pointers
t = t->pointerTo();
}
t->toCppMangle(buf, cms);
n++;
}
}
if (varargs)
buf->writestring("z");
else if (!n)
buf->writeByte('v'); // encode ( ) arguments
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "dsymbol.h"
#include "mtype.h"
#include "scope.h"
#include "init.h"
#include "expression.h"
#include "attrib.h"
#include "declaration.h"
#include "template.h"
#include "id.h"
#include "enum.h"
#include "import.h"
#include "aggregate.h"
#if CPP_MANGLE
/* Do mangling for C++ linkage.
* Follows Itanium C++ ABI 1.86
* No attempt is made to support mangling of templates, operator
* overloading, or special functions.
*
* So why don't we use the C++ ABI for D name mangling?
* Because D supports a lot of things (like modules) that the C++
* ABI has no concept of. These affect every D mangled name,
* so nothing would be compatible anyway.
*/
struct CppMangleState
{
static Array components;
int substitute(OutBuffer *buf, void *p);
};
Array CppMangleState::components;
void writeBase36(OutBuffer *buf, unsigned i)
{
if (i >= 36)
{
writeBase36(buf, i / 36);
i %= 36;
}
if (i < 10)
buf->writeByte(i + '0');
else if (i < 36)
buf->writeByte(i - 10 + 'A');
else
assert(0);
}
int CppMangleState::substitute(OutBuffer *buf, void *p)
{
for (size_t i = 0; i < components.dim; i++)
{
if (p == components.data[i])
{
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
*/
buf->writeByte('S');
if (i)
writeBase36(buf, i - 1);
buf->writeByte('_');
return 1;
}
}
components.push(p);
return 0;
}
void source_name(OutBuffer *buf, Dsymbol *s)
{
char *name = s->ident->toChars();
buf->printf("%d%s", strlen(name), name);
}
void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
if (!cms->substitute(buf, s))
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
prefix_name(buf, cms, p);
}
source_name(buf, s);
}
}
void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
buf->writeByte('N');
FuncDeclaration *fd = s->isFuncDeclaration();
if (!fd)
{
s->error("C++ static variables not supported");
}
else
if (fd->isConst())
buf->writeByte('K');
prefix_name(buf, cms, p);
source_name(buf, s);
buf->writeByte('E');
}
else
source_name(buf, s);
}
char *cpp_mangle(Dsymbol *s)
{
/*
* <mangled-name> ::= _Z <encoding>
* <encoding> ::= <function name> <bare-function-type>
* ::= <data name>
* ::= <special-name>
*/
CppMangleState cms;
memset(&cms, 0, sizeof(cms));
cms.components.setDim(0);
OutBuffer buf;
#if MACHOBJ
buf.writestring("__Z");
#else
buf.writestring("_Z");
#endif
cpp_mangle_name(&buf, &cms, s);
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ // add <bare-function-type>
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
Parameter::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
}
buf.writeByte(0);
return (char *)buf.extractData();
}
/* ============= Type Encodings ============================================= */
void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
/* Make this the 'vendor extended type' when there is no
* C++ analog.
* u <source-name>
*/
if (!cms->substitute(buf, this))
{ assert(deco);
buf->printf("u%d%s", strlen(deco), deco);
}
}
void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ char c;
char p = 0;
/* ABI spec says:
* v void
* w wchar_t
* b bool
* c char
* a signed char
* h unsigned char
* s short
* t unsigned short
* i int
* j unsigned int
* l long
* m unsigned long
* x long long, __int64
* y unsigned long long, __int64
* n __int128
* o unsigned __int128
* f float
* d double
* e long double, __float80
* g __float128
* z ellipsis
* u <source-name> # vendor extended type
*/
if (isConst())
buf->writeByte('K');
switch (ty)
{
case Tvoid: c = 'v'; break;
case Tint8: c = 'a'; break;
case Tuns8: c = 'h'; break;
case Tint16: c = 's'; break;
case Tuns16: c = 't'; break;
case Tint32: c = 'i'; break;
case Tuns32: c = 'j'; break;
case Tfloat32: c = 'f'; break;
case Tint64: c = 'x'; break;
case Tuns64: c = 'y'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break;
case Tdchar: c = 'w'; break;
case Timaginary32: p = 'G'; c = 'f'; break;
case Timaginary64: p = 'G'; c = 'd'; break;
case Timaginary80: p = 'G'; c = 'e'; break;
case Tcomplex32: p = 'C'; c = 'f'; break;
case Tcomplex64: p = 'C'; c = 'd'; break;
case Tcomplex80: p = 'C'; c = 'e'; break;
default: assert(0);
}
if (p)
{
if (cms->substitute(buf, this))
return;
buf->writeByte(p);
}
buf->writeByte(c);
}
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->printf("A%ju_", dim ? dim->toInteger() : 0);
next->toCppMangle(buf, cms);
}
}
void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('P');
next->toCppMangle(buf, cms);
}
}
void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('R');
next->toCppMangle(buf, cms);
}
}
void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ /*
* <function-type> ::= F [Y] <bare-function-type> E
* <bare-function-type> ::= <signature type>+
* # types are possible return type, then parameter types
*/
/* ABI says:
"The type of a non-static member function is considered to be different,
for the purposes of substitution, from the type of a namespace-scope or
static member function whose type appears similar. The types of two
non-static member functions are considered to be different, for the
purposes of substitution, if the functions are members of different
classes. In other words, for the purposes of substitution, the class of
which the function is a member is considered part of the type of
function."
BUG: Right now, types of functions are never merged, so our simplistic
component matcher always finds them to be different.
We should use Type::equals on these, and use different
TypeFunctions for non-static member functions, and non-static
member functions of different classes.
*/
if (!cms->substitute(buf, this))
{
buf->writeByte('F');
if (linkage == LINKc)
buf->writeByte('Y');
next->toCppMangle(buf, cms);
Parameter::argsCppMangle(buf, cms, parameters, varargs);
buf->writeByte('E');
}
}
void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writeByte('P');
if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
}
}
void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs)
{ int n = 0;
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Parameter *arg = (Parameter *)arguments->data[i];
Type *t = arg->type;
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
else if (arg->storageClass & STClazy)
{ // Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{ // Mangle static arrays as pointers
t = t->pointerTo();
}
t->toCppMangle(buf, cms);
n++;
}
}
if (varargs)
buf->writestring("z");
else if (!n)
buf->writeByte('v'); // encode ( ) arguments
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,214 +1,214 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "scope.h"
/********************************************
* Convert from expression to delegate that returns the expression,
* i.e. convert:
* expr
* to:
* t delegate() { return expr; }
*/
Expression *Expression::toDelegate(Scope *sc, Type *t)
{
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
FuncLiteralDeclaration *fld =
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
Expression *e;
#if 1
sc = sc->push();
sc->parent = fld; // set current function to be the delegate
e = this;
e->scanForNestedRef(sc);
sc = sc->pop();
#else
e = this->syntaxCopy();
#endif
Statement *s = new ReturnStatement(loc, e);
fld->fbody = s;
e = new FuncExp(loc, fld);
e = e->semantic(sc);
return e;
}
/******************************
* Perform scanForNestedRef() on an array of Expressions.
*/
void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
{
//printf("arrayExpressionScanForNestedRef(%p)\n", a);
if (a)
{
for (int i = 0; i < a->dim; i++)
{ Expression *e = (Expression *)a->data[i];
if (e)
{
e->scanForNestedRef(sc);
}
}
}
}
void Expression::scanForNestedRef(Scope *sc)
{
//printf("Expression::scanForNestedRef(%s)\n", toChars());
}
void SymOffExp::scanForNestedRef(Scope *sc)
{
//printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
VarDeclaration *v = var->isVarDeclaration();
if (v)
v->checkNestedReference(sc, 0);
}
void VarExp::scanForNestedRef(Scope *sc)
{
//printf("VarExp::scanForNestedRef(%s)\n", toChars());
VarDeclaration *v = var->isVarDeclaration();
if (v)
v->checkNestedReference(sc, 0);
}
void ThisExp::scanForNestedRef(Scope *sc)
{
assert(var);
var->isVarDeclaration()->checkNestedReference(sc, 0);
}
void SuperExp::scanForNestedRef(Scope *sc)
{
ThisExp::scanForNestedRef(sc);
}
void FuncExp::scanForNestedRef(Scope *sc)
{
//printf("FuncExp::scanForNestedRef(%s)\n", toChars());
//fd->parent = sc->parent;
}
void DeclarationExp::scanForNestedRef(Scope *sc)
{
//printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
declaration->parent = sc->parent;
}
void NewExp::scanForNestedRef(Scope *sc)
{
//printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
if (thisexp)
thisexp->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, newargs);
arrayExpressionScanForNestedRef(sc, arguments);
}
void UnaExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
}
void BinExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
e2->scanForNestedRef(sc);
}
void CallExp::scanForNestedRef(Scope *sc)
{
//printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
e1->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, arguments);
}
void IndexExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
if (lengthVar)
{ //printf("lengthVar\n");
lengthVar->parent = sc->parent;
}
e2->scanForNestedRef(sc);
}
void SliceExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
if (lengthVar)
{ //printf("lengthVar\n");
lengthVar->parent = sc->parent;
}
if (lwr)
lwr->scanForNestedRef(sc);
if (upr)
upr->scanForNestedRef(sc);
}
void ArrayLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, elements);
}
void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, keys);
arrayExpressionScanForNestedRef(sc, values);
}
void StructLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, elements);
}
void TupleExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, exps);
}
void ArrayExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, arguments);
}
void CondExp::scanForNestedRef(Scope *sc)
{
econd->scanForNestedRef(sc);
e1->scanForNestedRef(sc);
e2->scanForNestedRef(sc);
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "mars.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "scope.h"
/********************************************
* Convert from expression to delegate that returns the expression,
* i.e. convert:
* expr
* to:
* t delegate() { return expr; }
*/
Expression *Expression::toDelegate(Scope *sc, Type *t)
{
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
FuncLiteralDeclaration *fld =
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
Expression *e;
#if 1
sc = sc->push();
sc->parent = fld; // set current function to be the delegate
e = this;
e->scanForNestedRef(sc);
sc = sc->pop();
#else
e = this->syntaxCopy();
#endif
Statement *s = new ReturnStatement(loc, e);
fld->fbody = s;
e = new FuncExp(loc, fld);
e = e->semantic(sc);
return e;
}
/******************************
* Perform scanForNestedRef() on an array of Expressions.
*/
void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
{
//printf("arrayExpressionScanForNestedRef(%p)\n", a);
if (a)
{
for (int i = 0; i < a->dim; i++)
{ Expression *e = (Expression *)a->data[i];
if (e)
{
e->scanForNestedRef(sc);
}
}
}
}
void Expression::scanForNestedRef(Scope *sc)
{
//printf("Expression::scanForNestedRef(%s)\n", toChars());
}
void SymOffExp::scanForNestedRef(Scope *sc)
{
//printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
VarDeclaration *v = var->isVarDeclaration();
if (v)
v->checkNestedReference(sc, 0);
}
void VarExp::scanForNestedRef(Scope *sc)
{
//printf("VarExp::scanForNestedRef(%s)\n", toChars());
VarDeclaration *v = var->isVarDeclaration();
if (v)
v->checkNestedReference(sc, 0);
}
void ThisExp::scanForNestedRef(Scope *sc)
{
assert(var);
var->isVarDeclaration()->checkNestedReference(sc, 0);
}
void SuperExp::scanForNestedRef(Scope *sc)
{
ThisExp::scanForNestedRef(sc);
}
void FuncExp::scanForNestedRef(Scope *sc)
{
//printf("FuncExp::scanForNestedRef(%s)\n", toChars());
//fd->parent = sc->parent;
}
void DeclarationExp::scanForNestedRef(Scope *sc)
{
//printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
declaration->parent = sc->parent;
}
void NewExp::scanForNestedRef(Scope *sc)
{
//printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
if (thisexp)
thisexp->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, newargs);
arrayExpressionScanForNestedRef(sc, arguments);
}
void UnaExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
}
void BinExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
e2->scanForNestedRef(sc);
}
void CallExp::scanForNestedRef(Scope *sc)
{
//printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
e1->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, arguments);
}
void IndexExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
if (lengthVar)
{ //printf("lengthVar\n");
lengthVar->parent = sc->parent;
}
e2->scanForNestedRef(sc);
}
void SliceExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
if (lengthVar)
{ //printf("lengthVar\n");
lengthVar->parent = sc->parent;
}
if (lwr)
lwr->scanForNestedRef(sc);
if (upr)
upr->scanForNestedRef(sc);
}
void ArrayLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, elements);
}
void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, keys);
arrayExpressionScanForNestedRef(sc, values);
}
void StructLiteralExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, elements);
}
void TupleExp::scanForNestedRef(Scope *sc)
{
arrayExpressionScanForNestedRef(sc, exps);
}
void ArrayExp::scanForNestedRef(Scope *sc)
{
e1->scanForNestedRef(sc);
arrayExpressionScanForNestedRef(sc, arguments);
}
void CondExp::scanForNestedRef(Scope *sc)
{
econd->scanForNestedRef(sc);
e1->scanForNestedRef(sc);
e2->scanForNestedRef(sc);
}

2232
dmd2/doc.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,19 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_DOC_H
#define DMD_DOC_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_DOC_H
#define DMD_DOC_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -47,6 +47,8 @@ struct PostBlitDeclaration;
struct DtorDeclaration;
struct StaticCtorDeclaration;
struct StaticDtorDeclaration;
struct SharedStaticCtorDeclaration;
struct SharedStaticDtorDeclaration;
struct InvariantDeclaration;
struct UnitTestDeclaration;
struct NewDeclaration;
@@ -75,6 +77,7 @@ struct Expression;
struct DeleteDeclaration;
struct HdrGenState;
struct OverloadSet;
struct AA;
#if TARGET_NET
struct PragmaScope;
#endif
@@ -106,7 +109,7 @@ struct Classsym;
enum PROT
{
PROTundefined,
PROTnone, // no access
PROTnone, // no access
PROTprivate,
PROTpackage,
PROTprotected,
@@ -114,6 +117,18 @@ enum PROT
PROTexport,
};
/* State of symbol in winding its way through the passes of the compiler
*/
enum PASS
{
PASSinit, // initial state
PASSsemantic, // semantic() started
PASSsemanticdone, // semantic() done
PASSsemantic2, // semantic2() run
PASSsemantic3, // semantic3() started
PASSsemantic3done, // semantic3() done
PASSobj, // toObjFile() run
};
struct Dsymbol : Object
{
@@ -121,12 +136,12 @@ struct Dsymbol : Object
Identifier *c_ident;
Dsymbol *parent;
#if IN_DMD
Symbol *csym; // symbol for code generator
Symbol *isym; // import version of csym
Symbol *csym; // symbol for code generator
Symbol *isym; // import version of csym
#endif
unsigned char *comment; // documentation comment for this Dsymbol
Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic()
unsigned char *comment; // documentation comment for this Dsymbol
Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic()
Dsymbol();
Dsymbol(Identifier *);
@@ -144,20 +159,23 @@ struct Dsymbol : Object
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
static Array *arraySyntaxCopy(Array *a);
static Dsymbols *arraySyntaxCopy(Dsymbols *a);
virtual const char *toPrettyChars();
virtual const char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol
virtual Dsymbol *toAlias(); // resolve real symbol
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
virtual void semantic0(Scope *sc);
virtual void semantic(Scope *sc);
virtual void semantic2(Scope *sc);
virtual void semantic3(Scope *sc);
virtual void inlineScan();
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
Dsymbol *search_correct(Identifier *id);
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
virtual int overloadInsert(Dsymbol *s);
#ifdef _DH
@@ -166,24 +184,25 @@ struct Dsymbol : Object
#endif
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
virtual void toDocBuffer(OutBuffer *buf);
virtual void toJsonBuffer(OutBuffer *buf);
virtual unsigned size(Loc loc);
virtual int isforwardRef();
virtual void defineRef(Dsymbol *s);
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
virtual ClassDeclaration *isClassMember(); // are we a member of a class?
virtual int isExport(); // is Dsymbol exported?
virtual int isImportedSymbol(); // is Dsymbol imported?
virtual int isDeprecated(); // is Dsymbol deprecated?
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
virtual ClassDeclaration *isClassMember(); // are we a member of a class?
virtual int isExport(); // is Dsymbol exported?
virtual int isImportedSymbol(); // is Dsymbol imported?
virtual int isDeprecated(); // is Dsymbol deprecated?
#if DMDV2
virtual int isOverloadable();
#endif
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
virtual Type *getType(); // is this a type?
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
virtual Type *getType(); // is this a type?
virtual char *mangle();
virtual int needThis(); // need a 'this' pointer?
virtual int needThis(); // need a 'this' pointer?
virtual enum PROT prot();
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
virtual int oneMember(Dsymbol **ps);
static int oneMembers(Array *members, Dsymbol **ps);
virtual int hasPointers();
@@ -197,14 +216,14 @@ struct Dsymbol : Object
#if IN_DMD
// Backend
virtual Symbol *toSymbol(); // to backend symbol
virtual void toObjFile(int multiobj); // compile to .obj file
virtual int cvMember(unsigned char *p); // emit cv debug info for member
virtual Symbol *toSymbol(); // to backend symbol
virtual void toObjFile(int multiobj); // compile to .obj file
virtual int cvMember(unsigned char *p); // emit cv debug info for member
Symbol *toImport(); // to backend import symbol
static Symbol *toImport(Symbol *s); // to backend import symbol
Symbol *toImport(); // to backend import symbol
static Symbol *toImport(Symbol *s); // to backend import symbol
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
#endif
// Eliminate need for dynamic_cast
@@ -228,6 +247,8 @@ struct Dsymbol : Object
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
virtual NewDeclaration *isNewDeclaration() { return NULL; }
@@ -268,11 +289,11 @@ struct Dsymbol : Object
struct ScopeDsymbol : Dsymbol
{
Array *members; // all Dsymbol's in this scope
DsymbolTable *symtab; // members[] sorted into table
Dsymbols *members; // all Dsymbol's in this scope
DsymbolTable *symtab; // members[] sorted into table
Array *imports; // imported ScopeDsymbol's
unsigned char *prots; // array of PROT, one for each import
Array *imports; // imported ScopeDsymbol's
unsigned char *prots; // array of PROT, one for each import
ScopeDsymbol();
ScopeDsymbol(Identifier *id);
@@ -285,6 +306,7 @@ struct ScopeDsymbol : Dsymbol
Dsymbol *nameCollision(Dsymbol *s);
const char *kind();
FuncDeclaration *findGetMembers();
virtual Dsymbol *symtabInsert(Dsymbol *s);
void emitMemberComments(Scope *sc);
@@ -310,9 +332,9 @@ struct WithScopeSymbol : ScopeDsymbol
struct ArrayScopeSymbol : ScopeDsymbol
{
Expression *exp; // IndexExp or SliceExp
TypeTuple *type; // for tuple[length]
TupleDeclaration *td; // for tuples of objects
Expression *exp; // IndexExp or SliceExp
TypeTuple *type; // for tuple[length]
TupleDeclaration *td; // for tuples of objects
Scope *sc;
ArrayScopeSymbol(Scope *sc, Expression *e);
@@ -328,7 +350,7 @@ struct ArrayScopeSymbol : ScopeDsymbol
#if DMDV2
struct OverloadSet : Dsymbol
{
Dsymbols a; // array of Dsymbols
Dsymbols a; // array of Dsymbols
OverloadSet();
void push(Dsymbol *s);
@@ -341,7 +363,11 @@ struct OverloadSet : Dsymbol
struct DsymbolTable : Object
{
#if STRINGTABLE
StringTable *tab;
#else
AA *tab;
#endif
DsymbolTable();
~DsymbolTable();
@@ -354,7 +380,7 @@ struct DsymbolTable : Object
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
Dsymbol *update(Dsymbol *s);
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
};
#endif /* DMD_DSYMBOL_H */

View File

@@ -1,144 +1,144 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include "mars.h"
#include "mtype.h"
#include "declaration.h"
#include "expression.h"
#include "template.h"
static void indent(int indent)
{
int i;
for (i = 0; i < indent; i++)
printf(" ");
}
static char *type_print(Type *type)
{
return type ? type->toChars() : (char *) "null";
}
void dumpExpressions(int i, Expressions *exps)
{
for (size_t j = 0; j < exps->dim; j++)
{ Expression *e = (Expression *)exps->data[j];
indent(i);
printf("(\n");
e->dump(i + 2);
indent(i);
printf(")\n");
}
}
void Expression::dump(int i)
{
indent(i);
printf("%p %s type=%s\n", this, Token::toChars(op), type_print(type));
}
void IntegerExp::dump(int i)
{
indent(i);
printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type));
}
void IdentifierExp::dump(int i)
{
indent(i);
printf("%p ident '%s' type=%s\n", this, ident->toChars(), type_print(type));
}
void DsymbolExp::dump(int i)
{
indent(i);
printf("%p %s type=%s\n", this, s->toChars(), type_print(type));
}
void VarExp::dump(int i)
{
indent(i);
printf("%p %s var=%s type=%s\n", this, Token::toChars(op), var->toChars(), type_print(type));
}
void UnaExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
if (e1)
e1->dump(i + 2);
}
void CallExp::dump(int i)
{
UnaExp::dump(i);
dumpExpressions(i, arguments);
}
void SliceExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
if (e1)
e1->dump(i + 2);
if (lwr)
lwr->dump(i + 2);
if (upr)
upr->dump(i + 2);
}
void DotIdExp::dump(int i)
{
indent(i);
printf("%p %s type=%s ident=%s e1=%p\n", this, Token::toChars(op), type_print(type), ident->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DotVarExp::dump(int i)
{
indent(i);
printf("%p %s type=%s var='%s' e1=%p\n", this, Token::toChars(op), type_print(type), var->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DotTemplateInstanceExp::dump(int i)
{
indent(i);
printf("%p %s type=%s ti='%s' e1=%p\n", this, Token::toChars(op), type_print(type), ti->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DelegateExp::dump(int i)
{
indent(i);
printf("%p %s func=%s type=%s e1=%p\n", this, Token::toChars(op), func->toChars(), type_print(type), e1);
if (e1)
e1->dump(i + 2);
}
void BinExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p e2=%p\n", this, Token::toChars(op), type_print(type), e1, e2);
if (e1)
e1->dump(i + 2);
if (e2)
e2->dump(i + 2);
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include "mars.h"
#include "mtype.h"
#include "declaration.h"
#include "expression.h"
#include "template.h"
static void indent(int indent)
{
int i;
for (i = 0; i < indent; i++)
printf(" ");
}
static char *type_print(Type *type)
{
return type ? type->toChars() : (char *) "null";
}
void dumpExpressions(int i, Expressions *exps)
{
for (size_t j = 0; j < exps->dim; j++)
{ Expression *e = (Expression *)exps->data[j];
indent(i);
printf("(\n");
e->dump(i + 2);
indent(i);
printf(")\n");
}
}
void Expression::dump(int i)
{
indent(i);
printf("%p %s type=%s\n", this, Token::toChars(op), type_print(type));
}
void IntegerExp::dump(int i)
{
indent(i);
printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type));
}
void IdentifierExp::dump(int i)
{
indent(i);
printf("%p ident '%s' type=%s\n", this, ident->toChars(), type_print(type));
}
void DsymbolExp::dump(int i)
{
indent(i);
printf("%p %s type=%s\n", this, s->toChars(), type_print(type));
}
void VarExp::dump(int i)
{
indent(i);
printf("%p %s var=%s type=%s\n", this, Token::toChars(op), var->toChars(), type_print(type));
}
void UnaExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
if (e1)
e1->dump(i + 2);
}
void CallExp::dump(int i)
{
UnaExp::dump(i);
dumpExpressions(i, arguments);
}
void SliceExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
if (e1)
e1->dump(i + 2);
if (lwr)
lwr->dump(i + 2);
if (upr)
upr->dump(i + 2);
}
void DotIdExp::dump(int i)
{
indent(i);
printf("%p %s type=%s ident=%s e1=%p\n", this, Token::toChars(op), type_print(type), ident->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DotVarExp::dump(int i)
{
indent(i);
printf("%p %s type=%s var='%s' e1=%p\n", this, Token::toChars(op), type_print(type), var->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DotTemplateInstanceExp::dump(int i)
{
indent(i);
printf("%p %s type=%s ti='%s' e1=%p\n", this, Token::toChars(op), type_print(type), ti->toChars(), e1);
if (e1)
e1->dump(i + 2);
}
void DelegateExp::dump(int i)
{
indent(i);
printf("%p %s func=%s type=%s e1=%p\n", this, Token::toChars(op), func->toChars(), type_print(type), e1);
if (e1)
e1->dump(i + 2);
}
void BinExp::dump(int i)
{
indent(i);
printf("%p %s type=%s e1=%p e2=%p\n", this, Token::toChars(op), type_print(type), e1, e2);
if (e1)
e1->dump(i + 2);
if (e2)
e2->dump(i + 2);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,393 +1,428 @@
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "enum.h"
#include "mtype.h"
#include "scope.h"
#include "id.h"
#include "expression.h"
#include "module.h"
#include "declaration.h"
/********************************* EnumDeclaration ****************************/
EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
: ScopeDsymbol(id)
{
this->loc = loc;
type = new TypeEnum(this);
this->memtype = memtype;
maxval = NULL;
minval = NULL;
defaultval = NULL;
#if IN_DMD
sinit = NULL;
#endif
isdeprecated = 0;
}
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
{
Type *t = NULL;
if (memtype)
t = memtype->syntaxCopy();
EnumDeclaration *ed;
if (s)
{ ed = (EnumDeclaration *)s;
ed->memtype = t;
}
else
ed = new EnumDeclaration(loc, ident, t);
ScopeDsymbol::syntaxCopy(ed);
return ed;
}
void EnumDeclaration::semantic(Scope *sc)
{
Type *t;
Scope *sce;
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars());
//printf("EnumDeclaration::semantic() %s\n", toChars());
if (!members) // enum ident;
return;
if (!memtype && !isAnonymous())
{ // Set memtype if we can to reduce fwd reference errors
memtype = Type::tint32; // case 1) enum ident { ... }
}
if (symtab) // if already done
{ if (!scope)
return; // semantic() already completed
}
else
symtab = new DsymbolTable();
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
if (sc->stc & STCdeprecated)
isdeprecated = 1;
parent = sc->parent;
/* The separate, and distinct, cases are:
* 1. enum { ... }
* 2. enum : memtype { ... }
* 3. enum ident { ... }
* 4. enum ident : memtype { ... }
*/
if (memtype)
{
memtype = memtype->semantic(loc, sc);
/* Check to see if memtype is forward referenced
*/
if (memtype->ty == Tenum)
{ EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc);
if (!sym->memtype || !sym->members || !sym->symtab || sym->scope)
{ // memtype is forward referenced, so try again later
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
printf("\tdeferring %s\n", toChars());
return;
}
}
#if 0 // Decided to abandon this restriction for D 2.0
if (!memtype->isintegral())
{ error("base type must be of integral type, not %s", memtype->toChars());
memtype = Type::tint32;
}
#endif
}
type = type->semantic(loc, sc);
if (isAnonymous())
sce = sc;
else
{ sce = sc->push(this);
sce->parent = this;
}
if (members->dim == 0)
error("enum %s must have at least one member", toChars());
int first = 1;
Expression *elast = NULL;
for (int i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
Expression *e;
if (!em)
/* The e->semantic(sce) can insert other symbols, such as
* template instances and function literals.
*/
continue;
//printf(" Enum member '%s'\n",em->toChars());
if (em->type)
em->type = em->type->semantic(em->loc, sce);
e = em->value;
if (e)
{
assert(e->dyncast() == DYNCAST_EXPRESSION);
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
if (memtype)
{
e = e->implicitCastTo(sce, memtype);
e = e->optimize(WANTvalue | WANTinterpret);
if (!isAnonymous())
e = e->castTo(sce, type);
t = memtype;
}
else if (em->type)
{
e = e->implicitCastTo(sce, em->type);
e = e->optimize(WANTvalue | WANTinterpret);
assert(isAnonymous());
t = e->type;
}
else
t = e->type;
}
else if (first)
{
if (memtype)
t = memtype;
else if (em->type)
t = em->type;
else
t = Type::tint32;
e = new IntegerExp(em->loc, 0, Type::tint32);
e = e->implicitCastTo(sce, t);
e = e->optimize(WANTvalue | WANTinterpret);
if (!isAnonymous())
e = e->castTo(sce, type);
}
else
{
// Set value to (elast + 1).
// But first check that (elast != t.max)
assert(elast);
e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max));
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->toInteger())
error("overflow of enum value %s", elast->toChars());
// Now set e to (elast + 1)
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
e = e->semantic(sce);
e = e->castTo(sce, elast->type);
e = e->optimize(WANTvalue | WANTinterpret);
}
elast = e;
em->value = e;
// Add to symbol table only after evaluating 'value'
if (isAnonymous())
{
/* Anonymous enum members get added to enclosing scope.
*/
for (Scope *scx = sce; scx; scx = scx->enclosing)
{
if (scx->scopesym)
{
if (!scx->scopesym->symtab)
scx->scopesym->symtab = new DsymbolTable();
em->addMember(sce, scx->scopesym, 1);
break;
}
}
}
else
em->addMember(sc, this, 1);
/* Compute .min, .max and .default values.
* If enum doesn't have a name, we can never identify the enum type,
* so there is no purpose for a .min, .max or .default
*/
if (!isAnonymous())
{
if (first)
{ defaultval = e;
minval = e;
maxval = e;
}
else
{ Expression *ec;
/* In order to work successfully with UDTs,
* build expressions to do the comparisons,
* and let the semantic analyzer and constant
* folder give us the result.
*/
// Compute if(e < minval)
ec = new CmpExp(TOKlt, em->loc, e, minval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
if (ec->toInteger())
minval = e;
ec = new CmpExp(TOKgt, em->loc, e, maxval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
if (ec->toInteger())
maxval = e;
}
}
first = 0;
}
//printf("defaultval = %lld\n", defaultval);
//if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars());
if (sc != sce)
sce->pop();
//members->print();
}
int EnumDeclaration::oneMember(Dsymbol **ps)
{
if (isAnonymous())
return Dsymbol::oneMembers(members, ps);
return Dsymbol::oneMember(ps);
}
void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
buf->writestring("enum ");
if (ident)
{ buf->writestring(ident->toChars());
buf->writeByte(' ');
}
if (memtype)
{
buf->writestring(": ");
memtype->toCBuffer(buf, NULL, hgs);
}
if (!members)
{
buf->writeByte(';');
buf->writenl();
return;
}
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
if (!em)
continue;
//buf->writestring(" ");
em->toCBuffer(buf, hgs);
buf->writeByte(',');
buf->writenl();
}
buf->writeByte('}');
buf->writenl();
}
Type *EnumDeclaration::getType()
{
return type;
}
const char *EnumDeclaration::kind()
{
return "enum";
}
int EnumDeclaration::isDeprecated()
{
return isdeprecated;
}
Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars());
if (scope)
// Try one last time to resolve this enum
semantic(scope);
if (!members || !symtab || scope)
{ error("is forward referenced when looking for '%s'", ident->toChars());
//*(char*)0=0;
return NULL;
}
Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
return s;
}
/********************************* EnumMember ****************************/
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type)
: Dsymbol(id)
{
this->value = value;
this->type = type;
this->loc = loc;
}
Dsymbol *EnumMember::syntaxCopy(Dsymbol *s)
{
Expression *e = NULL;
if (value)
e = value->syntaxCopy();
Type *t = NULL;
if (type)
t = type->syntaxCopy();
EnumMember *em;
if (s)
{ em = (EnumMember *)s;
em->loc = loc;
em->value = e;
em->type = t;
}
else
em = new EnumMember(loc, ident, e, t);
return em;
}
void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (type)
type->toCBuffer(buf, ident, hgs);
else
buf->writestring(ident->toChars());
if (value)
{
buf->writestring(" = ");
value->toCBuffer(buf, hgs);
}
}
const char *EnumMember::kind()
{
return "enum member";
}
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "enum.h"
#include "mtype.h"
#include "scope.h"
#include "id.h"
#include "expression.h"
#include "module.h"
#include "declaration.h"
/********************************* EnumDeclaration ****************************/
EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
: ScopeDsymbol(id)
{
this->loc = loc;
type = new TypeEnum(this);
this->memtype = memtype;
maxval = NULL;
minval = NULL;
defaultval = NULL;
#if IN_DMD
sinit = NULL;
#endif
isdeprecated = 0;
isdone = 0;
}
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
{
Type *t = NULL;
if (memtype)
t = memtype->syntaxCopy();
EnumDeclaration *ed;
if (s)
{ ed = (EnumDeclaration *)s;
ed->memtype = t;
}
else
ed = new EnumDeclaration(loc, ident, t);
ScopeDsymbol::syntaxCopy(ed);
return ed;
}
void EnumDeclaration::semantic0(Scope *sc)
{
/* This function is a hack to get around a significant problem.
* The members of anonymous enums, like:
* enum { A, B, C }
* don't get installed into the symbol table until after they are
* semantically analyzed, yet they're supposed to go into the enclosing
* scope's table. Hence, when forward referenced, they come out as
* 'undefined'. The real fix is to add them in at addSymbol() time.
* But to get code to compile, we'll just do this quick hack at the moment
* to compile it if it doesn't depend on anything else.
*/
if (isdone || !scope)
return;
if (!isAnonymous() || memtype)
return;
for (int i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
if (em && (em->type || em->value))
return;
}
// Can do it
semantic(sc);
}
void EnumDeclaration::semantic(Scope *sc)
{
Type *t;
Scope *sce;
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars());
//printf("EnumDeclaration::semantic() %s\n", toChars());
if (!members) // enum ident;
return;
if (!memtype && !isAnonymous())
{ // Set memtype if we can to reduce fwd reference errors
memtype = Type::tint32; // case 1) enum ident { ... }
}
if (symtab) // if already done
{ if (isdone || !scope)
return; // semantic() already completed
}
else
symtab = new DsymbolTable();
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
if (sc->stc & STCdeprecated)
isdeprecated = 1;
parent = sc->parent;
/* The separate, and distinct, cases are:
* 1. enum { ... }
* 2. enum : memtype { ... }
* 3. enum ident { ... }
* 4. enum ident : memtype { ... }
*/
if (memtype)
{
memtype = memtype->semantic(loc, sc);
/* Check to see if memtype is forward referenced
*/
if (memtype->ty == Tenum)
{ EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc);
if (!sym->memtype || !sym->members || !sym->symtab || sym->scope)
{ // memtype is forward referenced, so try again later
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
Module::dprogress = dprogress_save;
//printf("\tdeferring %s\n", toChars());
return;
}
}
#if 0 // Decided to abandon this restriction for D 2.0
if (!memtype->isintegral())
{ error("base type must be of integral type, not %s", memtype->toChars());
memtype = Type::tint32;
}
#endif
}
isdone = 1;
Module::dprogress++;
type = type->semantic(loc, sc);
if (isAnonymous())
sce = sc;
else
{ sce = sc->push(this);
sce->parent = this;
}
if (members->dim == 0)
error("enum %s must have at least one member", toChars());
int first = 1;
Expression *elast = NULL;
for (int i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
Expression *e;
if (!em)
/* The e->semantic(sce) can insert other symbols, such as
* template instances and function literals.
*/
continue;
//printf(" Enum member '%s'\n",em->toChars());
if (em->type)
em->type = em->type->semantic(em->loc, sce);
e = em->value;
if (e)
{
assert(e->dyncast() == DYNCAST_EXPRESSION);
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
if (memtype)
{
e = e->implicitCastTo(sce, memtype);
e = e->optimize(WANTvalue | WANTinterpret);
if (!isAnonymous())
e = e->castTo(sce, type);
t = memtype;
}
else if (em->type)
{
e = e->implicitCastTo(sce, em->type);
e = e->optimize(WANTvalue | WANTinterpret);
assert(isAnonymous());
t = e->type;
}
else
t = e->type;
}
else if (first)
{
if (memtype)
t = memtype;
else if (em->type)
t = em->type;
else
t = Type::tint32;
e = new IntegerExp(em->loc, 0, Type::tint32);
e = e->implicitCastTo(sce, t);
e = e->optimize(WANTvalue | WANTinterpret);
if (!isAnonymous())
e = e->castTo(sce, type);
}
else
{
// Set value to (elast + 1).
// But first check that (elast != t.max)
assert(elast);
e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max));
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->toInteger())
error("overflow of enum value %s", elast->toChars());
// Now set e to (elast + 1)
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
e = e->semantic(sce);
e = e->castTo(sce, elast->type);
e = e->optimize(WANTvalue | WANTinterpret);
}
elast = e;
em->value = e;
// Add to symbol table only after evaluating 'value'
if (isAnonymous())
{
/* Anonymous enum members get added to enclosing scope.
*/
for (Scope *scx = sce; scx; scx = scx->enclosing)
{
if (scx->scopesym)
{
if (!scx->scopesym->symtab)
scx->scopesym->symtab = new DsymbolTable();
em->addMember(sce, scx->scopesym, 1);
break;
}
}
}
else
em->addMember(sc, this, 1);
/* Compute .min, .max and .default values.
* If enum doesn't have a name, we can never identify the enum type,
* so there is no purpose for a .min, .max or .default
*/
if (!isAnonymous())
{
if (first)
{ defaultval = e;
minval = e;
maxval = e;
}
else
{ Expression *ec;
/* In order to work successfully with UDTs,
* build expressions to do the comparisons,
* and let the semantic analyzer and constant
* folder give us the result.
*/
// Compute if(e < minval)
ec = new CmpExp(TOKlt, em->loc, e, minval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
if (ec->toInteger())
minval = e;
ec = new CmpExp(TOKgt, em->loc, e, maxval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
if (ec->toInteger())
maxval = e;
}
}
first = 0;
}
//printf("defaultval = %lld\n", defaultval);
//if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars());
if (sc != sce)
sce->pop();
//members->print();
}
int EnumDeclaration::oneMember(Dsymbol **ps)
{
if (isAnonymous())
return Dsymbol::oneMembers(members, ps);
return Dsymbol::oneMember(ps);
}
void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
buf->writestring("enum ");
if (ident)
{ buf->writestring(ident->toChars());
buf->writeByte(' ');
}
if (memtype)
{
buf->writestring(": ");
memtype->toCBuffer(buf, NULL, hgs);
}
if (!members)
{
buf->writeByte(';');
buf->writenl();
return;
}
buf->writenl();
buf->writeByte('{');
buf->writenl();
for (i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
if (!em)
continue;
//buf->writestring(" ");
em->toCBuffer(buf, hgs);
buf->writeByte(',');
buf->writenl();
}
buf->writeByte('}');
buf->writenl();
}
Type *EnumDeclaration::getType()
{
return type;
}
const char *EnumDeclaration::kind()
{
return "enum";
}
int EnumDeclaration::isDeprecated()
{
return isdeprecated;
}
Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars());
if (scope)
// Try one last time to resolve this enum
semantic(scope);
if (!members || !symtab || scope)
{ error("is forward referenced when looking for '%s'", ident->toChars());
//*(char*)0=0;
return NULL;
}
Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
return s;
}
/********************************* EnumMember ****************************/
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type)
: Dsymbol(id)
{
this->value = value;
this->type = type;
this->loc = loc;
}
Dsymbol *EnumMember::syntaxCopy(Dsymbol *s)
{
Expression *e = NULL;
if (value)
e = value->syntaxCopy();
Type *t = NULL;
if (type)
t = type->syntaxCopy();
EnumMember *em;
if (s)
{ em = (EnumMember *)s;
em->loc = loc;
em->value = e;
em->type = t;
}
else
em = new EnumMember(loc, ident, e, t);
return em;
}
void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (type)
type->toCBuffer(buf, ident, hgs);
else
buf->writestring(ident->toChars());
if (value)
{
buf->writestring(" = ");
value->toCBuffer(buf, hgs);
}
}
const char *EnumMember::kind()
{
return "enum member";
}

View File

@@ -1,94 +1,99 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ENUM_H
#define DMD_ENUM_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct Identifier;
struct Type;
struct Expression;
#ifdef _DH
struct HdrGenState;
#endif
struct EnumDeclaration : ScopeDsymbol
{ /* enum ident : memtype { ... }
*/
Type *type; // the TypeEnum
Type *memtype; // type of the members
#if DMDV1
dinteger_t maxval;
dinteger_t minval;
dinteger_t defaultval; // default initializer
#else
Expression *maxval;
Expression *minval;
Expression *defaultval; // default initializer
#endif
int isdeprecated;
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Type *getType();
const char *kind();
#if DMDV2
Dsymbol *search(Loc, Identifier *ident, int flags);
#endif
int isDeprecated(); // is Dsymbol deprecated?
void emitComment(Scope *sc);
void toDocBuffer(OutBuffer *buf);
EnumDeclaration *isEnumDeclaration() { return this; }
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
int cvMember(unsigned char *p);
Symbol *sinit;
Symbol *toInitializer();
#endif
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct EnumMember : Dsymbol
{
Expression *value;
Type *type;
EnumMember(Loc loc, Identifier *id, Expression *value, Type *type);
Dsymbol *syntaxCopy(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
void emitComment(Scope *sc);
void toDocBuffer(OutBuffer *buf);
EnumMember *isEnumMember() { return this; }
};
#endif /* DMD_ENUM_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_ENUM_H
#define DMD_ENUM_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct Identifier;
struct Type;
struct Expression;
#ifdef _DH
struct HdrGenState;
#endif
struct EnumDeclaration : ScopeDsymbol
{ /* enum ident : memtype { ... }
*/
Type *type; // the TypeEnum
Type *memtype; // type of the members
#if DMDV1
dinteger_t maxval;
dinteger_t minval;
dinteger_t defaultval; // default initializer
#else
Expression *maxval;
Expression *minval;
Expression *defaultval; // default initializer
#endif
int isdeprecated;
int isdone; // 0: not done
// 1: semantic() successfully completed
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic0(Scope *sc);
void semantic(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Type *getType();
const char *kind();
#if DMDV2
Dsymbol *search(Loc, Identifier *ident, int flags);
#endif
int isDeprecated(); // is Dsymbol deprecated?
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
void toDocBuffer(OutBuffer *buf);
EnumDeclaration *isEnumDeclaration() { return this; }
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
int cvMember(unsigned char *p);
Symbol *sinit;
Symbol *toInitializer();
#endif
#if IN_LLVM
void codegen(Ir*);
#endif
};
struct EnumMember : Dsymbol
{
Expression *value;
Type *type;
EnumMember(Loc loc, Identifier *id, Expression *value, Type *type);
Dsymbol *syntaxCopy(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
void toDocBuffer(OutBuffer *buf);
EnumMember *isEnumMember() { return this; }
};
#endif /* DMD_ENUM_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,104 +1,104 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// Initial header generation implementation by Dave Fladebo
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Routines to emit header files
#ifdef _DH
#define PRETTY_PRINT
#define TEST_EMIT_ALL 0 // For Testing
#define LOG 0
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#if __DMC__
#include <complex.h>
#endif
#include "rmem.h"
#include "id.h"
#include "init.h"
#include "attrib.h"
#include "cond.h"
#include "enum.h"
#include "import.h"
#include "module.h"
#include "mtype.h"
#include "scope.h"
#include "staticassert.h"
#include "template.h"
#include "utf.h"
#include "version.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "hdrgen.h"
void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs);
void Module::genhdrfile()
{
OutBuffer hdrbufr;
hdrbufr.printf("// D import file generated from '%s'", srcfile->toChars());
hdrbufr.writenl();
HdrGenState hgs;
memset(&hgs, 0, sizeof(hgs));
hgs.hdrgen = 1;
toCBuffer(&hdrbufr, &hgs);
// Transfer image to file
hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset);
hdrbufr.data = NULL;
char *pt = FileName::path(hdrfile->toChars());
if (*pt)
FileName::ensurePathExists(pt);
mem.free(pt);
hdrfile->writev();
}
void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (md)
{
buf->writestring("module ");
buf->writestring(md->toChars());
buf->writebyte(';');
buf->writenl();
}
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
s->toHBuffer(buf, hgs);
}
}
void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs)
{
toCBuffer(buf, hgs);
}
/*************************************/
#endif // #ifdef _DH
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// Initial header generation implementation by Dave Fladebo
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Routines to emit header files
#ifdef _DH
#define PRETTY_PRINT
#define TEST_EMIT_ALL 0 // For Testing
#define LOG 0
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#if __DMC__
#include <complex.h>
#endif
#include "rmem.h"
#include "id.h"
#include "init.h"
#include "attrib.h"
#include "cond.h"
#include "enum.h"
#include "import.h"
#include "module.h"
#include "mtype.h"
#include "scope.h"
#include "staticassert.h"
#include "template.h"
#include "utf.h"
#include "version.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "hdrgen.h"
void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs);
void Module::genhdrfile()
{
OutBuffer hdrbufr;
hdrbufr.printf("// D import file generated from '%s'", srcfile->toChars());
hdrbufr.writenl();
HdrGenState hgs;
memset(&hgs, 0, sizeof(hgs));
hgs.hdrgen = 1;
toCBuffer(&hdrbufr, &hgs);
// Transfer image to file
hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset);
hdrbufr.data = NULL;
char *pt = FileName::path(hdrfile->toChars());
if (*pt)
FileName::ensurePathExists(pt);
mem.free(pt);
hdrfile->writev();
}
void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (md)
{
buf->writestring("module ");
buf->writestring(md->toChars());
buf->writebyte(';');
buf->writenl();
}
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
s->toHBuffer(buf, hgs);
}
}
void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs)
{
toCBuffer(buf, hgs);
}
/*************************************/
#endif // #ifdef _DH

View File

@@ -1,34 +1,34 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// initial header generation implementation by Dave Fladebo
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
struct HdrGenState
{
int hdrgen; // 1 if generating header file
int ddoc; // 1 if generating Ddoc file
int console; // 1 if writing to console
int tpltMember;
int inCallExp;
int inPtrExp;
int inSlcExp;
int inDotExp;
int inBinExp;
int inArrExp;
int emitInst;
struct
{
int init;
int decl;
} FLinit;
HdrGenState() { memset(this, 0, sizeof(HdrGenState)); }
};
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// initial header generation implementation by Dave Fladebo
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
struct HdrGenState
{
int hdrgen; // 1 if generating header file
int ddoc; // 1 if generating Ddoc file
int console; // 1 if writing to console
int tpltMember;
int inCallExp;
int inPtrExp;
int inSlcExp;
int inDotExp;
int inBinExp;
int inArrExp;
int emitInst;
struct
{
int init;
int decl;
} FLinit;
HdrGenState() { memset(this, 0, sizeof(HdrGenState)); }
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +1,42 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_HTML_H
#define DMD_HTML_H 1
struct OutBuffer;
struct Html
{
const char *sourcename;
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
unsigned linnum; // current line number
OutBuffer *dbuf; // code source buffer
int inCode; // !=0 if in code
Html(const char *sourcename, unsigned char *base, unsigned length);
void error(const char *format, ...) IS_PRINTF(2);
void extractCode(OutBuffer *buf);
void skipTag();
void skipString();
unsigned char *skipWhite(unsigned char *q);
void scanComment();
int isCommentStart();
void scanCDATA();
int isCDATAStart();
int charEntity();
static int namedEntity(unsigned char *p, int length);
};
#endif
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_HTML_H
#define DMD_HTML_H 1
struct OutBuffer;
struct Html
{
const char *sourcename;
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
unsigned linnum; // current line number
OutBuffer *dbuf; // code source buffer
int inCode; // !=0 if in code
Html(const char *sourcename, unsigned char *base, unsigned length);
void error(const char *format, ...) IS_PRINTF(2);
void extractCode(OutBuffer *buf);
void skipTag();
void skipString();
unsigned char *skipWhite(unsigned char *q);
void scanComment();
int isCommentStart();
void scanCDATA();
int isCDATAStart();
int charEntity();
static int namedEntity(unsigned char *p, int length);
};
#endif

473
dmd2/id.c
View File

@@ -1,473 +0,0 @@
// File generated by idgen.c
#include "id.h"
#include "identifier.h"
#include "lexer.h"
Identifier *Id::IUnknown;
Identifier *Id::Object;
Identifier *Id::object;
Identifier *Id::max;
Identifier *Id::min;
Identifier *Id::This;
Identifier *Id::ctor;
Identifier *Id::dtor;
Identifier *Id::cpctor;
Identifier *Id::_postblit;
Identifier *Id::classInvariant;
Identifier *Id::unitTest;
Identifier *Id::init;
Identifier *Id::size;
Identifier *Id::__sizeof;
Identifier *Id::alignof;
Identifier *Id::mangleof;
Identifier *Id::stringof;
Identifier *Id::tupleof;
Identifier *Id::length;
Identifier *Id::remove;
Identifier *Id::ptr;
Identifier *Id::funcptr;
Identifier *Id::dollar;
Identifier *Id::offset;
Identifier *Id::offsetof;
Identifier *Id::ModuleInfo;
Identifier *Id::ClassInfo;
Identifier *Id::classinfo;
Identifier *Id::typeinfo;
Identifier *Id::outer;
Identifier *Id::Exception;
Identifier *Id::Throwable;
Identifier *Id::withSym;
Identifier *Id::result;
Identifier *Id::returnLabel;
Identifier *Id::delegate;
Identifier *Id::line;
Identifier *Id::empty;
Identifier *Id::p;
Identifier *Id::coverage;
Identifier *Id::__vptr;
Identifier *Id::__monitor;
Identifier *Id::system;
Identifier *Id::TypeInfo;
Identifier *Id::TypeInfo_Class;
Identifier *Id::TypeInfo_Interface;
Identifier *Id::TypeInfo_Struct;
Identifier *Id::TypeInfo_Enum;
Identifier *Id::TypeInfo_Typedef;
Identifier *Id::TypeInfo_Pointer;
Identifier *Id::TypeInfo_Array;
Identifier *Id::TypeInfo_StaticArray;
Identifier *Id::TypeInfo_AssociativeArray;
Identifier *Id::TypeInfo_Function;
Identifier *Id::TypeInfo_Delegate;
Identifier *Id::TypeInfo_Tuple;
Identifier *Id::TypeInfo_Const;
Identifier *Id::TypeInfo_Invariant;
Identifier *Id::TypeInfo_Shared;
Identifier *Id::elements;
Identifier *Id::_arguments_typeinfo;
Identifier *Id::_arguments;
Identifier *Id::_argptr;
Identifier *Id::_match;
Identifier *Id::destroy;
Identifier *Id::postblit;
Identifier *Id::LINE;
Identifier *Id::FILE;
Identifier *Id::DATE;
Identifier *Id::TIME;
Identifier *Id::TIMESTAMP;
Identifier *Id::VENDOR;
Identifier *Id::VERSIONX;
Identifier *Id::EOFX;
Identifier *Id::nan;
Identifier *Id::infinity;
Identifier *Id::dig;
Identifier *Id::epsilon;
Identifier *Id::mant_dig;
Identifier *Id::max_10_exp;
Identifier *Id::max_exp;
Identifier *Id::min_10_exp;
Identifier *Id::min_exp;
Identifier *Id::re;
Identifier *Id::im;
Identifier *Id::C;
Identifier *Id::D;
Identifier *Id::Windows;
Identifier *Id::Pascal;
Identifier *Id::System;
Identifier *Id::exit;
Identifier *Id::success;
Identifier *Id::failure;
Identifier *Id::keys;
Identifier *Id::values;
Identifier *Id::rehash;
Identifier *Id::sort;
Identifier *Id::reverse;
Identifier *Id::dup;
Identifier *Id::idup;
Identifier *Id::property;
Identifier *Id::___out;
Identifier *Id::___in;
Identifier *Id::__int;
Identifier *Id::__dollar;
Identifier *Id::__LOCAL_SIZE;
Identifier *Id::uadd;
Identifier *Id::neg;
Identifier *Id::com;
Identifier *Id::add;
Identifier *Id::add_r;
Identifier *Id::sub;
Identifier *Id::sub_r;
Identifier *Id::mul;
Identifier *Id::mul_r;
Identifier *Id::div;
Identifier *Id::div_r;
Identifier *Id::mod;
Identifier *Id::mod_r;
Identifier *Id::eq;
Identifier *Id::cmp;
Identifier *Id::iand;
Identifier *Id::iand_r;
Identifier *Id::ior;
Identifier *Id::ior_r;
Identifier *Id::ixor;
Identifier *Id::ixor_r;
Identifier *Id::shl;
Identifier *Id::shl_r;
Identifier *Id::shr;
Identifier *Id::shr_r;
Identifier *Id::ushr;
Identifier *Id::ushr_r;
Identifier *Id::cat;
Identifier *Id::cat_r;
Identifier *Id::assign;
Identifier *Id::addass;
Identifier *Id::subass;
Identifier *Id::mulass;
Identifier *Id::divass;
Identifier *Id::modass;
Identifier *Id::andass;
Identifier *Id::orass;
Identifier *Id::xorass;
Identifier *Id::shlass;
Identifier *Id::shrass;
Identifier *Id::ushrass;
Identifier *Id::catass;
Identifier *Id::postinc;
Identifier *Id::postdec;
Identifier *Id::index;
Identifier *Id::indexass;
Identifier *Id::slice;
Identifier *Id::sliceass;
Identifier *Id::call;
Identifier *Id::cast;
Identifier *Id::match;
Identifier *Id::next;
Identifier *Id::opIn;
Identifier *Id::opIn_r;
Identifier *Id::opStar;
Identifier *Id::opDot;
Identifier *Id::opImplicitCast;
Identifier *Id::classNew;
Identifier *Id::classDelete;
Identifier *Id::apply;
Identifier *Id::applyReverse;
Identifier *Id::Fempty;
Identifier *Id::Fhead;
Identifier *Id::Ftoe;
Identifier *Id::Fnext;
Identifier *Id::Fretreat;
Identifier *Id::adDup;
Identifier *Id::adReverse;
Identifier *Id::aaLen;
Identifier *Id::aaKeys;
Identifier *Id::aaValues;
Identifier *Id::aaRehash;
Identifier *Id::monitorenter;
Identifier *Id::monitorexit;
Identifier *Id::criticalenter;
Identifier *Id::criticalexit;
Identifier *Id::GNU_asm;
Identifier *Id::lib;
Identifier *Id::msg;
Identifier *Id::startaddress;
Identifier *Id::intrinsic;
Identifier *Id::va_intrinsic;
Identifier *Id::no_typeinfo;
Identifier *Id::no_moduleinfo;
Identifier *Id::Alloca;
Identifier *Id::vastart;
Identifier *Id::vacopy;
Identifier *Id::vaend;
Identifier *Id::vaarg;
Identifier *Id::ldc;
Identifier *Id::allow_inline;
Identifier *Id::llvm_inline_asm;
Identifier *Id::tohash;
Identifier *Id::tostring;
Identifier *Id::getmembers;
Identifier *Id::main;
Identifier *Id::WinMain;
Identifier *Id::DllMain;
Identifier *Id::tls_get_addr;
Identifier *Id::std;
Identifier *Id::math;
Identifier *Id::sin;
Identifier *Id::cos;
Identifier *Id::tan;
Identifier *Id::_sqrt;
Identifier *Id::fabs;
Identifier *Id::isAbstractClass;
Identifier *Id::isArithmetic;
Identifier *Id::isAssociativeArray;
Identifier *Id::isFinalClass;
Identifier *Id::isFloating;
Identifier *Id::isIntegral;
Identifier *Id::isScalar;
Identifier *Id::isStaticArray;
Identifier *Id::isUnsigned;
Identifier *Id::isVirtualFunction;
Identifier *Id::isAbstractFunction;
Identifier *Id::isFinalFunction;
Identifier *Id::hasMember;
Identifier *Id::getMember;
Identifier *Id::getVirtualFunctions;
Identifier *Id::classInstanceSize;
Identifier *Id::allMembers;
Identifier *Id::derivedMembers;
Identifier *Id::isSame;
Identifier *Id::compiles;
void Id::initialize()
{
IUnknown = Lexer::idPool("IUnknown");
Object = Lexer::idPool("Object");
object = Lexer::idPool("object");
max = Lexer::idPool("max");
min = Lexer::idPool("min");
This = Lexer::idPool("this");
ctor = Lexer::idPool("__ctor");
dtor = Lexer::idPool("__dtor");
cpctor = Lexer::idPool("__cpctor");
_postblit = Lexer::idPool("__postblit");
classInvariant = Lexer::idPool("__invariant");
unitTest = Lexer::idPool("__unitTest");
init = Lexer::idPool("init");
size = Lexer::idPool("size");
__sizeof = Lexer::idPool("sizeof");
alignof = Lexer::idPool("alignof");
mangleof = Lexer::idPool("mangleof");
stringof = Lexer::idPool("stringof");
tupleof = Lexer::idPool("tupleof");
length = Lexer::idPool("length");
remove = Lexer::idPool("remove");
ptr = Lexer::idPool("ptr");
funcptr = Lexer::idPool("funcptr");
dollar = Lexer::idPool("__dollar");
offset = Lexer::idPool("offset");
offsetof = Lexer::idPool("offsetof");
ModuleInfo = Lexer::idPool("ModuleInfo");
ClassInfo = Lexer::idPool("ClassInfo");
classinfo = Lexer::idPool("classinfo");
typeinfo = Lexer::idPool("typeinfo");
outer = Lexer::idPool("outer");
Exception = Lexer::idPool("Exception");
Throwable = Lexer::idPool("Throwable");
withSym = Lexer::idPool("__withSym");
result = Lexer::idPool("__result");
returnLabel = Lexer::idPool("__returnLabel");
delegate = Lexer::idPool("delegate");
line = Lexer::idPool("line");
empty = Lexer::idPool("");
p = Lexer::idPool("p");
coverage = Lexer::idPool("__coverage");
__vptr = Lexer::idPool("__vptr");
__monitor = Lexer::idPool("__monitor");
system = Lexer::idPool("system");
TypeInfo = Lexer::idPool("TypeInfo");
TypeInfo_Class = Lexer::idPool("TypeInfo_Class");
TypeInfo_Interface = Lexer::idPool("TypeInfo_Interface");
TypeInfo_Struct = Lexer::idPool("TypeInfo_Struct");
TypeInfo_Enum = Lexer::idPool("TypeInfo_Enum");
TypeInfo_Typedef = Lexer::idPool("TypeInfo_Typedef");
TypeInfo_Pointer = Lexer::idPool("TypeInfo_Pointer");
TypeInfo_Array = Lexer::idPool("TypeInfo_Array");
TypeInfo_StaticArray = Lexer::idPool("TypeInfo_StaticArray");
TypeInfo_AssociativeArray = Lexer::idPool("TypeInfo_AssociativeArray");
TypeInfo_Function = Lexer::idPool("TypeInfo_Function");
TypeInfo_Delegate = Lexer::idPool("TypeInfo_Delegate");
TypeInfo_Tuple = Lexer::idPool("TypeInfo_Tuple");
TypeInfo_Const = Lexer::idPool("TypeInfo_Const");
TypeInfo_Invariant = Lexer::idPool("TypeInfo_Invariant");
TypeInfo_Shared = Lexer::idPool("TypeInfo_Shared");
elements = Lexer::idPool("elements");
_arguments_typeinfo = Lexer::idPool("_arguments_typeinfo");
_arguments = Lexer::idPool("_arguments");
_argptr = Lexer::idPool("_argptr");
_match = Lexer::idPool("_match");
destroy = Lexer::idPool("destroy");
postblit = Lexer::idPool("postblit");
LINE = Lexer::idPool("__LINE__");
FILE = Lexer::idPool("__FILE__");
DATE = Lexer::idPool("__DATE__");
TIME = Lexer::idPool("__TIME__");
TIMESTAMP = Lexer::idPool("__TIMESTAMP__");
VENDOR = Lexer::idPool("__VENDOR__");
VERSIONX = Lexer::idPool("__VERSION__");
EOFX = Lexer::idPool("__EOF__");
nan = Lexer::idPool("nan");
infinity = Lexer::idPool("infinity");
dig = Lexer::idPool("dig");
epsilon = Lexer::idPool("epsilon");
mant_dig = Lexer::idPool("mant_dig");
max_10_exp = Lexer::idPool("max_10_exp");
max_exp = Lexer::idPool("max_exp");
min_10_exp = Lexer::idPool("min_10_exp");
min_exp = Lexer::idPool("min_exp");
re = Lexer::idPool("re");
im = Lexer::idPool("im");
C = Lexer::idPool("C");
D = Lexer::idPool("D");
Windows = Lexer::idPool("Windows");
Pascal = Lexer::idPool("Pascal");
System = Lexer::idPool("System");
exit = Lexer::idPool("exit");
success = Lexer::idPool("success");
failure = Lexer::idPool("failure");
keys = Lexer::idPool("keys");
values = Lexer::idPool("values");
rehash = Lexer::idPool("rehash");
sort = Lexer::idPool("sort");
reverse = Lexer::idPool("reverse");
dup = Lexer::idPool("dup");
idup = Lexer::idPool("idup");
property = Lexer::idPool("property");
___out = Lexer::idPool("out");
___in = Lexer::idPool("in");
__int = Lexer::idPool("int");
__dollar = Lexer::idPool("$");
__LOCAL_SIZE = Lexer::idPool("__LOCAL_SIZE");
uadd = Lexer::idPool("opPos");
neg = Lexer::idPool("opNeg");
com = Lexer::idPool("opCom");
add = Lexer::idPool("opAdd");
add_r = Lexer::idPool("opAdd_r");
sub = Lexer::idPool("opSub");
sub_r = Lexer::idPool("opSub_r");
mul = Lexer::idPool("opMul");
mul_r = Lexer::idPool("opMul_r");
div = Lexer::idPool("opDiv");
div_r = Lexer::idPool("opDiv_r");
mod = Lexer::idPool("opMod");
mod_r = Lexer::idPool("opMod_r");
eq = Lexer::idPool("opEquals");
cmp = Lexer::idPool("opCmp");
iand = Lexer::idPool("opAnd");
iand_r = Lexer::idPool("opAnd_r");
ior = Lexer::idPool("opOr");
ior_r = Lexer::idPool("opOr_r");
ixor = Lexer::idPool("opXor");
ixor_r = Lexer::idPool("opXor_r");
shl = Lexer::idPool("opShl");
shl_r = Lexer::idPool("opShl_r");
shr = Lexer::idPool("opShr");
shr_r = Lexer::idPool("opShr_r");
ushr = Lexer::idPool("opUShr");
ushr_r = Lexer::idPool("opUShr_r");
cat = Lexer::idPool("opCat");
cat_r = Lexer::idPool("opCat_r");
assign = Lexer::idPool("opAssign");
addass = Lexer::idPool("opAddAssign");
subass = Lexer::idPool("opSubAssign");
mulass = Lexer::idPool("opMulAssign");
divass = Lexer::idPool("opDivAssign");
modass = Lexer::idPool("opModAssign");
andass = Lexer::idPool("opAndAssign");
orass = Lexer::idPool("opOrAssign");
xorass = Lexer::idPool("opXorAssign");
shlass = Lexer::idPool("opShlAssign");
shrass = Lexer::idPool("opShrAssign");
ushrass = Lexer::idPool("opUShrAssign");
catass = Lexer::idPool("opCatAssign");
postinc = Lexer::idPool("opPostInc");
postdec = Lexer::idPool("opPostDec");
index = Lexer::idPool("opIndex");
indexass = Lexer::idPool("opIndexAssign");
slice = Lexer::idPool("opSlice");
sliceass = Lexer::idPool("opSliceAssign");
call = Lexer::idPool("opCall");
cast = Lexer::idPool("opCast");
match = Lexer::idPool("opMatch");
next = Lexer::idPool("opNext");
opIn = Lexer::idPool("opIn");
opIn_r = Lexer::idPool("opIn_r");
opStar = Lexer::idPool("opStar");
opDot = Lexer::idPool("opDot");
opImplicitCast = Lexer::idPool("opImplicitCast");
classNew = Lexer::idPool("new");
classDelete = Lexer::idPool("delete");
apply = Lexer::idPool("opApply");
applyReverse = Lexer::idPool("opApplyReverse");
Fempty = Lexer::idPool("empty");
Fhead = Lexer::idPool("front");
Ftoe = Lexer::idPool("back");
Fnext = Lexer::idPool("popFront");
Fretreat = Lexer::idPool("popBack");
adDup = Lexer::idPool("_adDupT");
adReverse = Lexer::idPool("_adReverse");
aaLen = Lexer::idPool("_aaLen");
aaKeys = Lexer::idPool("_aaKeys");
aaValues = Lexer::idPool("_aaValues");
aaRehash = Lexer::idPool("_aaRehash");
monitorenter = Lexer::idPool("_d_monitorenter");
monitorexit = Lexer::idPool("_d_monitorexit");
criticalenter = Lexer::idPool("_d_criticalenter");
criticalexit = Lexer::idPool("_d_criticalexit");
GNU_asm = Lexer::idPool("GNU_asm");
lib = Lexer::idPool("lib");
msg = Lexer::idPool("msg");
startaddress = Lexer::idPool("startaddress");
intrinsic = Lexer::idPool("intrinsic");
va_intrinsic = Lexer::idPool("va_intrinsic");
no_typeinfo = Lexer::idPool("no_typeinfo");
no_moduleinfo = Lexer::idPool("no_moduleinfo");
Alloca = Lexer::idPool("alloca");
vastart = Lexer::idPool("va_start");
vacopy = Lexer::idPool("va_copy");
vaend = Lexer::idPool("va_end");
vaarg = Lexer::idPool("va_arg");
ldc = Lexer::idPool("ldc");
allow_inline = Lexer::idPool("allow_inline");
llvm_inline_asm = Lexer::idPool("llvm_inline_asm");
tohash = Lexer::idPool("toHash");
tostring = Lexer::idPool("toString");
getmembers = Lexer::idPool("getMembers");
main = Lexer::idPool("main");
WinMain = Lexer::idPool("WinMain");
DllMain = Lexer::idPool("DllMain");
tls_get_addr = Lexer::idPool("___tls_get_addr");
std = Lexer::idPool("std");
math = Lexer::idPool("math");
sin = Lexer::idPool("sin");
cos = Lexer::idPool("cos");
tan = Lexer::idPool("tan");
_sqrt = Lexer::idPool("sqrt");
fabs = Lexer::idPool("fabs");
isAbstractClass = Lexer::idPool("isAbstractClass");
isArithmetic = Lexer::idPool("isArithmetic");
isAssociativeArray = Lexer::idPool("isAssociativeArray");
isFinalClass = Lexer::idPool("isFinalClass");
isFloating = Lexer::idPool("isFloating");
isIntegral = Lexer::idPool("isIntegral");
isScalar = Lexer::idPool("isScalar");
isStaticArray = Lexer::idPool("isStaticArray");
isUnsigned = Lexer::idPool("isUnsigned");
isVirtualFunction = Lexer::idPool("isVirtualFunction");
isAbstractFunction = Lexer::idPool("isAbstractFunction");
isFinalFunction = Lexer::idPool("isFinalFunction");
hasMember = Lexer::idPool("hasMember");
getMember = Lexer::idPool("getMember");
getVirtualFunctions = Lexer::idPool("getVirtualFunctions");
classInstanceSize = Lexer::idPool("classInstanceSize");
allMembers = Lexer::idPool("allMembers");
derivedMembers = Lexer::idPool("derivedMembers");
isSame = Lexer::idPool("isSame");
compiles = Lexer::idPool("compiles");
}

242
dmd2/id.h
View File

@@ -1,242 +0,0 @@
// File generated by idgen.c
#ifndef DMD_ID_H
#define DMD_ID_H 1
struct Identifier;
struct Id
{
static Identifier *IUnknown;
static Identifier *Object;
static Identifier *object;
static Identifier *max;
static Identifier *min;
static Identifier *This;
static Identifier *ctor;
static Identifier *dtor;
static Identifier *cpctor;
static Identifier *_postblit;
static Identifier *classInvariant;
static Identifier *unitTest;
static Identifier *init;
static Identifier *size;
static Identifier *__sizeof;
static Identifier *alignof;
static Identifier *mangleof;
static Identifier *stringof;
static Identifier *tupleof;
static Identifier *length;
static Identifier *remove;
static Identifier *ptr;
static Identifier *funcptr;
static Identifier *dollar;
static Identifier *offset;
static Identifier *offsetof;
static Identifier *ModuleInfo;
static Identifier *ClassInfo;
static Identifier *classinfo;
static Identifier *typeinfo;
static Identifier *outer;
static Identifier *Exception;
static Identifier *Throwable;
static Identifier *withSym;
static Identifier *result;
static Identifier *returnLabel;
static Identifier *delegate;
static Identifier *line;
static Identifier *empty;
static Identifier *p;
static Identifier *coverage;
static Identifier *__vptr;
static Identifier *__monitor;
static Identifier *system;
static Identifier *TypeInfo;
static Identifier *TypeInfo_Class;
static Identifier *TypeInfo_Interface;
static Identifier *TypeInfo_Struct;
static Identifier *TypeInfo_Enum;
static Identifier *TypeInfo_Typedef;
static Identifier *TypeInfo_Pointer;
static Identifier *TypeInfo_Array;
static Identifier *TypeInfo_StaticArray;
static Identifier *TypeInfo_AssociativeArray;
static Identifier *TypeInfo_Function;
static Identifier *TypeInfo_Delegate;
static Identifier *TypeInfo_Tuple;
static Identifier *TypeInfo_Const;
static Identifier *TypeInfo_Invariant;
static Identifier *TypeInfo_Shared;
static Identifier *elements;
static Identifier *_arguments_typeinfo;
static Identifier *_arguments;
static Identifier *_argptr;
static Identifier *_match;
static Identifier *destroy;
static Identifier *postblit;
static Identifier *LINE;
static Identifier *FILE;
static Identifier *DATE;
static Identifier *TIME;
static Identifier *TIMESTAMP;
static Identifier *VENDOR;
static Identifier *VERSIONX;
static Identifier *EOFX;
static Identifier *nan;
static Identifier *infinity;
static Identifier *dig;
static Identifier *epsilon;
static Identifier *mant_dig;
static Identifier *max_10_exp;
static Identifier *max_exp;
static Identifier *min_10_exp;
static Identifier *min_exp;
static Identifier *re;
static Identifier *im;
static Identifier *C;
static Identifier *D;
static Identifier *Windows;
static Identifier *Pascal;
static Identifier *System;
static Identifier *exit;
static Identifier *success;
static Identifier *failure;
static Identifier *keys;
static Identifier *values;
static Identifier *rehash;
static Identifier *sort;
static Identifier *reverse;
static Identifier *dup;
static Identifier *idup;
static Identifier *property;
static Identifier *___out;
static Identifier *___in;
static Identifier *__int;
static Identifier *__dollar;
static Identifier *__LOCAL_SIZE;
static Identifier *uadd;
static Identifier *neg;
static Identifier *com;
static Identifier *add;
static Identifier *add_r;
static Identifier *sub;
static Identifier *sub_r;
static Identifier *mul;
static Identifier *mul_r;
static Identifier *div;
static Identifier *div_r;
static Identifier *mod;
static Identifier *mod_r;
static Identifier *eq;
static Identifier *cmp;
static Identifier *iand;
static Identifier *iand_r;
static Identifier *ior;
static Identifier *ior_r;
static Identifier *ixor;
static Identifier *ixor_r;
static Identifier *shl;
static Identifier *shl_r;
static Identifier *shr;
static Identifier *shr_r;
static Identifier *ushr;
static Identifier *ushr_r;
static Identifier *cat;
static Identifier *cat_r;
static Identifier *assign;
static Identifier *addass;
static Identifier *subass;
static Identifier *mulass;
static Identifier *divass;
static Identifier *modass;
static Identifier *andass;
static Identifier *orass;
static Identifier *xorass;
static Identifier *shlass;
static Identifier *shrass;
static Identifier *ushrass;
static Identifier *catass;
static Identifier *postinc;
static Identifier *postdec;
static Identifier *index;
static Identifier *indexass;
static Identifier *slice;
static Identifier *sliceass;
static Identifier *call;
static Identifier *cast;
static Identifier *match;
static Identifier *next;
static Identifier *opIn;
static Identifier *opIn_r;
static Identifier *opStar;
static Identifier *opDot;
static Identifier *opImplicitCast;
static Identifier *classNew;
static Identifier *classDelete;
static Identifier *apply;
static Identifier *applyReverse;
static Identifier *Fempty;
static Identifier *Fhead;
static Identifier *Ftoe;
static Identifier *Fnext;
static Identifier *Fretreat;
static Identifier *adDup;
static Identifier *adReverse;
static Identifier *aaLen;
static Identifier *aaKeys;
static Identifier *aaValues;
static Identifier *aaRehash;
static Identifier *monitorenter;
static Identifier *monitorexit;
static Identifier *criticalenter;
static Identifier *criticalexit;
static Identifier *GNU_asm;
static Identifier *lib;
static Identifier *msg;
static Identifier *startaddress;
static Identifier *intrinsic;
static Identifier *va_intrinsic;
static Identifier *no_typeinfo;
static Identifier *no_moduleinfo;
static Identifier *Alloca;
static Identifier *vastart;
static Identifier *vacopy;
static Identifier *vaend;
static Identifier *vaarg;
static Identifier *ldc;
static Identifier *allow_inline;
static Identifier *llvm_inline_asm;
static Identifier *tohash;
static Identifier *tostring;
static Identifier *getmembers;
static Identifier *main;
static Identifier *WinMain;
static Identifier *DllMain;
static Identifier *tls_get_addr;
static Identifier *std;
static Identifier *math;
static Identifier *sin;
static Identifier *cos;
static Identifier *tan;
static Identifier *_sqrt;
static Identifier *fabs;
static Identifier *isAbstractClass;
static Identifier *isArithmetic;
static Identifier *isAssociativeArray;
static Identifier *isFinalClass;
static Identifier *isFloating;
static Identifier *isIntegral;
static Identifier *isScalar;
static Identifier *isStaticArray;
static Identifier *isUnsigned;
static Identifier *isVirtualFunction;
static Identifier *isAbstractFunction;
static Identifier *isFinalFunction;
static Identifier *hasMember;
static Identifier *getMember;
static Identifier *getVirtualFunctions;
static Identifier *classInstanceSize;
static Identifier *allMembers;
static Identifier *derivedMembers;
static Identifier *isSame;
static Identifier *compiles;
static void initialize();
};
#endif

View File

@@ -1,102 +1,102 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include "root.h"
#include "identifier.h"
#include "mars.h"
#include "lexer.h"
#include "id.h"
Identifier::Identifier(const char *string, int value)
{
//printf("Identifier('%s', %d)\n", string, value);
this->string = string;
this->value = value;
this->len = strlen(string);
}
hash_t Identifier::hashCode()
{
return String::calcHash(string);
}
int Identifier::equals(Object *o)
{
return this == o || memcmp(string,o->toChars(),len+1) == 0;
}
int Identifier::compare(Object *o)
{
return memcmp(string, o->toChars(), len + 1);
}
char *Identifier::toChars()
{
return (char *)string;
}
const char *Identifier::toHChars2()
{
const char *p = NULL;
if (this == Id::ctor) p = "this";
else if (this == Id::dtor) p = "~this";
else if (this == Id::classInvariant) p = "invariant";
else if (this == Id::unitTest) p = "unittest";
else if (this == Id::dollar) p = "$";
else if (this == Id::withSym) p = "with";
else if (this == Id::result) p = "result";
else if (this == Id::returnLabel) p = "return";
else
{ p = toChars();
if (*p == '_')
{
if (memcmp(p, "_staticCtor", 11) == 0)
p = "static this";
else if (memcmp(p, "_staticDtor", 11) == 0)
p = "static ~this";
}
}
return p;
}
void Identifier::print()
{
fprintf(stdmsg, "%s",string);
}
int Identifier::dyncast()
{
return DYNCAST_IDENTIFIER;
}
// BUG: these are redundant with Lexer::uniqueId()
Identifier *Identifier::generateId(const char *prefix)
{
static size_t i;
return generateId(prefix, ++i);
}
Identifier *Identifier::generateId(const char *prefix, size_t i)
{ OutBuffer buf;
buf.writestring(prefix);
buf.printf("%zu", i);
char *id = buf.toChars();
buf.data = NULL;
return Lexer::idPool(id);
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include "root.h"
#include "identifier.h"
#include "mars.h"
#include "lexer.h"
#include "id.h"
Identifier::Identifier(const char *string, int value)
{
//printf("Identifier('%s', %d)\n", string, value);
this->string = string;
this->value = value;
this->len = strlen(string);
}
hash_t Identifier::hashCode()
{
return String::calcHash(string);
}
int Identifier::equals(Object *o)
{
return this == o || memcmp(string,o->toChars(),len+1) == 0;
}
int Identifier::compare(Object *o)
{
return memcmp(string, o->toChars(), len + 1);
}
char *Identifier::toChars()
{
return (char *)string;
}
const char *Identifier::toHChars2()
{
const char *p = NULL;
if (this == Id::ctor) p = "this";
else if (this == Id::dtor) p = "~this";
else if (this == Id::classInvariant) p = "invariant";
else if (this == Id::unitTest) p = "unittest";
else if (this == Id::dollar) p = "$";
else if (this == Id::withSym) p = "with";
else if (this == Id::result) p = "result";
else if (this == Id::returnLabel) p = "return";
else
{ p = toChars();
if (*p == '_')
{
if (memcmp(p, "_staticCtor", 11) == 0)
p = "static this";
else if (memcmp(p, "_staticDtor", 11) == 0)
p = "static ~this";
}
}
return p;
}
void Identifier::print()
{
fprintf(stdmsg, "%s",string);
}
int Identifier::dyncast()
{
return DYNCAST_IDENTIFIER;
}
// BUG: these are redundant with Lexer::uniqueId()
Identifier *Identifier::generateId(const char *prefix)
{
static size_t i;
return generateId(prefix, ++i);
}
Identifier *Identifier::generateId(const char *prefix, size_t i)
{ OutBuffer buf;
buf.writestring(prefix);
buf.printf("%zu", i);
char *id = buf.toChars();
buf.data = NULL;
return Lexer::idPool(id);
}

View File

@@ -1,385 +1,412 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Program to generate string files in d data structures.
// Saves much tedious typing, and eliminates typo problems.
// Generates:
// id.h
// id.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
struct Msgtable
{
const char *ident; // name to use in DMD source
const char *name; // name in D executable
};
Msgtable msgtable[] =
{
{ "IUnknown" },
{ "Object" },
{ "object" },
{ "max" },
{ "min" },
{ "This", "this" },
{ "ctor", "__ctor" },
{ "dtor", "__dtor" },
{ "cpctor", "__cpctor" },
{ "_postblit", "__postblit" },
{ "classInvariant", "__invariant" },
{ "unitTest", "__unitTest" },
{ "init" },
{ "size" },
{ "__sizeof", "sizeof" },
{ "alignof" },
{ "mangleof" },
{ "stringof" },
{ "tupleof" },
{ "length" },
{ "remove" },
{ "ptr" },
{ "funcptr" },
{ "dollar", "__dollar" },
{ "offset" },
{ "offsetof" },
{ "ModuleInfo" },
{ "ClassInfo" },
{ "classinfo" },
{ "typeinfo" },
{ "outer" },
{ "Exception" },
{ "Throwable" },
{ "withSym", "__withSym" },
{ "result", "__result" },
{ "returnLabel", "__returnLabel" },
{ "delegate" },
{ "line" },
{ "empty", "" },
{ "p" },
{ "coverage", "__coverage" },
{ "__vptr" },
{ "__monitor" },
{ "system" },
{ "TypeInfo" },
{ "TypeInfo_Class" },
{ "TypeInfo_Interface" },
{ "TypeInfo_Struct" },
{ "TypeInfo_Enum" },
{ "TypeInfo_Typedef" },
{ "TypeInfo_Pointer" },
{ "TypeInfo_Array" },
{ "TypeInfo_StaticArray" },
{ "TypeInfo_AssociativeArray" },
{ "TypeInfo_Function" },
{ "TypeInfo_Delegate" },
{ "TypeInfo_Tuple" },
{ "TypeInfo_Const" },
{ "TypeInfo_Invariant" },
{ "TypeInfo_Shared" },
{ "elements" },
{ "_arguments_typeinfo" },
{ "_arguments" },
{ "_argptr" },
{ "_match" },
{ "destroy" },
{ "postblit" },
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
{ "DATE", "__DATE__" },
{ "TIME", "__TIME__" },
{ "TIMESTAMP", "__TIMESTAMP__" },
{ "VENDOR", "__VENDOR__" },
{ "VERSIONX", "__VERSION__" },
{ "EOFX", "__EOF__" },
{ "nan" },
{ "infinity" },
{ "dig" },
{ "epsilon" },
{ "mant_dig" },
{ "max_10_exp" },
{ "max_exp" },
{ "min_10_exp" },
{ "min_exp" },
{ "re" },
{ "im" },
{ "C" },
{ "D" },
{ "Windows" },
{ "Pascal" },
{ "System" },
{ "exit" },
{ "success" },
{ "failure" },
{ "keys" },
{ "values" },
{ "rehash" },
{ "sort" },
{ "reverse" },
{ "dup" },
{ "idup" },
{ "property" },
// For inline assembler
{ "___out", "out" },
{ "___in", "in" },
{ "__int", "int" },
{ "__dollar", "$" },
{ "__LOCAL_SIZE" },
// For operator overloads
{ "uadd", "opPos" },
{ "neg", "opNeg" },
{ "com", "opCom" },
{ "add", "opAdd" },
{ "add_r", "opAdd_r" },
{ "sub", "opSub" },
{ "sub_r", "opSub_r" },
{ "mul", "opMul" },
{ "mul_r", "opMul_r" },
{ "div", "opDiv" },
{ "div_r", "opDiv_r" },
{ "mod", "opMod" },
{ "mod_r", "opMod_r" },
{ "eq", "opEquals" },
{ "cmp", "opCmp" },
{ "iand", "opAnd" },
{ "iand_r", "opAnd_r" },
{ "ior", "opOr" },
{ "ior_r", "opOr_r" },
{ "ixor", "opXor" },
{ "ixor_r", "opXor_r" },
{ "shl", "opShl" },
{ "shl_r", "opShl_r" },
{ "shr", "opShr" },
{ "shr_r", "opShr_r" },
{ "ushr", "opUShr" },
{ "ushr_r", "opUShr_r" },
{ "cat", "opCat" },
{ "cat_r", "opCat_r" },
{ "assign", "opAssign" },
{ "addass", "opAddAssign" },
{ "subass", "opSubAssign" },
{ "mulass", "opMulAssign" },
{ "divass", "opDivAssign" },
{ "modass", "opModAssign" },
{ "andass", "opAndAssign" },
{ "orass", "opOrAssign" },
{ "xorass", "opXorAssign" },
{ "shlass", "opShlAssign" },
{ "shrass", "opShrAssign" },
{ "ushrass", "opUShrAssign" },
{ "catass", "opCatAssign" },
{ "postinc", "opPostInc" },
{ "postdec", "opPostDec" },
{ "index", "opIndex" },
{ "indexass", "opIndexAssign" },
{ "slice", "opSlice" },
{ "sliceass", "opSliceAssign" },
{ "call", "opCall" },
{ "cast", "opCast" },
{ "match", "opMatch" },
{ "next", "opNext" },
{ "opIn" },
{ "opIn_r" },
{ "opStar" },
{ "opDot" },
{ "opImplicitCast" },
{ "classNew", "new" },
{ "classDelete", "delete" },
// For foreach
{ "apply", "opApply" },
{ "applyReverse", "opApplyReverse" },
#if 1
{ "Fempty", "empty" },
{ "Fhead", "front" },
{ "Ftoe", "back" },
{ "Fnext", "popFront" },
{ "Fretreat", "popBack" },
#else
{ "Fempty", "empty" },
{ "Fhead", "head" },
{ "Ftoe", "toe" },
{ "Fnext", "next" },
{ "Fretreat", "retreat" },
#endif
{ "adDup", "_adDupT" },
{ "adReverse", "_adReverse" },
// For internal functions
{ "aaLen", "_aaLen" },
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
{ "monitorenter", "_d_monitorenter" },
{ "monitorexit", "_d_monitorexit" },
{ "criticalenter", "_d_criticalenter" },
{ "criticalexit", "_d_criticalexit" },
// For pragma's
{ "GNU_asm" },
{ "lib" },
{ "msg" },
{ "startaddress" },
#if IN_LLVM
// LDC pragma's
{ "intrinsic" },
{ "va_intrinsic" },
{ "no_typeinfo" },
{ "no_moduleinfo" },
{ "Alloca", "alloca" },
{ "vastart", "va_start" },
{ "vacopy", "va_copy" },
{ "vaend", "va_end" },
{ "vaarg", "va_arg" },
{ "ldc" },
{ "allow_inline" },
{ "llvm_inline_asm" },
#endif
// For special functions
{ "tohash", "toHash" },
{ "tostring", "toString" },
{ "getmembers", "getMembers" },
// Special functions
#if IN_DMD
{ "alloca" },
#endif
{ "main" },
{ "WinMain" },
{ "DllMain" },
{ "tls_get_addr", "___tls_get_addr" },
// Builtin functions
{ "std" },
{ "math" },
{ "sin" },
{ "cos" },
{ "tan" },
{ "_sqrt", "sqrt" },
{ "fabs" },
// Traits
{ "isAbstractClass" },
{ "isArithmetic" },
{ "isAssociativeArray" },
{ "isFinalClass" },
{ "isFloating" },
{ "isIntegral" },
{ "isScalar" },
{ "isStaticArray" },
{ "isUnsigned" },
{ "isVirtualFunction" },
{ "isAbstractFunction" },
{ "isFinalFunction" },
{ "hasMember" },
{ "getMember" },
{ "getVirtualFunctions" },
{ "classInstanceSize" },
{ "allMembers" },
{ "derivedMembers" },
{ "isSame" },
{ "compiles" },
};
int main()
{
FILE *fp;
unsigned i;
{
fp = fopen("id.h","w");
if (!fp)
{ printf("can't open id.h\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
#if __DMC__
fprintf(fp, "#pragma once\n");
#endif
fprintf(fp, "#ifndef DMD_ID_H\n");
fprintf(fp, "#define DMD_ID_H 1\n");
fprintf(fp, "struct Identifier;\n");
fprintf(fp, "struct Id\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
fprintf(fp," static Identifier *%s;\n", id);
}
fprintf(fp, " static void initialize();\n");
fprintf(fp, "};\n");
fprintf(fp, "#endif\n");
fclose(fp);
}
{
fp = fopen("id.c","w");
if (!fp)
{ printf("can't open id.c\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
fprintf(fp, "#include \"id.h\"\n");
fprintf(fp, "#include \"identifier.h\"\n");
fprintf(fp, "#include \"lexer.h\"\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
const char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp,"Identifier *Id::%s;\n", id);
}
fprintf(fp, "void Id::initialize()\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
const char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp," %s = Lexer::idPool(\"%s\");\n", id, p);
}
fprintf(fp, "}\n");
fclose(fp);
}
return EXIT_SUCCESS;
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Program to generate string files in d data structures.
// Saves much tedious typing, and eliminates typo problems.
// Generates:
// id.h
// id.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
struct Msgtable
{
const char *ident; // name to use in DMD source
const char *name; // name in D executable
};
Msgtable msgtable[] =
{
{ "IUnknown" },
{ "Object" },
{ "object" },
{ "max" },
{ "min" },
{ "This", "this" },
{ "ctor", "__ctor" },
{ "dtor", "__dtor" },
{ "cpctor", "__cpctor" },
{ "_postblit", "__postblit" },
{ "classInvariant", "__invariant" },
{ "unitTest", "__unitTest" },
{ "require", "__require" },
{ "ensure", "__ensure" },
{ "init" },
{ "size" },
{ "__sizeof", "sizeof" },
{ "__xalignof", "alignof" },
{ "mangleof" },
{ "stringof" },
{ "tupleof" },
{ "length" },
{ "remove" },
{ "ptr" },
{ "funcptr" },
{ "dollar", "__dollar" },
{ "ctfe", "__ctfe" },
{ "offset" },
{ "offsetof" },
{ "ModuleInfo" },
{ "ClassInfo" },
{ "classinfo" },
{ "typeinfo" },
{ "outer" },
{ "Exception" },
{ "AssociativeArray" },
{ "Throwable" },
{ "withSym", "__withSym" },
{ "result", "__result" },
{ "returnLabel", "__returnLabel" },
{ "delegate" },
{ "line" },
{ "empty", "" },
{ "p" },
{ "coverage", "__coverage" },
{ "__vptr" },
{ "__monitor" },
{ "TypeInfo" },
{ "TypeInfo_Class" },
{ "TypeInfo_Interface" },
{ "TypeInfo_Struct" },
{ "TypeInfo_Enum" },
{ "TypeInfo_Typedef" },
{ "TypeInfo_Pointer" },
{ "TypeInfo_Array" },
{ "TypeInfo_StaticArray" },
{ "TypeInfo_AssociativeArray" },
{ "TypeInfo_Function" },
{ "TypeInfo_Delegate" },
{ "TypeInfo_Tuple" },
{ "TypeInfo_Const" },
{ "TypeInfo_Invariant" },
{ "TypeInfo_Shared" },
{ "TypeInfo_Wild", "TypeInfo_Inout" },
{ "elements" },
{ "_arguments_typeinfo" },
{ "_arguments" },
{ "_argptr" },
{ "_match" },
{ "destroy" },
{ "postblit" },
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
{ "DATE", "__DATE__" },
{ "TIME", "__TIME__" },
{ "TIMESTAMP", "__TIMESTAMP__" },
{ "VENDOR", "__VENDOR__" },
{ "VERSIONX", "__VERSION__" },
{ "EOFX", "__EOF__" },
{ "nan" },
{ "infinity" },
{ "dig" },
{ "epsilon" },
{ "mant_dig" },
{ "max_10_exp" },
{ "max_exp" },
{ "min_10_exp" },
{ "min_exp" },
{ "min_normal" },
{ "re" },
{ "im" },
{ "C" },
{ "D" },
{ "Windows" },
{ "Pascal" },
{ "System" },
{ "exit" },
{ "success" },
{ "failure" },
{ "keys" },
{ "values" },
{ "rehash" },
{ "sort" },
{ "reverse" },
{ "dup" },
{ "idup" },
{ "property" },
{ "safe" },
{ "trusted" },
{ "system" },
{ "disable" },
// For inline assembler
{ "___out", "out" },
{ "___in", "in" },
{ "__int", "int" },
{ "__dollar", "$" },
{ "__LOCAL_SIZE" },
// For operator overloads
{ "uadd", "opPos" },
{ "neg", "opNeg" },
{ "com", "opCom" },
{ "add", "opAdd" },
{ "add_r", "opAdd_r" },
{ "sub", "opSub" },
{ "sub_r", "opSub_r" },
{ "mul", "opMul" },
{ "mul_r", "opMul_r" },
{ "div", "opDiv" },
{ "div_r", "opDiv_r" },
{ "mod", "opMod" },
{ "mod_r", "opMod_r" },
{ "eq", "opEquals" },
{ "cmp", "opCmp" },
{ "iand", "opAnd" },
{ "iand_r", "opAnd_r" },
{ "ior", "opOr" },
{ "ior_r", "opOr_r" },
{ "ixor", "opXor" },
{ "ixor_r", "opXor_r" },
{ "shl", "opShl" },
{ "shl_r", "opShl_r" },
{ "shr", "opShr" },
{ "shr_r", "opShr_r" },
{ "ushr", "opUShr" },
{ "ushr_r", "opUShr_r" },
{ "cat", "opCat" },
{ "cat_r", "opCat_r" },
{ "assign", "opAssign" },
{ "addass", "opAddAssign" },
{ "subass", "opSubAssign" },
{ "mulass", "opMulAssign" },
{ "divass", "opDivAssign" },
{ "modass", "opModAssign" },
{ "andass", "opAndAssign" },
{ "orass", "opOrAssign" },
{ "xorass", "opXorAssign" },
{ "shlass", "opShlAssign" },
{ "shrass", "opShrAssign" },
{ "ushrass", "opUShrAssign" },
{ "catass", "opCatAssign" },
{ "postinc", "opPostInc" },
{ "postdec", "opPostDec" },
{ "index", "opIndex" },
{ "indexass", "opIndexAssign" },
{ "slice", "opSlice" },
{ "sliceass", "opSliceAssign" },
{ "call", "opCall" },
{ "cast", "opCast" },
{ "match", "opMatch" },
{ "next", "opNext" },
{ "opIn" },
{ "opIn_r" },
{ "opStar" },
{ "opDot" },
{ "opDispatch" },
{ "opUnary" },
{ "opIndexUnary" },
{ "opSliceUnary" },
{ "opBinary" },
{ "opBinaryRight" },
{ "opOpAssign" },
{ "opIndexOpAssign" },
{ "opSliceOpAssign" },
{ "pow", "opPow" },
{ "pow_r", "opPow_r" },
{ "powass", "opPowAssign" },
{ "classNew", "new" },
{ "classDelete", "delete" },
// For foreach
{ "apply", "opApply" },
{ "applyReverse", "opApplyReverse" },
#if 1
{ "Fempty", "empty" },
{ "Fhead", "front" },
{ "Ftoe", "back" },
{ "Fnext", "popFront" },
{ "Fretreat", "popBack" },
#else
{ "Fempty", "empty" },
{ "Fhead", "head" },
{ "Ftoe", "toe" },
{ "Fnext", "next" },
{ "Fretreat", "retreat" },
#endif
{ "adDup", "_adDupT" },
{ "adReverse", "_adReverse" },
// For internal functions
{ "aaLen", "_aaLen" },
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
{ "monitorenter", "_d_monitorenter" },
{ "monitorexit", "_d_monitorexit" },
{ "criticalenter", "_d_criticalenter" },
{ "criticalexit", "_d_criticalexit" },
{ "_ArrayEq" },
// For pragma's
{ "GNU_asm" },
{ "lib" },
{ "msg" },
{ "startaddress" },
#if IN_LLVM
// LDC pragma's
{ "intrinsic" },
{ "va_intrinsic" },
{ "no_typeinfo" },
{ "no_moduleinfo" },
{ "Alloca", "alloca" },
{ "vastart", "va_start" },
{ "vacopy", "va_copy" },
{ "vaend", "va_end" },
{ "vaarg", "va_arg" },
{ "ldc" },
{ "allow_inline" },
{ "llvm_inline_asm" },
#endif
// For special functions
{ "tohash", "toHash" },
{ "tostring", "toString" },
{ "getmembers", "getMembers" },
// Special functions
#if IN_DMD
{ "alloca" },
#endif
{ "main" },
{ "WinMain" },
{ "DllMain" },
{ "tls_get_addr", "___tls_get_addr" },
// Builtin functions
{ "std" },
{ "math" },
{ "sin" },
{ "cos" },
{ "tan" },
{ "_sqrt", "sqrt" },
{ "_pow", "pow" },
{ "fabs" },
// Traits
{ "isAbstractClass" },
{ "isArithmetic" },
{ "isAssociativeArray" },
{ "isFinalClass" },
{ "isFloating" },
{ "isIntegral" },
{ "isScalar" },
{ "isStaticArray" },
{ "isUnsigned" },
{ "isVirtualFunction" },
{ "isAbstractFunction" },
{ "isFinalFunction" },
{ "isStaticFunction" },
{ "isRef" },
{ "isOut" },
{ "isLazy" },
{ "hasMember" },
{ "identifier" },
{ "getMember" },
{ "getOverloads" },
{ "getVirtualFunctions" },
{ "classInstanceSize" },
{ "allMembers" },
{ "derivedMembers" },
{ "isSame" },
{ "compiles" },
};
int main()
{
FILE *fp;
unsigned i;
{
fp = fopen("id.h","w");
if (!fp)
{ printf("can't open id.h\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
#if __DMC__
fprintf(fp, "#pragma once\n");
#endif
fprintf(fp, "#ifndef DMD_ID_H\n");
fprintf(fp, "#define DMD_ID_H 1\n");
fprintf(fp, "struct Identifier;\n");
fprintf(fp, "struct Id\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
fprintf(fp," static Identifier *%s;\n", id);
}
fprintf(fp, " static void initialize();\n");
fprintf(fp, "};\n");
fprintf(fp, "#endif\n");
fclose(fp);
}
{
fp = fopen("id.c","w");
if (!fp)
{ printf("can't open id.c\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
fprintf(fp, "#include \"id.h\"\n");
fprintf(fp, "#include \"identifier.h\"\n");
fprintf(fp, "#include \"lexer.h\"\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
const char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp,"Identifier *Id::%s;\n", id);
}
fprintf(fp, "void Id::initialize()\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ const char *id = msgtable[i].ident;
const char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp," %s = Lexer::idPool(\"%s\");\n", id, p);
}
fprintf(fp, "}\n");
fclose(fp);
}
return EXIT_SUCCESS;
}

View File

@@ -1,462 +1,462 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include "mtype.h"
TY impcnvResult[TMAX][TMAX];
TY impcnvType1[TMAX][TMAX];
TY impcnvType2[TMAX][TMAX];
int impcnvWarn[TMAX][TMAX];
int integral_promotion(int t)
{
switch (t)
{
case Tchar:
case Twchar:
//case Tbit:
case Tbool:
case Tint8:
case Tuns8:
case Tint16:
case Tuns16: return Tint32;
case Tdchar: return Tuns32;
default: return t;
}
}
void init()
{ int i, j;
// Set conversion tables
for (i = 0; i < TMAX; i++)
for (j = 0; j < TMAX; j++)
{ impcnvResult[i][j] = Terror;
impcnvType1[i][j] = Terror;
impcnvType2[i][j] = Terror;
impcnvWarn[i][j] = 0;
}
#define X(t1,t2, nt1,nt2, rt) \
impcnvResult[t1][t2] = rt; \
impcnvType1[t1][t2] = nt1; \
impcnvType2[t1][t2] = nt2;
/* ======================= */
#if 0
X(Tbit,Tbit, Tint32,Tint32, Tint32)
X(Tbit,Tint8, Tint32,Tint32, Tint32)
X(Tbit,Tuns8, Tint32,Tint32, Tint32)
X(Tbit,Tint16, Tint32,Tint32, Tint32)
X(Tbit,Tuns16, Tint32,Tint32, Tint32)
X(Tbit,Tint32, Tint32,Tint32, Tint32)
X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tbit,Tint64, Tint64,Tint64, Tint64)
X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tbit,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tbit,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tbit,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tbit,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tbit,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tbit,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tbit,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
#endif
/* ======================= */
X(Tbool,Tbool, Tbool,Tbool, Tbool)
X(Tbool,Tint8, Tint32,Tint32, Tint32)
X(Tbool,Tuns8, Tint32,Tint32, Tint32)
X(Tbool,Tint16, Tint32,Tint32, Tint32)
X(Tbool,Tuns16, Tint32,Tint32, Tint32)
X(Tbool,Tint32, Tint32,Tint32, Tint32)
X(Tbool,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tbool,Tint64, Tint64,Tint64, Tint64)
X(Tbool,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tbool,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tbool,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tbool,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tbool,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tbool,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tbool,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tbool,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tbool,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tbool,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint8,Tint8, Tint32,Tint32, Tint32)
X(Tint8,Tuns8, Tint32,Tint32, Tint32)
X(Tint8,Tint16, Tint32,Tint32, Tint32)
X(Tint8,Tuns16, Tint32,Tint32, Tint32)
X(Tint8,Tint32, Tint32,Tint32, Tint32)
X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint8,Tint64, Tint64,Tint64, Tint64)
X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns8,Tuns8, Tint32,Tint32, Tint32)
X(Tuns8,Tint16, Tint32,Tint32, Tint32)
X(Tuns8,Tuns16, Tint32,Tint32, Tint32)
X(Tuns8,Tint32, Tint32,Tint32, Tint32)
X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns8,Tint64, Tint64,Tint64, Tint64)
X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint16,Tint16, Tint32,Tint32, Tint32)
X(Tint16,Tuns16, Tint32,Tint32, Tint32)
X(Tint16,Tint32, Tint32,Tint32, Tint32)
X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint16,Tint64, Tint64,Tint64, Tint64)
X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns16,Tuns16, Tint32,Tint32, Tint32)
X(Tuns16,Tint32, Tint32,Tint32, Tint32)
X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns16,Tint64, Tint64,Tint64, Tint64)
X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint32,Tint32, Tint32,Tint32, Tint32)
X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint32,Tint64, Tint64,Tint64, Tint64)
X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns32,Tint64, Tint64,Tint64, Tint64)
X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint64,Tint64, Tint64,Tint64, Tint64)
X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tfloat32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tfloat32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat64,Timaginary32, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat64,Tcomplex32, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Timaginary64, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Tcomplex32, Tfloat80,Tcomplex80, Tcomplex80)
X(Tfloat80,Tcomplex64, Tfloat80,Tcomplex80, Tcomplex80)
X(Tfloat80,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32)
X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary32,Tcomplex32, Timaginary32,Tcomplex32, Tcomplex32)
X(Timaginary32,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary32,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary64,Tcomplex32, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary64,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary64,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80)
X(Timaginary80,Tcomplex64, Timaginary80,Tcomplex80, Tcomplex80)
X(Timaginary80,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32)
X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
#undef X
#define Y(t1,t2) impcnvWarn[t1][t2] = 1;
#if 0
Y(Tint8, Tbit)
Y(Tuns8, Tbit)
Y(Tint16, Tbit)
Y(Tuns16, Tbit)
Y(Tint32, Tbit)
Y(Tuns32, Tbit)
Y(Tint64, Tbit)
Y(Tuns64, Tbit)
#endif
Y(Tuns8, Tint8)
Y(Tint16, Tint8)
Y(Tuns16, Tint8)
Y(Tint32, Tint8)
Y(Tuns32, Tint8)
Y(Tint64, Tint8)
Y(Tuns64, Tint8)
Y(Tint8, Tuns8)
Y(Tint16, Tuns8)
Y(Tuns16, Tuns8)
Y(Tint32, Tuns8)
Y(Tuns32, Tuns8)
Y(Tint64, Tuns8)
Y(Tuns64, Tuns8)
Y(Tint8, Tchar)
Y(Tint16, Tchar)
Y(Tuns16, Tchar)
Y(Tint32, Tchar)
Y(Tuns32, Tchar)
Y(Tint64, Tchar)
Y(Tuns64, Tchar)
Y(Tuns16, Tint16)
Y(Tint32, Tint16)
Y(Tuns32, Tint16)
Y(Tint64, Tint16)
Y(Tuns64, Tint16)
Y(Tint16, Tuns16)
Y(Tint32, Tuns16)
Y(Tuns32, Tuns16)
Y(Tint64, Tuns16)
Y(Tuns64, Tuns16)
Y(Tint16, Twchar)
Y(Tint32, Twchar)
Y(Tuns32, Twchar)
Y(Tint64, Twchar)
Y(Tuns64, Twchar)
// Y(Tuns32, Tint32)
Y(Tint64, Tint32)
Y(Tuns64, Tint32)
// Y(Tint32, Tuns32)
Y(Tint64, Tuns32)
Y(Tuns64, Tuns32)
Y(Tint64, Tdchar)
Y(Tuns64, Tdchar)
Y(Tint64, Tuns64)
Y(Tuns64, Tint64)
for (i = 0; i < TMAX; i++)
for (j = 0; j < TMAX; j++)
{
if (impcnvResult[i][j] == Terror)
{
impcnvResult[i][j] = impcnvResult[j][i];
impcnvType1[i][j] = impcnvType2[j][i];
impcnvType2[i][j] = impcnvType1[j][i];
}
}
}
int main()
{ FILE *fp;
int i;
int j;
init();
fp = fopen("impcnvtab.c","w");
fprintf(fp,"// This file is generated by impcnvgen.c\n");
fprintf(fp,"#include \"mtype.h\"\n");
fprintf(fp,"unsigned char Type::impcnvResult[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvResult[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvType1[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvType1[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvType2[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvType2[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvWarn[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvWarn[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fclose(fp);
return EXIT_SUCCESS;
}
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include "mtype.h"
TY impcnvResult[TMAX][TMAX];
TY impcnvType1[TMAX][TMAX];
TY impcnvType2[TMAX][TMAX];
int impcnvWarn[TMAX][TMAX];
int integral_promotion(int t)
{
switch (t)
{
case Tchar:
case Twchar:
//case Tbit:
case Tbool:
case Tint8:
case Tuns8:
case Tint16:
case Tuns16: return Tint32;
case Tdchar: return Tuns32;
default: return t;
}
}
void init()
{ int i, j;
// Set conversion tables
for (i = 0; i < TMAX; i++)
for (j = 0; j < TMAX; j++)
{ impcnvResult[i][j] = Terror;
impcnvType1[i][j] = Terror;
impcnvType2[i][j] = Terror;
impcnvWarn[i][j] = 0;
}
#define X(t1,t2, nt1,nt2, rt) \
impcnvResult[t1][t2] = rt; \
impcnvType1[t1][t2] = nt1; \
impcnvType2[t1][t2] = nt2;
/* ======================= */
#if 0
X(Tbit,Tbit, Tint32,Tint32, Tint32)
X(Tbit,Tint8, Tint32,Tint32, Tint32)
X(Tbit,Tuns8, Tint32,Tint32, Tint32)
X(Tbit,Tint16, Tint32,Tint32, Tint32)
X(Tbit,Tuns16, Tint32,Tint32, Tint32)
X(Tbit,Tint32, Tint32,Tint32, Tint32)
X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tbit,Tint64, Tint64,Tint64, Tint64)
X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tbit,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tbit,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tbit,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tbit,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tbit,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tbit,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tbit,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
#endif
/* ======================= */
X(Tbool,Tbool, Tbool,Tbool, Tbool)
X(Tbool,Tint8, Tint32,Tint32, Tint32)
X(Tbool,Tuns8, Tint32,Tint32, Tint32)
X(Tbool,Tint16, Tint32,Tint32, Tint32)
X(Tbool,Tuns16, Tint32,Tint32, Tint32)
X(Tbool,Tint32, Tint32,Tint32, Tint32)
X(Tbool,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tbool,Tint64, Tint64,Tint64, Tint64)
X(Tbool,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tbool,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tbool,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tbool,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tbool,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tbool,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tbool,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tbool,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tbool,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tbool,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint8,Tint8, Tint32,Tint32, Tint32)
X(Tint8,Tuns8, Tint32,Tint32, Tint32)
X(Tint8,Tint16, Tint32,Tint32, Tint32)
X(Tint8,Tuns16, Tint32,Tint32, Tint32)
X(Tint8,Tint32, Tint32,Tint32, Tint32)
X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint8,Tint64, Tint64,Tint64, Tint64)
X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns8,Tuns8, Tint32,Tint32, Tint32)
X(Tuns8,Tint16, Tint32,Tint32, Tint32)
X(Tuns8,Tuns16, Tint32,Tint32, Tint32)
X(Tuns8,Tint32, Tint32,Tint32, Tint32)
X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns8,Tint64, Tint64,Tint64, Tint64)
X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint16,Tint16, Tint32,Tint32, Tint32)
X(Tint16,Tuns16, Tint32,Tint32, Tint32)
X(Tint16,Tint32, Tint32,Tint32, Tint32)
X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint16,Tint64, Tint64,Tint64, Tint64)
X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns16,Tuns16, Tint32,Tint32, Tint32)
X(Tuns16,Tint32, Tint32,Tint32, Tint32)
X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns16,Tint64, Tint64,Tint64, Tint64)
X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint32,Tint32, Tint32,Tint32, Tint32)
X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tint32,Tint64, Tint64,Tint64, Tint64)
X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32)
X(Tuns32,Tint64, Tint64,Tint64, Tint64)
X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tint64,Tint64, Tint64,Tint64, Tint64)
X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tint64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tint64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tint64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tint64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tint64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tint64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tint64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64)
X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tuns64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tuns64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tuns64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tuns64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tuns64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tuns64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tuns64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tuns64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
X(Tfloat32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
X(Tfloat32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat64,Timaginary32, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
X(Tfloat64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat64,Tcomplex32, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
X(Tfloat64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Timaginary64, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
X(Tfloat80,Tcomplex32, Tfloat80,Tcomplex80, Tcomplex80)
X(Tfloat80,Tcomplex64, Tfloat80,Tcomplex80, Tcomplex80)
X(Tfloat80,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32)
X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary32,Tcomplex32, Timaginary32,Tcomplex32, Tcomplex32)
X(Timaginary32,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary32,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary64,Tcomplex32, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary64,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
X(Timaginary64,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80)
X(Timaginary80,Tcomplex64, Timaginary80,Tcomplex80, Tcomplex80)
X(Timaginary80,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32)
X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
/* ======================= */
X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
#undef X
#define Y(t1,t2) impcnvWarn[t1][t2] = 1;
#if 0
Y(Tint8, Tbit)
Y(Tuns8, Tbit)
Y(Tint16, Tbit)
Y(Tuns16, Tbit)
Y(Tint32, Tbit)
Y(Tuns32, Tbit)
Y(Tint64, Tbit)
Y(Tuns64, Tbit)
#endif
Y(Tuns8, Tint8)
Y(Tint16, Tint8)
Y(Tuns16, Tint8)
Y(Tint32, Tint8)
Y(Tuns32, Tint8)
Y(Tint64, Tint8)
Y(Tuns64, Tint8)
Y(Tint8, Tuns8)
Y(Tint16, Tuns8)
Y(Tuns16, Tuns8)
Y(Tint32, Tuns8)
Y(Tuns32, Tuns8)
Y(Tint64, Tuns8)
Y(Tuns64, Tuns8)
Y(Tint8, Tchar)
Y(Tint16, Tchar)
Y(Tuns16, Tchar)
Y(Tint32, Tchar)
Y(Tuns32, Tchar)
Y(Tint64, Tchar)
Y(Tuns64, Tchar)
Y(Tuns16, Tint16)
Y(Tint32, Tint16)
Y(Tuns32, Tint16)
Y(Tint64, Tint16)
Y(Tuns64, Tint16)
Y(Tint16, Tuns16)
Y(Tint32, Tuns16)
Y(Tuns32, Tuns16)
Y(Tint64, Tuns16)
Y(Tuns64, Tuns16)
Y(Tint16, Twchar)
Y(Tint32, Twchar)
Y(Tuns32, Twchar)
Y(Tint64, Twchar)
Y(Tuns64, Twchar)
// Y(Tuns32, Tint32)
Y(Tint64, Tint32)
Y(Tuns64, Tint32)
// Y(Tint32, Tuns32)
Y(Tint64, Tuns32)
Y(Tuns64, Tuns32)
Y(Tint64, Tdchar)
Y(Tuns64, Tdchar)
// Y(Tint64, Tuns64)
// Y(Tuns64, Tint64)
for (i = 0; i < TMAX; i++)
for (j = 0; j < TMAX; j++)
{
if (impcnvResult[i][j] == Terror)
{
impcnvResult[i][j] = impcnvResult[j][i];
impcnvType1[i][j] = impcnvType2[j][i];
impcnvType2[i][j] = impcnvType1[j][i];
}
}
}
int main()
{ FILE *fp;
int i;
int j;
init();
fp = fopen("impcnvtab.c","w");
fprintf(fp,"// This file is generated by impcnvgen.c\n");
fprintf(fp,"#include \"mtype.h\"\n");
fprintf(fp,"unsigned char Type::impcnvResult[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvResult[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvType1[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvType1[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvType2[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvType2[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fprintf(fp,"unsigned char Type::impcnvWarn[TMAX][TMAX] =\n{\n");
for (i = 0; i < TMAX; i++)
{
for (j = 0; j < TMAX; j++)
{
fprintf(fp, "%d,",impcnvWarn[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp,"};\n");
fclose(fp);
return EXIT_SUCCESS;
}

82
dmd2/imphint.c Normal file
View File

@@ -0,0 +1,82 @@
// Compiler implementation of the D programming language
// Copyright (c) 2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
/******************************************
* Looks for undefined identifier s to see
* if it might be undefined because an import
* was not specified.
* Not meant to be a comprehensive list of names in each module,
* just the most common ones.
*/
const char *importHint(const char *s)
{
#if DMDV1
static const char *modules[] =
{ "std.c.stdio",
"std.stdio",
"std.math",
};
static const char *names[] =
{
"printf", NULL,
"writefln", NULL,
"sin", "cos", "sqrt", "fabs", NULL,
};
#else
static const char *modules[] =
{ "core.stdc.stdio",
"std.stdio",
"std.math",
};
static const char *names[] =
{
"printf", NULL,
"writeln", NULL,
"sin", "cos", "sqrt", "fabs", NULL,
};
#endif
int m = 0;
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++)
{
const char *p = names[n];
if (p == NULL)
{ m++;
continue;
}
assert(m < sizeof(modules)/sizeof(modules[0]));
if (strcmp(s, p) == 0)
return modules[m];
}
return NULL; // didn't find it
}
#if UNITTEST
void unittest_importHint()
{
const char *p;
p = importHint("printf");
assert(p);
p = importHint("fabs");
assert(p);
p = importHint("xxxxx");
assert(!p);
}
#endif

View File

@@ -1,364 +1,388 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "dsymbol.h"
#include "import.h"
#include "identifier.h"
#include "module.h"
#include "scope.h"
#include "hdrgen.h"
#include "mtype.h"
#include "declaration.h"
#include "id.h"
#include "attrib.h"
/********************************* Import ****************************/
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
int isstatic)
: Dsymbol(id)
{
assert(id);
this->loc = loc;
this->packages = packages;
this->id = id;
this->aliasId = aliasId;
this->isstatic = isstatic;
#if IN_LLVM
protection = PROTundefined;
#endif
pkg = NULL;
mod = NULL;
if (aliasId)
this->ident = aliasId;
// Kludge to change Import identifier to first package
else if (packages && packages->dim)
this->ident = (Identifier *)packages->data[0];
}
void Import::addAlias(Identifier *name, Identifier *alias)
{
if (isstatic)
error("cannot have an import bind list");
if (!aliasId)
this->ident = NULL; // make it an anonymous import
names.push(name);
aliases.push(alias);
}
const char *Import::kind()
{
return isstatic ? (char *)"static import" : (char *)"import";
}
#if IN_LLVM
enum PROT Import::prot()
{
return protection;
}
#endif
Dsymbol *Import::syntaxCopy(Dsymbol *s)
{
assert(!s);
Import *si;
si = new Import(loc, packages, id, aliasId, isstatic);
for (size_t i = 0; i < names.dim; i++)
{
si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
}
return si;
}
void Import::load(Scope *sc)
{
DsymbolTable *dst;
Dsymbol *s;
//printf("Import::load('%s')\n", toChars());
// See if existing module
dst = Package::resolve(packages, NULL, &pkg);
s = dst->lookup(id);
if (s)
{
#if TARGET_NET
mod = (Module *)s;
#else
if (s->isModule())
mod = (Module *)s;
else
error("package and module have the same name");
#endif
}
if (!mod)
{
// Load module
mod = Module::load(loc, packages, id);
dst->insert(id, mod); // id may be different from mod->ident,
// if so then insert alias
if (!mod->importedFrom)
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
}
if (!pkg)
pkg = mod;
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
}
void escapePath(OutBuffer *buf, const char *fname)
{
while (1)
{
switch (*fname)
{
case 0:
return;
case '(':
case ')':
case '\\':
buf->writebyte('\\');
default:
buf->writebyte(*fname);
break;
}
fname++;
}
}
void Import::semantic(Scope *sc)
{
//printf("Import::semantic('%s')\n", toChars());
load(sc);
if (mod)
{
#if 0
if (mod->loc.linnum != 0)
{ /* If the line number is not 0, then this is not
* a 'root' module, i.e. it was not specified on the command line.
*/
mod->importedFrom = sc->module->importedFrom;
assert(mod->importedFrom);
}
#endif
// Modules need a list of each imported module
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
sc->module->aimports.push(mod);
if (!isstatic && !aliasId && !names.dim)
{
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
sc->scopesym->importScope(mod, prot);
}
mod->semantic();
if (mod->needmoduleinfo)
sc->module->needmoduleinfo = 1;
sc = sc->push(mod);
for (size_t i = 0; i < aliasdecls.dim; i++)
{ AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
//printf("\tImport alias semantic('%s')\n", s->toChars());
if (!mod->search(loc, (Identifier *)names.data[i], 0))
error("%s not found", ((Identifier *)names.data[i])->toChars());
ad->importprot = protection;
ad->semantic(sc);
}
sc = sc->pop();
}
if (global.params.moduleDeps != NULL)
{
/* The grammar of the file is:
* ImportDeclaration
* ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
* ModuleAliasIdentifier ] "\n"
*
* BasicImportDeclaration
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
*
* FilePath
* - any string with '(', ')' and '\' escaped with the '\' character
*/
OutBuffer *ob = global.params.moduleDeps;
ob->writestring(sc->module->toPrettyChars());
ob->writestring(" (");
escapePath(ob, sc->module->srcfile->toChars());
ob->writestring(") : ");
ProtDeclaration::protectionToCBuffer(ob, sc->protection);
if (isstatic)
StorageClassDeclaration::stcToCBuffer(ob, STCstatic);
ob->writestring(": ");
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{
Identifier *pid = (Identifier *)packages->data[i];
ob->printf("%s.", pid->toChars());
}
}
ob->writestring(id->toChars());
ob->writestring(" (");
if (mod)
escapePath(ob, mod->srcfile->toChars());
else
ob->writestring("???");
ob->writebyte(')');
for (size_t i = 0; i < names.dim; i++)
{
if (i == 0)
ob->writebyte(':');
else
ob->writebyte(',');
Identifier *name = (Identifier *)names.data[i];
Identifier *alias = (Identifier *)aliases.data[i];
if (!alias)
{
ob->printf("%s", name->toChars());
alias = name;
}
else
ob->printf("%s=%s", alias->toChars(), name->toChars());
}
if (aliasId)
ob->printf(" -> %s", aliasId->toChars());
ob->writenl();
}
//printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
}
void Import::semantic2(Scope *sc)
{
//printf("Import::semantic2('%s')\n", toChars());
mod->semantic2();
if (mod->needmoduleinfo)
sc->module->needmoduleinfo = 1;
}
Dsymbol *Import::toAlias()
{
if (aliasId)
return mod;
return this;
}
/*****************************
* Add import to sd's symbol table.
*/
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
int result = 0;
if (names.dim == 0)
return Dsymbol::addMember(sc, sd, memnum);
if (aliasId)
result = Dsymbol::addMember(sc, sd, memnum);
/* Instead of adding the import to sd's symbol table,
* add each of the alias=name pairs
*/
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = (Identifier *)names.data[i];
Identifier *alias = (Identifier *)aliases.data[i];
if (!alias)
alias = name;
TypeIdentifier *tname = new TypeIdentifier(loc, name);
AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
result |= ad->addMember(sc, sd, memnum);
aliasdecls.push(ad);
}
return result;
}
Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
if (!pkg)
{ load(NULL);
mod->semantic();
}
// Forward it to the package/module
return pkg->search(loc, ident, flags);
}
int Import::overloadInsert(Dsymbol *s)
{
// Allow multiple imports of the same name
return s->isImport() != NULL;
}
void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (hgs->hdrgen && id == Id::object)
return; // object is imported by default
if (isstatic)
buf->writestring("static ");
buf->writestring("import ");
if (aliasId)
{
buf->printf("%s = ", aliasId->toChars());
}
if (packages && packages->dim)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = (Identifier *)packages->data[i];
buf->printf("%s.", pid->toChars());
}
}
buf->printf("%s;", id->toChars());
buf->writenl();
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "dsymbol.h"
#include "import.h"
#include "identifier.h"
#include "module.h"
#include "scope.h"
#include "hdrgen.h"
#include "mtype.h"
#include "declaration.h"
#include "id.h"
#include "attrib.h"
/********************************* Import ****************************/
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
int isstatic)
: Dsymbol(id)
{
assert(id);
this->loc = loc;
this->packages = packages;
this->id = id;
this->aliasId = aliasId;
this->isstatic = isstatic;
#if IN_LLVM
protection = PROTundefined;
#endif
pkg = NULL;
mod = NULL;
if (aliasId)
this->ident = aliasId;
// Kludge to change Import identifier to first package
else if (packages && packages->dim)
this->ident = (Identifier *)packages->data[0];
}
void Import::addAlias(Identifier *name, Identifier *alias)
{
if (isstatic)
error("cannot have an import bind list");
if (!aliasId)
this->ident = NULL; // make it an anonymous import
names.push(name);
aliases.push(alias);
}
const char *Import::kind()
{
return isstatic ? (char *)"static import" : (char *)"import";
}
#if IN_LLVM
enum PROT Import::prot()
{
return protection;
}
#endif
Dsymbol *Import::syntaxCopy(Dsymbol *s)
{
assert(!s);
Import *si;
si = new Import(loc, packages, id, aliasId, isstatic);
for (size_t i = 0; i < names.dim; i++)
{
si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
}
return si;
}
void Import::load(Scope *sc)
{
//printf("Import::load('%s')\n", toChars());
// See if existing module
DsymbolTable *dst = Package::resolve(packages, NULL, &pkg);
Dsymbol *s = dst->lookup(id);
if (s)
{
#if TARGET_NET
mod = (Module *)s;
#else
if (s->isModule())
mod = (Module *)s;
else
error("package and module have the same name");
#endif
}
if (!mod)
{
// Load module
mod = Module::load(loc, packages, id);
dst->insert(id, mod); // id may be different from mod->ident,
// if so then insert alias
if (!mod->importedFrom)
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
}
if (!pkg)
pkg = mod;
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
}
void escapePath(OutBuffer *buf, const char *fname)
{
while (1)
{
switch (*fname)
{
case 0:
return;
case '(':
case ')':
case '\\':
buf->writebyte('\\');
default:
buf->writebyte(*fname);
break;
}
fname++;
}
}
void Import::importAll(Scope *sc)
{
if (!mod)
{
load(sc);
mod->importAll(0);
if (!isstatic && !aliasId && !names.dim)
{
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
sc->scopesym->importScope(mod, prot);
}
}
}
void Import::semantic(Scope *sc)
{
//printf("Import::semantic('%s')\n", toChars());
// Load if not already done so
if (!mod)
{ load(sc);
mod->importAll(0);
}
if (mod)
{
#if 0
if (mod->loc.linnum != 0)
{ /* If the line number is not 0, then this is not
* a 'root' module, i.e. it was not specified on the command line.
*/
mod->importedFrom = sc->module->importedFrom;
assert(mod->importedFrom);
}
#endif
// Modules need a list of each imported module
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
sc->module->aimports.push(mod);
if (!isstatic && !aliasId && !names.dim)
{
/* Default to private importing
*/
enum PROT prot = sc->protection;
if (!sc->explicitProtection)
prot = PROTprivate;
sc->scopesym->importScope(mod, prot);
}
mod->semantic();
if (mod->needmoduleinfo)
{ //printf("module4 %s because of %s\n", sc->module->toChars(), mod->toChars());
sc->module->needmoduleinfo = 1;
}
sc = sc->push(mod);
for (size_t i = 0; i < aliasdecls.dim; i++)
{ AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
//printf("\tImport alias semantic('%s')\n", s->toChars());
if (!mod->search(loc, (Identifier *)names.data[i], 0))
error("%s not found", ((Identifier *)names.data[i])->toChars());
ad->importprot = protection;
ad->semantic(sc);
}
sc = sc->pop();
}
if (global.params.moduleDeps != NULL)
{
/* The grammar of the file is:
* ImportDeclaration
* ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
* ModuleAliasIdentifier ] "\n"
*
* BasicImportDeclaration
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
*
* FilePath
* - any string with '(', ')' and '\' escaped with the '\' character
*/
OutBuffer *ob = global.params.moduleDeps;
ob->writestring(sc->module->toPrettyChars());
ob->writestring(" (");
escapePath(ob, sc->module->srcfile->toChars());
ob->writestring(") : ");
ProtDeclaration::protectionToCBuffer(ob, sc->protection);
if (isstatic)
StorageClassDeclaration::stcToCBuffer(ob, STCstatic);
ob->writestring(": ");
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{
Identifier *pid = (Identifier *)packages->data[i];
ob->printf("%s.", pid->toChars());
}
}
ob->writestring(id->toChars());
ob->writestring(" (");
if (mod)
escapePath(ob, mod->srcfile->toChars());
else
ob->writestring("???");
ob->writebyte(')');
for (size_t i = 0; i < names.dim; i++)
{
if (i == 0)
ob->writebyte(':');
else
ob->writebyte(',');
Identifier *name = (Identifier *)names.data[i];
Identifier *alias = (Identifier *)aliases.data[i];
if (!alias)
{
ob->printf("%s", name->toChars());
alias = name;
}
else
ob->printf("%s=%s", alias->toChars(), name->toChars());
}
if (aliasId)
ob->printf(" -> %s", aliasId->toChars());
ob->writenl();
}
//printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
}
void Import::semantic2(Scope *sc)
{
//printf("Import::semantic2('%s')\n", toChars());
mod->semantic2();
if (mod->needmoduleinfo)
{ //printf("module5 %s because of %s\n", sc->module->toChars(), mod->toChars());
sc->module->needmoduleinfo = 1;
}
}
Dsymbol *Import::toAlias()
{
if (aliasId)
return mod;
return this;
}
/*****************************
* Add import to sd's symbol table.
*/
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
int result = 0;
if (names.dim == 0)
return Dsymbol::addMember(sc, sd, memnum);
if (aliasId)
result = Dsymbol::addMember(sc, sd, memnum);
/* Instead of adding the import to sd's symbol table,
* add each of the alias=name pairs
*/
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = (Identifier *)names.data[i];
Identifier *alias = (Identifier *)aliases.data[i];
if (!alias)
alias = name;
TypeIdentifier *tname = new TypeIdentifier(loc, name);
AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
result |= ad->addMember(sc, sd, memnum);
aliasdecls.push(ad);
}
return result;
}
Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
if (!pkg)
{ load(NULL);
mod->semantic();
}
// Forward it to the package/module
return pkg->search(loc, ident, flags);
}
int Import::overloadInsert(Dsymbol *s)
{
// Allow multiple imports of the same name
return s->isImport() != NULL;
}
void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (hgs->hdrgen && id == Id::object)
return; // object is imported by default
if (isstatic)
buf->writestring("static ");
buf->writestring("import ");
if (aliasId)
{
buf->printf("%s = ", aliasId->toChars());
}
if (packages && packages->dim)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = (Identifier *)packages->data[i];
buf->printf("%s.", pid->toChars());
}
}
buf->printf("%s;", id->toChars());
buf->writenl();
}

View File

@@ -1,71 +1,72 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_IMPORT_H
#define DMD_IMPORT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Identifier;
struct Scope;
struct OutBuffer;
struct Module;
struct Package;
struct AliasDeclaration;
#ifdef _DH
struct HdrGenState;
#endif
struct Import : Dsymbol
{
Array *packages; // array of Identifier's representing packages
Identifier *id; // module Identifier
Identifier *aliasId;
int isstatic; // !=0 if static import
#if IN_LLVM
enum PROT protection;
#endif
// Pairs of alias=name to bind into current namespace
Array names;
Array aliases;
Array aliasdecls; // AliasDeclarations for names/aliases
Module *mod;
Package *pkg; // leftmost package/module
Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
int isstatic);
void addAlias(Identifier *name, Identifier *alias);
const char *kind();
#if IN_LLVM
enum PROT prot();
#endif
Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
void load(Scope *sc);
void semantic(Scope *sc);
void semantic2(Scope *sc);
Dsymbol *toAlias();
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
int overloadInsert(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Import *isImport() { return this; }
};
#endif /* DMD_IMPORT_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_IMPORT_H
#define DMD_IMPORT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Identifier;
struct Scope;
struct OutBuffer;
struct Module;
struct Package;
struct AliasDeclaration;
#ifdef _DH
struct HdrGenState;
#endif
struct Import : Dsymbol
{
Array *packages; // array of Identifier's representing packages
Identifier *id; // module Identifier
Identifier *aliasId;
int isstatic; // !=0 if static import
#if IN_LLVM
enum PROT protection;
#endif
// Pairs of alias=name to bind into current namespace
Array names;
Array aliases;
Array aliasdecls; // AliasDeclarations for names/aliases
Module *mod;
Package *pkg; // leftmost package/module
Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
int isstatic);
void addAlias(Identifier *name, Identifier *alias);
const char *kind();
#if IN_LLVM
enum PROT prot();
#endif
Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
void load(Scope *sc);
void importAll(Scope *sc);
void semantic(Scope *sc);
void semantic2(Scope *sc);
Dsymbol *toAlias();
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
int overloadInsert(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Import *isImport() { return this; }
};
#endif /* DMD_IMPORT_H */

View File

@@ -1,329 +1,333 @@
/*
* Some portions copyright (c) 1994-1995 by Symantec
* Copyright (c) 1999-2009 by Digital Mars
* All Rights Reserved
* http://www.digitalmars.com
* Written by Walter Bright
*
* This source file is made available for personal use
* only. The license is in /dmd/src/dmd/backendlicense.txt
* For any other uses, please contact Digital Mars.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#if _WIN32
#include <windows.h>
#endif
#if __APPLE__
#include <sys/syslimits.h>
#endif
#if __FreeBSD__ || __sun&&__SVR4
// for PATH_MAX
#include <limits.h>
#endif
#if __sun&&__SVR4
#include <alloca.h>
#endif
#include "root.h"
#include "rmem.h"
#define LOG 0
char *skipspace(const char *p);
#if __GNUC__
char *strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif /* unix */
/*****************************
* Read and analyze .ini file.
* Input:
* argv0 program name (argv[0])
* inifile .ini file name
*/
void inifile(const char *argv0x, const char *inifilex)
{
char *argv0 = (char *)argv0x;
char *inifile = (char *)inifilex; // do const-correct later
char *path; // need path for @P macro
char *filename;
OutBuffer buf;
int i;
int k;
int envsection = 0;
#if LOG
printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
#endif
if (FileName::absolute(inifile))
{
filename = inifile;
}
else
{
/* Look for inifile in the following sequence of places:
* o current directory
* o home directory
* o directory off of argv0
* o /etc/
*/
if (FileName::exists(inifile))
{
filename = inifile;
}
else
{
filename = FileName::combine(getenv("HOME"), inifile);
if (!FileName::exists(filename))
{
#if _WIN32 // This fix by Tim Matthews
char resolved_name[MAX_PATH + 1];
if(GetModuleFileName(NULL, resolved_name, MAX_PATH + 1) && FileName::exists(resolved_name))
{
filename = (char *)FileName::replaceName(resolved_name, inifile);
if(FileName::exists(filename))
goto Ldone;
}
#endif
filename = (char *)FileName::replaceName(argv0, inifile);
if (!FileName::exists(filename))
{
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
#if __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne
/* argv0 might be a symbolic link,
* so try again looking past it to the real path
*/
#if __APPLE__ || __FreeBSD__ || __sun&&__SVR4
char resolved_name[PATH_MAX + 1];
char* real_argv0 = realpath(argv0, resolved_name);
#else
char* real_argv0 = realpath(argv0, NULL);
#endif
//printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0);
if (real_argv0)
{
filename = (char *)FileName::replaceName(real_argv0, inifile);
#if !(__APPLE__ || __FreeBSD__ || __sun&&__SVR4)
free(real_argv0);
#endif
if (FileName::exists(filename))
goto Ldone;
}
#else
#error use of glibc non-standard extension realpath(char*, NULL)
#endif
if (1){
// Search PATH for argv0
const char *p = getenv("PATH");
Array *paths = FileName::splitPath(p);
filename = FileName::searchPath(paths, argv0, 0);
if (!filename)
goto Letc; // argv0 not found on path
filename = (char *)FileName::replaceName(filename, inifile);
if (FileName::exists(filename))
goto Ldone;
}
#endif
// Search /etc/ for inifile
Letc:
filename = FileName::combine((char *)"/etc/", inifile);
Ldone:
;
}
}
}
}
path = FileName::path(filename);
#if LOG
printf("\tpath = '%s', filename = '%s'\n", path, filename);
#endif
File file(filename);
if (file.read())
return; // error reading file
// Parse into lines
int eof = 0;
for (i = 0; i < file.len && !eof; i++)
{
int linestart = i;
for (; i < file.len; i++)
{
switch (file.buffer[i])
{
case '\r':
break;
case '\n':
// Skip if it was preceded by '\r'
if (i && file.buffer[i - 1] == '\r')
goto Lskip;
break;
case 0:
case 0x1A:
eof = 1;
break;
default:
continue;
}
break;
}
// The line is file.buffer[linestart..i]
char *line;
int len;
char *p;
char *pn;
line = (char *)&file.buffer[linestart];
len = i - linestart;
buf.reset();
// First, expand the macros.
// Macros are bracketed by % characters.
for (k = 0; k < len; k++)
{
if (line[k] == '%')
{
int j;
for (j = k + 1; j < len; j++)
{
if (line[j] == '%')
{
if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
{
// %@P% is special meaning the path to the .ini file
p = path;
if (!*p)
p = (char *)".";
}
else
{ int len = j - k;
char tmp[10]; // big enough most of the time
if (len <= sizeof(tmp))
p = tmp;
else
p = (char *)alloca(len);
len--;
memcpy(p, &line[k + 1], len);
p[len] = 0;
strupr(p);
p = getenv(p);
if (!p)
p = (char *)"";
}
buf.writestring(p);
k = j;
goto L1;
}
}
}
buf.writeByte(line[k]);
L1:
;
}
// Remove trailing spaces
while (buf.offset && isspace(buf.data[buf.offset - 1]))
buf.offset--;
p = buf.toChars();
// The expanded line is in p.
// Now parse it for meaning.
p = skipspace(p);
switch (*p)
{
case ';': // comment
case 0: // blank
break;
case '[': // look for [Environment]
p = skipspace(p + 1);
for (pn = p; isalnum(*pn); pn++)
;
if (pn - p == 11 &&
memicmp(p, "Environment", 11) == 0 &&
*skipspace(pn) == ']'
)
envsection = 1;
else
envsection = 0;
break;
default:
if (envsection)
{
pn = p;
// Convert name to upper case;
// remove spaces bracketing =
for (p = pn; *p; p++)
{ if (islower(*p))
*p &= ~0x20;
else if (isspace(*p))
memmove(p, p + 1, strlen(p));
else if (*p == '=')
{
p++;
while (isspace(*p))
memmove(p, p + 1, strlen(p));
break;
}
}
putenv(strdup(pn));
#if LOG
printf("\tputenv('%s')\n", pn);
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
#endif
}
break;
}
Lskip:
;
}
}
/********************
* Skip spaces.
*/
char *skipspace(const char *p)
{
while (isspace(*p))
p++;
return (char *)p;
}
/*
* Some portions copyright (c) 1994-1995 by Symantec
* Copyright (c) 1999-2009 by Digital Mars
* All Rights Reserved
* http://www.digitalmars.com
* Written by Walter Bright
*
* This source file is made available for personal use
* only. The license is in /dmd/src/dmd/backendlicense.txt
* For any other uses, please contact Digital Mars.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#if _WIN32
#include <windows.h>
#endif
#if __APPLE__
#include <sys/syslimits.h>
#endif
#if __FreeBSD__ || __sun&&__SVR4
// for PATH_MAX
#include <limits.h>
#endif
#if __sun&&__SVR4
#include <alloca.h>
#endif
#include "root.h"
#include "rmem.h"
#define LOG 0
char *skipspace(const char *p);
#if __GNUC__
char *strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif /* unix */
/*****************************
* Read and analyze .ini file.
* Input:
* argv0 program name (argv[0])
* inifile .ini file name
* Returns:
* file name of ini file
* Note: this is a memory leak
*/
const char *inifile(const char *argv0x, const char *inifilex)
{
char *argv0 = (char *)argv0x;
char *inifile = (char *)inifilex; // do const-correct later
char *path; // need path for @P macro
char *filename;
OutBuffer buf;
int i;
int k;
int envsection = 0;
#if LOG
printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
#endif
if (FileName::absolute(inifile))
{
filename = inifile;
}
else
{
/* Look for inifile in the following sequence of places:
* o current directory
* o home directory
* o directory off of argv0
* o /etc/
*/
if (FileName::exists(inifile))
{
filename = inifile;
}
else
{
filename = FileName::combine(getenv("HOME"), inifile);
if (!FileName::exists(filename))
{
#if _WIN32 // This fix by Tim Matthews
char resolved_name[MAX_PATH + 1];
if(GetModuleFileName(NULL, resolved_name, MAX_PATH + 1) && FileName::exists(resolved_name))
{
filename = (char *)FileName::replaceName(resolved_name, inifile);
if(FileName::exists(filename))
goto Ldone;
}
#endif
filename = (char *)FileName::replaceName(argv0, inifile);
if (!FileName::exists(filename))
{
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
#if __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne
/* argv0 might be a symbolic link,
* so try again looking past it to the real path
*/
#if __APPLE__ || __FreeBSD__ || __sun&&__SVR4
char resolved_name[PATH_MAX + 1];
char* real_argv0 = realpath(argv0, resolved_name);
#else
char* real_argv0 = realpath(argv0, NULL);
#endif
//printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0);
if (real_argv0)
{
filename = (char *)FileName::replaceName(real_argv0, inifile);
#if !(__APPLE__ || __FreeBSD__ || __sun&&__SVR4)
free(real_argv0);
#endif
if (FileName::exists(filename))
goto Ldone;
}
#else
#error use of glibc non-standard extension realpath(char*, NULL)
#endif
if (1){
// Search PATH for argv0
const char *p = getenv("PATH");
Array *paths = FileName::splitPath(p);
filename = FileName::searchPath(paths, argv0, 0);
if (!filename)
goto Letc; // argv0 not found on path
filename = (char *)FileName::replaceName(filename, inifile);
if (FileName::exists(filename))
goto Ldone;
}
#endif
// Search /etc/ for inifile
Letc:
filename = FileName::combine((char *)"/etc/", inifile);
Ldone:
;
}
}
}
}
path = FileName::path(filename);
#if LOG
printf("\tpath = '%s', filename = '%s'\n", path, filename);
#endif
File file(filename);
if (file.read())
return filename; // error reading file
// Parse into lines
int eof = 0;
for (i = 0; i < file.len && !eof; i++)
{
int linestart = i;
for (; i < file.len; i++)
{
switch (file.buffer[i])
{
case '\r':
break;
case '\n':
// Skip if it was preceded by '\r'
if (i && file.buffer[i - 1] == '\r')
goto Lskip;
break;
case 0:
case 0x1A:
eof = 1;
break;
default:
continue;
}
break;
}
// The line is file.buffer[linestart..i]
char *line;
int len;
char *p;
char *pn;
line = (char *)&file.buffer[linestart];
len = i - linestart;
buf.reset();
// First, expand the macros.
// Macros are bracketed by % characters.
for (k = 0; k < len; k++)
{
if (line[k] == '%')
{
int j;
for (j = k + 1; j < len; j++)
{
if (line[j] == '%')
{
if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
{
// %@P% is special meaning the path to the .ini file
p = path;
if (!*p)
p = (char *)".";
}
else
{ int len = j - k;
char tmp[10]; // big enough most of the time
if (len <= sizeof(tmp))
p = tmp;
else
p = (char *)alloca(len);
len--;
memcpy(p, &line[k + 1], len);
p[len] = 0;
strupr(p);
p = getenv(p);
if (!p)
p = (char *)"";
}
buf.writestring(p);
k = j;
goto L1;
}
}
}
buf.writeByte(line[k]);
L1:
;
}
// Remove trailing spaces
while (buf.offset && isspace(buf.data[buf.offset - 1]))
buf.offset--;
p = buf.toChars();
// The expanded line is in p.
// Now parse it for meaning.
p = skipspace(p);
switch (*p)
{
case ';': // comment
case 0: // blank
break;
case '[': // look for [Environment]
p = skipspace(p + 1);
for (pn = p; isalnum(*pn); pn++)
;
if (pn - p == 11 &&
memicmp(p, "Environment", 11) == 0 &&
*skipspace(pn) == ']'
)
envsection = 1;
else
envsection = 0;
break;
default:
if (envsection)
{
pn = p;
// Convert name to upper case;
// remove spaces bracketing =
for (p = pn; *p; p++)
{ if (islower(*p))
*p &= ~0x20;
else if (isspace(*p))
memmove(p, p + 1, strlen(p));
else if (*p == '=')
{
p++;
while (isspace(*p))
memmove(p, p + 1, strlen(p));
break;
}
}
putenv(strdup(pn));
#if LOG
printf("\tputenv('%s')\n", pn);
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
#endif
}
break;
}
Lskip:
;
}
return filename;
}
/********************
* Skip spaces.
*/
char *skipspace(const char *p)
{
while (isspace(*p))
p++;
return (char *)p;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,139 +1,140 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef INIT_H
#define INIT_H
#include "root.h"
#include "mars.h"
#include "arraytypes.h"
struct Identifier;
struct Expression;
struct Scope;
struct Type;
struct dt_t;
struct AggregateDeclaration;
struct VoidInitializer;
struct StructInitializer;
struct ArrayInitializer;
struct ExpInitializer;
#ifdef _DH
struct HdrGenState;
#endif
struct Initializer : Object
{
Loc loc;
Initializer(Loc loc);
virtual Initializer *syntaxCopy();
virtual Initializer *semantic(Scope *sc, Type *t);
virtual Type *inferType(Scope *sc);
virtual Expression *toExpression() = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
char *toChars();
static Initializers *arraySyntaxCopy(Initializers *ai);
#if IN_DMD
virtual dt_t *toDt();
#endif
virtual VoidInitializer *isVoidInitializer() { return NULL; }
virtual StructInitializer *isStructInitializer() { return NULL; }
virtual ArrayInitializer *isArrayInitializer() { return NULL; }
virtual ExpInitializer *isExpInitializer() { return NULL; }
};
struct VoidInitializer : Initializer
{
Type *type; // type that this will initialize to
VoidInitializer(Loc loc);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
virtual VoidInitializer *isVoidInitializer() { return this; }
};
struct StructInitializer : Initializer
{
Identifiers field; // of Identifier *'s
Initializers value; // parallel array of Initializer *'s
Array vars; // parallel array of VarDeclaration *'s
AggregateDeclaration *ad; // which aggregate this is for
StructInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Identifier *field, Initializer *value);
Initializer *semantic(Scope *sc, Type *t);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
StructInitializer *isStructInitializer() { return this; }
};
struct ArrayInitializer : Initializer
{
Expressions index; // indices
Initializers value; // of Initializer *'s
unsigned dim; // length of array being initialized
Type *type; // type that array will be used to initialize
int sem; // !=0 if semantic() is run
ArrayInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Expression *index, Initializer *value);
Initializer *semantic(Scope *sc, Type *t);
Type *inferType(Scope *sc);
Expression *toExpression();
Initializer *toAssocArrayInitializer();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
dt_t *toDtBit(); // for bit arrays
#endif
ArrayInitializer *isArrayInitializer() { return this; }
};
struct ExpInitializer : Initializer
{
Expression *exp;
ExpInitializer(Loc loc, Expression *exp);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t);
Type *inferType(Scope *sc);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
virtual ExpInitializer *isExpInitializer() { return this; }
};
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef INIT_H
#define INIT_H
#include "root.h"
#include "mars.h"
#include "arraytypes.h"
struct Identifier;
struct Expression;
struct Scope;
struct Type;
struct dt_t;
struct AggregateDeclaration;
struct VoidInitializer;
struct StructInitializer;
struct ArrayInitializer;
struct ExpInitializer;
#ifdef _DH
struct HdrGenState;
#endif
struct Initializer : Object
{
Loc loc;
Initializer(Loc loc);
virtual Initializer *syntaxCopy();
virtual Initializer *semantic(Scope *sc, Type *t);
virtual Type *inferType(Scope *sc);
virtual Expression *toExpression() = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
char *toChars();
static Initializers *arraySyntaxCopy(Initializers *ai);
#if IN_DMD
virtual dt_t *toDt();
#endif
virtual VoidInitializer *isVoidInitializer() { return NULL; }
virtual StructInitializer *isStructInitializer() { return NULL; }
virtual ArrayInitializer *isArrayInitializer() { return NULL; }
virtual ExpInitializer *isExpInitializer() { return NULL; }
};
struct VoidInitializer : Initializer
{
Type *type; // type that this will initialize to
VoidInitializer(Loc loc);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
virtual VoidInitializer *isVoidInitializer() { return this; }
};
struct StructInitializer : Initializer
{
Identifiers field; // of Identifier *'s
Initializers value; // parallel array of Initializer *'s
Array vars; // parallel array of VarDeclaration *'s
AggregateDeclaration *ad; // which aggregate this is for
StructInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Identifier *field, Initializer *value);
Initializer *semantic(Scope *sc, Type *t);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
StructInitializer *isStructInitializer() { return this; }
};
struct ArrayInitializer : Initializer
{
Expressions index; // indices
Initializers value; // of Initializer *'s
unsigned dim; // length of array being initialized
Type *type; // type that array will be used to initialize
int sem; // !=0 if semantic() is run
ArrayInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Expression *index, Initializer *value);
Initializer *semantic(Scope *sc, Type *t);
int isAssociativeArray();
Type *inferType(Scope *sc);
Expression *toExpression();
Expression *toAssocArrayLiteral();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
dt_t *toDtBit(); // for bit arrays
#endif
ArrayInitializer *isArrayInitializer() { return this; }
};
struct ExpInitializer : Initializer
{
Expression *exp;
ExpInitializer(Loc loc, Expression *exp);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t);
Type *inferType(Scope *sc);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
dt_t *toDt();
#endif
virtual ExpInitializer *isExpInitializer() { return this; }
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,164 +1,186 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#include <stdio.h>
#include "irstate.h"
IRState::IRState(IRState *irs, Statement *s)
{
prev = irs;
statement = s;
symbol = NULL;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
}
}
IRState::IRState(IRState *irs, Dsymbol *s)
{
prev = irs;
statement = NULL;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
}
}
IRState::IRState(Module *m, Dsymbol *s)
{
prev = NULL;
statement = NULL;
this->m = m;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
startaddress = NULL;
}
block *IRState::getBreakBlock(Identifier *ident)
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (ident)
{
if (bc->prev && bc->prev->ident == ident)
return bc->breakBlock;
}
else if (bc->breakBlock)
return bc->breakBlock;
}
return NULL;
}
block *IRState::getContBlock(Identifier *ident)
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (ident)
{
if (bc->prev && bc->prev->ident == ident)
return bc->contBlock;
}
else if (bc->contBlock)
return bc->contBlock;
}
return NULL;
}
block *IRState::getSwitchBlock()
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (bc->switchBlock)
return bc->switchBlock;
}
return NULL;
}
block *IRState::getDefaultBlock()
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (bc->defaultBlock)
return bc->defaultBlock;
}
return NULL;
}
FuncDeclaration *IRState::getFunc()
{
IRState *bc;
for (bc = this; bc->prev; bc = bc->prev)
{
}
return (FuncDeclaration *)(bc->symbol);
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#include <stdio.h>
#include "mars.h"
#include "mtype.h"
#include "declaration.h"
#include "irstate.h"
IRState::IRState(IRState *irs, Statement *s)
{
prev = irs;
statement = s;
symbol = NULL;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
}
}
IRState::IRState(IRState *irs, Dsymbol *s)
{
prev = irs;
statement = NULL;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
}
}
IRState::IRState(Module *m, Dsymbol *s)
{
prev = NULL;
statement = NULL;
this->m = m;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
ident = NULL;
ehidden = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
startaddress = NULL;
}
block *IRState::getBreakBlock(Identifier *ident)
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (ident)
{
if (bc->prev && bc->prev->ident == ident)
return bc->breakBlock;
}
else if (bc->breakBlock)
return bc->breakBlock;
}
return NULL;
}
block *IRState::getContBlock(Identifier *ident)
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (ident)
{
if (bc->prev && bc->prev->ident == ident)
return bc->contBlock;
}
else if (bc->contBlock)
return bc->contBlock;
}
return NULL;
}
block *IRState::getSwitchBlock()
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (bc->switchBlock)
return bc->switchBlock;
}
return NULL;
}
block *IRState::getDefaultBlock()
{
IRState *bc;
for (bc = this; bc; bc = bc->prev)
{
if (bc->defaultBlock)
return bc->defaultBlock;
}
return NULL;
}
FuncDeclaration *IRState::getFunc()
{
IRState *bc;
for (bc = this; bc->prev; bc = bc->prev)
{
}
return (FuncDeclaration *)(bc->symbol);
}
/**********************
* Return !=0 if do array bounds checking
*/
int IRState::arrayBoundsCheck()
{
int result = global.params.useArrayBounds;
if (result == 1)
{ // For safe functions only
result = 0;
FuncDeclaration *fd = getFunc();
if (fd)
{ Type *t = fd->type;
if (t->ty == Tfunction && ((TypeFunction *)t)->trust == TRUSTsafe)
result = 1;
}
}
return result;
}

View File

@@ -1,57 +1,58 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#ifndef DMD_CONTEXT_H
#define DMD_CONTEXT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct Module;
struct Statement;
struct block;
struct Dsymbol;
struct Identifier;
struct Symbol;
struct FuncDeclaration;
struct Blockx;
struct Array;
struct elem;
struct IRState
{
IRState *prev;
Statement *statement;
Module *m; // module
Dsymbol *symbol;
Identifier *ident;
Symbol *shidden; // hidden parameter to function
Symbol *sthis; // 'this' parameter to function (member and nested)
Symbol *sclosure; // pointer to closure instance
Blockx *blx;
Array *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later
elem *ehidden; // transmit hidden pointer to CallExp::toElem()
Symbol *startaddress;
block *breakBlock;
block *contBlock;
block *switchBlock;
block *defaultBlock;
IRState(IRState *irs, Statement *s);
IRState(IRState *irs, Dsymbol *s);
IRState(Module *m, Dsymbol *s);
block *getBreakBlock(Identifier *ident);
block *getContBlock(Identifier *ident);
block *getSwitchBlock();
block *getDefaultBlock();
FuncDeclaration *getFunc();
};
#endif /* DMD_CONTEXT_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#ifndef DMD_CONTEXT_H
#define DMD_CONTEXT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct Module;
struct Statement;
struct block;
struct Dsymbol;
struct Identifier;
struct Symbol;
struct FuncDeclaration;
struct Blockx;
struct Array;
struct elem;
struct IRState
{
IRState *prev;
Statement *statement;
Module *m; // module
Dsymbol *symbol;
Identifier *ident;
Symbol *shidden; // hidden parameter to function
Symbol *sthis; // 'this' parameter to function (member and nested)
Symbol *sclosure; // pointer to closure instance
Blockx *blx;
Array *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later
elem *ehidden; // transmit hidden pointer to CallExp::toElem()
Symbol *startaddress;
block *breakBlock;
block *contBlock;
block *switchBlock;
block *defaultBlock;
IRState(IRState *irs, Statement *s);
IRState(IRState *irs, Dsymbol *s);
IRState(Module *m, Dsymbol *s);
block *getBreakBlock(Identifier *ident);
block *getContBlock(Identifier *ident);
block *getSwitchBlock();
block *getDefaultBlock();
FuncDeclaration *getFunc();
int arrayBoundsCheck();
};
#endif /* DMD_CONTEXT_H */

440
dmd2/json.c Normal file
View File

@@ -0,0 +1,440 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// This implements the JSON capability.
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <assert.h>
#include "rmem.h"
#include "root.h"
#include "mars.h"
#include "dsymbol.h"
#include "macro.h"
#include "template.h"
#include "lexer.h"
#include "aggregate.h"
#include "declaration.h"
#include "enum.h"
#include "id.h"
#include "module.h"
#include "scope.h"
#include "hdrgen.h"
#include "json.h"
#include "mtype.h"
#include "attrib.h"
#include "cond.h"
const char Pname[] = "name";
const char Pkind[] = "kind";
const char Pfile[] = "file";
const char Pline[] = "line";
const char Ptype[] = "type";
const char Pcomment[] = "comment";
const char Pmembers[] = "members";
void JsonRemoveComma(OutBuffer *buf);
void json_generate(Array *modules)
{ OutBuffer buf;
buf.writestring("[\n");
for (int i = 0; i < modules->dim; i++)
{ Module *m = (Module *)modules->data[i];
if (global.params.verbose)
printf("json gen %s\n", m->toChars());
m->toJsonBuffer(&buf);
buf.writestring(",\n");
}
JsonRemoveComma(&buf);
buf.writestring("]\n");
// Write buf to file
char *arg = global.params.xfilename;
if (!arg || !*arg)
{ // Generate lib file name from first obj name
char *n = (char *)global.params.objfiles->data[0];
n = FileName::name(n);
FileName *fn = FileName::forceExt(n, global.json_ext);
arg = fn->toChars();
}
else if (arg[0] == '-' && arg[1] == 0)
{ // Write to stdout; assume it succeeds
int n = fwrite(buf.data, 1, buf.offset, stdout);
assert(n == buf.offset); // keep gcc happy about return values
return;
}
// if (!FileName::absolute(arg))
// arg = FileName::combine(dir, arg);
FileName *jsonfilename = FileName::defaultExt(arg, global.json_ext);
File *jsonfile = new File(jsonfilename);
assert(jsonfile);
jsonfile->setbuffer(buf.data, buf.offset);
jsonfile->ref = 1;
char *pt = FileName::path(jsonfile->toChars());
if (*pt)
FileName::ensurePathExists(pt);
mem.free(pt);
jsonfile->writev();
}
/*********************************
* Encode string into buf, and wrap it in double quotes.
*/
void JsonString(OutBuffer *buf, const char *s)
{
buf->writeByte('\"');
for (; *s; s++)
{
unsigned char c = (unsigned char) *s;
switch (c)
{
case '\n':
buf->writestring("\\n");
break;
case '\r':
buf->writestring("\\r");
break;
case '\t':
buf->writestring("\\t");
break;
case '\"':
buf->writestring("\\\"");
break;
case '\\':
buf->writestring("\\\\");
break;
case '/':
buf->writestring("\\/");
break;
case '\b':
buf->writestring("\\b");
break;
case '\f':
buf->writestring("\\f");
break;
default:
if (c < 0x20)
buf->printf("\\u%04x", c);
else
// Note that UTF-8 chars pass through here just fine
buf->writeByte(c);
break;
}
}
buf->writeByte('\"');
}
void JsonProperty(OutBuffer *buf, const char *name, const char *value)
{
JsonString(buf, name);
buf->writestring(" : ");
JsonString(buf, value);
buf->writestring(",\n");
}
void JsonProperty(OutBuffer *buf, const char *name, int value)
{
JsonString(buf, name);
buf->writestring(" : ");
buf->printf("%d", value);
buf->writestring(",\n");
}
void JsonRemoveComma(OutBuffer *buf)
{
if (buf->offset >= 2 &&
buf->data[buf->offset - 2] == ',' &&
buf->data[buf->offset - 1] == '\n')
buf->offset -= 2;
}
void Dsymbol::toJsonBuffer(OutBuffer *buf)
{
}
void Module::toJsonBuffer(OutBuffer *buf)
{
buf->writestring("{\n");
if (md)
JsonProperty(buf, Pname, md->toChars());
JsonProperty(buf, Pkind, kind());
JsonProperty(buf, Pfile, srcfile->toChars());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
JsonString(buf, Pmembers);
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
s->toJsonBuffer(buf);
}
JsonRemoveComma(buf);
buf->writestring("]\n");
buf->writestring("}\n");
}
void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
{
//printf("AttribDeclaration::toJsonBuffer()\n");
Array *d = include(NULL, NULL);
if (d)
{
size_t offset = buf->offset;
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
s->toJsonBuffer(buf);
}
JsonRemoveComma(buf);
}
}
void ConditionalDeclaration::toJsonBuffer(OutBuffer *buf)
{
//printf("ConditionalDeclaration::toJsonBuffer()\n");
if (condition->inc)
{
AttribDeclaration::toJsonBuffer(buf);
}
}
void InvariantDeclaration::toJsonBuffer(OutBuffer *buf) { }
void DtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
void StaticCtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
void StaticDtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
void ClassInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
void ModuleInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
void TypeInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
void UnitTestDeclaration::toJsonBuffer(OutBuffer *buf) { }
#if DMDV2
void PostBlitDeclaration::toJsonBuffer(OutBuffer *buf) { }
#endif
void Declaration::toJsonBuffer(OutBuffer *buf)
{
//printf("Declaration::toJsonBuffer()\n");
buf->writestring("{\n");
JsonProperty(buf, Pname, toChars());
JsonProperty(buf, Pkind, kind());
if (type)
JsonProperty(buf, Ptype, type->toChars());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
if (loc.linnum)
JsonProperty(buf, Pline, loc.linnum);
TypedefDeclaration *td = isTypedefDeclaration();
if (td)
{
JsonProperty(buf, "base", td->basetype->toChars());
}
JsonRemoveComma(buf);
buf->writestring("}\n");
}
void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
{
//printf("AggregateDeclaration::toJsonBuffer()\n");
buf->writestring("{\n");
JsonProperty(buf, Pname, toChars());
JsonProperty(buf, Pkind, kind());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
if (loc.linnum)
JsonProperty(buf, Pline, loc.linnum);
ClassDeclaration *cd = isClassDeclaration();
if (cd)
{
if (cd->baseClass)
{
JsonProperty(buf, "base", cd->baseClass->toChars());
}
if (cd->interfaces_dim)
{
JsonString(buf, "interfaces");
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (int i = 0; i < cd->interfaces_dim; i++)
{ BaseClass *b = cd->interfaces[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
JsonString(buf, b->base->toChars());
}
JsonRemoveComma(buf);
buf->writestring("],\n");
}
}
if (members)
{
JsonString(buf, Pmembers);
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
s->toJsonBuffer(buf);
}
JsonRemoveComma(buf);
buf->writestring("]\n");
}
JsonRemoveComma(buf);
buf->writestring("}\n");
}
void TemplateDeclaration::toJsonBuffer(OutBuffer *buf)
{
//printf("TemplateDeclaration::toJsonBuffer()\n");
buf->writestring("{\n");
JsonProperty(buf, Pname, toChars());
JsonProperty(buf, Pkind, kind());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
if (loc.linnum)
JsonProperty(buf, Pline, loc.linnum);
JsonString(buf, Pmembers);
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
s->toJsonBuffer(buf);
}
JsonRemoveComma(buf);
buf->writestring("]\n");
buf->writestring("}\n");
}
void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
{
//printf("EnumDeclaration::toJsonBuffer()\n");
if (isAnonymous())
{
if (members)
{
for (int i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->toJsonBuffer(buf);
buf->writestring(",\n");
}
JsonRemoveComma(buf);
}
return;
}
buf->writestring("{\n");
JsonProperty(buf, Pname, toChars());
JsonProperty(buf, Pkind, kind());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
if (loc.linnum)
JsonProperty(buf, Pline, loc.linnum);
if (memtype)
JsonProperty(buf, "base", memtype->toChars());
if (members)
{
JsonString(buf, Pmembers);
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
}
s->toJsonBuffer(buf);
}
JsonRemoveComma(buf);
buf->writestring("]\n");
}
JsonRemoveComma(buf);
buf->writestring("}\n");
}
void EnumMember::toJsonBuffer(OutBuffer *buf)
{
//printf("EnumMember::toJsonBuffer()\n");
buf->writestring("{\n");
JsonProperty(buf, Pname, toChars());
JsonProperty(buf, Pkind, kind());
if (comment)
JsonProperty(buf, Pcomment, (const char *)comment);
if (loc.linnum)
JsonProperty(buf, Pline, loc.linnum);
JsonRemoveComma(buf);
buf->writestring("}\n");
}

24
dmd2/json.h Normal file
View File

@@ -0,0 +1,24 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_JSON_H
#define DMD_JSON_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct Array;
void json_generate(Array *);
#endif /* DMD_JSON_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,310 +1,318 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_LEXER_H
#define DMD_LEXER_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "mars.h"
struct StringTable;
struct Identifier;
struct Module;
/* Tokens:
( )
[ ]
{ }
< > <= >= == != === !==
<< >> <<= >>= >>> >>>=
+ - += -=
* / % *= /= %=
& | ^ &= |= ^=
= ! ~ @
++ --
. -> : ,
? && ||
*/
enum TOK
{
TOKreserved,
// Other
TOKlparen, TOKrparen,
TOKlbracket, TOKrbracket,
TOKlcurly, TOKrcurly,
TOKcolon, TOKneg,
TOKsemicolon, TOKdotdotdot,
TOKeof, TOKcast,
TOKnull, TOKassert,
TOKtrue, TOKfalse,
TOKarray, TOKcall,
TOKaddress,
TOKtype, TOKthrow,
TOKnew, TOKdelete,
TOKstar, TOKsymoff,
TOKvar, TOKdotvar,
TOKdotti, TOKdotexp,
TOKdottype, TOKslice,
TOKarraylength, TOKversion,
TOKmodule, TOKdollar,
TOKtemplate, TOKdottd,
TOKdeclaration, TOKtypeof,
TOKpragma, TOKdsymbol,
TOKtypeid, TOKuadd,
TOKremove,
TOKnewanonclass, TOKcomment,
TOKarrayliteral, TOKassocarrayliteral,
TOKstructliteral,
// Operators
TOKlt, TOKgt,
TOKle, TOKge,
TOKequal, TOKnotequal,
TOKidentity, TOKnotidentity,
TOKindex, TOKis,
TOKtobool,
// 60
// NCEG floating point compares
// !<>= <> <>= !> !>= !< !<= !<>
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
TOKshl, TOKshr,
TOKshlass, TOKshrass,
TOKushr, TOKushrass,
TOKcat, TOKcatass, // ~ ~=
TOKadd, TOKmin, TOKaddass, TOKminass,
TOKmul, TOKdiv, TOKmod,
TOKmulass, TOKdivass, TOKmodass,
TOKand, TOKor, TOKxor,
TOKandass, TOKorass, TOKxorass,
TOKassign, TOKnot, TOKtilde,
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
TOKdot, TOKarrow, TOKcomma,
TOKquestion, TOKandand, TOKoror,
// 104
// Numeric literals
TOKint32v, TOKuns32v,
TOKint64v, TOKuns64v,
TOKfloat32v, TOKfloat64v, TOKfloat80v,
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
// Char constants
TOKcharv, TOKwcharv, TOKdcharv,
// Leaf operators
TOKidentifier, TOKstring,
TOKthis, TOKsuper,
TOKhalt, TOKtuple,
// Basic types
TOKvoid,
TOKint8, TOKuns8,
TOKint16, TOKuns16,
TOKint32, TOKuns32,
TOKint64, TOKuns64,
TOKfloat32, TOKfloat64, TOKfloat80,
TOKimaginary32, TOKimaginary64, TOKimaginary80,
TOKcomplex32, TOKcomplex64, TOKcomplex80,
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
TOKcent, TOKucent,
// Aggregates
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
TOKmixin,
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKmanifest, TOKimmutable,
// Statements
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
TOKasm, TOKforeach, TOKforeach_reverse,
TOKscope,
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
// Contracts
TOKbody, TOKinvariant,
// Testing
TOKunittest,
// Added after 1.0
TOKref,
TOKmacro,
#if DMDV2
TOKtraits,
TOKoverloadset,
TOKpure,
TOKnothrow,
TOKtls,
TOKgshared,
TOKline,
TOKfile,
TOKshared,
TOKat,
#endif
// LDC specific
#if IN_LLVM
TOKgep,
#endif
TOKMAX
};
#define CASE_BASIC_TYPES \
case TOKwchar: case TOKdchar: \
case TOKbit: case TOKbool: case TOKchar: \
case TOKint8: case TOKuns8: \
case TOKint16: case TOKuns16: \
case TOKint32: case TOKuns32: \
case TOKint64: case TOKuns64: \
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
case TOKvoid
#define CASE_BASIC_TYPES_X(t) \
case TOKvoid: t = Type::tvoid; goto LabelX; \
case TOKint8: t = Type::tint8; goto LabelX; \
case TOKuns8: t = Type::tuns8; goto LabelX; \
case TOKint16: t = Type::tint16; goto LabelX; \
case TOKuns16: t = Type::tuns16; goto LabelX; \
case TOKint32: t = Type::tint32; goto LabelX; \
case TOKuns32: t = Type::tuns32; goto LabelX; \
case TOKint64: t = Type::tint64; goto LabelX; \
case TOKuns64: t = Type::tuns64; goto LabelX; \
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
case TOKbit: t = Type::tbit; goto LabelX; \
case TOKbool: t = Type::tbool; goto LabelX; \
case TOKchar: t = Type::tchar; goto LabelX; \
case TOKwchar: t = Type::twchar; goto LabelX; \
case TOKdchar: t = Type::tdchar; goto LabelX; \
LabelX
struct Token
{
Token *next;
unsigned char *ptr; // pointer to first character of this token within buffer
enum TOK value;
unsigned char *blockComment; // doc comment string prior to this token
unsigned char *lineComment; // doc comment for previous token
union
{
// Integers
d_int32 int32value;
d_uns32 uns32value;
d_int64 int64value;
d_uns64 uns64value;
// Floats
#ifdef IN_GCC
// real_t float80value; // can't use this in a union!
#else
d_float80 float80value;
#endif
struct
{ unsigned char *ustring; // UTF8 string
unsigned len;
unsigned char postfix; // 'c', 'w', 'd'
};
Identifier *ident;
};
#ifdef IN_GCC
real_t float80value; // can't use this in a union!
#endif
static const char *tochars[TOKMAX];
static void *operator new(size_t sz);
int isKeyword();
void print();
const char *toChars();
static const char *toChars(enum TOK);
};
struct Lexer
{
static StringTable stringtable;
static OutBuffer stringbuffer;
static Token *freelist;
Loc loc; // for error messages
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
Token token;
Module *mod;
int doDocComment; // collect doc comment information
int anyToken; // !=0 means seen at least one token
int commentToken; // !=0 means comments are TOKcomment's
Lexer(Module *mod,
unsigned char *base, unsigned begoffset, unsigned endoffset,
int doDocComment, int commentToken);
static void initKeywords();
static Identifier *idPool(const char *s);
static Identifier *uniqueId(const char *s);
static Identifier *uniqueId(const char *s, int num);
TOK nextToken();
TOK peekNext();
TOK peekNext2();
void scan(Token *t);
Token *peek(Token *t);
Token *peekPastParen(Token *t);
unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t);
#if DMDV2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t);
unsigned wchar(unsigned u);
TOK number(Token *t);
TOK inreal(Token *t);
void error(const char *format, ...) IS_PRINTF(2);
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
void pragma();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p);
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
};
#endif /* DMD_LEXER_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_LEXER_H
#define DMD_LEXER_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "mars.h"
struct StringTable;
struct Identifier;
struct Module;
/* Tokens:
( )
[ ]
{ }
< > <= >= == != === !==
<< >> <<= >>= >>> >>>=
+ - += -=
* / % *= /= %=
& | ^ &= |= ^=
= ! ~ @
^^ ^^=
++ --
. -> : ,
? && ||
*/
enum TOK
{
TOKreserved,
// Other
TOKlparen, TOKrparen,
TOKlbracket, TOKrbracket,
TOKlcurly, TOKrcurly,
TOKcolon, TOKneg,
TOKsemicolon, TOKdotdotdot,
TOKeof, TOKcast,
TOKnull, TOKassert,
TOKtrue, TOKfalse,
TOKarray, TOKcall,
TOKaddress,
TOKtype, TOKthrow,
TOKnew, TOKdelete,
TOKstar, TOKsymoff,
TOKvar, TOKdotvar,
TOKdotti, TOKdotexp,
TOKdottype, TOKslice,
TOKarraylength, TOKversion,
TOKmodule, TOKdollar,
TOKtemplate, TOKdottd,
TOKdeclaration, TOKtypeof,
TOKpragma, TOKdsymbol,
TOKtypeid, TOKuadd,
TOKremove,
TOKnewanonclass, TOKcomment,
TOKarrayliteral, TOKassocarrayliteral,
TOKstructliteral,
// Operators
TOKlt, TOKgt,
TOKle, TOKge,
TOKequal, TOKnotequal,
TOKidentity, TOKnotidentity,
TOKindex, TOKis,
TOKtobool,
// 60
// NCEG floating point compares
// !<>= <> <>= !> !>= !< !<= !<>
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
TOKshl, TOKshr,
TOKshlass, TOKshrass,
TOKushr, TOKushrass,
TOKcat, TOKcatass, // ~ ~=
TOKadd, TOKmin, TOKaddass, TOKminass,
TOKmul, TOKdiv, TOKmod,
TOKmulass, TOKdivass, TOKmodass,
TOKand, TOKor, TOKxor,
TOKandass, TOKorass, TOKxorass,
TOKassign, TOKnot, TOKtilde,
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
TOKdot, TOKarrow, TOKcomma,
TOKquestion, TOKandand, TOKoror,
TOKpreplusplus, TOKpreminusminus,
// 106
// Numeric literals
TOKint32v, TOKuns32v,
TOKint64v, TOKuns64v,
TOKfloat32v, TOKfloat64v, TOKfloat80v,
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
// Char constants
TOKcharv, TOKwcharv, TOKdcharv,
// Leaf operators
TOKidentifier, TOKstring,
TOKthis, TOKsuper,
TOKhalt, TOKtuple,
TOKerror,
// Basic types
TOKvoid,
TOKint8, TOKuns8,
TOKint16, TOKuns16,
TOKint32, TOKuns32,
TOKint64, TOKuns64,
TOKfloat32, TOKfloat64, TOKfloat80,
TOKimaginary32, TOKimaginary64, TOKimaginary80,
TOKcomplex32, TOKcomplex64, TOKcomplex80,
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
TOKcent, TOKucent,
// 152
// Aggregates
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
TOKmixin,
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKmanifest, TOKimmutable,
// Statements
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
TOKasm, TOKforeach, TOKforeach_reverse,
TOKscope,
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
// Contracts
TOKbody, TOKinvariant,
// Testing
TOKunittest,
// Added after 1.0
TOKref,
TOKmacro,
#if DMDV2
TOKtraits,
TOKoverloadset,
TOKpure,
TOKnothrow,
TOKtls,
TOKgshared,
TOKline,
TOKfile,
TOKshared,
TOKat,
TOKpow,
TOKpowass,
#endif
// LDC specific
#if IN_LLVM
TOKgep,
#endif
TOKMAX
};
#define TOKwild TOKinout
#define BASIC_TYPES \
TOKwchar: case TOKdchar: \
case TOKbit: case TOKbool: case TOKchar: \
case TOKint8: case TOKuns8: \
case TOKint16: case TOKuns16: \
case TOKint32: case TOKuns32: \
case TOKint64: case TOKuns64: \
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
case TOKvoid
#define BASIC_TYPES_X(t) \
TOKvoid: t = Type::tvoid; goto LabelX; \
case TOKint8: t = Type::tint8; goto LabelX; \
case TOKuns8: t = Type::tuns8; goto LabelX; \
case TOKint16: t = Type::tint16; goto LabelX; \
case TOKuns16: t = Type::tuns16; goto LabelX; \
case TOKint32: t = Type::tint32; goto LabelX; \
case TOKuns32: t = Type::tuns32; goto LabelX; \
case TOKint64: t = Type::tint64; goto LabelX; \
case TOKuns64: t = Type::tuns64; goto LabelX; \
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
case TOKbit: t = Type::tbit; goto LabelX; \
case TOKbool: t = Type::tbool; goto LabelX; \
case TOKchar: t = Type::tchar; goto LabelX; \
case TOKwchar: t = Type::twchar; goto LabelX; \
case TOKdchar: t = Type::tdchar; goto LabelX; \
LabelX
struct Token
{
Token *next;
unsigned char *ptr; // pointer to first character of this token within buffer
enum TOK value;
unsigned char *blockComment; // doc comment string prior to this token
unsigned char *lineComment; // doc comment for previous token
union
{
// Integers
d_int32 int32value;
d_uns32 uns32value;
d_int64 int64value;
d_uns64 uns64value;
// Floats
#ifdef IN_GCC
// real_t float80value; // can't use this in a union!
#else
d_float80 float80value;
#endif
struct
{ unsigned char *ustring; // UTF8 string
unsigned len;
unsigned char postfix; // 'c', 'w', 'd'
};
Identifier *ident;
};
#ifdef IN_GCC
real_t float80value; // can't use this in a union!
#endif
static const char *tochars[TOKMAX];
static void *operator new(size_t sz);
int isKeyword();
void print();
const char *toChars();
static const char *toChars(enum TOK);
};
struct Lexer
{
static StringTable stringtable;
static OutBuffer stringbuffer;
static Token *freelist;
Loc loc; // for error messages
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
Token token;
Module *mod;
int doDocComment; // collect doc comment information
int anyToken; // !=0 means seen at least one token
int commentToken; // !=0 means comments are TOKcomment's
Lexer(Module *mod,
unsigned char *base, unsigned begoffset, unsigned endoffset,
int doDocComment, int commentToken);
static void initKeywords();
static Identifier *idPool(const char *s);
static Identifier *uniqueId(const char *s);
static Identifier *uniqueId(const char *s, int num);
TOK nextToken();
TOK peekNext();
TOK peekNext2();
void scan(Token *t);
Token *peek(Token *t);
Token *peekPastParen(Token *t);
unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t);
#if DMDV2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t);
unsigned wchar(unsigned u);
TOK number(Token *t);
TOK inreal(Token *t);
void error(const char *format, ...) IS_PRINTF(2);
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
void pragma();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p);
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
};
#endif /* DMD_LEXER_H */

View File

@@ -1,49 +1,49 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_LIB_H
#define DMD_LIB_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct ObjModule;
struct ObjSymbol
{
char *name;
ObjModule *om;
};
struct Library
{
File *libfile;
Array objmodules; // ObjModule[]
Array objsymbols; // ObjSymbol[]
StringTable tab;
Library();
void setFilename(char *dir, char *filename);
void addObject(const char *module_name, void *buf, size_t buflen);
void addLibrary(void *buf, size_t buflen);
void write();
private:
void addSymbol(ObjModule *om, char *name, int pickAny = 0);
void scanObjModule(ObjModule *om);
unsigned short numDictPages(unsigned padding);
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
void WriteLibToBuffer(OutBuffer *libbuf);
};
#endif /* DMD_LIB_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_LIB_H
#define DMD_LIB_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct ObjModule;
struct ObjSymbol
{
char *name;
ObjModule *om;
};
struct Library
{
File *libfile;
Array objmodules; // ObjModule[]
Array objsymbols; // ObjSymbol[]
StringTable tab;
Library();
void setFilename(char *dir, char *filename);
void addObject(const char *module_name, void *buf, size_t buflen);
void addLibrary(void *buf, size_t buflen);
void write();
private:
void addSymbol(ObjModule *om, char *name, int pickAny = 0);
void scanObjModule(ObjModule *om);
unsigned short numDictPages(unsigned padding);
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
void WriteLibToBuffer(OutBuffer *libbuf);
};
#endif /* DMD_LIB_H */

View File

@@ -1,449 +1,449 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
/* Simple macro text processor.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <assert.h>
#include "rmem.h"
#include "root.h"
#include "macro.h"
#define isidstart(c) (isalpha(c) || (c) == '_')
#define isidchar(c) (isalnum(c) || (c) == '_')
unsigned char *memdup(unsigned char *p, size_t len)
{
return (unsigned char *)memcpy(mem.malloc(len), p, len);
}
Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
{
next = NULL;
#if 1
this->name = name;
this->namelen = namelen;
this->text = text;
this->textlen = textlen;
#else
this->name = name;
this->namelen = namelen;
this->text = text;
this->textlen = textlen;
#endif
inuse = 0;
}
Macro *Macro::search(unsigned char *name, size_t namelen)
{ Macro *table;
//printf("Macro::search(%.*s)\n", namelen, name);
for (table = this; table; table = table->next)
{
if (table->namelen == namelen &&
memcmp(table->name, name, namelen) == 0)
{
//printf("\tfound %d\n", table->textlen);
break;
}
}
return table;
}
Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
{
//printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
Macro *table;
//assert(ptable);
for (table = *ptable; table; table = table->next)
{
if (table->namelen == namelen &&
memcmp(table->name, name, namelen) == 0)
{
table->text = text;
table->textlen = textlen;
return table;
}
}
table = new Macro(name, namelen, text, textlen);
table->next = *ptable;
*ptable = table;
return table;
}
/**********************************************************
* Given buffer p[0..end], extract argument marg[0..marglen].
* Params:
* n 0: get entire argument
* 1..9: get nth argument
* -1: get 2nd through end
*/
unsigned extractArgN(unsigned char *p, unsigned end, unsigned char **pmarg, unsigned *pmarglen, int n)
{
/* Scan forward for matching right parenthesis.
* Nest parentheses.
* Skip over $( and $)
* Skip over "..." and '...' strings inside HTML tags.
* Skip over <!-- ... --> comments.
* Skip over previous macro insertions
* Set marglen.
*/
unsigned parens = 1;
unsigned char instring = 0;
unsigned incomment = 0;
unsigned intag = 0;
unsigned inexp = 0;
unsigned argn = 0;
unsigned v = 0;
Largstart:
#if 1
// Skip first space, if any, to find the start of the macro argument
if (v < end && isspace(p[v]))
v++;
#else
// Skip past spaces to find the start of the macro argument
for (; v < end && isspace(p[v]); v++)
;
#endif
*pmarg = p + v;
for (; v < end; v++)
{ unsigned char c = p[v];
switch (c)
{
case ',':
if (!inexp && !instring && !incomment && parens == 1)
{
argn++;
if (argn == 1 && n == -1)
{ v++;
goto Largstart;
}
if (argn == n)
break;
if (argn + 1 == n)
{ v++;
goto Largstart;
}
}
continue;
case '(':
if (!inexp && !instring && !incomment)
parens++;
continue;
case ')':
if (!inexp && !instring && !incomment && --parens == 0)
{
break;
}
continue;
case '"':
case '\'':
if (!inexp && !incomment && intag)
{
if (c == instring)
instring = 0;
else if (!instring)
instring = c;
}
continue;
case '<':
if (!inexp && !instring && !incomment)
{
if (v + 6 < end &&
p[v + 1] == '!' &&
p[v + 2] == '-' &&
p[v + 3] == '-')
{
incomment = 1;
v += 3;
}
else if (v + 2 < end &&
isalpha(p[v + 1]))
intag = 1;
}
continue;
case '>':
if (!inexp)
intag = 0;
continue;
case '-':
if (!inexp &&
!instring &&
incomment &&
v + 2 < end &&
p[v + 1] == '-' &&
p[v + 2] == '>')
{
incomment = 0;
v += 2;
}
continue;
case 0xFF:
if (v + 1 < end)
{
if (p[v + 1] == '{')
inexp++;
else if (p[v + 1] == '}')
inexp--;
}
continue;
default:
continue;
}
break;
}
if (argn == 0 && n == -1)
*pmarg = p + v;
*pmarglen = p + v - *pmarg;
//printf("extractArg%d('%.*s') = '%.*s'\n", n, end, p, *pmarglen, *pmarg);
return v;
}
/*****************************************************
* Expand macro in place in buf.
* Only look at the text in buf from start to end.
*/
void Macro::expand(OutBuffer *buf, unsigned start, unsigned *pend,
unsigned char *arg, unsigned arglen)
{
#if 0
printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
printf("Buf is: '%.*s'\n", *pend - start, buf->data + start);
#endif
static int nest;
if (nest > 100) // limit recursive expansion
return;
nest++;
unsigned end = *pend;
assert(start <= end);
assert(end <= buf->offset);
/* First pass - replace $0
*/
arg = memdup(arg, arglen);
for (unsigned u = start; u + 1 < end; )
{
unsigned char *p = buf->data; // buf->data is not loop invariant
/* Look for $0, but not $$0, and replace it with arg.
*/
if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))
{
if (u > start && p[u - 1] == '$')
{ // Don't expand $$0, but replace it with $0
buf->remove(u - 1, 1);
end--;
u += 1; // now u is one past the closing '1'
continue;
}
unsigned char c = p[u + 1];
int n = (c == '+') ? -1 : c - '0';
unsigned char *marg;
unsigned marglen;
extractArgN(arg, arglen, &marg, &marglen, n);
if (marglen == 0)
{ // Just remove macro invocation
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
buf->remove(u, 2);
end -= 2;
}
else if (c == '+')
{
// Replace '$+' with 'arg'
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
buf->remove(u, 2);
buf->insert(u, marg, marglen);
end += marglen - 2;
// Scan replaced text for further expansion
unsigned mend = u + marglen;
expand(buf, u, &mend, NULL, 0);
end += mend - (u + marglen);
u = mend;
}
else
{
// Replace '$1' with '\xFF{arg\xFF}'
//printf("Replacing '$%c' with '\xFF{%.*s\xFF}'\n", p[u + 1], marglen, marg);
buf->data[u] = 0xFF;
buf->data[u + 1] = '{';
buf->insert(u + 2, marg, marglen);
buf->insert(u + 2 + marglen, "\xFF}", 2);
end += -2 + 2 + marglen + 2;
// Scan replaced text for further expansion
unsigned mend = u + 2 + marglen;
expand(buf, u + 2, &mend, NULL, 0);
end += mend - (u + 2 + marglen);
u = mend;
}
//printf("u = %d, end = %d\n", u, end);
//printf("#%.*s#\n", end, &buf->data[0]);
continue;
}
u++;
}
/* Second pass - replace other macros
*/
for (unsigned u = start; u + 4 < end; )
{
unsigned char *p = buf->data; // buf->data is not loop invariant
/* A valid start of macro expansion is $(c, where c is
* an id start character, and not $$(c.
*/
if (p[u] == '$' && p[u + 1] == '(' && isidstart(p[u + 2]))
{
//printf("\tfound macro start '%c'\n", p[u + 2]);
unsigned char *name = p + u + 2;
unsigned namelen = 0;
unsigned char *marg;
unsigned marglen;
unsigned v;
/* Scan forward to find end of macro name and
* beginning of macro argument (marg).
*/
for (v = u + 2; v < end; v++)
{ unsigned char c = p[v];
if (!isidchar(c))
{ // We've gone past the end of the macro name.
namelen = v - (u + 2);
break;
}
}
v += extractArgN(p + v, end - v, &marg, &marglen, 0);
assert(v <= end);
if (v < end)
{ // v is on the closing ')'
if (u > start && p[u - 1] == '$')
{ // Don't expand $$(NAME), but replace it with $(NAME)
buf->remove(u - 1, 1);
end--;
u = v; // now u is one past the closing ')'
continue;
}
Macro *m = search(name, namelen);
if (m)
{
#if 0
if (m->textlen && m->text[0] == ' ')
{ m->text++;
m->textlen--;
}
#endif
if (m->inuse && marglen == 0)
{ // Remove macro invocation
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
}
else if (m->inuse && arglen == marglen && memcmp(arg, marg, arglen) == 0)
{ // Recursive expansion; just leave in place
}
else
{
//printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text);
#if 1
marg = memdup(marg, marglen);
// Insert replacement text
buf->spread(v + 1, 2 + m->textlen + 2);
buf->data[v + 1] = 0xFF;
buf->data[v + 2] = '{';
memcpy(buf->data + v + 3, m->text, m->textlen);
buf->data[v + 3 + m->textlen] = 0xFF;
buf->data[v + 3 + m->textlen + 1] = '}';
end += 2 + m->textlen + 2;
// Scan replaced text for further expansion
m->inuse++;
unsigned mend = v + 1 + 2+m->textlen+2;
expand(buf, v + 1, &mend, marg, marglen);
end += mend - (v + 1 + 2+m->textlen+2);
m->inuse--;
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
u += mend - (v + 1);
#else
// Insert replacement text
buf->insert(v + 1, m->text, m->textlen);
end += m->textlen;
// Scan replaced text for further expansion
m->inuse++;
unsigned mend = v + 1 + m->textlen;
expand(buf, v + 1, &mend, marg, marglen);
end += mend - (v + 1 + m->textlen);
m->inuse--;
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
u += mend - (v + 1);
#endif
mem.free(marg);
//printf("u = %d, end = %d\n", u, end);
//printf("#%.*s#\n", end - u, &buf->data[u]);
continue;
}
}
else
{
// Replace $(NAME) with nothing
buf->remove(u, v + 1 - u);
end -= (v + 1 - u);
continue;
}
}
}
u++;
}
mem.free(arg);
*pend = end;
nest--;
}
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
/* Simple macro text processor.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <assert.h>
#include "rmem.h"
#include "root.h"
#include "macro.h"
#define isidstart(c) (isalpha(c) || (c) == '_')
#define isidchar(c) (isalnum(c) || (c) == '_')
unsigned char *memdup(unsigned char *p, size_t len)
{
return (unsigned char *)memcpy(mem.malloc(len), p, len);
}
Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
{
next = NULL;
#if 1
this->name = name;
this->namelen = namelen;
this->text = text;
this->textlen = textlen;
#else
this->name = name;
this->namelen = namelen;
this->text = text;
this->textlen = textlen;
#endif
inuse = 0;
}
Macro *Macro::search(unsigned char *name, size_t namelen)
{ Macro *table;
//printf("Macro::search(%.*s)\n", namelen, name);
for (table = this; table; table = table->next)
{
if (table->namelen == namelen &&
memcmp(table->name, name, namelen) == 0)
{
//printf("\tfound %d\n", table->textlen);
break;
}
}
return table;
}
Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
{
//printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
Macro *table;
//assert(ptable);
for (table = *ptable; table; table = table->next)
{
if (table->namelen == namelen &&
memcmp(table->name, name, namelen) == 0)
{
table->text = text;
table->textlen = textlen;
return table;
}
}
table = new Macro(name, namelen, text, textlen);
table->next = *ptable;
*ptable = table;
return table;
}
/**********************************************************
* Given buffer p[0..end], extract argument marg[0..marglen].
* Params:
* n 0: get entire argument
* 1..9: get nth argument
* -1: get 2nd through end
*/
unsigned extractArgN(unsigned char *p, unsigned end, unsigned char **pmarg, unsigned *pmarglen, int n)
{
/* Scan forward for matching right parenthesis.
* Nest parentheses.
* Skip over $( and $)
* Skip over "..." and '...' strings inside HTML tags.
* Skip over <!-- ... --> comments.
* Skip over previous macro insertions
* Set marglen.
*/
unsigned parens = 1;
unsigned char instring = 0;
unsigned incomment = 0;
unsigned intag = 0;
unsigned inexp = 0;
unsigned argn = 0;
unsigned v = 0;
Largstart:
#if 1
// Skip first space, if any, to find the start of the macro argument
if (v < end && isspace(p[v]))
v++;
#else
// Skip past spaces to find the start of the macro argument
for (; v < end && isspace(p[v]); v++)
;
#endif
*pmarg = p + v;
for (; v < end; v++)
{ unsigned char c = p[v];
switch (c)
{
case ',':
if (!inexp && !instring && !incomment && parens == 1)
{
argn++;
if (argn == 1 && n == -1)
{ v++;
goto Largstart;
}
if (argn == n)
break;
if (argn + 1 == n)
{ v++;
goto Largstart;
}
}
continue;
case '(':
if (!inexp && !instring && !incomment)
parens++;
continue;
case ')':
if (!inexp && !instring && !incomment && --parens == 0)
{
break;
}
continue;
case '"':
case '\'':
if (!inexp && !incomment && intag)
{
if (c == instring)
instring = 0;
else if (!instring)
instring = c;
}
continue;
case '<':
if (!inexp && !instring && !incomment)
{
if (v + 6 < end &&
p[v + 1] == '!' &&
p[v + 2] == '-' &&
p[v + 3] == '-')
{
incomment = 1;
v += 3;
}
else if (v + 2 < end &&
isalpha(p[v + 1]))
intag = 1;
}
continue;
case '>':
if (!inexp)
intag = 0;
continue;
case '-':
if (!inexp &&
!instring &&
incomment &&
v + 2 < end &&
p[v + 1] == '-' &&
p[v + 2] == '>')
{
incomment = 0;
v += 2;
}
continue;
case 0xFF:
if (v + 1 < end)
{
if (p[v + 1] == '{')
inexp++;
else if (p[v + 1] == '}')
inexp--;
}
continue;
default:
continue;
}
break;
}
if (argn == 0 && n == -1)
*pmarg = p + v;
*pmarglen = p + v - *pmarg;
//printf("extractArg%d('%.*s') = '%.*s'\n", n, end, p, *pmarglen, *pmarg);
return v;
}
/*****************************************************
* Expand macro in place in buf.
* Only look at the text in buf from start to end.
*/
void Macro::expand(OutBuffer *buf, unsigned start, unsigned *pend,
unsigned char *arg, unsigned arglen)
{
#if 0
printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
printf("Buf is: '%.*s'\n", *pend - start, buf->data + start);
#endif
static int nest;
if (nest > 100) // limit recursive expansion
return;
nest++;
unsigned end = *pend;
assert(start <= end);
assert(end <= buf->offset);
/* First pass - replace $0
*/
arg = memdup(arg, arglen);
for (unsigned u = start; u + 1 < end; )
{
unsigned char *p = buf->data; // buf->data is not loop invariant
/* Look for $0, but not $$0, and replace it with arg.
*/
if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))
{
if (u > start && p[u - 1] == '$')
{ // Don't expand $$0, but replace it with $0
buf->remove(u - 1, 1);
end--;
u += 1; // now u is one past the closing '1'
continue;
}
unsigned char c = p[u + 1];
int n = (c == '+') ? -1 : c - '0';
unsigned char *marg;
unsigned marglen;
extractArgN(arg, arglen, &marg, &marglen, n);
if (marglen == 0)
{ // Just remove macro invocation
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
buf->remove(u, 2);
end -= 2;
}
else if (c == '+')
{
// Replace '$+' with 'arg'
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
buf->remove(u, 2);
buf->insert(u, marg, marglen);
end += marglen - 2;
// Scan replaced text for further expansion
unsigned mend = u + marglen;
expand(buf, u, &mend, NULL, 0);
end += mend - (u + marglen);
u = mend;
}
else
{
// Replace '$1' with '\xFF{arg\xFF}'
//printf("Replacing '$%c' with '\xFF{%.*s\xFF}'\n", p[u + 1], marglen, marg);
buf->data[u] = 0xFF;
buf->data[u + 1] = '{';
buf->insert(u + 2, marg, marglen);
buf->insert(u + 2 + marglen, "\xFF}", 2);
end += -2 + 2 + marglen + 2;
// Scan replaced text for further expansion
unsigned mend = u + 2 + marglen;
expand(buf, u + 2, &mend, NULL, 0);
end += mend - (u + 2 + marglen);
u = mend;
}
//printf("u = %d, end = %d\n", u, end);
//printf("#%.*s#\n", end, &buf->data[0]);
continue;
}
u++;
}
/* Second pass - replace other macros
*/
for (unsigned u = start; u + 4 < end; )
{
unsigned char *p = buf->data; // buf->data is not loop invariant
/* A valid start of macro expansion is $(c, where c is
* an id start character, and not $$(c.
*/
if (p[u] == '$' && p[u + 1] == '(' && isidstart(p[u + 2]))
{
//printf("\tfound macro start '%c'\n", p[u + 2]);
unsigned char *name = p + u + 2;
unsigned namelen = 0;
unsigned char *marg;
unsigned marglen;
unsigned v;
/* Scan forward to find end of macro name and
* beginning of macro argument (marg).
*/
for (v = u + 2; v < end; v++)
{ unsigned char c = p[v];
if (!isidchar(c))
{ // We've gone past the end of the macro name.
namelen = v - (u + 2);
break;
}
}
v += extractArgN(p + v, end - v, &marg, &marglen, 0);
assert(v <= end);
if (v < end)
{ // v is on the closing ')'
if (u > start && p[u - 1] == '$')
{ // Don't expand $$(NAME), but replace it with $(NAME)
buf->remove(u - 1, 1);
end--;
u = v; // now u is one past the closing ')'
continue;
}
Macro *m = search(name, namelen);
if (m)
{
#if 0
if (m->textlen && m->text[0] == ' ')
{ m->text++;
m->textlen--;
}
#endif
if (m->inuse && marglen == 0)
{ // Remove macro invocation
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
}
else if (m->inuse && arglen == marglen && memcmp(arg, marg, arglen) == 0)
{ // Recursive expansion; just leave in place
}
else
{
//printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text);
#if 1
marg = memdup(marg, marglen);
// Insert replacement text
buf->spread(v + 1, 2 + m->textlen + 2);
buf->data[v + 1] = 0xFF;
buf->data[v + 2] = '{';
memcpy(buf->data + v + 3, m->text, m->textlen);
buf->data[v + 3 + m->textlen] = 0xFF;
buf->data[v + 3 + m->textlen + 1] = '}';
end += 2 + m->textlen + 2;
// Scan replaced text for further expansion
m->inuse++;
unsigned mend = v + 1 + 2+m->textlen+2;
expand(buf, v + 1, &mend, marg, marglen);
end += mend - (v + 1 + 2+m->textlen+2);
m->inuse--;
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
u += mend - (v + 1);
#else
// Insert replacement text
buf->insert(v + 1, m->text, m->textlen);
end += m->textlen;
// Scan replaced text for further expansion
m->inuse++;
unsigned mend = v + 1 + m->textlen;
expand(buf, v + 1, &mend, marg, marglen);
end += mend - (v + 1 + m->textlen);
m->inuse--;
buf->remove(u, v + 1 - u);
end -= v + 1 - u;
u += mend - (v + 1);
#endif
mem.free(marg);
//printf("u = %d, end = %d\n", u, end);
//printf("#%.*s#\n", end - u, &buf->data[u]);
continue;
}
}
else
{
// Replace $(NAME) with nothing
buf->remove(u, v + 1 - u);
end -= (v + 1 - u);
continue;
}
}
}
u++;
}
mem.free(arg);
*pend = end;
nest--;
}

View File

@@ -1,44 +1,44 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MACRO_H
#define DMD_MACRO_H 1
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include "root.h"
class Macro
{
Macro *next; // next in list
unsigned char *name; // macro name
size_t namelen; // length of macro name
unsigned char *text; // macro replacement text
size_t textlen; // length of replacement text
int inuse; // macro is in use (don't expand)
Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
Macro *search(unsigned char *name, size_t namelen);
public:
static Macro *define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
void expand(OutBuffer *buf, unsigned start, unsigned *pend,
unsigned char *arg, unsigned arglen);
};
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MACRO_H
#define DMD_MACRO_H 1
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include "root.h"
class Macro
{
Macro *next; // next in list
unsigned char *name; // macro name
size_t namelen; // length of macro name
unsigned char *text; // macro replacement text
size_t textlen; // length of replacement text
int inuse; // macro is in use (don't expand)
Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
Macro *search(unsigned char *name, size_t namelen);
public:
static Macro *define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
void expand(OutBuffer *buf, unsigned start, unsigned *pend,
unsigned char *arg, unsigned arglen);
};
#endif

View File

@@ -1,298 +1,298 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "root.h"
#include "init.h"
#include "declaration.h"
#include "aggregate.h"
#include "mtype.h"
#include "attrib.h"
#include "template.h"
#include "id.h"
#include "module.h"
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
char *cpp_mangle(Dsymbol *s);
#endif
char *mangle(Declaration *sthis)
{
OutBuffer buf;
char *id;
Dsymbol *s;
//printf("::mangle(%s)\n", sthis->toChars());
s = sthis;
do
{
//printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
if (s->ident)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (s != sthis && fd)
{
id = mangle(fd);
buf.prependstring(id);
goto L1;
}
else
{
id = s->ident->toChars();
int len = strlen(id);
char tmp[sizeof(len) * 3 + 1];
buf.prependstring(id);
sprintf(tmp, "%d", len);
buf.prependstring(tmp);
}
}
else
buf.prependstring("0");
s = s->parent;
} while (s);
// buf.prependstring("_D");
L1:
//printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
//printf("sthis->type = %s\n", sthis->type->toChars());
FuncDeclaration *fd = sthis->isFuncDeclaration();
if (fd && (fd->needThis() || fd->isNested()))
buf.writeByte(Type::needThisPrefix());
if (sthis->type->deco)
buf.writestring(sthis->type->deco);
else
{
#ifdef DEBUG
if (!fd->inferRetType)
printf("%s\n", fd->toChars());
#endif
assert(fd->inferRetType);
}
id = buf.toChars();
buf.data = NULL;
return id;
}
char *Declaration::mangle()
#if __DMC__
__out(result)
{
int len = strlen(result);
assert(len > 0);
//printf("mangle: '%s' => '%s'\n", toChars(), result);
for (int i = 0; i < len; i++)
{
assert(result[i] == '_' ||
result[i] == '@' ||
isalnum(result[i]) || result[i] & 0x80);
}
}
__body
#endif
{
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
{
// If it's not a D declaration, no mangling
switch (linkage)
{
case LINKd:
break;
#if IN_LLVM
case LINKintrinsic:
#endif
case LINKc:
case LINKwindows:
case LINKpascal:
return ident->toChars();
case LINKcpp:
#if CPP_MANGLE
return cpp_mangle(this);
#else
// Windows C++ mangling is done by C++ back end
return ident->toChars();
#endif
case LINKdefault:
error("forward declaration");
return ident->toChars();
default:
fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
assert(0);
}
}
char *p = ::mangle(this);
OutBuffer buf;
buf.writestring("_D");
buf.writestring(p);
p = buf.toChars();
buf.data = NULL;
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
return p;
}
char *FuncDeclaration::mangle()
#if __DMC__
__out(result)
{
assert(strlen(result) > 0);
}
__body
#endif
{
if (isMain())
return (char *)"_Dmain";
if (isWinMain() || isDllMain() || ident == Id::tls_get_addr)
return ident->toChars();
assert(this);
return Declaration::mangle();
}
char *StructDeclaration::mangle()
{
//printf("StructDeclaration::mangle() '%s'\n", toChars());
return Dsymbol::mangle();
}
char *TypedefDeclaration::mangle()
{
//printf("TypedefDeclaration::mangle() '%s'\n", toChars());
return Dsymbol::mangle();
}
char *ClassDeclaration::mangle()
{
Dsymbol *parentsave = parent;
//printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
/* These are reserved to the compiler, so keep simple
* names for them.
*/
if (ident == Id::Exception)
{ if (parent->ident == Id::object)
parent = NULL;
}
else if (ident == Id::TypeInfo ||
// ident == Id::Exception ||
ident == Id::TypeInfo_Struct ||
ident == Id::TypeInfo_Class ||
ident == Id::TypeInfo_Typedef ||
ident == Id::TypeInfo_Tuple ||
this == object ||
this == classinfo ||
this == Module::moduleinfo ||
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
)
parent = NULL;
char *id = Dsymbol::mangle();
parent = parentsave;
return id;
}
char *TemplateInstance::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("TemplateInstance::mangle() %s", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (!tempdecl)
error("is not defined");
else if (tempdecl->parent)
{
char *p = tempdecl->parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
return id;
}
#if IN_LLVM
char *TemplateMixin::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("TemplateMixin::mangle() %s", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (parent)
{
char *p = parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
return id;
}
#endif
char *Dsymbol::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("Dsymbol::mangle() '%s'", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (parent)
{
char *p = parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
return id;
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "root.h"
#include "init.h"
#include "declaration.h"
#include "aggregate.h"
#include "mtype.h"
#include "attrib.h"
#include "template.h"
#include "id.h"
#include "module.h"
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
char *cpp_mangle(Dsymbol *s);
#endif
char *mangle(Declaration *sthis)
{
OutBuffer buf;
char *id;
Dsymbol *s;
//printf("::mangle(%s)\n", sthis->toChars());
s = sthis;
do
{
//printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
if (s->ident)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (s != sthis && fd)
{
id = mangle(fd);
buf.prependstring(id);
goto L1;
}
else
{
id = s->ident->toChars();
int len = strlen(id);
char tmp[sizeof(len) * 3 + 1];
buf.prependstring(id);
sprintf(tmp, "%d", len);
buf.prependstring(tmp);
}
}
else
buf.prependstring("0");
s = s->parent;
} while (s);
// buf.prependstring("_D");
L1:
//printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
//printf("sthis->type = %s\n", sthis->type->toChars());
FuncDeclaration *fd = sthis->isFuncDeclaration();
if (fd && (fd->needThis() || fd->isNested()))
buf.writeByte(Type::needThisPrefix());
if (sthis->type->deco)
buf.writestring(sthis->type->deco);
else
{
#ifdef DEBUG
if (!fd->inferRetType)
printf("%s\n", fd->toChars());
#endif
assert(fd && fd->inferRetType);
}
id = buf.toChars();
buf.data = NULL;
return id;
}
char *Declaration::mangle()
#if __DMC__
__out(result)
{
int len = strlen(result);
assert(len > 0);
//printf("mangle: '%s' => '%s'\n", toChars(), result);
for (int i = 0; i < len; i++)
{
assert(result[i] == '_' ||
result[i] == '@' ||
isalnum(result[i]) || result[i] & 0x80);
}
}
__body
#endif
{
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
{
// If it's not a D declaration, no mangling
switch (linkage)
{
case LINKd:
break;
#if IN_LLVM
case LINKintrinsic:
#endif
case LINKc:
case LINKwindows:
case LINKpascal:
return ident->toChars();
case LINKcpp:
#if CPP_MANGLE
return cpp_mangle(this);
#else
// Windows C++ mangling is done by C++ back end
return ident->toChars();
#endif
case LINKdefault:
error("forward declaration");
return ident->toChars();
default:
fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
assert(0);
}
}
char *p = ::mangle(this);
OutBuffer buf;
buf.writestring("_D");
buf.writestring(p);
p = buf.toChars();
buf.data = NULL;
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
return p;
}
char *FuncDeclaration::mangle()
#if __DMC__
__out(result)
{
assert(strlen(result) > 0);
}
__body
#endif
{
if (isMain())
return (char *)"_Dmain";
if (isWinMain() || isDllMain() || ident == Id::tls_get_addr)
return ident->toChars();
assert(this);
return Declaration::mangle();
}
char *StructDeclaration::mangle()
{
//printf("StructDeclaration::mangle() '%s'\n", toChars());
return Dsymbol::mangle();
}
char *TypedefDeclaration::mangle()
{
//printf("TypedefDeclaration::mangle() '%s'\n", toChars());
return Dsymbol::mangle();
}
char *ClassDeclaration::mangle()
{
Dsymbol *parentsave = parent;
//printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
/* These are reserved to the compiler, so keep simple
* names for them.
*/
if (ident == Id::Exception)
{ if (parent->ident == Id::object)
parent = NULL;
}
else if (ident == Id::TypeInfo ||
// ident == Id::Exception ||
ident == Id::TypeInfo_Struct ||
ident == Id::TypeInfo_Class ||
ident == Id::TypeInfo_Typedef ||
ident == Id::TypeInfo_Tuple ||
this == object ||
this == classinfo ||
this == Module::moduleinfo ||
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
)
parent = NULL;
char *id = Dsymbol::mangle();
parent = parentsave;
return id;
}
char *TemplateInstance::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("TemplateInstance::mangle() %s", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (!tempdecl)
error("is not defined");
else if (tempdecl->parent)
{
char *p = tempdecl->parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
return id;
}
#if IN_LLVM
char *TemplateMixin::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("TemplateMixin::mangle() %s", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (parent)
{
char *p = parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
return id;
}
#endif
char *Dsymbol::mangle()
{
OutBuffer buf;
char *id;
#if 0
printf("Dsymbol::mangle() '%s'", toChars());
if (parent)
printf(" parent = %s %s", parent->kind(), parent->toChars());
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (parent)
{
char *p = parent->mangle();
if (p[0] == '_' && p[1] == 'D')
p += 2;
buf.writestring(p);
}
buf.printf("%zu%s", strlen(id), id);
id = buf.toChars();
buf.data = NULL;
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
return id;
}

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -36,6 +36,7 @@
#include "expression.h"
#include "lexer.h"
#include "lib.h"
#include "json.h"
#if WINDOWS_SEH
#include <windows.h>
@@ -60,6 +61,8 @@ Global::Global()
hdr_ext = "di";
doc_ext = "html";
ddoc_ext = "ddoc";
json_ext = "json";
map_ext = "map";
#if IN_LLVM
ll_ext = "ll";
@@ -89,13 +92,13 @@ Global::Global()
#endif
#endif
copyright = "Copyright (c) 1999-2009 by Digital Mars";
copyright = "Copyright (c) 1999-2010 by Digital Mars";
written = "written by Walter Bright"
#if TARGET_NET
"\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
#endif
;
version = "v2.032";
version = "v2.049";
#if IN_LLVM
ldc_version = "LDC trunk";
llvm_version = "LLVM 2.8";
@@ -116,11 +119,11 @@ char *Loc::toChars()
if (filename)
{
buf.printf("%s", filename);
buf.printf("%s", filename);
}
if (linnum)
buf.printf("(%d)", linnum);
buf.printf("(%d)", linnum);
buf.writeByte(0);
return (char *)buf.extractData();
}
@@ -150,29 +153,34 @@ void error(Loc loc, const char *format, ...)
void warning(Loc loc, const char *format, ...)
{
if (global.params.warnings && !global.gag)
{
va_list ap;
va_start(ap, format);
vwarning(loc, format, ap);
va_end( ap );
}
va_list ap;
va_start(ap, format);
vwarning(loc, format, ap);
va_end( ap );
}
void verror(Loc loc, const char *format, va_list ap)
{
if (!global.gag)
{
char *p = loc.toChars();
char *p = loc.toChars();
if (*p)
fprintf(stdmsg, "%s: ", p);
mem.free(p);
if (*p)
fprintf(stdmsg, "%s: ", p);
mem.free(p);
fprintf(stdmsg, "Error: ");
vfprintf(stdmsg, format, ap);
fprintf(stdmsg, "\n");
fflush(stdmsg);
fprintf(stdmsg, "Error: ");
// MS doesn't recognize %zu format
OutBuffer tmp;
tmp.vprintf(format, ap);
#if _MSC_VER
fprintf(stdmsg, "%s", tmp.toChars());
#else
vfprintf(stdmsg, format, ap);
#endif
fprintf(stdmsg, "\n");
fflush(stdmsg);
//halt();
}
global.errors++;
}
@@ -188,9 +196,19 @@ void vwarning(Loc loc, const char *format, va_list ap)
mem.free(p);
fprintf(stdmsg, "Warning: ");
#if _MSC_VER
// MS doesn't recognize %zu format
OutBuffer tmp;
tmp.vprintf(format, ap);
fprintf(stdmsg, "%s", tmp.toChars());
#else
vfprintf(stdmsg, format, ap);
#endif
fprintf(stdmsg, "\n");
fflush(stdmsg);
//halt();
if (global.params.warnings == 1)
global.warnings++; // warnings don't count if gagged
}
}
@@ -226,25 +244,20 @@ void halt()
void getenv_setargv(const char *envvar, int *pargc, char** *pargv)
{
char *env;
char *p;
Array *argv;
int argc;
int wildcard; // do wildcard expansion
int instring;
int slash;
char c;
int j;
env = getenv(envvar);
char *env = getenv(envvar);
if (!env)
return;
return;
env = mem.strdup(env); // create our own writable copy
env = mem.strdup(env); // create our own writable copy
argc = *pargc;
argv = new Array();
int argc = *pargc;
Array *argv = new Array();
argv->setDim(argc);
int argc_left = 0;
@@ -259,83 +272,83 @@ void getenv_setargv(const char *envvar, int *pargc, char** *pargv)
argv->setDim(i);
break;
} else {
argv->data[i] = (void *)(*pargv)[i];
argv->data[i] = (void *)(*pargv)[i];
}
}
// HACK to stop required values from command line being drawn from DFLAGS
argv->push((char*)"");
argc++;
j = 1; // leave argv[0] alone
int j = 1; // leave argv[0] alone
while (1)
{
wildcard = 1;
switch (*env)
{
case ' ':
case '\t':
env++;
break;
int wildcard = 1; // do wildcard expansion
switch (*env)
{
case ' ':
case '\t':
env++;
break;
case 0:
goto Ldone;
case 0:
goto Ldone;
case '"':
wildcard = 0;
default:
argv->push(env); // append
//argv->insert(j, env); // insert at position j
j++;
argc++;
p = env;
slash = 0;
instring = 0;
c = 0;
case '"':
wildcard = 0;
default:
argv->push(env); // append
//argv->insert(j, env); // insert at position j
j++;
argc++;
p = env;
slash = 0;
instring = 0;
c = 0;
while (1)
{
c = *env++;
switch (c)
{
case '"':
p -= (slash >> 1);
if (slash & 1)
{ p--;
goto Laddc;
}
instring ^= 1;
slash = 0;
continue;
while (1)
{
c = *env++;
switch (c)
{
case '"':
p -= (slash >> 1);
if (slash & 1)
{ p--;
goto Laddc;
}
instring ^= 1;
slash = 0;
continue;
case ' ':
case '\t':
if (instring)
goto Laddc;
*p = 0;
//if (wildcard)
//wildcardexpand(); // not implemented
break;
case ' ':
case '\t':
if (instring)
goto Laddc;
*p = 0;
//if (wildcard)
//wildcardexpand(); // not implemented
break;
case '\\':
slash++;
*p++ = c;
continue;
case '\\':
slash++;
*p++ = c;
continue;
case 0:
*p = 0;
//if (wildcard)
//wildcardexpand(); // not implemented
goto Ldone;
case 0:
*p = 0;
//if (wildcard)
//wildcardexpand(); // not implemented
goto Ldone;
default:
Laddc:
slash = 0;
*p++ = c;
continue;
}
break;
}
}
default:
Laddc:
slash = 0;
*p++ = c;
continue;
}
break;
}
}
}
Ldone:

View File

@@ -1,462 +1,479 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MARS_H
#define DMD_MARS_H
#ifdef __DMC__
#pragma once
#endif
/*
It is very important to use version control macros correctly - the
idea is that host and target are independent. If these are done
correctly, cross compilers can be built.
The host compiler and host operating system are also different,
and are predefined by the host compiler. The ones used in
dmd are:
Macros defined by the compiler, not the code:
Compiler:
__DMC__ Digital Mars compiler
_MSC_VER Microsoft compiler
__GNUC__ Gnu compiler
Host operating system:
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
Windows 2000, Win XP, Vista
_WIN64 Windows for AMD64
linux Linux
__APPLE__ Mac OSX
__FreeBSD__ FreeBSD
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
For the target systems, there are the target operating system and
the target object file format:
Target operating system:
TARGET_WINDOS Covers 32 bit windows and 64 bit windows
TARGET_LINUX Covers 32 and 64 bit linux
TARGET_OSX Covers 32 and 64 bit Mac OSX
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
TARGET_SOLARIS Covers 32 and 64 bit Solaris
TARGET_NET Covers .Net
It is expected that the compiler for each platform will be able
to generate 32 and 64 bit code from the same compiler binary.
Target object module format:
OMFOBJ Intel Object Module Format, used on Windows
ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris
MACHOBJ Mach-O Object Module Format, used on Mac OSX
There are currently no macros for byte endianness order.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <stdarg.h>
#ifdef __DMC__
#ifdef DEBUG
#undef assert
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
#endif
#endif
#ifndef IS_PRINTF
# ifdef __GNUC__
# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
# else
# define IS_PRINTF(FMTARG)
# endif
#endif
#ifdef IN_GCC
/* Changes for the GDC compiler by David Friedman */
#endif
#define DMDV1 0
#define DMDV2 1 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
// Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
* TARGET_SOLARIS, which are
* set on the command line via the compiler makefile.
*/
#if _WIN32
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
#define OMFOBJ 1
#endif
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
#ifndef ELFOBJ
#define ELFOBJ 1
#endif
#endif
#if TARGET_OSX
#ifndef MACHOBJ
#define MACHOBJ 1
#endif
#endif
struct Array;
struct OutBuffer;
#if IN_LLVM
enum ARCH
{
ARCHinvalid,
ARCHx86,
ARCHx86_64,
ARCHppc,
ARCHppc_64,
ARCHarm,
ARCHthumb
};
enum OUTPUTFLAG
{
OUTPUTFLAGno,
OUTPUTFLAGdefault, // for the .o default
OUTPUTFLAGset // for -output
};
enum OS
{
OSinvalid,
OSLinux,
OSWindows,
OSMacOSX,
OSFreeBSD,
OSSolaris,
};
typedef unsigned char ubyte;
#endif
// Put command line switches in here
struct Param
{
bool obj; // write object file
bool link; // perform link
bool verbose; // verbose compile
bool vtls; // identify thread local variables
ubyte symdebug; // insert debug symbolic information
#if !IN_LLVM
// LDC uses a different mechanism
bool optimize; // run optimizer
char optimizeLevel; // optimization level
#endif
ARCH cpu; // target CPU
OS os;
bool is64bit; // generate X86_64 bit code
bool isLE; // generate little endian code
bool useDeprecated; // allow use of deprecated features
bool useAssert; // generate runtime code for assert()'s
bool useInvariants; // generate class invariant checks
bool useIn; // generate precondition checks
bool useOut; // generate postcondition checks
bool useArrayBounds; // generate array bounds checks
bool useSwitchError; // check for switches without a default
bool useUnitTests; // generate unittest code
bool useInline; // inline expand functions
bool warnings; // enable warnings
ubyte Dversion; // D version number
char safe; // enforce safe memory model
char *argv0; // program name
Array *imppath; // array of char*'s of where to look for import modules
Array *fileImppath; // array of char*'s of where to look for file import modules
char *objdir; // .obj file output directory
char *objname; // .obj file output name
bool doDocComments; // process embedded documentation comments
char *docdir; // write documentation file to docdir directory
char *docname; // write documentation file to docname
Array *ddocfiles; // macro include files for Ddoc
bool doHdrGeneration; // process embedded documentation comments
char *hdrdir; // write 'header' file to docdir directory
char *hdrname; // write 'header' file to docname
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
bool dump_source;
Array *defaultlibnames; // default libraries for non-debug builds
Array *debuglibnames; // default libraries for debug builds
const char *xmlname; // filename for XML output
char *moduleDepsFile; // filename for deps output
OutBuffer *moduleDeps; // contents to be written to deps file
// Hidden debug switches
bool debuga;
bool debugb;
bool debugc;
bool debugf;
bool debugr;
bool debugw;
bool debugx;
bool debugy;
bool run; // run resulting executable
// Linker stuff
Array *objfiles;
Array *linkswitches;
Array *libfiles;
char *deffile;
char *resfile;
char *exefile;
#if IN_LLVM
// LDC stuff
OUTPUTFLAG output_ll;
OUTPUTFLAG output_bc;
OUTPUTFLAG output_s;
OUTPUTFLAG output_o;
bool llvmAnnotate;
bool useInlineAsm;
bool verbose_cg;
bool useAvailableExternally;
// target stuff
const char* llvmArch;
const char *targetTriple;
const char *dataLayout;
#endif
};
struct Global
{
const char *mars_ext;
const char *sym_ext;
const char *obj_ext;
#if IN_LLVM
#if _WIN32
char *obj_ext_alt;
#endif
char *ll_ext;
char *bc_ext;
char *s_ext;
#endif
const char *lib_ext;
const char *doc_ext; // for Ddoc generated files
const char *ddoc_ext; // for Ddoc macro include files
const char *hdr_ext; // for D 'header' import files
const char *copyright;
const char *written;
Array *path; // Array of char*'s which form the import lookup path
Array *filePath; // Array of char*'s which form the file import lookup path
int structalign;
const char *version;
#if IN_LLVM
char *ldc_version;
char *llvm_version;
#endif
Param params;
unsigned errors; // number of errors reported so far
unsigned gag; // !=0 means gag reporting of errors
Global();
};
extern Global global;
/* Set if Windows Structured Exception Handling C extensions are supported.
* Apparently, VC has dropped support for these?
*/
#define WINDOWS_SEH (_WIN32 && __DMC__)
#ifdef __DMC__
typedef _Complex long double complex_t;
#else
#ifndef IN_GCC
#include "complex_t.h"
#endif
#ifdef __APPLE__
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
#endif
#endif
// Be careful not to care about sign when using dinteger_t
//typedef uint64_t integer_t;
typedef uint64_t dinteger_t; // use this instead of integer_t to
// avoid conflicts with system #include's
// Signed and unsigned variants
typedef int64_t sinteger_t;
typedef uint64_t uinteger_t;
typedef int8_t d_int8;
typedef uint8_t d_uns8;
typedef int16_t d_int16;
typedef uint16_t d_uns16;
typedef int32_t d_int32;
typedef uint32_t d_uns32;
typedef int64_t d_int64;
typedef uint64_t d_uns64;
typedef float d_float32;
typedef double d_float64;
typedef long double d_float80;
typedef d_uns8 d_char;
typedef d_uns16 d_wchar;
typedef d_uns32 d_dchar;
#ifdef IN_GCC
#include "d-gcc-real.h"
#else
typedef long double real_t;
#endif
// Modify OutBuffer::writewchar to write the correct size of wchar
#if _WIN32
#define writewchar writeword
#else
// This needs a configuration test...
#define writewchar write4
#endif
#ifdef IN_GCC
#include "d-gcc-complex_t.h"
#endif
struct Module;
//typedef unsigned Loc; // file location
struct Loc
{
const char *filename;
unsigned linnum;
Loc()
{
linnum = 0;
filename = NULL;
}
Loc(int x)
{
linnum = x;
filename = NULL;
}
Loc(Module *mod, unsigned linnum);
char *toChars();
bool equals(const Loc& loc);
};
#ifndef GCC_SAFE_DMD
#define TRUE 1
#define FALSE 0
#endif
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
// in interface vtbl[]'s
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
// in the inheritance graph multiple
// times, only one is used
enum LINK
{
LINKdefault,
LINKd,
LINKc,
LINKcpp,
LINKwindows,
LINKpascal,
#if IN_LLVM
LINKintrinsic,
#endif
};
enum DYNCAST
{
DYNCAST_OBJECT,
DYNCAST_EXPRESSION,
DYNCAST_DSYMBOL,
DYNCAST_TYPE,
DYNCAST_IDENTIFIER,
DYNCAST_TUPLE,
};
enum MATCH
{
MATCHnomatch, // no match
MATCHconvert, // match with conversions
#if DMDV2
MATCHconst, // match with conversion to const
#endif
MATCHexact // exact match
};
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
void vwarning(Loc loc, const char *format, va_list);
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
void verror(Loc loc, const char *format, va_list);
void fatal();
void err_nomem();
#if IN_LLVM
void inifile(char *argv0, const char *inifile);
#else
int runLINK();
void deleteExeFile();
int runProgram();
void inifile(const char *argv0, const char *inifile);
#endif
void halt();
#if !IN_LLVM
void util_progress();
#endif
/*** Where to send error messages ***/
#if IN_GCC || IN_LLVM
#define stdmsg stderr
#else
#define stdmsg stderr
#endif
#if !IN_LLVM
struct Dsymbol;
struct Library;
struct File;
void obj_start(char *srcfile);
void obj_end(Library *library, File *objfile);
void obj_append(Dsymbol *s);
void obj_write_deferred(Library *library);
#endif
#endif /* DMD_MARS_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MARS_H
#define DMD_MARS_H
#ifdef __DMC__
#pragma once
#endif
/*
It is very important to use version control macros correctly - the
idea is that host and target are independent. If these are done
correctly, cross compilers can be built.
The host compiler and host operating system are also different,
and are predefined by the host compiler. The ones used in
dmd are:
Macros defined by the compiler, not the code:
Compiler:
__DMC__ Digital Mars compiler
_MSC_VER Microsoft compiler
__GNUC__ Gnu compiler
Host operating system:
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
Windows 2000, Win XP, Vista
_WIN64 Windows for AMD64
linux Linux
__APPLE__ Mac OSX
__FreeBSD__ FreeBSD
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
For the target systems, there are the target operating system and
the target object file format:
Target operating system:
TARGET_WINDOS Covers 32 bit windows and 64 bit windows
TARGET_LINUX Covers 32 and 64 bit linux
TARGET_OSX Covers 32 and 64 bit Mac OSX
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
TARGET_SOLARIS Covers 32 and 64 bit Solaris
TARGET_NET Covers .Net
It is expected that the compiler for each platform will be able
to generate 32 and 64 bit code from the same compiler binary.
Target object module format:
OMFOBJ Intel Object Module Format, used on Windows
ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris
MACHOBJ Mach-O Object Module Format, used on Mac OSX
There are currently no macros for byte endianness order.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <stdarg.h>
#ifdef __DMC__
#ifdef DEBUG
#undef assert
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
#endif
#endif
#ifdef DEBUG
#define UNITTEST 1
#endif
void unittests();
#ifndef IS_PRINTF
# ifdef __GNUC__
# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
# else
# define IS_PRINTF(FMTARG)
# endif
#endif
#ifdef IN_GCC
/* Changes for the GDC compiler by David Friedman */
#endif
#define DMDV1 0
#define DMDV2 1 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
#define SARRAYVALUE DMDV2 // static arrays are value types
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
// Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
* TARGET_SOLARIS, which are
* set on the command line via the compiler makefile.
*/
#if _WIN32
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
#define OMFOBJ 1
#endif
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
#ifndef ELFOBJ
#define ELFOBJ 1
#endif
#endif
#if TARGET_OSX
#ifndef MACHOBJ
#define MACHOBJ 1
#endif
#endif
struct Array;
struct OutBuffer;
#if IN_LLVM
enum ARCH
{
ARCHinvalid,
ARCHx86,
ARCHx86_64,
ARCHppc,
ARCHppc_64,
ARCHarm,
ARCHthumb
};
enum OUTPUTFLAG
{
OUTPUTFLAGno,
OUTPUTFLAGdefault, // for the .o default
OUTPUTFLAGset // for -output
};
enum OS
{
OSinvalid,
OSLinux,
OSWindows,
OSMacOSX,
OSFreeBSD,
OSSolaris,
};
typedef unsigned char ubyte;
#endif
// Put command line switches in here
struct Param
{
bool obj; // write object file
bool link; // perform link
bool verbose; // verbose compile
bool vtls; // identify thread local variables
ubyte symdebug; // insert debug symbolic information
#if !IN_LLVM
// LDC uses a different mechanism
bool optimize; // run optimizer
char optimizeLevel; // optimization level
#endif
ARCH cpu; // target CPU
OS os;
bool is64bit; // generate X86_64 bit code
char map; // generate linker .map file
bool isLE; // generate little endian code
bool useDeprecated; // allow use of deprecated features
bool useAssert; // generate runtime code for assert()'s
bool useInvariants; // generate class invariant checks
bool useIn; // generate precondition checks
bool useOut; // generate postcondition checks
bool useArrayBounds; // generate array bounds checks
bool useSwitchError; // check for switches without a default
bool useUnitTests; // generate unittest code
bool useInline; // inline expand functions
bool warnings; // enable warnings
ubyte Dversion; // D version number
char *argv0; // program name
Array *imppath; // array of char*'s of where to look for import modules
Array *fileImppath; // array of char*'s of where to look for file import modules
char *objdir; // .obj file output directory
char *objname; // .obj file output name
bool doDocComments; // process embedded documentation comments
char *docdir; // write documentation file to docdir directory
char *docname; // write documentation file to docname
Array *ddocfiles; // macro include files for Ddoc
bool doHdrGeneration; // process embedded documentation comments
char *hdrdir; // write 'header' file to docdir directory
char *hdrname; // write 'header' file to docname
char doXGeneration; // write JSON file
char *xfilename; // write JSON file to xfilename
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
bool dump_source;
Array *defaultlibnames; // default libraries for non-debug builds
Array *debuglibnames; // default libraries for debug builds
char *moduleDepsFile; // filename for deps output
OutBuffer *moduleDeps; // contents to be written to deps file
// Hidden debug switches
bool debuga;
bool debugb;
bool debugc;
bool debugf;
bool debugr;
bool debugw;
bool debugx;
bool debugy;
bool run; // run resulting executable
// Linker stuff
Array *objfiles;
Array *linkswitches;
Array *libfiles;
char *deffile;
char *resfile;
char *exefile;
char *mapfile;
#if IN_LLVM
// LDC stuff
OUTPUTFLAG output_ll;
OUTPUTFLAG output_bc;
OUTPUTFLAG output_s;
OUTPUTFLAG output_o;
bool llvmAnnotate;
bool useInlineAsm;
bool verbose_cg;
bool useAvailableExternally;
// target stuff
const char* llvmArch;
const char *targetTriple;
const char *dataLayout;
#endif
};
struct Global
{
const char *mars_ext;
const char *sym_ext;
const char *obj_ext;
#if IN_LLVM
#if _WIN32
char *obj_ext_alt;
#endif
char *ll_ext;
char *bc_ext;
char *s_ext;
#endif
const char *lib_ext;
const char *dll_ext;
const char *doc_ext; // for Ddoc generated files
const char *ddoc_ext; // for Ddoc macro include files
const char *hdr_ext; // for D 'header' import files
const char *json_ext; // for JSON files
const char *map_ext; // for .map files
const char *copyright;
const char *written;
Array *path; // Array of char*'s which form the import lookup path
Array *filePath; // Array of char*'s which form the file import lookup path
int structalign;
const char *version;
#if IN_LLVM
char *ldc_version;
char *llvm_version;
#endif
Param params;
unsigned errors; // number of errors reported so far
unsigned warnings; // number of warnings reported so far
unsigned gag; // !=0 means gag reporting of errors & warnings
Global();
};
extern Global global;
/* Set if Windows Structured Exception Handling C extensions are supported.
* Apparently, VC has dropped support for these?
*/
#define WINDOWS_SEH (_WIN32 && __DMC__)
#ifdef __DMC__
typedef _Complex long double complex_t;
#else
#ifndef IN_GCC
#include "complex_t.h"
#endif
#ifdef __APPLE__
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
#endif
#endif
// Be careful not to care about sign when using dinteger_t
//typedef uint64_t integer_t;
typedef uint64_t dinteger_t; // use this instead of integer_t to
// avoid conflicts with system #include's
// Signed and unsigned variants
typedef int64_t sinteger_t;
typedef uint64_t uinteger_t;
typedef int8_t d_int8;
typedef uint8_t d_uns8;
typedef int16_t d_int16;
typedef uint16_t d_uns16;
typedef int32_t d_int32;
typedef uint32_t d_uns32;
typedef int64_t d_int64;
typedef uint64_t d_uns64;
typedef float d_float32;
typedef double d_float64;
typedef long double d_float80;
typedef d_uns8 d_char;
typedef d_uns16 d_wchar;
typedef d_uns32 d_dchar;
#ifdef IN_GCC
#include "d-gcc-real.h"
#else
typedef long double real_t;
#endif
// Modify OutBuffer::writewchar to write the correct size of wchar
#if _WIN32
#define writewchar writeword
#else
// This needs a configuration test...
#define writewchar write4
#endif
#ifdef IN_GCC
#include "d-gcc-complex_t.h"
#endif
struct Module;
//typedef unsigned Loc; // file location
struct Loc
{
const char *filename;
unsigned linnum;
Loc()
{
linnum = 0;
filename = NULL;
}
Loc(int x)
{
linnum = x;
filename = NULL;
}
Loc(Module *mod, unsigned linnum);
char *toChars();
bool equals(const Loc& loc);
};
#ifndef GCC_SAFE_DMD
#define TRUE 1
#define FALSE 0
#endif
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
// in interface vtbl[]'s
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
// in the inheritance graph multiple
// times, only one is used
enum LINK
{
LINKdefault,
LINKd,
LINKc,
LINKcpp,
LINKwindows,
LINKpascal,
#if IN_LLVM
LINKintrinsic,
#endif
};
enum DYNCAST
{
DYNCAST_OBJECT,
DYNCAST_EXPRESSION,
DYNCAST_DSYMBOL,
DYNCAST_TYPE,
DYNCAST_IDENTIFIER,
DYNCAST_TUPLE,
};
enum MATCH
{
MATCHnomatch, // no match
MATCHconvert, // match with conversions
#if DMDV2
MATCHconst, // match with conversion to const
#endif
MATCHexact // exact match
};
typedef uint64_t StorageClass;
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
void verror(Loc loc, const char *format, va_list);
void vwarning(Loc loc, const char *format, va_list);
void fatal();
void err_nomem();
#if IN_LLVM
void inifile(char *argv0, const char *inifile);
#else
int runLINK();
void deleteExeFile();
int runProgram();
const char *inifile(const char *argv0, const char *inifile);
#endif
void halt();
#if !IN_LLVM
void util_progress();
#endif
/*** Where to send error messages ***/
#if IN_GCC || IN_LLVM
#define stdmsg stderr
#else
#define stdmsg stderr
#endif
#if !IN_LLVM
struct Dsymbol;
struct Library;
struct File;
void obj_start(char *srcfile);
void obj_end(Library *library, File *objfile);
void obj_append(Dsymbol *s);
void obj_write_deferred(Library *library);
#endif
const char *importHint(const char *s);
#endif /* DMD_MARS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,215 +1,226 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MODULE_H
#define DMD_MODULE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct ModuleInfoDeclaration;
struct ClassDeclaration;
struct ModuleDeclaration;
struct Macro;
struct Escape;
struct VarDeclaration;
struct Library;
// Back end
#if IN_LLVM
class Ir;
struct DValue;
typedef DValue elem;
namespace llvm {
class LLVMContext;
class Module;
}
#else
#ifdef IN_GCC
union tree_node; typedef union tree_node elem;
#else
struct elem;
#endif
#endif
struct Package : ScopeDsymbol
{
Package(Identifier *ident);
const char *kind();
static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);
Package *isPackage() { return this; }
virtual void semantic(Scope *sc) { }
};
struct Module : Package
{
static Module *rootModule;
static DsymbolTable *modules; // symbol table of all modules
static Array amodules; // array of all modules
static Array deferred; // deferred Dsymbol's needing semantic() run on them
static unsigned dprogress; // progress resolving the deferred list
static void init();
static ClassDeclaration *moduleinfo;
const char *arg; // original argument name
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
File *srcfile; // input source file
File *objfile; // output object file
File *docfile; // output doc file
File *hdrfile; // output hdr file
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
int isHtml; // if it is an HTML file
int isDocFile; // if it is a documentation input file, not D source
int needmoduleinfo;
#ifdef IN_GCC
int strictlyneedmoduleinfo;
#endif
int selfimports; // 0: don't know, 1: does not, 2: does
int selfImports(); // returns !=0 if module imports itself
int insearch;
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
int semanticstarted; // has semantic() been started?
int semanticRun; // has semantic() been done?
int root; // != 0 if this is a 'root' module,
// i.e. a module that will be taken all the
// way to an object file
Module *importedFrom; // module from command line we're imported from,
// i.e. a module that will be taken all the
// way to an object file
Array *decldefs; // top level declarations for this Module
Array aimports; // all imported modules
ModuleInfoDeclaration *vmoduleinfo;
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
Array *debugidsNot; // forward referenced debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
Array *versionidsNot; // forward referenced version identifiers
Macro *macrotable; // document comment macros
Escape *escapetable; // document comment escapes
bool safe; // TRUE if module is marked as 'safe'
int doDocComment; // enable generating doc comments for this module
int doHdrGen; // enable generating header file for this module
Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
~Module();
static Module *load(Loc loc, Array *packages, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
#if !IN_LLVM
void setDocfile(); // set docfile member
#endif
void read(Loc loc); // read file
#if IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
void parse(); // syntactic parse
#endif
void semantic(Scope* unused_sc = NULL); // semantic analysis
void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis
void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis
void inlineScan(); // scan for functions to inline
#if !IN_LLVM
void setHdrfile(); // set hdrfile member
#endif
#ifdef _DH
void genhdrfile(); // generate D import file
#endif
// void gensymfile();
void gendocfile();
int needModuleInfo();
Dsymbol *search(Loc loc, Identifier *ident, int flags);
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
void runDeferredSemantic();
int imports(Module *m);
// Back end
#if IN_DMD
int doppelganger; // sub-module
Symbol *cov; // private uint[] __coverage;
unsigned *covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
Symbol *sdtor; // module destructor
Symbol *stest; // module unit test
Symbol *sfilename; // symbol for filename
Symbol *massert; // module assert function
Symbol *toModuleAssert(); // get module assert function
Symbol *marray; // module array bounds function
Symbol *toModuleArray(); // get module array bounds function
static Symbol *gencritsec();
elem *toEfilename();
elem *toEmodulename();
Symbol *toSymbol();
#endif
void genmoduleinfo();
#if IN_LLVM
// LDC
llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir);
void buildTargetFiles(bool singleObj);
File* buildFilePath(const char* forcename, const char* path, const char* ext);
Module *isModule() { return this; }
bool llvmForceLogging;
// array ops emitted in this module already
StringTable arrayfuncs;
#endif
};
struct ModuleDeclaration
{
Identifier *id;
Array *packages; // array of Identifier's representing packages
bool safe;
ModuleDeclaration(Array *packages, Identifier *id, bool safe);
char *toChars();
};
#endif /* DMD_MODULE_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_MODULE_H
#define DMD_MODULE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct ModuleInfoDeclaration;
struct ClassDeclaration;
struct ModuleDeclaration;
struct Macro;
struct Escape;
struct VarDeclaration;
struct Library;
// Back end
#if IN_LLVM
class Ir;
struct DValue;
typedef DValue elem;
namespace llvm {
class LLVMContext;
class Module;
}
#else
#ifdef IN_GCC
union tree_node; typedef union tree_node elem;
#else
struct elem;
#endif
#endif
struct Package : ScopeDsymbol
{
Package(Identifier *ident);
const char *kind();
static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);
Package *isPackage() { return this; }
virtual void semantic(Scope *sc) { }
};
struct Module : Package
{
static Module *rootModule;
static DsymbolTable *modules; // symbol table of all modules
static Array amodules; // array of all modules
static Array deferred; // deferred Dsymbol's needing semantic() run on them
static unsigned dprogress; // progress resolving the deferred list
static void init();
static ClassDeclaration *moduleinfo;
const char *arg; // original argument name
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
File *srcfile; // input source file
File *objfile; // output .obj file
File *hdrfile; // 'header' file
File *symfile; // output symbol file
File *docfile; // output documentation file
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
int isHtml; // if it is an HTML file
int isDocFile; // if it is a documentation input file, not D source
int needmoduleinfo;
#ifdef IN_GCC
int strictlyneedmoduleinfo;
#endif
int selfimports; // 0: don't know, 1: does not, 2: does
int selfImports(); // returns !=0 if module imports itself
int insearch;
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
int semanticstarted; // has semantic() been started?
int semanticRun; // has semantic() been done?
int root; // != 0 if this is a 'root' module,
// i.e. a module that will be taken all the
// way to an object file
Module *importedFrom; // module from command line we're imported from,
// i.e. a module that will be taken all the
// way to an object file
Array *decldefs; // top level declarations for this Module
Array aimports; // all imported modules
ModuleInfoDeclaration *vmoduleinfo;
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
Array *debugidsNot; // forward referenced debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
Array *versionidsNot; // forward referenced version identifiers
Macro *macrotable; // document comment macros
Escape *escapetable; // document comment escapes
bool safe; // TRUE if module is marked as 'safe'
size_t nameoffset; // offset of module name from start of ModuleInfo
size_t namelen; // length of module name in characters
int doDocComment; // enable generating doc comments for this module
int doHdrGen; // enable generating header file for this module
Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
~Module();
static Module *load(Loc loc, Array *packages, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toJsonBuffer(OutBuffer *buf);
const char *kind();
#if !IN_LLVM
void setDocfile(); // set docfile member
#endif
void read(Loc loc); // read file
#if IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
void parse(); // syntactic parse
#endif
void importAll(Scope *sc);
void semantic(Scope* unused_sc = NULL); // semantic analysis
void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis
void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis
void inlineScan(); // scan for functions to inline
#if !IN_LLVM
void setHdrfile(); // set hdrfile member
#endif
#ifdef _DH
void genhdrfile(); // generate D import file
#endif
// void gensymfile();
void gendocfile();
int needModuleInfo();
Dsymbol *search(Loc loc, Identifier *ident, int flags);
Dsymbol *symtabInsert(Dsymbol *s);
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
static void runDeferredSemantic();
static void clearCache();
int imports(Module *m);
// Back end
#if IN_DMD
int doppelganger; // sub-module
Symbol *cov; // private uint[] __coverage;
unsigned *covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
Symbol *sdtor; // module destructor
Symbol *ssharedctor; // module shared constructor
Symbol *sshareddtor; // module shared destructor
Symbol *stest; // module unit test
Symbol *sfilename; // symbol for filename
Symbol *massert; // module assert function
Symbol *toModuleAssert(); // get module assert function
Symbol *munittest; // module unittest failure function
Symbol *toModuleUnittest(); // get module unittest failure function
Symbol *marray; // module array bounds function
Symbol *toModuleArray(); // get module array bounds function
static Symbol *gencritsec();
elem *toEfilename();
Symbol *toSymbol();
#endif
void genmoduleinfo();
#if IN_LLVM
// LDC
llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir);
void buildTargetFiles(bool singleObj);
File* buildFilePath(const char* forcename, const char* path, const char* ext);
Module *isModule() { return this; }
bool llvmForceLogging;
// array ops emitted in this module already
StringTable arrayfuncs;
#endif
};
struct ModuleDeclaration
{
Identifier *id;
Array *packages; // array of Identifier's representing packages
bool safe;
ModuleDeclaration(Array *packages, Identifier *id, bool safe);
char *toChars();
};
#endif /* DMD_MODULE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +1,61 @@
#ifndef OBJFILE_H
#define OBJFILE_H
#include "root.h"
typedef void *SymHandle;
typedef unsigned SegOffset;
enum ObjFormat
{
NTCOFF,
ELF
};
struct ObjFile : File
{
ObjFile(FileName *);
~ObjFile();
ObjFile *init(ObjFormat);
void comment(const char *); // insert comment into object file
void modulename(const char *); // set module name
void library(const char *); // add default library
void startaddress(SegHandle seg, SegOffset offset); // set start address
// Segments
enum SegHandle
{ code = 1,
data, bss
};
SymHandle defineSym(const char *name, SegHandle seg, SegOffset offset);
SymHandle externSym(const char *name);
SegOffset write(SegHandle seg, const void *data, unsigned nbytes);
SegOffset writestring(SegHandle seg, char *string);
SegOffset write8(SegHandle seg, unsigned b);
SegOffset write16(SegHandle seg, unsigned w);
SegOffset write32(SegHandle seg, unsigned long v);
SegOffset write64(SegHandle seg, unsigned long long v);
SegOffset fill0(SegHandle seg, unsigned nbytes);
SegOffset align(SegHandle seg, unsigned size);
SegOffset writefixup(SegHandle seg, SymHandle sym, unsigned value, int selfrelative);
// Non-binding hint as to how big seg will grow
void reserve(SegHandle seg, SegOffset size);
// Set actual size
void setSize(SegHandle seg, SegOffset size);
// Get/set offset for subsequent writes
void setOffset(SegHandle seg, SegOffset offset);
SegOffset getOffset(SegHandle seg);
SegHandle createSeg(const char *name);
};
#endif
#ifndef OBJFILE_H
#define OBJFILE_H
#include "root.h"
typedef void *SymHandle;
typedef unsigned SegOffset;
enum ObjFormat
{
NTCOFF,
ELF
};
struct ObjFile : File
{
ObjFile(FileName *);
~ObjFile();
ObjFile *init(ObjFormat);
void comment(const char *); // insert comment into object file
void modulename(const char *); // set module name
void library(const char *); // add default library
void startaddress(SegHandle seg, SegOffset offset); // set start address
// Segments
enum SegHandle
{ code = 1,
data, bss
};
SymHandle defineSym(const char *name, SegHandle seg, SegOffset offset);
SymHandle externSym(const char *name);
SegOffset write(SegHandle seg, const void *data, unsigned nbytes);
SegOffset writestring(SegHandle seg, char *string);
SegOffset write8(SegHandle seg, unsigned b);
SegOffset write16(SegHandle seg, unsigned w);
SegOffset write32(SegHandle seg, unsigned long v);
SegOffset write64(SegHandle seg, unsigned long long v);
SegOffset fill0(SegHandle seg, unsigned nbytes);
SegOffset align(SegHandle seg, unsigned size);
SegOffset writefixup(SegHandle seg, SymHandle sym, unsigned value, int selfrelative);
// Non-binding hint as to how big seg will grow
void reserve(SegHandle seg, SegOffset size);
// Set actual size
void setSize(SegHandle seg, SegOffset size);
// Get/set offset for subsequent writes
void setOffset(SegHandle seg, SegOffset offset);
SegOffset getOffset(SegHandle seg);
SegHandle createSeg(const char *name);
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

12403
dmd2/parse.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,146 +1,182 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_PARSE_H
#define DMD_PARSE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "arraytypes.h"
#include "lexer.h"
#include "enum.h"
struct Type;
struct TypeQualified;
struct Expression;
struct Declaration;
struct Statement;
struct Import;
struct Initializer;
struct FuncDeclaration;
struct CtorDeclaration;
struct PostBlitDeclaration;
struct DtorDeclaration;
struct StaticCtorDeclaration;
struct StaticDtorDeclaration;
struct ConditionalDeclaration;
struct InvariantDeclaration;
struct UnitTestDeclaration;
struct NewDeclaration;
struct DeleteDeclaration;
struct Condition;
struct Module;
struct ModuleDeclaration;
struct TemplateDeclaration;
struct TemplateInstance;
struct StaticAssert;
/************************************
* These control how parseStatement() works.
*/
enum ParseStatementFlags
{
PSsemi = 1, // empty ';' statements are allowed
PSscope = 2, // start a new scope
PScurly = 4, // { } statement is required
PScurlyscope = 8, // { } starts a new scope
};
struct Parser : Lexer
{
ModuleDeclaration *md;
enum LINK linkage;
Loc endloc; // set to location of last right curly
int inBrackets; // inside [] of array index or slice
Parser(Module *module, unsigned char *base, unsigned length, int doDocComment);
Array *parseModule();
Array *parseDeclDefs(int once);
Array *parseAutoDeclarations(unsigned storageClass, unsigned char *comment);
Array *parseBlock();
void composeStorageClass(unsigned stc);
Expression *parseConstraint();
TemplateDeclaration *parseTemplateDeclaration();
TemplateParameters *parseTemplateParameterList(int flag = 0);
Dsymbol *parseMixin();
Objects *parseTemplateArgumentList();
Objects *parseTemplateArgumentList2();
Objects *parseTemplateArgument();
StaticAssert *parseStaticAssert();
TypeQualified *parseTypeof();
enum LINK parseLinkage();
Condition *parseDebugCondition();
Condition *parseVersionCondition();
Condition *parseStaticIfCondition();
Dsymbol *parseCtor();
PostBlitDeclaration *parsePostBlit();
DtorDeclaration *parseDtor();
StaticCtorDeclaration *parseStaticCtor();
StaticDtorDeclaration *parseStaticDtor();
InvariantDeclaration *parseInvariant();
UnitTestDeclaration *parseUnitTest();
NewDeclaration *parseNew();
DeleteDeclaration *parseDelete();
Arguments *parseParameters(int *pvarargs);
EnumDeclaration *parseEnum();
Dsymbol *parseAggregate();
BaseClasses *parseBaseClasses();
Import *parseImport(Array *decldefs, int isstatic);
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
Type *parseBasicType();
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
Array *parseDeclarations(unsigned storage_class);
void parseContracts(FuncDeclaration *f);
Statement *parseStatement(int flags);
Initializer *parseInitializer();
Expression *parseDefaultInitExp();
void check(Loc loc, enum TOK value);
void check(enum TOK value);
void check(enum TOK value, const char *string);
int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt);
int isBasicType(Token **pt);
int isDeclarator(Token **pt, int *haveId, enum TOK endtok);
int isParameters(Token **pt);
int isExpression(Token **pt);
int isTemplateInstance(Token *t, Token **pt);
int skipParens(Token *t, Token **pt);
Expression *parseExpression();
Expression *parsePrimaryExp();
Expression *parseUnaryExp();
Expression *parsePostExp(Expression *e);
Expression *parseMulExp();
Expression *parseAddExp();
Expression *parseShiftExp();
Expression *parseRelExp();
Expression *parseEqualExp();
Expression *parseCmpExp();
Expression *parseAndExp();
Expression *parseXorExp();
Expression *parseOrExp();
Expression *parseAndAndExp();
Expression *parseOrOrExp();
Expression *parseCondExp();
Expression *parseAssignExp();
Expressions *parseArguments();
Expression *parseNewExp(Expression *thisexp);
void addComment(Dsymbol *s, unsigned char *blockComment);
};
#endif /* DMD_PARSE_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_PARSE_H
#define DMD_PARSE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "arraytypes.h"
#include "lexer.h"
#include "enum.h"
struct Type;
struct TypeQualified;
struct Expression;
struct Declaration;
struct Statement;
struct Import;
struct Initializer;
struct FuncDeclaration;
struct CtorDeclaration;
struct PostBlitDeclaration;
struct DtorDeclaration;
struct StaticCtorDeclaration;
struct StaticDtorDeclaration;
struct SharedStaticCtorDeclaration;
struct SharedStaticDtorDeclaration;
struct ConditionalDeclaration;
struct InvariantDeclaration;
struct UnitTestDeclaration;
struct NewDeclaration;
struct DeleteDeclaration;
struct Condition;
struct Module;
struct ModuleDeclaration;
struct TemplateDeclaration;
struct TemplateInstance;
struct StaticAssert;
/************************************
* These control how parseStatement() works.
*/
enum ParseStatementFlags
{
PSsemi = 1, // empty ';' statements are allowed
PSscope = 2, // start a new scope
PScurly = 4, // { } statement is required
PScurlyscope = 8, // { } starts a new scope
};
struct Parser : Lexer
{
ModuleDeclaration *md;
enum LINK linkage;
Loc endloc; // set to location of last right curly
int inBrackets; // inside [] of array index or slice
Parser(Module *module, unsigned char *base, unsigned length, int doDocComment);
Dsymbols *parseModule();
Dsymbols *parseDeclDefs(int once);
Dsymbols *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
Dsymbols *parseBlock();
void composeStorageClass(StorageClass stc);
StorageClass parseAttribute();
StorageClass parsePostfix();
Expression *parseConstraint();
TemplateDeclaration *parseTemplateDeclaration(int ismixin);
TemplateParameters *parseTemplateParameterList(int flag = 0);
Dsymbol *parseMixin();
Objects *parseTemplateArgumentList();
Objects *parseTemplateArgumentList2();
Objects *parseTemplateArgument();
StaticAssert *parseStaticAssert();
TypeQualified *parseTypeof();
enum LINK parseLinkage();
Condition *parseDebugCondition();
Condition *parseVersionCondition();
Condition *parseStaticIfCondition();
Dsymbol *parseCtor();
PostBlitDeclaration *parsePostBlit();
DtorDeclaration *parseDtor();
StaticCtorDeclaration *parseStaticCtor();
StaticDtorDeclaration *parseStaticDtor();
SharedStaticCtorDeclaration *parseSharedStaticCtor();
SharedStaticDtorDeclaration *parseSharedStaticDtor();
InvariantDeclaration *parseInvariant();
UnitTestDeclaration *parseUnitTest();
NewDeclaration *parseNew();
DeleteDeclaration *parseDelete();
Parameters *parseParameters(int *pvarargs);
EnumDeclaration *parseEnum();
Dsymbol *parseAggregate();
BaseClasses *parseBaseClasses();
Import *parseImport(Dsymbols *decldefs, int isstatic);
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
Type *parseBasicType();
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
Dsymbols *parseDeclarations(StorageClass storage_class);
void parseContracts(FuncDeclaration *f);
Statement *parseStatement(int flags);
Initializer *parseInitializer();
Expression *parseDefaultInitExp();
void check(Loc loc, enum TOK value);
void check(enum TOK value);
void check(enum TOK value, const char *string);
void checkParens(enum TOK value, Expression *e);
int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt);
int isBasicType(Token **pt);
int isDeclarator(Token **pt, int *haveId, enum TOK endtok);
int isParameters(Token **pt);
int isExpression(Token **pt);
int isTemplateInstance(Token *t, Token **pt);
int skipParens(Token *t, Token **pt);
Expression *parseExpression();
Expression *parsePrimaryExp();
Expression *parseUnaryExp();
Expression *parsePostExp(Expression *e);
Expression *parseMulExp();
Expression *parseAddExp();
Expression *parseShiftExp();
#if DMDV1
Expression *parseRelExp();
Expression *parseEqualExp();
#endif
Expression *parseCmpExp();
Expression *parseAndExp();
Expression *parseXorExp();
Expression *parseOrExp();
Expression *parseAndAndExp();
Expression *parseOrOrExp();
Expression *parseCondExp();
Expression *parseAssignExp();
Expressions *parseArguments();
Expression *parseNewExp(Expression *thisexp);
void addComment(Dsymbol *s, unsigned char *blockComment);
};
// Operator precedence - greater values are higher precedence
enum PREC
{
PREC_zero,
PREC_expr,
PREC_assign,
PREC_cond,
PREC_oror,
PREC_andand,
PREC_or,
PREC_xor,
PREC_and,
PREC_equal,
PREC_rel,
PREC_shift,
PREC_add,
PREC_mul,
PREC_pow,
PREC_unary,
PREC_primary,
};
extern enum PREC precedence[TOKMAX];
void initPrecedence();
#endif /* DMD_PARSE_H */

188
dmd2/root/aav.c Normal file
View File

@@ -0,0 +1,188 @@
/**
* Implementation of associative arrays.
*
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "aav.h"
static const size_t prime_list[] = {
31UL,
97UL, 389UL,
1543UL, 6151UL,
24593UL, 98317UL,
393241UL, 1572869UL,
6291469UL, 25165843UL,
100663319UL, 402653189UL,
1610612741UL, 4294967291UL,
};
struct aaA
{
aaA *next;
Key key;
Value value;
};
struct AA
{
aaA* *b;
size_t b_length;
size_t nodes; // total number of aaA nodes
aaA* binit[4]; // initial value of b[]
};
static const AA bbinit = { NULL, };
/****************************************************
* Determine number of entries in associative array.
*/
size_t _aaLen(AA* aa)
{
return aa ? aa->nodes : 0;
}
/*************************************************
* Get pointer to value in associative array indexed by key.
* Add entry for key if it is not already there.
*/
Value* _aaGet(AA** paa, Key key)
{
//printf("paa = %p\n", paa);
if (!*paa)
{ AA *a = new AA();
*a = bbinit;
a->b = a->binit;
a->b_length = sizeof(a->binit) / sizeof(a->binit[0]);
*paa = a;
assert((*paa)->b_length == 4);
}
//printf("paa = %p, *paa = %p\n", paa, *paa);
assert((*paa)->b_length);
size_t i = (size_t)key % (*paa)->b_length;
aaA** pe = &(*paa)->b[i];
aaA *e;
while ((e = *pe) != NULL)
{
if (key == e->key)
return &e->value;
pe = &e->next;
}
// Not found, create new elem
//printf("create new one\n");
e = new aaA();
e->next = NULL;
e->key = key;
e->value = NULL;
*pe = e;
size_t nodes = ++(*paa)->nodes;
//printf("length = %d, nodes = %d\n", paa.a.b.length, nodes);
if (nodes > (*paa)->b_length * 4)
{
//printf("rehash\n");
_aaRehash(paa);
}
return &e->value;
}
/*************************************************
* Get value in associative array indexed by key.
* Returns NULL if it is not already there.
*/
Value _aaGetRvalue(AA* aa, Key key)
{
//printf("_aaGetRvalue(key = %p)\n", key);
if (!aa)
return NULL;
size_t len = aa->b_length;
if (len)
{
size_t i = (size_t)key % len;
aaA* e = aa->b[i];
while (e)
{
if (key == e->key)
return e->value;
e = e->next;
}
}
return NULL; // not found
}
/********************************************
* Rehash an array.
*/
void _aaRehash(AA** paa)
{
//printf("Rehash\n");
if (*paa)
{
AA newb = bbinit;
AA *aa = *paa;
size_t len = _aaLen(*paa);
if (len)
{ size_t i;
for (i = 0; i < sizeof(prime_list)/sizeof(prime_list[0]) - 1; i++)
{
if (len <= prime_list[i])
break;
}
len = prime_list[i];
newb.b = new aaA*[len];
memset(newb.b, 0, len * sizeof(aaA*));
newb.b_length = len;
for (size_t k = 0; k < aa->b_length; k++)
{ aaA *e = aa->b[k];
while (e)
{ aaA* enext = e->next;
size_t j = (size_t)e->key % len;
e->next = newb.b[j];
newb.b[j] = e;
e = enext;
}
}
if (aa->b != aa->binit)
delete aa->b;
newb.nodes = aa->nodes;
}
**paa = newb;
}
}
#if UNITTEST
void unittest_aa()
{
AA* aa = NULL;
Value v = _aaGetRvalue(aa, NULL);
assert(!v);
Value *pv = _aaGet(&aa, NULL);
assert(pv);
*pv = (void *)3;
v = _aaGetRvalue(aa, NULL);
assert(v == (void *)3);
}
#endif

11
dmd2/root/aav.h Normal file
View File

@@ -0,0 +1,11 @@
typedef void* Value;
typedef void* Key;
struct AA;
size_t _aaLen(AA* aa);
Value* _aaGet(AA** aa, Key key);
Value _aaGetRvalue(AA* aa, Key key);
void _aaRehash(AA** paa);

View File

@@ -1,224 +1,254 @@
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#if (defined (__SVR4) && defined (__sun))
#include <alloca.h>
#endif
#if _MSC_VER || __MINGW32__
#include <malloc.h>
#endif
#if IN_GCC
#include "gdc_alloca.h"
#endif
#if _WIN32
#include <windows.h>
#endif
#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utime.h>
#endif
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "rmem.h"
/********************************* Array ****************************/
Array::Array()
{
data = NULL;
dim = 0;
allocdim = 0;
}
Array::~Array()
{
mem.free(data);
}
void Array::mark()
{ unsigned u;
mem.mark(data);
for (u = 0; u < dim; u++)
mem.mark(data[u]); // BUG: what if arrays of Object's?
}
void Array::reserve(unsigned nentries)
{
//printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
if (allocdim - dim < nentries)
{
allocdim = dim + nentries;
data = (void **)mem.realloc(data, allocdim * sizeof(*data));
}
}
void Array::setDim(unsigned newdim)
{
if (dim < newdim)
{
reserve(newdim - dim);
}
dim = newdim;
}
void Array::fixDim()
{
if (dim != allocdim)
{ data = (void **)mem.realloc(data, dim * sizeof(*data));
allocdim = dim;
}
}
void Array::push(void *ptr)
{
reserve(1);
data[dim++] = ptr;
}
void *Array::pop()
{
return data[--dim];
}
void Array::shift(void *ptr)
{
reserve(1);
memmove(data + 1, data, dim * sizeof(*data));
data[0] = ptr;
dim++;
}
void Array::insert(unsigned index, void *ptr)
{
reserve(1);
memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
data[index] = ptr;
dim++;
}
void Array::insert(unsigned index, Array *a)
{
if (a)
{ unsigned d;
d = a->dim;
reserve(d);
if (dim != index)
memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
memcpy(data + index, a->data, d * sizeof(*data));
dim += d;
}
}
/***********************************
* Append array a to this array.
*/
void Array::append(Array *a)
{
insert(dim, a);
}
void Array::remove(unsigned i)
{
memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
dim--;
}
char *Array::toChars()
{
unsigned len;
unsigned u;
char **buf;
char *str;
char *p;
buf = (char **)alloca(dim * sizeof(char *));
len = 2;
for (u = 0; u < dim; u++)
{
buf[u] = ((Object *)data[u])->toChars();
len += strlen(buf[u]) + 1;
}
str = (char *)mem.malloc(len);
str[0] = '[';
p = str + 1;
for (u = 0; u < dim; u++)
{
if (u)
*p++ = ',';
len = strlen(buf[u]);
memcpy(p,buf[u],len);
p += len;
}
*p++ = ']';
*p = 0;
return str;
}
void Array::zero()
{
memset(data,0,dim * sizeof(data[0]));
}
void *Array::tos()
{
return dim ? data[dim - 1] : NULL;
}
int
#if _WIN32
__cdecl
#endif
Array_sort_compare(const void *x, const void *y)
{
Object *ox = *(Object **)x;
Object *oy = *(Object **)y;
return ox->compare(oy);
}
void Array::sort()
{
if (dim)
{
qsort(data, dim, sizeof(Object *), Array_sort_compare);
}
}
Array *Array::copy()
{
Array *a = new Array();
a->setDim(dim);
memcpy(a->data, data, dim * sizeof(void *));
return a;
}
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#if (defined (__SVR4) && defined (__sun))
#include <alloca.h>
#endif
#if _MSC_VER || __MINGW32__
#include <malloc.h>
#endif
#if IN_GCC
#include "gdc_alloca.h"
#endif
#if _WIN32
#include <windows.h>
#endif
#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utime.h>
#endif
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "rmem.h"
/********************************* Array ****************************/
Array::Array()
{
data = SMALLARRAYCAP ? &smallarray[0] : NULL;
dim = 0;
allocdim = SMALLARRAYCAP;
}
Array::~Array()
{
if (data != &smallarray[0])
mem.free(data);
}
void Array::mark()
{ unsigned u;
mem.mark(data);
for (u = 0; u < dim; u++)
mem.mark(data[u]); // BUG: what if arrays of Object's?
}
void Array::reserve(unsigned nentries)
{
//printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", dim, allocdim, nentries);
if (allocdim - dim < nentries)
{
if (allocdim == 0)
{ // Not properly initialized, someone memset it to zero
if (nentries <= SMALLARRAYCAP)
{ allocdim = SMALLARRAYCAP;
data = SMALLARRAYCAP ? &smallarray[0] : NULL;
}
else
{ allocdim = nentries;
data = (void **)mem.malloc(allocdim * sizeof(*data));
}
}
else if (allocdim == SMALLARRAYCAP)
{
allocdim = dim + nentries;
data = (void **)mem.malloc(allocdim * sizeof(*data));
memcpy(data, &smallarray[0], dim * sizeof(*data));
}
else
{ allocdim = dim + nentries;
data = (void **)mem.realloc(data, allocdim * sizeof(*data));
}
}
}
void Array::setDim(unsigned newdim)
{
if (dim < newdim)
{
reserve(newdim - dim);
}
dim = newdim;
}
void Array::fixDim()
{
if (dim != allocdim)
{
if (allocdim >= SMALLARRAYCAP)
{
if (dim <= SMALLARRAYCAP)
{
memcpy(&smallarray[0], data, dim * sizeof(*data));
mem.free(data);
}
else
data = (void **)mem.realloc(data, dim * sizeof(*data));
}
allocdim = dim;
}
}
void Array::push(void *ptr)
{
reserve(1);
data[dim++] = ptr;
}
void *Array::pop()
{
return data[--dim];
}
void Array::shift(void *ptr)
{
reserve(1);
memmove(data + 1, data, dim * sizeof(*data));
data[0] = ptr;
dim++;
}
void Array::insert(unsigned index, void *ptr)
{
reserve(1);
memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
data[index] = ptr;
dim++;
}
void Array::insert(unsigned index, Array *a)
{
if (a)
{ unsigned d;
d = a->dim;
reserve(d);
if (dim != index)
memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
memcpy(data + index, a->data, d * sizeof(*data));
dim += d;
}
}
/***********************************
* Append array a to this array.
*/
void Array::append(Array *a)
{
insert(dim, a);
}
void Array::remove(unsigned i)
{
memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
dim--;
}
char *Array::toChars()
{
unsigned len;
unsigned u;
char **buf;
char *str;
char *p;
buf = (char **)alloca(dim * sizeof(char *));
len = 2;
for (u = 0; u < dim; u++)
{
buf[u] = ((Object *)data[u])->toChars();
len += strlen(buf[u]) + 1;
}
str = (char *)mem.malloc(len);
str[0] = '[';
p = str + 1;
for (u = 0; u < dim; u++)
{
if (u)
*p++ = ',';
len = strlen(buf[u]);
memcpy(p,buf[u],len);
p += len;
}
*p++ = ']';
*p = 0;
return str;
}
void Array::zero()
{
memset(data,0,dim * sizeof(data[0]));
}
void *Array::tos()
{
return dim ? data[dim - 1] : NULL;
}
int
#if _WIN32
__cdecl
#endif
Array_sort_compare(const void *x, const void *y)
{
Object *ox = *(Object **)x;
Object *oy = *(Object **)y;
return ox->compare(oy);
}
void Array::sort()
{
if (dim)
{
qsort(data, dim, sizeof(Object *), Array_sort_compare);
}
}
Array *Array::copy()
{
Array *a = new Array();
a->setDim(dim);
memcpy(a->data, data, dim * sizeof(void *));
return a;
}

View File

@@ -8,7 +8,6 @@
#if _WIN32
#include <windows.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
@@ -43,7 +42,7 @@ struct AsyncRead
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}
@@ -64,22 +63,22 @@ void AsyncRead::start()
//printf("aw->filesdim = %p %d\n", this, filesdim);
if (filesdim)
{
unsigned threadaddr;
hThread = (HANDLE) _beginthreadex(NULL,
0,
&startthread,
this,
0,
(unsigned *)&threadaddr);
unsigned threadaddr;
hThread = (HANDLE) _beginthreadex(NULL,
0,
&startthread,
this,
0,
(unsigned *)&threadaddr);
if (hThread)
{
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
}
else
{
assert(0);
}
if (hThread)
{
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
}
else
{
assert(0);
}
}
}
@@ -87,7 +86,7 @@ int AsyncRead::read(size_t i)
{
FileData *f = &files[i];
WaitForSingleObject(f->event, INFINITE);
Sleep(0); // give up time slice
Sleep(0); // give up time slice
return f->result;
}
@@ -104,13 +103,160 @@ unsigned __stdcall startthread(void *p)
//printf("aw->filesdim = %p %d\n", aw, aw->filesdim);
for (size_t i = 0; i < aw->filesdim; i++)
{ FileData *f = &aw->files[i];
{ FileData *f = &aw->files[i];
f->result = f->file->read();
SetEvent(f->event);
f->result = f->file->read();
SetEvent(f->event);
}
_endthreadex(EXIT_SUCCESS);
return EXIT_SUCCESS; // if skidding
return EXIT_SUCCESS; // if skidding
}
#elif linux // Posix
#include <errno.h>
#include <pthread.h>
#include <time.h>
#include "root.h"
#include "rmem.h"
void *startthread(void *arg);
void err_abort(int status, const char *msg)
{
fprintf(stderr, "fatal error = %d, %s\n", status, msg);
exit(EXIT_FAILURE);
}
struct FileData
{
File *file;
int result;
pthread_mutex_t mutex;
pthread_cond_t cond;
int value;
};
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
size_t filesdim;
size_t filesmax;
FileData files[1];
};
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}
void AsyncRead::addFile(File *file)
{
//printf("addFile(file = %p)\n", file);
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
assert(filesdim < filesmax);
FileData *f = &files[filesdim];
f->file = file;
int status = pthread_mutex_init(&f->mutex, NULL);
if (status != 0)
err_abort(status, "init mutex");
status = pthread_cond_init(&f->cond, NULL);
if (status != 0)
err_abort(status, "init cond");
filesdim++;
}
void AsyncRead::start()
{
//printf("aw->filesdim = %p %d\n", this, filesdim);
if (filesdim)
{
pthread_t thread_id;
int status = pthread_create(&thread_id,
NULL,
&startthread,
this);
if (status != 0)
err_abort(status, "create thread");
}
}
int AsyncRead::read(size_t i)
{
FileData *f = &files[i];
// Wait for the event
int status = pthread_mutex_lock(&f->mutex);
if (status != 0)
err_abort(status, "lock mutex");
while (f->value == 0)
{
status = pthread_cond_wait(&f->cond, &f->mutex);
if (status != 0)
err_abort(status, "wait on condition");
}
status = pthread_mutex_unlock(&f->mutex);
if (status != 0)
err_abort(status, "unlock mutex");
return f->result;
}
void AsyncRead::dispose(AsyncRead *aw)
{
//printf("AsyncRead::dispose()\n");
for (int i = 0; i < aw->filesdim; i++)
{
FileData *f = &aw->files[i];
int status = pthread_cond_destroy(&f->cond);
if (status != 0)
err_abort(status, "cond destroy");
status = pthread_mutex_destroy(&f->mutex);
if (status != 0)
err_abort(status, "mutex destroy");
}
delete aw;
}
void *startthread(void *p)
{
AsyncRead *aw = (AsyncRead *)p;
//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);
size_t dim = aw->filesdim;
for (size_t i = 0; i < dim; i++)
{ FileData *f = &aw->files[i];
f->result = f->file->read();
// Set event
int status = pthread_mutex_lock(&f->mutex);
if (status != 0)
err_abort(status, "lock mutex");
f->value = 1;
status = pthread_cond_signal(&f->cond);
if (status != 0)
err_abort(status, "signal condition");
status = pthread_mutex_unlock(&f->mutex);
if (status != 0)
err_abort(status, "unlock mutex");
}
return NULL; // end thread
}
#else
@@ -147,7 +293,7 @@ struct AsyncRead
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}

View File

@@ -1,33 +1,33 @@
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef ASYNC_H
#define ASYNC_H
#if __DMC__
#pragma once
#endif
/*******************
* Simple interface to read files asynchronously in another
* thread.
*/
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
};
#endif
// Copyright (c) 2009-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef ASYNC_H
#define ASYNC_H
#if __DMC__
#pragma once
#endif
/*******************
* Simple interface to read files asynchronously in another
* thread.
*/
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
};
#endif

View File

@@ -1,482 +1,482 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include "dchar.h"
#include "rmem.h"
#if M_UNICODE
// Converts a char string to Unicode
dchar *Dchar::dup(char *p)
{
dchar *s;
size_t len;
if (!p)
return NULL;
len = strlen(p);
s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
for (unsigned i = 0; i < len; i++)
{
s[i] = (dchar)(p[i] & 0xFF);
}
s[len] = 0;
return s;
}
dchar *Dchar::memchr(dchar *p, int c, int count)
{
int u;
for (u = 0; u < count; u++)
{
if (p[u] == c)
return p + u;
}
return NULL;
}
#if _WIN32 && __DMC__
__declspec(naked)
unsigned Dchar::calcHash(const dchar *str, unsigned len)
{
__asm
{
mov ECX,4[ESP]
mov EDX,8[ESP]
xor EAX,EAX
test EDX,EDX
je L92
LC8: cmp EDX,1
je L98
cmp EDX,2
je LAE
add EAX,[ECX]
// imul EAX,EAX,025h
lea EAX,[EAX][EAX*8]
add ECX,4
sub EDX,2
jmp LC8
L98: mov DX,[ECX]
and EDX,0FFFFh
add EAX,EDX
ret
LAE: add EAX,[ECX]
L92: ret
}
}
#else
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
unsigned hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str;
return hash;
case 2:
hash += *(const uint32_t *)str;
return hash;
default:
hash += *(const uint32_t *)str;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#endif
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str | 0x20;
return hash;
case 2:
hash += *(const uint32_t *)str | 0x200020;
return hash;
default:
hash += *(const uint32_t *)str | 0x200020;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#elif MCBS
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str;
return hash;
case 3:
hash *= 37;
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str;
str += 4;
len -= 4;
break;
}
}
}
#elif UTF8
// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
char Dchar::mblen[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
};
dchar *Dchar::dec(dchar *pstart, dchar *p)
{
while ((p[-1] & 0xC0) == 0x80)
p--;
return p;
}
int Dchar::get(dchar *p)
{
unsigned c;
unsigned char *q = (unsigned char *)p;
c = q[0];
switch (mblen[c])
{
case 2:
c = ((c - 0xC0) << 6) |
(q[1] - 0x80);
break;
case 3:
c = ((c - 0xE0) << 12) |
((q[1] - 0x80) << 6) |
(q[2] - 0x80);
break;
case 4:
c = ((c - 0xF0) << 18) |
((q[1] - 0x80) << 12) |
((q[2] - 0x80) << 6) |
(q[3] - 0x80);
break;
case 5:
c = ((c - 0xF8) << 24) |
((q[1] - 0x80) << 18) |
((q[2] - 0x80) << 12) |
((q[3] - 0x80) << 6) |
(q[4] - 0x80);
break;
case 6:
c = ((c - 0xFC) << 30) |
((q[1] - 0x80) << 24) |
((q[2] - 0x80) << 18) |
((q[3] - 0x80) << 12) |
((q[4] - 0x80) << 6) |
(q[5] - 0x80);
break;
}
return c;
}
dchar *Dchar::put(dchar *p, unsigned c)
{
if (c <= 0x7F)
{
*p++ = c;
}
else if (c <= 0x7FF)
{
p[0] = 0xC0 + (c >> 6);
p[1] = 0x80 + (c & 0x3F);
p += 2;
}
else if (c <= 0xFFFF)
{
p[0] = 0xE0 + (c >> 12);
p[1] = 0x80 + ((c >> 6) & 0x3F);
p[2] = 0x80 + (c & 0x3F);
p += 3;
}
else if (c <= 0x1FFFFF)
{
p[0] = 0xF0 + (c >> 18);
p[1] = 0x80 + ((c >> 12) & 0x3F);
p[2] = 0x80 + ((c >> 6) & 0x3F);
p[3] = 0x80 + (c & 0x3F);
p += 4;
}
else if (c <= 0x3FFFFFF)
{
p[0] = 0xF8 + (c >> 24);
p[1] = 0x80 + ((c >> 18) & 0x3F);
p[2] = 0x80 + ((c >> 12) & 0x3F);
p[3] = 0x80 + ((c >> 6) & 0x3F);
p[4] = 0x80 + (c & 0x3F);
p += 5;
}
else if (c <= 0x7FFFFFFF)
{
p[0] = 0xFC + (c >> 30);
p[1] = 0x80 + ((c >> 24) & 0x3F);
p[2] = 0x80 + ((c >> 18) & 0x3F);
p[3] = 0x80 + ((c >> 12) & 0x3F);
p[4] = 0x80 + ((c >> 6) & 0x3F);
p[5] = 0x80 + (c & 0x3F);
p += 6;
}
else
assert(0); // not a UCS-4 character
return p;
}
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if __I86__
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if __I86__
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if __I86__
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
#else // ascii
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if __I86__
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if __I86__
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if __I86__
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str | 0x20;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str | 0x2020;
return hash;
case 3:
hash *= 37;
hash += ((*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2]) | 0x202020;
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str | 0x20202020;
str += 4;
len -= 4;
break;
}
}
}
#endif
#if 0
#include <stdio.h>
void main()
{
// Print out values to hardcode into Dchar::mblen[]
int c;
int s;
for (c = 0; c < 256; c++)
{
s = 1;
if (c >= 0xC0 && c <= 0xDF)
s = 2;
if (c >= 0xE0 && c <= 0xEF)
s = 3;
if (c >= 0xF0 && c <= 0xF7)
s = 4;
if (c >= 0xF8 && c <= 0xFB)
s = 5;
if (c >= 0xFC && c <= 0xFD)
s = 6;
printf("%d", s);
if ((c & 15) == 15)
printf(",\n");
else
printf(",");
}
}
#endif
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include "dchar.h"
#include "rmem.h"
#if M_UNICODE
// Converts a char string to Unicode
dchar *Dchar::dup(char *p)
{
dchar *s;
size_t len;
if (!p)
return NULL;
len = strlen(p);
s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
for (unsigned i = 0; i < len; i++)
{
s[i] = (dchar)(p[i] & 0xFF);
}
s[len] = 0;
return s;
}
dchar *Dchar::memchr(dchar *p, int c, int count)
{
int u;
for (u = 0; u < count; u++)
{
if (p[u] == c)
return p + u;
}
return NULL;
}
#if _WIN32 && __DMC__
__declspec(naked)
unsigned Dchar::calcHash(const dchar *str, unsigned len)
{
__asm
{
mov ECX,4[ESP]
mov EDX,8[ESP]
xor EAX,EAX
test EDX,EDX
je L92
LC8: cmp EDX,1
je L98
cmp EDX,2
je LAE
add EAX,[ECX]
// imul EAX,EAX,025h
lea EAX,[EAX][EAX*8]
add ECX,4
sub EDX,2
jmp LC8
L98: mov DX,[ECX]
and EDX,0FFFFh
add EAX,EDX
ret
LAE: add EAX,[ECX]
L92: ret
}
}
#else
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
unsigned hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str;
return hash;
case 2:
hash += *(const uint32_t *)str;
return hash;
default:
hash += *(const uint32_t *)str;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#endif
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str | 0x20;
return hash;
case 2:
hash += *(const uint32_t *)str | 0x200020;
return hash;
default:
hash += *(const uint32_t *)str | 0x200020;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#elif MCBS
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str;
return hash;
case 3:
hash *= 37;
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str;
str += 4;
len -= 4;
break;
}
}
}
#elif UTF8
// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
char Dchar::mblen[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
};
dchar *Dchar::dec(dchar *pstart, dchar *p)
{
while ((p[-1] & 0xC0) == 0x80)
p--;
return p;
}
int Dchar::get(dchar *p)
{
unsigned c;
unsigned char *q = (unsigned char *)p;
c = q[0];
switch (mblen[c])
{
case 2:
c = ((c - 0xC0) << 6) |
(q[1] - 0x80);
break;
case 3:
c = ((c - 0xE0) << 12) |
((q[1] - 0x80) << 6) |
(q[2] - 0x80);
break;
case 4:
c = ((c - 0xF0) << 18) |
((q[1] - 0x80) << 12) |
((q[2] - 0x80) << 6) |
(q[3] - 0x80);
break;
case 5:
c = ((c - 0xF8) << 24) |
((q[1] - 0x80) << 18) |
((q[2] - 0x80) << 12) |
((q[3] - 0x80) << 6) |
(q[4] - 0x80);
break;
case 6:
c = ((c - 0xFC) << 30) |
((q[1] - 0x80) << 24) |
((q[2] - 0x80) << 18) |
((q[3] - 0x80) << 12) |
((q[4] - 0x80) << 6) |
(q[5] - 0x80);
break;
}
return c;
}
dchar *Dchar::put(dchar *p, unsigned c)
{
if (c <= 0x7F)
{
*p++ = c;
}
else if (c <= 0x7FF)
{
p[0] = 0xC0 + (c >> 6);
p[1] = 0x80 + (c & 0x3F);
p += 2;
}
else if (c <= 0xFFFF)
{
p[0] = 0xE0 + (c >> 12);
p[1] = 0x80 + ((c >> 6) & 0x3F);
p[2] = 0x80 + (c & 0x3F);
p += 3;
}
else if (c <= 0x1FFFFF)
{
p[0] = 0xF0 + (c >> 18);
p[1] = 0x80 + ((c >> 12) & 0x3F);
p[2] = 0x80 + ((c >> 6) & 0x3F);
p[3] = 0x80 + (c & 0x3F);
p += 4;
}
else if (c <= 0x3FFFFFF)
{
p[0] = 0xF8 + (c >> 24);
p[1] = 0x80 + ((c >> 18) & 0x3F);
p[2] = 0x80 + ((c >> 12) & 0x3F);
p[3] = 0x80 + ((c >> 6) & 0x3F);
p[4] = 0x80 + (c & 0x3F);
p += 5;
}
else if (c <= 0x7FFFFFFF)
{
p[0] = 0xFC + (c >> 30);
p[1] = 0x80 + ((c >> 24) & 0x3F);
p[2] = 0x80 + ((c >> 18) & 0x3F);
p[3] = 0x80 + ((c >> 12) & 0x3F);
p[4] = 0x80 + ((c >> 6) & 0x3F);
p[5] = 0x80 + (c & 0x3F);
p += 6;
}
else
assert(0); // not a UCS-4 character
return p;
}
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if __I86__
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if __I86__
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if __I86__
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
#else // ascii
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if __I86__
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if __I86__
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if __I86__
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str | 0x20;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str | 0x2020;
return hash;
case 3:
hash *= 37;
hash += ((*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2]) | 0x202020;
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str | 0x20202020;
str += 4;
len -= 4;
break;
}
}
}
#endif
#if 0
#include <stdio.h>
void main()
{
// Print out values to hardcode into Dchar::mblen[]
int c;
int s;
for (c = 0; c < 256; c++)
{
s = 1;
if (c >= 0xC0 && c <= 0xDF)
s = 2;
if (c >= 0xE0 && c <= 0xEF)
s = 3;
if (c >= 0xF0 && c <= 0xF7)
s = 4;
if (c >= 0xF8 && c <= 0xFB)
s = 5;
if (c >= 0xFC && c <= 0xFD)
s = 6;
printf("%d", s);
if ((c & 15) == 15)
printf(",\n");
else
printf(",");
}
}
#endif

View File

@@ -1,194 +1,194 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DCHAR_H
#define DCHAR_H
#if __GNUC__ && !_WIN32
#include "gnuc.h"
#endif
#if _MSC_VER
// Disable useless warnings about unreferenced functions
#pragma warning (disable : 4514)
#endif
//#include "root.h"
typedef size_t hash_t;
#undef TEXT
// NOTE: All functions accepting pointer arguments must not be NULL
#if M_UNICODE
#include <string.h>
#include <wchar.h>
typedef wchar_t dchar;
#define TEXT(x) L##x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
static int len(const dchar *p) { return wcslen(p); }
static dchar get(dchar *p) { return *p; }
static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2)
{
#if __DMC__
if (!*s1 && !*s2) // wcscmp is broken
return 0;
#endif
return wcscmp(s1, s2);
#if 0
return (*s1 == *s2)
? wcscmp(s1, s2)
: ((int)*s1 - (int)*s2);
#endif
}
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return iswalpha(c); }
static int isUpper(dchar c) { return iswupper(c); }
static int isLower(dchar c) { return iswlower(c); }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
static dchar *dup(dchar *p) { return ::_wcsdup(p); } // BUG: out of memory?
static dchar *dup(char *p);
static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
static dchar *memchr(dchar *p, int c, int count);
static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#elif MCBS
#include <limits.h>
#include <mbstring.h>
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax MB_LEN_MAX
#elif UTF8
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 6
struct Dchar
{
static char mblen[256];
static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
static dchar *dec(dchar *pstart, dchar *p);
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p);
static int getprev(dchar *pstart, dchar *p)
{ return *dec(pstart, p) & 0xFF; }
static dchar *put(dchar *p, unsigned c);
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
};
#else
#include <string.h>
#ifndef GCC_SAFE_DMD
#include <ctype.h>
#endif
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p) { return *p & 0xFF; }
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
#ifndef GCC_SAFE_DMD
static int isAlpha(dchar c) { return isalpha(c); }
static int isUpper(dchar c) { return isupper(c); }
static int isLower(dchar c) { return islower(c); }
static int isLocaleUpper(dchar c) { return isupper(c); }
static int isLocaleLower(dchar c) { return islower(c); }
static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
#endif
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
#ifdef __GNUC__
static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
#else
static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
#endif
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#endif
#endif
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DCHAR_H
#define DCHAR_H
#if __GNUC__ && !_WIN32
#include "gnuc.h"
#endif
#if _MSC_VER
// Disable useless warnings about unreferenced functions
#pragma warning (disable : 4514)
#endif
//#include "root.h"
typedef size_t hash_t;
#undef TEXT
// NOTE: All functions accepting pointer arguments must not be NULL
#if M_UNICODE
#include <string.h>
#include <wchar.h>
typedef wchar_t dchar;
#define TEXT(x) L##x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
static int len(const dchar *p) { return wcslen(p); }
static dchar get(dchar *p) { return *p; }
static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2)
{
#if __DMC__
if (!*s1 && !*s2) // wcscmp is broken
return 0;
#endif
return wcscmp(s1, s2);
#if 0
return (*s1 == *s2)
? wcscmp(s1, s2)
: ((int)*s1 - (int)*s2);
#endif
}
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return iswalpha(c); }
static int isUpper(dchar c) { return iswupper(c); }
static int isLower(dchar c) { return iswlower(c); }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
static dchar *dup(dchar *p) { return ::_wcsdup(p); } // BUG: out of memory?
static dchar *dup(char *p);
static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
static dchar *memchr(dchar *p, int c, int count);
static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#elif MCBS
#include <limits.h>
#include <mbstring.h>
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax MB_LEN_MAX
#elif UTF8
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 6
struct Dchar
{
static char mblen[256];
static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
static dchar *dec(dchar *pstart, dchar *p);
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p);
static int getprev(dchar *pstart, dchar *p)
{ return *dec(pstart, p) & 0xFF; }
static dchar *put(dchar *p, unsigned c);
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
};
#else
#include <string.h>
#ifndef GCC_SAFE_DMD
#include <ctype.h>
#endif
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p) { return *p & 0xFF; }
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
#ifndef GCC_SAFE_DMD
static int isAlpha(dchar c) { return isalpha(c); }
static int isUpper(dchar c) { return isupper(c); }
static int isLower(dchar c) { return islower(c); }
static int isLocaleUpper(dchar c) { return isupper(c); }
static int isLocaleLower(dchar c) { return islower(c); }
static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
#endif
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
#ifdef __GNUC__
static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
#else
static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
#endif
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#endif
#endif

View File

@@ -8,20 +8,20 @@ int memicmp(const char *s1, const char *s2, int n)
int result = 0;
for (int i = 0; i < n; i++)
{ char c1 = s1[i];
char c2 = s2[i];
{ char c1 = s1[i];
char c2 = s2[i];
result = c1 - c2;
if (result)
{
if ('A' <= c1 && c1 <= 'Z')
c1 += 'a' - 'A';
if ('A' <= c2 && c2 <= 'Z')
c2 += 'a' - 'A';
result = c1 - c2;
if (result)
break;
}
result = c1 - c2;
if (result)
{
if ('A' <= c1 && c1 <= 'Z')
c1 += 'a' - 'A';
if ('A' <= c2 && c2 <= 'Z')
c2 += 'a' - 'A';
result = c1 - c2;
if (result)
break;
}
}
return result;
}
@@ -31,24 +31,24 @@ int stricmp(const char *s1, const char *s2)
int result = 0;
for (;;)
{ char c1 = *s1;
char c2 = *s2;
{ char c1 = *s1;
char c2 = *s2;
result = c1 - c2;
if (result)
{
if ('A' <= c1 && c1 <= 'Z')
c1 += 'a' - 'A';
if ('A' <= c2 && c2 <= 'Z')
c2 += 'a' - 'A';
result = c1 - c2;
if (result)
break;
}
if (!c1)
break;
s1++;
s2++;
result = c1 - c2;
if (result)
{
if ('A' <= c1 && c1 <= 'Z')
c1 += 'a' - 'A';
if ('A' <= c2 && c2 <= 'Z')
c2 += 'a' - 'A';
result = c1 - c2;
if (result)
break;
}
if (!c1)
break;
s1++;
s2++;
}
return result;
}

View File

@@ -1,63 +1,63 @@
// lstring.c
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdlib.h>
#include "dchar.h"
#include "rmem.h"
#include "lstring.h"
#ifdef _MSC_VER // prevent compiler internal crash
Lstring Lstring::zero;
#else
Lstring Lstring::zero = LSTRING_EMPTY();
#endif
Lstring *Lstring::ctor(const dchar *p, unsigned length)
{
Lstring *s;
s = alloc(length);
memcpy(s->string, p, length * sizeof(dchar));
return s;
}
Lstring *Lstring::alloc(unsigned length)
{
Lstring *s;
s = (Lstring *)mem.malloc(size(length));
s->length = length;
s->string[length] = 0;
return s;
}
Lstring *Lstring::append(const Lstring *s)
{
Lstring *t;
if (!s->length)
return this;
t = alloc(length + s->length);
memcpy(t->string, string, length * sizeof(dchar));
memcpy(t->string + length, s->string, s->length * sizeof(dchar));
return t;
}
Lstring *Lstring::substring(int start, int end)
{
Lstring *t;
if (start == end)
return &zero;
t = alloc(end - start);
memcpy(t->string, string + start, (end - start) * sizeof(dchar));
return t;
}
// lstring.c
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdlib.h>
#include "dchar.h"
#include "rmem.h"
#include "lstring.h"
#ifdef _MSC_VER // prevent compiler internal crash
Lstring Lstring::zero;
#else
Lstring Lstring::zero = LSTRING_EMPTY();
#endif
Lstring *Lstring::ctor(const dchar *p, unsigned length)
{
Lstring *s;
s = alloc(length);
memcpy(s->string, p, length * sizeof(dchar));
return s;
}
Lstring *Lstring::alloc(unsigned length)
{
Lstring *s;
s = (Lstring *)mem.malloc(size(length));
s->length = length;
s->string[length] = 0;
return s;
}
Lstring *Lstring::append(const Lstring *s)
{
Lstring *t;
if (!s->length)
return this;
t = alloc(length + s->length);
memcpy(t->string, string, length * sizeof(dchar));
memcpy(t->string + length, s->string, s->length * sizeof(dchar));
return t;
}
Lstring *Lstring::substring(int start, int end)
{
Lstring *t;
if (start == end)
return &zero;
t = alloc(end - start);
memcpy(t->string, string + start, (end - start) * sizeof(dchar));
return t;
}

View File

@@ -1,72 +1,72 @@
// lstring.h
// length-prefixed strings
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef LSTRING_H
#define LSTRING_H 1
#include "dchar.h"
struct Lstring
{
unsigned length;
// Disable warning about nonstandard extension
#pragma warning (disable : 4200)
dchar string[];
static Lstring zero; // 0 length string
// No constructors because we want to be able to statically
// initialize Lstring's, and Lstrings are of variable size.
#if M_UNICODE
#define LSTRING(p,length) { length, L##p }
#else
#define LSTRING(p,length) { length, p }
#endif
#if __GNUC__
#define LSTRING_EMPTY() { 0 }
#else
#define LSTRING_EMPTY() LSTRING("", 0)
#endif
static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
static Lstring *ctor(const dchar *p, unsigned length);
static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
static Lstring *alloc(unsigned length);
Lstring *clone();
unsigned len() { return length; }
dchar *toDchars() { return string; }
hash_t hash() { return Dchar::calcHash(string, length); }
hash_t ihash() { return Dchar::icalcHash(string, length); }
static int cmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
}
static int icmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
}
Lstring *append(const Lstring *s);
Lstring *substring(int start, int end);
};
#endif
// lstring.h
// length-prefixed strings
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef LSTRING_H
#define LSTRING_H 1
#include "dchar.h"
struct Lstring
{
unsigned length;
// Disable warning about nonstandard extension
#pragma warning (disable : 4200)
dchar string[];
static Lstring zero; // 0 length string
// No constructors because we want to be able to statically
// initialize Lstring's, and Lstrings are of variable size.
#if M_UNICODE
#define LSTRING(p,length) { length, L##p }
#else
#define LSTRING(p,length) { length, p }
#endif
#if __GNUC__
#define LSTRING_EMPTY() { 0 }
#else
#define LSTRING_EMPTY() LSTRING("", 0)
#endif
static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
static Lstring *ctor(const dchar *p, unsigned length);
static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
static Lstring *alloc(unsigned length);
Lstring *clone();
unsigned len() { return length; }
dchar *toDchars() { return string; }
hash_t hash() { return Dchar::calcHash(string, length); }
hash_t ihash() { return Dchar::icalcHash(string, length); }
static int cmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
}
static int icmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
}
Lstring *append(const Lstring *s);
Lstring *substring(int start, int end);
};
#endif

View File

@@ -1,100 +1,100 @@
// Compiler implementation of the D programming language
// Copyright (c) 2008-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#pragma comment(lib,"shell32.lib")
void browse(const char *url)
{
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}
#endif
#if linux || __FreeBSD__ || __sun&&__SVR4
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[3];
char *browser = getenv("BROWSER");
if (browser)
browser = strdup(browser);
else
browser = "x-www-browser";
args[0] = browser;
args[1] = url;
args[2] = NULL;
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
#if __APPLE__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[5];
char *browser = getenv("BROWSER");
if (browser)
{ browser = strdup(browser);
args[0] = browser;
args[1] = url;
args[2] = NULL;
}
else
{
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
args[0] = "open";
args[1] = "-a";
args[2] = "/Applications/Safari.app";
args[3] = url;
args[4] = NULL;
}
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
// Compiler implementation of the D programming language
// Copyright (c) 2008-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#pragma comment(lib,"shell32.lib")
void browse(const char *url)
{
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}
#endif
#if linux || __FreeBSD__ || __sun&&__SVR4
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[3];
const char *browser = getenv("BROWSER");
if (browser)
browser = strdup(browser);
else
browser = "x-www-browser";
args[0] = browser;
args[1] = url;
args[2] = NULL;
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif
#if __APPLE__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void browse(const char *url)
{
pid_t childpid;
const char *args[5];
char *browser = getenv("BROWSER");
if (browser)
{ browser = strdup(browser);
args[0] = browser;
args[1] = url;
args[2] = NULL;
}
else
{
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
args[0] = "open";
args[1] = "-a";
args[2] = "/Applications/Safari.app";
args[3] = url;
args[4] = NULL;
}
childpid = fork();
if (childpid == 0)
{
execvp(args[0], (char**)args);
perror(args[0]); // failed to execute
return;
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,78 +1,78 @@
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#ifndef PORT_H
#define PORT_H
// Portable wrapper around compiler/system specific things.
// The idea is to minimize #ifdef's in the app code.
#ifndef TYPEDEFS
#define TYPEDEFS
#include <wchar.h>
#if _MSC_VER
typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
#define strtof strtod
#else
typedef long long longlong;
typedef unsigned long long ulonglong;
#endif
#endif
typedef double d_time;
struct Port
{
static double nan;
static double infinity;
static double dbl_max;
static double dbl_min;
static long double ldbl_max;
#if __GNUC__
// These conflict with macros in math.h, should rename them
#undef isnan
#undef isfinite
#undef isinfinity
#undef signbit
#endif
static int isNan(double);
static int isNan(long double);
static int isSignallingNan(double);
static int isSignallingNan(long double);
static int isFinite(double);
static int isInfinity(double);
static int Signbit(double);
static double floor(double);
static double pow(double x, double y);
static ulonglong strtoull(const char *p, char **pend, int base);
static char *ull_to_string(char *buffer, ulonglong ull);
static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull);
// Convert ulonglong to double
static double ull_to_double(ulonglong ull);
// Get locale-dependent list separator
static const char *list_separator();
static const wchar_t *wlist_separator();
static char *strupr(char *);
};
#endif
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#ifndef PORT_H
#define PORT_H
// Portable wrapper around compiler/system specific things.
// The idea is to minimize #ifdef's in the app code.
#ifndef TYPEDEFS
#define TYPEDEFS
#include <wchar.h>
#if _MSC_VER
typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
#define strtof strtod
#else
typedef long long longlong;
typedef unsigned long long ulonglong;
#endif
#endif
typedef double d_time;
struct Port
{
static double nan;
static double infinity;
static double dbl_max;
static double dbl_min;
static long double ldbl_max;
#if __GNUC__
// These conflict with macros in math.h, should rename them
#undef isnan
#undef isfinite
#undef isinfinity
#undef signbit
#endif
static int isNan(double);
static int isNan(long double);
static int isSignallingNan(double);
static int isSignallingNan(long double);
static int isFinite(double);
static int isInfinity(double);
static int Signbit(double);
static double floor(double);
static double pow(double x, double y);
static ulonglong strtoull(const char *p, char **pend, int base);
static char *ull_to_string(char *buffer, ulonglong ull);
static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull);
// Convert ulonglong to double
static double ull_to_double(ulonglong ull);
// Get locale-dependent list separator
static const char *list_separator();
static const wchar_t *wlist_separator();
static char *strupr(char *);
};
#endif

View File

@@ -1,275 +1,275 @@
// Copyright (C) 1990-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
/*
* This source file is made available for personal use
* only. The license is in /dmd/src/dmd/backendlicense.txt
* For any other uses, please contact Digital Mars.
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#if _WIN32
#include <tchar.h>
#include <io.h>
#endif
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utime.h>
#endif
/*********************************
* #include <stdlib.h>
* int response_expand(int *pargc,char ***pargv);
*
* Expand any response files in command line.
* Response files are arguments that look like:
* @NAME
* The name is first searched for in the environment. If it is not
* there, it is searched for as a file name.
* Arguments are separated by spaces, tabs, or newlines. These can be
* imbedded within arguments by enclosing the argument in '' or "".
* Recursively expands nested response files.
*
* To use, put the line:
* response_expand(&argc,&argv);
* as the first executable statement in main(int argc, char **argv).
* argc and argv are adjusted to be the new command line arguments
* after response file expansion.
*
* Digital Mars's MAKE program can be notified that a program can accept
* long command lines via environment variables by preceding the rule
* line for the program with a *.
*
* Returns:
* 0 success
* !=0 failure (argc, argv unchanged)
*/
struct Narg
{
int argc; /* arg count */
int argvmax; /* dimension of nargv[] */
char **argv;
};
static int addargp(struct Narg *n, char *p)
{
/* The 2 is to always allow room for a NULL argp at the end */
if (n->argc + 2 >= n->argvmax)
{
n->argvmax = n->argc + 2;
n->argv = (char **) realloc(n->argv,n->argvmax * sizeof(char *));
if (!n->argv)
return 1;
}
n->argv[n->argc++] = p;
return 0;
}
int response_expand(int *pargc, char ***pargv)
{
struct Narg n;
int i;
char *cp;
int recurse = 0;
n.argc = 0;
n.argvmax = 0; /* dimension of n.argv[] */
n.argv = NULL;
for(i=0; i<*pargc; ++i)
{
cp = (*pargv)[i];
if (*cp == '@')
{
char *buffer;
char *bufend;
char *p;
cp++;
p = getenv(cp);
if (p)
{
buffer = strdup(p);
if (!buffer)
goto noexpand;
bufend = buffer + strlen(buffer);
}
else
{
long length;
int fd;
int nread;
size_t len;
#if __DMC__
length = filesize(cp);
#else
struct stat statbuf;
if (stat(cp, &statbuf))
goto noexpand;
length = statbuf.st_size;
#endif
if (length & 0xF0000000) /* error or file too big */
goto noexpand;
len = length;
buffer = (char *)malloc(len + 1);
if (!buffer)
goto noexpand;
bufend = &buffer[len];
/* Read file into buffer */
#if _WIN32
fd = open(cp,O_RDONLY|O_BINARY);
#else
fd = open(cp,O_RDONLY);
#endif
if (fd == -1)
goto noexpand;
nread = read(fd,buffer,len);
close(fd);
if (nread != len)
goto noexpand;
}
// The logic of this should match that in setargv()
for (p = buffer; p < bufend; p++)
{
char *d;
char c,lastc;
unsigned char instring;
int num_slashes,non_slashes;
switch (*p)
{
case 26: /* ^Z marks end of file */
goto L2;
case 0xD:
case 0:
case ' ':
case '\t':
case '\n':
continue; // scan to start of argument
case '@':
recurse = 1;
default: /* start of new argument */
if (addargp(&n,p))
goto noexpand;
instring = 0;
c = 0;
num_slashes = 0;
for (d = p; 1; p++)
{
lastc = c;
if (p >= bufend)
goto Lend;
c = *p;
switch (c)
{
case '"':
/*
Yes this looks strange,but this is so that we are
MS Compatible, tests have shown that:
\\\\"foo bar" gets passed as \\foo bar
\\\\foo gets passed as \\\\foo
\\\"foo gets passed as \"foo
and \"foo gets passed as "foo in VC!
*/
non_slashes = num_slashes % 2;
num_slashes = num_slashes / 2;
for (; num_slashes > 0; num_slashes--)
{
d--;
*d = '\0';
}
if (non_slashes)
{
*(d-1) = c;
}
else
{
instring ^= 1;
}
break;
case 26:
Lend:
*d = 0; // terminate argument
goto L2;
case 0xD: // CR
c = lastc;
continue; // ignore
case '@':
recurse = 1;
goto Ladd;
case ' ':
case '\t':
if (!instring)
{
case '\n':
case 0:
*d = 0; // terminate argument
goto Lnextarg;
}
default:
Ladd:
if (c == '\\')
num_slashes++;
else
num_slashes = 0;
*d++ = c;
break;
}
#ifdef _MBCS
if (_istlead (c)) {
*d++ = *++p;
if (*(d - 1) == '\0') {
d--;
goto Lnextarg;
}
}
#endif
}
break;
}
Lnextarg:
;
}
L2:
;
}
else if (addargp(&n,(*pargv)[i]))
goto noexpand;
}
n.argv[n.argc] = NULL;
if (recurse)
{
/* Recursively expand @filename */
if (response_expand(&n.argc,&n.argv))
goto noexpand;
}
*pargc = n.argc;
*pargv = n.argv;
return 0; /* success */
noexpand: /* error */
free(n.argv);
/* BUG: any file buffers are not free'd */
return 1;
}
// Copyright (C) 1990-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
/*
* This source file is made available for personal use
* only. The license is in /dmd/src/dmd/backendlicense.txt
* For any other uses, please contact Digital Mars.
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#if _WIN32
#include <tchar.h>
#include <io.h>
#endif
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utime.h>
#endif
/*********************************
* #include <stdlib.h>
* int response_expand(int *pargc,char ***pargv);
*
* Expand any response files in command line.
* Response files are arguments that look like:
* @NAME
* The name is first searched for in the environment. If it is not
* there, it is searched for as a file name.
* Arguments are separated by spaces, tabs, or newlines. These can be
* imbedded within arguments by enclosing the argument in '' or "".
* Recursively expands nested response files.
*
* To use, put the line:
* response_expand(&argc,&argv);
* as the first executable statement in main(int argc, char **argv).
* argc and argv are adjusted to be the new command line arguments
* after response file expansion.
*
* Digital Mars's MAKE program can be notified that a program can accept
* long command lines via environment variables by preceding the rule
* line for the program with a *.
*
* Returns:
* 0 success
* !=0 failure (argc, argv unchanged)
*/
struct Narg
{
int argc; /* arg count */
int argvmax; /* dimension of nargv[] */
char **argv;
};
static int addargp(struct Narg *n, char *p)
{
/* The 2 is to always allow room for a NULL argp at the end */
if (n->argc + 2 >= n->argvmax)
{
n->argvmax = n->argc + 2;
n->argv = (char **) realloc(n->argv,n->argvmax * sizeof(char *));
if (!n->argv)
return 1;
}
n->argv[n->argc++] = p;
return 0;
}
int response_expand(int *pargc, char ***pargv)
{
struct Narg n;
int i;
char *cp;
int recurse = 0;
n.argc = 0;
n.argvmax = 0; /* dimension of n.argv[] */
n.argv = NULL;
for(i=0; i<*pargc; ++i)
{
cp = (*pargv)[i];
if (*cp == '@')
{
char *buffer;
char *bufend;
char *p;
cp++;
p = getenv(cp);
if (p)
{
buffer = strdup(p);
if (!buffer)
goto noexpand;
bufend = buffer + strlen(buffer);
}
else
{
long length;
int fd;
int nread;
size_t len;
#if __DMC__
length = filesize(cp);
#else
struct stat statbuf;
if (stat(cp, &statbuf))
goto noexpand;
length = statbuf.st_size;
#endif
if (length & 0xF0000000) /* error or file too big */
goto noexpand;
len = length;
buffer = (char *)malloc(len + 1);
if (!buffer)
goto noexpand;
bufend = &buffer[len];
/* Read file into buffer */
#if _WIN32
fd = open(cp,O_RDONLY|O_BINARY);
#else
fd = open(cp,O_RDONLY);
#endif
if (fd == -1)
goto noexpand;
nread = read(fd,buffer,len);
close(fd);
if (nread != len)
goto noexpand;
}
// The logic of this should match that in setargv()
for (p = buffer; p < bufend; p++)
{
char *d;
char c,lastc;
unsigned char instring;
int num_slashes,non_slashes;
switch (*p)
{
case 26: /* ^Z marks end of file */
goto L2;
case 0xD:
case 0:
case ' ':
case '\t':
case '\n':
continue; // scan to start of argument
case '@':
recurse = 1;
default: /* start of new argument */
if (addargp(&n,p))
goto noexpand;
instring = 0;
c = 0;
num_slashes = 0;
for (d = p; 1; p++)
{
lastc = c;
if (p >= bufend)
goto Lend;
c = *p;
switch (c)
{
case '"':
/*
Yes this looks strange,but this is so that we are
MS Compatible, tests have shown that:
\\\\"foo bar" gets passed as \\foo bar
\\\\foo gets passed as \\\\foo
\\\"foo gets passed as \"foo
and \"foo gets passed as "foo in VC!
*/
non_slashes = num_slashes % 2;
num_slashes = num_slashes / 2;
for (; num_slashes > 0; num_slashes--)
{
d--;
*d = '\0';
}
if (non_slashes)
{
*(d-1) = c;
}
else
{
instring ^= 1;
}
break;
case 26:
Lend:
*d = 0; // terminate argument
goto L2;
case 0xD: // CR
c = lastc;
continue; // ignore
case '@':
recurse = 1;
goto Ladd;
case ' ':
case '\t':
if (!instring)
{
case '\n':
case 0:
*d = 0; // terminate argument
goto Lnextarg;
}
default:
Ladd:
if (c == '\\')
num_slashes++;
else
num_slashes = 0;
*d++ = c;
break;
}
#ifdef _MBCS
if (_istlead (c)) {
*d++ = *++p;
if (*(d - 1) == '\0') {
d--;
goto Lnextarg;
}
}
#endif
}
break;
}
Lnextarg:
;
}
L2:
;
}
else if (addargp(&n,(*pargv)[i]))
goto noexpand;
}
n.argv[n.argc] = NULL;
if (recurse)
{
/* Recursively expand @filename */
if (response_expand(&n.argc,&n.argv))
goto noexpand;
}
*pargc = n.argc;
*pargv = n.argv;
return 0; /* success */
noexpand: /* error */
free(n.argv);
/* BUG: any file buffers are not free'd */
return 1;
}

View File

@@ -1,51 +1,51 @@
// Copyright (C) 2000-2001 by Chromium Communications
// All Rights Reserved
#ifndef ROOT_MEM_H
#define ROOT_MEM_H
#include <stddef.h> // for size_t
typedef void (*FINALIZERPROC)(void* pObj, void* pClientData);
struct GC; // thread specific allocator
struct Mem
{
GC *gc; // pointer to our thread specific allocator
Mem() { gc = NULL; }
void init();
// Derive from Mem to get these storage allocators instead of global new/delete
void * operator new(size_t m_size);
void * operator new(size_t m_size, Mem *mem);
void * operator new(size_t m_size, GC *gc);
void operator delete(void *p);
void * operator new[](size_t m_size);
void operator delete[](void *p);
char *strdup(const char *s);
void *malloc(size_t size);
void *malloc_uncollectable(size_t size);
void *calloc(size_t size, size_t n);
void *realloc(void *p, size_t size);
void free(void *p);
void free_uncollectable(void *p);
void *mallocdup(void *o, size_t size);
void error();
void check(void *p); // validate pointer
void fullcollect(); // do full garbage collection
void fullcollectNoStack(); // do full garbage collection, no scan stack
void mark(void *pointer);
void addroots(char* pStart, char* pEnd);
void removeroots(char* pStart);
void setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData);
void setStackBottom(void *bottom);
GC *getThreadGC(); // get apartment allocator for this thread
};
extern Mem mem;
#endif /* ROOT_MEM_H */
// Copyright (C) 2000-2001 by Chromium Communications
// All Rights Reserved
#ifndef ROOT_MEM_H
#define ROOT_MEM_H
#include <stddef.h> // for size_t
typedef void (*FINALIZERPROC)(void* pObj, void* pClientData);
struct GC; // thread specific allocator
struct Mem
{
GC *gc; // pointer to our thread specific allocator
Mem() { gc = NULL; }
void init();
// Derive from Mem to get these storage allocators instead of global new/delete
void * operator new(size_t m_size);
void * operator new(size_t m_size, Mem *mem);
void * operator new(size_t m_size, GC *gc);
void operator delete(void *p);
void * operator new[](size_t m_size);
void operator delete[](void *p);
char *strdup(const char *s);
void *malloc(size_t size);
void *malloc_uncollectable(size_t size);
void *calloc(size_t size, size_t n);
void *realloc(void *p, size_t size);
void free(void *p);
void free_uncollectable(void *p);
void *mallocdup(void *o, size_t size);
void error();
void check(void *p); // validate pointer
void fullcollect(); // do full garbage collection
void fullcollectNoStack(); // do full garbage collection, no scan stack
void mark(void *pointer);
void addroots(char* pStart, char* pEnd);
void removeroots(char* pStart);
void setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData);
void setStackBottom(void *bottom);
GC *getThreadGC(); // get apartment allocator for this thread
};
extern Mem mem;
#endif /* ROOT_MEM_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,359 +1,367 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef ROOT_H
#define ROOT_H
#include <stdlib.h>
#include <stdarg.h>
#if __DMC__
#pragma once
#endif
typedef size_t hash_t;
#include "dchar.h"
char *wchar2ascii(wchar_t *);
int wcharIsAscii(wchar_t *);
char *wchar2ascii(wchar_t *, unsigned len);
int wcharIsAscii(wchar_t *, unsigned len);
int bstrcmp(unsigned char *s1, unsigned char *s2);
char *bstr2str(unsigned char *b);
void error(const char *format, ...);
void error(const wchar_t *format, ...);
void warning(const char *format, ...);
#ifndef TYPEDEFS
#define TYPEDEFS
#if _MSC_VER
#include <float.h> // for _isnan
#include <malloc.h> // for alloca
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
#define strtof strtod
#define isnan _isnan
typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
#else
typedef long long longlong;
typedef unsigned long long ulonglong;
#endif
#endif
longlong randomx();
/*
* Root of our class library.
*/
struct OutBuffer;
struct Array;
struct Object
{
Object() { }
virtual ~Object() { }
virtual int equals(Object *o);
/**
* Returns a hash code, useful for things like building hash tables of Objects.
*/
virtual hash_t hashCode();
/**
* Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
* Useful for sorting Objects.
*/
virtual int compare(Object *obj);
/**
* Pretty-print an Object. Useful for debugging the old-fashioned way.
*/
virtual void print();
virtual char *toChars();
virtual dchar *toDchars();
virtual void toBuffer(OutBuffer *buf);
/**
* Used as a replacement for dynamic_cast. Returns a unique number
* defined by the library user. For Object, the return value is 0.
*/
virtual int dyncast();
/**
* Marks pointers for garbage collector by calling mem.mark() for all pointers into heap.
*/
/*virtual*/ // not used, disable for now
void mark();
};
struct String : Object
{
int ref; // != 0 if this is a reference to someone else's string
char *str; // the string itself
String(char *str, int ref = 1);
~String();
static hash_t calcHash(const char *str, size_t len);
static hash_t calcHash(const char *str);
hash_t hashCode();
unsigned len();
int equals(Object *obj);
int compare(Object *obj);
char *toChars();
void print();
void mark();
};
struct FileName : String
{
FileName(char *str, int ref);
FileName(char *path, char *name);
hash_t hashCode();
int equals(Object *obj);
static int equals(const char *name1, const char *name2);
int compare(Object *obj);
static int compare(const char *name1, const char *name2);
static int absolute(const char *name);
static char *ext(const char *);
char *ext();
static char *removeExt(const char *str);
static char *name(const char *);
char *name();
static char *path(const char *);
static const char *replaceName(const char *path, const char *name);
static char *combine(const char *path, const char *name);
static Array *splitPath(const char *path);
static FileName *defaultExt(const char *name, const char *ext);
static FileName *forceExt(const char *name, const char *ext);
int equalsExt(const char *ext);
void CopyTo(FileName *to);
static char *searchPath(Array *path, const char *name, int cwd);
static int exists(const char *name);
static void ensurePathExists(const char *path);
};
struct File : Object
{
int ref; // != 0 if this is a reference to someone else's buffer
unsigned char *buffer; // data for our file
unsigned len; // amount of data in buffer[]
void *touchtime; // system time to use for file
FileName *name; // name of our file
File(char *);
File(FileName *);
~File();
void mark();
char *toChars();
/* Read file, return !=0 if error
*/
int read();
/* Write file, either succeed or fail
* with error message & exit.
*/
void readv();
/* Read file, return !=0 if error
*/
int mmread();
/* Write file, either succeed or fail
* with error message & exit.
*/
void mmreadv();
/* Write file, return !=0 if error
*/
int write();
/* Write file, either succeed or fail
* with error message & exit.
*/
void writev();
/* Return !=0 if file exists.
* 0: file doesn't exist
* 1: normal file
* 2: directory
*/
/* Append to file, return !=0 if error
*/
int append();
/* Append to file, either succeed or fail
* with error message & exit.
*/
void appendv();
/* Return !=0 if file exists.
* 0: file doesn't exist
* 1: normal file
* 2: directory
*/
int exists();
/* Given wildcard filespec, return an array of
* matching File's.
*/
static Array *match(char *);
static Array *match(FileName *);
// Compare file times.
// Return <0 this < f
// =0 this == f
// >0 this > f
int compareTime(File *f);
// Read system file statistics
void stat();
/* Set buffer
*/
void setbuffer(void *buffer, unsigned len)
{
this->buffer = (unsigned char *)buffer;
this->len = len;
}
void checkoffset(size_t offset, size_t nbytes);
void remove(); // delete file
};
struct OutBuffer : Object
{
unsigned char *data;
unsigned offset;
unsigned size;
OutBuffer();
~OutBuffer();
void *extractData();
void mark();
void reserve(unsigned nbytes);
void setsize(unsigned size);
void reset();
void write(const void *data, unsigned nbytes);
void writebstring(unsigned char *string);
void writestring(const char *string);
void writedstring(const char *string);
void writedstring(const wchar_t *string);
void prependstring(const char *string);
void writenl(); // write newline
void writeByte(unsigned b);
void writebyte(unsigned b) { writeByte(b); }
void writeUTF8(unsigned b);
void writedchar(unsigned b);
void prependbyte(unsigned b);
void writeword(unsigned w);
void writeUTF16(unsigned w);
void write4(unsigned w);
void write(OutBuffer *buf);
void write(Object *obj);
void fill0(unsigned nbytes);
void align(unsigned size);
void vprintf(const char *format, va_list args);
void printf(const char *format, ...);
#if M_UNICODE
void vprintf(const unsigned short *format, va_list args);
void printf(const unsigned short *format, ...);
#endif
void bracket(char left, char right);
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
void spread(unsigned offset, unsigned nbytes);
unsigned insert(unsigned offset, const void *data, unsigned nbytes);
void remove(unsigned offset, unsigned nbytes);
char *toChars();
char *extractString();
};
struct Array : Object
{
unsigned dim;
unsigned allocdim;
void **data;
Array();
~Array();
void mark();
char *toChars();
void reserve(unsigned nentries);
void setDim(unsigned newdim);
void fixDim();
void push(void *ptr);
void *pop();
void shift(void *ptr);
void insert(unsigned index, void *ptr);
void insert(unsigned index, Array *a);
void append(Array *a);
void remove(unsigned i);
void zero();
void *tos();
void sort();
Array *copy();
};
struct Bits : Object
{
unsigned bitdim;
unsigned allocdim;
unsigned *data;
Bits();
~Bits();
void mark();
void resize(unsigned bitdim);
void set(unsigned bitnum);
void clear(unsigned bitnum);
int test(unsigned bitnum);
void set();
void clear();
void copy(Bits *from);
Bits *clone();
void sub(Bits *b);
};
#endif
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef ROOT_H
#define ROOT_H
#include <stdlib.h>
#include <stdarg.h>
#if __DMC__
#pragma once
#endif
typedef size_t hash_t;
#include "dchar.h"
char *wchar2ascii(wchar_t *);
int wcharIsAscii(wchar_t *);
char *wchar2ascii(wchar_t *, unsigned len);
int wcharIsAscii(wchar_t *, unsigned len);
int bstrcmp(unsigned char *s1, unsigned char *s2);
char *bstr2str(unsigned char *b);
void error(const char *format, ...);
void error(const wchar_t *format, ...);
void warning(const char *format, ...);
#ifndef TYPEDEFS
#define TYPEDEFS
#if _MSC_VER
#include <float.h> // for _isnan
#include <malloc.h> // for alloca
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
#define strtof strtod
#define isnan _isnan
typedef __int64 longlong;
typedef unsigned __int64 ulonglong;
#else
typedef long long longlong;
typedef unsigned long long ulonglong;
#endif
#endif
longlong randomx();
/*
* Root of our class library.
*/
struct OutBuffer;
struct Array;
struct Object
{
Object() { }
virtual ~Object() { }
virtual int equals(Object *o);
/**
* Returns a hash code, useful for things like building hash tables of Objects.
*/
virtual hash_t hashCode();
/**
* Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
* Useful for sorting Objects.
*/
virtual int compare(Object *obj);
/**
* Pretty-print an Object. Useful for debugging the old-fashioned way.
*/
virtual void print();
virtual char *toChars();
virtual dchar *toDchars();
virtual void toBuffer(OutBuffer *buf);
/**
* Used as a replacement for dynamic_cast. Returns a unique number
* defined by the library user. For Object, the return value is 0.
*/
virtual int dyncast();
/**
* Marks pointers for garbage collector by calling mem.mark() for all pointers into heap.
*/
/*virtual*/ // not used, disable for now
void mark();
};
struct String : Object
{
int ref; // != 0 if this is a reference to someone else's string
char *str; // the string itself
String(char *str, int ref = 1);
~String();
static hash_t calcHash(const char *str, size_t len);
static hash_t calcHash(const char *str);
hash_t hashCode();
unsigned len();
int equals(Object *obj);
int compare(Object *obj);
char *toChars();
void print();
void mark();
};
struct FileName : String
{
FileName(char *str, int ref);
FileName(char *path, char *name);
hash_t hashCode();
int equals(Object *obj);
static int equals(const char *name1, const char *name2);
int compare(Object *obj);
static int compare(const char *name1, const char *name2);
static int absolute(const char *name);
static char *ext(const char *);
char *ext();
static char *removeExt(const char *str);
static char *name(const char *);
char *name();
static char *path(const char *);
static const char *replaceName(const char *path, const char *name);
static char *combine(const char *path, const char *name);
static Array *splitPath(const char *path);
static FileName *defaultExt(const char *name, const char *ext);
static FileName *forceExt(const char *name, const char *ext);
int equalsExt(const char *ext);
void CopyTo(FileName *to);
static char *searchPath(Array *path, const char *name, int cwd);
static char *safeSearchPath(Array *path, const char *name);
static int exists(const char *name);
static void ensurePathExists(const char *path);
static char *canonicalName(const char *name);
};
struct File : Object
{
int ref; // != 0 if this is a reference to someone else's buffer
unsigned char *buffer; // data for our file
unsigned len; // amount of data in buffer[]
void *touchtime; // system time to use for file
FileName *name; // name of our file
File(char *);
File(FileName *);
~File();
void mark();
char *toChars();
/* Read file, return !=0 if error
*/
int read();
/* Write file, either succeed or fail
* with error message & exit.
*/
void readv();
/* Read file, return !=0 if error
*/
int mmread();
/* Write file, either succeed or fail
* with error message & exit.
*/
void mmreadv();
/* Write file, return !=0 if error
*/
int write();
/* Write file, either succeed or fail
* with error message & exit.
*/
void writev();
/* Return !=0 if file exists.
* 0: file doesn't exist
* 1: normal file
* 2: directory
*/
/* Append to file, return !=0 if error
*/
int append();
/* Append to file, either succeed or fail
* with error message & exit.
*/
void appendv();
/* Return !=0 if file exists.
* 0: file doesn't exist
* 1: normal file
* 2: directory
*/
int exists();
/* Given wildcard filespec, return an array of
* matching File's.
*/
static Array *match(char *);
static Array *match(FileName *);
// Compare file times.
// Return <0 this < f
// =0 this == f
// >0 this > f
int compareTime(File *f);
// Read system file statistics
void stat();
/* Set buffer
*/
void setbuffer(void *buffer, unsigned len)
{
this->buffer = (unsigned char *)buffer;
this->len = len;
}
void checkoffset(size_t offset, size_t nbytes);
void remove(); // delete file
};
struct OutBuffer : Object
{
unsigned char *data;
unsigned offset;
unsigned size;
OutBuffer();
~OutBuffer();
void *extractData();
void mark();
void reserve(unsigned nbytes);
void setsize(unsigned size);
void reset();
void write(const void *data, unsigned nbytes);
void writebstring(unsigned char *string);
void writestring(const char *string);
void writedstring(const char *string);
void writedstring(const wchar_t *string);
void prependstring(const char *string);
void writenl(); // write newline
void writeByte(unsigned b);
void writebyte(unsigned b) { writeByte(b); }
void writeUTF8(unsigned b);
void writedchar(unsigned b);
void prependbyte(unsigned b);
void writeword(unsigned w);
void writeUTF16(unsigned w);
void write4(unsigned w);
void write(OutBuffer *buf);
void write(Object *obj);
void fill0(unsigned nbytes);
void align(unsigned size);
void vprintf(const char *format, va_list args);
void printf(const char *format, ...);
#if M_UNICODE
void vprintf(const unsigned short *format, va_list args);
void printf(const unsigned short *format, ...);
#endif
void bracket(char left, char right);
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
void spread(unsigned offset, unsigned nbytes);
unsigned insert(unsigned offset, const void *data, unsigned nbytes);
void remove(unsigned offset, unsigned nbytes);
char *toChars();
char *extractString();
};
struct Array : Object
{
unsigned dim;
void **data;
private:
unsigned allocdim;
#define SMALLARRAYCAP 1
void *smallarray[SMALLARRAYCAP]; // inline storage for small arrays
public:
Array();
~Array();
//Array(const Array&);
void mark();
char *toChars();
void reserve(unsigned nentries);
void setDim(unsigned newdim);
void fixDim();
void push(void *ptr);
void *pop();
void shift(void *ptr);
void insert(unsigned index, void *ptr);
void insert(unsigned index, Array *a);
void append(Array *a);
void remove(unsigned i);
void zero();
void *tos();
void sort();
Array *copy();
};
struct Bits : Object
{
unsigned bitdim;
unsigned allocdim;
unsigned *data;
Bits();
~Bits();
void mark();
void resize(unsigned bitdim);
void set(unsigned bitnum);
void clear(unsigned bitnum);
int test(unsigned bitnum);
void set();
void clear();
void copy(Bits *from);
Bits *clone();
void sub(Bits *b);
};
#endif

253
dmd2/root/speller.c Normal file
View File

@@ -0,0 +1,253 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "speller.h"
const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
/**************************************************
* Looks for correct spelling.
* Currently only looks a 'distance' of one from the seed[].
* This does an exhaustive search, so can potentially be very slow.
* Input:
* seed wrongly spelled word
* fp search function
* fparg argument to search function
* charset character set
* Returns:
* NULL no correct spellings found
* void* value returned by fp() for first possible correct spelling
*/
void *spellerY(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
const char *charset, size_t index)
{
if (!seedlen)
return NULL;
assert(seed[seedlen] == 0);
char tmp[30];
char *buf;
if (seedlen <= sizeof(tmp) - 2)
buf = tmp;
else
{
buf = (char *)alloca(seedlen + 2); // leave space for extra char
if (!buf)
return NULL; // no matches
}
memcpy(buf, seed, index);
/* Delete at seed[index] */
if (index < seedlen)
{
memcpy(buf + index, seed + index + 1, seedlen - index);
assert(buf[seedlen - 1] == 0);
void *p = (*fp)(fparg, buf);
if (p)
return p;
}
if (charset && *charset)
{
/* Substitutions */
if (index < seedlen)
{
memcpy(buf, seed, seedlen + 1);
for (const char *s = charset; *s; s++)
{
buf[index] = *s;
//printf("sub buf = '%s'\n", buf);
void *p = (*fp)(fparg, buf);
if (p)
return p;
}
assert(buf[seedlen] == 0);
}
/* Insertions */
memcpy (buf + index + 1, seed + index, seedlen + 1 - index);
for (const char *s = charset; *s; s++)
{
buf[index] = *s;
//printf("ins buf = '%s'\n", buf);
void *p = (*fp)(fparg, buf);
if (p)
return p;
}
assert(buf[seedlen + 1] == 0);
}
return NULL; // didn't find any corrections
}
void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
const char *charset, int flag)
{
if (!seedlen)
return NULL;
char tmp[30];
char *buf;
if (seedlen <= sizeof(tmp) - 2)
buf = tmp;
else
{
buf = (char *)alloca(seedlen + 2); // leave space for extra char
if (!buf)
return NULL; // no matches
}
/* Deletions */
memcpy(buf, seed + 1, seedlen);
for (int i = 0; i < seedlen; i++)
{
//printf("del buf = '%s'\n", buf);
void *p;
if (flag)
p = spellerY(buf, seedlen - 1, fp, fparg, charset, i);
else
p = (*fp)(fparg, buf);
if (p)
return p;
buf[i] = seed[i];
}
/* Transpositions */
if (!flag)
{
memcpy(buf, seed, seedlen + 1);
for (int i = 0; i + 1 < seedlen; i++)
{
// swap [i] and [i + 1]
buf[i] = seed[i + 1];
buf[i + 1] = seed[i];
//printf("tra buf = '%s'\n", buf);
void *p = (*fp)(fparg, buf);
if (p)
return p;
buf[i] = seed[i];
}
}
if (charset && *charset)
{
/* Substitutions */
memcpy(buf, seed, seedlen + 1);
for (int i = 0; i < seedlen; i++)
{
for (const char *s = charset; *s; s++)
{
buf[i] = *s;
//printf("sub buf = '%s'\n", buf);
void *p;
if (flag)
p = spellerY(buf, seedlen, fp, fparg, charset, i + 1);
else
p = (*fp)(fparg, buf);
if (p)
return p;
}
buf[i] = seed[i];
}
/* Insertions */
memcpy(buf + 1, seed, seedlen + 1);
for (int i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations
{
for (const char *s = charset; *s; s++)
{
buf[i] = *s;
//printf("ins buf = '%s'\n", buf);
void *p;
if (flag)
p = spellerY(buf, seedlen + 1, fp, fparg, charset, i + 1);
else
p = (*fp)(fparg, buf);
if (p)
return p;
}
buf[i] = seed[i]; // going past end of seed[] is ok, as we hit the 0
}
}
return NULL; // didn't find any corrections
}
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
{
size_t seedlen = strlen(seed);
for (int distance = 0; distance < 2; distance++)
{ void *p = spellerX(seed, seedlen, fp, fparg, charset, distance);
if (p)
return p;
// if (seedlen > 10)
// break;
}
return NULL; // didn't find it
}
#if UNITTEST
#include <stdio.h>
#include <string.h>
#include <assert.h>
void *speller_test(void *fparg, const char *s)
{
//printf("speller_test(%s, %s)\n", fparg, s);
if (strcmp((char *)fparg, s) == 0)
return fparg;
return NULL;
}
void unittest_speller()
{
static const char *cases[][3] =
{
{ "hello", "hell", "y" },
{ "hello", "hel", "y" },
{ "hello", "ello", "y" },
{ "hello", "llo", "y" },
{ "hello", "hellox", "y" },
{ "hello", "helloxy", "y" },
{ "hello", "xhello", "y" },
{ "hello", "xyhello", "y" },
{ "hello", "ehllo", "y" },
{ "hello", "helol", "y" },
{ "hello", "abcd", "n" },
//{ "ehllo", "helol", "y" },
{ "hello", "helxxlo", "y" },
{ "hello", "ehlxxlo", "n" },
{ "hello", "heaao", "y" },
{ "_123456789_123456789_123456789_123456789", "_123456789_123456789_123456789_12345678", "y" },
};
//printf("unittest_speller()\n");
const void *p = speller("hello", &speller_test, (void *)"hell", idchars);
assert(p != NULL);
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
{
//printf("case [%d]\n", i);
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
if (p)
assert(cases[i][2][0] == 'y');
else
assert(cases[i][2][0] == 'n');
}
//printf("unittest_speller() success\n");
}
#endif

7
dmd2/root/speller.h Normal file
View File

@@ -0,0 +1,7 @@
typedef void *(fp_speller_t)(void *, const char *);
extern const char idchars[];
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset);

View File

@@ -1,139 +1,139 @@
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "root.h"
#include "rmem.h"
#include "dchar.h"
#include "lstring.h"
#include "stringtable.h"
StringTable::StringTable(unsigned size)
{
table = (void **)mem.calloc(size, sizeof(void *));
tabledim = size;
count = 0;
}
StringTable::~StringTable()
{
unsigned i;
// Zero out dangling pointers to help garbage collector.
// Should zero out StringEntry's too.
for (i = 0; i < count; i++)
table[i] = NULL;
mem.free(table);
table = NULL;
}
struct StringEntry
{
StringEntry *left;
StringEntry *right;
hash_t hash;
StringValue value;
static StringEntry *alloc(const dchar *s, unsigned len);
};
StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
{
StringEntry *se;
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
se->value.lstring.length = len;
se->hash = Dchar::calcHash(s,len);
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
return se;
}
void **StringTable::search(const dchar *s, unsigned len)
{
hash_t hash;
unsigned u;
int cmp;
StringEntry **se;
//printf("StringTable::search(%p,%d)\n",s,len);
hash = Dchar::calcHash(s,len);
u = hash % tabledim;
se = (StringEntry **)&table[u];
//printf("\thash = %d, u = %d\n",hash,u);
while (*se)
{
cmp = (*se)->hash - hash;
if (cmp == 0)
{
cmp = (*se)->value.lstring.len() - len;
if (cmp == 0)
{
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
if (cmp == 0)
break;
}
}
if (cmp < 0)
se = &(*se)->left;
else
se = &(*se)->right;
}
//printf("\treturn %p, %p\n",se, (*se));
return (void **)se;
}
StringValue *StringTable::lookup(const dchar *s, unsigned len)
{ StringEntry *se;
se = *(StringEntry **)search(s,len);
if (se)
return &se->value;
else
return NULL;
}
StringValue *StringTable::update(const dchar *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
pse = (StringEntry **)search(s,len);
se = *pse;
if (!se) // not in table: so create new entry
{
se = StringEntry::alloc(s, len);
*pse = se;
}
return &se->value;
}
StringValue *StringTable::insert(const dchar *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
pse = (StringEntry **)search(s,len);
se = *pse;
if (se)
return NULL; // error: already in table
else
{
se = StringEntry::alloc(s, len);
*pse = se;
}
return &se->value;
}
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "root.h"
#include "rmem.h"
#include "dchar.h"
#include "lstring.h"
#include "stringtable.h"
StringTable::StringTable(unsigned size)
{
table = (void **)mem.calloc(size, sizeof(void *));
tabledim = size;
count = 0;
}
StringTable::~StringTable()
{
unsigned i;
// Zero out dangling pointers to help garbage collector.
// Should zero out StringEntry's too.
for (i = 0; i < count; i++)
table[i] = NULL;
mem.free(table);
table = NULL;
}
struct StringEntry
{
StringEntry *left;
StringEntry *right;
hash_t hash;
StringValue value;
static StringEntry *alloc(const dchar *s, unsigned len);
};
StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
{
StringEntry *se;
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
se->value.lstring.length = len;
se->hash = Dchar::calcHash(s,len);
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
return se;
}
void **StringTable::search(const dchar *s, unsigned len)
{
hash_t hash;
unsigned u;
int cmp;
StringEntry **se;
//printf("StringTable::search(%p,%d)\n",s,len);
hash = Dchar::calcHash(s,len);
u = hash % tabledim;
se = (StringEntry **)&table[u];
//printf("\thash = %d, u = %d\n",hash,u);
while (*se)
{
cmp = (*se)->hash - hash;
if (cmp == 0)
{
cmp = (*se)->value.lstring.len() - len;
if (cmp == 0)
{
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
if (cmp == 0)
break;
}
}
if (cmp < 0)
se = &(*se)->left;
else
se = &(*se)->right;
}
//printf("\treturn %p, %p\n",se, (*se));
return (void **)se;
}
StringValue *StringTable::lookup(const dchar *s, unsigned len)
{ StringEntry *se;
se = *(StringEntry **)search(s,len);
if (se)
return &se->value;
else
return NULL;
}
StringValue *StringTable::update(const dchar *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
pse = (StringEntry **)search(s,len);
se = *pse;
if (!se) // not in table: so create new entry
{
se = StringEntry::alloc(s, len);
*pse = se;
}
return &se->value;
}
StringValue *StringTable::insert(const dchar *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
pse = (StringEntry **)search(s,len);
se = *pse;
if (se)
return NULL; // error: already in table
else
{
se = StringEntry::alloc(s, len);
*pse = se;
}
return &se->value;
}

View File

@@ -1,48 +1,48 @@
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef STRINGTABLE_H
#define STRINGTABLE_H
#if __SC__
#pragma once
#endif
#include "root.h"
#include "dchar.h"
#include "lstring.h"
struct StringValue
{
union
{ int intvalue;
void *ptrvalue;
dchar *string;
};
Lstring lstring;
};
struct StringTable : Object
{
void **table;
unsigned count;
unsigned tabledim;
StringTable(unsigned size = 37);
~StringTable();
StringValue *lookup(const dchar *s, unsigned len);
StringValue *insert(const dchar *s, unsigned len);
StringValue *update(const dchar *s, unsigned len);
private:
void **search(const dchar *s, unsigned len);
};
#endif
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef STRINGTABLE_H
#define STRINGTABLE_H
#if __SC__
#pragma once
#endif
#include "root.h"
#include "dchar.h"
#include "lstring.h"
struct StringValue
{
union
{ int intvalue;
void *ptrvalue;
dchar *string;
};
Lstring lstring;
};
struct StringTable : Object
{
void **table;
unsigned count;
unsigned tabledim;
StringTable(unsigned size = 37);
~StringTable();
StringValue *lookup(const dchar *s, unsigned len);
StringValue *insert(const dchar *s, unsigned len);
StringValue *update(const dchar *s, unsigned len);
private:
void **search(const dchar *s, unsigned len);
};
#endif

View File

@@ -1,363 +1,401 @@
// Copyright (c) 1999-2005 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "mars.h"
#include "init.h"
#include "identifier.h"
#include "attrib.h"
#include "dsymbol.h"
#include "scope.h"
#include "declaration.h"
#include "aggregate.h"
#include "module.h"
#include "id.h"
Scope *Scope::freelist = NULL;
void *Scope::operator new(size_t size)
{
if (freelist)
{
Scope *s = freelist;
freelist = s->enclosing;
//printf("freelist %p\n", s);
assert(s->flags & SCOPEfree);
s->flags &= ~SCOPEfree;
return s;
}
void *p = ::operator new(size);
//printf("new %p\n", p);
return p;
}
Scope::Scope()
{ // Create root scope
//printf("Scope::Scope() %p\n", this);
this->module = NULL;
this->scopesym = NULL;
this->sd = NULL;
this->enclosing = NULL;
this->parent = NULL;
this->sw = NULL;
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
this->tinst = NULL;
this->sbreak = NULL;
this->scontinue = NULL;
this->fes = NULL;
this->structalign = global.structalign;
this->func = NULL;
this->slabel = NULL;
this->linkage = LINKd;
this->protection = PROTpublic;
this->explicitProtection = 0;
this->stc = 0;
this->offset = 0;
this->inunion = 0;
this->incontract = 0;
this->nofree = 0;
this->noctor = 0;
this->noaccesscheck = 0;
this->mustsemantic = 0;
this->intypeof = 0;
this->parameterSpecialization = 0;
this->callSuper = 0;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = NULL;
}
Scope::Scope(Scope *enclosing)
{
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
assert(!(enclosing->flags & SCOPEfree));
this->module = enclosing->module;
this->func = enclosing->func;
this->parent = enclosing->parent;
this->scopesym = NULL;
this->sd = NULL;
this->sw = enclosing->sw;
this->enclosingFinally = enclosing->enclosingFinally;
this->enclosingScopeExit = enclosing->enclosingScopeExit;
this->tinst = enclosing->tinst;
this->sbreak = enclosing->sbreak;
this->scontinue = enclosing->scontinue;
this->fes = enclosing->fes;
this->structalign = enclosing->structalign;
this->enclosing = enclosing;
#ifdef DEBUG
if (enclosing->enclosing)
assert(!(enclosing->enclosing->flags & SCOPEfree));
if (this == enclosing->enclosing)
{
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
}
assert(this != enclosing->enclosing);
#endif
this->slabel = NULL;
this->linkage = enclosing->linkage;
this->protection = enclosing->protection;
this->explicitProtection = enclosing->explicitProtection;
this->stc = enclosing->stc;
this->offset = 0;
this->inunion = enclosing->inunion;
this->incontract = enclosing->incontract;
this->nofree = 0;
this->noctor = enclosing->noctor;
this->noaccesscheck = enclosing->noaccesscheck;
this->mustsemantic = enclosing->mustsemantic;
this->intypeof = enclosing->intypeof;
this->parameterSpecialization = enclosing->parameterSpecialization;
this->callSuper = enclosing->callSuper;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = enclosing->docbuf;
assert(this != enclosing);
}
Scope *Scope::createGlobal(Module *module)
{
Scope *sc;
sc = new Scope();
sc->module = module;
sc->scopesym = new ScopeDsymbol();
sc->scopesym->symtab = new DsymbolTable();
// Add top level package as member of this global scope
Dsymbol *m = module;
while (m->parent)
m = m->parent;
m->addMember(NULL, sc->scopesym, 1);
m->parent = NULL; // got changed by addMember()
// Create the module scope underneath the global scope
sc = sc->push(module);
sc->parent = module;
return sc;
}
Scope *Scope::push()
{
//printf("Scope::push()\n");
Scope *s = new Scope(this);
assert(this != s);
return s;
}
Scope *Scope::push(ScopeDsymbol *ss)
{
//printf("Scope::push(%s)\n", ss->toChars());
Scope *s = push();
s->scopesym = ss;
return s;
}
Scope *Scope::pop()
{
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
Scope *enc = enclosing;
if (enclosing)
enclosing->callSuper |= callSuper;
if (!nofree)
{ enclosing = freelist;
freelist = this;
flags |= SCOPEfree;
}
return enc;
}
void Scope::mergeCallSuper(Loc loc, unsigned cs)
{
// This does a primitive flow analysis to support the restrictions
// regarding when and how constructors can appear.
// It merges the results of two paths.
// The two paths are callSuper and cs; the result is merged into callSuper.
if (cs != callSuper)
{ int a;
int b;
callSuper |= cs & (CSXany_ctor | CSXlabel);
if (cs & CSXreturn)
{
}
else if (callSuper & CSXreturn)
{
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
}
else
{
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
if (a != b)
error(loc, "one path skips constructor");
callSuper |= cs;
}
}
}
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
{ Dsymbol *s;
Scope *sc;
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
if (ident == Id::empty)
{
// Look for module scope
for (sc = this; sc; sc = sc->enclosing)
{
assert(sc != sc->enclosing);
if (sc->scopesym)
{
s = sc->scopesym->isModule();
if (s)
{
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
if (pscopesym)
*pscopesym = sc->scopesym;
return s;
}
}
}
return NULL;
}
for (sc = this; sc; sc = sc->enclosing)
{
assert(sc != sc->enclosing);
if (sc->scopesym)
{
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
s = sc->scopesym->search(loc, ident, 0);
if (s)
{
if ((global.params.warnings ||
global.params.Dversion > 1) &&
ident == Id::length &&
sc->scopesym->isArrayScopeSymbol() &&
sc->enclosing &&
sc->enclosing->search(loc, ident, NULL))
{
warning(s->loc, "array 'length' hides other 'length' name in outer scope");
}
//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
if (pscopesym)
*pscopesym = sc->scopesym;
return s;
}
}
}
return NULL;
}
Dsymbol *Scope::insert(Dsymbol *s)
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
//printf("\tsc = %p\n", sc);
if (sc->scopesym)
{
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
if (!sc->scopesym->symtab)
sc->scopesym->symtab = new DsymbolTable();
return sc->scopesym->symtab->insert(s);
}
}
assert(0);
return NULL;
}
/********************************************
* Search enclosing scopes for ClassDeclaration.
*/
ClassDeclaration *Scope::getClassScope()
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
ClassDeclaration *cd;
if (sc->scopesym)
{
cd = sc->scopesym->isClassDeclaration();
if (cd)
return cd;
}
}
return NULL;
}
/********************************************
* Search enclosing scopes for ClassDeclaration.
*/
AggregateDeclaration *Scope::getStructClassScope()
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
AggregateDeclaration *ad;
if (sc->scopesym)
{
ad = sc->scopesym->isClassDeclaration();
if (ad)
return ad;
else
{ ad = sc->scopesym->isStructDeclaration();
if (ad)
return ad;
}
}
}
return NULL;
}
/*******************************************
* For TemplateDeclarations, we need to remember the Scope
* where it was declared. So mark the Scope as not
* to be free'd.
*/
void Scope::setNoFree()
{ Scope *sc;
//int i = 0;
//printf("Scope::setNoFree(this = %p)\n", this);
for (sc = this; sc; sc = sc->enclosing)
{
//printf("\tsc = %p\n", sc);
sc->nofree = 1;
assert(!(flags & SCOPEfree));
//assert(sc != sc->enclosing);
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
//if (++i == 10)
//assert(0);
}
}
// Copyright (c) 1999-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include "root.h"
#include "speller.h"
#include "mars.h"
#include "init.h"
#include "identifier.h"
#include "attrib.h"
#include "dsymbol.h"
#include "scope.h"
#include "declaration.h"
#include "aggregate.h"
#include "module.h"
#include "id.h"
#include "lexer.h"
Scope *Scope::freelist = NULL;
void *Scope::operator new(size_t size)
{
if (freelist)
{
Scope *s = freelist;
freelist = s->enclosing;
//printf("freelist %p\n", s);
assert(s->flags & SCOPEfree);
s->flags &= ~SCOPEfree;
return s;
}
void *p = ::operator new(size);
//printf("new %p\n", p);
return p;
}
Scope::Scope()
{ // Create root scope
//printf("Scope::Scope() %p\n", this);
this->module = NULL;
this->scopesym = NULL;
this->sd = NULL;
this->enclosing = NULL;
this->parent = NULL;
this->sw = NULL;
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
this->tinst = NULL;
this->sbreak = NULL;
this->scontinue = NULL;
this->fes = NULL;
this->structalign = global.structalign;
this->func = NULL;
this->slabel = NULL;
this->linkage = LINKd;
this->protection = PROTpublic;
this->explicitProtection = 0;
this->stc = 0;
this->offset = 0;
this->inunion = 0;
this->incontract = 0;
this->nofree = 0;
this->noctor = 0;
this->noaccesscheck = 0;
this->mustsemantic = 0;
this->intypeof = 0;
this->parameterSpecialization = 0;
this->callSuper = 0;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = NULL;
}
Scope::Scope(Scope *enclosing)
{
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
assert(!(enclosing->flags & SCOPEfree));
this->module = enclosing->module;
this->func = enclosing->func;
this->parent = enclosing->parent;
this->scopesym = NULL;
this->sd = NULL;
this->sw = enclosing->sw;
this->enclosingFinally = enclosing->enclosingFinally;
this->enclosingScopeExit = enclosing->enclosingScopeExit;
this->tinst = enclosing->tinst;
this->sbreak = enclosing->sbreak;
this->scontinue = enclosing->scontinue;
this->fes = enclosing->fes;
this->structalign = enclosing->structalign;
this->enclosing = enclosing;
#ifdef DEBUG
if (enclosing->enclosing)
assert(!(enclosing->enclosing->flags & SCOPEfree));
if (this == enclosing->enclosing)
{
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
}
assert(this != enclosing->enclosing);
#endif
this->slabel = NULL;
this->linkage = enclosing->linkage;
this->protection = enclosing->protection;
this->explicitProtection = enclosing->explicitProtection;
this->stc = enclosing->stc;
this->offset = 0;
this->inunion = enclosing->inunion;
this->incontract = enclosing->incontract;
this->nofree = 0;
this->noctor = enclosing->noctor;
this->noaccesscheck = enclosing->noaccesscheck;
this->mustsemantic = enclosing->mustsemantic;
this->intypeof = enclosing->intypeof;
this->parameterSpecialization = enclosing->parameterSpecialization;
this->callSuper = enclosing->callSuper;
this->flags = 0;
this->anonAgg = NULL;
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = enclosing->docbuf;
assert(this != enclosing);
}
Scope *Scope::createGlobal(Module *module)
{
Scope *sc;
sc = new Scope();
sc->module = module;
sc->scopesym = new ScopeDsymbol();
sc->scopesym->symtab = new DsymbolTable();
// Add top level package as member of this global scope
Dsymbol *m = module;
while (m->parent)
m = m->parent;
m->addMember(NULL, sc->scopesym, 1);
m->parent = NULL; // got changed by addMember()
// Create the module scope underneath the global scope
sc = sc->push(module);
sc->parent = module;
return sc;
}
Scope *Scope::push()
{
//printf("Scope::push()\n");
Scope *s = new Scope(this);
assert(this != s);
return s;
}
Scope *Scope::push(ScopeDsymbol *ss)
{
//printf("Scope::push(%s)\n", ss->toChars());
Scope *s = push();
s->scopesym = ss;
return s;
}
Scope *Scope::pop()
{
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
Scope *enc = enclosing;
if (enclosing)
enclosing->callSuper |= callSuper;
if (!nofree)
{ enclosing = freelist;
freelist = this;
flags |= SCOPEfree;
}
return enc;
}
void Scope::mergeCallSuper(Loc loc, unsigned cs)
{
// This does a primitive flow analysis to support the restrictions
// regarding when and how constructors can appear.
// It merges the results of two paths.
// The two paths are callSuper and cs; the result is merged into callSuper.
if (cs != callSuper)
{ int a;
int b;
callSuper |= cs & (CSXany_ctor | CSXlabel);
if (cs & CSXreturn)
{
}
else if (callSuper & CSXreturn)
{
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
}
else
{
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
if (a != b)
error(loc, "one path skips constructor");
callSuper |= cs;
}
}
}
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
{ Dsymbol *s;
Scope *sc;
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
if (ident == Id::empty)
{
// Look for module scope
for (sc = this; sc; sc = sc->enclosing)
{
assert(sc != sc->enclosing);
if (sc->scopesym)
{
s = sc->scopesym->isModule();
if (s)
{
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
if (pscopesym)
*pscopesym = sc->scopesym;
return s;
}
}
}
return NULL;
}
for (sc = this; sc; sc = sc->enclosing)
{
assert(sc != sc->enclosing);
if (sc->scopesym)
{
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
s = sc->scopesym->search(loc, ident, 0);
if (s)
{
if ((global.params.warnings ||
global.params.Dversion > 1) &&
ident == Id::length &&
sc->scopesym->isArrayScopeSymbol() &&
sc->enclosing &&
sc->enclosing->search(loc, ident, NULL))
{
warning(s->loc, "array 'length' hides other 'length' name in outer scope");
}
//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
if (pscopesym)
*pscopesym = sc->scopesym;
return s;
}
}
}
return NULL;
}
Dsymbol *Scope::insert(Dsymbol *s)
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
//printf("\tsc = %p\n", sc);
if (sc->scopesym)
{
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
if (!sc->scopesym->symtab)
sc->scopesym->symtab = new DsymbolTable();
return sc->scopesym->symtabInsert(s);
}
}
assert(0);
return NULL;
}
/********************************************
* Search enclosing scopes for ClassDeclaration.
*/
ClassDeclaration *Scope::getClassScope()
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
ClassDeclaration *cd;
if (sc->scopesym)
{
cd = sc->scopesym->isClassDeclaration();
if (cd)
return cd;
}
}
return NULL;
}
/********************************************
* Search enclosing scopes for ClassDeclaration.
*/
AggregateDeclaration *Scope::getStructClassScope()
{ Scope *sc;
for (sc = this; sc; sc = sc->enclosing)
{
AggregateDeclaration *ad;
if (sc->scopesym)
{
ad = sc->scopesym->isClassDeclaration();
if (ad)
return ad;
else
{ ad = sc->scopesym->isStructDeclaration();
if (ad)
return ad;
}
}
}
return NULL;
}
/*******************************************
* For TemplateDeclarations, we need to remember the Scope
* where it was declared. So mark the Scope as not
* to be free'd.
*/
void Scope::setNoFree()
{ Scope *sc;
//int i = 0;
//printf("Scope::setNoFree(this = %p)\n", this);
for (sc = this; sc; sc = sc->enclosing)
{
//printf("\tsc = %p\n", sc);
sc->nofree = 1;
assert(!(flags & SCOPEfree));
//assert(sc != sc->enclosing);
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
//if (++i == 10)
//assert(0);
}
}
/************************************************
* Given the failed search attempt, try to find
* one with a close spelling.
*/
void *scope_search_fp(void *arg, const char *seed)
{
//printf("scope_search_fp('%s')\n", seed);
/* If not in the lexer's string table, it certainly isn't in the symbol table.
* Doing this first is a lot faster.
*/
size_t len = strlen(seed);
if (!len)
return NULL;
StringValue *sv = Lexer::stringtable.lookup(seed, len);
if (!sv)
return NULL;
Identifier *id = (Identifier *)sv->ptrvalue;
assert(id);
Scope *sc = (Scope *)arg;
Module::clearCache();
Dsymbol *s = sc->search(0, id, NULL);
return s;
}
Dsymbol *Scope::search_correct(Identifier *ident)
{
if (global.gag)
return NULL; // don't do it for speculative compiles; too time consuming
return (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars);
}

View File

@@ -1,126 +1,127 @@
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_SCOPE_H
#define DMD_SCOPE_H
#ifdef __DMC__
#pragma once
#endif
struct Dsymbol;
struct ScopeDsymbol;
struct Array;
struct Identifier;
struct Module;
struct Statement;
struct SwitchStatement;
struct TryFinallyStatement;
struct LabelStatement;
struct ForeachStatement;
struct ClassDeclaration;
struct AggregateDeclaration;
struct AnonymousAggregateDeclaration;
struct FuncDeclaration;
struct DocComment;
struct TemplateInstance;
#if IN_LLVM
struct EnclosingHandler;
struct AnonDeclaration;
#endif
#if __GNUC__
// Requires a full definition for PROT and LINK
#include "dsymbol.h" // PROT
#include "mars.h" // LINK
#else
enum LINK;
enum PROT;
#endif
struct Scope
{
Scope *enclosing; // enclosing Scope
Module *module; // Root module
ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember()
FuncDeclaration *func; // function we are in
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
TemplateInstance *tinst; // enclosing template instance
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
unsigned offset; // next offset to use in aggregate
int inunion; // we're processing members of a union
int incontract; // we're inside contract code
int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp)
int parameterSpecialization; // if in template parameter specialization
int noaccesscheck; // don't do access checks
int mustsemantic; // cannot defer semantic()
unsigned callSuper; // primitive flow analysis for constructors
#define CSXthis_ctor 1 // called this()
#define CSXsuper_ctor 2 // called super()
#define CSXthis 4 // referenced this
#define CSXsuper 8 // referenced super
#define CSXlabel 0x10 // seen a label
#define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
unsigned stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type
#define SCOPEstaticif 2 // inside static if
#define SCOPEfree 4 // is on free list
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
DocComment *lastdc; // documentation comment for last symbol at this scope
unsigned lastoffset; // offset in docbuf of where to insert next dec
OutBuffer *docbuf; // buffer for documentation output
static Scope *freelist;
static void *operator new(size_t sz);
static Scope *createGlobal(Module *module);
Scope();
Scope(Module *module);
Scope(Scope *enclosing);
Scope *push();
Scope *push(ScopeDsymbol *ss);
Scope *pop();
void mergeCallSuper(Loc loc, unsigned cs);
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *insert(Dsymbol *s);
ClassDeclaration *getClassScope();
AggregateDeclaration *getStructClassScope();
void setNoFree();
};
#endif /* DMD_SCOPE_H */
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_SCOPE_H
#define DMD_SCOPE_H
#ifdef __DMC__
#pragma once
#endif
struct Dsymbol;
struct ScopeDsymbol;
struct Array;
struct Identifier;
struct Module;
struct Statement;
struct SwitchStatement;
struct TryFinallyStatement;
struct LabelStatement;
struct ForeachStatement;
struct ClassDeclaration;
struct AggregateDeclaration;
struct AnonymousAggregateDeclaration;
struct FuncDeclaration;
struct DocComment;
struct TemplateInstance;
#if IN_LLVM
struct EnclosingHandler;
struct AnonDeclaration;
#endif
#if __GNUC__
// Requires a full definition for PROT and LINK
#include "dsymbol.h" // PROT
#include "mars.h" // LINK
#else
enum LINK;
enum PROT;
#endif
struct Scope
{
Scope *enclosing; // enclosing Scope
Module *module; // Root module
ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember()
FuncDeclaration *func; // function we are in
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
TemplateInstance *tinst; // enclosing template instance
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
unsigned offset; // next offset to use in aggregate
int inunion; // we're processing members of a union
int incontract; // we're inside contract code
int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp)
int parameterSpecialization; // if in template parameter specialization
int noaccesscheck; // don't do access checks
int mustsemantic; // cannot defer semantic()
unsigned callSuper; // primitive flow analysis for constructors
#define CSXthis_ctor 1 // called this()
#define CSXsuper_ctor 2 // called super()
#define CSXthis 4 // referenced this
#define CSXsuper 8 // referenced super
#define CSXlabel 0x10 // seen a label
#define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
StorageClass stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type
#define SCOPEstaticif 2 // inside static if
#define SCOPEfree 4 // is on free list
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
DocComment *lastdc; // documentation comment for last symbol at this scope
unsigned lastoffset; // offset in docbuf of where to insert next dec
OutBuffer *docbuf; // buffer for documentation output
static Scope *freelist;
static void *operator new(size_t sz);
static Scope *createGlobal(Module *module);
Scope();
Scope(Module *module);
Scope(Scope *enclosing);
Scope *push();
Scope *push(ScopeDsymbol *ss);
Scope *pop();
void mergeCallSuper(Loc loc, unsigned cs);
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *search_correct(Identifier *ident);
Dsymbol *insert(Dsymbol *s);
ClassDeclaration *getClassScope();
AggregateDeclaration *getStructClassScope();
void setNoFree();
};
#endif /* DMD_SCOPE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,120 +1,116 @@
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "dsymbol.h"
#include "staticassert.h"
#include "expression.h"
#include "id.h"
#include "hdrgen.h"
#include "scope.h"
#include "template.h"
/********************************* AttribDeclaration ****************************/
StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg)
: Dsymbol(Id::empty)
{
this->loc = loc;
this->exp = exp;
this->msg = msg;
}
Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s)
{
StaticAssert *sa;
assert(!s);
sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
return sa;
}
int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
return 0; // we didn't add anything
}
void StaticAssert::semantic(Scope *sc)
{
}
#include "scope.h"
#include "template.h"
#include "declaration.h"
void StaticAssert::semantic2(Scope *sc)
{
Expression *e;
//printf("StaticAssert::semantic2() %s\n", toChars());
e = exp->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(FALSE))
{
if (msg)
{ HdrGenState hgs;
OutBuffer buf;
msg = msg->semantic(sc);
msg = msg->optimize(WANTvalue | WANTinterpret);
hgs.console = 1;
msg->toCBuffer(&buf, &hgs);
error("%s", buf.toChars());
}
else
error("(%s) is false", exp->toChars());
if(sc->tinst)
sc->tinst->printInstantiationTrace();
if (!global.gag) {
fatal();
}
}
else if (!e->isBool(TRUE))
{
error("(%s) is not evaluatable at compile time", exp->toChars());
}
}
int StaticAssert::oneMember(Dsymbol **ps)
{
//printf("StaticAssert::oneMember())\n");
*ps = NULL;
return TRUE;
}
void StaticAssert::inlineScan()
{
}
void StaticAssert::toObjFile(int multiobj)
{
}
const char *StaticAssert::kind()
{
return "static assert";
}
void StaticAssert::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(kind());
buf->writeByte('(');
exp->toCBuffer(buf, hgs);
if (msg)
{
buf->writeByte(',');
msg->toCBuffer(buf, hgs);
}
buf->writestring(");");
buf->writenl();
}
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "dsymbol.h"
#include "staticassert.h"
#include "expression.h"
#include "id.h"
#include "hdrgen.h"
#include "scope.h"
#include "template.h"
#include "declaration.h"
/********************************* AttribDeclaration ****************************/
StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg)
: Dsymbol(Id::empty)
{
this->loc = loc;
this->exp = exp;
this->msg = msg;
}
Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s)
{
StaticAssert *sa;
assert(!s);
sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
return sa;
}
int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
return 0; // we didn't add anything
}
void StaticAssert::semantic(Scope *sc)
{
}
void StaticAssert::semantic2(Scope *sc)
{
Expression *e;
//printf("StaticAssert::semantic2() %s\n", toChars());
e = exp->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(FALSE))
{
if (msg)
{ HdrGenState hgs;
OutBuffer buf;
msg = msg->semantic(sc);
msg = msg->optimize(WANTvalue | WANTinterpret);
hgs.console = 1;
msg->toCBuffer(&buf, &hgs);
error("%s", buf.toChars());
}
else
error("(%s) is false", exp->toChars());
if (sc->tinst)
sc->tinst->printInstantiationTrace();
if (!global.gag)
fatal();
}
else if (!e->isBool(TRUE))
{
error("(%s) is not evaluatable at compile time", exp->toChars());
}
}
int StaticAssert::oneMember(Dsymbol **ps)
{
//printf("StaticAssert::oneMember())\n");
*ps = NULL;
return TRUE;
}
void StaticAssert::inlineScan()
{
}
void StaticAssert::toObjFile(int multiobj)
{
}
const char *StaticAssert::kind()
{
return "static assert";
}
void StaticAssert::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(kind());
buf->writeByte('(');
exp->toCBuffer(buf, hgs);
if (msg)
{
buf->writeByte(',');
msg->toCBuffer(buf, hgs);
}
buf->writestring(");");
buf->writenl();
}

View File

@@ -1,43 +1,43 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_STATICASSERT_H
#define DMD_STATICASSERT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Expression;
#ifdef _DH
struct HdrGenState;
#endif
struct StaticAssert : Dsymbol
{
Expression *exp;
Expression *msg;
StaticAssert(Loc loc, Expression *exp, Expression *msg);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
void semantic(Scope *sc);
void semantic2(Scope *sc);
void inlineScan();
int oneMember(Dsymbol **ps);
void toObjFile(int multiobj);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
#endif
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DMD_STATICASSERT_H
#define DMD_STATICASSERT_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "dsymbol.h"
struct Expression;
#ifdef _DH
struct HdrGenState;
#endif
struct StaticAssert : Dsymbol
{
Expression *exp;
Expression *msg;
StaticAssert(Loc loc, Expression *exp, Expression *msg);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
void semantic(Scope *sc);
void semantic2(Scope *sc);
void inlineScan();
int oneMember(Dsymbol **ps);
void toObjFile(int multiobj);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More