First import of dmd-2.065-b1 (7088593).

The CPP mangling is not integrated yet.
This commit is contained in:
Kai Nacke
2013-12-06 16:59:41 +01:00
parent 2fa997e6ad
commit 1de68a45b8
78 changed files with 3480 additions and 4561 deletions
-28
View File
@@ -57,7 +57,6 @@ public:
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // !=0 if deprecated bool isdeprecated; // !=0 if deprecated
#if DMDV2
Dsymbol *enclosing; /* !=NULL if is nested Dsymbol *enclosing; /* !=NULL if is nested
* pointing to the dsymbol that directly enclosing it. * pointing to the dsymbol that directly enclosing it.
* 1. The function that enclosing it (nested struct and class) * 1. The function that enclosing it (nested struct and class)
@@ -66,20 +65,17 @@ public:
* See AggregateDeclaraton::makeNested for the details. * See AggregateDeclaraton::makeNested for the details.
*/ */
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
#endif
// Special member functions // Special member functions
FuncDeclarations invs; // Array of invariants FuncDeclarations invs; // Array of invariants
FuncDeclaration *inv; // invariant FuncDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator NewDeclaration *aggNew; // allocator
DeleteDeclaration *aggDelete; // deallocator DeleteDeclaration *aggDelete; // deallocator
#if DMDV2
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
CtorDeclaration *defaultCtor; // default constructor - should have no arguments, because CtorDeclaration *defaultCtor; // default constructor - should have no arguments, because
// it would be stored in TypeInfo_Class.defaultConstructor // it would be stored in TypeInfo_Class.defaultConstructor
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
bool noDefaultCtor; // no default construction bool noDefaultCtor; // no default construction
#endif
FuncDeclarations dtors; // Array of destructors FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor FuncDeclaration *dtor; // aggregate destructor
@@ -152,7 +148,6 @@ class StructDeclaration : public AggregateDeclaration
{ {
public: public:
int zeroInit; // !=0 if initialize with 0 fill int zeroInit; // !=0 if initialize with 0 fill
#if DMDV2
int hasIdentityAssign; // !=0 if has identity opAssign int hasIdentityAssign; // !=0 if has identity opAssign
int hasIdentityEquals; // !=0 if has identity opEquals int hasIdentityEquals; // !=0 if has identity opEquals
FuncDeclaration *cpctor; // generated copy-constructor, if any FuncDeclaration *cpctor; // generated copy-constructor, if any
@@ -165,7 +160,6 @@ public:
static FuncDeclaration *xerrcmp; // object.xopCmp static FuncDeclaration *xerrcmp; // object.xopCmp
structalign_t alignment; // alignment applied outside of the struct structalign_t alignment; // alignment applied outside of the struct
#endif
// For 64 bit Efl function call/return ABI // For 64 bit Efl function call/return ABI
Type *arg1type; Type *arg1type;
@@ -180,10 +174,6 @@ public:
const char *kind(); const char *kind();
void finalizeSize(Scope *sc); void finalizeSize(Scope *sc);
bool isPOD(); bool isPOD();
#if DMDV1
Expression *cloneMembers();
#endif
#if DMDV2
int needOpAssign(); int needOpAssign();
int needOpEquals(); int needOpEquals();
FuncDeclaration *buildOpAssign(Scope *sc); FuncDeclaration *buildOpAssign(Scope *sc);
@@ -192,7 +182,6 @@ public:
FuncDeclaration *buildOpEquals(Scope *sc); FuncDeclaration *buildOpEquals(Scope *sc);
FuncDeclaration *buildXopEquals(Scope *sc); FuncDeclaration *buildXopEquals(Scope *sc);
FuncDeclaration *buildXopCmp(Scope *sc); FuncDeclaration *buildXopCmp(Scope *sc);
#endif
void toDocBuffer(OutBuffer *buf, Scope *sc); void toDocBuffer(OutBuffer *buf, Scope *sc);
PROT getAccess(Dsymbol *smember); // determine access to smember PROT getAccess(Dsymbol *smember); // determine access to smember
@@ -241,13 +230,8 @@ struct BaseClass
void copyBaseInterfaces(BaseClasses *); void copyBaseInterfaces(BaseClasses *);
}; };
#if DMDV2
#define CLASSINFO_SIZE_64 0x98 // value of ClassInfo.size #define CLASSINFO_SIZE_64 0x98 // value of ClassInfo.size
#define CLASSINFO_SIZE (0x3C+12+4) // 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
#define CLASSINFO_SIZE_64 (0x98) // value of ClassInfo.size
#endif
struct ClassFlags struct ClassFlags
{ {
@@ -274,10 +258,6 @@ public:
static ClassDeclaration *errorException; static ClassDeclaration *errorException;
ClassDeclaration *baseClass; // NULL only if this is Object ClassDeclaration *baseClass; // NULL only if this is Object
#if DMDV1
CtorDeclaration *ctor;
CtorDeclaration *defaultCtor; // default constructor
#endif
FuncDeclaration *staticCtor; FuncDeclaration *staticCtor;
FuncDeclaration *staticDtor; FuncDeclaration *staticDtor;
Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[] Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[]
@@ -296,9 +276,7 @@ public:
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
int com; // !=0 if this is a COM class (meaning int com; // !=0 if this is a COM class (meaning
// it derives from IUnknown) // it derives from IUnknown)
#if DMDV2
int cpp; // !=0 if this is a C++ interface int cpp; // !=0 if this is a C++ interface
#endif
int isscope; // !=0 if this is an auto class int isscope; // !=0 if this is an auto class
int isabstract; // !=0 if abstract class int isabstract; // !=0 if abstract class
int inuse; // to prevent recursive attempts int inuse; // to prevent recursive attempts
@@ -318,17 +296,13 @@ public:
virtual int isBaseInfoComplete(); virtual int isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags); Dsymbol *search(Loc, Identifier *ident, int flags);
ClassDeclaration *searchBase(Loc, Identifier *ident); ClassDeclaration *searchBase(Loc, Identifier *ident);
#if DMDV2
int isFuncHidden(FuncDeclaration *fd); int isFuncHidden(FuncDeclaration *fd);
#endif
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc); void interfaceSemantic(Scope *sc);
int isCOMclass(); int isCOMclass();
virtual int isCOMinterface(); virtual int isCOMinterface();
#if DMDV2
int isCPPclass(); int isCPPclass();
virtual int isCPPinterface(); virtual int isCPPinterface();
#endif
bool isAbstract(); bool isAbstract();
virtual int vtblOffset(); virtual int vtblOffset();
const char *kind(); const char *kind();
@@ -370,9 +344,7 @@ public:
const char *kind(); const char *kind();
int isBaseInfoComplete(); int isBaseInfoComplete();
int vtblOffset(); int vtblOffset();
#if DMDV2
int isCPPinterface(); int isCPPinterface();
#endif
virtual int isCOMinterface(); virtual int isCOMinterface();
#if IN_DMD #if IN_DMD
+33 -38
View File
@@ -20,40 +20,30 @@
#include "mtype.h" #include "mtype.h"
#include "declaration.h" #include "declaration.h"
#if DMDV2
Expression *resolveAliasThis(Scope *sc, Expression *e) Expression *resolveAliasThis(Scope *sc, Expression *e)
{ {
Type *t = e->type->toBasetype(); Type *t = e->type->toBasetype();
AggregateDeclaration *ad; AggregateDeclaration *ad = isAggregate(t);
if (t->ty == Tclass) if (ad && ad->aliasthis)
{ ad = ((TypeClass *)t)->sym; {
goto L1; bool isstatic = (e->op == TOKtype);
} e = new DotIdExp(e->loc, e, ad->aliasthis->ident);
else if (t->ty == Tstruct) e = e->semantic(sc);
{ ad = ((TypeStruct *)t)->sym; if (isstatic && ad->aliasthis->needThis())
L1:
if (ad && ad->aliasthis)
{ {
bool isstatic = (e->op == TOKtype); /* non-@property function is not called inside typeof(),
e = new DotIdExp(e->loc, e, ad->aliasthis->ident); * so resolve it ahead.
e = e->semantic(sc); */
if (isstatic && ad->aliasthis->needThis()) int save = sc->intypeof;
{ sc->intypeof = 1; // bypass "need this" error check
/* non-@property function is not called inside typeof(),
* so resolve it ahead.
*/
int save = sc->intypeof;
sc->intypeof = 1; // bypass "need this" error check
e = resolveProperties(sc, e);
sc->intypeof = save;
e = new TypeExp(e->loc, new TypeTypeof(e->loc, e));
e = e->semantic(sc);
}
e = resolveProperties(sc, e); e = resolveProperties(sc, e);
sc->intypeof = save;
e = new TypeExp(e->loc, new TypeTypeof(e->loc, e));
e = e->semantic(sc);
} }
e = resolveProperties(sc, e);
} }
return e; return e;
@@ -88,7 +78,8 @@ void AliasThis::semantic(Scope *sc)
assert(ad->members); assert(ad->members);
Dsymbol *s = ad->search(loc, ident, 0); Dsymbol *s = ad->search(loc, ident, 0);
if (!s) if (!s)
{ s = sc->search(loc, ident, NULL); {
s = sc->search(loc, ident, NULL);
if (s) if (s)
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars()); ::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
else else
@@ -98,17 +89,24 @@ void AliasThis::semantic(Scope *sc)
else if (ad->aliasthis && s != ad->aliasthis) else if (ad->aliasthis && s != ad->aliasthis)
error("there can be only one alias this"); error("there can be only one alias this");
if (ad->type->ty == Tstruct && ((TypeStruct *)ad->type)->sym != ad)
{
AggregateDeclaration *ad2 = ((TypeStruct *)ad->type)->sym;
assert(ad2->type == Type::terror);
ad->aliasthis = ad2->aliasthis;
return;
}
/* disable the alias this conversion so the implicit conversion check /* disable the alias this conversion so the implicit conversion check
* doesn't use it. * doesn't use it.
*/ */
/* This should use ad->aliasthis directly, but with static foreach and templates ad->aliasthis = NULL;
* ad->type->sym might be different to ad.
*/
AggregateDeclaration *ad2 = ad->type->toDsymbol(NULL)->isAggregateDeclaration();
Dsymbol *save = ad2->aliasthis;
ad2->aliasthis = NULL;
if (Declaration *d = s->isDeclaration()) Dsymbol *sx = s;
if (sx->isAliasDeclaration())
sx = sx->toAlias();
Declaration *d = sx->isDeclaration();
if (d && !d->isTupleDeclaration())
{ {
Type *t = d->type; Type *t = d->type;
assert(t); assert(t);
@@ -118,7 +116,6 @@ void AliasThis::semantic(Scope *sc)
} }
} }
ad2->aliasthis = save;
ad->aliasthis = s; ad->aliasthis = s;
} }
else else
@@ -136,5 +133,3 @@ void AliasThis::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(ident->toChars()); buf->writestring(ident->toChars());
buf->writestring(" this;\n"); buf->writestring(" this;\n");
} }
#endif
-4
View File
@@ -20,8 +20,6 @@
/**************************************************************/ /**************************************************************/
#if DMDV2
class AliasThis : public Dsymbol class AliasThis : public Dsymbol
{ {
public: public:
@@ -38,5 +36,3 @@ public:
}; };
#endif #endif
#endif
+6 -12
View File
@@ -99,7 +99,7 @@ TypeTuple *TypeBasic::toArgTypes()
t2 = Type::tfloat80; t2 = Type::tfloat80;
break; break;
case Tascii: case Tchar:
t1 = Type::tuns8; t1 = Type::tuns8;
break; break;
@@ -127,16 +127,13 @@ TypeTuple *TypeBasic::toArgTypes()
return t; return t;
} }
#if DMDV2
TypeTuple *TypeVector::toArgTypes() TypeTuple *TypeVector::toArgTypes()
{ {
return new TypeTuple(this); return new TypeTuple(this);
} }
#endif
TypeTuple *TypeSArray::toArgTypes() TypeTuple *TypeSArray::toArgTypes()
{ {
#if DMDV2
if (dim) if (dim)
{ {
/* Should really be done as if it were a struct with dim members /* Should really be done as if it were a struct with dim members
@@ -149,9 +146,6 @@ TypeTuple *TypeSArray::toArgTypes()
return next->toArgTypes(); return next->toArgTypes();
} }
return new TypeTuple(); // pass on the stack for efficiency return new TypeTuple(); // pass on the stack for efficiency
#else
return new TypeTuple(); // pass on the stack for efficiency
#endif
} }
TypeTuple *TypeAArray::toArgTypes() TypeTuple *TypeAArray::toArgTypes()
@@ -204,8 +198,8 @@ Type *argtypemerge(Type *t1, Type *t2, unsigned offset2)
if (!t2) if (!t2)
return t1; return t1;
unsigned sz1 = t1->size(Loc()); unsigned sz1 = (unsigned)t1->size(Loc());
unsigned sz2 = t2->size(Loc()); unsigned sz2 = (unsigned)t2->size(Loc());
if (t1->ty != t2->ty && if (t1->ty != t2->ty &&
(t1->ty == Tfloat80 || t2->ty == Tfloat80)) (t1->ty == Tfloat80 || t2->ty == Tfloat80))
@@ -265,7 +259,7 @@ TypeTuple *TypeDArray::toArgTypes()
if (global.params.is64bit && !global.params.isLP64) if (global.params.is64bit && !global.params.isLP64)
{ {
// For AMD64 ILP32 ABI, D arrays fit into a single integer register. // For AMD64 ILP32 ABI, D arrays fit into a single integer register.
unsigned offset = Type::tsize_t->size(Loc()); unsigned offset = (unsigned)Type::tsize_t->size(Loc());
Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset);
if (t) if (t)
return new TypeTuple(t); return new TypeTuple(t);
@@ -281,7 +275,7 @@ TypeTuple *TypeDelegate::toArgTypes()
if (global.params.is64bit && !global.params.isLP64) if (global.params.is64bit && !global.params.isLP64)
{ {
// For AMD64 ILP32 ABI, delegates fit into a single integer register. // For AMD64 ILP32 ABI, delegates fit into a single integer register.
unsigned offset = Type::tsize_t->size(Loc()); unsigned offset = (unsigned)Type::tsize_t->size(Loc());
Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset); Type *t = argtypemerge(Type::tsize_t, Type::tvoidptr, offset);
if (t) if (t)
return new TypeTuple(t); return new TypeTuple(t);
@@ -360,7 +354,7 @@ TypeTuple *TypeStruct::toArgTypes()
goto Lmemory; goto Lmemory;
// Fields that overlap the 8byte boundary goto Lmemory // Fields that overlap the 8byte boundary goto Lmemory
unsigned fieldsz = f->type->size(Loc()); d_uns64 fieldsz = f->type->size(Loc());
if (f->offset < 8 && (f->offset + fieldsz) > 8) if (f->offset < 8 && (f->offset + fieldsz) > 8)
goto Lmemory; goto Lmemory;
} }
+36 -34
View File
@@ -272,23 +272,12 @@ ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc)
* return p; * return p;
*/ */
Parameter *p = (*fparams)[0 /*fparams->dim - 1*/]; Parameter *p = (*fparams)[0 /*fparams->dim - 1*/];
#if DMDV1
// for (size_t i = 0; i < p.length; i++)
Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
Statement *s1 = new ForStatement(0,
new ExpStatement(0, d),
new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
new ExpStatement(0, loopbody));
#else
// foreach (i; 0 .. p.length) // foreach (i; 0 .. p.length)
Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach, Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach,
new Parameter(0, NULL, Id::p, NULL), new Parameter(0, NULL, Id::p, NULL),
new IntegerExp(Loc(), 0, Type::tsize_t), new IntegerExp(Loc(), 0, Type::tsize_t),
new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)), new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)),
new ExpStatement(Loc(), loopbody)); new ExpStatement(Loc(), loopbody));
#endif
//printf("%s\n", s1->toChars()); //printf("%s\n", s1->toChars());
Statement *s2 = new ReturnStatement(Loc(), new IdentifierExp(Loc(), p->ident)); Statement *s2 = new ReturnStatement(Loc(), new IdentifierExp(Loc(), p->ident));
//printf("s2: %s\n", s2->toChars()); //printf("s2: %s\n", s2->toChars());
@@ -316,7 +305,14 @@ ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc)
sc->linkage = LINKc; sc->linkage = LINKc;
fd->semantic(sc); fd->semantic(sc);
fd->semantic2(sc); fd->semantic2(sc);
unsigned errors = global.startGagging();
fd->semantic3(sc); fd->semantic3(sc);
if (global.endGagging(errors))
{
fd->type = Type::terror;
fd->errors = true;
fd->fbody = NULL;
}
sc->pop(); sc->pop();
if (op->cFunc) if (op->cFunc)
@@ -344,6 +340,7 @@ bool isArrayOpValid(Expression *e)
} }
Type *tb = e->type->toBasetype(); Type *tb = e->type->toBasetype();
BinExp *be;
if ( (tb->ty == Tarray) || (tb->ty == Tsarray) ) if ( (tb->ty == Tarray) || (tb->ty == Tsarray) )
{ {
switch (e->op) switch (e->op)
@@ -365,11 +362,14 @@ bool isArrayOpValid(Expression *e)
case TOKxorass: case TOKxorass:
case TOKandass: case TOKandass:
case TOKorass: case TOKorass:
#if DMDV2
case TOKpow: case TOKpow:
case TOKpowass: case TOKpowass:
#endif be = (BinExp *)e;
return isArrayOpValid(((BinExp *)e)->e1) && isArrayOpValid(((BinExp *)e)->e2); return isArrayOpValid(be->e1) && isArrayOpValid(be->e2);
case TOKconstruct:
be = (BinExp *)e;
return be->e1->op == TOKslice && isArrayOpValid(be->e2);
case TOKcall: case TOKcall:
return false; // TODO: Decide if [] is required after arrayop calls. return false; // TODO: Decide if [] is required after arrayop calls.
@@ -395,15 +395,15 @@ Expression *BinExp::arrayOp(Scope *sc)
Type *tb = type->toBasetype(); Type *tb = type->toBasetype();
assert(tb->ty == Tarray || tb->ty == Tsarray); assert(tb->ty == Tarray || tb->ty == Tsarray);
if (tb->nextOf()->toBasetype()->ty == Tvoid) Type *tbn = tb->nextOf()->toBasetype();
if (tbn->ty == Tvoid)
{ {
error("Cannot perform array operations on void[] arrays"); error("Cannot perform array operations on void[] arrays");
return new ErrorExp(); return new ErrorExp();
} }
if (!isArrayOpValid(this))
if (!isArrayOpValid(e2))
{ {
e2->error("invalid array operation %s (did you forget a [] ?)", toChars()); error("invalid array operation %s (did you forget a [] ?)", toChars());
return new ErrorExp(); return new ErrorExp();
} }
@@ -420,11 +420,7 @@ Expression *BinExp::arrayOp(Scope *sc)
/* Append deco of array element type /* Append deco of array element type
*/ */
#if DMDV2
buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco);
#else
buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif
buf.writeByte(0); buf.writeByte(0);
char *name = buf.toChars(); char *name = buf.toChars();
@@ -440,6 +436,20 @@ Expression *BinExp::arrayOp(Scope *sc)
if (!op) if (!op)
op = buildArrayOp(ident, this, sc, loc); op = buildArrayOp(ident, this, sc, loc);
if (op->dFunc && op->dFunc->errors)
{
const char *fmt;
if (tbn->ty == Tstruct || tbn->ty == Tclass)
fmt = "invalid array operation '%s' because %s doesn't support necessary arithmetic operations";
else if (!tbn->isscalar())
fmt = "invalid array operation '%s' because %s is not a scalar type";
else
fmt = "invalid array operation '%s' for element type %s";
error(fmt, toChars(), tbn->toChars());
return new ErrorExp();
}
*pOp = op; *pOp = op;
FuncDeclaration *fd = op->cFunc ? op->cFunc : op->dFunc; FuncDeclaration *fd = op->cFunc ? op->cFunc : op->dFunc;
@@ -462,6 +472,10 @@ Expression *BinAssignExp::arrayOp(Scope *sc)
error("slice %s is not mutable", e1->toChars()); error("slice %s is not mutable", e1->toChars());
return new ErrorExp(); return new ErrorExp();
} }
if (e1->op == TOKarrayliteral)
{
return e1->modifiableLvalue(sc, e1);
}
return BinExp::arrayOp(sc); return BinExp::arrayOp(sc);
} }
@@ -526,9 +540,7 @@ void BinAssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments)
case TOKxorass: s = "Xorass"; break; case TOKxorass: s = "Xorass"; break;
case TOKandass: s = "Andass"; break; case TOKandass: s = "Andass"; break;
case TOKorass: s = "Orass"; break; case TOKorass: s = "Orass"; break;
#if DMDV2
case TOKpowass: s = "Powass"; break; case TOKpowass: s = "Powass"; break;
#endif
default: assert(0); default: assert(0);
} }
buf->writestring(s); buf->writestring(s);
@@ -561,9 +573,7 @@ void BinExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments)
case TOKxor: s = "Xor"; break; case TOKxor: s = "Xor"; break;
case TOKand: s = "And"; break; case TOKand: s = "And"; break;
case TOKor: s = "Or"; break; case TOKor: s = "Or"; break;
#if DMDV2
case TOKpow: s = "Pow"; break; case TOKpow: s = "Pow"; break;
#endif
default: break; default: break;
} }
if (s) if (s)
@@ -632,14 +642,12 @@ Expression *AssignExp::buildArrayLoop(Parameters *fparams)
/* Evaluate assign expressions right to left /* Evaluate assign expressions right to left
*/ */
Expression *ex2 = e2->buildArrayLoop(fparams); Expression *ex2 = e2->buildArrayLoop(fparams);
#if DMDV2
/* Need the cast because: /* Need the cast because:
* b = c + p[i]; * b = c + p[i];
* where b is a byte fails because (c + p[i]) is an int * where b is a byte fails because (c + p[i]) is an int
* which cannot be implicitly cast to byte. * which cannot be implicitly cast to byte.
*/ */
ex2 = new CastExp(Loc(), ex2, e1->type->nextOf()); ex2 = new CastExp(Loc(), ex2, e1->type->nextOf());
#endif
Expression *ex1 = e1->buildArrayLoop(fparams); Expression *ex1 = e1->buildArrayLoop(fparams);
Parameter *param = (*fparams)[0]; Parameter *param = (*fparams)[0];
param->storageClass = 0; param->storageClass = 0;
@@ -666,9 +674,7 @@ Expression *BinAssignExp::buildArrayLoop(Parameters *fparams)
case TOKxorass: return new XorAssignExp(loc, ex1, ex2); case TOKxorass: return new XorAssignExp(loc, ex1, ex2);
case TOKandass: return new AndAssignExp(loc, ex1, ex2); case TOKandass: return new AndAssignExp(loc, ex1, ex2);
case TOKorass: return new OrAssignExp(loc, ex1, ex2); case TOKorass: return new OrAssignExp(loc, ex1, ex2);
#if DMDV2
case TOKpowass: return new PowAssignExp(loc, ex1, ex2); case TOKpowass: return new PowAssignExp(loc, ex1, ex2);
#endif
default: default:
assert(0); assert(0);
return NULL; return NULL;
@@ -701,9 +707,7 @@ Expression *BinExp::buildArrayLoop(Parameters *fparams)
case TOKxor: case TOKxor:
case TOKand: case TOKand:
case TOKor: case TOKor:
#if DMDV2
case TOKpow: case TOKpow:
#endif
{ {
/* Evaluate assign expressions left to right /* Evaluate assign expressions left to right
*/ */
@@ -755,10 +759,8 @@ int Expression::isArrayOperand()
case TOKxorass: case TOKxorass:
case TOKandass: case TOKandass:
case TOKorass: case TOKorass:
#if DMDV2
case TOKpow: case TOKpow:
case TOKpowass: case TOKpowass:
#endif
case TOKneg: case TOKneg:
case TOKtilde: case TOKtilde:
return 1; return 1;
+4 -2
View File
@@ -56,14 +56,16 @@ typedef Array<class AliasDeclaration> AliasDeclarations;
typedef Array<class Module> Modules; typedef Array<class Module> Modules;
typedef Array<class File> Files; typedef Array<struct File> Files;
typedef Array<class CaseStatement> CaseStatements; typedef Array<class CaseStatement> CaseStatements;
typedef Array<class CompoundStatement> CompoundStatements; typedef Array<class ScopeStatement> ScopeStatements;
typedef Array<class GotoCaseStatement> GotoCaseStatements; typedef Array<class GotoCaseStatement> GotoCaseStatements;
typedef Array<class GotoStatement> GotoStatements;
typedef Array<class ReturnStatement> ReturnStatements; typedef Array<class ReturnStatement> ReturnStatements;
typedef Array<class TemplateInstance> TemplateInstances; typedef Array<class TemplateInstance> TemplateInstances;
+25 -14
View File
@@ -207,7 +207,7 @@ void AttribDeclaration::inlineScan()
} }
} }
void AttribDeclaration::addComment(utf8_t *comment) void AttribDeclaration::addComment(const utf8_t *comment)
{ {
//printf("AttribDeclaration::addComment %s\n", comment); //printf("AttribDeclaration::addComment %s\n", comment);
if (comment) if (comment)
@@ -288,10 +288,10 @@ bool AttribDeclaration::hasStaticCtorOrDtor()
{ {
Dsymbol *s = (*d)[i]; Dsymbol *s = (*d)[i];
if (s->hasStaticCtorOrDtor()) if (s->hasStaticCtorOrDtor())
return TRUE; return true;
} }
} }
return FALSE; return false;
} }
const char *AttribDeclaration::kind() const char *AttribDeclaration::kind()
@@ -497,11 +497,11 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
{ STCalias, TOKalias }, { STCalias, TOKalias },
{ STCout, TOKout }, { STCout, TOKout },
{ STCin, TOKin }, { STCin, TOKin },
#if DMDV2
{ STCmanifest, TOKenum }, { STCmanifest, TOKenum },
{ STCimmutable, TOKimmutable }, { STCimmutable, TOKimmutable },
{ STCshared, TOKshared }, { STCshared, TOKshared },
{ STCnothrow, TOKnothrow }, { STCnothrow, TOKnothrow },
{ STCwild, TOKwild },
{ STCpure, TOKpure }, { STCpure, TOKpure },
{ STCref, TOKref }, { STCref, TOKref },
{ STCtls }, { STCtls },
@@ -511,7 +511,6 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
{ STCtrusted, TOKat, "trusted" }, { STCtrusted, TOKat, "trusted" },
{ STCsystem, TOKat, "system" }, { STCsystem, TOKat, "system" },
{ STCdisable, TOKat, "disable" }, { STCdisable, TOKat, "disable" },
#endif
}; };
for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
@@ -525,7 +524,6 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
return "__thread"; return "__thread";
TOK tok = table[i].tok; TOK tok = table[i].tok;
#if DMDV2
if (tok == TOKat) if (tok == TOKat)
{ {
tmp[0] = '@'; tmp[0] = '@';
@@ -533,7 +531,6 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
return tmp; return tmp;
} }
else else
#endif
return Token::toChars(tok); return Token::toChars(tok);
} }
} }
@@ -741,6 +738,12 @@ void ProtDeclaration::semantic(Scope *sc)
} }
} }
void ProtDeclaration::emitComment(Scope *sc)
{
if (protection != PROTprivate)
AttribDeclaration::emitComment(sc);
}
void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, PROT protection) void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, PROT protection)
{ {
const char *p; const char *p;
@@ -1080,7 +1083,6 @@ void PragmaDeclaration::semantic(Scope *sc)
} }
goto Lnodecl; goto Lnodecl;
} }
#if DMDV2
else if (ident == Id::startaddress) else if (ident == Id::startaddress)
{ {
if (!args || args->dim != 1) if (!args || args->dim != 1)
@@ -1102,7 +1104,6 @@ void PragmaDeclaration::semantic(Scope *sc)
} }
goto Lnodecl; goto Lnodecl;
} }
#endif
else if (ident == Id::mangle) else if (ident == Id::mangle)
{ {
if (!args || args->dim != 1) if (!args || args->dim != 1)
@@ -1388,7 +1389,7 @@ void ConditionalDeclaration::importAll(Scope *sc)
} }
} }
void ConditionalDeclaration::addComment(utf8_t *comment) void ConditionalDeclaration::addComment(const utf8_t *comment)
{ {
/* Because addComment is called by the parser, if we called /* Because addComment is called by the parser, if we called
* include() it would define a version before it was used. * include() it would define a version before it was used.
@@ -1605,7 +1606,8 @@ int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
this->sd = sd; this->sd = sd;
if (memnum == 0) if (memnum == 0)
{ /* No members yet, so parse the mixin now {
/* No members yet, so parse the mixin now
*/ */
compileIt(sc); compileIt(sc);
memnum |= AttribDeclaration::addMember(sc, sd, memnum); memnum |= AttribDeclaration::addMember(sc, sd, memnum);
@@ -1624,13 +1626,13 @@ void CompileDeclaration::compileIt(Scope *sc)
exp = exp->ctfeInterpret(); exp = exp->ctfeInterpret();
StringExp *se = exp->toString(); StringExp *se = exp->toString();
if (!se) if (!se)
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars()); {
exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
} }
else else
{ {
se = se->toUTF8(sc); se = se->toUTF8(sc);
Parser p(sc->module, (utf8_t *)se->string, se->len, 0); Parser p(loc, sc->module, (utf8_t *)se->string, se->len, 0);
p.scanloc = loc;
p.nextToken(); p.nextToken();
unsigned errors = global.errors; unsigned errors = global.errors;
decl = p.parseDeclDefs(0); decl = p.parseDeclDefs(0);
@@ -1650,6 +1652,15 @@ void CompileDeclaration::semantic(Scope *sc)
compileIt(sc); compileIt(sc);
AttribDeclaration::addMember(sc, sd, 0); AttribDeclaration::addMember(sc, sd, 0);
compiled = 1; compiled = 1;
if (scope && decl)
{
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = (*decl)[i];
s->setScope(scope);
}
}
} }
AttribDeclaration::semantic(sc); AttribDeclaration::semantic(sc);
} }
+3 -2
View File
@@ -46,7 +46,7 @@ public:
void semantic2(Scope *sc); void semantic2(Scope *sc);
void semantic3(Scope *sc); void semantic3(Scope *sc);
void inlineScan(); void inlineScan();
void addComment(utf8_t *comment); void addComment(const utf8_t *comment);
void emitComment(Scope *sc); void emitComment(Scope *sc);
const char *kind(); const char *kind();
bool oneMember(Dsymbol **ps, Identifier *ident); bool oneMember(Dsymbol **ps, Identifier *ident);
@@ -119,6 +119,7 @@ public:
void importAll(Scope *sc); void importAll(Scope *sc);
void setScope(Scope *sc); void setScope(Scope *sc);
void semantic(Scope *sc); void semantic(Scope *sc);
void emitComment(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void protectionToCBuffer(OutBuffer *buf, PROT protection); static void protectionToCBuffer(OutBuffer *buf, PROT protection);
@@ -184,7 +185,7 @@ public:
bool oneMember(Dsymbol **ps, Identifier *ident); bool oneMember(Dsymbol **ps, Identifier *ident);
void emitComment(Scope *sc); void emitComment(Scope *sc);
Dsymbols *include(Scope *sc, ScopeDsymbol *s); Dsymbols *include(Scope *sc, ScopeDsymbol *s);
void addComment(utf8_t *comment); void addComment(const utf8_t *comment);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toJson(JsonOut *json); void toJson(JsonOut *json);
void importAll(Scope *sc); void importAll(Scope *sc);
-3
View File
@@ -24,7 +24,6 @@
#include "id.h" #include "id.h"
#include "module.h" #include "module.h"
#if DMDV2
/********************************** /**********************************
* Determine if function is a builtin one that we can * Determine if function is a builtin one that we can
@@ -222,5 +221,3 @@ Expression *eval_builtin(Loc loc, BUILTIN builtin, Expressions *arguments)
} }
return e; return e;
} }
#endif
+12 -12
View File
@@ -23,7 +23,7 @@
#include "scope.h" #include "scope.h"
#include "attrib.h" #include "attrib.h"
int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow); bool Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow);
int lambdaCanThrow(Expression *e, void *param); int lambdaCanThrow(Expression *e, void *param);
/******************************************** /********************************************
@@ -40,11 +40,11 @@ struct CanThrow
bool mustnot; bool mustnot;
}; };
int Expression::canThrow(bool mustNotThrow) bool Expression::canThrow(bool mustNotThrow)
{ {
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars()); //printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
CanThrow ct; CanThrow ct;
ct.can = FALSE; ct.can = false;
ct.mustnot = mustNotThrow; ct.mustnot = mustNotThrow;
apply(&lambdaCanThrow, &ct); apply(&lambdaCanThrow, &ct);
return ct.can; return ct.can;
@@ -81,7 +81,7 @@ int lambdaCanThrow(Expression *e, void *param)
{ {
if (pct->mustnot) if (pct->mustnot)
e->error("'%s' is not nothrow", ce->f ? ce->f->toPrettyChars() : ce->e1->toChars()); e->error("'%s' is not nothrow", ce->f ? ce->f->toPrettyChars() : ce->e1->toChars());
pct->can = TRUE; pct->can = true;
} }
break; break;
} }
@@ -97,7 +97,7 @@ int lambdaCanThrow(Expression *e, void *param)
{ {
if (pct->mustnot) if (pct->mustnot)
e->error("constructor %s is not nothrow", ne->member->toChars()); e->error("constructor %s is not nothrow", ne->member->toChars());
pct->can = TRUE; pct->can = true;
} }
} }
// regard storage allocation failures as not recoverable // regard storage allocation failures as not recoverable
@@ -126,7 +126,7 @@ int lambdaCanThrow(Expression *e, void *param)
{ {
if (pct->mustnot) if (pct->mustnot)
e->error("'%s' is not nothrow", sd->postblit->toPrettyChars()); e->error("'%s' is not nothrow", sd->postblit->toPrettyChars());
pct->can = TRUE; pct->can = true;
} }
break; break;
} }
@@ -146,7 +146,7 @@ int lambdaCanThrow(Expression *e, void *param)
* Mirrors logic in Dsymbol_toElem(). * Mirrors logic in Dsymbol_toElem().
*/ */
int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow) bool Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
{ {
AttribDeclaration *ad; AttribDeclaration *ad;
VarDeclaration *vd; VarDeclaration *vd;
@@ -164,7 +164,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
{ {
s = (*decl)[i]; s = (*decl)[i];
if (Dsymbol_canThrow(s, mustNotThrow)) if (Dsymbol_canThrow(s, mustNotThrow))
return 1; return true;
} }
} }
} }
@@ -182,7 +182,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
if (vd->init) if (vd->init)
{ ExpInitializer *ie = vd->init->isExpInitializer(); { ExpInitializer *ie = vd->init->isExpInitializer();
if (ie && ie->exp->canThrow(mustNotThrow)) if (ie && ie->exp->canThrow(mustNotThrow))
return 1; return true;
} }
if (vd->edtor && !vd->noscope) if (vd->edtor && !vd->noscope)
return vd->edtor->canThrow(mustNotThrow); return vd->edtor->canThrow(mustNotThrow);
@@ -197,7 +197,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
{ {
Dsymbol *sm = (*tm->members)[i]; Dsymbol *sm = (*tm->members)[i];
if (Dsymbol_canThrow(sm, mustNotThrow)) if (Dsymbol_canThrow(sm, mustNotThrow))
return 1; return true;
} }
} }
} }
@@ -210,10 +210,10 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
if (eo->op == TOKdsymbol) if (eo->op == TOKdsymbol)
{ DsymbolExp *se = (DsymbolExp *)eo; { DsymbolExp *se = (DsymbolExp *)eo;
if (Dsymbol_canThrow(se->s, mustNotThrow)) if (Dsymbol_canThrow(se->s, mustNotThrow))
return 1; return true;
} }
} }
} }
} }
return 0; return false;
} }
+62 -73
View File
@@ -39,45 +39,12 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
MATCH match = implicitConvTo(t); MATCH match = implicitConvTo(t);
if (match) if (match)
{ {
#if DMDV1
TY tyfrom = type->toBasetype()->ty;
TY tyto = t->toBasetype()->ty;
if (global.params.warnings &&
Type::impcnvWarn[tyfrom][tyto] &&
op != TOKint64)
{
Expression *e = optimize(WANTflags | WANTvalue);
if (e->op == TOKint64)
return e->implicitCastTo(sc, t);
if (tyfrom == Tint32 &&
(op == TOKadd || op == TOKmin ||
op == TOKand || op == TOKor || op == TOKxor)
)
{
/* This is really only a semi-kludge fix,
* we really should look at the operands of op
* and see if they are narrower types.
* For example, b=b|b and b=b|7 and s=b+b should be allowed,
* but b=b|i should be an error.
*/
;
}
else
{
warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
toChars(), type->toChars(), t->toChars());
}
}
#endif
#if DMDV2
if (match == MATCHconst && type->constConv(t)) if (match == MATCHconst && type->constConv(t))
{ {
Expression *e = copy(); Expression *e = copy();
e->type = t; e->type = t;
return e; return e;
} }
#endif
return castTo(sc, t); return castTo(sc, t);
} }
@@ -178,9 +145,8 @@ MATCH Expression::implicitConvTo(Type *t)
if (type->isintegral() && t->isintegral() && if (type->isintegral() && t->isintegral() &&
type->isTypeBasic() && t->isTypeBasic()) type->isTypeBasic() && t->isTypeBasic())
{ IntRange src = this->getIntRange() DUMP; { IntRange src = this->getIntRange() DUMP;
IntRange targetUnsigned = IntRange::fromType(t, /*isUnsigned*/true) DUMP; IntRange target = IntRange::fromType(t) DUMP;
IntRange targetSigned = IntRange::fromType(t, /*isUnsigned*/false) DUMP; if (target.contains(src))
if (targetUnsigned.contains(src) || targetSigned.contains(src))
return MATCHconvert; return MATCHconvert;
} }
@@ -226,6 +192,8 @@ MATCH IntegerExp::implicitConvTo(Type *t)
if (t->ty == Tvector) if (t->ty == Tvector)
{ TypeVector *tv = (TypeVector *)t; { TypeVector *tv = (TypeVector *)t;
TypeBasic *tb = tv->elementType(); TypeBasic *tb = tv->elementType();
if (tb->ty == Tvoid)
goto Lno;
toty = tb->ty; toty = tb->ty;
} }
@@ -442,7 +410,6 @@ MATCH NullExp::implicitConvTo(Type *t)
return Expression::implicitConvTo(t); return Expression::implicitConvTo(t);
} }
#if DMDV2
MATCH StructLiteralExp::implicitConvTo(Type *t) MATCH StructLiteralExp::implicitConvTo(Type *t)
{ {
#if 0 #if 0
@@ -471,7 +438,6 @@ MATCH StructLiteralExp::implicitConvTo(Type *t)
} }
return m; return m;
} }
#endif
MATCH StringExp::implicitConvTo(Type *t) MATCH StringExp::implicitConvTo(Type *t)
{ {
@@ -645,6 +611,27 @@ MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
return Expression::implicitConvTo(t); return Expression::implicitConvTo(t);
} }
Expression *CallExp::implicitCastTo(Scope *sc, Type *t)
{
//printf("CallExp::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars());
/* Allow the result of strongly pure functions to
* convert to immutable
*/
if (f && f->isolateReturn() &&
type->immutableOf()->equals(t->immutableOf()))
{
/* Avoid emitting CastExp for:
* T[] make() pure { ... }
* immutable T[] arr = make(); // unique return
*/
Expression *e = copy();
e->type = t;
return e;
}
return Expression::implicitCastTo(sc, t);
}
MATCH CallExp::implicitConvTo(Type *t) MATCH CallExp::implicitConvTo(Type *t)
{ {
#if 0 #if 0
@@ -1025,7 +1012,7 @@ Type *SliceExp::toStaticArrayType()
Expression *upr = this->upr->optimize(WANTvalue); Expression *upr = this->upr->optimize(WANTvalue);
if (lwr->isConst() && upr->isConst()) if (lwr->isConst() && upr->isConst())
{ {
size_t len = upr->toUInteger() - lwr->toUInteger(); size_t len = (size_t)(upr->toUInteger() - lwr->toUInteger());
return TypeSArray::makeType(loc, type->toBasetype()->nextOf(), len); return TypeSArray::makeType(loc, type->toBasetype()->nextOf(), len);
} }
} }
@@ -1086,19 +1073,8 @@ Expression *Expression::castTo(Scope *sc, Type *t)
{ {
//printf("Converting [dim] to *\n"); //printf("Converting [dim] to *\n");
if (typeb->size(loc) == 0) e = new AddrExp(loc, e);
e = new NullExp(loc);
else
e = new AddrExp(loc, e);
} }
#if 0
else if (tb->ty == Tdelegate && type->ty != Tdelegate)
{
TypeDelegate *td = (TypeDelegate *)tb;
TypeFunction *tf = (TypeFunction *)td->nextOf();
return toDelegate(sc, tf->nextOf());
}
#endif
else else
{ {
if (typeb->ty == Tstruct) if (typeb->ty == Tstruct)
@@ -1147,7 +1123,7 @@ Expression *Expression::castTo(Scope *sc, Type *t)
} }
else if (typeb->implicitConvTo(tb) == MATCHconst && t->equals(type->constOf())) else if (typeb->implicitConvTo(tb) == MATCHconst && t->equals(type->constOf()))
{ {
Expression *e = copy(); e = copy();
e->type = t; e->type = t;
return e; return e;
} }
@@ -1480,7 +1456,7 @@ L2:
// See if need to truncate or extend the literal // See if need to truncate or extend the literal
if (tb->ty == Tsarray) if (tb->ty == Tsarray)
{ {
dinteger_t dim2 = ((TypeSArray *)tb)->dim->toInteger(); size_t dim2 = (size_t)((TypeSArray *)tb)->dim->toInteger();
//printf("dim from = %d, to = %d\n", (int)se->len, (int)dim2); //printf("dim from = %d, to = %d\n", (int)se->len, (int)dim2);
@@ -1744,9 +1720,7 @@ Expression *SymOffExp::castTo(Scope *sc, Type *t)
e = new SymOffExp(loc, f, 0); e = new SymOffExp(loc, f, 0);
e->type = t; e->type = t;
} }
#if DMDV2
f->tookAddressOf++; f->tookAddressOf++;
#endif
return e; return e;
} }
} }
@@ -1965,7 +1939,8 @@ Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters
{ {
if (to->ty == Tdelegate || if (to->ty == Tdelegate ||
to->ty == Tpointer && to->nextOf()->ty == Tfunction) to->ty == Tpointer && to->nextOf()->ty == Tfunction)
{ fd->treq = to; {
fd->treq = to;
} }
return this; return this;
} }
@@ -1985,7 +1960,8 @@ Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters
} }
if (td) if (td)
{ /// Parameter types inference from {
// Parameter types inference from 'to'
assert(td->scope); assert(td->scope);
if (t->ty == Tfunction) if (t->ty == Tfunction)
{ {
@@ -2005,10 +1981,12 @@ Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters
{ {
TemplateParameter *tp = (*td->parameters)[i]; TemplateParameter *tp = (*td->parameters)[i];
for (size_t u = 0; u < dim; u++) for (size_t u = 0; u < dim; u++)
{ Parameter *p = Parameter::getNth(tfl->parameters, u); {
Parameter *p = Parameter::getNth(tfl->parameters, u);
if (p->type->ty == Tident && if (p->type->ty == Tident &&
((TypeIdentifier *)p->type)->ident == tp->ident) ((TypeIdentifier *)p->type)->ident == tp->ident)
{ p = Parameter::getNth(tfv->parameters, u); {
p = Parameter::getNth(tfv->parameters, u);
Type *tprm = p->type; Type *tprm = p->type;
if (tprm->reliesOnTident(tparams)) if (tprm->reliesOnTident(tparams))
goto L1; goto L1;
@@ -2036,7 +2014,8 @@ Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters
fld->treq = NULL; fld->treq = NULL;
if (e->op == TOKfunction) if (e->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)e; {
FuncExp *fe = (FuncExp *)e;
assert(fe->td == NULL); assert(fe->td == NULL);
e = fe->inferType(to, flag); e = fe->inferType(to, flag);
} }
@@ -2065,7 +2044,8 @@ Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters
} }
L1: L1:
if (!flag && !e) if (!flag && !e)
{ error("cannot infer function literal type from %s", to->toChars()); {
error("cannot infer function literal type from %s", to->toChars());
e = new ErrorExp(); e = new ErrorExp();
} }
return e; return e;
@@ -2700,6 +2680,15 @@ Lcc:
e2 = e2->castTo(sc, t); e2 = e2->castTo(sc, t);
goto Lagain; goto Lagain;
} }
else if (t1->ty == Tnull && t2->ty == Tnull)
{
unsigned char mod = MODmerge(t1->mod, t2->mod);
t = t1->castMod(mod);
e1 = e1->castTo(sc, t);
e2 = e2->castTo(sc, t);
goto Lret;
}
else if (e1->isArrayOperand() && t1->ty == Tarray && else if (e1->isArrayOperand() && t1->ty == Tarray &&
e2->implicitConvTo(t1->nextOf())) e2->implicitConvTo(t1->nextOf()))
{ // T[] op T { // T[] op T
@@ -2770,6 +2759,8 @@ Expression *BinExp::typeCombine(Scope *sc)
goto Lerror; goto Lerror;
else if (t1->ty == Tclass && t2->ty == Tclass) else if (t1->ty == Tclass && t2->ty == Tclass)
goto Lerror; goto Lerror;
else if (t1->ty == Taarray && t2->ty == Taarray)
goto Lerror;
} }
if (!typeMerge(sc, this, &type, &e1, &e2)) if (!typeMerge(sc, this, &type, &e1, &e2))
@@ -2930,12 +2921,11 @@ IntRange DivExp::getIntRange()
return Expression::getIntRange() DUMP; return Expression::getIntRange() DUMP;
// [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)] // [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)]
SignExtendedNumber bdy[4] = { SignExtendedNumber bdy[4];
ir1.imin / ir2.imin, bdy[0] = ir1.imin / ir2.imin;
ir1.imin / ir2.imax, bdy[1] = ir1.imin / ir2.imax;
ir1.imax / ir2.imin, bdy[2] = ir1.imax / ir2.imin;
ir1.imax / ir2.imax bdy[3] = ir1.imax / ir2.imax;
};
return IntRange::fromNumbers4(bdy).cast(type) DUMP; return IntRange::fromNumbers4(bdy).cast(type) DUMP;
} }
@@ -2945,12 +2935,11 @@ IntRange MulExp::getIntRange()
IntRange ir2 = e2->getIntRange(); IntRange ir2 = e2->getIntRange();
// [a,b] * [c,d] = [min (ac, ad, bc, bd), max (ac, ad, bc, bd)] // [a,b] * [c,d] = [min (ac, ad, bc, bd), max (ac, ad, bc, bd)]
SignExtendedNumber bdy[4] = { SignExtendedNumber bdy[4];
ir1.imin * ir2.imin, bdy[0] = ir1.imin * ir2.imin;
ir1.imin * ir2.imax, bdy[1] = ir1.imin * ir2.imax;
ir1.imax * ir2.imin, bdy[2] = ir1.imax * ir2.imin;
ir1.imax * ir2.imax bdy[3] = ir1.imax * ir2.imax;
};
return IntRange::fromNumbers4(bdy).cast(type) DUMP; return IntRange::fromNumbers4(bdy).cast(type) DUMP;
} }
+23 -32
View File
@@ -155,7 +155,6 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
Type::typeinfotypelist = this; Type::typeinfotypelist = this;
} }
#if DMDV2
if (id == Id::TypeInfo_Const) if (id == Id::TypeInfo_Const)
{ if (!inObject) { if (!inObject)
error("%s", msg); error("%s", msg);
@@ -185,7 +184,6 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
error("%s", msg); error("%s", msg);
Type::typeinfovector = this; Type::typeinfovector = this;
} }
#endif
} }
if (id == Id::Object) if (id == Id::Object)
@@ -213,16 +211,8 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
} }
#if !MODULEINFO_IS_STRUCT #if !MODULEINFO_IS_STRUCT
#ifdef DMDV2
if (id == Id::ModuleInfo && !Module::moduleinfo) if (id == Id::ModuleInfo && !Module::moduleinfo)
Module::moduleinfo = this; Module::moduleinfo = this;
#else
if (id == Id::ModuleInfo)
{ if (Module::moduleinfo)
error("%s", msg);
Module::moduleinfo = this;
}
#endif
#endif #endif
} }
@@ -381,10 +371,21 @@ void ClassDeclaration::semantic(Scope *sc)
goto L7; goto L7;
} }
} }
if (!tc->sym->symtab || tc->sym->sizeok == SIZEOKnone) if (tc->sym->scope)
{ // Try to resolve forward reference {
if (/*doAncestorsSemantic == SemanticIn &&*/ tc->sym->scope) // Try to resolve forward reference
tc->sym->semantic(NULL); tc->sym->semantic(NULL);
}
if (tc->sym->symtab && tc->sym->scope == NULL)
{
/* Bugzilla 11034: Essentailly, class inheritance hierarchy
* and instance size of each classes are orthogonal information.
* Therefore, even if tc->sym->sizeof == SIZEOKnone,
* we need to set baseClass field for class covariance check.
*/
baseClass = tc->sym;
b->base = baseClass;
} }
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == SIZEOKnone) if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == SIZEOKnone)
{ {
@@ -399,10 +400,6 @@ void ClassDeclaration::semantic(Scope *sc)
scope->module->addDeferredSemantic(this); scope->module->addDeferredSemantic(this);
return; return;
} }
else
{ baseClass = tc->sym;
b->base = baseClass;
}
L7: ; L7: ;
} }
} }
@@ -448,10 +445,10 @@ void ClassDeclaration::semantic(Scope *sc)
error("inherits from duplicate interface %s", b2->base->toChars()); error("inherits from duplicate interface %s", b2->base->toChars());
} }
if (!tc->sym->symtab) if (tc->sym->scope)
{ // Try to resolve forward reference {
if (/*doAncestorsSemantic == SemanticIn &&*/ tc->sym->scope) // Try to resolve forward reference
tc->sym->semantic(NULL); tc->sym->semantic(NULL);
} }
b->base = tc->sym; b->base = tc->sym;
@@ -999,7 +996,6 @@ ClassDeclaration *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
* Return 1 if function is hidden (not findable through search). * Return 1 if function is hidden (not findable through search).
*/ */
#if DMDV2
int isf(void *param, Dsymbol *s) int isf(void *param, Dsymbol *s)
{ {
FuncDeclaration *fd = s->isFuncDeclaration(); FuncDeclaration *fd = s->isFuncDeclaration();
@@ -1044,7 +1040,6 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
return !fd->parent->isTemplateMixin(); return !fd->parent->isTemplateMixin();
} }
} }
#endif
/**************** /****************
* Find virtual function matching identifier and type. * Find virtual function matching identifier and type.
@@ -1172,7 +1167,6 @@ int ClassDeclaration::isCOMinterface()
return 0; return 0;
} }
#if DMDV2
int ClassDeclaration::isCPPclass() int ClassDeclaration::isCPPclass()
{ {
return cpp; return cpp;
@@ -1182,7 +1176,6 @@ int ClassDeclaration::isCPPinterface()
{ {
return 0; return 0;
} }
#endif
/**************************************** /****************************************
@@ -1366,10 +1359,10 @@ void InterfaceDeclaration::semantic(Scope *sc)
baseclasses->remove(i); baseclasses->remove(i);
continue; continue;
} }
if (!b->base->symtab) if (b->base->scope)
{ // Try to resolve forward reference {
if (doAncestorsSemantic == SemanticIn && b->base->scope) // Try to resolve forward reference
b->base->semantic(NULL); b->base->semantic(NULL);
} }
if (!b->base->symtab || b->base->scope || b->base->inuse) if (!b->base->symtab || b->base->scope || b->base->inuse)
{ {
@@ -1605,12 +1598,10 @@ int InterfaceDeclaration::isCOMinterface()
return com; return com;
} }
#if DMDV2
int InterfaceDeclaration::isCPPinterface() int InterfaceDeclaration::isCPPinterface()
{ {
return cpp; return cpp;
} }
#endif
/******************************************* /*******************************************
*/ */
+12 -11
View File
@@ -76,6 +76,7 @@ FuncDeclaration *AggregateDeclaration::hasIdentityOpAssign(Scope *sc)
unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it.
global.speculativeGag = global.gag; global.speculativeGag = global.gag;
sc = sc->push(); sc = sc->push();
sc->tinst = NULL;
sc->speculative = true; sc->speculative = true;
for (size_t i = 0; i < 2; i++) for (size_t i = 0; i < 2; i++)
@@ -196,7 +197,11 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
if (dtor || postblit) if (dtor || postblit)
{ {
if (dtor) if (dtor)
{
stc = mergeFuncAttrs(stc, dtor->storage_class); stc = mergeFuncAttrs(stc, dtor->storage_class);
if (stc & STCsafe)
stc = (stc & ~STCsafe) | STCtrusted;
}
} }
else else
{ {
@@ -241,7 +246,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{ {
tmp = new VarDeclaration(loc, type, idtmp, new VoidInitializer(loc)); tmp = new VarDeclaration(loc, type, idtmp, new VoidInitializer(loc));
tmp->noscope = 1; tmp->noscope = 1;
tmp->storage_class |= STCctfe; tmp->storage_class |= STCtemp | STCctfe;
e = new DeclarationExp(loc, tmp); e = new DeclarationExp(loc, tmp);
ec = new AssignExp(loc, ec = new AssignExp(loc,
new VarExp(loc, tmp), new VarExp(loc, tmp),
@@ -305,7 +310,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
Dsymbols *decldefs = new Dsymbols(); Dsymbols *decldefs = new Dsymbols();
decldefs->push(s); decldefs->push(s);
TemplateDeclaration *tempdecl = TemplateDeclaration *tempdecl =
new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0); new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs);
s = tempdecl; s = tempdecl;
} }
#endif #endif
@@ -419,6 +424,7 @@ FuncDeclaration *AggregateDeclaration::hasIdentityOpEquals(Scope *sc)
unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it. unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it.
global.speculativeGag = global.gag; global.speculativeGag = global.gag;
sc = sc->push(); sc = sc->push();
sc->tinst = NULL;
sc->speculative = true; sc->speculative = true;
for (size_t j = 0; j < 2; j++) for (size_t j = 0; j < 2; j++)
@@ -483,7 +489,7 @@ FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
{ {
TypeFunction *tfeqptr; TypeFunction *tfeqptr;
{ {
Scope sc; Scope scx;
/* const bool opEquals(ref const S s); /* const bool opEquals(ref const S s);
*/ */
@@ -491,7 +497,7 @@ FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL));
tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd); tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd);
tfeqptr->mod = MODconst; tfeqptr->mod = MODconst;
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &sc); tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &scx);
} }
fd = fd->overloadExactMatch(tfeqptr); fd = fd->overloadExactMatch(tfeqptr);
if (fd) if (fd)
@@ -569,7 +575,7 @@ FuncDeclaration *StructDeclaration::buildXopCmp(Scope *sc)
{ {
TypeFunction *tfcmpptr; TypeFunction *tfcmpptr;
{ {
Scope sc; Scope scx;
/* const int opCmp(ref const S s); /* const int opCmp(ref const S s);
*/ */
@@ -577,7 +583,7 @@ FuncDeclaration *StructDeclaration::buildXopCmp(Scope *sc)
parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL));
tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd); tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd);
tfcmpptr->mod = MODconst; tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &sc); tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &scx);
} }
fd = fd->overloadExactMatch(tfcmpptr); fd = fd->overloadExactMatch(tfcmpptr);
if (fd) if (fd)
@@ -758,7 +764,6 @@ FuncDeclaration *StructDeclaration::buildCpCtor(Scope *sc)
* and the ordering changes (runs forward instead of backwards). * and the ordering changes (runs forward instead of backwards).
*/ */
#if DMDV2
FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc) FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
{ {
//printf("StructDeclaration::buildPostBlit() %s\n", toChars()); //printf("StructDeclaration::buildPostBlit() %s\n", toChars());
@@ -864,8 +869,6 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
} }
} }
#endif
/***************************************** /*****************************************
* Create inclusive destructor for struct/class by aggregating * Create inclusive destructor for struct/class by aggregating
* all the destructors in dtors[] with the destructors for * all the destructors in dtors[] with the destructors for
@@ -882,7 +885,6 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
Loc loc = Loc(); // internal code should have no loc to prevent coverage Loc loc = Loc(); // internal code should have no loc to prevent coverage
Expression *e = NULL; Expression *e = NULL;
#if DMDV2
for (size_t i = 0; i < fields.dim; i++) for (size_t i = 0; i < fields.dim; i++)
{ {
Dsymbol *s = fields[i]; Dsymbol *s = fields[i];
@@ -946,7 +948,6 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
members->push(dd); members->push(dd);
dd->semantic(sc); dd->semantic(sc);
} }
#endif
switch (dtors.dim) switch (dtors.dim)
{ {
+4 -4
View File
@@ -34,11 +34,11 @@ int findCondition(Strings *ids, Identifier *ident)
const char *id = (*ids)[i]; const char *id = (*ids)[i];
if (strcmp(id, ident->toChars()) == 0) if (strcmp(id, ident->toChars()) == 0)
return TRUE; return true;
} }
} }
return FALSE; return false;
} }
/* ============================================================ */ /* ============================================================ */
@@ -375,9 +375,9 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
{ {
goto Lerror; goto Lerror;
} }
else if (e->isBool(TRUE)) else if (e->isBool(true))
inc = 1; inc = 1;
else if (e->isBool(FALSE)) else if (e->isBool(false))
inc = 2; inc = 2;
else else
{ {
+30 -123
View File
@@ -14,10 +14,6 @@
#include <string.h> // mem{cpy|set|cmp}() #include <string.h> // mem{cpy|set|cmp}()
#include <math.h> #include <math.h>
#if __DMC__
#include <complex.h>
#endif
#include "rmem.h" #include "rmem.h"
#include "root.h" #include "root.h"
#include "port.h" #include "port.h"
@@ -185,17 +181,6 @@ Expression *Add(Type *type, Expression *e1, Expression *e2)
switch (x) switch (x)
{ {
#if __DMC__
case 0+0: v = (complex_t) (r1 + r2); break;
case 0+1: v = r1 + i2 * I; break;
case 0+2: v = r1 + c2; break;
case 3+0: v = i1 * I + r2; break;
case 3+1: v = (complex_t) ((i1 + i2) * I); break;
case 3+2: v = i1 * I + c2; break;
case 6+0: v = c1 + r2; break;
case 6+1: v = c1 + i2 * I; break;
case 6+2: v = c1 + c2; break;
#else
case 0+0: v = complex_t(r1 + r2, 0); break; case 0+0: v = complex_t(r1 + r2, 0); break;
case 0+1: v = complex_t(r1, i2); break; case 0+1: v = complex_t(r1, i2); break;
case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break; case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break;
@@ -205,7 +190,6 @@ Expression *Add(Type *type, Expression *e1, Expression *e2)
case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break; case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break;
case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break; case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break;
case 6+2: v = c1 + c2; break; case 6+2: v = c1 + c2; break;
#endif
default: assert(0); default: assert(0);
} }
e = new ComplexExp(loc, v, type); e = new ComplexExp(loc, v, type);
@@ -282,17 +266,6 @@ Expression *Min(Type *type, Expression *e1, Expression *e2)
switch (x) switch (x)
{ {
#if __DMC__
case 0+0: v = (complex_t) (r1 - r2); break;
case 0+1: v = r1 - i2 * I; break;
case 0+2: v = r1 - c2; break;
case 3+0: v = i1 * I - r2; break;
case 3+1: v = (complex_t) ((i1 - i2) * I); break;
case 3+2: v = i1 * I - c2; break;
case 6+0: v = c1 - r2; break;
case 6+1: v = c1 - i2 * I; break;
case 6+2: v = c1 - c2; break;
#else
case 0+0: v = complex_t(r1 - r2, 0); break; case 0+0: v = complex_t(r1 - r2, 0); break;
case 0+1: v = complex_t(r1, -i2); break; case 0+1: v = complex_t(r1, -i2); break;
case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break; case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break;
@@ -302,7 +275,6 @@ Expression *Min(Type *type, Expression *e1, Expression *e2)
case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break; case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break;
case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break; case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break;
case 6+2: v = c1 - c2; break; case 6+2: v = c1 - c2; break;
#endif
default: assert(0); default: assert(0);
} }
e = new ComplexExp(loc, v, type); e = new ComplexExp(loc, v, type);
@@ -330,43 +302,27 @@ Expression *Mul(Type *type, Expression *e1, Expression *e2)
if (e1->type->isreal()) if (e1->type->isreal())
{ {
#if __DMC__
c = e1->toReal() * e2->toComplex();
#else
r = e1->toReal(); r = e1->toReal();
c = e2->toComplex(); c = e2->toComplex();
c = complex_t(r * creall(c), r * cimagl(c)); c = complex_t(r * creall(c), r * cimagl(c));
#endif
} }
else if (e1->type->isimaginary()) else if (e1->type->isimaginary())
{ {
#if __DMC__
c = e1->toImaginary() * I * e2->toComplex();
#else
r = e1->toImaginary(); r = e1->toImaginary();
c = e2->toComplex(); c = e2->toComplex();
c = complex_t(-r * cimagl(c), r * creall(c)); c = complex_t(-r * cimagl(c), r * creall(c));
#endif
} }
else if (e2->type->isreal()) else if (e2->type->isreal())
{ {
#if __DMC__
c = e2->toReal() * e1->toComplex();
#else
r = e2->toReal(); r = e2->toReal();
c = e1->toComplex(); c = e1->toComplex();
c = complex_t(r * creall(c), r * cimagl(c)); c = complex_t(r * creall(c), r * cimagl(c));
#endif
} }
else if (e2->type->isimaginary()) else if (e2->type->isimaginary())
{ {
#if __DMC__
c = e1->toComplex() * e2->toImaginary() * I;
#else
r = e2->toImaginary(); r = e2->toImaginary();
c = e1->toComplex(); c = e1->toComplex();
c = complex_t(-r * cimagl(c), r * creall(c)); c = complex_t(-r * cimagl(c), r * creall(c));
#endif
} }
else else
c = e1->toComplex() * e2->toComplex(); c = e1->toComplex() * e2->toComplex();
@@ -404,31 +360,15 @@ Expression *Div(Type *type, Expression *e1, Expression *e2)
e = new RealExp(loc, e1->toReal() / e2->toReal(), type); e = new RealExp(loc, e1->toReal() / e2->toReal(), type);
return e; return e;
} }
#if __DMC__
//r = e2->toReal();
//c = e1->toComplex();
//printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r);
c = e1->toComplex() / e2->toReal();
#else
r = e2->toReal(); r = e2->toReal();
c = e1->toComplex(); c = e1->toComplex();
c = complex_t(creall(c) / r, cimagl(c) / r); c = complex_t(creall(c) / r, cimagl(c) / r);
#endif
} }
else if (e2->type->isimaginary()) else if (e2->type->isimaginary())
{ {
#if __DMC__
//r = e2->toImaginary();
//c = e1->toComplex();
//printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r);
c = e1->toComplex() / (e2->toImaginary() * I);
#else
r = e2->toImaginary(); r = e2->toImaginary();
c = e1->toComplex(); c = e1->toComplex();
c = complex_t(cimagl(c) / r, -creall(c) / r); c = complex_t(cimagl(c) / r, -creall(c) / r);
#endif
} }
else else
{ {
@@ -476,20 +416,12 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2)
if (e2->type->isreal()) if (e2->type->isreal())
{ real_t r2 = e2->toReal(); { real_t r2 = e2->toReal();
#ifdef __DMC__
c = Port::fmodl(e1->toReal(), r2) + Port::fmodl(e1->toImaginary(), r2) * I;
#else
c = complex_t(Port::fmodl(e1->toReal(), r2), Port::fmodl(e1->toImaginary(), r2)); c = complex_t(Port::fmodl(e1->toReal(), r2), Port::fmodl(e1->toImaginary(), r2));
#endif
} }
else if (e2->type->isimaginary()) else if (e2->type->isimaginary())
{ real_t i2 = e2->toImaginary(); { real_t i2 = e2->toImaginary();
#ifdef __DMC__
c = Port::fmodl(e1->toReal(), i2) + Port::fmodl(e1->toImaginary(), i2) * I;
#else
c = complex_t(Port::fmodl(e1->toReal(), i2), Port::fmodl(e1->toImaginary(), i2)); c = complex_t(Port::fmodl(e1->toReal(), i2), Port::fmodl(e1->toImaginary(), i2));
#endif
} }
else else
assert(0); assert(0);
@@ -563,7 +495,12 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
else else
neg = false; neg = false;
if (e1->type->isfloating()) if (e1->type->iscomplex())
{
r = new ComplexExp(loc, e1->toComplex(), e1->type);
v = new ComplexExp(loc, complex_t(1.0, 0.0), e1->type);
}
else if (e1->type->isfloating())
{ {
r = new RealExp(loc, e1->toReal(), e1->type); r = new RealExp(loc, e1->toReal(), e1->type);
v = new RealExp(loc, ldouble(1.0), e1->type); v = new RealExp(loc, ldouble(1.0), e1->type);
@@ -585,7 +522,9 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
if (neg) if (neg)
v = Div(v->type, new RealExp(loc, ldouble(1.0), v->type), v); v = Div(v->type, new RealExp(loc, ldouble(1.0), v->type), v);
if (type->isintegral()) if (type->iscomplex())
e = new ComplexExp(loc, v->toComplex(), type);
else if (type->isintegral())
e = new IntegerExp(loc, v->toInteger(), type); e = new IntegerExp(loc, v->toInteger(), type);
else else
e = new RealExp(loc, v->toReal(), type); e = new RealExp(loc, v->toReal(), type);
@@ -819,7 +758,7 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2)
Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
if (v == EXP_CANT_INTERPRET) if (v == EXP_CANT_INTERPRET)
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
cmp = v->toInteger(); cmp = (int)v->toInteger();
if (cmp == 0) if (cmp == 0)
break; break;
} }
@@ -885,7 +824,7 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2)
Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
if (v == EXP_CANT_INTERPRET) if (v == EXP_CANT_INTERPRET)
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
cmp = v->toInteger(); cmp = (int)v->toInteger();
if (cmp == 0) if (cmp == 0)
break; break;
} }
@@ -896,11 +835,6 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2)
cmp = 0; cmp = 0;
} }
} }
#if 0 // Should handle this
else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
{
}
#endif
else if (e1->isConst() != 1 || e2->isConst() != 1) else if (e1->isConst() != 1 || e2->isConst() != 1)
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
else if (e1->type->isreal()) else if (e1->type->isreal())
@@ -914,9 +848,6 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2)
r1 = e1->toImaginary(); r1 = e1->toImaginary();
r2 = e2->toImaginary(); r2 = e2->toImaginary();
L1: L1:
#if __DMC__
cmp = (r1 == r2);
#else
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{ {
cmp = 0; cmp = 0;
@@ -925,7 +856,6 @@ Expression *Equal(TOK op, Type *type, Expression *e1, Expression *e2)
{ {
cmp = (r1 == r2); cmp = (r1 == r2);
} }
#endif
} }
else if (e1->type->iscomplex()) else if (e1->type->iscomplex())
{ {
@@ -1046,30 +976,8 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2)
r1 = e1->toImaginary(); r1 = e1->toImaginary();
r2 = e2->toImaginary(); r2 = e2->toImaginary();
L1: L1:
#if __DMC__
// DMC is the only compiler I know of that handles NAN arguments
// correctly in comparisons.
switch (op)
{
case TOKlt: n = r1 < r2; break;
case TOKle: n = r1 <= r2; break;
case TOKgt: n = r1 > r2; break;
case TOKge: n = r1 >= r2; break;
case TOKleg: n = r1 <>= r2; break;
case TOKlg: n = r1 <> r2; break;
case TOKunord: n = r1 !<>= r2; break;
case TOKue: n = r1 !<> r2; break;
case TOKug: n = r1 !<= r2; break;
case TOKuge: n = r1 !< r2; break;
case TOKul: n = r1 !>= r2; break;
case TOKule: n = r1 !> r2; break;
default:
assert(0);
}
#else
// Don't rely on compiler, handle NAN arguments separately // Don't rely on compiler, handle NAN arguments separately
// (DMC does do it correctly)
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{ {
switch (op) switch (op)
@@ -1114,7 +1022,6 @@ Expression *Cmp(TOK op, Type *type, Expression *e1, Expression *e2)
assert(0); assert(0);
} }
} }
#endif
} }
else if (e1->type->iscomplex()) else if (e1->type->iscomplex())
{ {
@@ -1362,7 +1269,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
} }
else if (e1->op == TOKarrayliteral) else if (e1->op == TOKarrayliteral)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
e = (*ale->elements)[i]; e = (*ale->elements)[(size_t)i];
e->type = type; e->type = type;
e->loc = loc; e->loc = loc;
if (e->hasSideEffect()) if (e->hasSideEffect())
@@ -1381,7 +1288,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
e = new ErrorExp(); e = new ErrorExp();
} }
else else
{ e = (*ale->elements)[i]; { e = (*ale->elements)[(size_t)i];
e->type = type; e->type = type;
e->loc = loc; e->loc = loc;
if (e->hasSideEffect()) if (e->hasSideEffect())
@@ -1401,7 +1308,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
if (ex == EXP_CANT_INTERPRET) if (ex == EXP_CANT_INTERPRET)
return ex; return ex;
if (ex->isBool(TRUE)) if (ex->isBool(true))
{ e = (*ae->values)[i]; { e = (*ae->values)[i];
e->type = type; e->type = type;
e->loc = loc; e->loc = loc;
@@ -1441,8 +1348,8 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
else else
{ {
void *s; void *s;
size_t len = iupr - ilwr; size_t len = (size_t)(iupr - ilwr);
int sz = es1->sz; unsigned char sz = es1->sz;
StringExp *es; StringExp *es;
s = mem.malloc((len + 1) * sz); s = mem.malloc((len + 1) * sz);
@@ -1471,10 +1378,10 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
else else
{ {
Expressions *elements = new Expressions(); Expressions *elements = new Expressions();
elements->setDim(iupr - ilwr); elements->setDim((size_t)(iupr - ilwr));
memcpy(elements->tdata(), memcpy(elements->tdata(),
es1->elements->tdata() + ilwr, es1->elements->tdata() + ilwr,
(iupr - ilwr) * sizeof((*es1->elements)[0])); (size_t)(iupr - ilwr) * sizeof((*es1->elements)[0]));
e = new ArrayLiteralExp(e1->loc, elements); e = new ArrayLiteralExp(e1->loc, elements);
e->type = type; e->type = type;
} }
@@ -1519,8 +1426,8 @@ void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *n
unsigned value = (unsigned)((*newae->elements)[j]->toInteger()); unsigned value = (unsigned)((*newae->elements)[j]->toInteger());
switch (existingSE->sz) switch (existingSE->sz)
{ {
case 1: s[j+firstIndex] = value; break; case 1: s[j+firstIndex] = (utf8_t)value; break;
case 2: ((unsigned short *)s)[j+firstIndex] = value; break; case 2: ((unsigned short *)s)[j+firstIndex] = (unsigned short)value; break;
case 4: ((unsigned *)s)[j+firstIndex] = value; break; case 4: ((unsigned *)s)[j+firstIndex] = value; break;
default: default:
assert(0); assert(0);
@@ -1609,11 +1516,11 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
StringExp *es; StringExp *es;
if (t->nextOf()) if (t->nextOf())
t = t->nextOf()->toBasetype(); t = t->nextOf()->toBasetype();
size_t sz = t->size(); unsigned char sz = (unsigned char)t->size();
dinteger_t v = e->toInteger(); dinteger_t v = e->toInteger();
size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, v); size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, (dchar_t)v);
s = mem.malloc((len + 1) * sz); s = mem.malloc((len + 1) * sz);
if (t->ty == tn->ty) if (t->ty == tn->ty)
#if IN_LLVM #if IN_LLVM
@@ -1627,7 +1534,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
memcpy((utf8_t *)s, &v, sz); memcpy((utf8_t *)s, &v, sz);
#endif #endif
else else
utf_encode(sz, s, v); utf_encode(sz, s, (dchar_t)v);
// Add terminating 0 // Add terminating 0
memset((utf8_t *)s + len * sz, 0, sz); memset((utf8_t *)s + len * sz, 0, sz);
@@ -1672,7 +1579,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
StringExp *es2 = (StringExp *)e2; StringExp *es2 = (StringExp *)e2;
StringExp *es; StringExp *es;
size_t len = es1->len + es2->len; size_t len = es1->len + es2->len;
int sz = es1->sz; unsigned char sz = es1->sz;
if (sz != es2->sz) if (sz != es2->sz)
{ {
@@ -1737,14 +1644,14 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
void *s; void *s;
StringExp *es1 = (StringExp *)e1; StringExp *es1 = (StringExp *)e1;
StringExp *es; StringExp *es;
size_t sz = es1->sz; unsigned char sz = es1->sz;
dinteger_t v = e2->toInteger(); dinteger_t v = e2->toInteger();
// Is it a concatentation of homogenous types? // Is it a concatentation of homogenous types?
// (char[] ~ char, wchar[]~wchar, or dchar[]~dchar) // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar)
bool homoConcat = (sz == t2->size()); bool homoConcat = (sz == t2->size());
size_t len = es1->len; size_t len = es1->len;
len += homoConcat ? 1 : utf_codeLength(sz, v); len += homoConcat ? 1 : utf_codeLength(sz, (dchar_t)v);
s = mem.malloc((len + 1) * sz); s = mem.malloc((len + 1) * sz);
memcpy(s, es1->string, es1->len * sz); memcpy(s, es1->string, es1->len * sz);
@@ -1760,7 +1667,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
memcpy((utf8_t *)s + (sz * es1->len), &v, sz); memcpy((utf8_t *)s + (sz * es1->len), &v, sz);
#endif #endif
else else
utf_encode(sz, (utf8_t *)s + (sz * es1->len), v); utf_encode(sz, (utf8_t *)s + (sz * es1->len), (dchar_t)v);
// Add terminating 0 // Add terminating 0
memset((utf8_t *)s + len * sz, 0, sz); memset((utf8_t *)s + len * sz, 0, sz);
@@ -1778,7 +1685,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
StringExp *es2 = (StringExp *)e2; StringExp *es2 = (StringExp *)e2;
StringExp *es; StringExp *es;
size_t len = 1 + es2->len; size_t len = 1 + es2->len;
int sz = es2->sz; unsigned char sz = es2->sz;
dinteger_t v = e1->toInteger(); dinteger_t v = e1->toInteger();
s = mem.malloc((len + 1) * sz); s = mem.malloc((len + 1) * sz);
@@ -1917,7 +1824,7 @@ Expression *Ptr(Type *type, Expression *e1)
{ AddrExp *ade = (AddrExp *)ae->e1; { AddrExp *ade = (AddrExp *)ae->e1;
if (ade->e1->op == TOKstructliteral) if (ade->e1->op == TOKstructliteral)
{ StructLiteralExp *se = (StructLiteralExp *)ade->e1; { StructLiteralExp *se = (StructLiteralExp *)ade->e1;
unsigned offset = ae->e2->toInteger(); unsigned offset = (unsigned)ae->e2->toInteger();
Expression *e = se->getField(type, offset); Expression *e = se->getField(type, offset);
if (!e) if (!e)
e = EXP_CANT_INTERPRET; e = EXP_CANT_INTERPRET;
+1 -1
View File
@@ -127,7 +127,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
/// Create a string literal consisting of 'value' duplicated 'dim' times. /// Create a string literal consisting of 'value' duplicated 'dim' times.
StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type, StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
unsigned value, size_t dim, int sz); unsigned value, size_t dim, unsigned char sz);
/* Set dest = src, where both dest and src are container value literals /* Set dest = src, where both dest and src are container value literals
+69 -52
View File
@@ -314,12 +314,13 @@ Expression *copyLiteral(Expression *e)
} }
else if (e->op == TOKfunction || e->op == TOKdelegate else if (e->op == TOKfunction || e->op == TOKdelegate
|| e->op == TOKsymoff || e->op == TOKnull || e->op == TOKsymoff || e->op == TOKnull
|| e->op == TOKvar || e->op == TOKvar || e->op == TOKdotvar
|| e->op == TOKint64 || e->op == TOKfloat64 || e->op == TOKint64 || e->op == TOKfloat64
|| e->op == TOKchar || e->op == TOKcomplex80 || e->op == TOKchar || e->op == TOKcomplex80
|| e->op == TOKvoid) || e->op == TOKvoid)
{ // Simple value types {
Expression *r = e->syntaxCopy(); // Simple value types
Expression *r = e->copy(); // keep e1 for DelegateExp and DotVarExp
r->type = e->type; r->type = e->type;
return r; return r;
} }
@@ -331,12 +332,14 @@ Expression *copyLiteral(Expression *e)
else if (e->op == TOKindex) else if (e->op == TOKindex)
r = new IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2); r = new IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2);
else if (e->op == TOKdotvar) else if (e->op == TOKdotvar)
{
#if DMDV2 #if DMDV2
r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1,
((DotVarExp *)e)->var, ((DotVarExp *)e)->hasOverloads); ((DotVarExp *)e)->var, ((DotVarExp *)e)->hasOverloads);
#else #else
r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, ((DotVarExp *)e)->var); r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, ((DotVarExp *)e)->var);
#endif #endif
}
else else
assert(0); assert(0);
r->type = e->type; r->type = e->type;
@@ -470,7 +473,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
{ {
// If it is a multidimensional array literal, do it recursively // If it is a multidimensional array literal, do it recursively
elem = createBlockDuplicatedArrayLiteral(loc, type->nextOf(), elem, elem = createBlockDuplicatedArrayLiteral(loc, type->nextOf(), elem,
((TypeSArray *)type->nextOf())->dim->toInteger()); (size_t)((TypeSArray *)type->nextOf())->dim->toInteger());
} }
bool mustCopy = needToCopyLiteral(elem); bool mustCopy = needToCopyLiteral(elem);
for (size_t i = 0; i < dim; i++) for (size_t i = 0; i < dim; i++)
@@ -489,15 +492,15 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
* Create a string literal consisting of 'value' duplicated 'dim' times. * Create a string literal consisting of 'value' duplicated 'dim' times.
*/ */
StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type, StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
unsigned value, size_t dim, int sz) unsigned value, size_t dim, unsigned char sz)
{ {
utf8_t *s = (utf8_t *)mem.calloc(dim + 1, sz); utf8_t *s = (utf8_t *)mem.calloc(dim + 1, sz);
for (size_t elemi = 0; elemi < dim; ++elemi) for (size_t elemi = 0; elemi < dim; ++elemi)
{ {
switch (sz) switch (sz)
{ {
case 1: s[elemi] = value; break; case 1: s[elemi] = (utf8_t)value; break;
case 2: ((unsigned short *)s)[elemi] = value; break; case 2: ((unsigned short *)s)[elemi] = (unsigned short)value; break;
case 4: ((unsigned *)s)[elemi] = value; break; case 4: ((unsigned *)s)[elemi] = value; break;
default: assert(0); default: assert(0);
} }
@@ -568,10 +571,10 @@ bool isPointer(Type *t)
return tb->ty == Tpointer && tb->nextOf()->ty != Tfunction; return tb->ty == Tpointer && tb->nextOf()->ty != Tfunction;
} }
// For CTFE only. Returns true if 'e' is TRUE or a non-null pointer. // For CTFE only. Returns true if 'e' is true or a non-null pointer.
int isTrueBool(Expression *e) int isTrueBool(Expression *e)
{ {
return e->isBool(TRUE) || ((e->type->ty == Tpointer || e->type->ty == Tclass) return e->isBool(true) || ((e->type->ty == Tpointer || e->type->ty == Tclass)
&& e->op != TOKnull); && e->op != TOKnull);
} }
@@ -786,7 +789,7 @@ int comparePointers(Loc loc, TOK op, Type *type, Expression *agg1, dinteger_t of
{ {
if ( pointToSameMemoryBlock(agg1, agg2) ) if ( pointToSameMemoryBlock(agg1, agg2) )
{ {
dinteger_t n; int n;
switch(op) switch(op)
{ {
case TOKlt: n = (ofs1 < ofs2); break; case TOKlt: n = (ofs1 < ofs2); break;
@@ -880,7 +883,7 @@ Expression *paintFloatInt(Expression *fromVal, Type *to)
} }
else else
{ {
u.x = fromVal->toInteger(); u.x = (d_int32)fromVal->toInteger();
return new RealExp(fromVal->loc, ldouble(u.f), to); return new RealExp(fromVal->loc, ldouble(u.f), to);
} }
} }
@@ -1128,6 +1131,7 @@ bool isCtfeComparable(Expression *e)
x->op != TOKdelegate && x->op != TOKdelegate &&
x->op != TOKarrayliteral && x->op != TOKarrayliteral &&
x->op != TOKstructliteral && x->op != TOKstructliteral &&
x->op != TOKassocarrayliteral &&
x->op != TOKclassreference) x->op != TOKclassreference)
{ {
return false; return false;
@@ -1191,29 +1195,7 @@ int intSignedCmp(TOK op, sinteger_t n1, sinteger_t n2)
int realCmp(TOK op, real_t r1, real_t r2) int realCmp(TOK op, real_t r1, real_t r2)
{ {
int n; int n;
#if __DMC__
// DMC is the only compiler I know of that handles NAN arguments
// correctly in comparisons.
switch (op)
{
case TOKlt: n = r1 < r2; break;
case TOKle: n = r1 <= r2; break;
case TOKgt: n = r1 > r2; break;
case TOKge: n = r1 >= r2; break;
case TOKleg: n = r1 <>= r2; break;
case TOKlg: n = r1 <> r2; break;
case TOKunord: n = r1 !<>= r2; break;
case TOKue: n = r1 !<> r2; break;
case TOKug: n = r1 !<= r2; break;
case TOKuge: n = r1 !< r2; break;
case TOKul: n = r1 !>= r2; break;
case TOKule: n = r1 !> r2; break;
default:
assert(0);
}
#else
// Don't rely on compiler, handle NAN arguments separately // Don't rely on compiler, handle NAN arguments separately
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{ {
@@ -1259,7 +1241,6 @@ int realCmp(TOK op, real_t r1, real_t r2)
assert(0); assert(0);
} }
} }
#endif
return n; return n;
} }
@@ -1294,11 +1275,11 @@ int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len)
// Now both must be either TOKarrayliteral or TOKstring // Now both must be either TOKarrayliteral or TOKstring
if (se1 && se2) if (se1 && se2)
return sliceCmpStringWithString(se1, se2, lo1, lo2, len); return sliceCmpStringWithString(se1, se2, (size_t)lo1, (size_t)lo2, (size_t)len);
if (se1 && ae2) if (se1 && ae2)
return sliceCmpStringWithArray(se1, ae2, lo1, lo2, len); return sliceCmpStringWithArray(se1, ae2, (size_t)lo1, (size_t)lo2, (size_t)len);
if (se2 && ae1) if (se2 && ae1)
return -sliceCmpStringWithArray(se2, ae1, lo2, lo1, len); return -sliceCmpStringWithArray(se2, ae1, (size_t)lo2, (size_t)lo1, (size_t)len);
assert (ae1 && ae2); assert (ae1 && ae2);
// Comparing two array literals. This case is potentially recursive. // Comparing two array literals. This case is potentially recursive.
@@ -1306,8 +1287,8 @@ int ctfeCmpArrays(Loc loc, Expression *e1, Expression *e2, uinteger_t len)
// a full cmp. // a full cmp.
bool needCmp = ae1->type->nextOf()->isintegral(); bool needCmp = ae1->type->nextOf()->isintegral();
for (size_t i = 0; i < len; i++) for (size_t i = 0; i < len; i++)
{ Expression *ee1 = (*ae1->elements)[lo1 + i]; { Expression *ee1 = (*ae1->elements)[(size_t)(lo1 + i)];
Expression *ee2 = (*ae2->elements)[lo2 + i]; Expression *ee2 = (*ae2->elements)[(size_t)(lo2 + i)];
if (needCmp) if (needCmp)
{ sinteger_t c = ee1->toInteger() - ee2->toInteger(); { sinteger_t c = ee1->toInteger() - ee2->toInteger();
if (c > 0) if (c > 0)
@@ -1418,7 +1399,7 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
if (res != 0) if (res != 0)
return res; return res;
} }
return len1 - len2; return (int)(len1 - len2);
} }
if (e1->type->isintegral()) if (e1->type->isintegral())
{ {
@@ -1437,9 +1418,6 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
r1 = e1->toImaginary(); r1 = e1->toImaginary();
r2 = e2->toImaginary(); r2 = e2->toImaginary();
L1: L1:
#if __DMC__
return (r1 != r2);
#else
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{ {
return 1; return 1;
@@ -1448,7 +1426,6 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
{ {
return (r1 != r2); return (r1 != r2);
} }
#endif
} }
else if (e1->type->iscomplex()) else if (e1->type->iscomplex())
{ {
@@ -1486,6 +1463,43 @@ int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2)
return 0; // All elements are equal return 0; // All elements are equal
} }
} }
if (e1->op == TOKassocarrayliteral && e2->op == TOKassocarrayliteral)
{
AssocArrayLiteralExp *es1 = (AssocArrayLiteralExp *)e1;
AssocArrayLiteralExp *es2 = (AssocArrayLiteralExp *)e2;
int dim = es1->keys->dim;
if (es2->keys->dim != dim)
return 1;
bool *used = (bool *)mem.malloc(sizeof(bool) * dim);
memset(used, 0, sizeof(bool) * dim);
for (size_t i = 0; i < dim; ++i)
{
Expression *k1 = (*es1->keys)[i];
Expression *v1 = (*es1->values)[i];
for (size_t j = 0; j < dim; ++j)
{
if (used[j])
continue;
Expression *k2 = (*es2->keys)[j];
Expression *v2 = (*es2->values)[j];
if (ctfeRawCmp(loc, k1, k2))
continue;
used[j] = true;
if (ctfeRawCmp(loc, v1, v2))
{
mem.free(used);
return 1;
}
}
}
mem.free(used);
return 0;
}
error(loc, "CTFE internal error: bad compare"); error(loc, "CTFE internal error: bad compare");
assert(0); assert(0);
return 0; return 0;
@@ -1601,7 +1615,7 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
StringExp *es1 = (StringExp *)e2; StringExp *es1 = (StringExp *)e2;
ArrayLiteralExp *es2 = (ArrayLiteralExp *)e1; ArrayLiteralExp *es2 = (ArrayLiteralExp *)e1;
size_t len = es1->len + es2->elements->dim; size_t len = es1->len + es2->elements->dim;
int sz = es1->sz; unsigned char sz = es1->sz;
void *s = mem.malloc((len + 1) * sz); void *s = mem.malloc((len + 1) * sz);
memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz); memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz);
@@ -1641,7 +1655,7 @@ Expression *ctfeCat(Type *type, Expression *e1, Expression *e2)
StringExp *es1 = (StringExp *)e1; StringExp *es1 = (StringExp *)e1;
ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
size_t len = es1->len + es2->elements->dim; size_t len = es1->len + es2->elements->dim;
int sz = es1->sz; unsigned char sz = es1->sz;
void *s = mem.malloc((len + 1) * sz); void *s = mem.malloc((len + 1) * sz);
memcpy(s, es1->string, es1->len * sz); memcpy(s, es1->string, es1->len * sz);
@@ -1746,7 +1760,7 @@ Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx)
error(loc, "array index %llu is out of bounds %s[0 .. %llu]", indx, e1->toChars(), (ulonglong)ale->elements->dim); error(loc, "array index %llu is out of bounds %s[0 .. %llu]", indx, e1->toChars(), (ulonglong)ale->elements->dim);
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
} }
Expression *e = (*ale->elements)[indx]; Expression *e = (*ale->elements)[(size_t)indx];
return paintTypeOntoLiteral(type, e); return paintTypeOntoLiteral(type, e);
} }
@@ -1949,7 +1963,7 @@ Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
// Resolve slices // Resolve slices
size_t indxlo = 0; size_t indxlo = 0;
if (oldval->op == TOKslice) if (oldval->op == TOKslice)
{ indxlo = ((SliceExp *)oldval)->lwr->toInteger(); { indxlo = (size_t)((SliceExp *)oldval)->lwr->toInteger();
oldval = ((SliceExp *)oldval)->e1; oldval = ((SliceExp *)oldval)->e1;
} }
size_t copylen = oldlen < newlen ? oldlen : newlen; size_t copylen = oldlen < newlen ? oldlen : newlen;
@@ -1963,9 +1977,9 @@ Expression *changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
{ {
switch (oldse->sz) switch (oldse->sz)
{ {
case 1: s[indxlo + elemi] = defaultValue; break; case 1: s[(size_t)(indxlo + elemi)] = (utf8_t)defaultValue; break;
case 2: ((unsigned short *)s)[indxlo + elemi] = defaultValue; break; case 2: ((unsigned short *)s)[(size_t)(indxlo + elemi)] = (unsigned short)defaultValue; break;
case 4: ((unsigned *)s)[indxlo + elemi] = defaultValue; break; case 4: ((unsigned *)s)[(size_t)(indxlo + elemi)] = defaultValue; break;
default: assert(0); default: assert(0);
} }
} }
@@ -2069,6 +2083,9 @@ bool isCtfeValueValid(Expression *newval)
if (newval->op == TOKfunction) if (newval->op == TOKfunction)
return true; // function literal or delegate literal return true; // function literal or delegate literal
if (newval->op == TOKvector)
return true; // vector literal
if (newval->op == TOKdelegate) if (newval->op == TOKdelegate)
{ {
Expression *dge = ((DelegateExp *)newval)->e1; Expression *dge = ((DelegateExp *)newval)->e1;
@@ -2254,7 +2271,7 @@ Expression *TypeSArray::voidInitLiteral(VarDeclaration *var)
bool mustCopy = (elem->op == TOKarrayliteral || elem->op == TOKstructliteral); bool mustCopy = (elem->op == TOKarrayliteral || elem->op == TOKstructliteral);
Expressions *elements = new Expressions(); Expressions *elements = new Expressions();
size_t d = dim->toInteger(); size_t d = (size_t)dim->toInteger();
elements->setDim(d); elements->setDim(d);
for (size_t i = 0; i < d; i++) for (size_t i = 0; i < d; i++)
{ if (mustCopy && i > 0) { if (mustCopy && i > 0)
+72 -265
View File
@@ -27,8 +27,6 @@
#include "ctfe.h" #include "ctfe.h"
#include "target.h" #include "target.h"
AggregateDeclaration *isAggregate(Type *t); // from opover.c
void checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad) void checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad)
{ {
if (!ad->isNested()) if (!ad->isNested())
@@ -99,7 +97,7 @@ const char *Declaration::kind()
unsigned Declaration::size(Loc loc) unsigned Declaration::size(Loc loc)
{ {
assert(type); assert(type);
return type->size(); return (unsigned)type->size();
} }
bool Declaration::isDelete() bool Declaration::isDelete()
@@ -132,8 +130,6 @@ PROT Declaration::prot()
* Issue error if not. * Issue error if not.
*/ */
#if DMDV2
int Declaration::checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag) int Declaration::checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag)
{ {
VarDeclaration *v = isVarDeclaration(); VarDeclaration *v = isVarDeclaration();
@@ -161,14 +157,13 @@ int Declaration::checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int fl
} }
return 1; return 1;
} }
#endif
Dsymbol *Declaration::search(Loc loc, Identifier *ident, int flags) Dsymbol *Declaration::search(Loc loc, Identifier *ident, int flags)
{ {
Dsymbol *s = Dsymbol::search(loc, ident, flags); Dsymbol *s = Dsymbol::search(loc, ident, flags);
if (!s && type) if (!s && type)
{ {
s = type->toDsymbol(NULL); s = type->toDsymbol(scope);
if (s) if (s)
s = s->search(loc, ident, flags); s = s->search(loc, ident, flags);
} }
@@ -359,9 +354,7 @@ void TypedefDeclaration::semantic(Scope *sc)
return; return;
} }
sem = SemanticDone; sem = SemanticDone;
#if DMDV2
type = type->addStorageClass(storage_class); type = type->addStorageClass(storage_class);
#endif
Type *savedtype = type; Type *savedtype = type;
type = type->semantic(loc, sc); type = type->semantic(loc, sc);
if (sc->parent->isFuncDeclaration() && init) if (sc->parent->isFuncDeclaration() && init)
@@ -379,6 +372,8 @@ void TypedefDeclaration::semantic(Scope *sc)
else if (sem == SemanticIn) else if (sem == SemanticIn)
{ {
error("circular definition"); error("circular definition");
basetype = Type::terror;
errors = true;
} }
} }
@@ -387,6 +382,7 @@ void TypedefDeclaration::semantic2(Scope *sc)
//printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
if (sem == SemanticDone) if (sem == SemanticDone)
{ sem = Semantic2Done; { sem = Semantic2Done;
basetype->alignment(); // used to detect circular typedef declarations
if (init) if (init)
{ {
Initializer *savedinit = init; Initializer *savedinit = init;
@@ -508,11 +504,6 @@ void AliasDeclaration::semantic(Scope *sc)
} }
this->inSemantic = true; this->inSemantic = true;
#if DMDV1 // don't really know why this is here
if (storage_class & STCconst)
error("cannot be const");
#endif
storage_class |= sc->stc & STCdeprecated; storage_class |= sc->stc & STCdeprecated;
protection = sc->protection; protection = sc->protection;
userAttributes = sc->userAttributes; userAttributes = sc->userAttributes;
@@ -545,14 +536,9 @@ void AliasDeclaration::semantic(Scope *sc)
s = NULL; s = NULL;
type = Type::terror; type = Type::terror;
} }
if (s if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()))
#if DMDV2
&& ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
#endif
)
goto L2; // it's a symbolic alias goto L2; // it's a symbolic alias
#if DMDV2
type = type->addStorageClass(storage_class); type = type->addStorageClass(storage_class);
if (storage_class & (STCref | STCnothrow | STCpure | STCdisable)) if (storage_class & (STCref | STCnothrow | STCpure | STCdisable))
{ // For 'ref' to be attached to function types, and picked { // For 'ref' to be attached to function types, and picked
@@ -563,7 +549,6 @@ void AliasDeclaration::semantic(Scope *sc)
sc = sc->pop(); sc = sc->pop();
} }
else else
#endif
type->resolve(loc, sc, &e, &t, &s); type->resolve(loc, sc, &e, &t, &s);
if (s) if (s)
{ {
@@ -730,38 +715,18 @@ Dsymbol *AliasDeclaration::toAlias()
void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ {
buf->writestring("alias "); buf->writestring("alias ");
#if 0 if (aliassym)
if (hgs->hdrgen)
{ {
if (haliassym)
{
#if IN_LLVM #if IN_LLVM
buf->writestring(haliassym->toChars()); buf->writestring(aliassym->toChars());
#else #else
haliassym->toCBuffer(buf, hgs); aliassym->toCBuffer(buf, hgs);
#endif #endif
buf->writeByte(' '); buf->writeByte(' ');
buf->writestring(ident->toChars()); buf->writestring(ident->toChars());
}
else
htype->toCBuffer(buf, ident, hgs);
} }
else else
#endif type->toCBuffer(buf, ident, hgs);
{
if (aliassym)
{
#if IN_LLVM
buf->writestring(aliassym->toChars());
#else
aliassym->toCBuffer(buf, hgs);
#endif
buf->writeByte(' ');
buf->writestring(ident->toChars());
}
else
type->toCBuffer(buf, ident, hgs);
}
buf->writeByte(';'); buf->writeByte(';');
buf->writenl(); buf->writenl();
} }
@@ -786,27 +751,19 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
this->loc = loc; this->loc = loc;
offset = 0; offset = 0;
noscope = 0; noscope = 0;
#if DMDV2 isargptr = false;
isargptr = FALSE;
#endif
#if DMDV1
nestedref = 0;
#endif
alignment = 0; alignment = 0;
ctorinit = 0; ctorinit = 0;
aliassym = NULL; aliassym = NULL;
onstack = 0; onstack = 0;
canassign = 0; canassign = 0;
lastVar = NULL;
ctfeAdrOnStack = -1; ctfeAdrOnStack = -1;
#if DMDV2
rundtor = NULL; rundtor = NULL;
edtor = NULL; edtor = NULL;
#endif
#if IN_LLVM #if IN_LLVM
aggrIndex = 0; aggrIndex = 0;
nakedUse = false; nakedUse = false;
availableExternally = true; // assume this unless proven otherwise availableExternally = true; // assume this unless proven otherwise
#endif #endif
} }
@@ -873,7 +830,8 @@ void VarDeclaration::semantic(Scope *sc)
Scope *scx = NULL; Scope *scx = NULL;
if (scope) if (scope)
{ sc = scope; {
sc = scope;
scx = sc; scx = sc;
scope = NULL; scope = NULL;
} }
@@ -894,17 +852,19 @@ void VarDeclaration::semantic(Scope *sc)
*/ */
int inferred = 0; int inferred = 0;
if (!type) if (!type)
{ inuse++; {
inuse++;
// Infering the type requires running semantic, // Infering the type requires running semantic,
// so mark the scope as ctfe if required // so mark the scope as ctfe if required
bool needctfe = (storage_class & (STCmanifest | STCstatic)); bool needctfe = (storage_class & (STCmanifest | STCstatic)) != 0;
if (needctfe) sc = sc->startCTFE(); if (needctfe) sc = sc->startCTFE();
//printf("inferring type for %s with init %s\n", toChars(), init->toChars()); //printf("inferring type for %s with init %s\n", toChars(), init->toChars());
ArrayInitializer *ai = init->isArrayInitializer(); ArrayInitializer *ai = init->isArrayInitializer();
if (ai) if (ai)
{ Expression *e; {
Expression *e;
if (ai->isAssociativeArray()) if (ai->isAssociativeArray())
e = ai->toAssocArrayLiteral(); e = ai->toAssocArrayLiteral();
else else
@@ -931,7 +891,8 @@ void VarDeclaration::semantic(Scope *sc)
inferred = 1; inferred = 1;
if (init->isArrayInitializer() && type->toBasetype()->ty == Tsarray) if (init->isArrayInitializer() && type->toBasetype()->ty == Tsarray)
{ // Prefer array literals to give a T[] type rather than a T[dim] {
// Prefer array literals to give a T[] type rather than a T[dim]
type = type->toBasetype()->nextOf()->arrayOf(); type = type->toBasetype()->nextOf()->arrayOf();
} }
@@ -942,7 +903,8 @@ void VarDeclaration::semantic(Scope *sc)
originalType = type->syntaxCopy(); originalType = type->syntaxCopy();
} }
else else
{ if (!originalType) {
if (!originalType)
originalType = type->syntaxCopy(); originalType = type->syntaxCopy();
inuse++; inuse++;
type = type->semantic(loc, sc); type = type->semantic(loc, sc);
@@ -966,7 +928,6 @@ void VarDeclaration::semantic(Scope *sc)
//printf("sc->stc = %x\n", sc->stc); //printf("sc->stc = %x\n", sc->stc);
//printf("storage_class = x%x\n", storage_class); //printf("storage_class = x%x\n", storage_class);
#if DMDV2
// Safety checks // Safety checks
if (sc->func && !sc->intypeof) if (sc->func && !sc->intypeof)
{ {
@@ -994,10 +955,8 @@ void VarDeclaration::semantic(Scope *sc)
} }
} }
} }
#endif
Dsymbol *parent = toParent(); Dsymbol *parent = toParent();
FuncDeclaration *fd = parent->isFuncDeclaration();
Type *tb = type->toBasetype(); Type *tb = type->toBasetype();
Type *tbn = tb->baseElemOf(); Type *tbn = tb->baseElemOf();
@@ -1014,13 +973,14 @@ void VarDeclaration::semantic(Scope *sc)
tb = type; tb = type;
} }
if (tb->ty == Tfunction) if (tb->ty == Tfunction)
{ error("cannot be declared to be a function"); {
error("cannot be declared to be a function");
type = Type::terror; type = Type::terror;
tb = type; tb = type;
} }
if (tb->ty == Tstruct) if (tb->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tb; {
TypeStruct *ts = (TypeStruct *)tb;
if (!ts->sym->members) if (!ts->sym->members)
{ {
error("no definition of struct %s", ts->toChars()); error("no definition of struct %s", ts->toChars());
@@ -1030,13 +990,12 @@ void VarDeclaration::semantic(Scope *sc)
error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?");
if (tb->ty == Ttuple) if (tb->ty == Ttuple)
{ /* Instead, declare variables for each of the tuple elements {
/* Instead, declare variables for each of the tuple elements
* and add those. * and add those.
*/ */
TypeTuple *tt = (TypeTuple *)tb; TypeTuple *tt = (TypeTuple *)tb;
size_t nelems = Parameter::dim(tt->arguments); size_t nelems = Parameter::dim(tt->arguments);
Objects *exps = new Objects();
exps->setDim(nelems);
Expression *ie = (init && !init->isVoidInitializer()) ? init->toExpression() : NULL; Expression *ie = (init && !init->isVoidInitializer()) ? init->toExpression() : NULL;
if (ie) ie = ie->semantic(sc); if (ie) ie = ie->semantic(sc);
@@ -1081,7 +1040,7 @@ void VarDeclaration::semantic(Scope *sc)
Identifier *id = Lexer::uniqueId("__tup"); Identifier *id = Lexer::uniqueId("__tup");
ExpInitializer *ei = new ExpInitializer(e->loc, e); ExpInitializer *ei = new ExpInitializer(e->loc, e);
VarDeclaration *v = new VarDeclaration(loc, NULL, id, ei); VarDeclaration *v = new VarDeclaration(loc, NULL, id, ei);
v->storage_class = STCctfe | STCref | STCforeach; v->storage_class = STCtemp | STCctfe | STCref | STCforeach;
VarExp *ve = new VarExp(loc, v); VarExp *ve = new VarExp(loc, v);
ve->type = e->type; ve->type = e->type;
@@ -1093,7 +1052,7 @@ void VarDeclaration::semantic(Scope *sc)
{ {
Lexpand2: Lexpand2:
Expression *ee = (*exps)[u]; Expression *ee = (*exps)[u];
Parameter *arg = Parameter::getNth(tt->arguments, pos + u); arg = Parameter::getNth(tt->arguments, pos + u);
arg->type = arg->type->semantic(loc, sc); arg->type = arg->type->semantic(loc, sc);
//printf("[%d+%d] exps->dim = %d, ", pos, u, exps->dim); //printf("[%d+%d] exps->dim = %d, ", pos, u, exps->dim);
//printf("ee = (%s %s, %s), ", Token::tochars[ee->op], ee->toChars(), ee->type->toChars()); //printf("ee = (%s %s, %s), ", Token::tochars[ee->op], ee->toChars(), ee->type->toChars());
@@ -1133,12 +1092,15 @@ Lnomatch:
TupleExp *te = (TupleExp *)ie; TupleExp *te = (TupleExp *)ie;
size_t tedim = te->exps->dim; size_t tedim = te->exps->dim;
if (tedim != nelems) if (tedim != nelems)
{ ::error(loc, "tuple of %d elements cannot be assigned to tuple of %d elements", (int)tedim, (int)nelems); {
::error(loc, "tuple of %d elements cannot be assigned to tuple of %d elements", (int)tedim, (int)nelems);
for (size_t u = tedim; u < nelems; u++) // fill dummy expression for (size_t u = tedim; u < nelems; u++) // fill dummy expression
te->exps->push(new ErrorExp()); te->exps->push(new ErrorExp());
} }
} }
Objects *exps = new Objects();
exps->setDim(nelems);
for (size_t i = 0; i < nelems; i++) for (size_t i = 0; i < nelems; i++)
{ {
Parameter *arg = Parameter::getNth(tt->arguments, i); Parameter *arg = Parameter::getNth(tt->arguments, i);
@@ -1166,7 +1128,7 @@ Lnomatch:
ti = init ? init->syntaxCopy() : NULL; ti = init ? init->syntaxCopy() : NULL;
VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
v->storage_class |= storage_class; v->storage_class |= STCtemp | storage_class;
if (arg->storageClass & STCparameter) if (arg->storageClass & STCparameter)
v->storage_class |= arg->storageClass; v->storage_class |= arg->storageClass;
//printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
@@ -1176,7 +1138,8 @@ Lnomatch:
// removed for LDC since TupleDeclaration::toObj already creates the fields; // removed for LDC since TupleDeclaration::toObj already creates the fields;
// adding them to the scope again leads to duplicates // adding them to the scope again leads to duplicates
if (sc->scopesym) if (sc->scopesym)
{ //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); {
//printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
if (sc->scopesym->members) if (sc->scopesym->members)
sc->scopesym->members->push(v); sc->scopesym->members->push(v);
} }
@@ -1247,14 +1210,12 @@ Lnomatch:
fprintf(global.stdmsg, "%s: %s.%s is %s field\n", p ? p : "", ad->toPrettyChars(), toChars(), s); fprintf(global.stdmsg, "%s: %s.%s is %s field\n", p ? p : "", ad->toPrettyChars(), toChars(), s);
} }
storage_class |= STCfield; storage_class |= STCfield;
#if DMDV2
if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor || if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor ||
tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor) tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor)
{ {
if (!isThisDeclaration()) if (!isThisDeclaration() && !init)
aad->noDefaultCtor = TRUE; aad->noDefaultCtor = true;
} }
#endif
#else #else
if (storage_class & (STCconst | STCimmutable) && init) if (storage_class & (STCconst | STCimmutable) && init)
{ {
@@ -1267,14 +1228,12 @@ Lnomatch:
else else
{ {
storage_class |= STCfield; storage_class |= STCfield;
#if DMDV2
if ((tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor) || if ((tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor) ||
(tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor)) (tbn->ty == Tclass && ((TypeClass *)tbn)->sym->noDefaultCtor))
{ {
if (!isThisDeclaration()) if (!isThisDeclaration() && !init)
aad->noDefaultCtor = TRUE; aad->noDefaultCtor = true;
} }
#endif
} }
#endif #endif
} }
@@ -1308,7 +1267,6 @@ Lnomatch:
} }
} }
#if DMDV2
if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref &&
ident != Id::This) ident != Id::This)
{ {
@@ -1360,8 +1318,8 @@ Lnomatch:
error("default construction is disabled for type %s", type->toChars()); error("default construction is disabled for type %s", type->toChars());
} }
} }
#endif
FuncDeclaration *fd = parent->isFuncDeclaration();
if (type->isscope() && !noscope) if (type->isscope() && !noscope)
{ {
if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd)
@@ -1416,7 +1374,8 @@ Lnomatch:
} }
else if (type->ty == Tstruct && else if (type->ty == Tstruct &&
((TypeStruct *)type)->sym->zeroInit == 1) ((TypeStruct *)type)->sym->zeroInit == 1)
{ /* If a struct is all zeros, as a special case {
/* If a struct is all zeros, as a special case
* set it's initializer to the integer 0. * set it's initializer to the integer 0.
* In AssignExp::toElem(), we check for this and issue * In AssignExp::toElem(), we check for this and issue
* a memset() to initialize the struct. * a memset() to initialize the struct.
@@ -1431,9 +1390,11 @@ Lnomatch:
goto Ldtor; goto Ldtor;
} }
else if (type->ty == Ttypedef) else if (type->ty == Ttypedef)
{ TypeTypedef *td = (TypeTypedef *)type; {
TypeTypedef *td = (TypeTypedef *)type;
if (td->sym->init) if (td->sym->init)
{ init = td->sym->init; {
init = td->sym->init;
ExpInitializer *ie = init->isExpInitializer(); ExpInitializer *ie = init->isExpInitializer();
if (ie) if (ie)
// Make copy so we can modify it // Make copy so we can modify it
@@ -1455,22 +1416,16 @@ Lnomatch:
sc = sc->push(); sc = sc->push();
sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref | STCdisable); sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref | STCdisable);
ArrayInitializer *ai = init->isArrayInitializer();
if (ai && tb->ty == Taarray)
{
Expression *e = ai->toAssocArrayLiteral();
init = new ExpInitializer(e->loc, e);
}
ExpInitializer *ei = init->isExpInitializer(); ExpInitializer *ei = init->isExpInitializer();
if (ei && isScope()) if (ei && isScope())
{ {
// See if initializer is a NewExp that can be allocated on the stack // See if initializer is a NewExp that can be allocated on the stack
if (ei->exp->op == TOKnew) if (ei->exp->op == TOKnew)
{ NewExp *ne = (NewExp *)ei->exp; {
NewExp *ne = (NewExp *)ei->exp;
if (!(ne->newargs && ne->newargs->dim)) if (!(ne->newargs && ne->newargs->dim))
{ ne->onstack = 1; {
ne->onstack = 1;
onstack = 1; onstack = 1;
if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
onstack = 2; onstack = 2;
@@ -1478,7 +1433,8 @@ Lnomatch:
} }
// or a delegate that doesn't escape a reference to the function // or a delegate that doesn't escape a reference to the function
else if (ei->exp->op == TOKfunction) else if (ei->exp->op == TOKfunction)
{ FuncDeclaration *f = ((FuncExp *)ei->exp)->fd; {
FuncDeclaration *f = ((FuncExp *)ei->exp)->fd;
f->tookAddressOf--; f->tookAddressOf--;
} }
} }
@@ -1495,14 +1451,20 @@ Lnomatch:
//printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
if (!ei) if (!ei)
{ {
Expression *e = init->toExpression(); ArrayInitializer *ai = init->isArrayInitializer();
Expression *e;
if (ai && (tb->ty == Taarray || tb->ty == Tstruct && ai->isAssociativeArray()))
e = ai->toAssocArrayLiteral();
else
e = init->toExpression();
if (!e) if (!e)
{ {
// Run semantic, but don't need to interpret // Run semantic, but don't need to interpret
init = init->semantic(sc, type, INITnointerpret); init = init->semantic(sc, type, INITnointerpret);
e = init->toExpression(); e = init->toExpression();
if (!e) if (!e)
{ error("is not a static and cannot have static initializer"); {
error("is not a static and cannot have static initializer");
return; return;
} }
} }
@@ -1511,150 +1473,6 @@ Lnomatch:
} }
Expression *e1 = new VarExp(loc, this); Expression *e1 = new VarExp(loc, this);
Type *t = type->toBasetype();
if (ei && !inferred)
ei->exp = ei->exp->inferType(t);
Linit2:
if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
{
ei->exp = ei->exp->semantic(sc);
if (!ei->exp->implicitConvTo(type))
{
dinteger_t dim = ((TypeSArray *)t)->dim->toInteger();
// If multidimensional static array, treat as one large array
while (1)
{
t = t->nextOf()->toBasetype();
if (t->ty != Tsarray)
break;
dim *= ((TypeSArray *)t)->dim->toInteger();
e1->type = TypeSArray::makeType(Loc(), t->nextOf(), dim);
}
}
e1 = new SliceExp(loc, e1, NULL, NULL);
}
else if (t->ty == Tstruct)
{
ei->exp = ei->exp->semantic(sc);
ei->exp = resolveProperties(sc, ei->exp);
StructDeclaration *sd = ((TypeStruct *)t)->sym;
#if DMDV2
Expression** pinit = &ei->exp;
while ((*pinit)->op == TOKcomma)
{
pinit = &((CommaExp *)*pinit)->e2;
}
/* Look to see if initializer is a call to the constructor
*/
if (sd->ctor && // there are constructors
(*pinit)->type->ty == Tstruct && // rvalue is the same struct
((TypeStruct *)(*pinit)->type)->sym == sd &&
(*pinit)->op == TOKcall)
{
/* Look for form of constructor call which is:
* *__ctmp.ctor(arguments...)
*/
if ((*pinit)->type->implicitConvTo(t))
{ CallExp *ce = (CallExp *)(*pinit);
if (ce->e1->op == TOKdotvar)
{ DotVarExp *dve = (DotVarExp *)ce->e1;
if (dve->var->isCtorDeclaration())
{ /* It's a constructor call, currently constructing
* a temporary __ctmp.
*/
/* Before calling the constructor, initialize
* variable with a bit copy of the default
* initializer
*/
/* Remove ref if this declaration is ref binding.
* ref Type __self = (__ctmp = 0, __ctmp).this(...);
* -> Type __self = (__self = 0, __self.this(...));
*/
storage_class &= ~(STCref | STCforeach | STCparameter);
Expression *e = new VarExp(loc, this);
if (sd->zeroInit == 1)
{
e = new ConstructExp(loc, e, new IntegerExp(loc, 0, Type::tint32));
}
else if (sd->isNested())
{
e = new AssignExp(loc, e, t->defaultInitLiteral(loc));
e->op = TOKblit;
}
else
{
e = new AssignExp(loc, e, t->defaultInit(loc));
e->op = TOKblit;
}
e->type = t;
/* Replace __ctmp being constructed with e1.
* We need to copy constructor call expression,
* because it may be used in other place.
*/
DotVarExp *dvx = (DotVarExp *)dve->copy();
dvx->e1 = e1;
CallExp *cx = (CallExp *)ce->copy();
cx->e1 = dvx;
(*pinit) = new CommaExp(loc, e, cx);
(*pinit) = (*pinit)->semantic(sc);
goto Ldtor;
}
}
}
}
/* Look for ((S tmp = S()),tmp) and replace it with just S()
*/
Expression *e2 = ei->exp->isTemp();
if (e2)
{
ei->exp = e2;
goto Linit2;
}
#endif
if (!ei->exp->implicitConvTo(type))
{
Type *ti = ei->exp->type->toBasetype();
// Look for constructor first
if (sd->ctor &&
/* Initializing with the same type is done differently
*/
!(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
{
// Rewrite as e1.ctor(arguments)
Expression *ector = new DotIdExp(loc, e1, Id::ctor);
ei->exp = new CallExp(loc, ector, ei->exp);
/* Before calling the constructor, initialize
* variable with a bit copy of the default
* initializer
*/
Expression *e = new AssignExp(loc, e1, t->defaultInit(loc));
e->op = TOKblit;
e->type = t;
ei->exp = new CommaExp(loc, e, ei->exp);
}
else
/* Look for static opCall
* See bugzilla 2702 for more discussion
*/
// Don't cast away invariant or mutability in initializer
if (search_function(sd, Id::call) &&
/* Initializing with the same type is done differently
*/
!(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
{ // Rewrite as e1.call(arguments)
Expression *e = typeDotIdExp(ei->exp->loc, t, Id::call);
ei->exp = new CallExp(loc, e, ei->exp);
}
}
}
ei->exp = new AssignExp(loc, e1, ei->exp); ei->exp = new AssignExp(loc, e1, ei->exp);
ei->exp->op = op; ei->exp->op = op;
canassign++; canassign++;
@@ -1685,7 +1503,6 @@ Lnomatch:
{ {
unsigned errors = global.errors; unsigned errors = global.errors;
inuse++; inuse++;
#if DMDV2
if (ei) if (ei)
{ {
Expression *exp = ei->exp->syntaxCopy(); Expression *exp = ei->exp->syntaxCopy();
@@ -1696,7 +1513,7 @@ Lnomatch:
exp = resolveProperties(sc, exp); exp = resolveProperties(sc, exp);
if (needctfe) sc = sc->endCTFE(); if (needctfe) sc = sc->endCTFE();
Type *tb = type->toBasetype(); Type *tb2 = type->toBasetype();
Type *ti = exp->type->toBasetype(); Type *ti = exp->type->toBasetype();
/* The problem is the following code: /* The problem is the following code:
@@ -1717,16 +1534,15 @@ Lnomatch:
* (which implies a postblit) * (which implies a postblit)
*/ */
if (sd->cpctor && // there is a copy constructor if (sd->cpctor && // there is a copy constructor
tb->toDsymbol(NULL) == sd) // exp is the same struct tb2->toDsymbol(NULL) == sd) // exp is the same struct
{ {
// The only allowable initializer is a (non-copy) constructor // The only allowable initializer is a (non-copy) constructor
if (exp->isLvalue()) if (exp->isLvalue())
error("of type struct %s uses this(this), which is not allowed in static initialization", tb->toChars()); error("of type struct %s uses this(this), which is not allowed in static initialization", tb2->toChars());
} }
} }
ei->exp = exp; ei->exp = exp;
} }
#endif
init = init->semantic(sc, type, INITinterpret); init = init->semantic(sc, type, INITinterpret);
inuse--; inuse--;
if (global.errors > errors) if (global.errors > errors)
@@ -1927,7 +1743,7 @@ void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset,
} }
unsigned memsize = t->size(loc); // size of member unsigned memsize = (unsigned)t->size(loc); // size of member
unsigned memalignsize = Target::fieldalign(t); // size of member for alignment purposes unsigned memalignsize = Target::fieldalign(t); // size of member for alignment purposes
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment, offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
@@ -1978,12 +1794,10 @@ void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(ident->toChars()); buf->writestring(ident->toChars());
if (init) if (init)
{ buf->writestring(" = "); { buf->writestring(" = ");
#if DMDV2
ExpInitializer *ie = init->isExpInitializer(); ExpInitializer *ie = init->isExpInitializer();
if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
else else
#endif
init->toCBuffer(buf, hgs); init->toCBuffer(buf, hgs);
} }
buf->writeByte(';'); buf->writeByte(';');
@@ -2106,7 +1920,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
{ {
if (i == fdv->closureVars.dim) if (i == fdv->closureVars.dim)
{ {
fdv->closureVars.push(this); if (!sc->intypeof && !(sc->flags & SCOPEcompile))
fdv->closureVars.push(this);
break; break;
} }
if (fdv->closureVars[i] == this) if (fdv->closureVars[i] == this)
@@ -2440,7 +2255,6 @@ char *TypeInfoDeclaration::toChars()
/***************************** TypeInfoConstDeclaration **********************/ /***************************** TypeInfoConstDeclaration **********************/
#if DMDV2
TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0) : TypeInfoDeclaration(tinfo, 0)
{ {
@@ -2450,11 +2264,9 @@ TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
} }
type = Type::typeinfoconst->type; type = Type::typeinfoconst->type;
} }
#endif
/***************************** TypeInfoInvariantDeclaration **********************/ /***************************** TypeInfoInvariantDeclaration **********************/
#if DMDV2
TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0) : TypeInfoDeclaration(tinfo, 0)
{ {
@@ -2464,11 +2276,9 @@ TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
} }
type = Type::typeinfoinvariant->type; type = Type::typeinfoinvariant->type;
} }
#endif
/***************************** TypeInfoSharedDeclaration **********************/ /***************************** TypeInfoSharedDeclaration **********************/
#if DMDV2
TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0) : TypeInfoDeclaration(tinfo, 0)
{ {
@@ -2478,11 +2288,9 @@ TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
} }
type = Type::typeinfoshared->type; type = Type::typeinfoshared->type;
} }
#endif
/***************************** TypeInfoWildDeclaration **********************/ /***************************** TypeInfoWildDeclaration **********************/
#if DMDV2
TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo) TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0) : TypeInfoDeclaration(tinfo, 0)
{ {
@@ -2492,7 +2300,6 @@ TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
} }
type = Type::typeinfowild->type; type = Type::typeinfowild->type;
} }
#endif
/***************************** TypeInfoStructDeclaration **********************/ /***************************** TypeInfoStructDeclaration **********************/
@@ -2665,4 +2472,4 @@ Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
assert(0); // should never be produced by syntax assert(0); // should never be produced by syntax
return NULL; return NULL;
} }
+14 -36
View File
@@ -91,16 +91,16 @@ enum PURE;
#define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) #define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild)
#define STC_FUNCATTR (STCref | STCnothrow | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) #define STC_FUNCATTR (STCref | STCnothrow | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem)
#define STCproperty 0x100000000LL #define STCproperty 0x100000000LL
#define STCsafe 0x200000000LL #define STCsafe 0x200000000LL
#define STCtrusted 0x400000000LL #define STCtrusted 0x400000000LL
#define STCsystem 0x800000000LL #define STCsystem 0x800000000LL
#define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static #define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static
#define STCdisable 0x2000000000LL // for functions that are not callable #define STCdisable 0x2000000000LL // for functions that are not callable
#define STCresult 0x4000000000LL // for result variables passed to out contracts #define STCresult 0x4000000000LL // for result variables passed to out contracts
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor #define STCnodefaultctor 0x8000000000LL // must be set inside constructor
#define STCtemp 0x10000000000LL // temporary variable introduced by inlining #define STCtemp 0x10000000000LL // temporary variable
// and used only in backend process, so it's rvalue #define STCrvalue 0x20000000000LL // force rvalue for variables
const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias | STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias |
@@ -288,18 +288,15 @@ public:
Initializer *init; Initializer *init;
unsigned offset; unsigned offset;
bool noscope; // no auto semantics bool noscope; // no auto semantics
#if DMDV2
FuncDeclarations nestedrefs; // referenced by these lexically nested functions FuncDeclarations nestedrefs; // referenced by these lexically nested functions
bool isargptr; // if parameter that _argptr points to bool isargptr; // if parameter that _argptr points to
#else
int nestedref; // referenced by a lexically nested function
#endif
structalign_t alignment; structalign_t alignment;
bool ctorinit; // it has been initialized in a ctor bool ctorinit; // it has been initialized in a ctor
short onstack; // 1: it has been allocated on the stack short onstack; // 1: it has been allocated on the stack
// 2: on stack, run destructor anyway // 2: on stack, run destructor anyway
int canassign; // it can be assigned to int canassign; // it can be assigned to
Dsymbol *aliassym; // if redone as alias to another symbol Dsymbol *aliassym; // if redone as alias to another symbol
VarDeclaration *lastVar; // Linked list of variables for goto-skips-init detection
// When interpreting, these point to the value (NULL if value not determinable) // When interpreting, these point to the value (NULL if value not determinable)
// The index of this variable on the CTFE stack, -1 if not allocated // The index of this variable on the CTFE stack, -1 if not allocated
@@ -311,12 +308,10 @@ public:
void setValueWithoutChecking(Expression *newval); void setValueWithoutChecking(Expression *newval);
void setValue(Expression *newval); void setValue(Expression *newval);
#if DMDV2
VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see
// if the destructor should be run. Used to prevent // if the destructor should be run. Used to prevent
// dtor calls on postblitted vars // dtor calls on postblitted vars
Expression *edtor; // if !=NULL, does the destruction of the variable Expression *edtor; // if !=NULL, does the destruction of the variable
#endif
VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
@@ -336,10 +331,8 @@ public:
bool isThreadlocal(); bool isThreadlocal();
bool isCTFE(); bool isCTFE();
bool hasPointers(); bool hasPointers();
#if DMDV2
bool canTakeAddressOf(); bool canTakeAddressOf();
bool needsAutoDtor(); bool needsAutoDtor();
#endif
Expression *callScopeDtor(Scope *sc); Expression *callScopeDtor(Scope *sc);
ExpInitializer *getExpInitializer(); ExpInitializer *getExpInitializer();
Expression *getConstInitializer(bool needFullType = true); Expression *getConstInitializer(bool needFullType = true);
@@ -616,7 +609,6 @@ public:
#endif #endif
}; };
#if DMDV2
class TypeInfoConstDeclaration : public TypeInfoDeclaration class TypeInfoConstDeclaration : public TypeInfoDeclaration
{ {
public: public:
@@ -686,7 +678,6 @@ public:
void llvmDefine(); void llvmDefine();
#endif #endif
}; };
#endif
/**************************************************************/ /**************************************************************/
@@ -706,7 +697,6 @@ enum ILS
}; };
/**************************************************************/ /**************************************************************/
#if DMDV2
enum BUILTIN enum BUILTIN
{ {
@@ -733,9 +723,6 @@ enum BUILTIN
Expression *eval_builtin(Loc loc, BUILTIN builtin, Expressions *arguments); Expression *eval_builtin(Loc loc, BUILTIN builtin, Expressions *arguments);
#else
enum BUILTIN { };
#endif
class FuncDeclaration : public Declaration class FuncDeclaration : public Declaration
{ {
@@ -812,8 +799,8 @@ public:
#endif #endif
ReturnStatements *returns; ReturnStatements *returns;
GotoStatements *gotos; // Gotos with forward references
#if DMDV2
BUILTIN builtin; // set if this is a known, builtin BUILTIN builtin; // set if this is a known, builtin
// function we can evaluate at compile // function we can evaluate at compile
// time // time
@@ -834,9 +821,6 @@ public:
#define FUNCFLAGpurityInprocess 1 // working on determining purity #define FUNCFLAGpurityInprocess 1 // working on determining purity
#define FUNCFLAGsafetyInprocess 2 // working on determining safety #define FUNCFLAGsafetyInprocess 2 // working on determining safety
#define FUNCFLAGnothrowInprocess 4 // working on determining nothrow #define FUNCFLAGnothrowInprocess 4 // working on determining nothrow
#else
int nestedFrameRef; // !=0 if nested variables referenced
#endif
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type); FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
@@ -897,7 +881,7 @@ public:
void ctfeCompile(); void ctfeCompile();
void inlineScan(); void inlineScan();
int canInline(int hasthis, int hdrscan, int statementsToo); int canInline(int hasthis, int hdrscan, int statementsToo);
Expression *expandInline(InlineScanState *iss, Expression *ethis, Expressions *arguments, Statement **ps); Expression *expandInline(InlineScanState *iss, Expression *eret, Expression *ethis, Expressions *arguments, Statement **ps);
const char *kind(); const char *kind();
void toDocBuffer(OutBuffer *buf, Scope *sc); void toDocBuffer(OutBuffer *buf, Scope *sc);
FuncDeclaration *isUnique(); FuncDeclaration *isUnique();
@@ -960,13 +944,11 @@ public:
#endif #endif
}; };
#if DMDV2
FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s, FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
Objects *tiargs, Objects *tiargs,
Type *tthis, Type *tthis,
Expressions *arguments, Expressions *arguments,
int flags = 0); int flags = 0);
#endif
class FuncAliasDeclaration : public FuncDeclaration class FuncAliasDeclaration : public FuncDeclaration
{ {
@@ -1001,6 +983,7 @@ public:
FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
const char *kind(); const char *kind();
const char *toPrettyChars();
#if IN_LLVM #if IN_LLVM
// If this is only used as alias parameter to a template instantiation, // If this is only used as alias parameter to a template instantiation,
@@ -1028,7 +1011,6 @@ public:
CtorDeclaration *isCtorDeclaration() { return this; } CtorDeclaration *isCtorDeclaration() { return this; }
}; };
#if DMDV2
class PostBlitDeclaration : public FuncDeclaration class PostBlitDeclaration : public FuncDeclaration
{ {
public: public:
@@ -1045,7 +1027,6 @@ public:
PostBlitDeclaration *isPostBlitDeclaration() { return this; } PostBlitDeclaration *isPostBlitDeclaration() { return this; }
}; };
#endif
class DtorDeclaration : public FuncDeclaration class DtorDeclaration : public FuncDeclaration
{ {
@@ -1084,7 +1065,6 @@ public:
StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
}; };
#if DMDV2
class SharedStaticCtorDeclaration : public StaticCtorDeclaration class SharedStaticCtorDeclaration : public StaticCtorDeclaration
{ {
public: public:
@@ -1094,7 +1074,6 @@ public:
SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
}; };
#endif
class StaticDtorDeclaration : public FuncDeclaration class StaticDtorDeclaration : public FuncDeclaration
{ {
@@ -1116,7 +1095,6 @@ public:
StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
}; };
#if DMDV2
class SharedStaticDtorDeclaration : public StaticDtorDeclaration class SharedStaticDtorDeclaration : public StaticDtorDeclaration
{ {
public: public:
@@ -1126,7 +1104,6 @@ public:
SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
}; };
#endif
class InvariantDeclaration : public FuncDeclaration class InvariantDeclaration : public FuncDeclaration
{ {
@@ -1155,6 +1132,7 @@ public:
bool addPreInvariant(); bool addPreInvariant();
bool addPostInvariant(); bool addPostInvariant();
void emitComment(Scope *sc); void emitComment(Scope *sc);
void inlineScan();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
UnitTestDeclaration *isUnitTestDeclaration() { return this; } UnitTestDeclaration *isUnitTestDeclaration() { return this; }
+77 -91
View File
@@ -47,10 +47,10 @@ struct Escape
class Section class Section
{ {
public: public:
utf8_t *name; const utf8_t *name;
size_t namelen; size_t namelen;
utf8_t *body; const utf8_t *body;
size_t bodylen; size_t bodylen;
int nooutput; int nooutput;
@@ -86,19 +86,19 @@ struct DocComment
summary(NULL), copyright(NULL), macros(NULL), pmacrotable(NULL), pescapetable(NULL) summary(NULL), copyright(NULL), macros(NULL), pmacrotable(NULL), pescapetable(NULL)
{ } { }
static DocComment *parse(Scope *sc, Dsymbol *s, utf8_t *comment); static DocComment *parse(Scope *sc, Dsymbol *s, const utf8_t *comment);
static void parseMacros(Escape **pescapetable, Macro **pmacrotable, utf8_t *m, size_t mlen); static void parseMacros(Escape **pescapetable, Macro **pmacrotable, const utf8_t *m, size_t mlen);
static void parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t textlen); static void parseEscapes(Escape **pescapetable, const utf8_t *textstart, size_t textlen);
void parseSections(utf8_t *comment); void parseSections(const utf8_t *comment);
void writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf); void writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf);
}; };
int cmp(const char *stringz, void *s, size_t slen); int cmp(const char *stringz, const void *s, size_t slen);
int icmp(const char *stringz, void *s, size_t slen); int icmp(const char *stringz, const void *s, size_t slen);
int isDitto(utf8_t *comment); int isDitto(const utf8_t *comment);
utf8_t *skipwhitespace(utf8_t *p); const utf8_t *skipwhitespace(const utf8_t *p);
size_t skiptoident(OutBuffer *buf, size_t i); size_t skiptoident(OutBuffer *buf, size_t i);
size_t skippastident(OutBuffer *buf, size_t i); size_t skippastident(OutBuffer *buf, size_t i);
size_t skippastURL(OutBuffer *buf, size_t i); size_t skippastURL(OutBuffer *buf, size_t i);
@@ -106,13 +106,13 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset);
void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool anchor = true); void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool anchor = true);
void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset); void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset);
TypeFunction *isTypeFunction(Dsymbol *s); TypeFunction *isTypeFunction(Dsymbol *s);
Parameter *isFunctionParameter(Dsymbol *s, utf8_t *p, size_t len); Parameter *isFunctionParameter(Dsymbol *s, const utf8_t *p, size_t len);
TemplateParameter *isTemplateParameter(Dsymbol *s, utf8_t *p, size_t len); TemplateParameter *isTemplateParameter(Dsymbol *s, const utf8_t *p, size_t len);
int isIdStart(utf8_t *p); int isIdStart(const utf8_t *p);
int isIdTail(utf8_t *p); int isIdTail(const utf8_t *p);
int isIndentWS(utf8_t *p); int isIndentWS(const utf8_t *p);
int utfStride(utf8_t *p); int utfStride(const utf8_t *p);
static const char ddoc_default[] = "\ static const char ddoc_default[] = "\
DDOC = <html><head>\n\ DDOC = <html><head>\n\
@@ -249,7 +249,7 @@ void Module::gendocfile()
mbuf.write(file.buffer, file.len); mbuf.write(file.buffer, file.len);
} }
} }
DocComment::parseMacros(&escapetable, &macrotable, mbuf.data, mbuf.offset); DocComment::parseMacros(&escapetable, &macrotable, (utf8_t *)mbuf.data, mbuf.offset);
Scope *sc = Scope::createGlobal(this); // create root scope Scope *sc = Scope::createGlobal(this); // create root scope
sc->docbuf = &buf; sc->docbuf = &buf;
@@ -305,7 +305,7 @@ void Module::gendocfile()
} }
//printf("BODY= '%.*s'\n", buf.offset, buf.data); //printf("BODY= '%.*s'\n", buf.offset, buf.data);
Macro::define(&macrotable, (utf8_t *)"BODY", 4, buf.data, buf.offset); Macro::define(&macrotable, (utf8_t *)"BODY", 4, (utf8_t *)buf.data, buf.offset);
OutBuffer buf2; OutBuffer buf2;
buf2.writestring("$(DDOC)\n"); buf2.writestring("$(DDOC)\n");
@@ -319,7 +319,7 @@ void Module::gendocfile()
{ {
buf.setsize(0); buf.setsize(0);
buf.reserve(buf2.offset); buf.reserve(buf2.offset);
utf8_t *p = buf2.data; utf8_t *p = (utf8_t *)buf2.data;
for (size_t j = 0; j < buf2.offset; j++) for (size_t j = 0; j < buf2.offset; j++)
{ {
utf8_t c = p[j]; utf8_t c = p[j];
@@ -552,7 +552,7 @@ void emitUnittestComment(Scope *sc, Dsymbol *s, size_t ofs)
continue; continue;
// Strip whitespaces to avoid showing empty summary // Strip whitespaces to avoid showing empty summary
utf8_t *c = utd->comment; const utf8_t *c = utd->comment;
while (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r') ++c; while (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r') ++c;
OutBuffer codebuf; OutBuffer codebuf;
@@ -665,9 +665,7 @@ void emitProtection(OutBuffer *buf, PROT prot)
void Dsymbol::emitComment(Scope *sc) { } void Dsymbol::emitComment(Scope *sc) { }
void InvariantDeclaration::emitComment(Scope *sc) { } void InvariantDeclaration::emitComment(Scope *sc) { }
void UnitTestDeclaration::emitComment(Scope *sc) { } void UnitTestDeclaration::emitComment(Scope *sc) { }
#if DMDV2
void PostBlitDeclaration::emitComment(Scope *sc) { } void PostBlitDeclaration::emitComment(Scope *sc) { }
#endif
void DtorDeclaration::emitComment(Scope *sc) { } void DtorDeclaration::emitComment(Scope *sc) { }
void StaticCtorDeclaration::emitComment(Scope *sc) { } void StaticCtorDeclaration::emitComment(Scope *sc) { }
void StaticDtorDeclaration::emitComment(Scope *sc) { } void StaticDtorDeclaration::emitComment(Scope *sc) { }
@@ -746,7 +744,7 @@ void TemplateDeclaration::emitComment(Scope *sc)
if (prot() == PROTprivate) if (prot() == PROTprivate)
return; return;
utf8_t *com = comment; const utf8_t *com = comment;
int hasmembers = 1; int hasmembers = 1;
Dsymbol *ss = this; Dsymbol *ss = this;
@@ -900,10 +898,8 @@ void prefix(OutBuffer *buf, Dsymbol *s)
{ {
if (d->isConst()) if (d->isConst())
buf->writestring("const "); buf->writestring("const ");
#if DMDV2
if (d->isImmutable()) if (d->isImmutable())
buf->writestring("immutable "); buf->writestring("immutable ");
#endif
if (d->isSynchronized()) if (d->isSynchronized())
buf->writestring("synchronized "); buf->writestring("synchronized ");
} }
@@ -1081,17 +1077,6 @@ void FuncDeclaration::toDocBuffer(OutBuffer *buf, Scope *sc)
} }
} }
#if DMDV1
void CtorDeclaration::toDocBuffer(OutBuffer *buf, Scope *sc)
{
HdrGenState hgs;
buf->writestring("this");
Parameter::argsToCBuffer(buf, &hgs, arguments, varargs);
buf->writestring(";\n");
}
#endif
void AggregateDeclaration::toDocBuffer(OutBuffer *buf, Scope *sc) void AggregateDeclaration::toDocBuffer(OutBuffer *buf, Scope *sc)
{ {
if (ident) if (ident)
@@ -1210,7 +1195,7 @@ void EnumMember::toDocBuffer(OutBuffer *buf, Scope *sc)
/********************************* DocComment *********************************/ /********************************* DocComment *********************************/
DocComment *DocComment::parse(Scope *sc, Dsymbol *s, utf8_t *comment) DocComment *DocComment::parse(Scope *sc, Dsymbol *s, const utf8_t *comment)
{ {
//printf("parse(%s): '%s'\n", s->toChars(), comment); //printf("parse(%s): '%s'\n", s->toChars(), comment);
if (sc->lastdc && isDitto(comment)) if (sc->lastdc && isDitto(comment))
@@ -1247,21 +1232,22 @@ DocComment *DocComment::parse(Scope *sc, Dsymbol *s, utf8_t *comment)
* then (*pcomment)[0 .. idlen] is the identifier. * then (*pcomment)[0 .. idlen] is the identifier.
*/ */
void DocComment::parseSections(utf8_t *comment) void DocComment::parseSections(const utf8_t *comment)
{ utf8_t *p; {
utf8_t *pstart; const utf8_t *p;
utf8_t *pend; const utf8_t *pstart;
utf8_t *idstart; const utf8_t *pend;
const utf8_t *idstart;
size_t idlen; size_t idlen;
utf8_t *name = NULL; const utf8_t *name = NULL;
size_t namelen = 0; size_t namelen = 0;
//printf("parseSections('%s')\n", comment); //printf("parseSections('%s')\n", comment);
p = comment; p = comment;
while (*p) while (*p)
{ {
utf8_t *pstart0 = p; const utf8_t *pstart0 = p;
p = skipwhitespace(p); p = skipwhitespace(p);
pstart = p; pstart = p;
pend = p; pend = p;
@@ -1296,7 +1282,7 @@ void DocComment::parseSections(utf8_t *comment)
if (!inCode && isIdStart(p)) if (!inCode && isIdStart(p))
{ {
utf8_t *q = p + utfStride(p); const utf8_t *q = p + utfStride(p);
while (isIdTail(q)) while (isIdTail(q))
q += utfStride(q); q += utfStride(q);
if (*q == ':') // identifier: ends it if (*q == ':') // identifier: ends it
@@ -1451,17 +1437,17 @@ void Section::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf) void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
{ {
utf8_t *p = body; const utf8_t *p = body;
size_t len = bodylen; size_t len = bodylen;
utf8_t *pend = p + len; const utf8_t *pend = p + len;
utf8_t *tempstart; const utf8_t *tempstart;
size_t templen; size_t templen;
utf8_t *namestart; const utf8_t *namestart;
size_t namelen = 0; // !=0 if line continuation size_t namelen = 0; // !=0 if line continuation
utf8_t *textstart; const utf8_t *textstart;
size_t textlen; size_t textlen;
size_t o, paramcount = 0; size_t o, paramcount = 0;
@@ -1606,19 +1592,19 @@ void MacroSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
* name2 = value2 * name2 = value2
*/ */
void DocComment::parseMacros(Escape **pescapetable, Macro **pmacrotable, utf8_t *m, size_t mlen) void DocComment::parseMacros(Escape **pescapetable, Macro **pmacrotable, const utf8_t *m, size_t mlen)
{ {
utf8_t *p = m; const utf8_t *p = m;
size_t len = mlen; size_t len = mlen;
utf8_t *pend = p + len; const utf8_t *pend = p + len;
utf8_t *tempstart; const utf8_t *tempstart;
size_t templen; size_t templen;
utf8_t *namestart; const utf8_t *namestart;
size_t namelen = 0; // !=0 if line continuation size_t namelen = 0; // !=0 if line continuation
utf8_t *textstart; const utf8_t *textstart;
size_t textlen; size_t textlen;
while (p < pend) while (p < pend)
@@ -1731,7 +1717,7 @@ Ldone:
* by whitespace and/or commas. * by whitespace and/or commas.
*/ */
void DocComment::parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t textlen) void DocComment::parseEscapes(Escape **pescapetable, const utf8_t *textstart, size_t textlen)
{ Escape *escapetable = *pescapetable; { Escape *escapetable = *pescapetable;
if (!escapetable) if (!escapetable)
@@ -1740,8 +1726,8 @@ void DocComment::parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t t
*pescapetable = escapetable; *pescapetable = escapetable;
} }
//printf("parseEscapes('%.*s') pescapetable = %p\n", textlen, textstart, pescapetable); //printf("parseEscapes('%.*s') pescapetable = %p\n", textlen, textstart, pescapetable);
utf8_t *p = textstart; const utf8_t *p = textstart;
utf8_t *pend = p + textlen; const utf8_t *pend = p + textlen;
while (1) while (1)
{ {
@@ -1757,7 +1743,7 @@ void DocComment::parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t t
return; return;
utf8_t c = p[1]; utf8_t c = p[1];
p += 3; p += 3;
utf8_t *start = p; const utf8_t *start = p;
while (1) while (1)
{ {
if (p >= pend) if (p >= pend)
@@ -1781,7 +1767,7 @@ void DocComment::parseEscapes(Escape **pescapetable, utf8_t *textstart, size_t t
* Return < 0, ==0, > 0 * Return < 0, ==0, > 0
*/ */
int cmp(const char *stringz, void *s, size_t slen) int cmp(const char *stringz, const void *s, size_t slen)
{ {
size_t len1 = strlen(stringz); size_t len1 = strlen(stringz);
@@ -1790,7 +1776,7 @@ int cmp(const char *stringz, void *s, size_t slen)
return memcmp(stringz, s, slen); return memcmp(stringz, s, slen);
} }
int icmp(const char *stringz, void *s, size_t slen) int icmp(const char *stringz, const void *s, size_t slen)
{ {
size_t len1 = strlen(stringz); size_t len1 = strlen(stringz);
@@ -1803,13 +1789,13 @@ int icmp(const char *stringz, void *s, size_t slen)
* Return !=0 if comment consists entirely of "ditto". * Return !=0 if comment consists entirely of "ditto".
*/ */
int isDitto(utf8_t *comment) int isDitto(const utf8_t *comment)
{ {
if (comment) if (comment)
{ {
utf8_t *p = skipwhitespace(comment); const utf8_t *p = skipwhitespace(comment);
if (Port::memicmp((char *)p, "ditto", 5) == 0 && *skipwhitespace(p + 5) == 0) if (Port::memicmp((const char *)p, "ditto", 5) == 0 && *skipwhitespace(p + 5) == 0)
return 1; return 1;
} }
return 0; return 0;
@@ -1819,7 +1805,7 @@ int isDitto(utf8_t *comment)
* Skip white space. * Skip white space.
*/ */
utf8_t *skipwhitespace(utf8_t *p) const utf8_t *skipwhitespace(const utf8_t *p)
{ {
for (; 1; p++) for (; 1; p++)
{ switch (*p) { switch (*p)
@@ -1903,7 +1889,7 @@ size_t skippastident(OutBuffer *buf, size_t i)
size_t skippastURL(OutBuffer *buf, size_t i) size_t skippastURL(OutBuffer *buf, size_t i)
{ size_t length = buf->offset - i; { size_t length = buf->offset - i;
utf8_t *p = &buf->data[i]; utf8_t *p = (utf8_t *)&buf->data[i];
size_t j; size_t j;
unsigned sawdot = 0; unsigned sawdot = 0;
@@ -1991,7 +1977,7 @@ TypeFunction *isTypeFunction(Dsymbol *s)
/**************************************************** /****************************************************
*/ */
Parameter *isFunctionParameter(Dsymbol *s, utf8_t *p, size_t len) Parameter *isFunctionParameter(Dsymbol *s, const utf8_t *p, size_t len)
{ {
TypeFunction *tf = isTypeFunction(s); TypeFunction *tf = isTypeFunction(s);
if (tf && tf->parameters) if (tf && tf->parameters)
@@ -2011,7 +1997,7 @@ Parameter *isFunctionParameter(Dsymbol *s, utf8_t *p, size_t len)
/**************************************************** /****************************************************
*/ */
TemplateParameter *isTemplateParameter(Dsymbol *s, utf8_t *p, size_t len) TemplateParameter *isTemplateParameter(Dsymbol *s, const utf8_t *p, size_t len)
{ {
TemplateDeclaration *td = s->isTemplateDeclaration(); TemplateDeclaration *td = s->isTemplateDeclaration();
if (td && td->origParameters) if (td && td->origParameters)
@@ -2062,7 +2048,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
if (!sc->module->isDocFile && if (!sc->module->isDocFile &&
!inCode && i == iLineStart && i + 1 < buf->offset) // if "\n\n" !inCode && i == iLineStart && i + 1 < buf->offset) // if "\n\n"
{ {
static char blankline[] = "$(DDOC_BLANKLINE)\n"; static const char blankline[] = "$(DDOC_BLANKLINE)\n";
i = buf->insert(i, blankline, strlen(blankline)); i = buf->insert(i, blankline, strlen(blankline));
} }
@@ -2074,7 +2060,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
leadingBlank = 0; leadingBlank = 0;
if (inCode) if (inCode)
break; break;
p = &buf->data[i]; p = (utf8_t *)&buf->data[i];
se = sc->module->escapetable->escapeChar('<'); se = sc->module->escapetable->escapeChar('<');
if (se && strcmp(se, "&lt;") == 0) if (se && strcmp(se, "&lt;") == 0)
@@ -2148,7 +2134,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
leadingBlank = 0; leadingBlank = 0;
if (inCode) if (inCode)
break; break;
p = &buf->data[i]; p = (utf8_t *)&buf->data[i];
if (p[1] == '#' || isalpha(p[1])) if (p[1] == '#' || isalpha(p[1]))
break; // already a character entity break; // already a character entity
// Replace '&' with '&amp;' character entity // Replace '&' with '&amp;' character entity
@@ -2220,8 +2206,8 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
// Remove leading indentations from all lines // Remove leading indentations from all lines
bool lineStart = true; bool lineStart = true;
utf8_t *endp = codebuf.data + codebuf.offset; utf8_t *endp = (utf8_t *)codebuf.data + codebuf.offset;
for (utf8_t *p = codebuf.data; p < endp; ) for (p = (utf8_t *)codebuf.data; p < endp; )
{ {
if (lineStart) if (lineStart)
{ {
@@ -2229,11 +2215,11 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
utf8_t *q = p; utf8_t *q = p;
while (j-- > 0 && q < endp && isIndentWS(q)) while (j-- > 0 && q < endp && isIndentWS(q))
++q; ++q;
codebuf.remove(p - codebuf.data, q - p); codebuf.remove(p - (utf8_t *)codebuf.data, q - p);
assert(codebuf.data <= p); assert((utf8_t *)codebuf.data <= p);
assert(p < codebuf.data + codebuf.offset); assert(p < (utf8_t *)codebuf.data + codebuf.offset);
lineStart = false; lineStart = false;
endp = codebuf.data + codebuf.offset; // update endp = (utf8_t *)codebuf.data + codebuf.offset; // update
continue; continue;
} }
if (*p == '\n') if (*p == '\n')
@@ -2248,7 +2234,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
i -= 2; // in next loop, c should be '\n' i -= 2; // in next loop, c should be '\n'
} }
else else
{ static char pre[] = "$(D_CODE \n"; { static const char pre[] = "$(D_CODE \n";
inCode = 1; inCode = 1;
codeIndent = istart - iLineStart; // save indent count codeIndent = istart - iLineStart; // save indent count
@@ -2263,7 +2249,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
default: default:
leadingBlank = 0; leadingBlank = 0;
if (!sc->module->isDocFile && if (!sc->module->isDocFile &&
!inCode && isIdStart(&buf->data[i])) !inCode && isIdStart((utf8_t *)&buf->data[i]))
{ {
size_t j = skippastident(buf, i); size_t j = skippastident(buf, i);
if (j > i) if (j > i)
@@ -2286,14 +2272,14 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
i = buf->bracket(i, "$(DDOC_PSYMBOL ", j, ")") - 1; i = buf->bracket(i, "$(DDOC_PSYMBOL ", j, ")") - 1;
break; break;
} }
else if (isKeyword(buf->data + i, j - i)) else if (isKeyword((utf8_t *)buf->data + i, j - i))
{ {
i = buf->bracket(i, "$(DDOC_KEYWORD ", j, ")") - 1; i = buf->bracket(i, "$(DDOC_KEYWORD ", j, ")") - 1;
break; break;
} }
else else
{ {
if (f && isFunctionParameter(f, buf->data + i, j - i)) if (f && isFunctionParameter(f, (utf8_t *)buf->data + i, j - i))
{ {
//printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j); //printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j);
i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1; i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1;
@@ -2342,7 +2328,7 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool an
i = buf->insert(i, se, len); i = buf->insert(i, se, len);
i--; // point to ';' i--; // point to ';'
} }
else if (isIdStart(&buf->data[i])) else if (isIdStart((utf8_t *)&buf->data[i]))
{ {
size_t j = skippastident(buf, i); size_t j = skippastident(buf, i);
if (j > i) if (j > i)
@@ -2354,7 +2340,7 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool an
} }
else if (f) else if (f)
{ {
if (isFunctionParameter(f, buf->data + i, j - i)) if (isFunctionParameter(f, (utf8_t *)buf->data + i, j - i))
{ {
//printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j); //printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j);
i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1; i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1;
@@ -2370,7 +2356,7 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool an
/**************************************** /****************************************
*/ */
void highlightCode3(Scope *sc, OutBuffer *buf, utf8_t *p, utf8_t *pend) void highlightCode3(Scope *sc, OutBuffer *buf, const utf8_t *p, const utf8_t *pend)
{ {
for (; p < pend; p++) for (; p < pend; p++)
{ const char *s = sc->module->escapetable->escapeChar(*p); { const char *s = sc->module->escapetable->escapeChar(*p);
@@ -2391,10 +2377,10 @@ void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
const char *sid = s->ident->toChars(); const char *sid = s->ident->toChars();
FuncDeclaration *f = s->isFuncDeclaration(); FuncDeclaration *f = s->isFuncDeclaration();
unsigned errorsave = global.errors; unsigned errorsave = global.errors;
Lexer lex(NULL, buf->data, 0, buf->offset - 1, 0, 1); Lexer lex(NULL, (utf8_t *)buf->data, 0, buf->offset - 1, 0, 1);
Token tok; Token tok;
OutBuffer res; OutBuffer res;
utf8_t *lastp = buf->data; const utf8_t *lastp = (utf8_t *)buf->data;
const char *highlight; const char *highlight;
if (s->isModule() && ((Module *)s)->isDocFile) if (s->isModule() && ((Module *)s)->isDocFile)
@@ -2496,7 +2482,7 @@ const char *Escape::escapeChar(unsigned c)
* Determine if p points to the start of an identifier. * Determine if p points to the start of an identifier.
*/ */
int isIdStart(utf8_t *p) int isIdStart(const utf8_t *p)
{ {
unsigned c = *p; unsigned c = *p;
if (isalpha(c) || c == '_') if (isalpha(c) || c == '_')
@@ -2515,7 +2501,7 @@ int isIdStart(utf8_t *p)
* Determine if p points to the rest of an identifier. * Determine if p points to the rest of an identifier.
*/ */
int isIdTail(utf8_t *p) int isIdTail(const utf8_t *p)
{ {
unsigned c = *p; unsigned c = *p;
if (isalnum(c) || c == '_') if (isalnum(c) || c == '_')
@@ -2534,7 +2520,7 @@ int isIdTail(utf8_t *p)
* Determine if p points to the indentation space. * Determine if p points to the indentation space.
*/ */
int isIndentWS(utf8_t *p) int isIndentWS(const utf8_t *p)
{ {
return (*p == ' ') || (*p == '\t'); return (*p == ' ') || (*p == '\t');
} }
@@ -2543,7 +2529,7 @@ int isIndentWS(utf8_t *p)
* Return number of bytes in UTF character. * Return number of bytes in UTF character.
*/ */
int utfStride(utf8_t *p) int utfStride(const utf8_t *p)
{ {
unsigned c = *p; unsigned c = *p;
if (c < 0x80) if (c < 0x80)
+30 -33
View File
@@ -199,7 +199,7 @@ bool Dsymbol::hasPointers()
bool Dsymbol::hasStaticCtorOrDtor() bool Dsymbol::hasStaticCtorOrDtor()
{ {
//printf("Dsymbol::hasStaticCtorOrDtor() %s\n", toChars()); //printf("Dsymbol::hasStaticCtorOrDtor() %s\n", toChars());
return FALSE; return false;
} }
void Dsymbol::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion) void Dsymbol::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
@@ -466,24 +466,23 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id)
//printf("\ttemplate instance id\n"); //printf("\ttemplate instance id\n");
Dsymbol *st = (Dsymbol *)id; Dsymbol *st = (Dsymbol *)id;
TemplateInstance *ti = st->isTemplateInstance(); TemplateInstance *ti = st->isTemplateInstance();
Identifier *id = ti->name; sm = s->search(loc, ti->name, 0);
sm = s->search(loc, id, 0);
if (!sm) if (!sm)
{ {
sm = s->search_correct(id); sm = s->search_correct(ti->name);
if (sm) if (sm)
error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?", error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?",
id->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars()); ti->name->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars());
else else
error("template identifier '%s' is not a member of '%s %s'", error("template identifier '%s' is not a member of '%s %s'",
id->toChars(), s->kind(), s->toChars()); ti->name->toChars(), s->kind(), s->toChars());
return NULL; return NULL;
} }
sm = sm->toAlias(); sm = sm->toAlias();
TemplateDeclaration *td = sm->isTemplateDeclaration(); TemplateDeclaration *td = sm->isTemplateDeclaration();
if (!td) if (!td)
{ {
error("%s is not a template, it is a %s", id->toChars(), sm->kind()); error("%s is not a template, it is a %s", ti->name->toChars(), sm->kind());
return NULL; return NULL;
} }
ti->tempdecl = td; ti->tempdecl = td;
@@ -568,7 +567,6 @@ bool Dsymbol::isDeprecated()
return false; return false;
} }
#if DMDV2
bool Dsymbol::isOverloadable() bool Dsymbol::isOverloadable()
{ {
return false; return false;
@@ -578,7 +576,6 @@ bool Dsymbol::hasOverloads()
{ {
return false; return false;
} }
#endif
LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()? LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()?
{ {
@@ -806,24 +803,21 @@ Dsymbols *Dsymbol::arraySyntaxCopy(Dsymbols *a)
* Ignore NULL comments. * Ignore NULL comments.
*/ */
void Dsymbol::addComment(utf8_t *comment) void Dsymbol::addComment(const utf8_t *comment)
{ {
//if (comment) //if (comment)
//printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
if (!this->comment) if (!this->comment)
this->comment = comment; this->comment = comment;
#if 1
else if (comment && strcmp((char *)comment, (char *)this->comment) != 0) else if (comment && strcmp((char *)comment, (char *)this->comment) != 0)
{ // Concatenate the two { // Concatenate the two
this->comment = Lexer::combineComments(this->comment, comment); this->comment = Lexer::combineComments(this->comment, comment);
} }
#endif
} }
/********************************* OverloadSet ****************************/ /********************************* OverloadSet ****************************/
#if DMDV2
OverloadSet::OverloadSet(Identifier *ident) OverloadSet::OverloadSet(Identifier *ident)
: Dsymbol(ident) : Dsymbol(ident)
{ {
@@ -838,7 +832,6 @@ const char *OverloadSet::kind()
{ {
return "overloadset"; return "overloadset";
} }
#endif
/********************************* ScopeDsymbol ****************************/ /********************************* ScopeDsymbol ****************************/
@@ -1028,7 +1021,7 @@ void ScopeDsymbol::importScope(Dsymbol *s, PROT protection)
} }
} }
imports->push(s); imports->push(s);
prots = (unsigned char *)mem.realloc(prots, imports->dim * sizeof(prots[0])); prots = (PROT *)mem.realloc(prots, imports->dim * sizeof(prots[0]));
prots[imports->dim - 1] = protection; prots[imports->dim - 1] = protection;
} }
} }
@@ -1115,17 +1108,16 @@ bool ScopeDsymbol::hasStaticCtorOrDtor()
{ Dsymbol *member = (*members)[i]; { Dsymbol *member = (*members)[i];
if (member->hasStaticCtorOrDtor()) if (member->hasStaticCtorOrDtor())
return TRUE; return true;
} }
} }
return FALSE; return false;
} }
/*************************************** /***************************************
* Determine number of Dsymbols, folding in AttribDeclaration members. * Determine number of Dsymbols, folding in AttribDeclaration members.
*/ */
#if DMDV2
static int dimDg(void *ctx, size_t n, Dsymbol *) static int dimDg(void *ctx, size_t n, Dsymbol *)
{ {
++*(size_t *)ctx; ++*(size_t *)ctx;
@@ -1138,7 +1130,6 @@ size_t ScopeDsymbol::dim(Dsymbols *members)
foreach(NULL, members, &dimDg, &n); foreach(NULL, members, &dimDg, &n);
return n; return n;
} }
#endif
/*************************************** /***************************************
* Get nth Dsymbol, folding in AttribDeclaration members. * Get nth Dsymbol, folding in AttribDeclaration members.
@@ -1148,7 +1139,6 @@ size_t ScopeDsymbol::dim(Dsymbols *members)
* of Dsymbols * of Dsymbols
*/ */
#if DMDV2
struct GetNthSymbolCtx struct GetNthSymbolCtx
{ {
size_t nth; size_t nth;
@@ -1171,7 +1161,6 @@ Dsymbol *ScopeDsymbol::getNth(Dsymbols *members, size_t nth, size_t *pn)
int res = foreach(NULL, members, &getNthSymbolDg, &ctx); int res = foreach(NULL, members, &getNthSymbolDg, &ctx);
return res ? ctx.sym : NULL; return res ? ctx.sym : NULL;
} }
#endif
/*************************************** /***************************************
* Expands attribute declarations in members in depth first * Expands attribute declarations in members in depth first
@@ -1182,7 +1171,6 @@ Dsymbol *ScopeDsymbol::getNth(Dsymbols *members, size_t nth, size_t *pn)
* calculating dim and calling N times getNth. * calculating dim and calling N times getNth.
*/ */
#if DMDV2
int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg dg, void *ctx, size_t *pn) int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg dg, void *ctx, size_t *pn)
{ {
assert(dg); assert(dg);
@@ -1213,7 +1201,6 @@ int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg
*pn = n; // update index *pn = n; // update index
return result; return result;
} }
#endif
/******************************************* /*******************************************
* Look for member of the form: * Look for member of the form:
@@ -1221,7 +1208,6 @@ int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg
* Returns NULL if not found * Returns NULL if not found
*/ */
#if DMDV2
FuncDeclaration *ScopeDsymbol::findGetMembers() FuncDeclaration *ScopeDsymbol::findGetMembers()
{ {
Dsymbol *s = search_function(this, Id::getmembers); Dsymbol *s = search_function(this, Id::getmembers);
@@ -1249,7 +1235,6 @@ FuncDeclaration *ScopeDsymbol::findGetMembers()
return fdx; return fdx;
} }
#endif
/****************************** WithScopeSymbol ******************************/ /****************************** WithScopeSymbol ******************************/
@@ -1267,11 +1252,22 @@ Dsymbol *WithScopeSymbol::search(Loc loc, Identifier *ident, int flags)
Expression *eold = NULL; Expression *eold = NULL;
for (Expression *e = withstate->exp; e != eold; e = resolveAliasThis(scope, e)) for (Expression *e = withstate->exp; e != eold; e = resolveAliasThis(scope, e))
{ {
Type *t = e->type->toBasetype(); if (e->op == TOKimport)
if (t->ty == Taarray) {
s = ((TypeAArray *)t)->getImpl(); s = ((ScopeExp *)e)->sds;
}
else if (e->op == TOKtype)
{
s = e->type->toDsymbol(NULL);
}
else else
s = t->toDsymbol(NULL); {
Type *t = e->type->toBasetype();
if (t->ty == Taarray)
s = ((TypeAArray *)t)->getImpl();
else
s = t->toDsymbol(NULL);
}
if (s) if (s)
{ {
s = s->search(loc, ident, 0); s = s->search(loc, ident, 0);
@@ -1328,7 +1324,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
Expression *e = new IntegerExp(Loc(), td->objects->dim, Type::tsize_t); Expression *e = new IntegerExp(Loc(), td->objects->dim, Type::tsize_t);
v->init = new ExpInitializer(Loc(), e); v->init = new ExpInitializer(Loc(), e);
v->storage_class |= STCstatic | STCconst; v->storage_class |= STCtemp | STCstatic | STCconst;
v->semantic(sc); v->semantic(sc);
return v; return v;
} }
@@ -1339,7 +1335,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
Expression *e = new IntegerExp(Loc(), type->arguments->dim, Type::tsize_t); Expression *e = new IntegerExp(Loc(), type->arguments->dim, Type::tsize_t);
v->init = new ExpInitializer(Loc(), e); v->init = new ExpInitializer(Loc(), e);
v->storage_class |= STCstatic | STCconst; v->storage_class |= STCtemp | STCstatic | STCconst;
v->semantic(sc); v->semantic(sc);
return v; return v;
} }
@@ -1404,7 +1400,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
*/ */
Expression *e = new IntegerExp(Loc(), ((TupleExp *)ce)->exps->dim, Type::tsize_t); Expression *e = new IntegerExp(Loc(), ((TupleExp *)ce)->exps->dim, Type::tsize_t);
v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(Loc(), e)); v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(Loc(), e));
v->storage_class |= STCstatic | STCconst; v->storage_class |= STCtemp | STCstatic | STCconst;
} }
else if (ce->type && (t = ce->type->toBasetype()) != NULL && else if (ce->type && (t = ce->type->toBasetype()) != NULL &&
(t->ty == Tstruct || t->ty == Tclass)) (t->ty == Tstruct || t->ty == Tclass))
@@ -1473,6 +1469,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
if (t && t->ty == Tfunction) if (t && t->ty == Tfunction)
e = new CallExp(e->loc, e); e = new CallExp(e->loc, e);
v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(Loc(), e)); v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(Loc(), e));
v->storage_class |= STCtemp;
} }
else else
{ /* For arrays, $ will either be a compile-time constant { /* For arrays, $ will either be a compile-time constant
@@ -1483,7 +1480,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
VoidInitializer *e = new VoidInitializer(Loc()); VoidInitializer *e = new VoidInitializer(Loc());
e->type = Type::tsize_t; e->type = Type::tsize_t;
v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, e); v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, e);
v->storage_class |= STCctfe; // it's never a true static variable v->storage_class |= STCtemp | STCctfe; // it's never a true static variable
} }
*pvar = v; *pvar = v;
} }
+3 -7
View File
@@ -146,7 +146,7 @@ public:
Symbol *csym; // symbol for code generator Symbol *csym; // symbol for code generator
Symbol *isym; // import version of csym Symbol *isym; // import version of csym
#endif #endif
utf8_t *comment; // documentation comment for this Dsymbol const utf8_t *comment; // documentation comment for this Dsymbol
Loc loc; // where defined Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic() Scope *scope; // !=NULL means context to use for semantic()
bool errors; // this symbol failed to pass semantic() bool errors; // this symbol failed to pass semantic()
@@ -211,10 +211,8 @@ public:
virtual bool isExport(); // is Dsymbol exported? virtual bool isExport(); // is Dsymbol exported?
virtual bool isImportedSymbol(); // is Dsymbol imported? virtual bool isImportedSymbol(); // is Dsymbol imported?
virtual bool isDeprecated(); // is Dsymbol deprecated? virtual bool isDeprecated(); // is Dsymbol deprecated?
#if DMDV2
virtual bool isOverloadable(); virtual bool isOverloadable();
virtual bool hasOverloads(); virtual bool hasOverloads();
#endif
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration? virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
virtual Type *getType(); // is this a type? virtual Type *getType(); // is this a type?
@@ -230,7 +228,7 @@ public:
virtual void addLocalClass(ClassDeclarations *) { } virtual void addLocalClass(ClassDeclarations *) { }
virtual void checkCtorConstInit() { } virtual void checkCtorConstInit() { }
virtual void addComment(utf8_t *comment); virtual void addComment(const utf8_t *comment);
virtual void emitComment(Scope *sc); virtual void emitComment(Scope *sc);
void emitDitto(Scope *sc); void emitDitto(Scope *sc);
@@ -310,7 +308,7 @@ public:
DsymbolTable *symtab; // members[] sorted into table DsymbolTable *symtab; // members[] sorted into table
Dsymbols *imports; // imported Dsymbol's Dsymbols *imports; // imported Dsymbol's
unsigned char *prots; // array of PROT, one for each import PROT *prots; // array of PROT, one for each import
ScopeDsymbol(); ScopeDsymbol();
ScopeDsymbol(Identifier *id); ScopeDsymbol(Identifier *id);
@@ -370,7 +368,6 @@ public:
// Overload Sets // Overload Sets
#if DMDV2
class OverloadSet : public Dsymbol class OverloadSet : public Dsymbol
{ {
public: public:
@@ -381,7 +378,6 @@ public:
OverloadSet *isOverloadSet() { return this; } OverloadSet *isOverloadSet() { return this; }
const char *kind(); const char *kind();
}; };
#endif
// Table of Dsymbol's // Table of Dsymbol's
+1 -1
View File
@@ -2374,7 +2374,7 @@ static NameId* namesTable[] = {
namesS, namesT, namesU, namesV, namesW, namesX, namesY, namesZ, NULL namesS, namesT, namesU, namesV, namesW, namesX, namesY, namesZ, NULL
}; };
int HtmlNamedEntity(utf8_t *p, size_t length) int HtmlNamedEntity(const utf8_t *p, size_t length)
{ {
int tableIndex = tolower(*p) - 'a'; int tableIndex = tolower(*p) - 'a';
if (tableIndex >= 0 && tableIndex < 26) if (tableIndex >= 0 && tableIndex < 26)
+4 -3
View File
@@ -381,20 +381,21 @@ Type *EnumDeclaration::getMemtype(Loc loc)
if (loc.linnum == 0) if (loc.linnum == 0)
loc = this->loc; loc = this->loc;
if (scope) if (scope)
{ /* Enum is forward referenced. We don't need to resolve the whole thing, {
/* Enum is forward referenced. We don't need to resolve the whole thing,
* just the base type * just the base type
*/ */
if (memtype) if (memtype)
memtype = memtype->semantic(loc, scope); memtype = memtype->semantic(loc, scope);
else else
{ {
if (!isAnonymous()) if (!isAnonymous() && members)
memtype = Type::tint32; memtype = Type::tint32;
} }
} }
if (!memtype) if (!memtype)
{ {
if (!isAnonymous()) if (!isAnonymous() && members)
memtype = Type::tint32; memtype = Type::tint32;
else else
{ {
-2
View File
@@ -57,9 +57,7 @@ public:
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Type *getType(); Type *getType();
const char *kind(); const char *kind();
#if DMDV2
Dsymbol *search(Loc, Identifier *ident, int flags); Dsymbol *search(Loc, Identifier *ident, int flags);
#endif
bool isDeprecated(); // is Dsymbol deprecated? bool isDeprecated(); // is Dsymbol deprecated?
PROT prot(); PROT prot();
Expression *getMaxMinValue(Loc loc, Identifier *id); Expression *getMaxMinValue(Loc loc, Identifier *id);
+536 -603
View File
File diff suppressed because it is too large Load Diff
+114 -59
View File
@@ -104,14 +104,14 @@ int arrayExpressionCanThrow(Expressions *exps, bool mustNotThrow);
TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s); TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
Expression *valueNoDtor(Expression *e); Expression *valueNoDtor(Expression *e);
int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1); int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
#if DMDV2
Expression *resolveAliasThis(Scope *sc, Expression *e); Expression *resolveAliasThis(Scope *sc, Expression *e);
Expression *callCpCtor(Scope *sc, Expression *e); Expression *callCpCtor(Scope *sc, Expression *e);
#endif
Expression *resolveOpDollar(Scope *sc, ArrayExp *ae); Expression *resolveOpDollar(Scope *sc, ArrayExp *ae);
Expression *resolveOpDollar(Scope *sc, SliceExp *se); Expression *resolveOpDollar(Scope *sc, SliceExp *se);
Expressions *arrayExpressionSemantic(Expressions *exps, Scope *sc); Expressions *arrayExpressionSemantic(Expressions *exps, Scope *sc);
AggregateDeclaration *isAggregate(Type *t);
/* Run CTFE on the expression, but allow the expression to be a TypeExp /* Run CTFE on the expression, but allow the expression to be a TypeExp
* or a tuple containing a TypeExp. (This is required by pragma(msg)). * or a tuple containing a TypeExp. (This is required by pragma(msg)).
*/ */
@@ -197,7 +197,6 @@ public:
Expression *addressOf(Scope *sc); Expression *addressOf(Scope *sc);
Expression *deref(); Expression *deref();
Expression *integralPromotions(Scope *sc); Expression *integralPromotions(Scope *sc);
Expression *isTemp();
Expression *toDelegate(Scope *sc, Type *t); Expression *toDelegate(Scope *sc, Type *t);
@@ -216,7 +215,7 @@ public:
bool hasSideEffect(); bool hasSideEffect();
void discardValue(); void discardValue();
void useValue(); void useValue();
int canThrow(bool mustNotThrow); bool canThrow(bool mustNotThrow);
virtual int inlineCost3(InlineCostState *ics); virtual int inlineCost3(InlineCostState *ics);
virtual Expression *doInline(InlineDoState *ids); virtual Expression *doInline(InlineDoState *ids);
@@ -467,7 +466,7 @@ public:
int isLvalue(); int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e); Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e);
unsigned charAt(size_t i); unsigned charAt(uinteger_t i);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toMangleBuffer(OutBuffer *buf); void toMangleBuffer(OutBuffer *buf);
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
@@ -626,6 +625,7 @@ public:
void toMangleBuffer(OutBuffer *buf); void toMangleBuffer(OutBuffer *buf);
Expression *optimize(int result, bool keepLvalue = false); Expression *optimize(int result, bool keepLvalue = false);
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
Expression *addDtorHook(Scope *sc);
#if IN_LLVM #if IN_LLVM
// With the introduction of pointers returned from CTFE, struct literals can // With the introduction of pointers returned from CTFE, struct literals can
// now contain pointers to themselves. While in toElem, contains a pointer // now contain pointers to themselves. While in toElem, contains a pointer
@@ -742,7 +742,6 @@ public:
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#if DMDV2
class SymbolExp : public Expression class SymbolExp : public Expression
{ {
public: public:
@@ -753,16 +752,15 @@ public:
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
}; };
#endif
// Offset from symbol // Offset from symbol
class SymOffExp : public SymbolExp class SymOffExp : public SymbolExp
{ {
public: public:
unsigned offset; dinteger_t offset;
SymOffExp(Loc loc, Declaration *var, unsigned offset, bool hasOverloads = false); SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads = false);
Expression *semantic(Scope *sc); Expression *semantic(Scope *sc);
Expression *optimize(int result, bool keepLvalue = false); Expression *optimize(int result, bool keepLvalue = false);
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
@@ -814,7 +812,6 @@ public:
//Expression *inlineScan(InlineScanState *iss); //Expression *inlineScan(InlineScanState *iss);
}; };
#if DMDV2
// Overload Set // Overload Set
class OverExp : public Expression class OverExp : public Expression
@@ -827,7 +824,6 @@ public:
Expression *toLvalue(Scope *sc, Expression *e); Expression *toLvalue(Scope *sc, Expression *e);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#endif
// Function/Delegate literal // Function/Delegate literal
@@ -892,7 +888,6 @@ public:
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#if DMDV2
class TraitsExp : public Expression class TraitsExp : public Expression
{ {
public: public:
@@ -902,9 +897,11 @@ public:
TraitsExp(Loc loc, Identifier *ident, Objects *args); TraitsExp(Loc loc, Identifier *ident, Objects *args);
Expression *syntaxCopy(); Expression *syntaxCopy();
Expression *semantic(Scope *sc); Expression *semantic(Scope *sc);
Expression *isTypeX(bool (*fp)(Type *t));
Expression *isFuncX(bool (*fp)(FuncDeclaration *f));
Expression *isDeclX(bool (*fp)(Declaration *d));
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#endif
class HaltExp : public Expression class HaltExp : public Expression
{ {
@@ -1177,11 +1174,13 @@ public:
int isLvalue(); int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e); Expression *toLvalue(Scope *sc, Expression *e);
Expression *addDtorHook(Scope *sc); Expression *addDtorHook(Scope *sc);
Expression *implicitCastTo(Scope *sc, Type *t);
MATCH implicitConvTo(Type *t); MATCH implicitConvTo(Type *t);
int inlineCost3(InlineCostState *ics); int inlineCost3(InlineCostState *ics);
Expression *doInline(InlineDoState *ids); Expression *doInline(InlineDoState *ids);
Expression *inlineScan(InlineScanState *iss); Expression *inlineScan(InlineScanState *iss);
Expression *inlineScan(InlineScanState *iss, Expression *eret);
#if IN_LLVM #if IN_LLVM
void cacheLvalue(IRState* p); void cacheLvalue(IRState* p);
@@ -1307,10 +1306,10 @@ class CastExp : public UnaExp
public: public:
// Possible to cast to one type while painting to another type // Possible to cast to one type while painting to another type
Type *to; // type to cast to Type *to; // type to cast to
unsigned mod; // MODxxxxx unsigned char mod; // MODxxxxx
CastExp(Loc loc, Expression *e, Type *t); CastExp(Loc loc, Expression *e, Type *t);
CastExp(Loc loc, Expression *e, unsigned mod); CastExp(Loc loc, Expression *e, unsigned char mod);
Expression *syntaxCopy(); Expression *syntaxCopy();
Expression *semantic(Scope *sc); Expression *semantic(Scope *sc);
MATCH implicitConvTo(Type *t); MATCH implicitConvTo(Type *t);
@@ -1517,6 +1516,9 @@ public:
Identifier *opId(); // For operator overloading Identifier *opId(); // For operator overloading
void buildArrayIdent(OutBuffer *buf, Expressions *arguments); void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
Expression *buildArrayLoop(Parameters *fparams); Expression *buildArrayLoop(Parameters *fparams);
Expression *inlineScan(InlineScanState *iss);
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
#if IN_LLVM #if IN_LLVM
@@ -1530,53 +1532,111 @@ public:
ConstructExp(Loc loc, Expression *e1, Expression *e2); ConstructExp(Loc loc, Expression *e1, Expression *e2);
}; };
#define ASSIGNEXP(op) \ class AddAssignExp : public BinAssignExp
class op##AssignExp : public BinAssignExp \ {
{ \ public:
public: \ AddAssignExp(Loc loc, Expression *e1, Expression *e2);
op##AssignExp(Loc loc, Expression *e1, Expression *e2); \ Identifier *opId(); /* For operator overloading */
S(Expression *semantic(Scope *sc);) \ elem *toElem(IRState *irs);
\
Identifier *opId(); /* For operator overloading */ \
\
elem *toElem(IRState *irs); \
}; };
#define X(a) a class MinAssignExp : public BinAssignExp
#define S(a) {
ASSIGNEXP(Add) public:
ASSIGNEXP(Min) MinAssignExp(Loc loc, Expression *e1, Expression *e2);
ASSIGNEXP(Mul) Identifier *opId(); /* For operator overloading */
ASSIGNEXP(Div) elem *toElem(IRState *irs);
ASSIGNEXP(Mod) };
ASSIGNEXP(And)
ASSIGNEXP(Or)
ASSIGNEXP(Xor)
#undef S
#if DMDV2 class MulAssignExp : public BinAssignExp
#define S(a) a {
ASSIGNEXP(Pow) public:
#undef S MulAssignExp(Loc loc, Expression *e1, Expression *e2);
#endif Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
#undef S class DivAssignExp : public BinAssignExp
#undef X {
public:
DivAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
#define X(a) class ModAssignExp : public BinAssignExp
{
public:
ModAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
#define S(a) class AndAssignExp : public BinAssignExp
ASSIGNEXP(Shl) {
ASSIGNEXP(Shr) public:
ASSIGNEXP(Ushr) AndAssignExp(Loc loc, Expression *e1, Expression *e2);
#undef S Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
#define S(a) a class OrAssignExp : public BinAssignExp
ASSIGNEXP(Cat) {
#undef S public:
OrAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
#undef X class XorAssignExp : public BinAssignExp
#undef ASSIGNEXP {
public:
XorAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class PowAssignExp : public BinAssignExp
{
public:
PowAssignExp(Loc loc, Expression *e1, Expression *e2);
Expression *semantic(Scope *sc);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class ShlAssignExp : public BinAssignExp
{
public:
ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class ShrAssignExp : public BinAssignExp
{
public:
ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class UshrAssignExp : public BinAssignExp
{
public:
UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class CatAssignExp : public BinAssignExp
{
public:
CatAssignExp(Loc loc, Expression *e1, Expression *e2);
Expression *semantic(Scope *sc);
Identifier *opId(); /* For operator overloading */
elem *toElem(IRState *irs);
};
class AddExp : public BinExp class AddExp : public BinExp
{ {
@@ -1678,7 +1738,6 @@ public:
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
}; };
#if DMDV2
class PowExp : public BinExp class PowExp : public BinExp
{ {
public: public:
@@ -1692,7 +1751,6 @@ public:
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
}; };
#endif
class ShlExp : public BinExp class ShlExp : public BinExp
{ {
@@ -1914,7 +1972,6 @@ public:
elem *toElem(IRState *irs); elem *toElem(IRState *irs);
}; };
#if DMDV2
/****************************************************************/ /****************************************************************/
class DefaultInitExp : public Expression class DefaultInitExp : public Expression
@@ -1966,8 +2023,6 @@ public:
Expression *resolveLoc(Loc loc, Scope *sc); Expression *resolveLoc(Loc loc, Scope *sc);
}; };
#endif
/****************************************************************/ /****************************************************************/
#if IN_LLVM #if IN_LLVM
+168 -127
View File
@@ -79,9 +79,6 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
isArrayOp = 0; isArrayOp = 0;
dArrayOp = NULL; dArrayOp = NULL;
semantic3Errors = 0; semantic3Errors = 0;
#if DMDV1
nestedFrameRef = 0;
#endif
fes = NULL; fes = NULL;
introducing = 0; introducing = 0;
tintro = NULL; tintro = NULL;
@@ -96,13 +93,12 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
#if IN_DMD #if IN_DMD
shidden = NULL; shidden = NULL;
#endif #endif
#if DMDV2
builtin = BUILTINunknown; builtin = BUILTINunknown;
tookAddressOf = 0; tookAddressOf = 0;
requiresClosure = false; requiresClosure = false;
flags = 0; flags = 0;
#endif
returns = NULL; returns = NULL;
gotos = NULL;
#if IN_LLVM #if IN_LLVM
// LDC // LDC
@@ -165,7 +161,6 @@ static Parameters *outToRef(Parameters* params)
void FuncDeclaration::semantic(Scope *sc) void FuncDeclaration::semantic(Scope *sc)
{ TypeFunction *f; { TypeFunction *f;
AggregateDeclaration *ad; AggregateDeclaration *ad;
StructDeclaration *sd;
ClassDeclaration *cd; ClassDeclaration *cd;
InterfaceDeclaration *id; InterfaceDeclaration *id;
bool doesoverride; bool doesoverride;
@@ -215,6 +210,8 @@ void FuncDeclaration::semantic(Scope *sc)
if (StructDeclaration *sd = ad->isStructDeclaration()) if (StructDeclaration *sd = ad->isStructDeclaration())
sd->makeNested(); sd->makeNested();
} }
if (sc->func)
storage_class |= sc->func->storage_class & STCdisable;
// Remove prefix storage classes silently. // Remove prefix storage classes silently.
if ((storage_class & STC_TYPECTOR) && !(ad || isNested())) if ((storage_class & STC_TYPECTOR) && !(ad || isNested()))
storage_class &= ~STC_TYPECTOR; storage_class &= ~STC_TYPECTOR;
@@ -223,7 +220,17 @@ void FuncDeclaration::semantic(Scope *sc)
FuncLiteralDeclaration *fld = isFuncLiteralDeclaration(); FuncLiteralDeclaration *fld = isFuncLiteralDeclaration();
if (fld && fld->treq) if (fld && fld->treq)
linkage = ((TypeFunction *)fld->treq->nextOf())->linkage; {
Type *treq = fld->treq;
assert(treq->nextOf()->ty == Tfunction);
if (treq->ty == Tdelegate)
fld->tok = TOKdelegate;
else if (treq->ty == Tpointer && treq->nextOf()->ty == Tfunction)
fld->tok = TOKfunction;
else
assert(0);
linkage = ((TypeFunction *)treq->nextOf())->linkage;
}
else else
linkage = sc->linkage; linkage = sc->linkage;
protection = sc->protection; protection = sc->protection;
@@ -360,7 +367,12 @@ void FuncDeclaration::semantic(Scope *sc)
storage_class &= ~STCref; storage_class &= ~STCref;
if (type->ty != Tfunction) if (type->ty != Tfunction)
{ {
error("%s must be a function instead of %s", toChars(), type->toChars()); if (type->ty != Terror)
{
error("%s must be a function instead of %s", toChars(), type->toChars());
type = Type::terror;
}
errors = true;
return; return;
} }
f = (TypeFunction *)type; f = (TypeFunction *)type;
@@ -407,7 +419,7 @@ void FuncDeclaration::semantic(Scope *sc)
} }
#endif #endif
sd = parent->isStructDeclaration(); StructDeclaration *sd = parent->isStructDeclaration();
if (sd) if (sd)
{ {
if (isCtorDeclaration()) if (isCtorDeclaration())
@@ -446,9 +458,7 @@ void FuncDeclaration::semantic(Scope *sc)
storage_class |= STCabstract; storage_class |= STCabstract;
if (isCtorDeclaration() || if (isCtorDeclaration() ||
#if DMDV2
isPostBlitDeclaration() || isPostBlitDeclaration() ||
#endif
isDtorDeclaration() || isDtorDeclaration() ||
isInvariantDeclaration() || isInvariantDeclaration() ||
isNewDeclaration() || isDelete()) isNewDeclaration() || isDelete())
@@ -496,12 +506,12 @@ void FuncDeclaration::semantic(Scope *sc)
continue; continue;
for (size_t j = 0; j < cbd->vtbl.dim; j++) for (size_t j = 0; j < cbd->vtbl.dim; j++)
{ {
FuncDeclaration *f = cbd->vtbl[j]->isFuncDeclaration(); FuncDeclaration *f2 = cbd->vtbl[j]->isFuncDeclaration();
if (!f || f->ident != ident) if (!f2 || f2->ident != ident)
continue; continue;
if (cbd->parent && cbd->parent->isTemplateInstance()) if (cbd->parent && cbd->parent->isTemplateInstance())
{ {
if (!f->functionSemantic()) if (!f2->functionSemantic())
goto Ldone; goto Ldone;
} }
may_override = true; may_override = true;
@@ -521,7 +531,7 @@ void FuncDeclaration::semantic(Scope *sc)
vi = cd->baseClass ? findVtblIndex((Dsymbols*)&cd->baseClass->vtbl, cd->baseClass->vtbl.dim) vi = cd->baseClass ? findVtblIndex((Dsymbols*)&cd->baseClass->vtbl, cd->baseClass->vtbl.dim)
: -1; : -1;
doesoverride = FALSE; doesoverride = false;
switch (vi) switch (vi)
{ {
case (size_t)-1: case (size_t)-1:
@@ -536,12 +546,12 @@ void FuncDeclaration::semantic(Scope *sc)
{ Dsymbol *s = cd->baseClass->search(loc, ident, 0); { Dsymbol *s = cd->baseClass->search(loc, ident, 0);
if (s) if (s)
{ {
FuncDeclaration *f = s->isFuncDeclaration(); FuncDeclaration *f2 = s->isFuncDeclaration();
if (f) if (f2)
{ {
f = f->overloadExactMatch(type); f2 = f2->overloadExactMatch(type);
if (f && f->isFinalFunc() && f->prot() != PROTprivate) if (f2 && f2->isFinalFunc() && f2->prot() != PROTprivate)
error("cannot override final function %s", f->toPrettyChars()); error("cannot override final function %s", f2->toPrettyChars());
} }
} }
} }
@@ -576,7 +586,7 @@ void FuncDeclaration::semantic(Scope *sc)
if (fdc == this) if (fdc == this)
{ {
doesoverride = TRUE; doesoverride = true;
break; break;
} }
@@ -596,11 +606,9 @@ void FuncDeclaration::semantic(Scope *sc)
if (fdv->isFinalFunc()) if (fdv->isFinalFunc())
error("cannot override final function %s", fdv->toPrettyChars()); error("cannot override final function %s", fdv->toPrettyChars());
doesoverride = TRUE; doesoverride = true;
#if DMDV2
if (!isOverride()) if (!isOverride())
::deprecation(loc, "overriding base class function without using override attribute is deprecated (%s overrides %s)", toPrettyChars(), fdv->toPrettyChars()); ::deprecation(loc, "overriding base class function without using override attribute is deprecated (%s overrides %s)", toPrettyChars(), fdv->toPrettyChars());
#endif
if (fdc->toParent() == parent) if (fdc->toParent() == parent)
{ {
@@ -675,13 +683,11 @@ void FuncDeclaration::semantic(Scope *sc)
*/ */
foverrides.push(fdv); foverrides.push(fdv);
#if DMDV2
/* Should we really require 'override' when implementing /* Should we really require 'override' when implementing
* an interface function? * an interface function?
*/ */
//if (!isOverride()) //if (!isOverride())
//warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); //warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
#endif
if (fdv->tintro) if (fdv->tintro)
ti = fdv->tintro; ti = fdv->tintro;
@@ -754,12 +760,12 @@ void FuncDeclaration::semantic(Scope *sc)
Dsymbol *s = search_function(b->base, ident); Dsymbol *s = search_function(b->base, ident);
if (s) if (s)
{ {
FuncDeclaration *f = s->isFuncDeclaration(); FuncDeclaration *f2 = s->isFuncDeclaration();
if (f) if (f2)
{ {
f = f->overloadExactMatch(type); f2 = f2->overloadExactMatch(type);
if (f && f->isFinalFunc() && f->prot() != PROTprivate) if (f2 && f2->isFinalFunc() && f2->prot() != PROTprivate)
error("cannot override final function %s.%s", b->base->toChars(), f->toPrettyChars()); error("cannot override final function %s.%s", b->base->toChars(), f2->toPrettyChars());
} }
} }
} }
@@ -790,10 +796,10 @@ void FuncDeclaration::semantic(Scope *sc)
} }
// If it's a member template // If it's a member template
ClassDeclaration *cd = ti->tempdecl->isClassMember(); ClassDeclaration *cd2 = ti->tempdecl->isClassMember();
if (cd) if (cd2)
{ {
error("cannot use template to add virtual function to class '%s'", cd->toChars()); error("cannot use template to add virtual function to class '%s'", cd2->toChars());
} }
} }
} }
@@ -985,14 +991,14 @@ Ldone:
{ {
printedMain = true; printedMain = true;
const char *name = FileName::searchPath(global.path, mod->srcfile->toChars(), 1); const char *name = FileName::searchPath(global.path, mod->srcfile->toChars(), 1);
printf("entry %-10s\t%s\n", type, name); fprintf(global.stdmsg, "entry %-10s\t%s\n", type, name);
} }
} }
if (fbody && isMain() && sc->module->isRoot()) if (fbody && isMain() && sc->module->isRoot())
genCmain(sc); genCmain(sc);
return; assert(type->ty != Terror || errors);
} }
void FuncDeclaration::semantic2(Scope *sc) void FuncDeclaration::semantic2(Scope *sc)
@@ -1133,8 +1139,6 @@ void FuncDeclaration::semantic3(Scope *sc)
// Declare hidden variable _arguments[] and _argptr // Declare hidden variable _arguments[] and _argptr
if (f->varargs == 1) if (f->varargs == 1)
{ {
Type *t;
#if !IN_GCC && !IN_LLVM #if !IN_GCC && !IN_LLVM
if (global.params.is64bit && !global.params.isWindows) if (global.params.is64bit && !global.params.isWindows)
{ // Declare save area for varargs registers { // Declare save area for varargs registers
@@ -1148,6 +1152,7 @@ void FuncDeclaration::semantic3(Scope *sc)
else else
{ {
v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL); v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL);
v_argsave->storage_class |= STCtemp;
v_argsave->semantic(sc2); v_argsave->semantic(sc2);
sc2->insert(v_argsave); sc2->insert(v_argsave);
v_argsave->parent = this; v_argsave->parent = this;
@@ -1158,22 +1163,24 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->linkage == LINKd) if (f->linkage == LINKd)
{ // Declare _arguments[] { // Declare _arguments[]
v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
v_arguments->storage_class = STCparameter; v_arguments->storage_class |= STCtemp | STCparameter;
v_arguments->semantic(sc2); v_arguments->semantic(sc2);
sc2->insert(v_arguments); sc2->insert(v_arguments);
v_arguments->parent = this; v_arguments->parent = this;
//t = Type::typeinfo->type->constOf()->arrayOf(); //Type *t = Type::typeinfo->type->constOf()->arrayOf();
t = Type::dtypeinfo->type->arrayOf(); Type *t = Type::dtypeinfo->type->arrayOf();
_arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL); _arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL);
_arguments->storage_class |= STCtemp;
_arguments->semantic(sc2); _arguments->semantic(sc2);
sc2->insert(_arguments); sc2->insert(_arguments);
_arguments->parent = this; _arguments->parent = this;
} }
if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters))) if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
{ // Declare _argptr { // Declare _argptr
t = Type::tvalist; Type *t = Type::tvalist;
argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL); argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL);
argptr->storage_class |= STCtemp;
argptr->semantic(sc2); argptr->semantic(sc2);
sc2->insert(argptr); sc2->insert(argptr);
argptr->parent = this; argptr->parent = this;
@@ -1237,20 +1244,23 @@ void FuncDeclaration::semantic3(Scope *sc)
{ {
Parameter *arg = Parameter::getNth(f->parameters, i); Parameter *arg = Parameter::getNth(f->parameters, i);
Identifier *id = arg->ident; Identifier *id = arg->ident;
StorageClass stc = 0;
if (!id) if (!id)
{ {
/* Generate identifier for un-named parameter, /* Generate identifier for un-named parameter,
* because we need it later on. * because we need it later on.
*/ */
arg->ident = id = Identifier::generateId("_param_", i); arg->ident = id = Identifier::generateId("_param_", i);
stc |= STCtemp;
} }
Type *vtype = arg->type; Type *vtype = arg->type;
VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
//printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
v->storage_class |= STCparameter; stc |= STCparameter;
if (f->varargs == 2 && i + 1 == nparams) if (f->varargs == 2 && i + 1 == nparams)
v->storage_class |= STCvariadic; stc |= STCvariadic;
v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); stc |= arg->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
v->storage_class = stc;
v->semantic(sc2); v->semantic(sc2);
if (!sc2->insert(v)) if (!sc2->insert(v))
error("parameter %s.%s is already defined", toChars(), v->toChars()); error("parameter %s.%s is already defined", toChars(), v->toChars());
@@ -1410,17 +1420,17 @@ void FuncDeclaration::semantic3(Scope *sc)
sym->parent = sc2->scopesym; sym->parent = sc2->scopesym;
sc2 = sc2->push(sym); sc2 = sc2->push(sym);
AggregateDeclaration *ad = isAggregateMember2(); AggregateDeclaration *ad2 = isAggregateMember2();
/* If this is a class constructor /* If this is a class constructor
*/ */
if (ad && isCtorDeclaration()) if (ad2 && isCtorDeclaration())
{ {
sc2->fieldinit = new unsigned[ad->fields.dim]; sc2->fieldinit = (unsigned *)mem.malloc(sizeof(unsigned) * ad2->fields.dim);
sc2->fieldinit_dim = ad->fields.dim; sc2->fieldinit_dim = ad2->fields.dim;
for (size_t i = 0; i < ad->fields.dim; i++) for (size_t i = 0; i < ad2->fields.dim; i++)
{ {
VarDeclaration *v = ad->fields[i]; VarDeclaration *v = ad2->fields[i];
v->ctorinit = 0; v->ctorinit = 0;
sc2->fieldinit[i] = 0; sc2->fieldinit[i] = 0;
} }
@@ -1483,26 +1493,15 @@ void FuncDeclaration::semantic3(Scope *sc)
if (fbody->isErrorStatement()) if (fbody->isErrorStatement())
; ;
else if (isCtorDeclaration() && ad) else if (isCtorDeclaration() && ad2)
{ {
#if DMDV2 ClassDeclaration *cd = ad2->isClassDeclaration();
// Check for errors related to 'nothrow'.
int nothrowErrors = global.errors;
int blockexit = fbody->blockExit(f->isnothrow);
if (f->isnothrow && (global.errors != nothrowErrors) )
::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars());
if (flags & FUNCFLAGnothrowInprocess)
f->isnothrow = !(blockexit & BEthrow);
#endif
//printf("callSuper = x%x\n", sc2->callSuper);
ClassDeclaration *cd = ad->isClassDeclaration();
// Verify that all the ctorinit fields got initialized // Verify that all the ctorinit fields got initialized
if (!(sc2->callSuper & CSXthis_ctor)) if (!(sc2->callSuper & CSXthis_ctor))
{ {
for (size_t i = 0; i < ad->fields.dim; i++) for (size_t i = 0; i < ad2->fields.dim; i++)
{ VarDeclaration *v = ad->fields[i]; { VarDeclaration *v = ad2->fields[i];
if (v->ctorinit == 0) if (v->ctorinit == 0)
{ {
@@ -1530,7 +1529,7 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
} }
} }
delete[] sc2->fieldinit; mem.free(sc2->fieldinit);
sc2->fieldinit = NULL; sc2->fieldinit = NULL;
sc2->fieldinit_dim = 0; sc2->fieldinit_dim = 0;
@@ -1556,6 +1555,15 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
} }
// Check for errors related to 'nothrow'.
int nothrowErrors = global.errors;
int blockexit = fbody->blockExit(f->isnothrow);
if (f->isnothrow && (global.errors != nothrowErrors) )
::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars());
if (flags & FUNCFLAGnothrowInprocess)
f->isnothrow = !(blockexit & BEthrow);
//printf("callSuper = x%x\n", sc2->callSuper);
/* Append: /* Append:
* return this; * return this;
* to function body * to function body
@@ -1585,7 +1593,6 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
else else
{ {
#if DMDV2
// Check for errors related to 'nothrow'. // Check for errors related to 'nothrow'.
int nothrowErrors = global.errors; int nothrowErrors = global.errors;
int blockexit = fbody->blockExit(f->isnothrow); int blockexit = fbody->blockExit(f->isnothrow);
@@ -1598,16 +1605,11 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
int offend = blockexit & BEfallthru; int offend = blockexit & BEfallthru;
#endif
if (type->nextOf()->ty != Tvoid) if (type->nextOf()->ty != Tvoid)
{ {
if (offend) if (offend)
{ Expression *e; { Expression *e;
#if DMDV1
warning(loc, "no return exp; or assert(0); at end of function");
#else
error("no return exp; or assert(0); at end of function"); error("no return exp; or assert(0); at end of function");
#endif
if (global.params.useAssert && if (global.params.useAssert &&
!global.params.useInline) !global.params.useInline)
{ /* Add an assert(0, msg); where the missing return { /* Add an assert(0, msg); where the missing return
@@ -1785,7 +1787,7 @@ void FuncDeclaration::semantic3(Scope *sc)
e = new AssignExp(Loc(), e1, e); e = new AssignExp(Loc(), e1, e);
e->type = t; e->type = t;
a->push(new ExpStatement(Loc(), e)); a->push(new ExpStatement(Loc(), e));
p->isargptr = TRUE; p->isargptr = true;
} }
#endif #endif
} }
@@ -1866,7 +1868,6 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
fbody = new CompoundStatement(Loc(), a); fbody = new CompoundStatement(Loc(), a);
#if DMDV2
/* Append destructor calls for parameters as finally blocks. /* Append destructor calls for parameters as finally blocks.
*/ */
if (parameters) if (parameters)
@@ -1890,7 +1891,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->isnothrow && (global.errors != nothrowErrors) ) if (f->isnothrow && (global.errors != nothrowErrors) )
::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars()); ::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars());
if (flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow) if (flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow)
f->isnothrow = FALSE; f->isnothrow = false;
if (fbody->blockExit(f->isnothrow) == BEfallthru) if (fbody->blockExit(f->isnothrow) == BEfallthru)
fbody = new CompoundStatement(Loc(), fbody, s); fbody = new CompoundStatement(Loc(), fbody, s);
else else
@@ -1900,13 +1901,11 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
// from this point on all possible 'throwers' are checked // from this point on all possible 'throwers' are checked
flags &= ~FUNCFLAGnothrowInprocess; flags &= ~FUNCFLAGnothrowInprocess;
#endif
if (isSynchronized()) if (isSynchronized())
{ /* Wrap the entire function body in a synchronized statement { /* Wrap the entire function body in a synchronized statement
*/ */
AggregateDeclaration *ad = isThis(); ClassDeclaration *cd = isThis() ? isThis()->isClassDeclaration() : parent->isClassDeclaration();
ClassDeclaration *cd = ad ? ad->isClassDeclaration() : parent->isClassDeclaration();
if (cd) if (cd)
{ {
@@ -1941,6 +1940,15 @@ void FuncDeclaration::semantic3(Scope *sc)
} }
} }
// Fix up forward-referenced gotos
if (gotos)
{
for (size_t i = 0; i < gotos->dim; ++i)
{
(*gotos)[i]->checkLabel();
}
}
sc2->callSuper = 0; sc2->callSuper = 0;
sc2->pop(); sc2->pop();
} }
@@ -1991,6 +1999,8 @@ void FuncDeclaration::semantic3(Scope *sc)
semanticRun = PASSsemantic3done; semanticRun = PASSsemantic3done;
semantic3Errors = global.errors - nerrors; semantic3Errors = global.errors - nerrors;
} }
if (type->ty == Terror)
errors = true;
//printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
//fflush(stdout); //fflush(stdout);
} }
@@ -2010,7 +2020,7 @@ bool FuncDeclaration::functionSemantic()
semantic(scope); semantic(scope);
global.gag = oldgag; global.gag = oldgag;
if (spec && global.errors != olderrs) if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs; spec->errors = global.errors - olderrs != 0;
if (olderrs != global.errors) // if errors compiling this function if (olderrs != global.errors) // if errors compiling this function
return false; return false;
} }
@@ -2060,7 +2070,7 @@ bool FuncDeclaration::functionSemantic3()
// If it is a speculatively-instantiated template, and errors occur, // If it is a speculatively-instantiated template, and errors occur,
// we need to mark the template as having errors. // we need to mark the template as having errors.
if (spec && global.errors != olderrs) if (spec && global.errors != olderrs)
spec->errors = global.errors - olderrs; spec->errors = global.errors - olderrs != 0;
if (olderrs != global.errors) // if errors compiling this function if (olderrs != global.errors) // if errors compiling this function
return false; return false;
} }
@@ -2074,9 +2084,9 @@ void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
StorageClassDeclaration::stcToCBuffer(buf, storage_class); StorageClassDeclaration::stcToCBuffer(buf, storage_class);
type->toCBuffer(buf, ident, hgs); type->toCBuffer(buf, ident, hgs);
if(hgs->hdrgen == 1) if (hgs->hdrgen == 1)
{ {
if(storage_class & STCauto) if (storage_class & STCauto)
{ {
hgs->autoMember++; hgs->autoMember++;
bodyToCBuffer(buf, hgs); bodyToCBuffer(buf, hgs);
@@ -2202,7 +2212,8 @@ void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ {
buf->writestring("out"); buf->writestring("out");
if (outId) if (outId)
{ buf->writebyte('('); {
buf->writebyte('(');
buf->writestring(outId->toChars()); buf->writestring(outId->toChars());
buf->writebyte(')'); buf->writebyte(')');
} }
@@ -2228,7 +2239,8 @@ void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs)
hgs->autoMember = saveauto; hgs->autoMember = saveauto;
} }
else else
{ buf->writeByte(';'); {
buf->writeByte(';');
buf->writenl(); buf->writenl();
} }
} }
@@ -2255,16 +2267,15 @@ void FuncDeclaration::buildResultVar()
outId = Id::result; // provide a default outId = Id::result; // provide a default
VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL); VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
if (outId == Id::result) v->storage_class |= STCtemp;
v->noscope = 1; v->noscope = 1;
v->storage_class |= STCresult; v->storage_class |= STCresult;
#if DMDV2
if (!isVirtual()) if (!isVirtual())
v->storage_class |= STCconst; v->storage_class |= STCconst;
if (tf->isref) if (tf->isref)
{ {
v->storage_class |= STCref | STCforeach; v->storage_class |= STCref | STCforeach;
} }
#endif
v->semantic(scout); v->semantic(scout);
if (!scout->insert(v)) if (!scout->insert(v))
error("out result %s is already defined", v->toChars()); error("out result %s is already defined", v->toChars());
@@ -2445,6 +2456,7 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf, Identifier *oid)
*/ */
ExpInitializer *ei = new ExpInitializer(Loc(), eresult); ExpInitializer *ei = new ExpInitializer(Loc(), eresult);
VarDeclaration *v = new VarDeclaration(Loc(), t1, Lexer::uniqueId("__covres"), ei); VarDeclaration *v = new VarDeclaration(Loc(), t1, Lexer::uniqueId("__covres"), ei);
v->storage_class |= STCtemp;
DeclarationExp *de = new DeclarationExp(Loc(), v); DeclarationExp *de = new DeclarationExp(Loc(), v);
VarExp *ve = new VarExp(Loc(), v); VarExp *ve = new VarExp(Loc(), v);
eresult = new CommaExp(Loc(), de, ve); eresult = new CommaExp(Loc(), de, ve);
@@ -2578,6 +2590,8 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
bool FuncDeclaration::overloadInsert(Dsymbol *s) bool FuncDeclaration::overloadInsert(Dsymbol *s)
{ {
//printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s->toChars(), toChars()); //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s->toChars(), toChars());
assert(s != this);
AliasDeclaration *ad = s->isAliasDeclaration(); AliasDeclaration *ad = s->isAliasDeclaration();
if (ad) if (ad)
{ {
@@ -2598,7 +2612,7 @@ bool FuncDeclaration::overloadInsert(Dsymbol *s)
if (overnext) if (overnext)
return overnext->overloadInsert(td); return overnext->overloadInsert(td);
overnext = td; overnext = td;
return TRUE; return true;
} }
FuncDeclaration *fd = s->isFuncDeclaration(); FuncDeclaration *fd = s->isFuncDeclaration();
if (!fd) if (!fd)
@@ -2620,7 +2634,7 @@ bool FuncDeclaration::overloadInsert(Dsymbol *s)
!isFuncAliasDeclaration()) !isFuncAliasDeclaration())
{ {
//printf("\tfalse: conflict %s\n", kind()); //printf("\tfalse: conflict %s\n", kind());
return FALSE; return false;
} }
#endif #endif
@@ -2760,7 +2774,6 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
return 1; return 1;
} }
#if DMDV2
/* Allow covariant matches, as long as the return type /* Allow covariant matches, as long as the return type
* is just a const conversion. * is just a const conversion.
* This allows things like pure functions to match with an impure function type. * This allows things like pure functions to match with an impure function type.
@@ -2774,7 +2787,6 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
return 1; return 1;
} }
} }
#endif
return 0; return 0;
} }
}; };
@@ -2788,7 +2800,7 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
static void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod) static void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod)
{ {
bool bothMutable = ((lhsMod & rhsMod) == 0); bool bothMutable = ((lhsMod & rhsMod) == 0);
bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared); bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared) != 0;
bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared); bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared);
if (lhsMod & MODshared) if (lhsMod & MODshared)
@@ -3006,7 +3018,6 @@ Lerror:
if (tthis) if (tthis)
tthis->modToBuffer(&fargsBuf); tthis->modToBuffer(&fargsBuf);
assert(!m.lastf || m.nextf);
if (!m.lastf && !(flags & 1)) // no match if (!m.lastf && !(flags & 1)) // no match
{ {
if (td) if (td)
@@ -3202,12 +3213,17 @@ int FuncDeclaration::getLevel(Loc loc, Scope *sc, FuncDeclaration *fd)
return level; return level;
Lerr: Lerr:
Dsymbol *p = toParent2();
while (p->toParent2()->isFuncDeclaration())
p = p->toParent2();
// Don't give error if in template constraint // Don't give error if in template constraint
if (!((sc->flags & SCOPEstaticif) && parent->isTemplateDeclaration())) if (!(sc->flags & SCOPEstaticif) && !p->parent->isTemplateDeclaration())
{ {
const char *xstatic = isStatic() ? "static " : "";
// better diagnostics for static functions // better diagnostics for static functions
::error(loc, "%s%s %s cannot access frame of function %s", ::error(loc, "%s%s %s cannot access frame of function %s",
isStatic() ? "static " : "", kind(), toPrettyChars(), fd->toPrettyChars()); xstatic, kind(), toPrettyChars(), fd->toPrettyChars());
} }
return 1; return 1;
} }
@@ -3414,7 +3430,7 @@ PURE FuncDeclaration::isPureBypassingInference()
/************************************** /**************************************
* The function is doing something impure, * The function is doing something impure,
* so mark it as impure. * so mark it as impure.
* If there's a purity error, return TRUE. * If there's a purity error, return true.
*/ */
bool FuncDeclaration::setImpure() bool FuncDeclaration::setImpure()
{ {
@@ -3423,8 +3439,8 @@ bool FuncDeclaration::setImpure()
flags &= ~FUNCFLAGpurityInprocess; flags &= ~FUNCFLAGpurityInprocess;
} }
else if (isPure()) else if (isPure())
return TRUE; return true;
return FALSE; return false;
} }
bool FuncDeclaration::isSafe() bool FuncDeclaration::isSafe()
@@ -3454,7 +3470,7 @@ bool FuncDeclaration::isTrusted()
/************************************** /**************************************
* The function is doing something unsave, * The function is doing something unsave,
* so mark it as unsafe. * so mark it as unsafe.
* If there's a safe error, return TRUE. * If there's a safe error, return true.
*/ */
bool FuncDeclaration::setUnsafe() bool FuncDeclaration::setUnsafe()
{ {
@@ -3464,8 +3480,8 @@ bool FuncDeclaration::setUnsafe()
((TypeFunction *)type)->trust = TRUSTsystem; ((TypeFunction *)type)->trust = TRUSTsystem;
} }
else if (isSafe()) else if (isSafe())
return TRUE; return true;
return FALSE; return false;
} }
/************************************** /**************************************
@@ -3737,7 +3753,7 @@ void FuncDeclaration::checkNestedReference(Scope *sc, Loc loc)
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
//printf("this = %s in [%s]\n", this->toChars(), this->loc.toChars()); //printf("this = %s in [%s]\n", this->toChars(), this->loc.toChars());
//printf("fdv = %s in [%s]\n", fdv->toChars(), fdv->loc.toChars()); //printf("fdv2 = %s in [%s]\n", fdv2->toChars(), fdv2->loc.toChars());
//printf("fdthis = %s in [%s]\n", fdthis->toChars(), fdthis->loc.toChars()); //printf("fdthis = %s in [%s]\n", fdthis->toChars(), fdthis->loc.toChars());
if (fdv2 && fdthis && fdv2 != fdthis) if (fdv2 && fdthis && fdv2 != fdthis)
@@ -3747,19 +3763,20 @@ void FuncDeclaration::checkNestedReference(Scope *sc, Loc loc)
{ {
bool found = false; bool found = false;
for (int i = 0; i < siblingCallers.dim; ++i) for (int i = 0; i < siblingCallers.dim; ++i)
{ if (siblingCallers[i] == fdthis) {
if (siblingCallers[i] == fdthis)
found = true; found = true;
} }
if (!found) if (!found)
{ {
//printf("\tadding sibling %s\n", fdthis->toPrettyChars()); //printf("\tadding sibling %s\n", fdthis->toPrettyChars());
siblingCallers.push(fdthis); if (!sc->intypeof && !(sc->flags & SCOPEcompile))
siblingCallers.push(fdthis);
} }
} }
} }
FuncDeclaration *fdv = toParent()->isFuncDeclaration(); FuncDeclaration *fdv = toParent2()->isFuncDeclaration();
fdv = toParent()->isFuncDeclaration();
if (fdv && fdthis && fdv != fdthis) if (fdv && fdthis && fdv != fdthis)
{ {
int lv = fdthis->getLevel(loc, sc, fdv); int lv = fdthis->getLevel(loc, sc, fdv);
@@ -3806,8 +3823,18 @@ void markAsNeedingClosure(Dsymbol *f, FuncDeclaration *outerFunc)
* Note that nested functions can only call lexically earlier nested * Note that nested functions can only call lexically earlier nested
* functions, so loops are impossible. * functions, so loops are impossible.
*/ */
bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc) bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc, void *p = NULL)
{ {
struct PrevSibling
{
PrevSibling *p;
FuncDeclaration *f;
};
PrevSibling ps;
ps.p = (PrevSibling *)p;
ps.f = f;
//printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f->toChars(), outerFunc->toChars()); //printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f->toChars(), outerFunc->toChars());
bool bAnyClosures = false; bool bAnyClosures = false;
for (int i = 0; i < f->siblingCallers.dim; ++i) for (int i = 0; i < f->siblingCallers.dim; ++i)
@@ -3818,7 +3845,19 @@ bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc)
markAsNeedingClosure(g, outerFunc); markAsNeedingClosure(g, outerFunc);
bAnyClosures = true; bAnyClosures = true;
} }
bAnyClosures |= checkEscapingSiblings(g, outerFunc);
PrevSibling *prev = (PrevSibling *)p;
while (1)
{
if (!prev)
{
bAnyClosures |= checkEscapingSiblings(g, outerFunc, &ps);
break;
}
if (prev->f == g)
break;
prev = prev->p;
}
} }
//printf("\t%d\n", bAnyClosures); //printf("\t%d\n", bAnyClosures);
return bAnyClosures; return bAnyClosures;
@@ -3831,7 +3870,6 @@ bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc)
* created for them. * created for them.
*/ */
#if DMDV2
bool FuncDeclaration::needsClosure() bool FuncDeclaration::needsClosure()
{ {
/* Need a closure for all the closureVars[] if any of the /* Need a closure for all the closureVars[] if any of the
@@ -3926,7 +3964,6 @@ Lyes:
//printf("\tneeds closure\n"); //printf("\tneeds closure\n");
return true; return true;
} }
#endif
/*********************************************** /***********************************************
* Determine if function's variables are referenced by a function * Determine if function's variables are referenced by a function
@@ -3935,11 +3972,7 @@ Lyes:
bool FuncDeclaration::hasNestedFrameRefs() bool FuncDeclaration::hasNestedFrameRefs()
{ {
#if DMDV2
if (closureVars.dim) if (closureVars.dim)
#else
if (nestedFrameRef)
#endif
return true; return true;
/* If a virtual method has contracts, assume its variables are referenced /* If a virtual method has contracts, assume its variables are referenced
@@ -4108,6 +4141,16 @@ void FuncLiteralDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
} }
} }
const char *FuncLiteralDeclaration::toPrettyChars()
{
if (parent)
{
TemplateInstance *ti = parent->isTemplateInstance();
if (ti)
return ti->tempdecl->toPrettyChars();
}
return Dsymbol::toPrettyChars();
}
/********************************* CtorDeclaration ****************************/ /********************************* CtorDeclaration ****************************/
@@ -4167,7 +4210,7 @@ void CtorDeclaration::semantic(Scope *sc)
storage_class |= STCdisable; storage_class |= STCdisable;
fbody = NULL; fbody = NULL;
} }
sd->noDefaultCtor = TRUE; sd->noDefaultCtor = true;
} }
else else
{ {
@@ -4204,7 +4247,6 @@ bool CtorDeclaration::addPostInvariant()
/********************************* PostBlitDeclaration ****************************/ /********************************* PostBlitDeclaration ****************************/
#if DMDV2
PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id) PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
: FuncDeclaration(loc, endloc, id, stc, NULL) : FuncDeclaration(loc, endloc, id, stc, NULL)
{ {
@@ -4238,7 +4280,7 @@ void PostBlitDeclaration::semantic(Scope *sc)
ad->postblits.push(this); ad->postblits.push(this);
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
sc = sc->push(); sc = sc->push();
sc->stc &= ~STCstatic; // not static sc->stc &= ~STCstatic; // not static
@@ -4274,7 +4316,6 @@ void PostBlitDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("this(this)"); buf->writestring("this(this)");
bodyToCBuffer(buf, hgs); bodyToCBuffer(buf, hgs);
} }
#endif
/********************************* DtorDeclaration ****************************/ /********************************* DtorDeclaration ****************************/
@@ -4318,7 +4359,7 @@ void DtorDeclaration::semantic(Scope *sc)
ad->dtors.push(this); ad->dtors.push(this);
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
sc = sc->push(); sc = sc->push();
sc->stc &= ~STCstatic; // not a static destructor sc->stc &= ~STCstatic; // not a static destructor
@@ -4398,7 +4439,7 @@ void StaticCtorDeclaration::semantic(Scope *sc)
} }
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); type = new TypeFunction(NULL, Type::tvoid, false, LINKd);
/* If the static ctor appears within a template instantiation, /* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors * it could get called multiple times by the module constructors
@@ -4414,7 +4455,7 @@ void StaticCtorDeclaration::semantic(Scope *sc)
*/ */
Identifier *id = Lexer::idPool("__gate"); Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL); VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL);
v->storage_class = isSharedStaticCtorDeclaration() ? STCstatic : STCtls; v->storage_class = STCtemp | (isSharedStaticCtorDeclaration() ? STCstatic : STCtls);
Statements *sa = new Statements(); Statements *sa = new Statements();
Statement *s = new ExpStatement(Loc(), v); Statement *s = new ExpStatement(Loc(), v);
sa->push(s); sa->push(s);
@@ -4452,7 +4493,7 @@ bool StaticCtorDeclaration::isVirtual()
bool StaticCtorDeclaration::hasStaticCtorOrDtor() bool StaticCtorDeclaration::hasStaticCtorOrDtor()
{ {
return TRUE; return true;
} }
bool StaticCtorDeclaration::addPreInvariant() bool StaticCtorDeclaration::addPreInvariant()
@@ -4529,7 +4570,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
} }
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
/* If the static ctor appears within a template instantiation, /* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors * it could get called multiple times by the module constructors
@@ -4546,7 +4587,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
*/ */
Identifier *id = Lexer::idPool("__gate"); Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL); VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, id, NULL);
v->storage_class = isSharedStaticDtorDeclaration() ? STCstatic : STCtls; v->storage_class = STCtemp | (isSharedStaticDtorDeclaration() ? STCstatic : STCtls);
Statements *sa = new Statements(); Statements *sa = new Statements();
Statement *s = new ExpStatement(Loc(), v); Statement *s = new ExpStatement(Loc(), v);
sa->push(s); sa->push(s);
@@ -4585,7 +4626,7 @@ bool StaticDtorDeclaration::isVirtual()
bool StaticDtorDeclaration::hasStaticCtorOrDtor() bool StaticDtorDeclaration::hasStaticCtorOrDtor()
{ {
return TRUE; return true;
} }
bool StaticDtorDeclaration::addPreInvariant() bool StaticDtorDeclaration::addPreInvariant()
@@ -4669,7 +4710,7 @@ void InvariantDeclaration::semantic(Scope *sc)
ad->invs.push(this); ad->invs.push(this);
} }
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd, storage_class); type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
sc = sc->push(); sc = sc->push();
sc->stc &= ~STCstatic; // not a static invariant sc->stc &= ~STCstatic; // not a static invariant
@@ -4752,7 +4793,7 @@ void UnitTestDeclaration::semantic(Scope *sc)
if (global.params.useUnitTests) if (global.params.useUnitTests)
{ {
if (!type) if (!type)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); type = new TypeFunction(NULL, Type::tvoid, false, LINKd);
Scope *sc2 = sc->push(); Scope *sc2 = sc->push();
sc2->linkage = LINKd; sc2->linkage = LINKd;
FuncDeclaration::semantic(sc2); FuncDeclaration::semantic(sc2);
-3
View File
@@ -18,9 +18,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#if __DMC__
#include <complex.h>
#endif
#include "rmem.h" #include "rmem.h"
-5
View File
@@ -25,11 +25,6 @@ Identifier::Identifier(const char *string, int value)
this->len = strlen(string); this->len = strlen(string);
} }
hash_t Identifier::hashCode()
{
return String::calcHash(string);
}
bool Identifier::equals(RootObject *o) bool Identifier::equals(RootObject *o)
{ {
#if IN_LLVM // ASan #if IN_LLVM // ASan
-1
View File
@@ -26,7 +26,6 @@ public:
Identifier(const char *string, int value); Identifier(const char *string, int value);
bool equals(RootObject *o); bool equals(RootObject *o);
hash_t hashCode();
int compare(RootObject *o); int compare(RootObject *o);
void print(); void print();
char *toChars(); char *toChars();
+1 -4
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2012 by Digital Mars // Copyright (c) 1999-2013 by Digital Mars
// All Rights Reserved // All Rights Reserved
// written by Walter Bright // written by Walter Bright
// http://www.digitalmars.com // http://www.digitalmars.com
@@ -405,9 +405,6 @@ int main()
} }
fprintf(fp, "// File generated by idgen.c\n"); 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, "#ifndef DMD_ID_H\n");
fprintf(fp, "#define DMD_ID_H 1\n"); fprintf(fp, "#define DMD_ID_H 1\n");
fprintf(fp, "class Identifier;\n"); fprintf(fp, "class Identifier;\n");
-16
View File
@@ -27,21 +27,6 @@
const char *importHint(const char *s) const char *importHint(const char *s)
{ {
#if DMDV1
static const char *modules[] =
{ "std.c.stdio",
"std.stdio",
"std.math",
"std.c.stdarg",
};
static const char *names[] =
{
"printf", NULL,
"writefln", NULL,
"sin", "cos", "sqrt", "fabs", NULL,
"__va_argsave_t", NULL,
};
#else
static const char *modules[] = static const char *modules[] =
{ "core.stdc.stdio", { "core.stdc.stdio",
"std.stdio", "std.stdio",
@@ -55,7 +40,6 @@ const char *importHint(const char *s)
"sin", "cos", "sqrt", "fabs", NULL, "sin", "cos", "sqrt", "fabs", NULL,
"__va_argsave_t", NULL, "__va_argsave_t", NULL,
}; };
#endif
int m = 0; int m = 0;
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++)
{ {
+1 -1
View File
@@ -289,7 +289,7 @@ void Import::semantic(Scope *sc)
* ModuleAliasIdentifier ] "\n" * ModuleAliasIdentifier ] "\n"
* *
* BasicImportDeclaration * BasicImportDeclaration
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection * ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")" * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
* *
* FilePath * FilePath
+25 -15
View File
@@ -287,13 +287,14 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needI
ExpInitializer *ie = new ExpInitializer(loc, e); ExpInitializer *ie = new ExpInitializer(loc, e);
return ie->semantic(sc, t, needInterpret); return ie->semantic(sc, t, needInterpret);
} }
else if (t->ty == Tdelegate && value.dim == 0) else if ((t->ty == Tdelegate || t->ty == Tpointer && t->nextOf()->ty == Tfunction) && value.dim == 0)
{ {
TOK tok = (t->ty == Tdelegate) ? TOKdelegate : TOKfunction;
/* Rewrite as empty delegate literal { } /* Rewrite as empty delegate literal { }
*/ */
Parameters *arguments = new Parameters; Parameters *arguments = new Parameters;
Type *tf = new TypeFunction(arguments, NULL, 0, LINKd); Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, Loc(), tf, TOKdelegate, NULL); FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, Loc(), tf, tok, NULL);
fd->fbody = new CompoundStatement(loc, new Statements()); fd->fbody = new CompoundStatement(loc, new Statements());
fd->endloc = loc; fd->endloc = loc;
Expression *e = new FuncExp(loc, fd); Expression *e = new FuncExp(loc, fd);
@@ -387,12 +388,9 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needIn
if (sem) // if semantic() already run if (sem) // if semantic() already run
return this; return this;
sem = 1; sem = 1;
type = t;
Initializer *aa = NULL;
t = t->toBasetype(); t = t->toBasetype();
switch (t->ty) switch (t->ty)
{ {
case Tpointer:
case Tsarray: case Tsarray:
case Tarray: case Tarray:
break; break;
@@ -402,15 +400,27 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needIn
break; break;
case Taarray: case Taarray:
// was actually an associative array literal case Tstruct: // consider implicit constructor call
aa = new ExpInitializer(loc, toAssocArrayLiteral()); {
return aa->semantic(sc, t, needInterpret); Expression *e;
if (t->ty == Taarray || isAssociativeArray())
e = toAssocArrayLiteral();
else
e = toExpression();
ExpInitializer *ei = new ExpInitializer(e->loc, e);
return ei->semantic(sc, t, needInterpret);
}
case Tpointer:
if (t->nextOf()->ty != Tfunction)
break;
default: default:
error(loc, "cannot use array to initialize %s", type->toChars()); error(loc, "cannot use array to initialize %s", t->toChars());
goto Lerr; goto Lerr;
} }
type = t;
length = 0; length = 0;
for (size_t i = 0; i < index.dim; i++) for (size_t i = 0; i < index.dim; i++)
{ {
@@ -422,7 +432,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needIn
sc = sc->endCTFE(); sc = sc->endCTFE();
idx = idx->ctfeInterpret(); idx = idx->ctfeInterpret();
index[i] = idx; index[i] = idx;
length = idx->toInteger(); length = (size_t)idx->toInteger();
if (idx->op == TOKerror) if (idx->op == TOKerror)
errors = true; errors = true;
} }
@@ -509,7 +519,7 @@ Expression *ArrayInitializer::toExpression(Type *tx)
switch (t->ty) switch (t->ty)
{ {
case Tsarray: case Tsarray:
edim = ((TypeSArray *)t)->dim->toInteger(); edim = (size_t)((TypeSArray *)t)->dim->toInteger();
break; break;
case Tpointer: case Tpointer:
@@ -529,7 +539,7 @@ Expression *ArrayInitializer::toExpression(Type *tx)
if (index[i]) if (index[i])
{ {
if (index[i]->op == TOKint64) if (index[i]->op == TOKint64)
j = index[i]->toInteger(); j = (size_t)index[i]->toInteger();
else else
goto Lno; goto Lno;
} }
@@ -544,7 +554,7 @@ Expression *ArrayInitializer::toExpression(Type *tx)
for (size_t i = 0, j = 0; i < value.dim; i++, j++) for (size_t i = 0, j = 0; i < value.dim; i++, j++)
{ {
if (index[i]) if (index[i])
j = (index[i])->toInteger(); j = (size_t)(index[i])->toInteger();
assert(j < edim); assert(j < edim);
Initializer *iz = value[i]; Initializer *iz = value[i];
if (!iz) if (!iz)
@@ -808,7 +818,7 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInte
exp = resolveProperties(sc, exp); exp = resolveProperties(sc, exp);
if (needInterpret) sc = sc->endCTFE(); if (needInterpret) sc = sc->endCTFE();
if (exp->op == TOKerror) if (exp->op == TOKerror)
return this; return new ErrorInitializer();
int olderrors = global.errors; int olderrors = global.errors;
if (needInterpret) if (needInterpret)
@@ -966,7 +976,7 @@ Expression *ExpInitializer::toExpression(Type *t)
if (tb->ty == Tsarray && exp->implicitConvTo(tb->nextOf())) if (tb->ty == Tsarray && exp->implicitConvTo(tb->nextOf()))
{ {
TypeSArray *tsa = (TypeSArray *)tb; TypeSArray *tsa = (TypeSArray *)tb;
size_t d = tsa->dim->toInteger(); size_t d = (size_t)tsa->dim->toInteger();
Expressions *elements = new Expressions(); Expressions *elements = new Expressions();
elements->setDim(d); elements->setDim(d);
for (size_t i = 0; i < d; i++) for (size_t i = 0; i < d; i++)
+237 -152
View File
@@ -156,12 +156,10 @@ int ReturnStatement::inlineCost(InlineCostState *ics)
return expressionInlineCost(exp, ics); return expressionInlineCost(exp, ics);
} }
#if DMDV2
int ImportStatement::inlineCost(InlineCostState *ics) int ImportStatement::inlineCost(InlineCostState *ics)
{ {
return 0; return 0;
} }
#endif
int ForStatement::inlineCost(InlineCostState *ics) int ForStatement::inlineCost(InlineCostState *ics)
{ {
@@ -253,10 +251,8 @@ int ThisExp::inlineCost3(InlineCostState *ics)
int StructLiteralExp::inlineCost3(InlineCostState *ics) int StructLiteralExp::inlineCost3(InlineCostState *ics)
{ {
//printf("StructLiteralExp::inlineCost3() %s\n", toChars()); //printf("StructLiteralExp::inlineCost3() %s\n", toChars());
#if DMDV2
if (sd->isNested()) if (sd->isNested())
return COST_MAX; return COST_MAX;
#endif
return 1; return 1;
} }
@@ -309,10 +305,8 @@ int DeclarationExp::inlineCost3(InlineCostState *ics)
return COST_MAX; return COST_MAX;
cost += 1; cost += 1;
#if DMDV2
if (vd->edtor) // if destructor required if (vd->edtor) // if destructor required
return COST_MAX; // needs work to make this work return COST_MAX; // needs work to make this work
#endif
// Scan initializer (vd->init) // Scan initializer (vd->init)
if (vd->init) if (vd->init)
{ {
@@ -332,9 +326,7 @@ int DeclarationExp::inlineCost3(InlineCostState *ics)
declaration->isClassDeclaration() || declaration->isClassDeclaration() ||
declaration->isFuncDeclaration() || declaration->isFuncDeclaration() ||
declaration->isTypedefDeclaration() || declaration->isTypedefDeclaration() ||
#if DMDV2
declaration->isAttribDeclaration() || declaration->isAttribDeclaration() ||
#endif
declaration->isTemplateMixin()) declaration->isTemplateMixin())
return COST_MAX; return COST_MAX;
@@ -364,13 +356,15 @@ int CallExp::inlineCost3(InlineCostState *ics)
struct InlineDoState struct InlineDoState
{ {
// inline context
VarDeclaration *vthis; VarDeclaration *vthis;
Dsymbols from; // old Dsymbols Dsymbols from; // old Dsymbols
Dsymbols to; // parallel array of new Dsymbols Dsymbols to; // parallel array of new Dsymbols
Dsymbol *parent; // new parent Dsymbol *parent; // new parent
FuncDeclaration *fd; // function being inlined (old parent) FuncDeclaration *fd; // function being inlined (old parent)
// inline result
bool foundReturn;
}; };
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
Statement *Statement::doInlineStatement(InlineDoState *ids) Statement *Statement::doInlineStatement(InlineDoState *ids)
@@ -397,20 +391,7 @@ Statement *CompoundStatement::doInlineStatement(InlineDoState *ids)
if (s) if (s)
{ {
as->push(s->doInlineStatement(ids)); as->push(s->doInlineStatement(ids));
if (s->isReturnStatement()) if (ids->foundReturn)
break;
/* Check for:
* if (condition)
* return exp1;
* else
* return exp2;
*/
IfStatement *ifs = s->isIfStatement();
if (ifs && ifs->elsebody && ifs->ifbody &&
ifs->ifbody->isReturnStatement() &&
ifs->elsebody->isReturnStatement()
)
break; break;
} }
else else
@@ -429,7 +410,7 @@ Statement *UnrolledLoopStatement::doInlineStatement(InlineDoState *ids)
if (s) if (s)
{ {
as->push(s->doInlineStatement(ids)); as->push(s->doInlineStatement(ids));
if (s->isReturnStatement()) if (ids->foundReturn)
break; break;
} }
else else
@@ -450,7 +431,11 @@ Statement *IfStatement::doInlineStatement(InlineDoState *ids)
Expression *condition = this->condition ? this->condition->doInline(ids) : NULL; Expression *condition = this->condition ? this->condition->doInline(ids) : NULL;
Statement *ifbody = this->ifbody ? this->ifbody->doInlineStatement(ids) : NULL; Statement *ifbody = this->ifbody ? this->ifbody->doInlineStatement(ids) : NULL;
bool bodyReturn = ids->foundReturn;
ids->foundReturn = false;
Statement *elsebody = this->elsebody ? this->elsebody->doInlineStatement(ids) : NULL; Statement *elsebody = this->elsebody ? this->elsebody->doInlineStatement(ids) : NULL;
ids->foundReturn = ids->foundReturn && bodyReturn;
return new IfStatement(loc, arg, condition, ifbody, elsebody); return new IfStatement(loc, arg, condition, ifbody, elsebody);
} }
@@ -458,15 +443,14 @@ Statement *IfStatement::doInlineStatement(InlineDoState *ids)
Statement *ReturnStatement::doInlineStatement(InlineDoState *ids) Statement *ReturnStatement::doInlineStatement(InlineDoState *ids)
{ {
//printf("ReturnStatement::doInlineStatement() '%s'\n", exp ? exp->toChars() : ""); //printf("ReturnStatement::doInlineStatement() '%s'\n", exp ? exp->toChars() : "");
ids->foundReturn = true;
return new ReturnStatement(loc, exp ? exp->doInline(ids) : NULL); return new ReturnStatement(loc, exp ? exp->doInline(ids) : NULL);
} }
#if DMDV2
Statement *ImportStatement::doInlineStatement(InlineDoState *ids) Statement *ImportStatement::doInlineStatement(InlineDoState *ids)
{ {
return NULL; return NULL;
} }
#endif
Statement *ForStatement::doInlineStatement(InlineDoState *ids) Statement *ForStatement::doInlineStatement(InlineDoState *ids)
{ {
@@ -507,20 +491,7 @@ Expression *CompoundStatement::doInline(InlineDoState *ids)
{ {
Expression *e2 = s->doInline(ids); Expression *e2 = s->doInline(ids);
e = Expression::combine(e, e2); e = Expression::combine(e, e2);
if (s->isReturnStatement()) if (ids->foundReturn)
break;
/* Check for:
* if (condition)
* return exp1;
* else
* return exp2;
*/
IfStatement *ifs = s->isIfStatement();
if (ifs && ifs->elsebody && ifs->ifbody &&
ifs->ifbody->isReturnStatement() &&
ifs->elsebody->isReturnStatement()
)
break; break;
} }
@@ -539,7 +510,7 @@ Expression *UnrolledLoopStatement::doInline(InlineDoState *ids)
{ {
Expression *e2 = s->doInline(ids); Expression *e2 = s->doInline(ids);
e = Expression::combine(e, e2); e = Expression::combine(e, e2);
if (s->isReturnStatement()) if (ids->foundReturn)
break; break;
} }
} }
@@ -562,9 +533,13 @@ Expression *IfStatement::doInline(InlineDoState *ids)
econd = condition->doInline(ids); econd = condition->doInline(ids);
assert(econd); assert(econd);
if (ifbody) if (ifbody)
{
e1 = ifbody->doInline(ids); e1 = ifbody->doInline(ids);
}
else else
e1 = NULL; e1 = NULL;
bool bodyReturn = ids->foundReturn;
ids->foundReturn = false;
if (elsebody) if (elsebody)
e2 = elsebody->doInline(ids); e2 = elsebody->doInline(ids);
else else
@@ -573,6 +548,12 @@ Expression *IfStatement::doInline(InlineDoState *ids)
{ {
e = new CondExp(econd->loc, econd, e1, e2); e = new CondExp(econd->loc, econd, e1, e2);
e->type = e1->type; e->type = e1->type;
if (e->type->ty == Ttuple)
{
e1->type = Type::tvoid;
e2->type = Type::tvoid;
e->type = Type::tvoid;
}
} }
else if (e1) else if (e1)
{ {
@@ -588,21 +569,21 @@ Expression *IfStatement::doInline(InlineDoState *ids)
{ {
e = econd; e = econd;
} }
ids->foundReturn = ids->foundReturn && bodyReturn;
return e; return e;
} }
Expression *ReturnStatement::doInline(InlineDoState *ids) Expression *ReturnStatement::doInline(InlineDoState *ids)
{ {
//printf("ReturnStatement::doInline() '%s'\n", exp ? exp->toChars() : ""); //printf("ReturnStatement::doInline() '%s'\n", exp ? exp->toChars() : "");
ids->foundReturn = true;
return exp ? exp->doInline(ids) : NULL; return exp ? exp->doInline(ids) : NULL;
} }
#if DMDV2
Expression *ImportStatement::doInline(InlineDoState *ids) Expression *ImportStatement::doInline(InlineDoState *ids)
{ {
return NULL; return NULL;
} }
#endif
/* --------------------------------------------------------------- */ /* --------------------------------------------------------------- */
@@ -643,7 +624,6 @@ Expression *SymOffExp::doInline(InlineDoState *ids)
if (var == ids->from[i]) if (var == ids->from[i])
{ {
SymOffExp *se = (SymOffExp *)copy(); SymOffExp *se = (SymOffExp *)copy();
se->var = (Declaration *)ids->to[i]; se->var = (Declaration *)ids->to[i];
return se; return se;
} }
@@ -659,7 +639,6 @@ Expression *VarExp::doInline(InlineDoState *ids)
if (var == ids->from[i]) if (var == ids->from[i])
{ {
VarExp *ve = (VarExp *)copy(); VarExp *ve = (VarExp *)copy();
ve->var = (Declaration *)ids->to[i]; ve->var = (Declaration *)ids->to[i];
return ve; return ve;
} }
@@ -755,11 +734,9 @@ Expression *SuperExp::doInline(InlineDoState *ids)
} }
Expression *DeclarationExp::doInline(InlineDoState *ids) Expression *DeclarationExp::doInline(InlineDoState *ids)
{ DeclarationExp *de = (DeclarationExp *)copy(); {
VarDeclaration *vd;
//printf("DeclarationExp::doInline(%s)\n", toChars()); //printf("DeclarationExp::doInline(%s)\n", toChars());
vd = declaration->isVarDeclaration(); VarDeclaration *vd = declaration->isVarDeclaration();
if (vd) if (vd)
{ {
#if 0 #if 0
@@ -780,9 +757,33 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
else else
{ {
VarDeclaration *vto; VarDeclaration *vto;
if (ids->fd && vd == ids->fd->nrvo_var)
{
for (size_t i = 0; i < ids->from.dim; i++)
{
if (vd == ids->from[i])
{
vto = (VarDeclaration *)ids->to[i];
if ((vd->storage_class & STCref) == 0 &&
(vto->storage_class & STCref))
{
Expression *e;
if (vd->init && !vd->init->isVoidInitializer())
{
e = vd->init->toExpression();
assert(e);
e = e->doInline(ids);
}
else
e = new IntegerExp(vd->init->loc, 0, Type::tint32);
return e;
}
goto L1;
}
}
}
vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init);
memcpy((void*)vto, (void*)vd, sizeof(VarDeclaration)); memcpy((void *)vto, (void *)vd, sizeof(VarDeclaration));
vto->parent = ids->parent; vto->parent = ids->parent;
#if IN_DMD #if IN_DMD
vto->csym = NULL; vto->csym = NULL;
@@ -792,6 +793,7 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
ids->from.push(vd); ids->from.push(vd);
ids->to.push(vto); ids->to.push(vto);
L1:
if (vd->init) if (vd->init)
{ {
if (vd->init->isVoidInitializer()) if (vd->init->isVoidInitializer())
@@ -805,13 +807,15 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
vto->init = new ExpInitializer(e->loc, e->doInline(ids)); vto->init = new ExpInitializer(e->loc, e->doInline(ids));
} }
} }
DeclarationExp *de = (DeclarationExp *)copy();
de->declaration = (Dsymbol *) (void *)vto; de->declaration = (Dsymbol *) (void *)vto;
return de;
} }
} }
/* This needs work, like DeclarationExp::toElem(), if we are /* This needs work, like DeclarationExp::toElem(), if we are
* to handle TemplateMixin's. For now, we just don't inline them. * to handle TemplateMixin's. For now, we just don't inline them.
*/ */
return de; return Expression::doInline(ids);
} }
Expression *NewExp::doInline(InlineDoState *ids) Expression *NewExp::doInline(InlineDoState *ids)
@@ -1051,7 +1055,7 @@ Statement *ExpStatement::inlineScan(InlineScanState *iss)
if (fd && fd != iss->fd && fd->canInline(0, 0, 1)) if (fd && fd != iss->fd && fd->canInline(0, 0, 1))
{ {
Statement *s; Statement *s;
fd->expandInline(iss, NULL, ce->arguments, &s); fd->expandInline(iss, NULL, NULL, ce->arguments, &s);
return s; return s;
} }
} }
@@ -1126,7 +1130,6 @@ Statement *ForeachStatement::inlineScan(InlineScanState *iss)
} }
#if DMDV2
Statement *ForeachRangeStatement::inlineScan(InlineScanState *iss) Statement *ForeachRangeStatement::inlineScan(InlineScanState *iss)
{ {
lwr = lwr->inlineScan(iss); lwr = lwr->inlineScan(iss);
@@ -1135,7 +1138,6 @@ Statement *ForeachRangeStatement::inlineScan(InlineScanState *iss)
body = body->inlineScan(iss); body = body->inlineScan(iss);
return this; return this;
} }
#endif
Statement *IfStatement::inlineScan(InlineScanState *iss) Statement *IfStatement::inlineScan(InlineScanState *iss)
@@ -1281,7 +1283,7 @@ Expression *Expression::inlineScan(InlineScanState *iss)
return this; return this;
} }
void scanVar(Dsymbol *s, InlineScanState *iss) Expression *scanVar(Dsymbol *s, InlineScanState *iss)
{ {
//printf("scanVar(%s %s)\n", s->kind(), s->toPrettyChars()); //printf("scanVar(%s %s)\n", s->kind(), s->toPrettyChars());
VarDeclaration *vd = s->isVarDeclaration(); VarDeclaration *vd = s->isVarDeclaration();
@@ -1291,47 +1293,20 @@ void scanVar(Dsymbol *s, InlineScanState *iss)
if (td) if (td)
{ {
for (size_t i = 0; i < td->objects->dim; i++) for (size_t i = 0; i < td->objects->dim; i++)
{ DsymbolExp *se = (DsymbolExp *)(*td->objects)[i]; {
DsymbolExp *se = (DsymbolExp *)(*td->objects)[i];
assert(se->op == TOKdsymbol); assert(se->op == TOKdsymbol);
scanVar(se->s, iss); scanVar(se->s, iss); // TODO
} }
} }
else else if (vd->init)
{ {
// Scan initializer (vd->init) if (ExpInitializer *ie = vd->init->isExpInitializer())
if (vd->init)
{ {
ExpInitializer *ie = vd->init->isExpInitializer(); Expression *e = ie->exp->inlineScan(iss);
if (vd->init != ie) // DeclareExp with vd appears in e
if (ie) return e;
{ ie->exp = e;
#if DMDV2
if (vd->type)
{ Type *tb = vd->type->toBasetype();
if (tb->ty == Tstruct)
{ StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->cpctor)
{ /* The problem here is that if the initializer is a
* function call that returns a struct S with a cpctor:
* S s = foo();
* the postblit is done by the return statement in foo()
* in s2ir.c, the intermediate code generator.
* But, if foo() is inlined and now the code looks like:
* S s = x;
* the postblit is not there, because such assignments
* are rewritten as s.cpctor(&x) by the front end.
* So, the inlining won't get the postblit called.
* Work around by not inlining these cases.
* A proper fix would be to move all the postblit
* additions to the front end.
*/
return;
}
}
}
#endif
ie->exp = ie->exp->inlineScan(iss);
}
} }
} }
} }
@@ -1339,13 +1314,14 @@ void scanVar(Dsymbol *s, InlineScanState *iss)
{ {
s->inlineScan(); s->inlineScan();
} }
return NULL;
} }
Expression *DeclarationExp::inlineScan(InlineScanState *iss) Expression *DeclarationExp::inlineScan(InlineScanState *iss)
{ {
//printf("DeclarationExp::inlineScan()\n"); //printf("DeclarationExp::inlineScan()\n");
scanVar(declaration, iss); Expression *e = scanVar(declaration, iss);
return this; return e ? e : this;
} }
Expression *UnaExp::inlineScan(InlineScanState *iss) Expression *UnaExp::inlineScan(InlineScanState *iss)
@@ -1369,9 +1345,51 @@ Expression *BinExp::inlineScan(InlineScanState *iss)
return this; return this;
} }
Expression *AssignExp::inlineScan(InlineScanState *iss)
{
if (op == TOKconstruct && e2->op == TOKcall)
{
CallExp *ce = (CallExp *)e2;
if (ce->f && ce->f->nrvo_var) // NRVO
{
if (e1->op == TOKvar)
{
/* Inlining:
* S s = foo(); // initializing by rvalue
* S s = S(1); // constrcutor call
*/
Declaration *d = ((VarExp *)e1)->var;
if (d->storage_class & (STCout | STCref)) // refinit
goto L1;
}
else
{
/* Inlining:
* this.field = foo(); // inside constructor
*/
e1 = e1->inlineScan(iss);
}
Expression *e = ce->inlineScan(iss, e1);
if (e != ce)
{
//printf("call with nrvo: %s ==> %s\n", toChars(), e->toChars());
return e;
}
}
}
L1:
return BinExp::inlineScan(iss);
}
Expression *CallExp::inlineScan(InlineScanState *iss) Expression *CallExp::inlineScan(InlineScanState *iss)
{ Expression *e = this; {
return inlineScan(iss, NULL);
}
Expression *CallExp::inlineScan(InlineScanState *iss, Expression *eret)
{
Expression *e = this;
//printf("CallExp::inlineScan()\n"); //printf("CallExp::inlineScan()\n");
e1 = e1->inlineScan(iss); e1 = e1->inlineScan(iss);
@@ -1384,7 +1402,7 @@ Expression *CallExp::inlineScan(InlineScanState *iss)
if (fd && fd != iss->fd && fd->canInline(0, 0, 0)) if (fd && fd != iss->fd && fd->canInline(0, 0, 0))
{ {
e = fd->expandInline(iss, NULL, arguments, NULL); e = fd->expandInline(iss, eret, NULL, arguments, NULL);
} }
} }
else if (e1->op == TOKdotvar) else if (e1->op == TOKdotvar)
@@ -1404,10 +1422,12 @@ Expression *CallExp::inlineScan(InlineScanState *iss)
; ;
} }
else else
e = fd->expandInline(iss, dve->e1, arguments, NULL); e = fd->expandInline(iss, eret, dve->e1, arguments, NULL);
} }
} }
if (e && type->ty != Tvoid)
e->type = type;
return e; return e;
} }
@@ -1680,12 +1700,13 @@ Lno:
return 0; return 0;
} }
Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethis, Expressions *arguments, Statement **ps) Expression *FuncDeclaration::expandInline(InlineScanState *iss,
Expression *eret, Expression *ethis, Expressions *arguments, Statement **ps)
{ {
InlineDoState ids; InlineDoState ids;
DeclarationExp *de;
Expression *e = NULL; Expression *e = NULL;
Statements *as = NULL; Statements *as = NULL;
TypeFunction *tf = (TypeFunction*)type;
#if LOG || CANINLINE_LOG #if LOG || CANINLINE_LOG
printf("FuncDeclaration::expandInline('%s')\n", toChars()); printf("FuncDeclaration::expandInline('%s')\n", toChars());
@@ -1698,6 +1719,38 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
if (ps) if (ps)
as = new Statements(); as = new Statements();
VarDeclaration *vret = NULL;
if (eret)
{
if (eret->op == TOKvar)
{
vret = ((VarExp *)eret)->var->isVarDeclaration();
assert(!(vret->storage_class & (STCout | STCref)));
}
else
{
/* Inlining:
* this.field = foo(); // inside constructor
*/
vret = new VarDeclaration(loc, eret->type, Lexer::uniqueId("_satmp"), NULL);
vret->storage_class |= STCtemp | STCforeach | STCref;
vret->linkage = LINKd;
vret->parent = iss->fd;
Expression *de;
de = new DeclarationExp(loc, vret);
de->type = Type::tvoid;
e = Expression::combine(e, de);
Expression *ex;
ex = new VarExp(loc, vret);
ex->type = vret->type;
ex = new ConstructExp(loc, ex, eret);
ex->type = vret->type;
e = Expression::combine(e, ex);
}
}
// Set up vthis // Set up vthis
if (ethis) if (ethis)
{ {
@@ -1737,12 +1790,31 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
// Set up parameters // Set up parameters
if (ethis) if (ethis)
{ {
e = new DeclarationExp(Loc(), ids.vthis); Expression *de = new DeclarationExp(Loc(), ids.vthis);
e->type = Type::tvoid; de->type = Type::tvoid;
if (as) e = Expression::combine(e, de);
as->push(new ExpStatement(e->loc, e));
} }
if (!ps && nrvo_var)
{
if (vret)
{
ids.from.push(nrvo_var);
ids.to.push(vret);
}
else
{
Identifier* tmp = Identifier::generateId("__nrvoretval");
VarDeclaration* vd = new VarDeclaration(loc, nrvo_var->type, tmp, NULL);
assert(!tf->isref);
vd->storage_class = STCtemp | STCrvalue;
vd->linkage = tf->linkage;
vd->parent = iss->fd;
ids.from.push(nrvo_var);
ids.to.push(vd);
}
}
if (arguments && arguments->dim) if (arguments && arguments->dim)
{ {
assert(parameters->dim == arguments->dim); assert(parameters->dim == arguments->dim);
@@ -1758,7 +1830,7 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
ei = new ExpInitializer(arg->loc, arg); ei = new ExpInitializer(arg->loc, arg);
vto = new VarDeclaration(vfrom->loc, vfrom->type, vfrom->ident, ei); vto = new VarDeclaration(vfrom->loc, vfrom->type, vfrom->ident, ei);
vto->storage_class |= vfrom->storage_class & (STCin | STCout | STClazy | STCref); vto->storage_class |= vfrom->storage_class & (STCtemp | STCin | STCout | STClazy | STCref);
vto->linkage = vfrom->linkage; vto->linkage = vfrom->linkage;
vto->parent = iss->fd; vto->parent = iss->fd;
//printf("vto = '%s', vto->storage_class = x%x\n", vto->toChars(), vto->storage_class); //printf("vto = '%s', vto->storage_class = x%x\n", vto->toChars(), vto->storage_class);
@@ -1770,25 +1842,24 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
ei->exp = new ConstructExp(vto->loc, ve, arg); ei->exp = new ConstructExp(vto->loc, ve, arg);
ei->exp->type = ve->type; ei->exp->type = ve->type;
//ve->type->print(); //ve->type->print();
//arg->type->print(); //arg->type->print();
//ei->exp->print(); //ei->exp->print();
ids.from.push(vfrom); ids.from.push(vfrom);
ids.to.push(vto); ids.to.push(vto);
de = new DeclarationExp(Loc(), vto); DeclarationExp *de = new DeclarationExp(Loc(), vto);
de->type = Type::tvoid; de->type = Type::tvoid;
if (as) e = Expression::combine(e, de);
as->push(new ExpStatement(Loc(), de));
else
e = Expression::combine(e, de);
} }
} }
if (ps) if (ps)
{ {
if (e)
as->push(new ExpStatement(Loc(), e));
inlineNest++; inlineNest++;
Statement *s = fbody->doInlineStatement(&ids); Statement *s = fbody->doInlineStatement(&ids);
as->push(s); as->push(s);
@@ -1804,55 +1875,69 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
//eb->type->print(); //eb->type->print();
//eb->print(); //eb->print();
//eb->dump(0); //eb->dump(0);
// Bugzilla 11322:
if (tf->isref)
e = e->toLvalue(NULL, NULL);
/* There's a problem if what the function returns is used subsequently as an
* lvalue, as in a struct return that is then used as a 'this'.
* If we take the address of the return value, we will be taking the address
* of the original, not the copy. Fix this by assigning the return value to
* a temporary, then returning the temporary. If the temporary is used as an
* lvalue, it will work.
* This only happens with struct returns.
* See Bugzilla 2127 for an example.
*
* On constructor call making __inlineretval is merely redundant, because
* the returned reference is exactly same as vthis, and the 'this' variable
* already exists at the caller side.
*/
if (tf->next->ty == Tstruct && !nrvo_var && !isCtorDeclaration())
{
/* Generate a new variable to hold the result and initialize it with the
* inlined body of the function:
* tret __inlineretval = e;
*/
ExpInitializer* ei = new ExpInitializer(loc, e);
Identifier* tmp = Identifier::generateId("__inlineretval");
VarDeclaration* vd = new VarDeclaration(loc, tf->next, tmp, ei);
vd->storage_class = (tf->isref ? STCref : 0) | STCtemp | STCrvalue;
vd->linkage = tf->linkage;
vd->parent = iss->fd;
VarExp *ve = new VarExp(loc, vd);
ve->type = tf->next;
ei->exp = new ConstructExp(loc, ve, e);
ei->exp->type = ve->type;
DeclarationExp* de = new DeclarationExp(Loc(), vd);
de->type = Type::tvoid;
// Chain the two together:
// ( typeof(return) __inlineretval = ( inlined body )) , __inlineretval
e = Expression::combine(de, ve);
//fprintf(stderr, "CallExp::inlineScan: e = "); e->print();
}
} }
//printf("%s->expandInline = { %s }\n", toChars(), e->toChars()); //printf("%s->expandInline = { %s }\n", toChars(), e->toChars());
/* There's a problem if what the function returns is used subsequently as an
* lvalue, as in a struct return that is then used as a 'this'.
* If we take the address of the return value, we will be taking the address
* of the original, not the copy. Fix this by assigning the return value to
* a temporary, then returning the temporary. If the temporary is used as an
* lvalue, it will work.
* This only happens with struct returns.
* See Bugzilla 2127 for an example.
*/
TypeFunction *tf = (TypeFunction*)type;
if (!ps && tf->next->ty == Tstruct)
{
/* Generate a new variable to hold the result and initialize it with the
* inlined body of the function:
* tret __inlineretval = e;
*/
ExpInitializer* ei = new ExpInitializer(loc, e);
Identifier* tmp = Identifier::generateId("__inlineretval");
VarDeclaration* vd = new VarDeclaration(loc, tf->next, tmp, ei);
vd->storage_class = (tf->isref ? STCref : 0) | STCtemp;
vd->linkage = tf->linkage;
vd->parent = iss->fd;
VarExp *ve = new VarExp(loc, vd);
ve->type = tf->next;
ei->exp = new ConstructExp(loc, ve, e);
ei->exp->type = ve->type;
DeclarationExp* de = new DeclarationExp(Loc(), vd);
de->type = Type::tvoid;
// Chain the two together:
// ( typeof(return) __inlineretval = ( inlined body )) , __inlineretval
e = Expression::combine(de, ve);
//fprintf(stderr, "CallExp::inlineScan: e = "); e->print();
}
// Need to reevaluate whether parent can now be inlined // Need to reevaluate whether parent can now be inlined
// in expressions, as we might have inlined statements // in expressions, as we might have inlined statements
iss->fd->inlineStatusExp = ILSuninitialized; iss->fd->inlineStatusExp = ILSuninitialized;
return e; return e;
} }
void UnitTestDeclaration::inlineScan()
{
if (global.params.useUnitTests)
{
FuncDeclaration::inlineScan();
}
}
/**************************************************** /****************************************************
* Perform the "inline copying" of a default argument for a function parameter. * Perform the "inline copying" of a default argument for a function parameter.
+207 -85
View File
@@ -306,7 +306,7 @@ int CompiledCtfeFunction::walkAllVars(Expression *e, void *_this)
if (global.gag && ccf->func) if (global.gag && ccf->func)
return 1; return 1;
printf("CTFE: ErrorExp in %s\n", ccf->func ? ccf->func->loc.toChars() : ccf->callingloc.toChars()); e->error("CTFE internal error: ErrorExp in %s\n", ccf->func ? ccf->func->loc.toChars() : ccf->callingloc.toChars());
assert(0); assert(0);
} }
if (e->op == TOKdeclaration) if (e->op == TOKdeclaration)
@@ -570,11 +570,7 @@ void TryCatchStatement::ctfeCompile(CompiledCtfeFunction *ccf)
body->ctfeCompile(ccf); body->ctfeCompile(ccf);
for (size_t i = 0; i < catches->dim; i++) for (size_t i = 0; i < catches->dim; i++)
{ {
#if DMDV1 Catch *ca = (*catches)[i];
Catch *ca = (Catch *)catches->data[i];
#else
Catch *ca = catches->tdata()[i];
#endif
if (ca->var) if (ca->var)
ccf->onDeclaration(ca->var); ccf->onDeclaration(ca->var);
if (ca->handler) if (ca->handler)
@@ -958,6 +954,12 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
#endif #endif
} }
if (istatex.start)
{
error("CTFE internal error: failed to resume at statement %s", istatex.start->toChars());
return EXP_CANT_INTERPRET;
}
/* This is how we deal with a recursive statement AST /* This is how we deal with a recursive statement AST
* that has arbitrary goto statements in it. * that has arbitrary goto statements in it.
* Bubble up a 'result' which is the target of the goto * Bubble up a 'result' which is the target of the goto
@@ -1001,13 +1003,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
/******************************** Statement ***************************/ /******************************** Statement ***************************/
#define START() \
if (istate->start) \
{ if (istate->start != this) \
return NULL; \
istate->start = NULL; \
}
/*********************************** /***********************************
* Interpret the statement. * Interpret the statement.
* Returns: * Returns:
@@ -1021,7 +1016,12 @@ Expression *Statement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s Statement::interpret()\n", loc.toChars()); printf("%s Statement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
error("Statement %s cannot be interpreted at compile time", this->toChars()); error("Statement %s cannot be interpreted at compile time", this->toChars());
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
} }
@@ -1031,7 +1031,12 @@ Expression *ExpStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s ExpStatement::interpret(%s)\n", loc.toChars(), exp ? exp->toChars() : ""); printf("%s ExpStatement::interpret(%s)\n", loc.toChars(), exp ? exp->toChars() : "");
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
if (exp) if (exp)
{ {
Expression *e = exp->interpret(istate, ctfeNeedNothing); Expression *e = exp->interpret(istate, ctfeNeedNothing);
@@ -1140,7 +1145,7 @@ Expression *IfStatement::interpret(InterState *istate)
{ {
if (isTrueBool(e)) if (isTrueBool(e))
e = ifbody ? ifbody->interpret(istate) : NULL; e = ifbody ? ifbody->interpret(istate) : NULL;
else if (e->isBool(FALSE)) else if (e->isBool(false))
e = elsebody ? elsebody->interpret(istate) : NULL; e = elsebody ? elsebody->interpret(istate) : NULL;
else else
{ {
@@ -1349,7 +1354,12 @@ Expression *ReturnStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s ReturnStatement::interpret(%s)\n", loc.toChars(), exp ? exp->toChars() : ""); printf("%s ReturnStatement::interpret(%s)\n", loc.toChars(), exp ? exp->toChars() : "");
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
if (!exp) if (!exp)
return EXP_VOID_INTERPRET; return EXP_VOID_INTERPRET;
assert(istate && istate->fd && istate->fd->type); assert(istate && istate->fd && istate->fd->type);
@@ -1410,7 +1420,12 @@ Expression *BreakStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s BreakStatement::interpret()\n", loc.toChars()); printf("%s BreakStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
if (ident) if (ident)
{ {
LabelDsymbol *label = istate->fd->searchLabel(ident); LabelDsymbol *label = istate->fd->searchLabel(ident);
@@ -1440,7 +1455,12 @@ Expression *ContinueStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s ContinueStatement::interpret()\n", loc.toChars()); printf("%s ContinueStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
if (ident) if (ident)
{ {
LabelDsymbol *label = istate->fd->searchLabel(ident); LabelDsymbol *label = istate->fd->searchLabel(ident);
@@ -1513,7 +1533,7 @@ Expression *DoStatement::interpret(InterState *istate)
if (isTrueBool(e)) if (isTrueBool(e))
{ {
} }
else if (e->isBool(FALSE)) else if (e->isBool(false))
{ e = NULL; { e = NULL;
break; break;
} }
@@ -1550,7 +1570,7 @@ Expression *ForStatement::interpret(InterState *istate)
{ e = EXP_CANT_INTERPRET; { e = EXP_CANT_INTERPRET;
break; break;
} }
if (e->isBool(FALSE)) if (e->isBool(false))
{ e = NULL; { e = NULL;
break; break;
} }
@@ -1704,7 +1724,12 @@ Expression *GotoStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s GotoStatement::interpret()\n", loc.toChars()); printf("%s GotoStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
assert(label && label->statement); assert(label && label->statement);
istate->gotoTarget = label->statement; istate->gotoTarget = label->statement;
return EXP_GOTO_INTERPRET; return EXP_GOTO_INTERPRET;
@@ -1715,7 +1740,12 @@ Expression *GotoCaseStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s GotoCaseStatement::interpret()\n", loc.toChars()); printf("%s GotoCaseStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
assert(cs); assert(cs);
istate->gotoTarget = cs; istate->gotoTarget = cs;
return EXP_GOTO_INTERPRET; return EXP_GOTO_INTERPRET;
@@ -1726,7 +1756,12 @@ Expression *GotoDefaultStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s GotoDefaultStatement::interpret()\n", loc.toChars()); printf("%s GotoDefaultStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
assert(sw && sw->sdefault); assert(sw && sw->sdefault);
istate->gotoTarget = sw->sdefault; istate->gotoTarget = sw->sdefault;
return EXP_GOTO_INTERPRET; return EXP_GOTO_INTERPRET;
@@ -1748,7 +1783,22 @@ Expression *TryCatchStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s TryCatchStatement::interpret()\n", loc.toChars()); printf("%s TryCatchStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start == this)
istate->start = NULL;
if (istate->start)
{
Expression *e = NULL;
if (body)
e = body->interpret(istate);
for (size_t i = 0; !e && istate->start && i < catches->dim; i++)
{
Catch *ca = (*catches)[i];
if (ca->handler)
e = ca->handler->interpret(istate);
}
return e;
}
Expression *e = body ? body->interpret(istate) : NULL; Expression *e = body ? body->interpret(istate) : NULL;
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
return e; return e;
@@ -1760,21 +1810,36 @@ Expression *TryCatchStatement::interpret(InterState *istate)
// Search for an appropriate catch clause. // Search for an appropriate catch clause.
for (size_t i = 0; i < catches->dim; i++) for (size_t i = 0; i < catches->dim; i++)
{ {
#if DMDV1
Catch *ca = (Catch *)catches->data[i];
#else
Catch *ca = (*catches)[i]; Catch *ca = (*catches)[i];
#endif
Type *catype = ca->type; Type *catype = ca->type;
if (catype->equals(extype) || catype->isBaseOf(extype, NULL)) if (catype->equals(extype) || catype->isBaseOf(extype, NULL))
{ // Execute the handler {
// Execute the handler
if (ca->var) if (ca->var)
{ {
ctfeStack.push(ca->var); ctfeStack.push(ca->var);
ca->var->setValue(ex->thrown); ca->var->setValue(ex->thrown);
} }
return ca->handler ? ca->handler->interpret(istate) : NULL; if (ca->handler)
{
e = ca->handler->interpret(istate);
if (e == EXP_GOTO_INTERPRET)
{
InterState istatex = *istate;
istatex.start = istate->gotoTarget; // set starting statement
istatex.gotoTarget = NULL;
Expression *eh = ca->handler->interpret(&istatex);
if (!istatex.start)
{
istate->gotoTarget = NULL;
e = eh;
}
}
}
else
e = NULL;
return e;
} }
} }
return e; return e;
@@ -1820,7 +1885,18 @@ Expression *TryFinallyStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s TryFinallyStatement::interpret()\n", loc.toChars()); printf("%s TryFinallyStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start == this)
istate->start = NULL;
if (istate->start)
{
Expression *e = NULL;
if (body)
e = body->interpret(istate);
// Jump into/out from finalbody is disabled in semantic analysis.
// and jump inside will be handled by the ScopeStatement == finalbody.
return e;
}
Expression *e = body ? body->interpret(istate) : NULL; Expression *e = body ? body->interpret(istate) : NULL;
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
return e; return e;
@@ -1842,7 +1918,12 @@ Expression *ThrowStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s ThrowStatement::interpret()\n", loc.toChars()); printf("%s ThrowStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
Expression *e = exp->interpret(istate); Expression *e = exp->interpret(istate);
if (exceptionOrCantInterpret(e)) if (exceptionOrCantInterpret(e))
return e; return e;
@@ -1866,7 +1947,12 @@ Expression *WithStatement::interpret(InterState *istate)
if (exp->op == TOKimport || exp->op == TOKtype) if (exp->op == TOKimport || exp->op == TOKtype)
return body ? body->interpret(istate) : EXP_VOID_INTERPRET; return body ? body->interpret(istate) : EXP_VOID_INTERPRET;
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
Expression *e = exp->interpret(istate); Expression *e = exp->interpret(istate);
if (exceptionOrCantInterpret(e)) if (exceptionOrCantInterpret(e))
return e; return e;
@@ -1877,7 +1963,24 @@ Expression *WithStatement::interpret(InterState *istate)
} }
ctfeStack.push(wthis); ctfeStack.push(wthis);
wthis->setValue(e); wthis->setValue(e);
e = body ? body->interpret(istate) : EXP_VOID_INTERPRET; if (body)
{
e = body->interpret(istate);
if (e == EXP_GOTO_INTERPRET)
{
InterState istatex = *istate;
istatex.start = istate->gotoTarget; // set starting statement
istatex.gotoTarget = NULL;
Expression *ex = body->interpret(&istatex);
if (!istatex.start)
{
istate->gotoTarget = NULL;
e = ex;
}
}
}
else
e = EXP_VOID_INTERPRET;
ctfeStack.pop(wthis); ctfeStack.pop(wthis);
return e; return e;
} }
@@ -1887,7 +1990,12 @@ Expression *AsmStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("%s AsmStatement::interpret()\n", loc.toChars()); printf("%s AsmStatement::interpret()\n", loc.toChars());
#endif #endif
START() if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
error("asm statements cannot be interpreted at compile time"); error("asm statements cannot be interpreted at compile time");
return EXP_CANT_INTERPRET; return EXP_CANT_INTERPRET;
} }
@@ -1898,7 +2006,12 @@ Expression *ImportStatement::interpret(InterState *istate)
#if LOG #if LOG
printf("ImportStatement::interpret()\n"); printf("ImportStatement::interpret()\n");
#endif #endif
START(); if (istate->start)
{ if (istate->start != this)
return NULL;
istate->start = NULL;
}
;
return NULL; return NULL;
} }
#endif #endif
@@ -2432,11 +2545,11 @@ Expression *DeclarationExp::interpret(InterState *istate, CtfeGoal goal)
} }
else if (s->isTupleDeclaration() && !v->init) else if (s->isTupleDeclaration() && !v->init)
e = NULL; e = NULL;
else if (v->isStatic() && !v->init) else if (v->isStatic())
e = NULL; // Just ignore static variables which aren't read or written yet e = NULL; // Just ignore static variables which aren't read or written yet
else else
{ {
error("Static variable %s cannot be modified at compile time", v->toChars()); error("Variable %s cannot be modified at compile time", v->toChars());
e = EXP_CANT_INTERPRET; e = EXP_CANT_INTERPRET;
} }
} }
@@ -2779,7 +2892,7 @@ Expression *recursivelyCreateArrayLiteral(Loc loc, Type *newtype, InterState *is
|| elemType->ty == Tdchar) || elemType->ty == Tdchar)
return createBlockDuplicatedStringLiteral(loc, newtype, return createBlockDuplicatedStringLiteral(loc, newtype,
(unsigned)(elemType->defaultInitLiteral(loc)->toInteger()), (unsigned)(elemType->defaultInitLiteral(loc)->toInteger()),
len, elemType->size()); len, (unsigned char)elemType->size());
return createBlockDuplicatedArrayLiteral(loc, newtype, return createBlockDuplicatedArrayLiteral(loc, newtype,
elemType->defaultInitLiteral(loc), elemType->defaultInitLiteral(loc),
len); len);
@@ -3207,8 +3320,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
if (op == TOKconstruct && this->e1->op==TOKvar if (op == TOKconstruct && this->e1->op==TOKvar
&& ((VarExp*)this->e1)->var->storage_class & STCref) && ((VarExp*)this->e1)->var->storage_class & STCref)
{ {
wantRef = true; wantRef = true;
wantLvalueRef = true; wantLvalueRef = true;
} }
if (fp) if (fp)
@@ -3353,8 +3466,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
returnValue = newval; returnValue = newval;
if (e1->op == TOKarraylength) if (e1->op == TOKarraylength)
{ {
size_t oldlen = oldval->toInteger(); size_t oldlen = (size_t)oldval->toInteger();
size_t newlen = newval->toInteger(); size_t newlen = (size_t)newval->toInteger();
if (oldlen == newlen) // no change required -- we're done! if (oldlen == newlen) // no change required -- we're done!
return returnValue; return returnValue;
// Now change the assignment from arr.length = n into arr = newval // Now change the assignment from arr.length = n into arr = newval
@@ -3894,9 +4007,9 @@ bool interpretAssignToIndex(InterState *istate, Loc loc,
if (existingAE) if (existingAE)
{ {
if (newval->op == TOKstructliteral) if (newval->op == TOKstructliteral)
assignInPlace((*existingAE->elements)[indexToModify], newval); assignInPlace((*existingAE->elements)[(size_t)indexToModify], newval);
else else
(*existingAE->elements)[indexToModify] = newval; (*existingAE->elements)[(size_t)indexToModify] = newval;
return true; return true;
} }
if (existingSE) if (existingSE)
@@ -3907,12 +4020,12 @@ bool interpretAssignToIndex(InterState *istate, Loc loc,
originalExp->error("cannot modify read-only string literal %s", ie->e1->toChars()); originalExp->error("cannot modify read-only string literal %s", ie->e1->toChars());
return false; return false;
} }
unsigned value = newval->toInteger(); dinteger_t value = newval->toInteger();
switch (existingSE->sz) switch (existingSE->sz)
{ {
case 1: s[indexToModify] = value; break; case 1: s[(size_t)indexToModify] = (utf8_t)value; break;
case 2: ((unsigned short *)s)[indexToModify] = value; break; case 2: ((unsigned short *)s)[(size_t)indexToModify] = (unsigned short)value; break;
case 4: ((unsigned *)s)[indexToModify] = value; break; case 4: ((unsigned *)s)[(size_t)indexToModify] = (unsigned)value; break;
default: default:
assert(0); assert(0);
break; break;
@@ -4008,9 +4121,9 @@ Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc,
if (exceptionOrCantInterpret(lower)) if (exceptionOrCantInterpret(lower))
return lower; return lower;
size_t dim = dollar; unsigned dim = (unsigned)dollar;
size_t upperbound = upper ? upper->toInteger() : dim; size_t upperbound = (size_t)(upper ? upper->toInteger() : dim);
int lowerbound = lower ? lower->toInteger() : 0; int lowerbound = (int)(lower ? lower->toInteger() : 0);
if (!assignmentToSlicedPointer && (((int)lowerbound < 0) || (upperbound > dim))) if (!assignmentToSlicedPointer && (((int)lowerbound < 0) || (upperbound > dim)))
{ {
@@ -4137,13 +4250,13 @@ Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc,
Type *elemtype = existingAE->type->nextOf(); Type *elemtype = existingAE->type->nextOf();
for (size_t j = 0; j < newelems->dim; j++) for (size_t j = 0; j < newelems->dim; j++)
{ {
(*oldelems)[j + firstIndex] = paintTypeOntoLiteral(elemtype, (*newelems)[j]); (*oldelems)[(size_t)(j + firstIndex)] = paintTypeOntoLiteral(elemtype, (*newelems)[j]);
} }
return newval; return newval;
} }
else if (newval->op == TOKstring && existingSE) else if (newval->op == TOKstring && existingSE)
{ {
sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, firstIndex); sliceAssignStringFromString((StringExp *)existingSE, (StringExp *)newval, (size_t)firstIndex);
return newval; return newval;
} }
else if (newval->op == TOKstring && existingAE else if (newval->op == TOKstring && existingAE
@@ -4151,27 +4264,27 @@ Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc,
{ /* Mixed slice: it was initialized as an array literal of chars. { /* Mixed slice: it was initialized as an array literal of chars.
* Now a slice of it is being set with a string. * Now a slice of it is being set with a string.
*/ */
sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, firstIndex); sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, (size_t)firstIndex);
return newval; return newval;
} }
else if (newval->op == TOKarrayliteral && existingSE) else if (newval->op == TOKarrayliteral && existingSE)
{ /* Mixed slice: it was initialized as a string literal. { /* Mixed slice: it was initialized as a string literal.
* Now a slice of it is being set with an array literal. * Now a slice of it is being set with an array literal.
*/ */
sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, firstIndex); sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, (size_t)firstIndex);
return newval; return newval;
} }
else if (existingSE) else if (existingSE)
{ // String literal block slice assign { // String literal block slice assign
unsigned value = newval->toInteger(); dinteger_t value = newval->toInteger();
utf8_t *s = (utf8_t *)existingSE->string; utf8_t *s = (utf8_t *)existingSE->string;
for (size_t j = 0; j < upperbound-lowerbound; j++) for (size_t j = 0; j < upperbound-lowerbound; j++)
{ {
switch (existingSE->sz) switch (existingSE->sz)
{ {
case 1: s[j+firstIndex] = value; break; case 1: s[(size_t)(j+firstIndex)] = (utf8_t)value; break;
case 2: ((unsigned short *)s)[j+firstIndex] = value; break; case 2: ((unsigned short *)s)[(size_t)(j+firstIndex)] = (unsigned short)value; break;
case 4: ((unsigned *)s)[j+firstIndex] = value; break; case 4: ((unsigned *)s)[(size_t)(j+firstIndex)] = (unsigned)value; break;
default: default:
assert(0); assert(0);
break; break;
@@ -4208,13 +4321,13 @@ Expression *interpretAssignToSlice(InterState *istate, CtfeGoal goal, Loc loc,
{ {
if (!directblk) if (!directblk)
// Multidimensional array block assign // Multidimensional array block assign
recursiveBlockAssign((ArrayLiteralExp *)(*w)[j+firstIndex], newval, wantRef); recursiveBlockAssign((ArrayLiteralExp *)(*w)[(size_t)(j+firstIndex)], newval, wantRef);
else else
{ {
if (wantRef || cow) if (wantRef || cow)
(*existingAE->elements)[j+firstIndex] = newval; (*existingAE->elements)[(size_t)(j+firstIndex)] = newval;
else else
assignInPlace((*existingAE->elements)[j+firstIndex], newval); assignInPlace((*existingAE->elements)[(size_t)(j+firstIndex)], newval);
} }
} }
if (goal == ctfeNeedNothing) if (goal == ctfeNeedNothing)
@@ -4376,7 +4489,7 @@ Expression *BinExp::interpretFourPointerRelation(InterState *istate, CtfeGoal go
if ( !pointToSameMemoryBlock(agg1, agg2) if ( !pointToSameMemoryBlock(agg1, agg2)
&& agg1->op != TOKnull && agg2->op != TOKnull) && agg1->op != TOKnull && agg2->op != TOKnull)
{ // Here it is either CANT_INTERPRET, { // Here it is either CANT_INTERPRET,
// or an IsInside comparison returning FALSE. // or an IsInside comparison returning false.
p3 = p3->interpret(istate); p3 = p3->interpret(istate);
if (p3 == EXP_CANT_INTERPRET) if (p3 == EXP_CANT_INTERPRET)
return p3; return p3;
@@ -4463,7 +4576,7 @@ Expression *AndAndExp::interpret(InterState *istate, CtfeGoal goal)
int result; int result;
if (e != EXP_CANT_INTERPRET) if (e != EXP_CANT_INTERPRET)
{ {
if (e->isBool(FALSE)) if (e->isBool(false))
result = 0; result = 0;
else if (isTrueBool(e)) else if (isTrueBool(e))
{ {
@@ -4475,7 +4588,7 @@ Expression *AndAndExp::interpret(InterState *istate, CtfeGoal goal)
assert(type->ty == Tvoid); assert(type->ty == Tvoid);
return NULL; return NULL;
} }
if (e->isBool(FALSE)) if (e->isBool(false))
result = 0; result = 0;
else if (isTrueBool(e)) else if (isTrueBool(e))
result = 1; result = 1;
@@ -4516,7 +4629,7 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal)
{ {
if (isTrueBool(e)) if (isTrueBool(e))
result = 1; result = 1;
else if (e->isBool(FALSE)) else if (e->isBool(false))
{ {
e = e2->interpret(istate); e = e2->interpret(istate);
if (exceptionOrCantInterpret(e)) if (exceptionOrCantInterpret(e))
@@ -4529,7 +4642,7 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal)
} }
if (e != EXP_CANT_INTERPRET) if (e != EXP_CANT_INTERPRET)
{ {
if (e->isBool(FALSE)) if (e->isBool(false))
result = 0; result = 0;
else if (isTrueBool(e)) else if (isTrueBool(e))
result = 1; result = 1;
@@ -4788,14 +4901,18 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
} }
eresult = fd->interpret(istate, arguments, pthis); eresult = fd->interpret(istate, arguments, pthis);
if (eresult == EXP_CANT_INTERPRET) if (eresult == EXP_CANT_INTERPRET)
{ // Print a stack trace. {
// Print a stack trace.
if (!global.gag) if (!global.gag)
showCtfeBackTrace(istate, this, fd); showCtfeBackTrace(istate, this, fd);
} }
else if (eresult == EXP_VOID_INTERPRET) else if (eresult == EXP_VOID_INTERPRET)
; ;
else else
{
eresult->type = type;
eresult->loc = loc; eresult->loc = loc;
}
return eresult; return eresult;
} }
@@ -4888,7 +5005,7 @@ Expression *CondExp::interpret(InterState *istate, CtfeGoal goal)
return e; return e;
if (isTrueBool(e)) if (isTrueBool(e))
e = e1->interpret(istate, goal); e = e1->interpret(istate, goal);
else if (e->isBool(FALSE)) else if (e->isBool(false))
e = e2->interpret(istate, goal); e = e2->interpret(istate, goal);
else else
{ {
@@ -5412,7 +5529,7 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal)
Expression *xx = NULL; Expression *xx = NULL;
if (ie->e1->op == TOKarrayliteral && ie->e2->op == TOKint64) if (ie->e1->op == TOKarrayliteral && ie->e2->op == TOKint64)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1; { ArrayLiteralExp *ale = (ArrayLiteralExp *)ie->e1;
uinteger_t indx = ie->e2->toInteger(); size_t indx = (size_t)ie->e2->toInteger();
if (indx < ale->elements->dim) if (indx < ale->elements->dim)
xx = (*ale->elements)[indx]; xx = (*ale->elements)[indx];
} }
@@ -5528,7 +5645,7 @@ Expression *AssertExp::interpret(InterState *istate, CtfeGoal goal)
if (isTrueBool(e1)) if (isTrueBool(e1))
{ {
} }
else if (e1->isBool(FALSE)) else if (e1->isBool(false))
{ {
if (msg) if (msg)
{ {
@@ -5583,7 +5700,7 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
if (ex->op == TOKstructliteral) if (ex->op == TOKstructliteral)
{ StructLiteralExp *se = (StructLiteralExp *)ex; { StructLiteralExp *se = (StructLiteralExp *)ex;
dinteger_t offset = ae->e2->toInteger(); dinteger_t offset = ae->e2->toInteger();
e = se->getField(type, offset); e = se->getField(type, (unsigned)offset);
if (!e) if (!e)
e = EXP_CANT_INTERPRET; e = EXP_CANT_INTERPRET;
return e; return e;
@@ -5591,16 +5708,17 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
} }
e = Ptr(type, e1); e = Ptr(type, e1);
} }
#if DMDV2
#else // this is required for D1, where structs return *this instead of 'this'.
else if (e1->op == TOKthis)
{
if (ctfeStack.getThis())
return ctfeStack.getThis()->interpret(istate);
}
#endif
else else
{ {
#if DMDV2
#else // this is required for D1, where structs return *this instead of 'this'.
if (e1->op == TOKthis)
{
if (ctfeStack.getThis())
return ctfeStack.getThis()->interpret(istate);
goto Ldone;
}
#endif
// Check for .classinfo, which is lowered in the semantic pass into **(class). // Check for .classinfo, which is lowered in the semantic pass into **(class).
if (e1->op == TOKstar && e1->type->ty == Tpointer && isTypeInfo_Class(e1->type->nextOf())) if (e1->op == TOKstar && e1->type->ty == Tpointer && isTypeInfo_Class(e1->type->nextOf()))
{ {
@@ -5738,6 +5856,7 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
e = paintTypeOntoLiteral(type, e); e = paintTypeOntoLiteral(type, e);
} }
Ldone:
#if LOG #if LOG
if (e == EXP_CANT_INTERPRET) if (e == EXP_CANT_INTERPRET)
printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); printf("PtrExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars());
@@ -6046,7 +6165,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
Type *charType = (*fd->parameters)[numParams-1]->type; Type *charType = (*fd->parameters)[numParams-1]->type;
Type *indexType = numParams == 2 ? (*fd->parameters)[0]->type Type *indexType = numParams == 2 ? (*fd->parameters)[0]->type
: Type::tsize_t; : Type::tsize_t;
uinteger_t len = resolveArrayLength(str); size_t len = (size_t)resolveArrayLength(str);
if (len == 0) if (len == 0)
return new IntegerExp(deleg->loc, 0, indexType); return new IntegerExp(deleg->loc, 0, indexType);
@@ -6086,7 +6205,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
{ // If it is an array literal, copy the code points into the buffer { // If it is an array literal, copy the code points into the buffer
size_t buflen = 1; // #code points in the buffer size_t buflen = 1; // #code points in the buffer
size_t n = 1; // #code points in this char size_t n = 1; // #code points in this char
size_t sz = ale->type->nextOf()->size(); size_t sz = (size_t)ale->type->nextOf()->size();
switch(sz) switch(sz)
{ {
@@ -6148,7 +6267,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
Expression * r = (*ale->elements)[indx]; Expression * r = (*ale->elements)[indx];
assert(r->op == TOKint64); assert(r->op == TOKint64);
rawvalue = ((IntegerExp *)r)->value; rawvalue = (dchar_t)((IntegerExp *)r)->value;
n = 1; n = 1;
} }
break; break;
@@ -6303,7 +6422,10 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
} }
e = eval_builtin(loc, b, &args); e = eval_builtin(loc, b, &args);
if (!e) if (!e)
{
error(loc, "cannot evaluate unimplemented builtin %s at compile time", fd->toChars());
e = EXP_CANT_INTERPRET; e = EXP_CANT_INTERPRET;
}
} }
} }
-6
View File
@@ -807,9 +807,7 @@ void ConditionalDeclaration::toJson(JsonOut *json)
void ClassInfoDeclaration::toJson(JsonOut *json) { } void ClassInfoDeclaration::toJson(JsonOut *json) { }
void TypeInfoDeclaration::toJson(JsonOut *json) { } void TypeInfoDeclaration::toJson(JsonOut *json) { }
#if DMDV2
void PostBlitDeclaration::toJson(JsonOut *json) { } void PostBlitDeclaration::toJson(JsonOut *json) { }
#endif
void Declaration::toJson(JsonOut *json) void Declaration::toJson(JsonOut *json)
@@ -966,14 +964,10 @@ void TemplateDeclaration::toJson(JsonOut *json)
TemplateTypeParameter *type = s->isTemplateTypeParameter(); TemplateTypeParameter *type = s->isTemplateTypeParameter();
if (type) if (type)
{ {
#if DMDV2
if (s->isTemplateThisParameter()) if (s->isTemplateThisParameter())
json->property("kind", "this"); json->property("kind", "this");
else else
json->property("kind", "type"); json->property("kind", "type");
#else
json->property("kind", "type");
#endif
json->property("type", "deco", type->specType); json->property("type", "deco", type->specType);
json->property("default", "defaultDeco", type->defaultType); json->property("default", "defaultDeco", type->defaultType);
+165 -237
View File
@@ -36,7 +36,7 @@
#include "id.h" #include "id.h"
#include "module.h" #include "module.h"
extern int HtmlNamedEntity(utf8_t *p, size_t length); extern int HtmlNamedEntity(const utf8_t *p, size_t length);
#define LS 0x2028 // UTF line separator #define LS 0x2028 // UTF line separator
#define PS 0x2029 // UTF paragraph separator #define PS 0x2029 // UTF paragraph separator
@@ -53,9 +53,9 @@ const int CMoctal = 0x1;
const int CMhex = 0x2; const int CMhex = 0x2;
const int CMidchar = 0x4; const int CMidchar = 0x4;
inline bool isoctal (utf8_t c) { return cmtable[c] & CMoctal; } inline bool isoctal (utf8_t c) { return (cmtable[c] & CMoctal) != 0; }
inline bool ishex (utf8_t c) { return cmtable[c] & CMhex; } inline bool ishex (utf8_t c) { return (cmtable[c] & CMhex) != 0; }
inline bool isidchar(utf8_t c) { return cmtable[c] & CMidchar; } inline bool isidchar(utf8_t c) { return (cmtable[c] & CMidchar) != 0; }
static void cmtable_init() static void cmtable_init()
{ {
@@ -99,55 +99,55 @@ const char *Token::toChars()
{ const char *p; { const char *p;
static char buffer[3 + 3 * sizeof(float80value) + 1]; static char buffer[3 + 3 * sizeof(float80value) + 1];
p = buffer; p = &buffer[0];
switch (value) switch (value)
{ {
case TOKint32v: case TOKint32v:
sprintf(buffer,"%d",int32value); sprintf(&buffer[0],"%d",int32value);
break; break;
case TOKuns32v: case TOKuns32v:
case TOKcharv: case TOKcharv:
case TOKwcharv: case TOKwcharv:
case TOKdcharv: case TOKdcharv:
sprintf(buffer,"%uU",uns32value); sprintf(&buffer[0],"%uU",uns32value);
break; break;
case TOKint64v: case TOKint64v:
sprintf(buffer,"%lldL",(longlong)int64value); sprintf(&buffer[0],"%lldL",(longlong)int64value);
break; break;
case TOKuns64v: case TOKuns64v:
sprintf(buffer,"%lluUL",(ulonglong)uns64value); sprintf(&buffer[0],"%lluUL",(ulonglong)uns64value);
break; break;
case TOKfloat32v: case TOKfloat32v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
strcat(buffer, "f"); strcat(&buffer[0], "f");
break; break;
case TOKfloat64v: case TOKfloat64v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
break; break;
case TOKfloat80v: case TOKfloat80v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
strcat(buffer, "L"); strcat(&buffer[0], "L");
break; break;
case TOKimaginary32v: case TOKimaginary32v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
strcat(buffer, "fi"); strcat(&buffer[0], "fi");
break; break;
case TOKimaginary64v: case TOKimaginary64v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
strcat(buffer, "i"); strcat(&buffer[0], "i");
break; break;
case TOKimaginary80v: case TOKimaginary80v:
ld_sprint(buffer, 'g', float80value); ld_sprint(&buffer[0], 'g', float80value);
strcat(buffer, "Li"); strcat(&buffer[0], "Li");
break; break;
case TOKstring: case TOKstring:
@@ -208,8 +208,8 @@ const char *Token::toChars(TOK value)
p = tochars[value]; p = tochars[value];
if (!p) if (!p)
{ sprintf(buffer,"TOK%d",value); { sprintf(&buffer[0],"TOK%d",value);
p = buffer; p = &buffer[0];
} }
return p; return p;
} }
@@ -221,7 +221,7 @@ StringTable Lexer::stringtable;
OutBuffer Lexer::stringbuffer; OutBuffer Lexer::stringbuffer;
Lexer::Lexer(Module *mod, Lexer::Lexer(Module *mod,
utf8_t *base, size_t begoffset, size_t endoffset, const utf8_t *base, size_t begoffset, size_t endoffset,
int doDocComment, int commentToken) int doDocComment, int commentToken)
{ {
scanloc = Loc(mod, 1); scanloc = Loc(mod, 1);
@@ -409,7 +409,7 @@ Token *Lexer::peekPastParen(Token *tk)
* 0 invalid * 0 invalid
*/ */
int Lexer::isValidIdentifier(char *p) int Lexer::isValidIdentifier(const char *p)
{ {
size_t len; size_t len;
size_t idx; size_t idx;
@@ -503,7 +503,6 @@ void Lexer::scan(Token *t)
t->value = hexStringConstant(t); t->value = hexStringConstant(t);
return; return;
#if DMDV2
case 'q': case 'q':
if (p[1] == '"') if (p[1] == '"')
{ {
@@ -519,16 +518,14 @@ void Lexer::scan(Token *t)
} }
else else
goto case_ident; goto case_ident;
#endif
case '"': case '"':
t->value = escapeStringConstant(t,0); t->value = escapeStringConstant(t,0);
return; return;
#if ! TEXTUAL_ASSEMBLY_OUT
case '\\': // escaped string literal case '\\': // escaped string literal
{ unsigned c; { unsigned c;
utf8_t *pstart = p; const utf8_t *pstart = p;
stringbuffer.reset(); stringbuffer.reset();
do do
@@ -555,21 +552,14 @@ void Lexer::scan(Token *t)
memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); memcpy(t->ustring, stringbuffer.data, stringbuffer.offset);
t->postfix = 0; t->postfix = 0;
t->value = TOKstring; t->value = TOKstring;
#if DMDV2
error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart); error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart);
#endif
return; return;
} }
#endif
case 'a': case 'b': case 'c': case 'd': case 'e': case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j': case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o': case 'k': case 'l': case 'm': case 'n': case 'o':
#if DMDV2
case 'p': /*case 'q': case 'r':*/ case 's': case 't': case 'p': /*case 'q': case 'r':*/ case 's': case 't':
#else
case 'p': case 'q': /*case 'r':*/ case 's': case 't':
#endif
case 'u': case 'v': case 'w': /*case 'x':*/ case 'y': case 'u': case 'v': case 'w': /*case 'x':*/ case 'y':
case 'z': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'A': case 'B': case 'C': case 'D': case 'E':
@@ -588,7 +578,7 @@ void Lexer::scan(Token *t)
if (isidchar(c)) if (isidchar(c))
continue; continue;
else if (c & 0x80) else if (c & 0x80)
{ utf8_t *s = p; { const utf8_t *s = p;
unsigned u = decodeUTF(); unsigned u = decodeUTF();
if (isUniAlpha(u)) if (isUniAlpha(u))
continue; continue;
@@ -617,28 +607,15 @@ void Lexer::scan(Token *t)
if (!initdone) // lazy evaluation if (!initdone) // lazy evaluation
{ {
initdone = true; initdone = true;
time_t t; time_t ct;
::time(&t); ::time(&ct);
char *p = ctime(&t); char *p = ctime(&ct);
assert(p); assert(p);
sprintf(date, "%.6s %.4s", p + 4, p + 20); sprintf(&date[0], "%.6s %.4s", p + 4, p + 20);
sprintf(time, "%.8s", p + 11); sprintf(&time[0], "%.8s", p + 11);
sprintf(timestamp, "%.24s", p); sprintf(&timestamp[0], "%.24s", p);
} }
#if DMDV1
if (mod && id == Id::FILE)
{
t->ustring = (utf8_t *)(loc.filename ? loc.filename : mod->ident->toChars());
goto Lstr;
}
else if (mod && id == Id::LINE)
{
t->value = TOKint64v;
t->uns64value = scanloc.linnum;
}
else
#endif
if (id == Id::DATE) if (id == Id::DATE)
{ {
t->ustring = (utf8_t *)date; t->ustring = (utf8_t *)date;
@@ -669,7 +646,7 @@ void Lexer::scan(Token *t)
for (const char *p = global.version + 1; 1; p++) for (const char *p = global.version + 1; 1; p++)
{ {
char c = *p; c = *p;
if (isdigit((utf8_t)c)) if (isdigit((utf8_t)c))
minor = minor * 10 + c - '0'; minor = minor * 10 + c - '0';
else if (c == '.') else if (c == '.')
@@ -686,7 +663,6 @@ void Lexer::scan(Token *t)
t->value = TOKint64v; t->value = TOKint64v;
t->uns64value = major * 1000 + minor; t->uns64value = major * 1000 + minor;
} }
#if DMDV2
else if (id == Id::EOFX) else if (id == Id::EOFX)
{ {
t->value = TOKeof; t->value = TOKeof;
@@ -694,7 +670,6 @@ void Lexer::scan(Token *t)
while (!(*p == 0 || *p == 0x1A)) while (!(*p == 0 || *p == 0x1A))
p++; p++;
} }
#endif
} }
//printf("t->value = %d\n",t->value); //printf("t->value = %d\n",t->value);
return; return;
@@ -962,12 +937,6 @@ void Lexer::scan(Token *t)
{ p++; { p++;
t->value = TOKminass; t->value = TOKminass;
} }
#if 0
else if (*p == '>')
{ p++;
t->value = TOKarrow;
}
#endif
else if (*p == '-') else if (*p == '-')
{ p++; { p++;
t->value = TOKminusminus; t->value = TOKminusminus;
@@ -1089,12 +1058,10 @@ void Lexer::scan(Token *t)
{ p++; { p++;
t->value = TOKequal; // == t->value = TOKequal; // ==
} }
#if DMDV2
else if (*p == '>') else if (*p == '>')
{ p++; { p++;
t->value = TOKgoesto; // => t->value = TOKgoesto; // =>
} }
#endif
else else
t->value = TOKassign; // = t->value = TOKassign; // =
return; return;
@@ -1109,7 +1076,6 @@ void Lexer::scan(Token *t)
t->value = TOKtilde; // ~ t->value = TOKtilde; // ~
return; return;
#if DMDV2
case '^': case '^':
p++; p++;
if (*p == '^') if (*p == '^')
@@ -1128,7 +1094,6 @@ void Lexer::scan(Token *t)
else else
t->value = TOKxor; // ^ t->value = TOKxor; // ^
return; return;
#endif
#define SINGLE(c,tok) case c: p++; t->value = tok; return; #define SINGLE(c,tok) case c: p++; t->value = tok; return;
@@ -1143,9 +1108,7 @@ void Lexer::scan(Token *t)
SINGLE(';', TOKsemicolon) SINGLE(';', TOKsemicolon)
SINGLE(':', TOKcolon) SINGLE(':', TOKcolon)
SINGLE('$', TOKdollar) SINGLE('$', TOKdollar)
#if DMDV2
SINGLE('@', TOKat) SINGLE('@', TOKat)
#endif
#undef SINGLE #undef SINGLE
#define DOUBLE(c1,tok1,c2,tok2) \ #define DOUBLE(c1,tok1,c2,tok2) \
@@ -1161,9 +1124,6 @@ void Lexer::scan(Token *t)
DOUBLE('*', TOKmul, '=', TOKmulass) DOUBLE('*', TOKmul, '=', TOKmulass)
DOUBLE('%', TOKmod, '=', TOKmodass) DOUBLE('%', TOKmod, '=', TOKmodass)
#if DMDV1
DOUBLE('^', TOKxor, '=', TOKxorass)
#endif
#undef DOUBLE #undef DOUBLE
case '#': case '#':
@@ -1218,9 +1178,6 @@ void Lexer::scan(Token *t)
unsigned Lexer::escapeSequence() unsigned Lexer::escapeSequence()
{ unsigned c = *p; { unsigned c = *p;
#ifdef TEXTUAL_ASSEMBLY_OUT
return c;
#endif
int n; int n;
int ndigits; int ndigits;
@@ -1253,14 +1210,14 @@ unsigned Lexer::escapeSequence()
Lhex: Lhex:
p++; p++;
c = *p; c = *p;
if (ishex(c)) if (ishex((utf8_t)c))
{ unsigned v; { unsigned v;
n = 0; n = 0;
v = 0; v = 0;
while (1) while (1)
{ {
if (isdigit(c)) if (isdigit((utf8_t)c))
c -= '0'; c -= '0';
else if (islower(c)) else if (islower(c))
c -= 'a' - 10; c -= 'a' - 10;
@@ -1270,7 +1227,7 @@ unsigned Lexer::escapeSequence()
c = *++p; c = *++p;
if (++n == ndigits) if (++n == ndigits)
break; break;
if (!ishex(c)) if (!ishex((utf8_t)c))
{ error("escape hex sequence has %d hex digits instead of %d", n, ndigits); { error("escape hex sequence has %d hex digits instead of %d", n, ndigits);
break; break;
} }
@@ -1286,7 +1243,7 @@ unsigned Lexer::escapeSequence()
break; break;
case '&': // named character entity case '&': // named character entity
for (utf8_t *idstart = ++p; 1; p++) for (const utf8_t *idstart = ++p; 1; p++)
{ {
switch (*p) switch (*p)
{ {
@@ -1316,7 +1273,7 @@ unsigned Lexer::escapeSequence()
break; break;
default: default:
if (isoctal(c)) if (isoctal((utf8_t)c))
{ unsigned v; { unsigned v;
n = 0; n = 0;
@@ -1325,7 +1282,7 @@ unsigned Lexer::escapeSequence()
{ {
v = v * 8 + (c - '0'); v = v * 8 + (c - '0');
c = *++p; c = *++p;
} while (++n < 3 && isoctal(c)); } while (++n < 3 && isoctal((utf8_t)c));
c = v; c = v;
if (c > 0xFF) if (c > 0xFF)
error("0%03o is larger than a byte", c); error("0%03o is larger than a byte", c);
@@ -1484,7 +1441,6 @@ TOK Lexer::hexStringConstant(Token *t)
} }
#if DMDV2
/************************************** /**************************************
* Lex delimited strings: * Lex delimited strings:
* q"(foo(xxx))" // "foo(xxx)" * q"(foo(xxx))" // "foo(xxx)"
@@ -1566,15 +1522,15 @@ TOK Lexer::delimitedStringConstant(Token *t)
delimright = '>'; delimright = '>';
else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c))) else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))
{ // Start of identifier; must be a heredoc { // Start of identifier; must be a heredoc
Token t; Token tok;
p--; p--;
scan(&t); // read in heredoc identifier scan(&tok); // read in heredoc identifier
if (t.value != TOKidentifier) if (tok.value != TOKidentifier)
{ error("identifier expected for heredoc, not %s", t.toChars()); { error("identifier expected for heredoc, not %s", tok.toChars());
delimright = c; delimright = c;
} }
else else
{ hereid = t.ident; { hereid = tok.ident;
//printf("hereid = '%s'\n", hereid->toChars()); //printf("hereid = '%s'\n", hereid->toChars());
blankrol = 1; blankrol = 1;
} }
@@ -1583,10 +1539,8 @@ TOK Lexer::delimitedStringConstant(Token *t)
else else
{ delimright = c; { delimright = c;
nest = 0; nest = 0;
#if DMDV2
if (isspace(c)) if (isspace(c))
error("delimiter cannot be whitespace"); error("delimiter cannot be whitespace");
#endif
} }
} }
else else
@@ -1608,17 +1562,13 @@ TOK Lexer::delimitedStringConstant(Token *t)
} }
else if (c == delimright) else if (c == delimright)
goto Ldone; goto Ldone;
if (startline && isalpha(c) if (startline && isalpha(c) && hereid)
#if DMDV2 { Token tok;
&& hereid const utf8_t *psave = p;
#endif
)
{ Token t;
utf8_t *psave = p;
p--; p--;
scan(&t); // read in possible heredoc identifier scan(&tok); // read in possible heredoc identifier
//printf("endid = '%s'\n", t.ident->toChars()); //printf("endid = '%s'\n", tok.ident->toChars());
if (t.value == TOKidentifier && t.ident->equals(hereid)) if (tok.value == TOKidentifier && tok.ident->equals(hereid))
{ /* should check that rest of line is blank { /* should check that rest of line is blank
*/ */
goto Ldone; goto Ldone;
@@ -1633,6 +1583,8 @@ TOK Lexer::delimitedStringConstant(Token *t)
Ldone: Ldone:
if (*p == '"') if (*p == '"')
p++; p++;
else if (hereid)
error("delimited string must end in %s\"", hereid->toChars());
else else
error("delimited string must end in %c\"", delimright); error("delimited string must end in %c\"", delimright);
t->len = stringbuffer.offset; t->len = stringbuffer.offset;
@@ -1663,7 +1615,7 @@ TOK Lexer::tokenStringConstant(Token *t)
{ {
unsigned nest = 1; unsigned nest = 1;
Loc start = scanloc; Loc start = scanloc;
utf8_t *pstart = ++p; const utf8_t *pstart = ++p;
while (1) while (1)
{ Token tok; { Token tok;
@@ -1704,7 +1656,6 @@ Lerror:
return TOKstring; return TOKstring;
} }
#endif
/************************************** /**************************************
@@ -1722,7 +1673,6 @@ TOK Lexer::escapeStringConstant(Token *t, int wide)
c = *p++; c = *p++;
switch (c) switch (c)
{ {
#if !( TEXTUAL_ASSEMBLY_OUT )
case '\\': case '\\':
switch (*p) switch (*p)
{ {
@@ -1738,7 +1688,6 @@ TOK Lexer::escapeStringConstant(Token *t, int wide)
break; break;
} }
break; break;
#endif
case '\n': case '\n':
scanloc.linnum++; scanloc.linnum++;
break; break;
@@ -1799,7 +1748,6 @@ TOK Lexer::charConstant(Token *t, int wide)
c = *p++; c = *p++;
switch (c) switch (c)
{ {
#if ! TEXTUAL_ASSEMBLY_OUT
case '\\': case '\\':
switch (*p) switch (*p)
{ {
@@ -1819,7 +1767,6 @@ TOK Lexer::charConstant(Token *t, int wide)
break; break;
} }
break; break;
#endif
case '\n': case '\n':
L1: L1:
scanloc.linnum++; scanloc.linnum++;
@@ -1905,7 +1852,7 @@ TOK Lexer::number(Token *t)
FLAGS flags = FLAGS_decimal; FLAGS flags = FLAGS_decimal;
unsigned c; unsigned c;
utf8_t *start; const utf8_t *start;
TOK result; TOK result;
//printf("Lexer::number()\n"); //printf("Lexer::number()\n");
@@ -1936,10 +1883,8 @@ TOK Lexer::number(Token *t)
case '.': case '.':
if (p[1] == '.') // .. is a separate token if (p[1] == '.') // .. is a separate token
goto done; goto done;
#if DMDV2
if (isalpha(p[1]) || p[1] == '_' || (p[1] & 0x80)) if (isalpha(p[1]) || p[1] == '_' || (p[1] & 0x80))
goto done; goto done;
#endif
case 'i': case 'i':
case 'f': case 'f':
case 'F': case 'F':
@@ -1978,10 +1923,8 @@ TOK Lexer::number(Token *t)
} }
if (c == '.' && p[1] != '.') if (c == '.' && p[1] != '.')
{ {
#if DMDV2
if (isalpha(p[1]) || p[1] == '_' || (p[1] & 0x80)) if (isalpha(p[1]) || p[1] == '_' || (p[1] & 0x80))
goto done; goto done;
#endif
goto real; goto real;
} }
else if (c == 'i' || c == 'f' || c == 'F' || else if (c == 'i' || c == 'f' || c == 'F' ||
@@ -1999,7 +1942,7 @@ TOK Lexer::number(Token *t)
case STATE_hex0: // reading hex number case STATE_hex0: // reading hex number
case STATE_hex: case STATE_hex:
if (!ishex(c)) if (!ishex((utf8_t)c))
{ {
if (c == '_') // ignore embedded _ if (c == '_') // ignore embedded _
{ p++; { p++;
@@ -2018,7 +1961,7 @@ TOK Lexer::number(Token *t)
case STATE_octal: // reading octal number case STATE_octal: // reading octal number
case STATE_octale: // reading octal number with non-octal digits case STATE_octale: // reading octal number with non-octal digits
if (!isoctal(c)) if (!isoctal((utf8_t)c))
{ {
if (c == '_') // ignore embedded _ if (c == '_') // ignore embedded _
{ p++; { p++;
@@ -2078,14 +2021,10 @@ done:
n = stringbuffer.data[0] - '0'; n = stringbuffer.data[0] - '0';
else else
{ {
// Convert string to integer /* Convert string to integer
#if __DMC__ * Not everybody implements strtoull()
errno = 0; * and besides, we don't want to deal with errno.
n = strtoull((char *)stringbuffer.data,NULL,0); */
if (errno == ERANGE)
error("integer overflow");
#else
// Not everybody implements strtoull()
char *p = (char *)stringbuffer.data; char *p = (char *)stringbuffer.data;
int r = 10, d; int r = 10, d;
@@ -2123,7 +2062,7 @@ done:
n = n2 + d; n = n2 + d;
p++; p++;
} }
#endif
if (sizeof(n) > 8 && if (sizeof(n) > 8 &&
n > 0xFFFFFFFFFFFFFFFFULL) // if n needs more than 64 bits n > 0xFFFFFFFFFFFFFFFFULL) // if n needs more than 64 bits
error("integer overflow"); error("integer overflow");
@@ -2154,11 +2093,9 @@ done:
break; break;
} }
#if DMDV2
if (state == STATE_octal && n >= 8) if (state == STATE_octal && n >= 8)
deprecation("octal literals 0%llo%.*s are deprecated, use std.conv.octal!%llo%.*s instead", deprecation("octal literals 0%llo%.*s are deprecated, use std.conv.octal!%llo%.*s instead",
n, p - psuffix, psuffix, n, p - psuffix, psuffix); n, p - psuffix, psuffix, n, p - psuffix, psuffix);
#endif
switch (flags) switch (flags)
{ {
@@ -2238,113 +2175,93 @@ done:
*/ */
TOK Lexer::inreal(Token *t) TOK Lexer::inreal(Token *t)
#ifdef __DMC__
__in
{ {
assert(*p == '.' || isdigit(*p));
}
__out (result)
{
switch (result)
{
case TOKfloat32v:
case TOKfloat64v:
case TOKfloat80v:
case TOKimaginary32v:
case TOKimaginary64v:
case TOKimaginary80v:
break;
default:
assert(0);
}
}
__body
#endif /* __DMC__ */
{ int dblstate;
unsigned c;
char hex; // is this a hexadecimal-floating-constant?
TOK result;
//printf("Lexer::inreal()\n"); //printf("Lexer::inreal()\n");
#ifdef DEBUG
assert(*p == '.' || isdigit(*p));
#endif
stringbuffer.reset(); stringbuffer.reset();
dblstate = 0; const unsigned char *pstart = p;
hex = 0; char hex = 0;
Lnext: unsigned c = *p++;
// Leading '0x'
if (c == '0')
{
c = *p++;
if (c == 'x' || c == 'X')
{
hex = true;
c = *p++;
}
}
// Digits to left of '.'
while (1) while (1)
{ {
// Get next char from input if (c == '.')
c = *p++;
//printf("dblstate = %d, c = '%c'\n", dblstate, c);
while (1)
{ {
switch (dblstate) c = *p++;
{
case 0: // opening state
if (c == '0')
dblstate = 9;
else if (c == '.')
dblstate = 3;
else
dblstate = 1;
break;
case 9:
dblstate = 1;
if (c == 'X' || c == 'x')
{ hex++;
break;
}
case 1: // digits to left of .
case 3: // digits to right of .
case 7: // continuing exponent digits
if (!isdigit(c) && !(hex && isxdigit(c)))
{
if (c == '_')
goto Lnext; // ignore embedded '_'
dblstate++;
continue;
}
break;
case 2: // no more digits to left of .
if (c == '.')
{ dblstate++;
break;
}
case 4: // no more digits to right of .
if ((c == 'E' || c == 'e') ||
hex && (c == 'P' || c == 'p'))
{ dblstate = 5;
hex = 0; // exponent is always decimal
break;
}
if (hex)
error("binary-exponent-part required");
goto done;
case 5: // looking immediately to right of E
dblstate++;
if (c == '-' || c == '+')
break;
case 6: // 1st exponent digit expected
if (!isdigit(c))
error("exponent expected");
dblstate++;
break;
case 8: // past end of exponent digits
goto done;
}
break; break;
} }
stringbuffer.writeByte(c); if (isdigit(c) || (hex && isxdigit(c)) || c == '_')
{
c = *p++;
continue;
}
break;
}
// Digits to right of '.'
while (1)
{
if (isdigit(c) || (hex && isxdigit(c)) || c == '_')
{
c = *p++;
continue;
}
break;
}
if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P')))
{
c = *p++;
if (c == '-' || c == '+')
{
c = *p++;
}
bool anyexp;
while (1)
{
if (isdigit(c) || (hex && isxdigit(c)))
{
anyexp = true;
c = *p++;
continue;
}
if (c == '_')
{
c = *p++;
continue;
}
if (!anyexp)
error("missing exponent");
break;
}
}
else if (hex)
error("exponent required for hex float");
--p;
while (pstart < p)
{
if (*pstart != '_')
stringbuffer.writeByte(*pstart);
++pstart;
} }
done:
p--;
stringbuffer.writeByte(0); stringbuffer.writeByte(0);
TOK result;
t->float80value = Port::strtold((char *)stringbuffer.data, NULL); t->float80value = Port::strtold((char *)stringbuffer.data, NULL);
errno = 0; errno = 0;
switch (*p) switch (*p)
@@ -2395,6 +2312,21 @@ done:
} }
if (errno == ERANGE) if (errno == ERANGE)
error("number is not representable"); error("number is not representable");
#ifdef DEBUG
switch (result)
{
case TOKfloat32v:
case TOKfloat64v:
case TOKfloat80v:
case TOKimaginary32v:
case TOKimaginary64v:
case TOKimaginary80v:
break;
default:
assert(0);
}
#endif
return result; return result;
} }
@@ -2413,7 +2345,7 @@ void Lexer::poundLine()
scan(&tok); scan(&tok);
if (tok.value == TOKint32v || tok.value == TOKint64v) if (tok.value == TOKint32v || tok.value == TOKint64v)
{ linnum = tok.uns64value - 1; { linnum = (int)(tok.uns64value - 1);
if (linnum != tok.uns64value - 1) if (linnum != tok.uns64value - 1)
error("line number out of range"); error("line number out of range");
} }
@@ -2523,7 +2455,7 @@ unsigned Lexer::decodeUTF()
{ {
dchar_t u; dchar_t u;
utf8_t c; utf8_t c;
utf8_t *s = p; const utf8_t *s = p;
size_t len; size_t len;
size_t idx; size_t idx;
const char *msg; const char *msg;
@@ -2563,9 +2495,9 @@ void Lexer::getDocComment(Token *t, unsigned lineComment)
/* Start of comment text skips over / * *, / + +, or / / / /* Start of comment text skips over / * *, / + +, or / / /
*/ */
utf8_t *q = t->ptr + 3; // start of comment text const utf8_t *q = t->ptr + 3; // start of comment text
utf8_t *qend = p; const utf8_t *qend = p;
if (ct == '*' || ct == '+') if (ct == '*' || ct == '+')
qend -= 2; qend -= 2;
@@ -2658,7 +2590,7 @@ void Lexer::getDocComment(Token *t, unsigned lineComment)
// It's a line comment if the start of the doc comment comes // It's a line comment if the start of the doc comment comes
// after other non-whitespace on the same line. // after other non-whitespace on the same line.
utf8_t** dc = (lineComment && anyToken) const utf8_t** dc = (lineComment && anyToken)
? &t->lineComment ? &t->lineComment
: &t->blockComment; : &t->blockComment;
@@ -2674,11 +2606,11 @@ void Lexer::getDocComment(Token *t, unsigned lineComment)
* separated by a newline. * separated by a newline.
*/ */
utf8_t *Lexer::combineComments(utf8_t *c1, utf8_t *c2) const utf8_t *Lexer::combineComments(const utf8_t *c1, const utf8_t *c2)
{ {
//printf("Lexer::combineComments('%s', '%s')\n", c1, c2); //printf("Lexer::combineComments('%s', '%s')\n", c1, c2);
utf8_t *c = c2; const utf8_t *c = c2;
if (c1) if (c1)
{ c = c1; { c = c1;
@@ -2686,14 +2618,15 @@ utf8_t *Lexer::combineComments(utf8_t *c1, utf8_t *c2)
{ size_t len1 = strlen((char *)c1); { size_t len1 = strlen((char *)c1);
size_t len2 = strlen((char *)c2); size_t len2 = strlen((char *)c2);
c = (utf8_t *)mem.malloc(len1 + 1 + len2 + 1); utf8_t *p = (utf8_t *)mem.malloc(len1 + 1 + len2 + 1);
memcpy(c, c1, len1); memcpy(p, c1, len1);
if (len1 && c1[len1 - 1] != '\n') if (len1 && c1[len1 - 1] != '\n')
{ c[len1] = '\n'; { p[len1] = '\n';
len1++; len1++;
} }
memcpy(c + len1, c2, len2); memcpy(p + len1, c2, len2);
c[len1 + len2] = 0; p[len1 + len2] = 0;
c = p;
} }
} }
return c; return c;
@@ -2860,7 +2793,7 @@ static Keyword keywords[] =
{ "__parameters", TOKparameters }, { "__parameters", TOKparameters },
{ "ref", TOKref }, { "ref", TOKref },
{ "macro", TOKmacro }, { "macro", TOKmacro },
#if DMDV2
{ "pure", TOKpure }, { "pure", TOKpure },
{ "nothrow", TOKnothrow }, { "nothrow", TOKnothrow },
{ "__gshared", TOKgshared }, { "__gshared", TOKgshared },
@@ -2874,7 +2807,6 @@ static Keyword keywords[] =
{ "__PRETTY_FUNCTION__", TOKprettyfunc }, { "__PRETTY_FUNCTION__", TOKprettyfunc },
{ "shared", TOKshared }, { "shared", TOKshared },
{ "immutable", TOKimmutable }, { "immutable", TOKimmutable },
#endif
}; };
int Token::isKeyword() int Token::isKeyword()
@@ -2922,9 +2854,7 @@ void Lexer::initKeywords()
Token::tochars[TOKxorass] = "^="; Token::tochars[TOKxorass] = "^=";
Token::tochars[TOKassign] = "="; Token::tochars[TOKassign] = "=";
Token::tochars[TOKconstruct] = "="; Token::tochars[TOKconstruct] = "=";
#if DMDV2
Token::tochars[TOKblit] = "="; Token::tochars[TOKblit] = "=";
#endif
Token::tochars[TOKlt] = "<"; Token::tochars[TOKlt] = "<";
Token::tochars[TOKgt] = ">"; Token::tochars[TOKgt] = ">";
Token::tochars[TOKle] = "<="; Token::tochars[TOKle] = "<=";
@@ -2993,13 +2923,11 @@ void Lexer::initKeywords()
Token::tochars[TOKorass] = "|="; Token::tochars[TOKorass] = "|=";
Token::tochars[TOKidentifier] = "identifier"; Token::tochars[TOKidentifier] = "identifier";
#if DMDV2
Token::tochars[TOKat] = "@"; Token::tochars[TOKat] = "@";
Token::tochars[TOKpow] = "^^"; Token::tochars[TOKpow] = "^^";
Token::tochars[TOKpowass] = "^^="; Token::tochars[TOKpowass] = "^^=";
Token::tochars[TOKgoesto] = "=>"; Token::tochars[TOKgoesto] = "=>";
Token::tochars[TOKpound] = "#"; Token::tochars[TOKpound] = "#";
#endif
// For debugging // For debugging
Token::tochars[TOKerror] = "error"; Token::tochars[TOKerror] = "error";
+12 -15
View File
@@ -126,7 +126,7 @@ enum TOK
TOKfloat32, TOKfloat64, TOKfloat80, TOKfloat32, TOKfloat64, TOKfloat80,
TOKimaginary32, TOKimaginary64, TOKimaginary80, TOKimaginary32, TOKimaginary64, TOKimaginary80,
TOKcomplex32, TOKcomplex64, TOKcomplex80, TOKcomplex32, TOKcomplex64, TOKcomplex80,
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool, TOKchar, TOKwchar, TOKdchar, TOKbool,
// 152 // 152
// Aggregates // Aggregates
@@ -157,7 +157,7 @@ enum TOK
TOKargTypes, TOKargTypes,
TOKref, TOKref,
TOKmacro, TOKmacro,
#if DMDV2
TOKparameters, TOKparameters,
TOKtraits, TOKtraits,
TOKoverloadset, TOKoverloadset,
@@ -176,7 +176,6 @@ enum TOK
TOKgoesto, TOKgoesto,
TOKvector, TOKvector,
TOKpound, TOKpound,
#endif
// LDC specific // LDC specific
#if IN_LLVM #if IN_LLVM
@@ -190,7 +189,7 @@ enum TOK
#define BASIC_TYPES \ #define BASIC_TYPES \
TOKwchar: case TOKdchar: \ TOKwchar: case TOKdchar: \
case TOKbit: case TOKbool: case TOKchar: \ case TOKbool: case TOKchar: \
case TOKint8: case TOKuns8: \ case TOKint8: case TOKuns8: \
case TOKint16: case TOKuns16: \ case TOKint16: case TOKuns16: \
case TOKint32: case TOKuns32: \ case TOKint32: case TOKuns32: \
@@ -232,10 +231,10 @@ struct Token
{ {
Token *next; Token *next;
Loc loc; Loc loc;
utf8_t *ptr; // pointer to first character of this token within buffer const utf8_t *ptr; // pointer to first character of this token within buffer
TOK value; TOK value;
utf8_t *blockComment; // doc comment string prior to this token const utf8_t *blockComment; // doc comment string prior to this token
utf8_t *lineComment; // doc comment for previous token const utf8_t *lineComment; // doc comment for previous token
union union
{ {
// Integers // Integers
@@ -277,9 +276,9 @@ public:
Loc scanloc; // for error messages Loc scanloc; // for error messages
utf8_t *base; // pointer to start of buffer const utf8_t *base; // pointer to start of buffer
utf8_t *end; // past end of buffer const utf8_t *end; // past end of buffer
utf8_t *p; // current character const utf8_t *p; // current character
Token token; Token token;
Module *mod; Module *mod;
int doDocComment; // collect doc comment information int doDocComment; // collect doc comment information
@@ -287,7 +286,7 @@ public:
int commentToken; // !=0 means comments are TOKcomment's int commentToken; // !=0 means comments are TOKcomment's
Lexer(Module *mod, Lexer(Module *mod,
utf8_t *base, size_t begoffset, size_t endoffset, const utf8_t *base, size_t begoffset, size_t endoffset,
int doDocComment, int commentToken); int doDocComment, int commentToken);
static void initKeywords(); static void initKeywords();
@@ -304,10 +303,8 @@ public:
unsigned escapeSequence(); unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc); TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t); TOK hexStringConstant(Token *t);
#if DMDV2
TOK delimitedStringConstant(Token *t); TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t); TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide); TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide); TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t); void stringPostfix(Token *t);
@@ -320,8 +317,8 @@ public:
unsigned decodeUTF(); unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment); void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p); static int isValidIdentifier(const char *p);
static utf8_t *combineComments(utf8_t *c1, utf8_t *c2); static const utf8_t *combineComments(const utf8_t *c1, const utf8_t *c2);
}; };
#endif /* DMD_LEXER_H */ #endif /* DMD_LEXER_H */
+1 -1
View File
@@ -20,7 +20,7 @@ class Library
public: public:
static Library *factory(); static Library *factory();
virtual void setFilename(char *dir, char *filename) = 0; virtual void setFilename(const char *dir, const char *filename) = 0;
virtual void addObject(const char *module_name, void *buf, size_t buflen) = 0; virtual void addObject(const char *module_name, void *buf, size_t buflen) = 0;
virtual void addLibrary(void *buf, size_t buflen) = 0; virtual void addLibrary(void *buf, size_t buflen) = 0;
virtual void write() = 0; virtual void write() = 0;
+15 -15
View File
@@ -21,16 +21,16 @@
#include "macro.h" #include "macro.h"
int isIdStart(utf8_t *p); int isIdStart(const utf8_t *p);
int isIdTail(utf8_t *p); int isIdTail(const utf8_t *p);
int utfStride(utf8_t *p); int utfStride(const utf8_t *p);
utf8_t *memdup(utf8_t *p, size_t len) utf8_t *memdup(const utf8_t *p, size_t len)
{ {
return (utf8_t *)memcpy(mem.malloc(len), p, len); return (utf8_t *)memcpy(mem.malloc(len), p, len);
} }
Macro::Macro(utf8_t *name, size_t namelen, utf8_t *text, size_t textlen) Macro::Macro(const utf8_t *name, size_t namelen, const utf8_t *text, size_t textlen)
{ {
next = NULL; next = NULL;
@@ -51,7 +51,7 @@ Macro::Macro(utf8_t *name, size_t namelen, utf8_t *text, size_t textlen)
} }
Macro *Macro::search(utf8_t *name, size_t namelen) Macro *Macro::search(const utf8_t *name, size_t namelen)
{ Macro *table; { Macro *table;
//printf("Macro::search(%.*s)\n", namelen, name); //printf("Macro::search(%.*s)\n", namelen, name);
@@ -67,7 +67,7 @@ Macro *Macro::search(utf8_t *name, size_t namelen)
return table; return table;
} }
Macro *Macro::define(Macro **ptable, utf8_t *name, size_t namelen, utf8_t *text, size_t textlen) Macro *Macro::define(Macro **ptable, const utf8_t *name, size_t namelen, const utf8_t *text, size_t textlen)
{ {
//printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text); //printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
@@ -98,7 +98,7 @@ Macro *Macro::define(Macro **ptable, utf8_t *name, size_t namelen, utf8_t *text,
* -1: get 2nd through end * -1: get 2nd through end
*/ */
size_t extractArgN(utf8_t *p, size_t end, utf8_t **pmarg, size_t *pmarglen, int n) size_t extractArgN(const utf8_t *p, size_t end, const utf8_t **pmarg, size_t *pmarglen, int n)
{ {
/* Scan forward for matching right parenthesis. /* Scan forward for matching right parenthesis.
* Nest parentheses. * Nest parentheses.
@@ -238,7 +238,7 @@ size_t extractArgN(utf8_t *p, size_t end, utf8_t **pmarg, size_t *pmarglen, int
*/ */
void Macro::expand(OutBuffer *buf, size_t start, size_t *pend, void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
utf8_t *arg, size_t arglen) const utf8_t *arg, size_t arglen)
{ {
#if 0 #if 0
printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg); printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
@@ -259,7 +259,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
arg = memdup(arg, arglen); arg = memdup(arg, arglen);
for (size_t u = start; u + 1 < end; ) for (size_t u = start; u + 1 < end; )
{ {
utf8_t *p = buf->data; // buf->data is not loop invariant utf8_t *p = (utf8_t *)buf->data; // buf->data is not loop invariant
/* Look for $0, but not $$0, and replace it with arg. /* Look for $0, but not $$0, and replace it with arg.
*/ */
@@ -276,7 +276,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
utf8_t c = p[u + 1]; utf8_t c = p[u + 1];
int n = (c == '+') ? -1 : c - '0'; int n = (c == '+') ? -1 : c - '0';
utf8_t *marg; const utf8_t *marg;
size_t marglen; size_t marglen;
extractArgN(arg, arglen, &marg, &marglen, n); extractArgN(arg, arglen, &marg, &marglen, n);
if (marglen == 0) if (marglen == 0)
@@ -327,7 +327,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
*/ */
for (size_t u = start; u + 4 < end; ) for (size_t u = start; u + 4 < end; )
{ {
utf8_t *p = buf->data; // buf->data is not loop invariant utf8_t *p = (utf8_t *)buf->data; // buf->data is not loop invariant
/* A valid start of macro expansion is $(c, where c is /* A valid start of macro expansion is $(c, where c is
* an id start character, and not $$(c. * an id start character, and not $$(c.
@@ -338,7 +338,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
utf8_t *name = p + u + 2; utf8_t *name = p + u + 2;
size_t namelen = 0; size_t namelen = 0;
utf8_t *marg; const utf8_t *marg;
size_t marglen; size_t marglen;
size_t v; size_t v;
@@ -427,7 +427,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
end -= v + 1 - u; end -= v + 1 - u;
u += mend - (v + 1); u += mend - (v + 1);
#endif #endif
mem.free(marg); mem.free((utf8_t *)marg);
//printf("u = %d, end = %d\n", u, end); //printf("u = %d, end = %d\n", u, end);
//printf("#%.*s#\n", end - u, &buf->data[u]); //printf("#%.*s#\n", end - u, &buf->data[u]);
continue; continue;
@@ -444,7 +444,7 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
} }
u++; u++;
} }
mem.free(arg); mem.free((utf8_t *)arg);
*pend = end; *pend = end;
nest--; nest--;
} }
+6 -6
View File
@@ -24,22 +24,22 @@ struct Macro
private: private:
Macro *next; // next in list Macro *next; // next in list
utf8_t *name; // macro name const utf8_t *name; // macro name
size_t namelen; // length of macro name size_t namelen; // length of macro name
utf8_t *text; // macro replacement text const utf8_t *text; // macro replacement text
size_t textlen; // length of replacement text size_t textlen; // length of replacement text
int inuse; // macro is in use (don't expand) int inuse; // macro is in use (don't expand)
Macro(utf8_t *name, size_t namelen, utf8_t *text, size_t textlen); Macro(const utf8_t *name, size_t namelen, const utf8_t *text, size_t textlen);
Macro *search(utf8_t *name, size_t namelen); Macro *search(const utf8_t *name, size_t namelen);
public: public:
static Macro *define(Macro **ptable, utf8_t *name, size_t namelen, utf8_t *text, size_t textlen); static Macro *define(Macro **ptable, const utf8_t *name, size_t namelen, const utf8_t *text, size_t textlen);
void expand(OutBuffer *buf, size_t start, size_t *pend, void expand(OutBuffer *buf, size_t start, size_t *pend,
utf8_t *arg, size_t arglen); const utf8_t *arg, size_t arglen);
}; };
#endif #endif
+38 -44
View File
@@ -67,7 +67,12 @@ char *mangle(Declaration *sthis, bool isv)
} }
else else
buf.prependstring("0"); buf.prependstring("0");
s = s->parent;
TemplateInstance *ti = s->isTemplateInstance();
if (ti && !ti->isTemplateMixin())
s = ti->tempdecl->parent;
else
s = s->parent;
} while (s); } while (s);
// buf.prependstring("_D"); // buf.prependstring("_D");
@@ -118,23 +123,9 @@ L1:
} }
const char *Declaration::mangle(bool isv) const char *Declaration::mangle(bool isv)
#if __DMC__ {
__out(result) char *p;
{
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); //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 (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
{ {
@@ -150,34 +141,52 @@ const char *Declaration::mangle(bool isv)
case LINKc: case LINKc:
case LINKwindows: case LINKwindows:
case LINKpascal: case LINKpascal:
return ident->toChars(); p = ident->toChars();
goto Lret;
case LINKcpp: case LINKcpp:
#if CPP_MANGLE #if CPP_MANGLE
return cpp_mangle(this); p = cpp_mangle(this);
#else #else
// Windows C++ mangling is done by C++ back end // Windows C++ mangling is done by C++ back end
return ident->toChars(); p = ident->toChars();
#endif #endif
goto Lret;
case LINKdefault: case LINKdefault:
error("forward declaration"); error("forward declaration");
return ident->toChars(); p = ident->toChars();
goto Lret;
default: default:
fprintf(stderr, "'%s', linkage = %d\n", toChars(), linkage); fprintf(stderr, "'%s', linkage = %d\n", toChars(), linkage);
assert(0); assert(0);
} }
} }
char *p = ::mangle(this, isv); {
p = ::mangle(this, isv);
OutBuffer buf; OutBuffer buf;
buf.writestring("_D"); buf.writestring("_D");
buf.writestring(p); buf.writestring(p);
p = buf.toChars(); p = buf.toChars();
buf.data = NULL; buf.data = NULL;
}
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p); //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
Lret:
#ifdef DEBUG
size_t len = strlen(p);
assert(len > 0);
//printf("mangle: '%s' => '%s'\n", toChars(), p);
for (size_t i = 0; i < len; i++)
{
assert(p[i] == '_' ||
p[i] == '@' ||
isalnum(p[i]) || p[i] & 0x80);
}
#endif
return p; return p;
} }
/****************************************************************************** /******************************************************************************
* Normally FuncDeclaration and FuncAliasDeclaration have overloads. * Normally FuncDeclaration and FuncAliasDeclaration have overloads.
@@ -222,14 +231,7 @@ const char *FuncAliasDeclaration::mangle(bool isv)
* Returns exact mangled name of function. * Returns exact mangled name of function.
*/ */
const char *FuncDeclaration::mangleExact(bool isv) const char *FuncDeclaration::mangleExact(bool isv)
#if __DMC__ {
__out(result)
{
assert(strlen(result) > 0);
}
__body
#endif
{
assert(!isFuncAliasDeclaration()); assert(!isFuncAliasDeclaration());
if (mangleOverride) if (mangleOverride)
@@ -243,22 +245,15 @@ const char *FuncDeclaration::mangleExact(bool isv)
assert(this); assert(this);
return Declaration::mangle(isv); return Declaration::mangle(isv);
} }
const char *VarDeclaration::mangle(bool isv) const char *VarDeclaration::mangle(bool isv)
#if __DMC__ {
__out(result)
{
assert(strlen(result) > 0);
}
__body
#endif
{
if (mangleOverride) if (mangleOverride)
return mangleOverride; return mangleOverride;
return Declaration::mangle(); return Declaration::mangle();
} }
const char *TypedefDeclaration::mangle(bool isv) const char *TypedefDeclaration::mangle(bool isv)
{ {
@@ -269,7 +264,6 @@ const char *TypedefDeclaration::mangle(bool isv)
const char *AggregateDeclaration::mangle(bool isv) const char *AggregateDeclaration::mangle(bool isv)
{ {
#if 1
//printf("AggregateDeclaration::mangle() '%s'\n", toChars()); //printf("AggregateDeclaration::mangle() '%s'\n", toChars());
if (Dsymbol *p = toParent2()) if (Dsymbol *p = toParent2())
{ if (FuncDeclaration *fd = p->isFuncDeclaration()) { if (FuncDeclaration *fd = p->isFuncDeclaration())
@@ -279,7 +273,7 @@ const char *AggregateDeclaration::mangle(bool isv)
return id; return id;
} }
} }
#endif
return Dsymbol::mangle(isv); return Dsymbol::mangle(isv);
} }
@@ -341,7 +335,7 @@ const char *TemplateInstance::mangle(bool isv)
error("is not defined"); error("is not defined");
else else
{ {
Dsymbol *par = enclosing || isTemplateMixin() ? parent : tempdecl->parent; Dsymbol *par = isTemplateMixin() ? parent : tempdecl->parent;
if (par) if (par)
{ {
const char *p = par->mangle(isv); const char *p = par->mangle(isv);
+55 -109
View File
@@ -47,9 +47,9 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
#endif #endif
#if !IN_LLVM #if !IN_LLVM
int response_expand(size_t *pargc, char ***pargv); int response_expand(size_t *pargc, const char ***pargv);
void browse(const char *url); void browse(const char *url);
void getenv_setargv(const char *envvar, size_t *pargc, char** *pargv); void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv);
void obj_start(char *srcfile); void obj_start(char *srcfile);
void obj_end(Library *library, File *objfile); void obj_end(Library *library, File *objfile);
@@ -57,7 +57,7 @@ void obj_end(Library *library, File *objfile);
void printCtfePerformanceStats(); void printCtfePerformanceStats();
static bool parse_arch(size_t argc, char** argv, bool is64bit); static bool parse_arch(size_t argc, const char** argv, bool is64bit);
/** Normalize path by turning forward slashes into backslashes */ /** Normalize path by turning forward slashes into backslashes */
void toWinPath(char *src) void toWinPath(char *src)
@@ -384,7 +384,7 @@ Usage:\n\
-debuglib=name set symbolic debug library to name\n\ -debuglib=name set symbolic debug library to name\n\
-defaultlib=name set default library to name\n\ -defaultlib=name set default library to name\n\
-deps print module dependencies (imports/file/version/debug/lib)\n\ -deps print module dependencies (imports/file/version/debug/lib)\n\
-deps=filename write module dependencies to filename (only imports - deprecated)\n%s\ -deps=filename write module dependencies to filename (only imports)\n%s\
-g add symbolic debug info\n\ -g add symbolic debug info\n\
-gc add symbolic debug info, pretend to be C\n\ -gc add symbolic debug info, pretend to be C\n\
-gs always emit stack frame\n\ -gs always emit stack frame\n\
@@ -432,14 +432,6 @@ Usage:\n\
extern signed char tyalignsize[]; extern signed char tyalignsize[];
#if _WIN32 && __DMC__
extern "C"
{
extern int _xi_a;
extern int _end;
}
#endif
static Module *entrypoint = NULL; static Module *entrypoint = NULL;
/************************************ /************************************
@@ -457,7 +449,7 @@ void genCmain(Scope *sc)
/* The D code to be generated is provided as D source code in the form of a string. /* The D code to be generated is provided as D source code in the form of a string.
* Note that Solaris, for unknown reasons, requires both a main() and an _main() * Note that Solaris, for unknown reasons, requires both a main() and an _main()
*/ */
static utf8_t code[] = "extern(C) {\n\ static const utf8_t cmaincode[] = "extern(C) {\n\
int _d_run_main(int argc, char **argv, void* mainFunc);\n\ int _d_run_main(int argc, char **argv, void* mainFunc);\n\
int _Dmain(char[][] args);\n\ int _Dmain(char[][] args);\n\
int main(int argc, char **argv) { return _d_run_main(argc, argv, &_Dmain); }\n\ int main(int argc, char **argv) { return _d_run_main(argc, argv, &_Dmain); }\n\
@@ -468,7 +460,7 @@ void genCmain(Scope *sc)
Identifier *id = Id::entrypoint; Identifier *id = Id::entrypoint;
Module *m = new Module("__entrypoint.d", id, 0, 0); Module *m = new Module("__entrypoint.d", id, 0, 0);
Parser p(m, code, sizeof(code) / sizeof(code[0]), 0); Parser p(m, cmaincode, strlen((const char *)cmaincode), 0);
p.scanloc = Loc(); p.scanloc = Loc();
p.nextToken(); p.nextToken();
m->members = p.parseModule(); m->members = p.parseModule();
@@ -486,18 +478,10 @@ void genCmain(Scope *sc)
entrypoint = m; entrypoint = m;
} }
int tryMain(size_t argc, char *argv[]) int tryMain(size_t argc, const char *argv[])
{ {
mem.init(); // initialize storage allocator
mem.setStackBottom(&argv);
#if _WIN32 && __DMC__
mem.addroots((char *)&_xi_a, (char *)&_end);
#endif
Strings files; Strings files;
Strings libmodules; Strings libmodules;
char *p;
Module *m;
size_t argcstart = argc; size_t argcstart = argc;
int setdebuglib = 0; int setdebuglib = 0;
char noboundscheck = 0; char noboundscheck = 0;
@@ -552,7 +536,7 @@ int tryMain(size_t argc, char *argv[])
global.params.is64bit = (sizeof(size_t) == 8); global.params.is64bit = (sizeof(size_t) == 8);
#if TARGET_WINDOS #if TARGET_WINDOS
global.params.is64bit = 0; global.params.is64bit = false;
global.params.defaultlibname = "phobos"; global.params.defaultlibname = "phobos";
#elif TARGET_LINUX #elif TARGET_LINUX
global.params.defaultlibname = "libphobos2.a"; global.params.defaultlibname = "libphobos2.a";
@@ -597,9 +581,7 @@ int tryMain(size_t argc, char *argv[])
VersionCondition::addPredefinedGlobalIdent("LittleEndian"); VersionCondition::addPredefinedGlobalIdent("LittleEndian");
//VersionCondition::addPredefinedGlobalIdent("D_Bits"); //VersionCondition::addPredefinedGlobalIdent("D_Bits");
#if DMDV2
VersionCondition::addPredefinedGlobalIdent("D_Version2"); VersionCondition::addPredefinedGlobalIdent("D_Version2");
#endif
VersionCondition::addPredefinedGlobalIdent("all"); VersionCondition::addPredefinedGlobalIdent("all");
#if _WIN32 #if _WIN32
@@ -611,7 +593,7 @@ int tryMain(size_t argc, char *argv[])
#endif #endif
size_t dflags_argc = 0; size_t dflags_argc = 0;
char** dflags_argv = NULL; const char** dflags_argv = NULL;
getenv_setargv("DFLAGS", &dflags_argc, &dflags_argv); getenv_setargv("DFLAGS", &dflags_argc, &dflags_argv);
bool is64bit = global.params.is64bit; // use default bool is64bit = global.params.is64bit; // use default
@@ -619,7 +601,8 @@ int tryMain(size_t argc, char *argv[])
is64bit = parse_arch(dflags_argc, dflags_argv, is64bit); is64bit = parse_arch(dflags_argc, dflags_argv, is64bit);
global.params.is64bit = is64bit; global.params.is64bit = is64bit;
inifile(argv[0], inifilename, is64bit ? "Environment64" : "Environment32"); const char *envsec = is64bit ? "Environment64" : "Environment32";
inifile(argv[0], inifilename, envsec);
getenv_setargv("DFLAGS", &argc, &argv); getenv_setargv("DFLAGS", &argc, &argv);
@@ -632,7 +615,7 @@ int tryMain(size_t argc, char *argv[])
for (size_t i = 1; i < argc; i++) for (size_t i = 1; i < argc; i++)
{ {
p = argv[i]; const char *p = argv[i];
if (*p == '-') if (*p == '-')
{ {
if (strcmp(p + 1, "allinst") == 0) if (strcmp(p + 1, "allinst") == 0)
@@ -657,10 +640,10 @@ int tryMain(size_t argc, char *argv[])
{ long percent; { long percent;
errno = 0; errno = 0;
percent = strtol(p + 5, &p, 10); percent = strtol(p + 5, (char **)&p, 10);
if (*p || errno || percent > 100) if (*p || errno || percent > 100)
goto Lerror; goto Lerror;
global.params.covPercent = percent; global.params.covPercent = (unsigned char)percent;
} }
else else
goto Lerror; goto Lerror;
@@ -704,14 +687,13 @@ int tryMain(size_t argc, char *argv[])
global.params.trace = 1; global.params.trace = 1;
} }
else if (strcmp(p + 1, "m32") == 0) else if (strcmp(p + 1, "m32") == 0)
global.params.is64bit = 0; global.params.is64bit = false;
else if (strcmp(p + 1, "m64") == 0) else if (strcmp(p + 1, "m64") == 0)
global.params.is64bit = 1; global.params.is64bit = true;
else if (strcmp(p + 1, "profile") == 0) else if (strcmp(p + 1, "profile") == 0)
global.params.trace = 1; global.params.trace = 1;
else if (strcmp(p + 1, "v") == 0) else if (strcmp(p + 1, "v") == 0)
global.params.verbose = 1; global.params.verbose = 1;
#if DMDV2
else if (strcmp(p + 1, "vtls") == 0) else if (strcmp(p + 1, "vtls") == 0)
global.params.vtls = 1; global.params.vtls = 1;
else if (memcmp(p + 1, "transition", 10) == 0) else if (memcmp(p + 1, "transition", 10) == 0)
@@ -740,7 +722,7 @@ Language changes listed by -transition=id:\n\
{ long num; { long num;
errno = 0; errno = 0;
num = strtol(p + 12, &p, 10); num = strtol(p + 12, (char **)&p, 10);
if (*p || errno || num > INT_MAX) if (*p || errno || num > INT_MAX)
goto Lerror; goto Lerror;
switch (num) // Bugzilla issue number switch (num) // Bugzilla issue number
@@ -767,7 +749,6 @@ Language changes listed by -transition=id:\n\
else else
goto Lerror; goto Lerror;
} }
#endif
else if (strcmp(p + 1, "w") == 0) else if (strcmp(p + 1, "w") == 0)
global.params.warnings = 1; global.params.warnings = 1;
else if (strcmp(p + 1, "wi") == 0) else if (strcmp(p + 1, "wi") == 0)
@@ -786,7 +767,7 @@ Language changes listed by -transition=id:\n\
if (!p[3]) if (!p[3])
goto Lnoarg; goto Lnoarg;
#if _WIN32 #if _WIN32
toWinPath(p + 3); toWinPath((char *)p + 3);
#endif #endif
global.params.objdir = p + 3; global.params.objdir = p + 3;
break; break;
@@ -795,7 +776,7 @@ Language changes listed by -transition=id:\n\
if (!p[3]) if (!p[3])
goto Lnoarg; goto Lnoarg;
#if _WIN32 #if _WIN32
toWinPath(p + 3); toWinPath((char *)p + 3);
#endif #endif
global.params.objname = p + 3; global.params.objname = p + 3;
break; break;
@@ -892,10 +873,8 @@ Language changes listed by -transition=id:\n\
global.params.release = 1; global.params.release = 1;
else if (strcmp(p + 1, "betterC") == 0) else if (strcmp(p + 1, "betterC") == 0)
global.params.betterC = 1; global.params.betterC = 1;
#if DMDV2
else if (strcmp(p + 1, "noboundscheck") == 0) else if (strcmp(p + 1, "noboundscheck") == 0)
noboundscheck = 1; noboundscheck = 1;
#endif
else if (strcmp(p + 1, "unittest") == 0) else if (strcmp(p + 1, "unittest") == 0)
global.params.useUnitTests = 1; global.params.useUnitTests = 1;
else if (p[1] == 'I') else if (p[1] == 'I')
@@ -922,7 +901,7 @@ Language changes listed by -transition=id:\n\
{ long level; { long level;
errno = 0; errno = 0;
level = strtol(p + 7, &p, 10); level = strtol(p + 7, (char **)&p, 10);
if (*p || errno || level > INT_MAX) if (*p || errno || level > INT_MAX)
goto Lerror; goto Lerror;
DebugCondition::setGlobalLevel((int)level); DebugCondition::setGlobalLevel((int)level);
@@ -948,7 +927,7 @@ Language changes listed by -transition=id:\n\
{ long level; { long level;
errno = 0; errno = 0;
level = strtol(p + 9, &p, 10); level = strtol(p + 9, (char **)&p, 10);
if (*p || errno || level > INT_MAX) if (*p || errno || level > INT_MAX)
goto Lerror; goto Lerror;
VersionCondition::setGlobalLevel((int)level); VersionCondition::setGlobalLevel((int)level);
@@ -1017,39 +996,19 @@ Language changes listed by -transition=id:\n\
else if (memcmp(p + 1, "man", 3) == 0) else if (memcmp(p + 1, "man", 3) == 0)
{ {
#if _WIN32 #if _WIN32
#if DMDV1
browse("http://www.digitalmars.com/d/1.0/dmd-windows.html");
#else
browse("http://dlang.org/dmd-windows.html"); browse("http://dlang.org/dmd-windows.html");
#endif #endif
#endif
#if linux #if linux
#if DMDV1
browse("http://www.digitalmars.com/d/1.0/dmd-linux.html");
#else
browse("http://dlang.org/dmd-linux.html"); browse("http://dlang.org/dmd-linux.html");
#endif #endif
#endif
#if __APPLE__ #if __APPLE__
#if DMDV1
browse("http://www.digitalmars.com/d/1.0/dmd-osx.html");
#else
browse("http://dlang.org/dmd-osx.html"); browse("http://dlang.org/dmd-osx.html");
#endif #endif
#endif
#if __FreeBSD__ #if __FreeBSD__
#if DMDV1
browse("http://www.digitalmars.com/d/1.0/dmd-freebsd.html");
#else
browse("http://dlang.org/dmd-freebsd.html"); browse("http://dlang.org/dmd-freebsd.html");
#endif #endif
#endif
#if __OpenBSD__ #if __OpenBSD__
#if DMDV1
browse("http://www.digitalmars.com/d/1.0/dmd-openbsd.html");
#else
browse("http://dlang.org/dmd-openbsd.html"); browse("http://dlang.org/dmd-openbsd.html");
#endif
#endif #endif
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@@ -1103,7 +1062,7 @@ Language changes listed by -transition=id:\n\
if(global.params.is64bit != is64bit) if(global.params.is64bit != is64bit)
error(Loc(), "the architecture must not be changed in the %s section of %s", error(Loc(), "the architecture must not be changed in the %s section of %s",
is64bit ? "Environment64" : "Environment32", inifilename); envsec, inifilename);
// Target uses 64bit pointers. // Target uses 64bit pointers.
global.params.isLP64 = global.params.is64bit; global.params.isLP64 = global.params.is64bit;
@@ -1175,15 +1134,7 @@ Language changes listed by -transition=id:\n\
global.params.objname = NULL; global.params.objname = NULL;
// Haven't investigated handling these options with multiobj // Haven't investigated handling these options with multiobj
if (!global.params.cov && !global.params.trace if (!global.params.cov && !global.params.trace)
#if 0 && TARGET_WINDOS
/* multiobj causes class/struct debug info to be attached to init-data,
* but this will not be linked into the executable, so this info is lost.
* Bugzilla 4014
*/
&& !global.params.symdebug
#endif
)
global.params.multiobj = 1; global.params.multiobj = 1;
} }
else if (global.params.run) else if (global.params.run)
@@ -1234,14 +1185,12 @@ Language changes listed by -transition=id:\n\
VersionCondition::addPredefinedGlobalIdent("D_Coverage"); VersionCondition::addPredefinedGlobalIdent("D_Coverage");
if (global.params.pic) if (global.params.pic)
VersionCondition::addPredefinedGlobalIdent("D_PIC"); VersionCondition::addPredefinedGlobalIdent("D_PIC");
#if DMDV2
if (global.params.useUnitTests) if (global.params.useUnitTests)
VersionCondition::addPredefinedGlobalIdent("unittest"); VersionCondition::addPredefinedGlobalIdent("unittest");
if (global.params.useAssert) if (global.params.useAssert)
VersionCondition::addPredefinedGlobalIdent("assert"); VersionCondition::addPredefinedGlobalIdent("assert");
if (noboundscheck) if (noboundscheck)
VersionCondition::addPredefinedGlobalIdent("D_NoBoundsChecks"); VersionCondition::addPredefinedGlobalIdent("D_NoBoundsChecks");
#endif
VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); VersionCondition::addPredefinedGlobalIdent("D_HardFloat");
@@ -1266,7 +1215,7 @@ Language changes listed by -transition=id:\n\
{ {
for (size_t i = 0; i < global.params.imppath->dim; i++) for (size_t i = 0; i < global.params.imppath->dim; i++)
{ {
char *path = (*global.params.imppath)[i]; const char *path = (*global.params.imppath)[i];
Strings *a = FileName::splitPath(path); Strings *a = FileName::splitPath(path);
if (a) if (a)
@@ -1283,7 +1232,7 @@ Language changes listed by -transition=id:\n\
{ {
for (size_t i = 0; i < global.params.fileImppath->dim; i++) for (size_t i = 0; i < global.params.fileImppath->dim; i++)
{ {
char *path = (*global.params.fileImppath)[i]; const char *path = (*global.params.fileImppath)[i];
Strings *a = FileName::splitPath(path); Strings *a = FileName::splitPath(path);
if (a) if (a)
@@ -1306,22 +1255,18 @@ Language changes listed by -transition=id:\n\
bool firstmodule = true; bool firstmodule = true;
for (size_t i = 0; i < files.dim; i++) for (size_t i = 0; i < files.dim; i++)
{ {
const char *ext; ;
char *name; const char *name;
p = files[i]; const char *p = files[i];
#if _WIN32 #if _WIN32
// Convert / to \ so linker will work toWinPath((char *)p);
for (size_t j = 0; p[j]; j++)
{
if (p[j] == '/')
p[j] = '\\';
}
#endif #endif
p = (char *)FileName::name(p); // strip path p = FileName::name(p); // strip path
ext = FileName::ext(p); const char *ext = FileName::ext(p);
char *newname;
if (ext) if (ext)
{ /* Deduce what to do with a file based on its extension { /* Deduce what to do with a file based on its extension
*/ */
@@ -1386,9 +1331,10 @@ Language changes listed by -transition=id:\n\
{ {
ext--; // skip onto '.' ext--; // skip onto '.'
assert(*ext == '.'); assert(*ext == '.');
name = (char *)mem.malloc((ext - p) + 1); newname = (char *)mem.malloc((ext - p) + 1);
memcpy(name, p, ext - p); memcpy(newname, p, ext - p);
name[ext - p] = 0; // strip extension newname[ext - p] = 0; // strip extension
name = newname;
if (name[0] == 0 || if (name[0] == 0 ||
strcmp(name, "..") == 0 || strcmp(name, "..") == 0 ||
@@ -1415,11 +1361,11 @@ Language changes listed by -transition=id:\n\
*/ */
Identifier *id = Lexer::idPool(name); Identifier *id = Lexer::idPool(name);
m = new Module(files[i], id, global.params.doDocComments, global.params.doHdrGeneration); Module *m = new Module(files[i], id, global.params.doDocComments, global.params.doHdrGeneration);
modules.push(m); modules.push(m);
if (firstmodule) if (firstmodule)
{ global.params.objfiles->push((char *)m->objfile->name->str); { global.params.objfiles->push(m->objfile->name->str);
firstmodule = false; firstmodule = false;
} }
} }
@@ -1450,7 +1396,7 @@ Language changes listed by -transition=id:\n\
AsyncRead *aw = AsyncRead::create(modules.dim); AsyncRead *aw = AsyncRead::create(modules.dim);
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
aw->addFile(m->srcfile); aw->addFile(m->srcfile);
} }
aw->start(); aw->start();
@@ -1458,7 +1404,7 @@ Language changes listed by -transition=id:\n\
// Single threaded // Single threaded
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
m->read(Loc()); m->read(Loc());
} }
#endif #endif
@@ -1468,7 +1414,7 @@ Language changes listed by -transition=id:\n\
size_t filecount = modules.dim; size_t filecount = modules.dim;
for (size_t filei = 0, modi = 0; filei < filecount; filei++, modi++) for (size_t filei = 0, modi = 0; filei < filecount; filei++, modi++)
{ {
m = modules[modi]; Module *m = modules[modi];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "parse %s\n", m->toChars()); fprintf(global.stdmsg, "parse %s\n", m->toChars());
if (!Module::rootModule) if (!Module::rootModule)
@@ -1528,7 +1474,7 @@ Language changes listed by -transition=id:\n\
*/ */
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "import %s\n", m->toChars()); fprintf(global.stdmsg, "import %s\n", m->toChars());
m->genhdrfile(); m->genhdrfile();
@@ -1540,7 +1486,7 @@ Language changes listed by -transition=id:\n\
// load all unconditional imports for better symbol resolving // load all unconditional imports for better symbol resolving
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "importall %s\n", m->toChars()); fprintf(global.stdmsg, "importall %s\n", m->toChars());
m->importAll(NULL); m->importAll(NULL);
@@ -1553,7 +1499,7 @@ Language changes listed by -transition=id:\n\
// Do semantic analysis // Do semantic analysis
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "semantic %s\n", m->toChars()); fprintf(global.stdmsg, "semantic %s\n", m->toChars());
m->semantic(); m->semantic();
@@ -1567,7 +1513,7 @@ Language changes listed by -transition=id:\n\
// Do pass 2 semantic analysis // Do pass 2 semantic analysis
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "semantic2 %s\n", m->toChars()); fprintf(global.stdmsg, "semantic2 %s\n", m->toChars());
m->semantic2(); m->semantic2();
@@ -1578,7 +1524,7 @@ Language changes listed by -transition=id:\n\
// Do pass 3 semantic analysis // Do pass 3 semantic analysis
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "semantic3 %s\n", m->toChars()); fprintf(global.stdmsg, "semantic3 %s\n", m->toChars());
m->semantic3(); m->semantic3();
@@ -1599,7 +1545,7 @@ Language changes listed by -transition=id:\n\
// since otherwise functions in them cannot be inlined // since otherwise functions in them cannot be inlined
for (size_t i = 0; i < Module::amodules.dim; i++) for (size_t i = 0; i < Module::amodules.dim; i++)
{ {
m = Module::amodules[i]; Module *m = Module::amodules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "semantic3 %s\n", m->toChars()); fprintf(global.stdmsg, "semantic3 %s\n", m->toChars());
m->semantic3(); m->semantic3();
@@ -1630,7 +1576,7 @@ Language changes listed by -transition=id:\n\
{ {
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "inline scan %s\n", m->toChars()); fprintf(global.stdmsg, "inline scan %s\n", m->toChars());
m->inlineScan(); m->inlineScan();
@@ -1652,7 +1598,7 @@ Language changes listed by -transition=id:\n\
// Add input object and input library files to output library // Add input object and input library files to output library
for (size_t i = 0; i < libmodules.dim; i++) for (size_t i = 0; i < libmodules.dim; i++)
{ {
char *p = libmodules[i]; const char *p = libmodules[i];
library->addObject(p, NULL, 0); library->addObject(p, NULL, 0);
} }
} }
@@ -1711,7 +1657,7 @@ Language changes listed by -transition=id:\n\
obj_start(modules[0]->srcfile->toChars()); obj_start(modules[0]->srcfile->toChars());
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "code %s\n", m->toChars()); fprintf(global.stdmsg, "code %s\n", m->toChars());
m->genobjfile(0); m->genobjfile(0);
@@ -1729,7 +1675,7 @@ Language changes listed by -transition=id:\n\
{ {
for (size_t i = 0; i < modules.dim; i++) for (size_t i = 0; i < modules.dim; i++)
{ {
m = modules[i]; Module *m = modules[i];
if (global.params.verbose) if (global.params.verbose)
fprintf(global.stdmsg, "code %s\n", m->toChars()); fprintf(global.stdmsg, "code %s\n", m->toChars());
if (global.params.obj) if (global.params.obj)
@@ -1794,7 +1740,7 @@ Language changes listed by -transition=id:\n\
return status; return status;
} }
int main(int argc, char *argv[]) int main(int argc, const char *argv[])
{ {
int status = -1; int status = -1;
#if WINDOWS_SEH #if WINDOWS_SEH
@@ -1821,7 +1767,7 @@ int main(int argc, char *argv[])
* The string is separated into arguments, processing \ and ". * The string is separated into arguments, processing \ and ".
*/ */
void getenv_setargv(const char *envvar, size_t *pargc, char** *pargv) void getenv_setargv(const char *envvar, size_t *pargc, const char** *pargv)
{ {
char *p; char *p;
@@ -1965,10 +1911,10 @@ void escapePath(OutBuffer *buf, const char *fname)
* to detect the desired architecture. * to detect the desired architecture.
*/ */
static bool parse_arch(size_t argc, char** argv, bool is64bit) static bool parse_arch(size_t argc, const char** argv, bool is64bit)
{ {
for (size_t i = 0; i < argc; ++i) for (size_t i = 0; i < argc; ++i)
{ char* p = argv[i]; { const char* p = argv[i];
if (p[0] == '-') if (p[0] == '-')
{ {
if (strcmp(p + 1, "m32") == 0) if (strcmp(p + 1, "m32") == 0)
+46 -45
View File
@@ -96,12 +96,12 @@ void unittests();
#define DMDV1 0 #define DMDV1 0
#define DMDV2 1 // Version 2.0 features #define DMDV2 1 // Version 2.0 features
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN #define SNAN_DEFAULT_INIT 1 // if floats are default initialized to signalling NaN
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class #define MODULEINFO_IS_STRUCT 1 // if ModuleInfo is a struct rather than a class
#define PULL93 0 // controversial pull #93 for bugzilla 3449 #define PULL93 0 // controversial pull #93 for bugzilla 3449
// Set if C++ mangling is done by the front end // Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS || IN_LLVM)) #define CPP_MANGLE (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD, TARGET_OPENBSD and /* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD, TARGET_OPENBSD and
* TARGET_SOLARIS, which are * TARGET_SOLARIS, which are
@@ -135,7 +135,7 @@ struct OutBuffer;
// Can't include arraytypes.h here, need to declare these directly. // Can't include arraytypes.h here, need to declare these directly.
template <typename TYPE> struct Array; template <typename TYPE> struct Array;
typedef Array<class Identifier> Identifiers; typedef Array<class Identifier> Identifiers;
typedef Array<char> Strings; typedef Array<const char> Strings;
#if IN_LLVM #if IN_LLVM
enum OUTPUTFLAG enum OUTPUTFLAG
@@ -151,9 +151,9 @@ typedef unsigned char ubyte;
// Put command line switches in here // Put command line switches in here
struct Param struct Param
{ {
#if IN_LLVM
bool obj; // write object file bool obj; // write object file
bool link; // perform link bool link; // perform link
#if IN_LLVM
bool verbose; // verbose compile bool verbose; // verbose compile
bool vtls; // identify thread local variables bool vtls; // identify thread local variables
bool vfield; // identify non-mutable field variables bool vfield; // identify non-mutable field variables
@@ -168,6 +168,8 @@ struct Param
bool isOpenBSD; // generate code for OpenBSD bool isOpenBSD; // generate code for OpenBSD
bool isSolaris; // generate code for Solaris bool isSolaris; // generate code for Solaris
#else #else
char obj; // write object file
char link; // perform link
char dll; // generate shared dynamic library char dll; // generate shared dynamic library
char lib; // write library file instead of object file(s) char lib; // write library file instead of object file(s)
char multiobj; // break one object file into multiple ones char multiobj; // break one object file into multiple ones
@@ -181,7 +183,7 @@ struct Param
bool alwaysframe; // always emit standard stack frame bool alwaysframe; // always emit standard stack frame
bool optimize; // run optimizer bool optimize; // run optimizer
char map; // generate linker .map file char map; // generate linker .map file
char is64bit; // generate 64 bit code bool is64bit; // generate 64 bit code
char isLP64; // generate code for LP64 char isLP64; // generate code for LP64
char isLinux; // generate code for linux char isLinux; // generate code for linux
char isOSX; // generate code for Mac OSX char isOSX; // generate code for Mac OSX
@@ -217,8 +219,6 @@ struct Param
ubyte Dversion; // D version number ubyte Dversion; // D version number
bool ignoreUnsupportedPragmas; // rather than error on them bool ignoreUnsupportedPragmas; // rather than error on them
bool enforcePropertySyntax; bool enforcePropertySyntax;
bool addMain; // LDC_FIXME: Implement.
bool allInst; // LDC_FIXME: Implement.
#else #else
bool pic; // generate position-independent-code for shared libs bool pic; // generate position-independent-code for shared libs
bool cov; // generate code coverage data bool cov; // generate code coverage data
@@ -227,38 +227,51 @@ struct Param
char ignoreUnsupportedPragmas; // rather than error on them char ignoreUnsupportedPragmas; // rather than error on them
char enforcePropertySyntax; char enforcePropertySyntax;
char betterC; // be a "better C" compiler; no dependency on D runtime char betterC; // be a "better C" compiler; no dependency on D runtime
#endif
bool addMain; // add a default main() function bool addMain; // add a default main() function
bool allInst; // generate code for all template instantiations bool allInst; // generate code for all template instantiations
#endif
char *argv0; // program name const char *argv0; // program name
Strings *imppath; // array of char*'s of where to look for import modules Strings *imppath; // array of char*'s of where to look for import modules
Strings *fileImppath; // array of char*'s of where to look for file import modules Strings *fileImppath; // array of char*'s of where to look for file import modules
char *objdir; // .obj/.lib file output directory const char *objdir; // .obj/.lib file output directory
char *objname; // .obj file output name const char *objname; // .obj file output name
const char *libname; // .lib file output name
bool doDocComments; // process embedded documentation comments #if IN_LLVM
char *docdir; // write documentation file to docdir directory bool doDocComments; // process embedded documentation comments
char *docname; // write documentation file to docname #else
Strings *ddocfiles; // macro include files for Ddoc char doDocComments; // process embedded documentation comments
#endif
const char *docdir; // write documentation file to docdir directory
const char *docname; // write documentation file to docname
Strings *ddocfiles; // macro include files for Ddoc
bool doHdrGeneration; // process embedded documentation comments #if IN_LLVM
char *hdrdir; // write 'header' file to docdir directory bool doHdrGeneration; // process embedded documentation comments
char *hdrname; // write 'header' file to docname #else
char doHdrGeneration; // process embedded documentation comments
#endif
const char *hdrdir; // write 'header' file to docdir directory
const char *hdrname; // write 'header' file to docname
bool doXGeneration; // write JSON file #if IN_LLVM
char *xfilename; // write JSON file to xfilename bool doXGeneration; // write JSON file
#else
char doXGeneration; // write JSON file
#endif
const char *xfilename; // write JSON file to xfilename
unsigned debuglevel; // debug level unsigned debuglevel; // debug level
Strings *debugids; // debug identifiers Strings *debugids; // debug identifiers
unsigned versionlevel; // version level unsigned versionlevel; // version level
Strings *versionids; // version identifiers Strings *versionids; // version identifiers
Strings *defaultlibnames; // default libraries for non-debug builds Strings *defaultlibnames; // default libraries for non-debug builds
Strings *debuglibnames; // default libraries for debug builds Strings *debuglibnames; // default libraries for debug builds
char *moduleDepsFile; // filename for deps output const char *moduleDepsFile; // filename for deps output
OutBuffer *moduleDeps; // contents to be written to deps file OutBuffer *moduleDeps; // contents to be written to deps file
#if IN_DMD #if IN_DMD
@@ -276,17 +289,17 @@ struct Param
bool run; // run resulting executable bool run; // run resulting executable
#if !IN_LLVM #if !IN_LLVM
size_t runargs_length; size_t runargs_length;
char** runargs; // arguments for executable const char** runargs; // arguments for executable
#endif #endif
// Linker stuff // Linker stuff
Strings *objfiles; Strings *objfiles;
Strings *linkswitches; Strings *linkswitches;
Strings *libfiles; Strings *libfiles;
char *deffile; const char *deffile;
char *resfile; const char *resfile;
char *exefile; const char *exefile;
char *mapfile; const char *mapfile;
#if IN_LLVM #if IN_LLVM
// Whether to keep all function bodies in .di file generation or to strip // Whether to keep all function bodies in .di file generation or to strip
// those of plain functions. For DMD, this is govenered by the -inline // those of plain functions. For DMD, this is govenered by the -inline
@@ -399,12 +412,7 @@ extern Global global;
#include "longdouble.h" #include "longdouble.h"
#ifdef __DMC__ #include "complex_t.h"
#include <complex.h>
typedef _Complex long double complex_t;
#else
#include "complex_t.h"
#endif
// Be careful not to care about sign when using dinteger_t // Be careful not to care about sign when using dinteger_t
//typedef uint64_t integer_t; //typedef uint64_t integer_t;
@@ -455,13 +463,6 @@ struct Loc
bool equals(const Loc& loc); bool equals(const Loc& loc);
}; };
#ifndef GCC_SAFE_DMD
#undef TRUE
#define TRUE 1
#undef FALSE
#define FALSE 0
#endif
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry #define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
// in interface vtbl[]'s // in interface vtbl[]'s
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears #define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
@@ -497,9 +498,7 @@ enum MATCH
{ {
MATCHnomatch, // no match MATCHnomatch, // no match
MATCHconvert, // match with conversions MATCHconvert, // match with conversions
#if DMDV2
MATCHconst, // match with conversion to const MATCHconst, // match with conversion to const
#endif
MATCHexact // exact match MATCHexact // exact match
}; };
@@ -520,6 +519,8 @@ void vdeprecation(Loc loc, const char *format, va_list ap, const char *p1 = NULL
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
__attribute__((noreturn)) __attribute__((noreturn))
#elif _MSC_VER
__declspec(noreturn)
#endif #endif
void fatal(); void fatal();
@@ -538,7 +539,7 @@ void halt();
#if !IN_LLVM #if !IN_LLVM
class Dsymbol; class Dsymbol;
class Library; class Library;
class File; struct File;
void obj_start(char *srcfile); void obj_start(char *srcfile);
void obj_end(Library *library, File *objfile); void obj_end(Library *library, File *objfile);
void obj_append(Dsymbol *s); void obj_append(Dsymbol *s);
+56 -33
View File
@@ -44,7 +44,7 @@ void Module::init()
modules = new DsymbolTable(); modules = new DsymbolTable();
} }
Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen) Module::Module(const char *filename, Identifier *ident, int doDocComment, int doHdrGen)
: Package(ident) : Package(ident)
{ {
const char *srcfilename; const char *srcfilename;
@@ -90,7 +90,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
macrotable = NULL; macrotable = NULL;
escapetable = NULL; escapetable = NULL;
safe = FALSE; safe = false;
#if IN_DMD #if IN_DMD
doppelganger = 0; doppelganger = 0;
cov = NULL; cov = NULL;
@@ -101,7 +101,30 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
namelen = 0; namelen = 0;
srcfilename = FileName::defaultExt(filename, global.mars_ext); srcfilename = FileName::defaultExt(filename, global.mars_ext);
if (!FileName::equalsExt(srcfilename, global.mars_ext) &&
#if IN_LLVM
bool allow_no_extension = global.params.isLinux || global.params.isOSX ||
global.params.isFreeBSD || global.params.isOpenBSD ||
global.params.isSolaris;
#else
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
/* Allow 'script' D source files to have no extension.
*/
bool allow_no_extension = true;
#else
bool allow_no_extension = false;
#endif
#endif
if (allow_no_extension &&
global.params.run &&
!FileName::ext(filename) &&
FileName::exists(srcfilename) == 0 &&
FileName::exists(filename) == 1)
{
FileName::free(srcfilename);
srcfilename = FileName::removeExt(filename); // just does a mem.strdup(filename)
}
else if (!FileName::equalsExt(srcfilename, global.mars_ext) &&
!FileName::equalsExt(srcfilename, global.hdr_ext) && !FileName::equalsExt(srcfilename, global.hdr_ext) &&
!FileName::equalsExt(srcfilename, "dd")) !FileName::equalsExt(srcfilename, "dd"))
{ {
@@ -303,7 +326,7 @@ bool Module::read(Loc loc)
{ {
for (size_t i = 0; i < global.path->dim; i++) for (size_t i = 0; i < global.path->dim; i++)
{ {
char *p = (*global.path)[i]; const char *p = (*global.path)[i];
fprintf(stderr, "import path[%llu] = %s\n", (ulonglong)i, p); fprintf(stderr, "import path[%llu] = %s\n", (ulonglong)i, p);
} }
} }
@@ -399,7 +422,7 @@ void Module::parse()
char *srcname = srcfile->name->toChars(); char *srcname = srcfile->name->toChars();
//printf("Module::parse(srcname = '%s')\n", srcname); //printf("Module::parse(srcname = '%s')\n", srcname);
utf8_t *buf = srcfile->buffer; utf8_t *buf = (utf8_t *)srcfile->buffer;
size_t buflen = srcfile->len; size_t buflen = srcfile->len;
if (buflen >= 2) if (buflen >= 2)
@@ -578,28 +601,30 @@ void Module::parse()
#endif #endif
return; return;
} }
{
#if IN_LLVM #if IN_LLVM
Parser p(this, buf, buflen, gen_docs); Parser p(this, buf, buflen, gen_docs);
#else #else
Parser p(this, buf, buflen, docfile != NULL); Parser p(this, buf, buflen, docfile != NULL);
#endif #endif
p.nextToken(); p.nextToken();
members = p.parseModule(); members = p.parseModule();
md = p.md;
numlines = p.scanloc.linnum;
}
if (srcfile->ref == 0) if (srcfile->ref == 0)
::free(srcfile->buffer); ::free(srcfile->buffer);
srcfile->buffer = NULL; srcfile->buffer = NULL;
srcfile->len = 0; srcfile->len = 0;
md = p.md;
numlines = p.scanloc.linnum;
/* The symbol table into which the module is to be inserted. /* The symbol table into which the module is to be inserted.
*/ */
DsymbolTable *dst; DsymbolTable *dst;
if (md) if (md)
{ /* A ModuleDeclaration, md, was provided. {
/* A ModuleDeclaration, md, was provided.
* The ModuleDeclaration sets the packages this module appears in, and * The ModuleDeclaration sets the packages this module appears in, and
* the name of this module. * the name of this module.
*/ */
@@ -608,17 +633,17 @@ void Module::parse()
Package *ppack = NULL; Package *ppack = NULL;
dst = Package::resolve(md->packages, &this->parent, &ppack); dst = Package::resolve(md->packages, &this->parent, &ppack);
assert(dst); assert(dst);
#if 0
if (ppack && ppack->isModule()) Module *m = ppack ? ppack->isModule() : NULL;
if (m && strcmp(m->srcfile->name->name(), "package.d") != 0)
{ {
error(loc, "package name '%s' in file %s conflicts with usage as a module name in file %s", ::error(md->loc, "package name '%s' conflicts with usage as a module name in file %s",
ppack->toChars(), srcname, ppack->isModule()->srcfile->toChars()); ppack->toPrettyChars(), m->srcfile->toChars());
dst = modules;
} }
#endif
} }
else else
{ /* The name of the module is set to the source file name. {
/* The name of the module is set to the source file name.
* There are no packages. * There are no packages.
*/ */
dst = modules; // and so this module goes into global module symbol table dst = modules; // and so this module goes into global module symbol table
@@ -665,8 +690,7 @@ void Module::parse()
*/ */
Dsymbol *prev = dst->lookup(ident); Dsymbol *prev = dst->lookup(ident);
assert(prev); assert(prev);
Module *mprev = prev->isModule(); if (Module *mprev = prev->isModule())
if (mprev)
{ {
if (strcmp(srcname, mprev->srcfile->toChars()) == 0) if (strcmp(srcname, mprev->srcfile->toChars()) == 0)
error(loc, "from file %s must be imported as module '%s'", error(loc, "from file %s must be imported as module '%s'",
@@ -675,10 +699,8 @@ void Module::parse()
error(loc, "from file %s conflicts with another module %s from file %s", error(loc, "from file %s conflicts with another module %s from file %s",
srcname, mprev->toChars(), mprev->srcfile->toChars()); srcname, mprev->toChars(), mprev->srcfile->toChars());
} }
else else if (Package *pkg = prev->isPackage())
{ {
Package *pkg = prev->isPackage();
assert(pkg);
if (pkg->isPkgMod == PKGunknown && isPackageMod) if (pkg->isPkgMod == PKGunknown && isPackageMod)
{ {
/* If the previous inserted Package is not yet determined as package.d, /* If the previous inserted Package is not yet determined as package.d,
@@ -691,6 +713,8 @@ void Module::parse()
error(pkg->loc, "from file %s conflicts with package name %s", error(pkg->loc, "from file %s conflicts with package name %s",
srcname, pkg->toChars()); srcname, pkg->toChars());
} }
else
assert(global.errors);
} }
else else
{ {
@@ -1071,7 +1095,7 @@ void Module::runDeferredSemantic3()
/************************************ /************************************
* Recursively look at every module this module imports, * Recursively look at every module this module imports,
* return TRUE if it imports m. * return true if it imports m.
* Can be used to detect circular imports. * Can be used to detect circular imports.
*/ */
@@ -1087,7 +1111,7 @@ int Module::imports(Module *m)
for (size_t i = 0; i < aimports.dim; i++) for (size_t i = 0; i < aimports.dim; i++)
{ Module *mi = aimports[i]; { Module *mi = aimports[i];
if (mi == m) if (mi == m)
return TRUE; return true;
if (!mi->insearch) if (!mi->insearch)
{ {
mi->insearch = 1; mi->insearch = 1;
@@ -1096,7 +1120,7 @@ int Module::imports(Module *m)
return r; return r;
} }
} }
return FALSE; return false;
} }
/************************************* /*************************************
@@ -1191,8 +1215,8 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
if (packages) if (packages)
{ {
for (size_t i = 0; i < packages->dim; i++) for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = (*packages)[i]; {
Identifier *pid = (*packages)[i];
Package *pkg; Package *pkg;
Dsymbol *p = dst->lookup(pid); Dsymbol *p = dst->lookup(pid);
if (!p) if (!p)
@@ -1219,14 +1243,13 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
dst = pkg->symtab; dst = pkg->symtab;
if (ppkg && !*ppkg) if (ppkg && !*ppkg)
*ppkg = pkg; *ppkg = pkg;
#if 0
if (pkg->isModule()) if (pkg->isModule())
{ // Return the module so that a nice error message can be generated {
// Return the module so that a nice error message can be generated
if (ppkg) if (ppkg)
*ppkg = (Package *)p; *ppkg = (Package *)p;
break; break;
} }
#endif
} }
} }
if (pparent) if (pparent)
+6 -5
View File
@@ -81,6 +81,7 @@ public:
static AggregateDeclaration *moduleinfo; static AggregateDeclaration *moduleinfo;
const char *arg; // original argument name const char *arg; // original argument name
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
File *srcfile; // input source file File *srcfile; // input source file
@@ -88,7 +89,6 @@ public:
File *hdrfile; // 'header' file File *hdrfile; // 'header' file
File *symfile; // output symbol file File *symfile; // output symbol file
File *docfile; // output documentation file File *docfile; // output documentation file
unsigned errors; // if any errors in file unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file unsigned numlines; // number of lines in source file
int isDocFile; // if it is a documentation input file, not D source int isDocFile; // if it is a documentation input file, not D source
@@ -122,10 +122,10 @@ public:
size_t nameoffset; // offset of module name from start of ModuleInfo size_t nameoffset; // offset of module name from start of ModuleInfo
size_t namelen; // length of module name in characters size_t namelen; // length of module name in characters
int doDocComment; // enable generating doc comments for this module bool doDocComment; // enable generating doc comments for this module
int doHdrGen; // enable generating header file for this module bool doHdrGen; // enable generating header file for this module
Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen); Module(const char *arg, Identifier *ident, int doDocComment, int doHdrGen);
~Module(); ~Module();
static Module *load(Loc loc, Identifiers *packages, Identifier *ident); static Module *load(Loc loc, Identifiers *packages, Identifier *ident);
@@ -199,12 +199,13 @@ public:
#endif #endif
void genmoduleinfo(); void genmoduleinfo();
Module *isModule() { return this; }
#if IN_LLVM #if IN_LLVM
// LDC // LDC
llvm::Module* genLLVMModule(llvm::LLVMContext& context); llvm::Module* genLLVMModule(llvm::LLVMContext& context);
void buildTargetFiles(bool singleObj); void buildTargetFiles(bool singleObj);
File* buildFilePath(const char* forcename, const char* path, const char* ext); File* buildFilePath(const char* forcename, const char* path, const char* ext);
Module *isModule() { return this; }
llvm::GlobalVariable* moduleInfoSymbol(); llvm::GlobalVariable* moduleInfoSymbol();
bool llvmForceLogging; bool llvmForceLogging;
+303 -238
View File
File diff suppressed because it is too large Load Diff
+35 -40
View File
@@ -116,8 +116,6 @@ enum ENUMTY
}; };
typedef unsigned char TY; // ENUMTY typedef unsigned char TY; // ENUMTY
#define Tascii Tchar
extern int Tsize_t; extern int Tsize_t;
extern int Tptrdiff_t; extern int Tptrdiff_t;
@@ -267,13 +265,13 @@ public:
#if CPP_MANGLE #if CPP_MANGLE
virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif #endif
virtual int isintegral(); virtual bool isintegral();
virtual int isfloating(); // real, imaginary, or complex virtual bool isfloating(); // real, imaginary, or complex
virtual int isreal(); virtual bool isreal();
virtual int isimaginary(); virtual bool isimaginary();
virtual int iscomplex(); virtual bool iscomplex();
virtual int isscalar(); virtual bool isscalar();
virtual int isunsigned(); virtual bool isunsigned();
virtual int isscope(); virtual int isscope();
virtual int isString(); virtual int isString();
virtual int isAssignable(); virtual int isAssignable();
@@ -432,13 +430,13 @@ public:
#if CPP_MANGLE #if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms); void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif #endif
int isintegral(); bool isintegral();
int isfloating(); bool isfloating();
int isreal(); bool isreal();
int isimaginary(); bool isimaginary();
int iscomplex(); bool iscomplex();
int isscalar(); bool isscalar();
int isunsigned(); bool isunsigned();
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(Loc loc); int isZeroInit(Loc loc);
@@ -471,10 +469,10 @@ public:
#if CPP_MANGLE #if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms); void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif #endif
int isintegral(); bool isintegral();
int isfloating(); bool isfloating();
int isscalar(); bool isscalar();
int isunsigned(); bool isunsigned();
int checkBoolean(); int checkBoolean();
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
@@ -633,7 +631,7 @@ public:
void toJson(JsonOut *json); void toJson(JsonOut *json);
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
MATCH constConv(Type *to); MATCH constConv(Type *to);
int isscalar(); bool isscalar();
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(Loc loc); int isZeroInit(Loc loc);
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
@@ -953,13 +951,13 @@ public:
void toJson(JsonOut *json); void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
Expression *getProperty(Loc loc, Identifier *ident, int flag); Expression *getProperty(Loc loc, Identifier *ident, int flag);
int isintegral(); bool isintegral();
int isfloating(); bool isfloating();
int isreal(); bool isreal();
int isimaginary(); bool isimaginary();
int iscomplex(); bool iscomplex();
int isscalar(); bool isscalar();
int isunsigned(); bool isunsigned();
int checkBoolean(); int checkBoolean();
int isString(); int isString();
int isAssignable(); int isAssignable();
@@ -1003,13 +1001,13 @@ public:
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
structalign_t alignment(); structalign_t alignment();
Expression *getProperty(Loc loc, Identifier *ident, int flag); Expression *getProperty(Loc loc, Identifier *ident, int flag);
int isintegral(); bool isintegral();
int isfloating(); bool isfloating();
int isreal(); bool isreal();
int isimaginary(); bool isimaginary();
int iscomplex(); bool iscomplex();
int isscalar(); bool isscalar();
int isunsigned(); bool isunsigned();
int checkBoolean(); int checkBoolean();
int isAssignable(); int isAssignable();
int needsDestruction(); int needsDestruction();
@@ -1131,7 +1129,7 @@ public:
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
int checkBoolean(); int checkBoolean();
void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json); void toJson(JsonOut *json);
d_uns64 size(Loc loc); d_uns64 size(Loc loc);
@@ -1171,16 +1169,13 @@ public:
static int foreach(Parameters *args, ForeachDg dg, void *ctx, size_t *pn=NULL); static int foreach(Parameters *args, ForeachDg dg, void *ctx, size_t *pn=NULL);
}; };
extern int Tsize_t;
extern int Tptrdiff_t;
int arrayTypeCompatible(Loc loc, Type *t1, Type *t2); int arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
int arrayTypeCompatibleWithoutCasting(Loc loc, Type *t1, Type *t2); int arrayTypeCompatibleWithoutCasting(Loc loc, Type *t1, Type *t2);
void MODtoBuffer(OutBuffer *buf, unsigned char mod); void MODtoBuffer(OutBuffer *buf, unsigned char mod);
char *MODtoChars(unsigned char mod); char *MODtoChars(unsigned char mod);
int MODimplicitConv(unsigned char modfrom, unsigned char modto); int MODimplicitConv(unsigned char modfrom, unsigned char modto);
int MODmethodConv(unsigned char modfrom, unsigned char modto); int MODmethodConv(unsigned char modfrom, unsigned char modto);
int MODmerge(unsigned char mod1, unsigned char mod2); unsigned char MODmerge(unsigned char mod1, unsigned char mod2);
void identifierToDocBuffer(Identifier* ident, OutBuffer *buf, HdrGenState *hgs); void identifierToDocBuffer(Identifier* ident, OutBuffer *buf, HdrGenState *hgs);
#endif /* DMD_MTYPE_H */ #endif /* DMD_MTYPE_H */
+9 -40
View File
@@ -13,11 +13,6 @@
#include <ctype.h> #include <ctype.h>
#include <assert.h> #include <assert.h>
#include <string.h> // memset() #include <string.h> // memset()
#if _MSC_VER || IN_LLVM // complex.h breaks LLVM headers.
#include <complex>
#else
#include <complex.h>
#endif
#ifdef __APPLE__ #ifdef __APPLE__
#define integer_t dmd_integer_t #define integer_t dmd_integer_t
@@ -50,7 +45,7 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *arguments, int flag
int Expression::isCommutative() int Expression::isCommutative()
{ {
return FALSE; // default is no reverse return false; // default is no reverse
} }
/*********************************** /***********************************
@@ -90,14 +85,14 @@ Identifier *PostExp::opId() { return (op == TOKplusplus)
? Id::postinc ? Id::postinc
: Id::postdec; } : Id::postdec; }
int AddExp::isCommutative() { return TRUE; } int AddExp::isCommutative() { return true; }
Identifier *AddExp::opId() { return Id::add; } Identifier *AddExp::opId() { return Id::add; }
Identifier *AddExp::opId_r() { return Id::add_r; } Identifier *AddExp::opId_r() { return Id::add_r; }
Identifier *MinExp::opId() { return Id::sub; } Identifier *MinExp::opId() { return Id::sub; }
Identifier *MinExp::opId_r() { return Id::sub_r; } Identifier *MinExp::opId_r() { return Id::sub_r; }
int MulExp::isCommutative() { return TRUE; } int MulExp::isCommutative() { return true; }
Identifier *MulExp::opId() { return Id::mul; } Identifier *MulExp::opId() { return Id::mul; }
Identifier *MulExp::opId_r() { return Id::mul_r; } Identifier *MulExp::opId_r() { return Id::mul_r; }
@@ -107,10 +102,8 @@ Identifier *DivExp::opId_r() { return Id::div_r; }
Identifier *ModExp::opId() { return Id::mod; } Identifier *ModExp::opId() { return Id::mod; }
Identifier *ModExp::opId_r() { return Id::mod_r; } Identifier *ModExp::opId_r() { return Id::mod_r; }
#if DMDV2
Identifier *PowExp::opId() { return Id::pow; } Identifier *PowExp::opId() { return Id::pow; }
Identifier *PowExp::opId_r() { return Id::pow_r; } Identifier *PowExp::opId_r() { return Id::pow_r; }
#endif
Identifier *ShlExp::opId() { return Id::shl; } Identifier *ShlExp::opId() { return Id::shl; }
Identifier *ShlExp::opId_r() { return Id::shl_r; } Identifier *ShlExp::opId_r() { return Id::shl_r; }
@@ -121,15 +114,15 @@ Identifier *ShrExp::opId_r() { return Id::shr_r; }
Identifier *UshrExp::opId() { return Id::ushr; } Identifier *UshrExp::opId() { return Id::ushr; }
Identifier *UshrExp::opId_r() { return Id::ushr_r; } Identifier *UshrExp::opId_r() { return Id::ushr_r; }
int AndExp::isCommutative() { return TRUE; } int AndExp::isCommutative() { return true; }
Identifier *AndExp::opId() { return Id::iand; } Identifier *AndExp::opId() { return Id::iand; }
Identifier *AndExp::opId_r() { return Id::iand_r; } Identifier *AndExp::opId_r() { return Id::iand_r; }
int OrExp::isCommutative() { return TRUE; } int OrExp::isCommutative() { return true; }
Identifier *OrExp::opId() { return Id::ior; } Identifier *OrExp::opId() { return Id::ior; }
Identifier *OrExp::opId_r() { return Id::ior_r; } Identifier *OrExp::opId_r() { return Id::ior_r; }
int XorExp::isCommutative() { return TRUE; } int XorExp::isCommutative() { return true; }
Identifier *XorExp::opId() { return Id::ixor; } Identifier *XorExp::opId() { return Id::ixor; }
Identifier *XorExp::opId_r() { return Id::ixor_r; } Identifier *XorExp::opId_r() { return Id::ixor_r; }
@@ -151,10 +144,10 @@ Identifier *UshrAssignExp::opId() { return Id::ushrass; }
Identifier * CatAssignExp::opId() { return Id::catass; } Identifier * CatAssignExp::opId() { return Id::catass; }
Identifier * PowAssignExp::opId() { return Id::powass; } Identifier * PowAssignExp::opId() { return Id::powass; }
int EqualExp::isCommutative() { return TRUE; } int EqualExp::isCommutative() { return true; }
Identifier *EqualExp::opId() { return Id::eq; } Identifier *EqualExp::opId() { return Id::eq; }
int CmpExp::isCommutative() { return TRUE; } int CmpExp::isCommutative() { return true; }
Identifier *CmpExp::opId() { return Id::cmp; } Identifier *CmpExp::opId() { return Id::cmp; }
Identifier *ArrayExp::opId() { return Id::index; } Identifier *ArrayExp::opId() { return Id::index; }
@@ -219,7 +212,6 @@ Expression *UnaExp::op_overload(Scope *sc)
{ {
//printf("UnaExp::op_overload() (%s)\n", toChars()); //printf("UnaExp::op_overload() (%s)\n", toChars());
#if DMDV2
if (e1->op == TOKarray) if (e1->op == TOKarray)
{ {
ArrayExp *ae = (ArrayExp *)e1; ArrayExp *ae = (ArrayExp *)e1;
@@ -311,7 +303,6 @@ Expression *UnaExp::op_overload(Scope *sc)
att1 = NULL; att1 = NULL;
} }
} }
#endif
e1 = e1->semantic(sc); e1 = e1->semantic(sc);
e1 = resolveProperties(sc, e1); e1 = resolveProperties(sc, e1);
@@ -345,7 +336,6 @@ Expression *UnaExp::op_overload(Scope *sc)
} }
#endif #endif
#if DMDV2
/* Rewrite as: /* Rewrite as:
* e1.opUnary!("+")(); * e1.opUnary!("+")();
*/ */
@@ -373,7 +363,6 @@ Expression *UnaExp::op_overload(Scope *sc)
ue->e1 = e1; ue->e1 = e1;
return ue->trySemantic(sc); return ue->trySemantic(sc);
} }
#endif
} }
return NULL; return NULL;
} }
@@ -501,7 +490,6 @@ Expression *BinExp::op_overload(Scope *sc)
#endif #endif
Objects *tiargs = NULL; Objects *tiargs = NULL;
#if DMDV2
if (op == TOKplusplus || op == TOKminusminus) if (op == TOKplusplus || op == TOKminusminus)
{ // Bug4099 fix { // Bug4099 fix
if (ad1 && search_function(ad1, Id::opUnary)) if (ad1 && search_function(ad1, Id::opUnary))
@@ -537,7 +525,6 @@ Expression *BinExp::op_overload(Scope *sc)
tiargs = opToArg(sc, op); tiargs = opToArg(sc, op);
} }
} }
#endif
if (s || s_r) if (s || s_r)
{ {
@@ -692,7 +679,6 @@ L1:
} }
#endif #endif
#if DMDV2
// Try alias this on first operand // Try alias this on first operand
if (ad1 && ad1->aliasthis && if (ad1 && ad1->aliasthis &&
!(op == TOKassign && ad2 && ad1 == ad2)) // See Bugzilla 2943 !(op == TOKassign && ad2 && ad1 == ad2)) // See Bugzilla 2943
@@ -731,7 +717,6 @@ L1:
be->e2 = e2; be->e2 = e2;
return be->trySemantic(sc); return be->trySemantic(sc);
} }
#endif
return NULL; return NULL;
} }
@@ -948,7 +933,6 @@ Expression *BinAssignExp::op_overload(Scope *sc)
{ {
//printf("BinAssignExp::op_overload() (%s)\n", toChars()); //printf("BinAssignExp::op_overload() (%s)\n", toChars());
#if DMDV2
if (e1->op == TOKarray) if (e1->op == TOKarray)
{ {
ArrayExp *ae = (ArrayExp *)e1; ArrayExp *ae = (ArrayExp *)e1;
@@ -1045,7 +1029,6 @@ Expression *BinAssignExp::op_overload(Scope *sc)
att1 = NULL; att1 = NULL;
} }
} }
#endif
BinExp::semantic(sc); BinExp::semantic(sc);
e1 = resolveProperties(sc, e1); e1 = resolveProperties(sc, e1);
@@ -1071,7 +1054,6 @@ Expression *BinAssignExp::op_overload(Scope *sc)
#endif #endif
Objects *tiargs = NULL; Objects *tiargs = NULL;
#if DMDV2
if (!s) if (!s)
{ /* Try the new D2 scheme, opOpAssign { /* Try the new D2 scheme, opOpAssign
*/ */
@@ -1091,7 +1073,6 @@ Expression *BinAssignExp::op_overload(Scope *sc)
tiargs = opToArg(sc, op); tiargs = opToArg(sc, op);
} }
} }
#endif
if (s) if (s)
{ {
@@ -1131,7 +1112,6 @@ Expression *BinAssignExp::op_overload(Scope *sc)
L1: L1:
#if DMDV2
// Try alias this on first operand // Try alias this on first operand
if (ad1 && ad1->aliasthis) if (ad1 && ad1->aliasthis)
{ {
@@ -1166,7 +1146,6 @@ L1:
be->e2 = e2; be->e2 = e2;
return be->trySemantic(sc); return be->trySemantic(sc);
} }
#endif
return NULL; return NULL;
} }
@@ -1226,10 +1205,8 @@ Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid)
int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply) int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
{ {
Identifier *idapply = (op == TOKforeach) ? Id::apply : Id::applyReverse; Identifier *idapply = (op == TOKforeach) ? Id::apply : Id::applyReverse;
#if DMDV2
Identifier *idfront = (op == TOKforeach) ? Id::Ffront : Id::Fback; Identifier *idfront = (op == TOKforeach) ? Id::Ffront : Id::Fback;
int sliced = 0; int sliced = 0;
#endif
Type *tab; Type *tab;
Type *att = NULL; Type *att = NULL;
Expression *org_aggr = aggr; Expression *org_aggr = aggr;
@@ -1265,7 +1242,6 @@ int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
goto Laggr; goto Laggr;
Laggr: Laggr:
#if DMDV2
if (!sliced) if (!sliced)
{ {
sapply = search_function(ad, idapply); sapply = search_function(ad, idapply);
@@ -1298,13 +1274,6 @@ int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
aggr = new DotIdExp(aggr->loc, aggr, ad->aliasthis->ident); aggr = new DotIdExp(aggr->loc, aggr, ad->aliasthis->ident);
continue; continue;
} }
#else
sapply = search_function(ad, idapply);
if (sapply)
{ // opApply aggregate
break;
}
#endif
goto Lerr; goto Lerr;
case Tdelegate: case Tdelegate:
@@ -1488,7 +1457,7 @@ static Dsymbol *inferApplyArgTypesX(Expression *ethis, FuncDeclaration *fstart,
struct ParamOpOver struct ParamOpOver
{ {
Parameters *arguments; Parameters *arguments;
int mod; unsigned char mod;
MATCH match; MATCH match;
FuncDeclaration *fd_best; FuncDeclaration *fd_best;
FuncDeclaration *fd_ambig; FuncDeclaration *fd_ambig;
+16 -21
View File
@@ -13,10 +13,6 @@
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
#if __DMC__
#include <complex.h>
#endif
#include "lexer.h" #include "lexer.h"
#include "mtype.h" #include "mtype.h"
#include "expression.h" #include "expression.h"
@@ -421,7 +417,7 @@ Expression *PtrExp::optimize(int result, bool keepLvalue)
Expression *e = expandVar(result, v); Expression *e = expandVar(result, v);
if (e && e->op == TOKstructliteral) if (e && e->op == TOKstructliteral)
{ StructLiteralExp *sle = (StructLiteralExp *)e; { StructLiteralExp *sle = (StructLiteralExp *)e;
e = sle->getField(type, se->offset); e = sle->getField(type, (unsigned)se->offset);
if (e && e != EXP_CANT_INTERPRET) if (e && e != EXP_CANT_INTERPRET)
return e; return e;
} }
@@ -449,7 +445,7 @@ Expression *DotVarExp::optimize(int result, bool keepLvalue)
VarDeclaration *vf = var->isVarDeclaration(); VarDeclaration *vf = var->isVarDeclaration();
if (vf) if (vf)
{ {
Expression *e = sle->getField(type, vf->offset); e = sle->getField(type, vf->offset);
if (e && e != EXP_CANT_INTERPRET) if (e && e != EXP_CANT_INTERPRET)
return e; return e;
} }
@@ -489,7 +485,6 @@ Expression *NewExp::optimize(int result, bool keepLvalue)
Expression *CallExp::optimize(int result, bool keepLvalue) Expression *CallExp::optimize(int result, bool keepLvalue)
{ {
//printf("CallExp::optimize(result = %d) %s\n", result, toChars()); //printf("CallExp::optimize(result = %d) %s\n", result, toChars());
Expression *e = this;
// Optimize parameters with keeping lvalue-ness // Optimize parameters with keeping lvalue-ness
if (arguments) if (arguments)
@@ -502,9 +497,9 @@ Expression *CallExp::optimize(int result, bool keepLvalue)
for (size_t i = 0; i < arguments->dim; i++) for (size_t i = 0; i < arguments->dim; i++)
{ {
Parameter *p = Parameter::getNth(tf->parameters, i); Parameter *p = Parameter::getNth(tf->parameters, i);
bool keepLvalue = (p ? (p->storageClass & (STCref | STCout)) != 0 : false); bool keep = (p ? (p->storageClass & (STCref | STCout)) != 0 : false);
Expression *e = (*arguments)[i]; Expression *e = (*arguments)[i];
e = e->optimize(WANTvalue, keepLvalue); e = e->optimize(WANTvalue, keep);
(*arguments)[i] = e; (*arguments)[i] = e;
} }
} }
@@ -513,6 +508,7 @@ Expression *CallExp::optimize(int result, bool keepLvalue)
if (keepLvalue) if (keepLvalue)
return this; return this;
Expression *e = this;
#if 1 #if 1
#else #else
if (e1->op == TOKvar) if (e1->op == TOKvar)
@@ -573,7 +569,10 @@ Expression *CastExp::optimize(int result, bool keepLvalue)
e1->type->implicitConvTo(type) >= MATCHconst) e1->type->implicitConvTo(type) >= MATCHconst)
{ {
if (X) printf(" returning2 %s\n", e1->toChars()); if (X) printf(" returning2 %s\n", e1->toChars());
goto L1; L1: // Returning e1 with changing its type
Expression *e = (e1old == e1 ? e1->copy() : e1);
e->type = type;
return e;
} }
/* The first test here is to prevent infinite loops /* The first test here is to prevent infinite loops
@@ -632,10 +631,6 @@ Expression *CastExp::optimize(int result, bool keepLvalue)
e = this; e = this;
if (X) printf(" returning6 %s\n", e->toChars()); if (X) printf(" returning6 %s\n", e->toChars());
return e; return e;
L1: // Returning e1 with changing its type
e = (e1old == e1 ? e1->copy() : e1);
e->type = type;
return e;
#undef X #undef X
} }
@@ -1034,7 +1029,7 @@ void setLengthVarIfKnown(VarDeclaration *lengthVar, Expression *arr)
{ {
Type *t = arr->type->toBasetype(); Type *t = arr->type->toBasetype();
if (t->ty == Tsarray) if (t->ty == Tsarray)
len = ((TypeSArray *)t)->dim->toInteger(); len = (size_t)((TypeSArray *)t)->dim->toInteger();
else else
return; // we don't know the length yet return; // we don't know the length yet
} }
@@ -1100,7 +1095,7 @@ Expression *AndAndExp::optimize(int result, bool keepLvalue)
if (e1->op == TOKerror) if (e1->op == TOKerror)
return e1; return e1;
e = this; e = this;
if (e1->isBool(FALSE)) if (e1->isBool(false))
{ {
if (type->toBasetype()->ty == Tvoid) if (type->toBasetype()->ty == Tvoid)
e = e2; e = e2;
@@ -1126,7 +1121,7 @@ Expression *AndAndExp::optimize(int result, bool keepLvalue)
e = new IntegerExp(loc, n1 && n2, type); e = new IntegerExp(loc, n1 && n2, type);
} }
else if (e1->isBool(TRUE)) else if (e1->isBool(true))
{ {
if (type->toBasetype()->ty == Tvoid) if (type->toBasetype()->ty == Tvoid)
e = e2; e = e2;
@@ -1144,7 +1139,7 @@ Expression *OrOrExp::optimize(int result, bool keepLvalue)
if (e1->op == TOKerror) if (e1->op == TOKerror)
return e1; return e1;
e = this; e = this;
if (e1->isBool(TRUE)) if (e1->isBool(true))
{ // Replace with (e1, 1) { // Replace with (e1, 1)
e = new CommaExp(loc, e1, new IntegerExp(loc, 1, type)); e = new CommaExp(loc, e1, new IntegerExp(loc, 1, type));
e->type = type; e->type = type;
@@ -1166,7 +1161,7 @@ Expression *OrOrExp::optimize(int result, bool keepLvalue)
e = new IntegerExp(loc, n1 || n2, type); e = new IntegerExp(loc, n1 || n2, type);
} }
else if (e1->isBool(FALSE)) else if (e1->isBool(false))
{ {
if (type->toBasetype()->ty == Tvoid) if (type->toBasetype()->ty == Tvoid)
e = e2; e = e2;
@@ -1211,9 +1206,9 @@ Expression *CondExp::optimize(int result, bool keepLvalue)
{ Expression *e; { Expression *e;
econd = econd->optimize(WANTflags); econd = econd->optimize(WANTflags);
if (econd->isBool(TRUE)) if (econd->isBool(true))
e = e1->optimize(result, keepLvalue); e = e1->optimize(result, keepLvalue);
else if (econd->isBool(FALSE)) else if (econd->isBool(false))
e = e2->optimize(result, keepLvalue); e = e2->optimize(result, keepLvalue);
else else
{ e1 = e1->optimize(result, keepLvalue); { e1 = e1->optimize(result, keepLvalue);
+157 -277
View File
File diff suppressed because it is too large Load Diff
+7 -10
View File
@@ -69,18 +69,19 @@ public:
int inBrackets; // inside [] of array index or slice int inBrackets; // inside [] of array index or slice
Loc lookingForElse; // location of lonely if looking for an else Loc lookingForElse; // location of lonely if looking for an else
Parser(Module *module, utf8_t *base, size_t length, int doDocComment); Parser(Loc loc, Module *module, const utf8_t *base, size_t length, int doDocComment);
Parser(Module *module, const utf8_t *base, size_t length, int doDocComment);
Dsymbols *parseModule(); Dsymbols *parseModule();
Dsymbols *parseDeclDefs(int once, Dsymbol **pLastDecl = NULL); Dsymbols *parseDeclDefs(int once, Dsymbol **pLastDecl = NULL);
Dsymbols *parseAutoDeclarations(StorageClass storageClass, utf8_t *comment); Dsymbols *parseAutoDeclarations(StorageClass storageClass, const utf8_t *comment);
Dsymbols *parseBlock(Dsymbol **pLastDecl); Dsymbols *parseBlock(Dsymbol **pLastDecl);
void composeStorageClass(StorageClass stc); void composeStorageClass(StorageClass stc);
StorageClass parseAttribute(Expressions **pexps); StorageClass parseAttribute(Expressions **pexps);
StorageClass parsePostfix(); StorageClass parsePostfix();
StorageClass parseTypeCtor(); StorageClass parseTypeCtor();
Expression *parseConstraint(); Expression *parseConstraint();
TemplateDeclaration *parseTemplateDeclaration(int ismixin); TemplateDeclaration *parseTemplateDeclaration(bool ismixin = false);
TemplateParameters *parseTemplateParameterList(int flag = 0); TemplateParameters *parseTemplateParameterList(int flag = 0);
Dsymbol *parseMixin(); Dsymbol *parseMixin();
Objects *parseTemplateArgumentList(); Objects *parseTemplateArgumentList();
@@ -112,11 +113,11 @@ public:
Type *parseBasicType(); Type *parseBasicType();
Type *parseBasicType2(Type *t); Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL, StorageClass storage_class = 0, int* pdisable = NULL); Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL, StorageClass storage_class = 0, int* pdisable = NULL);
Dsymbols *parseDeclarations(StorageClass storage_class, utf8_t *comment); Dsymbols *parseDeclarations(StorageClass storage_class, const utf8_t *comment);
void parseContracts(FuncDeclaration *f); void parseContracts(FuncDeclaration *f);
void checkDanglingElse(Loc elseloc); void checkDanglingElse(Loc elseloc);
/** endPtr used for documented unittests */ /** endPtr used for documented unittests */
Statement *parseStatement(int flags, utf8_t** endPtr = NULL); Statement *parseStatement(int flags, const utf8_t** endPtr = NULL);
Initializer *parseInitializer(); Initializer *parseInitializer();
Expression *parseDefaultInitExp(); Expression *parseDefaultInitExp();
void check(Loc loc, TOK value); void check(Loc loc, TOK value);
@@ -138,10 +139,6 @@ public:
Expression *parseMulExp(); Expression *parseMulExp();
Expression *parseAddExp(); Expression *parseAddExp();
Expression *parseShiftExp(); Expression *parseShiftExp();
#if DMDV1
Expression *parseRelExp();
Expression *parseEqualExp();
#endif
Expression *parseCmpExp(); Expression *parseCmpExp();
Expression *parseAndExp(); Expression *parseAndExp();
Expression *parseXorExp(); Expression *parseXorExp();
@@ -155,7 +152,7 @@ public:
Expression *parseNewExp(Expression *thisexp); Expression *parseNewExp(Expression *thisexp);
void addComment(Dsymbol *s, utf8_t *blockComment); void addComment(Dsymbol *s, const utf8_t *blockComment);
}; };
// Operator precedence - greater values are higher precedence // Operator precedence - greater values are higher precedence
-499
View File
@@ -1,499 +0,0 @@
// Copyright (c) 2000-2011 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 <string.h>
#include <assert.h>
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
#include <unistd.h>
#include <pthread.h>
#endif
#include "rmem.h"
#include "gc/gc.h"
//#include "printf.h"
/* This implementation of the storage allocator uses the Digital Mars gc.
*/
Mem mem;
//static int nuncollectable;
extern "C"
{
void gc_init();
GC *gc_get();
}
void Mem::init()
{
gc_init();
}
char *Mem::strdup(const char *s)
{
return gc_get()->strdup(s);
}
void *Mem::malloc(size_t size)
{
if (gc) // if cached allocator
{
// PRINTF("Using cached gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line);
// GC::file = NULL;
// GC::line = 0;
return ((GC *)gc)->malloc(size);
}
if (this == &mem) // don't cache global mem
{
// PRINTF("Using global gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line);
// GC::file = NULL;
// GC::line = 0;
return gc_get()->malloc(size);
}
// PRINTF("Generating cached gc for size %d, file = '%s', line = %d\n", size, GC::file, GC::line);
gc = gc_get();
return gc->malloc(size);
}
void *Mem::malloc_uncollectable(size_t size)
{ void *p;
p = ::malloc(size);
if (!p)
error();
addroots((char *)p, (char *)p + size);
#if 0
++nuncollectable;
WPRINTF(L"malloc_uncollectable(%u) = %x, n=%d\n", size, p, nuncollectable);
#endif
return p;
}
void *Mem::calloc(size_t size, size_t n)
{
return gc_get()->calloc(size, n);
}
void *Mem::realloc(void *p, size_t size)
{
return gc_get()->realloc(p, size);
}
void Mem::free(void *p)
{
gc_get()->free(p);
}
void Mem::free_uncollectable(void *p)
{
if (p)
{ removeroots((char *)p);
::free(p);
#if 0
--nuncollectable;
WPRINTF(L"free_uncollectable(%x) n=%d\n", p, nuncollectable);
#endif
#if 0
gc_get()->fullcollect();
GCStats stats;
getStats(&stats);
WPRINTF(L"poolsize = %x, usedsize = %x, freelistsize = %x\n",
stats.poolsize, stats.usedsize, stats.freelistsize);
#endif
}
}
void *Mem::mallocdup(void *o, size_t size)
{
return gc_get()->mallocdup(o, size);
}
void Mem::check(void *p)
{
if (gc)
gc->check(p);
else
gc_get()->check(p);
}
void Mem::error()
{
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
assert(0);
#endif
printf("Error: out of memory\n");
exit(EXIT_FAILURE);
}
void Mem::fullcollect()
{
gc_get()->fullcollect();
#if 0
{
GCStats stats;
gc_get()->getStats(&stats);
WPRINTF(L"Thread %x ", Thread::getId());
WPRINTF(L"poolsize=x%x, usedsize=x%x, freelistsize=x%x, freeblocks=%d, pageblocks=%d\n",
stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks);
}
#endif
}
void Mem::fullcollectNoStack()
{
gc_get()->fullcollectNoStack();
#if 0
{
GCStats stats;
gc_get()->getStats(&stats);
WPRINTF(L"Thread %x ", Thread::getId());
WPRINTF(L"poolsize=x%x, usedsize=x%x, freelistsize=x%x, freeblocks=%d, pageblocks=%d\n",
stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks);
}
#endif
}
void Mem::mark(void *pointer)
{
(void) pointer; // for VC /W4 compatibility
}
void Mem::addroots(char* pStart, char* pEnd)
{
gc_get()->addRange(pStart, pEnd);
}
void Mem::removeroots(char* pStart)
{
gc_get()->removeRange(pStart);
}
void Mem::setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData)
{
(void)pClientData;
gc_get()->setFinalizer(pObj, pFn);
}
void Mem::setStackBottom(void *stackbottom)
{
gc_get()->setStackBottom(stackbottom);
}
GC *Mem::getThreadGC()
{
return gc_get();
}
/* =================================================== */
#if 1
void * operator new(size_t m_size)
{
//PRINTF("Call to global operator new(%d), file = '%s', line = %d\n", m_size, GC::file ? GC::file : "(null)", GC::line);
GC::file = NULL;
GC::line = 0;
return mem.malloc(m_size);
}
void operator delete(void *p)
{
//WPRINTF(L"Call to global operator delete\n");
mem.free(p);
}
void* operator new[](size_t size)
{
return operator new(size);
}
void operator delete[](void *pv)
{
operator delete(pv);
}
#endif
void * Mem::operator new(size_t m_size)
{ void *p;
p = gc_get()->malloc(m_size);
//printf("Mem::operator new(%d) = %p\n", m_size, p);
if (!p)
mem.error();
return p;
}
void * Mem::operator new(size_t m_size, Mem *mem)
{ void *p;
p = mem->malloc(m_size);
//printf("Mem::operator new(%d) = %p\n", m_size, p);
if (!p)
::mem.error();
return p;
}
void * Mem::operator new(size_t m_size, GC *gc)
{ void *p;
// if (!gc)
// WPRINTF(L"gc is NULL\n");
p = gc->malloc(m_size);
//printf("Mem::operator new(%d) = %p\n", m_size, p);
if (!p)
::mem.error();
return p;
}
void Mem::operator delete(void *p)
{
// printf("Mem::operator delete(%p)\n", p);
gc_get()->free(p);
}
/* ============================================================ */
/* The following section of code exists to find the right
* garbage collector for this thread. There is one independent instance
* of the collector per thread.
*/
/* ===================== linux ================================ */
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
#include <pthread.h>
#define LOG 0 // log thread creation / destruction
extern "C"
{
// Key identifying the thread-specific data
static pthread_key_t gc_key;
/* "Once" variable ensuring that the key for gc_alloc will be allocated
* exactly once.
*/
static pthread_once_t gc_alloc_key_once = PTHREAD_ONCE_INIT;
/* Forward functions */
static void gc_alloc_key();
static void gc_alloc_destroy_gc(void * accu);
void gc_init()
{
#if LOG
WPRINTF(L"Thread %lx: gc_init()\n", pthread_self());
#endif
pthread_once(&gc_alloc_key_once, gc_alloc_key);
#if LOG
WPRINTF(L"Thread %lx: gc_init() return\n", pthread_self());
#endif
}
GC *gc_get()
{
GC *gc;
// Get the thread-specific data associated with the key
gc = (GC *) pthread_getspecific(gc_key);
// It's initially NULL, meaning that we must allocate the buffer first.
if (gc == NULL)
{
GC_LOG();
gc = new GC();
gc->init();
// Store the buffer pointer in the thread-specific data.
pthread_setspecific(gc_key, (void *) gc);
#if LOG
WPRINTF(L"Thread %lx: allocating gc at %x\n", pthread_self(), gc);
#endif
}
return gc;
}
// Function to allocate the key for gc_alloc thread-specific data.
static void gc_alloc_key()
{
pthread_key_create(&gc_key, gc_alloc_destroy_gc);
#if LOG
WPRINTF(L"Thread %lx: allocated gc key %d\n", pthread_self(), gc_key);
#endif
}
// Function to free the buffer when the thread exits.
// Called only when the thread-specific data is not NULL.
static void gc_alloc_destroy_gc(void *gc)
{
#if LOG
WPRINTF(L"Thread %x: freeing gc at %x\n", pthread_self(), gc);
#endif
delete (GC *)gc;
}
}
#endif
/* ===================== win32 ================================ */
#if !defined(linux) && defined(_WIN32)
#if 1 // single threaded version
extern "C"
{
static GC *gc;
void gc_init()
{
if (!gc)
{ gc = (GC *)::malloc(sizeof(GC));
gc->init();
}
}
GC *gc_get()
{
return gc;
}
}
#else // multi threaded version
#include "mutex.h"
#include "thread.h"
/* This is the win32 version. It suffers from the bug that
* when the thread exits the data structure is not cleared,
* but the memory pool it points to is free'd.
* Thus, if a new thread comes along with the same thread id,
* the data will look initialized, but will point to garbage.
*
* What needs to happen is when a thread exits, the associated
* GC_context data struct is cleared.
*/
struct GC_context
{
ThreadId threadid; // identifier of current thread
GC *gc;
};
Mutex gc_mutex;
static GC_context array[64];
// Array of pointers to GC_context objects, one per threadid
GC_context *gccontext = array;
unsigned gccontext_allocdim = 64;
unsigned gccontext_dim;
ThreadId gc_cache_ti;
GC_context *gc_cache_cc;
extern "C" void gc_init()
{
}
extern "C" GC *gc_get()
{
/* This works by creating an array of GC_context's, one
* for each thread. We match up by thread id.
*/
ThreadId ti;
GC_context *cc;
//PRINTF("gc_get()\n");
ti = Thread::getId();
gc_mutex.acquire();
// Used cached version if we can
if (ti == gc_cache_ti)
{
cc = gc_cache_cc;
//exception(L"getGC_context(): cache x%x", ti);
}
else
{
// This does a linear search through gccontext[].
// A hash table might be faster if there are more
// than a dozen threads.
GC_context *ccp;
GC_context *ccptop = &gccontext[gccontext_dim];
for (ccp = gccontext; ccp < ccptop; ccp++)
{
cc = ccp;
if (cc->threadid == ti)
{
WPRINTF(L"getGC_context(): existing x%x", ti);
goto Lret;
}
}
// Do not allocate with garbage collector, as this must reside
// global to all threads.
assert(gccontext_dim < gccontext_allocdim);
cc = ccp;
memset(cc, 0, sizeof(*cc));
cc->threadid = ti;
cc->gc = new GC();
cc->gc->init();
gccontext_dim++;
WPRINTF(L"getGC_context(): new x%x\n", ti);
Lret:
// Cache for next time
gc_cache_ti = ti;
gc_cache_cc = cc;
}
gc_mutex.release();
return cc->gc;
}
#endif
#endif
+11 -9
View File
@@ -520,6 +520,16 @@ int ld_type(longdouble x)
size_t ld_sprint(char* str, int fmt, longdouble x) size_t ld_sprint(char* str, int fmt, longdouble x)
{ {
// ensure dmc compatible strings for nan and inf
switch(ld_type(x))
{
case LD_TYPE_QNAN:
case LD_TYPE_SNAN:
return sprintf(str, "nan");
case LD_TYPE_INFINITE:
return sprintf(str, x.sign ? "-inf" : "inf");
}
// fmt is 'a','A','f' or 'g' // fmt is 'a','A','f' or 'g'
if(fmt != 'a' && fmt != 'A') if(fmt != 'a' && fmt != 'A')
{ {
@@ -537,16 +547,8 @@ size_t ld_sprint(char* str, int fmt, longdouble x)
unsigned short exp = x.exponent; unsigned short exp = x.exponent;
unsigned long long mantissa = x.mantissa; unsigned long long mantissa = x.mantissa;
switch(ld_type(x)) if(ld_type(x) == LD_TYPE_ZERO)
{
case LD_TYPE_ZERO:
return sprintf(str, "0x0.0L"); return sprintf(str, "0x0.0L");
case LD_TYPE_QNAN:
case LD_TYPE_SNAN:
return sprintf(str, "NAN");
case LD_TYPE_INFINITE:
return sprintf(str, x.sign ? "-INF" : "INF");
}
size_t len = 0; size_t len = 0;
if(x.sign) if(x.sign)
+1 -1
View File
@@ -763,7 +763,7 @@ int Port::isInfinity(double r)
longdouble Port::fmodl(longdouble x, longdouble y) longdouble Port::fmodl(longdouble x, longdouble y)
{ {
#if __FreeBSD__ || __OpenBSD__ #if __FreeBSD__ && __FreeBSD_version < 800000 || __OpenBSD__
return ::fmod(x, y); // hack for now, fix later return ::fmod(x, y); // hack for now, fix later
#else #else
return ::fmodl(x, y); return ::fmodl(x, y);
-22
View File
@@ -18,10 +18,6 @@
Mem mem; Mem mem;
void Mem::init()
{
}
char *Mem::strdup(const char *s) char *Mem::strdup(const char *s)
{ {
char *p; char *p;
@@ -118,24 +114,6 @@ void Mem::error()
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
void Mem::fullcollect()
{
}
void Mem::mark(void *pointer)
{
(void) pointer; // necessary for VC /W4
}
void Mem::setStackBottom(void *bottom)
{
}
void Mem::addroots(char* pStart, char* pEnd)
{
}
/* =================================================== */ /* =================================================== */
#if defined(__has_feature) #if defined(__has_feature)
+1 -28
View File
@@ -15,44 +15,17 @@
#endif #endif
#include <stddef.h> // for size_t #include <stddef.h> // for size_t
typedef void (*FINALIZERPROC)(void* pObj, void* pClientData);
struct GC; // thread specific allocator
struct Mem struct Mem
{ {
GC *gc; // pointer to our thread specific allocator Mem() { }
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); char *strdup(const char *s);
void *malloc(size_t size); void *malloc(size_t size);
void *malloc_uncollectable(size_t size);
void *calloc(size_t size, size_t n); void *calloc(size_t size, size_t n);
void *realloc(void *p, size_t size); void *realloc(void *p, size_t size);
void free(void *p); void free(void *p);
void free_uncollectable(void *p);
void *mallocdup(void *o, size_t size); void *mallocdup(void *o, size_t size);
void error(); 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; extern Mem mem;
+9 -254
View File
@@ -103,11 +103,6 @@ bool RootObject::equals(RootObject *o)
return o == this; return o == this;
} }
hash_t RootObject::hashCode()
{
return (hash_t) this;
}
int RootObject::compare(RootObject *obj) int RootObject::compare(RootObject *obj)
{ {
return this - obj; return this - obj;
@@ -133,104 +128,10 @@ void RootObject::toBuffer(OutBuffer *b)
b->writestring("Object"); b->writestring("Object");
} }
void RootObject::mark()
{
}
/****************************** String ********************************/
String::String(const char *str)
: str(mem.strdup(str))
{
}
String::~String()
{
mem.free((void *)str);
}
void String::mark()
{
mem.mark((void *)str);
}
hash_t String::calcHash(const char *str, size_t len)
{
hash_t hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(uint8_t *)str;
return hash;
case 2:
hash *= 37;
hash += *(uint16_t *)str;
return hash;
case 3:
hash *= 37;
hash += (*(uint16_t *)str << 8) +
((uint8_t *)str)[2];
return hash;
default:
hash *= 37;
hash += *(uint32_t *)str;
str += 4;
len -= 4;
break;
}
}
}
hash_t String::calcHash(const char *str)
{
return calcHash(str, strlen(str));
}
hash_t String::hashCode()
{
return calcHash(str, strlen(str));
}
size_t String::len()
{
return strlen(str);
}
bool String::equals(RootObject *obj)
{
return strcmp(str,((String *)obj)->str) == 0;
}
int String::compare(RootObject *obj)
{
return strcmp(str,((String *)obj)->str);
}
char *String::toChars()
{
return (char *)str; // toChars() should really be const
}
void String::print()
{
printf("String '%s'\n",str);
}
/****************************** FileName ********************************/ /****************************** FileName ********************************/
FileName::FileName(const char *str) FileName::FileName(const char *str)
: String(str) : str(mem.strdup(str))
{ {
} }
@@ -339,51 +240,6 @@ Strings *FileName::splitPath(const char *path)
return array; return array;
} }
hash_t FileName::hashCode()
{
#if _WIN32
// We need a different hashCode because it must be case-insensitive
size_t len = strlen(str);
hash_t hash = 0;
utf8_t *s = (utf8_t *)str;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(uint8_t *)s | 0x20;
return hash;
case 2:
hash *= 37;
hash += *(uint16_t *)s | 0x2020;
return hash;
case 3:
hash *= 37;
hash += ((*(uint16_t *)s << 8) +
((uint8_t *)s)[2]) | 0x202020;
break;
default:
hash *= 37;
hash += *(uint32_t *)s | 0x20202020;
s += 4;
len -= 4;
break;
}
}
#else
// darwin HFS is case insensitive, though...
return String::hashCode();
#endif
}
int FileName::compare(RootObject *obj) int FileName::compare(RootObject *obj)
{ {
return compare(str, ((FileName *)obj)->str); return compare(str, ((FileName *)obj)->str);
@@ -941,6 +797,11 @@ void FileName::free(const char *str)
mem.free((void *)str); mem.free((void *)str);
} }
char *FileName::toChars()
{
return (char *)str; // toChars() should really be const
}
/****************************** File ********************************/ /****************************** File ********************************/
@@ -969,7 +830,7 @@ File::~File()
if (ref == 0) if (ref == 0)
mem.free(buffer); mem.free(buffer);
#if _WIN32 #if _WIN32
else if (ref == 2) if (ref == 2)
UnmapViewOfFile(buffer); UnmapViewOfFile(buffer);
#endif #endif
} }
@@ -977,13 +838,6 @@ File::~File()
mem.free(touchtime); mem.free(touchtime);
} }
void File::mark()
{
mem.mark(buffer);
mem.mark(touchtime);
mem.mark(name);
}
/************************************* /*************************************
*/ */
@@ -1394,9 +1248,9 @@ Files *File::match(FileName *n)
char *fn; char *fn;
File *f; File *f;
fn = (char *)mem.malloc(name - c + strlen(fileinfo.cFileName) + 1); fn = (char *)mem.malloc(name - c + strlen(&fileinfo.cFileName[0]) + 1);
memcpy(fn, c, name - c); memcpy(fn, c, name - c);
strcpy(fn + (name - c), fileinfo.cFileName); strcpy(fn + (name - c), &fileinfo.cFileName[0]);
f = new File(fn); f = new File(fn);
f->touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); f->touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA));
memcpy(f->touchtime, &fileinfo, sizeof(fileinfo)); memcpy(f->touchtime, &fileinfo, sizeof(fileinfo));
@@ -1490,11 +1344,6 @@ char *OutBuffer::extractData()
return p; return p;
} }
void OutBuffer::mark()
{
mem.mark(data);
}
void OutBuffer::reserve(size_t nbytes) void OutBuffer::reserve(size_t nbytes)
{ {
//printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes); //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
@@ -1861,97 +1710,3 @@ char *OutBuffer::toChars()
writeByte(0); writeByte(0);
return (char *)data; return (char *)data;
} }
// TODO: Remove (only used by disabled GC)
/********************************* Bits ****************************/
Bits::Bits()
{
data = NULL;
bitdim = 0;
allocdim = 0;
}
Bits::~Bits()
{
mem.free(data);
}
void Bits::mark()
{
mem.mark(data);
}
void Bits::resize(unsigned bitdim)
{
unsigned allocdim;
unsigned mask;
allocdim = (bitdim + 31) / 32;
data = (unsigned *)mem.realloc(data, allocdim * sizeof(data[0]));
if (this->allocdim < allocdim)
memset(data + this->allocdim, 0, (allocdim - this->allocdim) * sizeof(data[0]));
// Clear other bits in last word
mask = (1 << (bitdim & 31)) - 1;
if (mask)
data[allocdim - 1] &= ~mask;
this->bitdim = bitdim;
this->allocdim = allocdim;
}
void Bits::set(unsigned bitnum)
{
data[bitnum / 32] |= 1 << (bitnum & 31);
}
void Bits::clear(unsigned bitnum)
{
data[bitnum / 32] &= ~(1 << (bitnum & 31));
}
int Bits::test(unsigned bitnum)
{
return data[bitnum / 32] & (1 << (bitnum & 31));
}
void Bits::set()
{ unsigned mask;
memset(data, ~0, allocdim * sizeof(data[0]));
// Clear other bits in last word
mask = (1 << (bitdim & 31)) - 1;
if (mask)
data[allocdim - 1] &= mask;
}
void Bits::clear()
{
memset(data, 0, allocdim * sizeof(data[0]));
}
void Bits::copy(Bits *from)
{
assert(bitdim == from->bitdim);
memcpy(data, from->data, allocdim * sizeof(data[0]));
}
Bits *Bits::clone()
{
Bits *b;
b = new Bits();
b->resize(bitdim);
b->copy(this);
return b;
}
void Bits::sub(Bits *b)
{
unsigned u;
for (u = 0; u < allocdim; u++)
data[u] &= ~b->data[u];
}
+6 -71
View File
@@ -31,8 +31,8 @@ struct OutBuffer;
// Can't include arraytypes.h here, need to declare these directly. // Can't include arraytypes.h here, need to declare these directly.
template <typename TYPE> struct Array; template <typename TYPE> struct Array;
typedef Array<class File> Files; typedef Array<struct File> Files;
typedef Array<char> Strings; typedef Array<const char> Strings;
class RootObject class RootObject
@@ -43,11 +43,6 @@ public:
virtual bool equals(RootObject *o); virtual bool equals(RootObject *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. * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
* Useful for sorting Objects. * Useful for sorting Objects.
@@ -67,38 +62,13 @@ public:
* defined by the library user. For Object, the return value is 0. * defined by the library user. For Object, the return value is 0.
*/ */
virtual int dyncast(); 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();
}; };
class String : public RootObject struct FileName
{
public:
const char *str; // the string itself
String(const char *str);
~String();
static hash_t calcHash(const char *str, size_t len);
static hash_t calcHash(const char *str);
hash_t hashCode();
size_t len();
bool equals(RootObject *obj);
int compare(RootObject *obj);
char *toChars();
void print();
void mark();
};
class FileName : public String
{ {
public: public:
const char *str;
FileName(const char *str); FileName(const char *str);
hash_t hashCode();
bool equals(RootObject *obj); bool equals(RootObject *obj);
static int equals(const char *name1, const char *name2); static int equals(const char *name1, const char *name2);
int compare(RootObject *obj); int compare(RootObject *obj);
@@ -129,9 +99,10 @@ public:
static const char *canonicalName(const char *name); static const char *canonicalName(const char *name);
static void free(const char *str); static void free(const char *str);
char *toChars();
}; };
class File : public RootObject struct File
{ {
public: public:
int ref; // != 0 if this is a reference to someone else's buffer int ref; // != 0 if this is a reference to someone else's buffer
@@ -145,8 +116,6 @@ public:
File(const FileName *); File(const FileName *);
~File(); ~File();
void mark();
char *toChars(); char *toChars();
/* Read file, return !=0 if error /* Read file, return !=0 if error
@@ -250,7 +219,6 @@ struct OutBuffer
OutBuffer(); OutBuffer();
~OutBuffer(); ~OutBuffer();
char *extractData(); char *extractData();
void mark();
void reserve(size_t nbytes); void reserve(size_t nbytes);
void setsize(size_t size); void setsize(size_t size);
@@ -308,13 +276,6 @@ struct Array
mem.free(data); mem.free(data);
} }
void mark()
{
mem.mark(data);
for (size_t u = 0; u < dim; u++)
mem.mark(data[u]); // BUG: what if arrays of Object's?
}
char *toChars() char *toChars()
{ {
char **buf = (char **)malloc(dim * sizeof(char *)); char **buf = (char **)malloc(dim * sizeof(char *));
@@ -522,30 +483,4 @@ struct Array
} }
}; };
// TODO: Remove (only used by disabled GC)
class Bits : public RootObject
{
public:
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 #endif
+2 -1
View File
@@ -203,7 +203,8 @@ void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset) void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
{ {
size_t seedlen = strlen(seed); size_t seedlen = strlen(seed);
for (int distance = 0; distance < 2; distance++) size_t maxdist = seedlen < 3 ? seedlen - 1 : 2;
for (int distance = 0; distance < maxdist; distance++)
{ void *p = spellerX(seed, seedlen, fp, fparg, charset, distance); { void *p = spellerX(seed, seedlen, fp, fparg, charset, distance);
if (p) if (p)
return p; return p;
+2 -6
View File
@@ -36,7 +36,7 @@ bool Statement::apply(sapply_fp_t fp, void *param)
/****************************** /******************************
* Perform apply() on an t if not null * Perform apply() on an t if not null
*/ */
#define scondApply(t, fp, param) (t ? t->apply(fp, param) : 0) #define scondApply(t, fp, param) (t ? t->apply(fp, param) : false)
@@ -101,13 +101,11 @@ bool ForeachStatement::apply(sapply_fp_t fp, void *param)
(*fp)(this, param); (*fp)(this, param);
} }
#if DMDV2
bool ForeachRangeStatement::apply(sapply_fp_t fp, void *param) bool ForeachRangeStatement::apply(sapply_fp_t fp, void *param)
{ {
return scondApply(body, fp, param) || return scondApply(body, fp, param) ||
(*fp)(this, param); (*fp)(this, param);
} }
#endif
bool IfStatement::apply(sapply_fp_t fp, void *param) bool IfStatement::apply(sapply_fp_t fp, void *param)
{ {
@@ -141,13 +139,11 @@ bool CaseStatement::apply(sapply_fp_t fp, void *param)
(*fp)(this, param); (*fp)(this, param);
} }
#if DMDV2
bool CaseRangeStatement::apply(sapply_fp_t fp, void *param) bool CaseRangeStatement::apply(sapply_fp_t fp, void *param)
{ {
return scondApply(statement, fp, param) || return scondApply(statement, fp, param) ||
(*fp)(this, param); (*fp)(this, param);
} }
#endif
bool DefaultStatement::apply(sapply_fp_t fp, void *param) bool DefaultStatement::apply(sapply_fp_t fp, void *param)
{ {
@@ -176,7 +172,7 @@ bool TryCatchStatement::apply(sapply_fp_t fp, void *param)
for (size_t i = 0; i < catches->dim; i++) for (size_t i = 0; i < catches->dim; i++)
{ Catch *c = (*catches)[i]; { Catch *c = (*catches)[i];
bool r = scondApply(c->handler, fp, param); r = scondApply(c->handler, fp, param);
if (r) if (r)
return r; return r;
} }
+31 -11
View File
@@ -57,8 +57,12 @@ Scope::Scope()
this->enclosing = NULL; this->enclosing = NULL;
this->parent = NULL; this->parent = NULL;
this->sw = NULL; this->sw = NULL;
#if IN_LLVM
this->enclosingFinally = NULL; this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL; this->enclosingScopeExit = NULL;
#else
this->tf = NULL;
#endif
this->tinst = NULL; this->tinst = NULL;
this->sbreak = NULL; this->sbreak = NULL;
this->scontinue = NULL; this->scontinue = NULL;
@@ -78,6 +82,7 @@ Scope::Scope()
this->noctor = 0; this->noctor = 0;
this->intypeof = 0; this->intypeof = 0;
this->speculative = 0; this->speculative = 0;
this->lastVar = NULL;
this->callSuper = 0; this->callSuper = 0;
this->fieldinit = NULL; this->fieldinit = NULL;
this->fieldinit_dim = 0; this->fieldinit_dim = 0;
@@ -99,8 +104,12 @@ Scope::Scope(Scope *enclosing)
this->scopesym = NULL; this->scopesym = NULL;
this->sd = NULL; this->sd = NULL;
this->sw = enclosing->sw; this->sw = enclosing->sw;
#if IN_LLVM
this->enclosingFinally = enclosing->enclosingFinally; this->enclosingFinally = enclosing->enclosingFinally;
this->enclosingScopeExit = enclosing->enclosingScopeExit; this->enclosingScopeExit = enclosing->enclosingScopeExit;
#else
this->tf = enclosing->tf;
#endif
this->tinst = enclosing->tinst; this->tinst = enclosing->tinst;
this->sbreak = enclosing->sbreak; this->sbreak = enclosing->sbreak;
this->scontinue = enclosing->scontinue; this->scontinue = enclosing->scontinue;
@@ -129,10 +138,11 @@ Scope::Scope(Scope *enclosing)
this->noctor = enclosing->noctor; this->noctor = enclosing->noctor;
this->intypeof = enclosing->intypeof; this->intypeof = enclosing->intypeof;
this->speculative = enclosing->speculative; this->speculative = enclosing->speculative;
this->lastVar = enclosing->lastVar;
this->callSuper = enclosing->callSuper; this->callSuper = enclosing->callSuper;
this->fieldinit = enclosing->saveFieldInit(); this->fieldinit = enclosing->saveFieldInit();
this->fieldinit_dim = enclosing->fieldinit_dim; this->fieldinit_dim = enclosing->fieldinit_dim;
this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug | SCOPEctfe)); this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug | SCOPEctfe | SCOPEcompile));
this->lastdc = NULL; this->lastdc = NULL;
this->lastoffset = 0; this->lastoffset = 0;
this->docbuf = enclosing->docbuf; this->docbuf = enclosing->docbuf;
@@ -191,7 +201,7 @@ Scope *Scope::pop()
size_t dim = fieldinit_dim; size_t dim = fieldinit_dim;
for (size_t i = 0; i < dim; i++) for (size_t i = 0; i < dim; i++)
enclosing->fieldinit[i] |= fieldinit[i]; enclosing->fieldinit[i] |= fieldinit[i];
delete[] fieldinit; mem.free(fieldinit);
fieldinit = NULL; fieldinit = NULL;
} }
} }
@@ -277,14 +287,9 @@ unsigned *Scope::saveFieldInit()
if (fieldinit) // copy if (fieldinit) // copy
{ {
size_t dim = fieldinit_dim; size_t dim = fieldinit_dim;
fi = new unsigned[dim]; fi = (unsigned *)mem.malloc(sizeof(unsigned) * dim);
#if IN_LLVM // ASan
memcpy(fi, fieldinit, sizeof(*fi) * dim);
#else
fi[0] = dim;
for (size_t i = 0; i < dim; i++) for (size_t i = 0; i < dim; i++)
fi[i] = fieldinit[i]; fi[i] = fieldinit[i];
#endif
} }
return fi; return fi;
} }
@@ -455,9 +460,24 @@ Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
} }
Dsymbol *Scope::insert(Dsymbol *s) Dsymbol *Scope::insert(Dsymbol *s)
{ Scope *sc; {
if (VarDeclaration *vd = s->isVarDeclaration())
for (sc = this; sc; sc = sc->enclosing) {
if (lastVar)
vd->lastVar = lastVar;
lastVar = vd;
}
else if (WithScopeSymbol *ss = s->isWithScopeSymbol())
{
if (VarDeclaration *vd = ss->withstate->wthis)
{
if (lastVar)
vd->lastVar = lastVar;
lastVar = vd;
}
return NULL;
}
for (Scope *sc = this; sc; sc = sc->enclosing)
{ {
//printf("\tsc = %p\n", sc); //printf("\tsc = %p\n", sc);
if (sc->scopesym) if (sc->scopesym)
+2
View File
@@ -64,6 +64,7 @@ enum PROT;
#define SCOPEctfe 0x0080 // inside a ctfe-only expression #define SCOPEctfe 0x0080 // inside a ctfe-only expression
#define SCOPEnoaccesscheck 0x0100 // don't do access checks #define SCOPEnoaccesscheck 0x0100 // don't do access checks
#define SCOPEcompile 0x0200 // inside __traits(compile)
struct Scope struct Scope
{ {
@@ -95,6 +96,7 @@ struct Scope
int noctor; // set if constructor calls aren't allowed int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp) int intypeof; // in typeof(exp)
bool speculative; // in __traits(compiles) or typeof(exp) bool speculative; // in __traits(compiles) or typeof(exp)
VarDeclaration *lastVar; // Previous symbol used to prevent goto-skips-init
unsigned callSuper; // primitive flow analysis for constructors unsigned callSuper; // primitive flow analysis for constructors
unsigned *fieldinit; unsigned *fieldinit;
+5 -5
View File
@@ -31,7 +31,7 @@ int lambdaHasSideEffect(Expression *e, void *param);
bool Expression::hasSideEffect() bool Expression::hasSideEffect()
{ {
bool has = FALSE; bool has = false;
apply(&lambdaHasSideEffect, &has); apply(&lambdaHasSideEffect, &has);
return has; return has;
} }
@@ -68,7 +68,7 @@ int lambdaHasSideEffect(Expression *e, void *param)
case TOKdelete: case TOKdelete:
case TOKnew: case TOKnew:
case TOKnewanonclass: case TOKnewanonclass:
*phas = TRUE; *phas = true;
break; break;
case TOKcall: case TOKcall:
@@ -89,7 +89,7 @@ int lambdaHasSideEffect(Expression *e, void *param)
{ {
} }
else else
*phas = TRUE; *phas = true;
} }
break; break;
} }
@@ -101,7 +101,7 @@ int lambdaHasSideEffect(Expression *e, void *param)
* cast(classtype)func() // because it may throw * cast(classtype)func() // because it may throw
*/ */
if (ce->to->ty == Tclass && ce->e1->op == TOKcall && ce->e1->type->ty == Tclass) if (ce->to->ty == Tclass && ce->e1->op == TOKcall && ce->e1->type->ty == Tclass)
*phas = TRUE; *phas = true;
break; break;
} }
@@ -118,7 +118,7 @@ int lambdaHasSideEffect(Expression *e, void *param)
*/ */
void Expression::discardValue() void Expression::discardValue()
{ {
bool has = FALSE; bool has = false;
lambdaHasSideEffect(this, &has); lambdaHasSideEffect(this, &has);
if (!has) if (!has)
{ {
+275 -229
View File
File diff suppressed because it is too large Load Diff
+9 -8
View File
@@ -326,6 +326,7 @@ public:
Statement *syntaxCopy(); Statement *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
ScopeStatement *isScopeStatement() { return this; } ScopeStatement *isScopeStatement() { return this; }
ReturnStatement *isReturnStatement();
Statement *semantic(Scope *sc); Statement *semantic(Scope *sc);
bool hasBreak(); bool hasBreak();
bool hasContinue(); bool hasContinue();
@@ -434,7 +435,7 @@ public:
FuncDeclaration *func; // function we're lexically in FuncDeclaration *func; // function we're lexically in
Statements *cases; // put breaks, continues, gotos and returns here Statements *cases; // put breaks, continues, gotos and returns here
CompoundStatements *gotos; // forward referenced goto's go here ScopeStatements *gotos; // forward referenced goto's go here
ForeachStatement(Loc loc, TOK op, Parameters *arguments, Expression *aggr, Statement *body); ForeachStatement(Loc loc, TOK op, Parameters *arguments, Expression *aggr, Statement *body);
Statement *syntaxCopy(); Statement *syntaxCopy();
@@ -455,7 +456,6 @@ public:
void toIR(IRState *irs); void toIR(IRState *irs);
}; };
#if DMDV2
class ForeachRangeStatement : public Statement class ForeachRangeStatement : public Statement
{ {
public: public:
@@ -483,7 +483,6 @@ public:
void toIR(IRState *irs); void toIR(IRState *irs);
}; };
#endif
class IfStatement : public Statement class IfStatement : public Statement
{ {
@@ -631,7 +630,6 @@ public:
#endif #endif
}; };
#if DMDV2
class CaseRangeStatement : public Statement class CaseRangeStatement : public Statement
{ {
@@ -647,7 +645,6 @@ public:
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#endif
class DefaultStatement : public Statement class DefaultStatement : public Statement
{ {
@@ -961,16 +958,19 @@ class GotoStatement : public Statement
public: public:
Identifier *ident; Identifier *ident;
LabelDsymbol *label; LabelDsymbol *label;
#if !IN_LLVM #if IN_LLVM
TryFinallyStatement *tf;
#else
TryFinallyStatement *enclosingFinally; TryFinallyStatement *enclosingFinally;
Statement* enclosingScopeExit; Statement* enclosingScopeExit;
#else
TryFinallyStatement *tf;
#endif #endif
VarDeclaration *lastVar;
FuncDeclaration *fd;
GotoStatement(Loc loc, Identifier *ident); GotoStatement(Loc loc, Identifier *ident);
Statement *syntaxCopy(); Statement *syntaxCopy();
Statement *semantic(Scope *sc); Statement *semantic(Scope *sc);
bool checkLabel();
int blockExit(bool mustNotThrow); int blockExit(bool mustNotThrow);
Expression *interpret(InterState *istate); Expression *interpret(InterState *istate);
void ctfeCompile(CompiledCtfeFunction *ccf); void ctfeCompile(CompiledCtfeFunction *ccf);
@@ -991,6 +991,7 @@ public:
Statement* enclosingScopeExit; Statement* enclosingScopeExit;
#endif #endif
Statement *gotoTarget; // interpret Statement *gotoTarget; // interpret
VarDeclaration *lastVar;
block *lblock; // back end block *lblock; // back end
Blocks *fwdrefs; // forward references to this LabelStatement Blocks *fwdrefs; // forward references to this LabelStatement
+2 -2
View File
@@ -77,7 +77,7 @@ void StaticAssert::semantic2(Scope *sc)
{ {
errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars()); errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars());
} }
else if (e->isBool(FALSE)) else if (e->isBool(false))
{ {
if (msg) if (msg)
{ {
@@ -105,7 +105,7 @@ void StaticAssert::semantic2(Scope *sc)
if (!global.gag) if (!global.gag)
fatal(); fatal();
} }
else if (!e->isBool(TRUE)) else if (!e->isBool(true))
{ {
error("(%s) is not evaluatable at compile time", exp->toChars()); error("(%s) is not evaluatable at compile time", exp->toChars());
} }
+1 -77
View File
@@ -120,12 +120,10 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
enclosing = NULL; enclosing = NULL;
vthis = NULL; vthis = NULL;
#if DMDV2
ctor = NULL; ctor = NULL;
defaultCtor = NULL; defaultCtor = NULL;
aliasthis = NULL; aliasthis = NULL;
noDefaultCtor = FALSE; noDefaultCtor = false;
#endif
dtor = NULL; dtor = NULL;
getRTInfo = NULL; getRTInfo = NULL;
@@ -565,7 +563,6 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
: AggregateDeclaration(loc, id) : AggregateDeclaration(loc, id)
{ {
zeroInit = 0; // assume false until we do semantic processing zeroInit = 0; // assume false until we do semantic processing
#if DMDV2
hasIdentityAssign = 0; hasIdentityAssign = 0;
hasIdentityEquals = 0; hasIdentityEquals = 0;
cpctor = NULL; cpctor = NULL;
@@ -574,7 +571,6 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
xeq = NULL; xeq = NULL;
xcmp = NULL; xcmp = NULL;
alignment = 0; alignment = 0;
#endif
arg1type = NULL; arg1type = NULL;
arg2type = NULL; arg2type = NULL;
@@ -582,16 +578,8 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
type = new TypeStruct(this); type = new TypeStruct(this);
#if MODULEINFO_IS_STRUCT #if MODULEINFO_IS_STRUCT
#ifdef DMDV2
if (id == Id::ModuleInfo && !Module::moduleinfo) if (id == Id::ModuleInfo && !Module::moduleinfo)
Module::moduleinfo = this; Module::moduleinfo = this;
#else
if (id == Id::ModuleInfo)
{ if (Module::moduleinfo)
Module::moduleinfo->error("only object.d can define this reserved struct name");
Module::moduleinfo = this;
}
#endif
#endif #endif
} }
@@ -758,69 +746,6 @@ void StructDeclaration::semantic(Scope *sc)
} }
} }
#if DMDV1
/* This doesn't work for DMDV2 because (ref S) and (S) parameter
* lists will overload the same.
*/
/* The TypeInfo_Struct is expecting an opEquals and opCmp with
* a parameter that is a pointer to the struct. But if there
* isn't one, but is an opEquals or opCmp with a value, write
* another that is a shell around the value:
* int opCmp(struct *p) { return opCmp(*p); }
*/
TypeFunction *tfeqptr;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, handle, Id::p, NULL);
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), sc);
}
TypeFunction *tfeq;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, type, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(Loc(), sc);
}
Identifier *id = Id::eq;
for (int i = 0; i < 2; i++)
{
Dsymbol *s = search_function(this, id);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
if (!fd)
{ fd = fdx->overloadExactMatch(tfeq);
if (fd)
{ // Create the thunk, fdptr
FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
Expression *e = new IdentifierExp(loc, Id::p);
e = new PtrExp(loc, e);
Expressions *args = new Expressions();
args->push(e);
e = new IdentifierExp(loc, id);
e = new CallExp(loc, e, args);
fdptr->fbody = new ReturnStatement(loc, e);
ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
assert(s);
s->members->push(fdptr);
fdptr->addMember(sc, s, 1);
fdptr->semantic(sc2);
}
}
}
id = Id::cmp;
}
#endif
#if DMDV2
dtor = buildDtor(sc2); dtor = buildDtor(sc2);
postblit = buildPostBlit(sc2); postblit = buildPostBlit(sc2);
cpctor = buildCpCtor(sc2); cpctor = buildCpCtor(sc2);
@@ -840,7 +765,6 @@ void StructDeclaration::semantic(Scope *sc)
/* Defer requesting semantic3 until TypeInfo generation is actually invoked. /* Defer requesting semantic3 until TypeInfo generation is actually invoked.
* See Type::getTypeInfo(). * See Type::getTypeInfo().
*/ */
#endif
inv = buildInv(sc2); inv = buildInv(sc2);
sc2->pop(); sc2->pop();
+250 -130
View File
@@ -454,7 +454,6 @@ void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, RootObject *oarg)
} }
} }
#if DMDV2
RootObject *objectSyntaxCopy(RootObject *o) RootObject *objectSyntaxCopy(RootObject *o)
{ {
if (!o) if (!o)
@@ -467,13 +466,12 @@ RootObject *objectSyntaxCopy(RootObject *o)
return e->syntaxCopy(); return e->syntaxCopy();
return o; return o;
} }
#endif
/* ======================== TemplateDeclaration ============================= */ /* ======================== TemplateDeclaration ============================= */
TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, int ismixin) TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, bool ismixin, bool literal)
: ScopeDsymbol(id) : ScopeDsymbol(id)
{ {
#if LOG #if LOG
@@ -501,8 +499,9 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
this->overroot = NULL; this->overroot = NULL;
this->funcroot = NULL; this->funcroot = NULL;
this->onemember = NULL; this->onemember = NULL;
this->literal = 0; this->literal = literal;
this->ismixin = ismixin; this->ismixin = ismixin;
this->isstatic = true;
this->previous = NULL; this->previous = NULL;
this->protection = PROTundefined; this->protection = PROTundefined;
this->numinstances = 0; this->numinstances = 0;
@@ -540,8 +539,7 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
if (constraint) if (constraint)
e = constraint->syntaxCopy(); e = constraint->syntaxCopy();
Dsymbols *d = Dsymbol::arraySyntaxCopy(members); Dsymbols *d = Dsymbol::arraySyntaxCopy(members);
td = new TemplateDeclaration(loc, ident, p, e, d, ismixin); td = new TemplateDeclaration(loc, ident, p, e, d, ismixin, literal);
td->literal = literal;
#if IN_LLVM #if IN_LLVM
td->intrinsicName = intrinsicName; td->intrinsicName = intrinsicName;
#endif #endif
@@ -568,13 +566,6 @@ void TemplateDeclaration::semantic(Scope *sc)
Type::rtinfo = this; Type::rtinfo = this;
} }
if (sc->func)
{
#if DMDV1
error("cannot declare template at function scope %s", sc->func->toChars());
#endif
}
if (/*global.params.useArrayBounds &&*/ sc->module) if (/*global.params.useArrayBounds &&*/ sc->module)
{ {
// Generate this function as it may be used // Generate this function as it may be used
@@ -591,7 +582,6 @@ void TemplateDeclaration::semantic(Scope *sc)
//sc->module->toModuleAssert(); //sc->module->toModuleAssert();
} }
#if DMDV2
if (sc->module) if (sc->module)
{ {
// Generate this function as it may be used // Generate this function as it may be used
@@ -599,13 +589,13 @@ void TemplateDeclaration::semantic(Scope *sc)
// FIXME: LDC // FIXME: LDC
// sc->module->toModuleUnittest(); // sc->module->toModuleUnittest();
} }
#endif
/* Remember Scope for later instantiations, but make /* Remember Scope for later instantiations, but make
* a copy since attributes can change. * a copy since attributes can change.
*/ */
if (!this->scope) if (!this->scope)
{ this->scope = new Scope(*sc); {
this->scope = new Scope(*sc);
this->scope->setNoFree(); this->scope->setNoFree();
} }
@@ -618,6 +608,9 @@ void TemplateDeclaration::semantic(Scope *sc)
if (!parent) if (!parent)
parent = sc->parent; parent = sc->parent;
isstatic = toParent()->isModule() ||
toParent()->isFuncDeclaration() && (scope->stc & STCstatic);
protection = sc->protection; protection = sc->protection;
if (global.params.doDocComments) if (global.params.doDocComments)
@@ -644,7 +637,8 @@ void TemplateDeclaration::semantic(Scope *sc)
tp->semantic(paramscope, parameters); tp->semantic(paramscope, parameters);
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter()) if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
{ error("template tuple parameter must be last one"); {
error("template tuple parameter must be last one");
errors = true; errors = true;
} }
} }
@@ -904,7 +898,6 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
} }
} }
#if DMDV2
if (m && constraint && !flag) if (m && constraint && !flag)
{ {
/* Check to see if constraint is satisfied. /* Check to see if constraint is satisfied.
@@ -979,16 +972,15 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
goto Lnomatch; goto Lnomatch;
e = e->ctfeInterpret(); e = e->ctfeInterpret();
if (e->isBool(TRUE)) if (e->isBool(true))
; ;
else if (e->isBool(FALSE)) else if (e->isBool(false))
goto Lnomatch; goto Lnomatch;
else else
{ {
e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
} }
} }
#endif
#if LOGM #if LOGM
// Print out the results // Print out the results
@@ -1135,8 +1127,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
unsigned wildmatch = 0; unsigned wildmatch = 0;
TemplateParameters *inferparams = parameters; TemplateParameters *inferparams = parameters;
TypeFunction *tf = (TypeFunction *)fd->type;
#if 0 #if 0
printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars());
for (size_t i = 0; i < (fargs ? fargs->dim : 0); i++) for (size_t i = 0; i < (fargs ? fargs->dim : 0); i++)
@@ -1157,7 +1147,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
dedtypes.setDim(parameters->dim); dedtypes.setDim(parameters->dim);
dedtypes.zero(); dedtypes.zero();
if (errors) if (errors || f->errors)
return MATCHnomatch; return MATCHnomatch;
// Set up scope for parameters // Set up scope for parameters
@@ -1222,11 +1212,10 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
for (size_t i = 0; i < n; i++) for (size_t i = 0; i < n; i++)
{ assert(i < parameters->dim); { assert(i < parameters->dim);
TemplateParameter *tp = (*parameters)[i];
MATCH m; MATCH m;
Declaration *sparam = NULL; Declaration *sparam = NULL;
m = tp->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, &sparam); m = (*parameters)[i]->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m); //printf("\tdeduceType m = %d\n", m);
if (m == MATCHnomatch) if (m == MATCHnomatch)
goto Lnomatch; goto Lnomatch;
@@ -1312,15 +1301,14 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
} }
} }
#if DMDV2
if (tthis) if (tthis)
{ {
bool hasttp = false; bool hasttp = false;
// Match 'tthis' to any TemplateThisParameter's // Match 'tthis' to any TemplateThisParameter's
for (size_t i = 0; i < parameters->dim; i++) for (size_t i = 0; i < parameters->dim; i++)
{ TemplateParameter *tp = (*parameters)[i]; {
TemplateThisParameter *ttp = tp->isTemplateThisParameter(); TemplateThisParameter *ttp = (*parameters)[i]->isTemplateThisParameter();
if (ttp) if (ttp)
{ hasttp = true; { hasttp = true;
@@ -1336,7 +1324,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
// Match attributes of tthis against attributes of fd // Match attributes of tthis against attributes of fd
if (fd->type && !fd->isCtorDeclaration()) if (fd->type && !fd->isCtorDeclaration())
{ {
unsigned mod = fd->type->mod; unsigned char mod = fd->type->mod;
StorageClass stc = scope->stc | fd->storage_class2; StorageClass stc = scope->stc | fd->storage_class2;
// Propagate parent storage class (see bug 5504) // Propagate parent storage class (see bug 5504)
Dsymbol *p = parent; Dsymbol *p = parent;
@@ -1360,7 +1348,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
if (mod & MODconst) if (mod & MODconst)
mod &= ~STCwild; mod &= ~STCwild;
unsigned thismod = tthis->mod; unsigned char thismod = tthis->mod;
if (hasttp) if (hasttp)
mod = MODmerge(thismod, mod); mod = MODmerge(thismod, mod);
if (thismod != mod) if (thismod != mod)
@@ -1372,7 +1360,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
} }
} }
} }
#endif
// Loop through the function parameters // Loop through the function parameters
{ {
@@ -1667,7 +1654,6 @@ Lretry:
#endif #endif
Type *argtype = farg->type; Type *argtype = farg->type;
#if DMDV2
/* Allow expressions that have CT-known boundaries and type [] to match with [dim] /* Allow expressions that have CT-known boundaries and type [] to match with [dim]
*/ */
Type *taai; Type *taai;
@@ -1699,8 +1685,7 @@ Lretry:
*/ */
if (farg->op == TOKfunction) if (farg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)farg; { FuncExp *fe = (FuncExp *)farg;
Type *tp = prmtype; Expression *e = fe->inferType(prmtype, 1, paramscope, inferparams);
Expression *e = fe->inferType(tp, 1, paramscope, inferparams);
if (!e) if (!e)
goto Lvarargs; goto Lvarargs;
farg = e; farg = e;
@@ -1719,7 +1704,6 @@ Lretry:
{ {
argtype = argtype->mutableOf(); argtype = argtype->mutableOf();
} }
#endif
if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs) if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs)
goto Lvarargs; goto Lvarargs;
@@ -1741,7 +1725,6 @@ Lretry:
if (!m) if (!m)
{ Type *tbp = prmtype->toBasetype(); { Type *tbp = prmtype->toBasetype();
Type *tba = farg->type->toBasetype(); Type *tba = farg->type->toBasetype();
AggregateDeclaration *ad;
if (tbp->ty == Tdelegate) if (tbp->ty == Tdelegate)
{ {
TypeDelegate *td = (TypeDelegate *)prmtype->toBasetype(); TypeDelegate *td = (TypeDelegate *)prmtype->toBasetype();
@@ -1755,23 +1738,18 @@ Lretry:
} }
//printf("\tm2 = %d\n", m); //printf("\tm2 = %d\n", m);
} }
else if (tba->ty == Tclass) else if (AggregateDeclaration *ad = isAggregate(tba))
{ {
ad = ((TypeClass *)tba)->sym;
goto Lad;
}
else if (tba->ty == Tstruct)
{
ad = ((TypeStruct *)tba)->sym;
Lad:
if (ad->aliasthis) if (ad->aliasthis)
{ /* If a semantic error occurs while doing alias this, {
/* If a semantic error occurs while doing alias this,
* eg purity(bug 7295), just regard it as not a match. * eg purity(bug 7295), just regard it as not a match.
*/ */
unsigned olderrors = global.startGagging(); unsigned olderrors = global.startGagging();
Expression *e = resolveAliasThis(sc, farg); Expression *e = resolveAliasThis(sc, farg);
if (!global.endGagging(olderrors)) if (!global.endGagging(olderrors))
{ farg = e; {
farg = e;
goto Lretry; goto Lretry;
} }
} }
@@ -1881,9 +1859,8 @@ Lretry:
if (arg->op == TOKfunction) if (arg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)arg; { FuncExp *fe = (FuncExp *)arg;
Type *tp = tb->nextOf();
Expression *e = fe->inferType(tp, 1, paramscope, inferparams); Expression *e = fe->inferType(tb->nextOf(), 1, paramscope, inferparams);
if (!e) if (!e)
goto Lnomatch; goto Lnomatch;
arg = e; arg = e;
@@ -1992,7 +1969,6 @@ Lmatch:
} }
} }
#if DMDV2
if (constraint) if (constraint)
{ {
/* Check to see if constraint is satisfied. /* Check to see if constraint is satisfied.
@@ -2037,7 +2013,6 @@ Lmatch:
int nerrors = global.errors; int nerrors = global.errors;
FuncDeclaration *fd = f;
Dsymbol *s = parent; Dsymbol *s = parent;
while (s->isTemplateInstance() || s->isTemplateMixin()) while (s->isTemplateInstance() || s->isTemplateMixin())
s = s->parent; s = s->parent;
@@ -2066,16 +2041,15 @@ Lmatch:
goto Lnomatch; goto Lnomatch;
e = e->ctfeInterpret(); e = e->ctfeInterpret();
if (e->isBool(TRUE)) if (e->isBool(true))
; ;
else if (e->isBool(FALSE)) else if (e->isBool(false))
goto Lnomatch; goto Lnomatch;
else else
{ {
e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
} }
} }
#endif
#if 0 #if 0
for (i = 0; i < dedargs->dim; i++) for (i = 0; i < dedargs->dim; i++)
@@ -2251,10 +2225,13 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
static int fp(void *param, Dsymbol *s) static int fp(void *param, Dsymbol *s)
{ {
if (FuncDeclaration *fd = s->isFuncDeclaration()) if (!s->errors)
return ((ParamDeduce *)param)->fp(fd); {
if (TemplateDeclaration *td = s->isTemplateDeclaration()) if (FuncDeclaration *fd = s->isFuncDeclaration())
return ((ParamDeduce *)param)->fp(td); return ((ParamDeduce *)param)->fp(fd);
if (TemplateDeclaration *td = s->isTemplateDeclaration())
return ((ParamDeduce *)param)->fp(td);
}
return 0; return 0;
} }
int fp(FuncDeclaration *fd) int fp(FuncDeclaration *fd)
@@ -2378,7 +2355,11 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
if (td->semanticRun == PASSinit) if (td->semanticRun == PASSinit)
{ {
::error(loc, "forward reference to template %s", td->toChars()); ::error(loc, "forward reference to template %s", td->toChars());
goto Lerror; Lerror:
m->lastf = NULL;
m->count = 0;
m->last = MATCHnomatch;
return 1;
} }
FuncDeclaration *f; FuncDeclaration *f;
f = td->onemember ? td->onemember/*->toAlias()*/->isFuncDeclaration() : NULL; f = td->onemember ? td->onemember/*->toAlias()*/->isFuncDeclaration() : NULL;
@@ -2501,7 +2482,9 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
{ {
// Disambiguate by tf->callMatch // Disambiguate by tf->callMatch
TypeFunction *tf1 = (TypeFunction *)fd->type; TypeFunction *tf1 = (TypeFunction *)fd->type;
assert(tf1->ty == Tfunction);
TypeFunction *tf2 = (TypeFunction *)m->lastf->type; TypeFunction *tf2 = (TypeFunction *)m->lastf->type;
assert(tf2->ty == Tfunction);
MATCH c1 = tf1->callMatch(tthis_fd, fargs); MATCH c1 = tf1->callMatch(tthis_fd, fargs);
MATCH c2 = tf2->callMatch(tthis_best, fargs); MATCH c2 = tf2->callMatch(tthis_best, fargs);
//printf("2: c1 = %d, c2 = %d\n", c1, c2); //printf("2: c1 = %d, c2 = %d\n", c1, c2);
@@ -2542,12 +2525,6 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
continue; continue;
} }
return 0; return 0;
Lerror:
m->lastf = NULL;
m->count = 0;
m->last = MATCHnomatch;
return 1;
} }
}; };
ParamDeduce p; ParamDeduce p;
@@ -2604,6 +2581,8 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL; p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL;
TypeFunction *tf = (TypeFunction *)m->lastf->type; TypeFunction *tf = (TypeFunction *)m->lastf->type;
if (tf->ty == Terror)
goto Lerror;
assert(tf->ty == Tfunction); assert(tf->ty == Tfunction);
if (!tf->callMatch(p.tthis_best, fargs)) if (!tf->callMatch(p.tthis_best, fargs))
goto Lerror; goto Lerror;
@@ -2719,15 +2698,15 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
sc2->tinst = ti; sc2->tinst = ti;
{ {
Scope *sc = sc2; Scope *scx = sc2;
sc = sc->push(); scx = scx->push();
if (hasttp) if (hasttp)
fd->type = fd->type->addMod(tthis->mod); fd->type = fd->type->addMod(tthis->mod);
//printf("tthis = %s, fdtype = %s\n", tthis->toChars(), fd->type->toChars()); //printf("tthis = %s, fdtype = %s\n", tthis->toChars(), fd->type->toChars());
if (fd->isCtorDeclaration()) if (fd->isCtorDeclaration())
{ {
sc->flags |= SCOPEctor; scx->flags |= SCOPEctor;
Dsymbol *parent = toParent2(); Dsymbol *parent = toParent2();
Type *tret; Type *tret;
@@ -2739,7 +2718,7 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
else else
{ tret = ad->handle; { tret = ad->handle;
assert(tret); assert(tret);
tret = tret->addStorageClass(fd->storage_class | sc->stc); tret = tret->addStorageClass(fd->storage_class | scx->stc);
tret = tret->addMod(fd->type->mod); tret = tret->addMod(fd->type->mod);
} }
((TypeFunction *)fd->type)->next = tret; ((TypeFunction *)fd->type)->next = tret;
@@ -2747,9 +2726,9 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
((TypeFunction *)fd->type)->isref = 1; ((TypeFunction *)fd->type)->isref = 1;
//printf("fd->type = %s\n", fd->type->toChars()); //printf("fd->type = %s\n", fd->type->toChars());
} }
fd->type = fd->type->addSTC(sc->stc); fd->type = fd->type->addSTC(scx->stc);
fd->type = fd->type->semantic(fd->loc, sc); fd->type = fd->type->semantic(fd->loc, scx);
sc = sc->pop(); scx = scx->pop();
} }
//printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod); //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
//printf("fd->needThis() = %d\n", fd->needThis()); //printf("fd->needThis() = %d\n", fd->needThis());
@@ -2757,12 +2736,12 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
sc2->pop(); sc2->pop();
scope->pop(); scope->pop();
return fd; return fd->type->ty == Tfunction ? fd : NULL;
} }
bool TemplateDeclaration::hasStaticCtorOrDtor() bool TemplateDeclaration::hasStaticCtorOrDtor()
{ {
return FALSE; // don't scan uninstantiated templates return false; // don't scan uninstantiated templates
} }
void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -2771,6 +2750,88 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
if (onemember && onemember->isFuncDeclaration()) if (onemember && onemember->isFuncDeclaration())
buf->writestring("foo "); buf->writestring("foo ");
#endif #endif
if (hgs->hdrgen && members && members->dim == 1)
{
FuncDeclaration *fd = (*members)[0]->isFuncDeclaration();
if (fd && fd->type && fd->type->ty == Tfunction && fd->ident == ident)
{
TypeFunction *tf = (TypeFunction *)fd->type;
tf->toCBufferWithAttributes(buf, ident, hgs, tf, this);
if (constraint)
{
buf->writestring(" if (");
constraint->toCBuffer(buf, hgs);
buf->writeByte(')');
}
hgs->tpltMember++;
fd->bodyToCBuffer(buf, hgs);
hgs->tpltMember--;
return;
}
AggregateDeclaration *ad = (*members)[0]->isAggregateDeclaration();
if (ad)
{
buf->writestring(ad->kind());
buf->writeByte(' ');
buf->writestring(ident->toChars());
buf->writeByte('(');
for (size_t i = 0; i < parameters->dim; i++)
{
TemplateParameter *tp = (*parameters)[i];
if (hgs->ddoc)
tp = (*origParameters)[i];
if (i)
buf->writestring(", ");
tp->toCBuffer(buf, hgs);
}
buf->writeByte(')');
if (constraint)
{
buf->writestring(" if (");
constraint->toCBuffer(buf, hgs);
buf->writeByte(')');
}
ClassDeclaration *cd = ad->isClassDeclaration();
if (cd && cd->baseclasses->dim)
{
buf->writestring(" : ");
for (size_t i = 0; i < cd->baseclasses->dim; i++)
{
BaseClass *b = (*cd->baseclasses)[i];
if (i)
buf->writestring(", ");
b->type->toCBuffer(buf, NULL, hgs);
}
}
hgs->tpltMember++;
if (ad->members)
{
buf->writenl();
buf->writeByte('{');
buf->writenl();
buf->level++;
for (size_t i = 0; i < ad->members->dim; i++)
{
Dsymbol *s = (*ad->members)[i];
s->toCBuffer(buf, hgs);
}
buf->level--;
buf->writestring("}");
}
else
buf->writeByte(';');
buf->writenl();
hgs->tpltMember--;
return;
}
}
if (hgs->ddoc) if (hgs->ddoc)
buf->writestring(kind()); buf->writestring(kind());
else else
@@ -2788,13 +2849,12 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
tp->toCBuffer(buf, hgs); tp->toCBuffer(buf, hgs);
} }
buf->writeByte(')'); buf->writeByte(')');
#if DMDV2
if (constraint) if (constraint)
{ buf->writestring(" if ("); {
buf->writestring(" if (");
constraint->toCBuffer(buf, hgs); constraint->toCBuffer(buf, hgs);
buf->writeByte(')'); buf->writeByte(')');
} }
#endif
if (hgs->hdrgen) if (hgs->hdrgen)
{ {
@@ -2817,7 +2877,11 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
char *TemplateDeclaration::toChars() char *TemplateDeclaration::toChars()
{ OutBuffer buf; {
if (literal)
return Dsymbol::toChars();
OutBuffer buf;
HdrGenState hgs; HdrGenState hgs;
memset(&hgs, 0, sizeof(hgs)); memset(&hgs, 0, sizeof(hgs));
@@ -2833,7 +2897,8 @@ char *TemplateDeclaration::toChars()
buf.writeByte(')'); buf.writeByte(')');
if (onemember) if (onemember)
{ /* Bugzilla 9406: {
/* Bugzilla 9406:
* onemember->toAlias() might run semantic, so should not call it in stringizing * onemember->toAlias() might run semantic, so should not call it in stringizing
*/ */
FuncDeclaration *fd = onemember->isFuncDeclaration(); FuncDeclaration *fd = onemember->isFuncDeclaration();
@@ -2845,13 +2910,12 @@ char *TemplateDeclaration::toChars()
} }
} }
#if DMDV2
if (constraint) if (constraint)
{ buf.writestring(" if ("); {
buf.writestring(" if (");
constraint->toCBuffer(&buf, &hgs); constraint->toCBuffer(&buf, &hgs);
buf.writeByte(')'); buf.writeByte(')');
} }
#endif
buf.writeByte(0); buf.writeByte(0);
return (char *)buf.extractData(); return (char *)buf.extractData();
} }
@@ -3348,7 +3412,12 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
if (ty != tparam->ty) if (ty != tparam->ty)
{ {
#if DMDV2 if (Dsymbol *sym = toDsymbol(sc))
{
if (sym->isforwardRef() && !tparam->deco)
goto Lnomatch;
}
// Can't instantiate AssociativeArray!() without a scope // Can't instantiate AssociativeArray!() without a scope
if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc) if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc)
((TypeAArray*)tparam)->sc = sc; ((TypeAArray*)tparam)->sc = sc;
@@ -3361,9 +3430,6 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
m = at->deduceType(sc, tparam, parameters, dedtypes, wildmatch); m = at->deduceType(sc, tparam, parameters, dedtypes, wildmatch);
} }
return m; return m;
#else
return implicitConvTo(tparam);
#endif
} }
if (nextOf()) if (nextOf())
@@ -3380,13 +3446,10 @@ Lexact:
Lnomatch: Lnomatch:
return MATCHnomatch; return MATCHnomatch;
#if DMDV2
Lconst: Lconst:
return MATCHconst; return MATCHconst;
#endif
} }
#if DMDV2
MATCH TypeVector::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, MATCH TypeVector::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes, unsigned *wildmatch) Objects *dedtypes, unsigned *wildmatch)
{ {
@@ -3401,9 +3464,7 @@ MATCH TypeVector::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
} }
return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch); return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch);
} }
#endif
#if DMDV2
MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes, unsigned *wildmatch) Objects *dedtypes, unsigned *wildmatch)
{ {
@@ -3414,7 +3475,6 @@ MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
#endif #endif
return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch); return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch);
} }
#endif
MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes, unsigned *wildmatch) Objects *dedtypes, unsigned *wildmatch)
@@ -3628,12 +3688,12 @@ MATCH TypeInstance::deduceType(Scope *sc,
printf("\tthis = %d, ", ty); print(); printf("\tthis = %d, ", ty); print();
printf("\ttparam = %d, ", tparam->ty); tparam->print(); printf("\ttparam = %d, ", tparam->ty); tparam->print();
#endif #endif
TemplateDeclaration *tempdecl = tempinst->tempdecl->isTemplateDeclaration();
assert(tempdecl);
// Extra check // Extra check
if (tparam && tparam->ty == Tinstance) if (tparam && tparam->ty == Tinstance && tempinst->tempdecl)
{ {
TemplateDeclaration *tempdecl = tempinst->tempdecl->isTemplateDeclaration();
assert(tempdecl);
TypeInstance *tp = (TypeInstance *)tparam; TypeInstance *tp = (TypeInstance *)tparam;
//printf("tempinst->tempdecl = %p\n", tempdecl); //printf("tempinst->tempdecl = %p\n", tempdecl);
@@ -3816,8 +3876,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
goto Le; goto Le;
goto Lnomatch; goto Lnomatch;
} }
TemplateParameter *tp = (*parameters)[j]; if (!(*parameters)[j]->matchArg(sc, e1, j, parameters, dedtypes, NULL))
if (!tp->matchArg(sc, e1, j, parameters, dedtypes, NULL))
goto Lnomatch; goto Lnomatch;
} }
else if (s1 && s2) else if (s1 && s2)
@@ -3836,8 +3895,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
goto Ls; goto Ls;
goto Lnomatch; goto Lnomatch;
} }
TemplateParameter *tp = (*parameters)[j]; if (!(*parameters)[j]->matchArg(sc, s1, j, parameters, dedtypes, NULL))
if (!tp->matchArg(sc, s1, j, parameters, dedtypes, NULL))
goto Lnomatch; goto Lnomatch;
} }
else else
@@ -3899,6 +3957,8 @@ MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
TypeStruct *tp = (TypeStruct *)tparam; TypeStruct *tp = (TypeStruct *)tparam;
//printf("\t%d\n", (MATCH) implicitConvTo(tp)); //printf("\t%d\n", (MATCH) implicitConvTo(tp));
if (wildmatch && wildConvTo(tparam))
return MATCHconst;
return implicitConvTo(tp); return implicitConvTo(tp);
} }
return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch); return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch);
@@ -4084,6 +4144,8 @@ MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *paramet
TypeClass *tp = (TypeClass *)tparam; TypeClass *tp = (TypeClass *)tparam;
//printf("\t%d\n", (MATCH) implicitConvTo(tp)); //printf("\t%d\n", (MATCH) implicitConvTo(tp));
if (wildmatch && wildConvTo(tparam))
return MATCHconst;
return implicitConvTo(tp); return implicitConvTo(tp);
} }
return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch); return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch);
@@ -4118,12 +4180,10 @@ TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter()
return NULL; return NULL;
} }
#if DMDV2
TemplateThisParameter *TemplateParameter::isTemplateThisParameter() TemplateThisParameter *TemplateParameter::isTemplateThisParameter()
{ {
return NULL; return NULL;
} }
#endif
/******************************************* /*******************************************
* Match to a particular TemplateParameter. * Match to a particular TemplateParameter.
@@ -4343,12 +4403,13 @@ void TemplateTypeParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
void *TemplateTypeParameter::dummyArg() void *TemplateTypeParameter::dummyArg()
{ Type *t; {
Type *t;
if (specType) if (specType)
t = specType; t = specType;
else else
{ // Use this for alias-parameter's too (?) {
// Use this for alias-parameter's too (?)
if (!tdummy) if (!tdummy)
tdummy = new TypeIdentifier(loc, ident); tdummy = new TypeIdentifier(loc, ident);
t = tdummy; t = tdummy;
@@ -4378,7 +4439,6 @@ RootObject *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc)
/* ======================== TemplateThisParameter =========================== */ /* ======================== TemplateThisParameter =========================== */
#if DMDV2
// this-parameter // this-parameter
TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident, TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident,
@@ -4408,7 +4468,6 @@ void TemplateThisParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("this "); buf->writestring("this ");
TemplateTypeParameter::toCBuffer(buf, hgs); TemplateTypeParameter::toCBuffer(buf, hgs);
} }
#endif
/* ======================== TemplateAliasParameter ========================== */ /* ======================== TemplateAliasParameter ========================== */
@@ -4982,9 +5041,7 @@ RootObject *TemplateValueParameter::defaultArg(Loc loc, Scope *sc)
e = e->syntaxCopy(); e = e->syntaxCopy();
e = e->semantic(sc); e = e->semantic(sc);
e = resolveProperties(sc, e); e = resolveProperties(sc, e);
#if DMDV2
e = e->resolveLoc(loc, sc); e = e->resolveLoc(loc, sc);
#endif
} }
return e; return e;
} }
@@ -5151,6 +5208,7 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->instantiatingModule = NULL; this->instantiatingModule = NULL;
this->inst = NULL; this->inst = NULL;
this->tinst = NULL; this->tinst = NULL;
this->deferred = NULL;
this->argsym = NULL; this->argsym = NULL;
this->aliasdecl = NULL; this->aliasdecl = NULL;
this->semantictiargsdone = false; this->semantictiargsdone = false;
@@ -5185,6 +5243,7 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
this->instantiatingModule = NULL; this->instantiatingModule = NULL;
this->inst = NULL; this->inst = NULL;
this->tinst = NULL; this->tinst = NULL;
this->deferred = NULL;
this->argsym = NULL; this->argsym = NULL;
this->aliasdecl = NULL; this->aliasdecl = NULL;
this->semantictiargsdone = true; this->semantictiargsdone = true;
@@ -5246,9 +5305,11 @@ void TemplateInstance::semantic(Scope *sc)
void TemplateInstance::expandMembers(Scope *sc2) void TemplateInstance::expandMembers(Scope *sc2)
{ {
for (size_t i = 0; i < members->dim; i++) for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i]; {
Dsymbol *s = (*members)[i];
s->setScope(sc2); s->setScope(sc2);
} }
for (size_t i = 0; i < members->dim; i++) for (size_t i = 0; i < members->dim; i++)
{ {
Dsymbol *s = (*members)[i]; Dsymbol *s = (*members)[i];
@@ -5402,7 +5463,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
if (tempdecl->ismixin) if (tempdecl->ismixin)
error("mixin templates are not regular templates"); error("mixin templates are not regular templates");
hasNestedArgs(tiargs); hasNestedArgs(tiargs, tempdecl->isstatic);
arrayCheckRecursiveExpansion(&tdtypes, tempdecl, sc); arrayCheckRecursiveExpansion(&tdtypes, tempdecl, sc);
@@ -5521,10 +5582,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
Module *m = (Module *)s; Module *m = (Module *)s;
if (!m->isRoot()) if (!m->isRoot())
{ {
//if (tinst && tinst->objFileModule) m = m->importedFrom;
// m = tinst->objFileModule;
//else
m = m->importedFrom;
} }
//printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars());
a = m->members; a = m->members;
@@ -5551,7 +5609,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
#endif #endif
// Copy the syntax trees from the TemplateDeclaration // Copy the syntax trees from the TemplateDeclaration
if (members && speculative) if (members && speculative && !errors)
{} // Don't copy again so they were previously created. {} // Don't copy again so they were previously created.
else else
members = Dsymbol::arraySyntaxCopy(tempdecl->members); members = Dsymbol::arraySyntaxCopy(tempdecl->members);
@@ -5680,6 +5738,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
sc2->parent = /*enclosing ? sc->parent :*/ this; sc2->parent = /*enclosing ? sc->parent :*/ this;
sc2->tinst = this; sc2->tinst = this;
sc2->speculative = speculative; sc2->speculative = speculative;
if (enclosing && tempdecl->isstatic)
sc2->stc &= ~STCstatic;
tryExpandMembers(sc2); tryExpandMembers(sc2);
@@ -5743,10 +5803,64 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
semantic2(sc2); semantic2(sc2);
} }
if (sc->func) if (sc->func && aliasdecl && aliasdecl->toAlias()->isFuncDeclaration())
{ {
/* Template function instantiation should run semantic3 immediately
* for attribute inference.
*/
//printf("function semantic3 %s inside %s\n", toChars(), sc->func->toChars());
trySemantic3(sc2); trySemantic3(sc2);
} }
else if (sc->func && !tinst)
{
/* If a template is instantiated inside function, the whole instantiation
* should be done at that position. But, immediate running semantic3 of
* dependent templates may cause unresolved forward reference (Bugzilla 9050).
* To avoid the issue, don't run semantic3 until semantic and semantic2 done.
*/
TemplateInstances deferred;
this->deferred = &deferred;
//printf("Run semantic3 on %s\n", toChars());
trySemantic3(sc2);
for (size_t i = 0; i < deferred.dim; i++)
{
//printf("+ run deferred semantic3 on %s\n", deferred[i]->toChars());
deferred[i]->semantic3(NULL);
}
this->deferred = NULL;
}
else if (tinst)
{
TemplateInstance *ti = tinst;
int nest = 0;
while (ti && !ti->deferred && ti->tinst)
{
ti = ti->tinst;
if (++nest > 500)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
}
if (ti && ti->deferred)
{
//printf("deferred semantic3 of %p %s, ti = %s, ti->deferred = %p\n", this, toChars(), ti->toChars());
for (size_t i = 0; ; i++)
{
if (i == ti->deferred->dim)
{
ti->deferred->push(this);
break;
}
if ((*ti->deferred)[i] == this)
break;
}
}
}
Laftersemantic: Laftersemantic:
sc2->pop(); sc2->pop();
@@ -5756,7 +5870,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
// Give additional context info if error occurred during instantiation // Give additional context info if error occurred during instantiation
if (global.errors != errorsave) if (global.errors != errorsave)
{ {
error(loc, "error instantiating"); if (!tempdecl->literal)
error(loc, "error instantiating");
if (tinst) if (tinst)
{ tinst->printInstantiationTrace(); { tinst->printInstantiationTrace();
} }
@@ -6571,7 +6686,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
* Sets enclosing property if so, and returns != 0; * Sets enclosing property if so, and returns != 0;
*/ */
bool TemplateInstance::hasNestedArgs(Objects *args) bool TemplateInstance::hasNestedArgs(Objects *args, bool isstatic)
{ {
int nested = 0; int nested = 0;
//printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
@@ -6656,15 +6771,13 @@ bool TemplateInstance::hasNestedArgs(Objects *args)
(ad && ad->isNested()) || (ad && ad->isNested()) ||
#endif #endif
(d && !d->isDataseg() && (d && !d->isDataseg() &&
#if DMDV2
!(d->storage_class & STCmanifest) && !(d->storage_class & STCmanifest) &&
#endif
(!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
!isTemplateMixin() !isTemplateMixin()
)) ))
{ {
// if module level template // if module level template
if (tempdecl->toParent()->isModule()) if (isstatic)
{ {
Dsymbol *dparent = sa->toParent2(); Dsymbol *dparent = sa->toParent2();
if (!enclosing) if (!enclosing)
@@ -6699,7 +6812,7 @@ bool TemplateInstance::hasNestedArgs(Objects *args)
} }
else if (va) else if (va)
{ {
nested |= hasNestedArgs(&va->objects); nested |= hasNestedArgs(&va->objects, isstatic);
} }
} }
//printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested); //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested);
@@ -7058,6 +7171,8 @@ void TemplateInstance::toCBufferTiargs(OutBuffer *buf, HdrGenState *hgs)
buf->writeByte('!'); buf->writeByte('!');
if (nest) if (nest)
buf->writestring("(...)"); buf->writestring("(...)");
else if (!tiargs)
buf->writestring("()");
else else
{ {
if (tiargs->dim == 1) if (tiargs->dim == 1)
@@ -7192,7 +7307,7 @@ int TemplateInstance::compare(RootObject *o)
if (fargs) if (fargs)
{ {
FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration(); FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration();
if (fd) if (fd && !fd->errors)
{ {
Parameters *fparameters = fd->getParameters(NULL); Parameters *fparameters = fd->getParameters(NULL);
size_t nfparams = Parameter::dim(fparameters); // Num function parameters size_t nfparams = Parameter::dim(fparameters); // Num function parameters
@@ -7200,8 +7315,6 @@ int TemplateInstance::compare(RootObject *o)
{ {
Parameter *fparam = Parameter::getNth(fparameters, j); Parameter *fparam = Parameter::getNth(fparameters, j);
Expression *farg = (*fargs)[j]; Expression *farg = (*fargs)[j];
if (Expression *e = farg->isTemp())
farg = e;
if (fparam->storageClass & STCauto) // if "auto ref" if (fparam->storageClass & STCauto) // if "auto ref"
{ {
if (farg->isLvalue()) if (farg->isLvalue())
@@ -7278,18 +7391,18 @@ bool TemplateMixin::findTemplateDeclaration(Scope *sc)
*/ */
if (os) if (os)
{ {
Dsymbol *s = NULL; Dsymbol *ds = NULL;
for (size_t i = 0; i < os->a.dim; i++) for (size_t i = 0; i < os->a.dim; i++)
{ {
Dsymbol *s2 = os->a[i]->isTemplateDeclaration(); Dsymbol *s2 = os->a[i]->isTemplateDeclaration();
if (s2) if (s2)
{ {
if (s) if (ds)
{ {
tempdecl = os; tempdecl = os;
break; break;
} }
s = s2; ds = s2;
} }
} }
} }
@@ -7467,7 +7580,7 @@ void TemplateMixin::semantic(Scope *sc)
} }
// Copy the syntax trees from the TemplateDeclaration // Copy the syntax trees from the TemplateDeclaration
if (scx && members) if (scx && members && !errors)
{} // Don't copy again so they were previously created. {} // Don't copy again so they were previously created.
else else
members = Dsymbol::arraySyntaxCopy(tempdecl->members); members = Dsymbol::arraySyntaxCopy(tempdecl->members);
@@ -7529,6 +7642,12 @@ void TemplateMixin::semantic(Scope *sc)
fatal(); fatal();
} }
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
s->setScope(sc2);
}
for (size_t i = 0; i < members->dim; i++) for (size_t i = 0; i < members->dim; i++)
{ {
Dsymbol *s = (*members)[i]; Dsymbol *s = (*members)[i];
@@ -7580,6 +7699,7 @@ void TemplateMixin::semantic(Scope *sc)
if (global.errors != errorsave) if (global.errors != errorsave)
{ {
error("error instantiating"); error("error instantiating");
errors = true;
} }
sc2->pop(); sc2->pop();
+7 -14
View File
@@ -71,8 +71,9 @@ public:
Dsymbol *onemember; // if !=NULL then one member of this template Dsymbol *onemember; // if !=NULL then one member of this template
int literal; // this template declaration is a literal bool literal; // this template declaration is a literal
int ismixin; // template declaration is only to be used as a mixin bool ismixin; // template declaration is only to be used as a mixin
bool isstatic; // this is static template declaration
PROT protection; PROT protection;
struct Previous struct Previous
@@ -83,7 +84,7 @@ public:
Previous *previous; // threaded list of previous instantiation attempts on stack Previous *previous; // threaded list of previous instantiation attempts on stack
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
Expression *constraint, Dsymbols *decldefs, int ismixin); Expression *constraint, Dsymbols *decldefs, bool ismixin = false, bool literal = false);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc); void semantic(Scope *sc);
bool overloadInsert(Dsymbol *s); bool overloadInsert(Dsymbol *s);
@@ -145,9 +146,7 @@ public:
virtual TemplateTypeParameter *isTemplateTypeParameter(); virtual TemplateTypeParameter *isTemplateTypeParameter();
virtual TemplateValueParameter *isTemplateValueParameter(); virtual TemplateValueParameter *isTemplateValueParameter();
virtual TemplateAliasParameter *isTemplateAliasParameter(); virtual TemplateAliasParameter *isTemplateAliasParameter();
#if DMDV2
virtual TemplateThisParameter *isTemplateThisParameter(); virtual TemplateThisParameter *isTemplateThisParameter();
#endif
virtual TemplateTupleParameter *isTemplateTupleParameter(); virtual TemplateTupleParameter *isTemplateTupleParameter();
virtual TemplateParameter *syntaxCopy() = 0; virtual TemplateParameter *syntaxCopy() = 0;
@@ -198,7 +197,6 @@ public:
void *dummyArg(); void *dummyArg();
}; };
#if DMDV2
class TemplateThisParameter : public TemplateTypeParameter class TemplateThisParameter : public TemplateTypeParameter
{ {
public: public:
@@ -212,7 +210,6 @@ public:
TemplateParameter *syntaxCopy(); TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
}; };
#endif
class TemplateValueParameter : public TemplateParameter class TemplateValueParameter : public TemplateParameter
{ {
@@ -324,12 +321,8 @@ public:
hash_t hash; // cached result of hashCode() hash_t hash; // cached result of hashCode()
Expressions *fargs; // for function template, these are the function arguments Expressions *fargs; // for function template, these are the function arguments
Module *instantiatingModule; // the top module that instantiated this instance Module *instantiatingModule; // the top module that instantiated this instance
#ifdef IN_GCC
/* On some targets, it is necessary to know whether a symbol TemplateInstances* deferred;
will be emitted in the output or not before the symbol
is used. This can be different from getModule(). */
Module * objFileModule;
#endif
TemplateInstance(Loc loc, Identifier *temp_id); TemplateInstance(Loc loc, Identifier *temp_id);
TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs); TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
@@ -363,7 +356,7 @@ public:
bool semanticTiargs(Scope *sc); bool semanticTiargs(Scope *sc);
bool findBestMatch(Scope *sc, Expressions *fargs); bool findBestMatch(Scope *sc, Expressions *fargs);
bool needsTypeInference(Scope *sc, int flag = 0); bool needsTypeInference(Scope *sc, int flag = 0);
bool hasNestedArgs(Objects *tiargs); bool hasNestedArgs(Objects *tiargs, bool isstatic);
void declareParameters(Scope *sc); void declareParameters(Scope *sc);
Identifier *genIdent(Objects *args); Identifier *genIdent(Objects *args);
void expandMembers(Scope *sc); void expandMembers(Scope *sc);
+102 -67
View File
@@ -38,7 +38,6 @@
#define LOGSEMANTIC 0 #define LOGSEMANTIC 0
#if DMDV2
/************************************************ /************************************************
* Delegate to be passed to overloadApply() that looks * Delegate to be passed to overloadApply() that looks
@@ -93,6 +92,8 @@ static int fptraits(void *param, Dsymbol *s)
*/ */
static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions *unitTests) static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions *unitTests)
{ {
if (!symbols)
return;
for (size_t i = 0; i < symbols->dim; i++) for (size_t i = 0; i < symbols->dim; i++)
{ {
Dsymbol *symbol = (*symbols)[i]; Dsymbol *symbol = (*symbols)[i];
@@ -124,6 +125,81 @@ static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions
/************************ TraitsExp ************************************/ /************************ TraitsExp ************************************/
bool isTypeArithmetic(Type *t) { return t->isintegral() || t->isfloating(); }
bool isTypeFloating(Type *t) { return t->isfloating(); }
bool isTypeIntegral(Type *t) { return t->isintegral(); }
bool isTypeScalar(Type *t) { return t->isscalar(); }
bool isTypeUnsigned(Type *t) { return t->isunsigned(); }
bool isTypeAssociativeArray(Type *t) { return t->toBasetype()->ty == Taarray; }
bool isTypeStaticArray(Type *t) { return t->toBasetype()->ty == Tsarray; }
bool isTypeAbstractClass(Type *t) { return t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->isAbstract(); }
bool isTypeFinalClass(Type *t) { return t->toBasetype()->ty == Tclass && (((TypeClass *)t->toBasetype())->sym->storage_class & STCfinal) != 0; }
Expression *TraitsExp::isTypeX(bool (*fp)(Type *t))
{
int result = 0;
if (!args || !args->dim)
goto Lfalse;
for (size_t i = 0; i < args->dim; i++)
{
Type *t = getType((*args)[i]);
if (!t || !fp(t))
goto Lfalse;
}
result = 1;
Lfalse:
return new IntegerExp(loc, result, Type::tbool);
}
bool isFuncAbstractFunction(FuncDeclaration *f) { return f->isAbstract(); }
bool isFuncVirtualFunction(FuncDeclaration *f) { return f->isVirtual(); }
bool isFuncVirtualMethod(FuncDeclaration *f) { return f->isVirtualMethod(); }
bool isFuncFinalFunction(FuncDeclaration *f) { return f->isFinalFunc(); }
bool isFuncStaticFunction(FuncDeclaration *f) { return !f->needThis() && !f->isNested(); }
bool isFuncOverrideFunction(FuncDeclaration *f) { return f->isOverride(); }
Expression *TraitsExp::isFuncX(bool (*fp)(FuncDeclaration *f))
{
int result = 0;
if (!args || !args->dim)
goto Lfalse;
for (size_t i = 0; i < args->dim; i++)
{
Dsymbol *s = getDsymbol((*args)[i]);
if (!s)
goto Lfalse;
FuncDeclaration *f = s->isFuncDeclaration();
if (!f || !fp(f))
goto Lfalse;
}
result = 1;
Lfalse:
return new IntegerExp(loc, result, Type::tbool);
}
bool isDeclRef(Declaration *d) { return d->isRef(); }
bool isDeclOut(Declaration *d) { return d->isOut(); }
bool isDeclLazy(Declaration *d) { return (d->storage_class & STClazy) != 0; }
Expression *TraitsExp::isDeclX(bool (*fp)(Declaration *d))
{
int result = 0;
if (!args || !args->dim)
goto Lfalse;
for (size_t i = 0; i < args->dim; i++)
{
Dsymbol *s = getDsymbol((*args)[i]);
if (!s)
goto Lfalse;
Declaration *d = s->isDeclaration();
if (!d || !fp(d))
goto Lfalse;
}
result = 1;
Lfalse:
return new IntegerExp(loc, result, Type::tbool);
}
Expression *TraitsExp::semantic(Scope *sc) Expression *TraitsExp::semantic(Scope *sc)
{ {
#if LOGSEMANTIC #if LOGSEMANTIC
@@ -137,67 +213,41 @@ Expression *TraitsExp::semantic(Scope *sc)
size_t dim = args ? args->dim : 0; size_t dim = args ? args->dim : 0;
Declaration *d; Declaration *d;
#define ISTYPE(cond) \
for (size_t i = 0; i < dim; i++) \
{ Type *t = getType((*args)[i]); \
if (!t) \
goto Lfalse; \
if (!(cond)) \
goto Lfalse; \
} \
if (!dim) \
goto Lfalse; \
goto Ltrue;
#define ISDSYMBOL(cond) \
for (size_t i = 0; i < dim; i++) \
{ Dsymbol *s = getDsymbol((*args)[i]); \
if (!s) \
goto Lfalse; \
if (!(cond)) \
goto Lfalse; \
} \
if (!dim) \
goto Lfalse; \
goto Ltrue;
if (ident == Id::isArithmetic) if (ident == Id::isArithmetic)
{ {
ISTYPE(t->isintegral() || t->isfloating()) return isTypeX(&isTypeArithmetic);
} }
else if (ident == Id::isFloating) else if (ident == Id::isFloating)
{ {
ISTYPE(t->isfloating()) return isTypeX(&isTypeFloating);
} }
else if (ident == Id::isIntegral) else if (ident == Id::isIntegral)
{ {
ISTYPE(t->isintegral()) return isTypeX(&isTypeIntegral);
} }
else if (ident == Id::isScalar) else if (ident == Id::isScalar)
{ {
ISTYPE(t->isscalar()) return isTypeX(&isTypeScalar);
} }
else if (ident == Id::isUnsigned) else if (ident == Id::isUnsigned)
{ {
ISTYPE(t->isunsigned()) return isTypeX(&isTypeUnsigned);
} }
else if (ident == Id::isAssociativeArray) else if (ident == Id::isAssociativeArray)
{ {
ISTYPE(t->toBasetype()->ty == Taarray) return isTypeX(&isTypeAssociativeArray);
} }
else if (ident == Id::isStaticArray) else if (ident == Id::isStaticArray)
{ {
ISTYPE(t->toBasetype()->ty == Tsarray) return isTypeX(&isTypeStaticArray);
} }
else if (ident == Id::isAbstractClass) else if (ident == Id::isAbstractClass)
{ {
ISTYPE(t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->isAbstract()) return isTypeX(&isTypeAbstractClass);
} }
else if (ident == Id::isFinalClass) else if (ident == Id::isFinalClass)
{ {
ISTYPE(t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->storage_class & STCfinal) return isTypeX(&isTypeFinalClass);
} }
else if (ident == Id::isPOD) else if (ident == Id::isPOD)
{ {
@@ -251,41 +301,35 @@ Expression *TraitsExp::semantic(Scope *sc)
} }
else if (ident == Id::isAbstractFunction) else if (ident == Id::isAbstractFunction)
{ {
FuncDeclaration *f; return isFuncX(&isFuncAbstractFunction);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isAbstract())
} }
else if (ident == Id::isVirtualFunction) else if (ident == Id::isVirtualFunction)
{ {
FuncDeclaration *f; return isFuncX(&isFuncVirtualFunction);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isVirtual())
} }
else if (ident == Id::isVirtualMethod) else if (ident == Id::isVirtualMethod)
{ {
FuncDeclaration *f; return isFuncX(&isFuncVirtualMethod);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isVirtualMethod())
} }
else if (ident == Id::isFinalFunction) else if (ident == Id::isFinalFunction)
{ {
FuncDeclaration *f; return isFuncX(&isFuncFinalFunction);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinalFunc())
} }
#if DMDV2
else if (ident == Id::isStaticFunction) else if (ident == Id::isStaticFunction)
{ {
FuncDeclaration *f; return isFuncX(&isFuncStaticFunction);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && !f->needThis() && !f->isNested())
} }
else if (ident == Id::isRef) else if (ident == Id::isRef)
{ {
ISDSYMBOL((d = s->isDeclaration()) != NULL && d->isRef()) return isDeclX(&isDeclRef);
} }
else if (ident == Id::isOut) else if (ident == Id::isOut)
{ {
ISDSYMBOL((d = s->isDeclaration()) != NULL && d->isOut()) return isDeclX(&isDeclOut);
} }
else if (ident == Id::isLazy) else if (ident == Id::isLazy)
{ {
ISDSYMBOL((d = s->isDeclaration()) != NULL && d->storage_class & STClazy) return isDeclX(&isDeclLazy);
} }
else if (ident == Id::identifier) else if (ident == Id::identifier)
{ // Get identifier for symbol as a string literal { // Get identifier for symbol as a string literal
@@ -366,7 +410,6 @@ Expression *TraitsExp::semantic(Scope *sc)
} }
return (new DsymbolExp(loc, s))->semantic(sc); return (new DsymbolExp(loc, s))->semantic(sc);
} }
#endif
else if (ident == Id::hasMember || else if (ident == Id::hasMember ||
ident == Id::getMember || ident == Id::getMember ||
ident == Id::getOverloads || ident == Id::getOverloads ||
@@ -614,16 +657,11 @@ Expression *TraitsExp::semantic(Scope *sc)
(*exps)[i] = se; (*exps)[i] = se;
} }
#if DMDV1
Expression *e = new ArrayLiteralExp(loc, exps);
#endif
#if DMDV2
/* Making this a tuple is more flexible, as it can be statically unrolled. /* Making this a tuple is more flexible, as it can be statically unrolled.
* To make an array literal, enclose __traits in [ ]: * To make an array literal, enclose __traits in [ ]:
* [ __traits(allMembers, ...) ] * [ __traits(allMembers, ...) ]
*/ */
Expression *e = new TupleExp(loc, exps); Expression *e = new TupleExp(loc, exps);
#endif
e = e->semantic(sc); e = e->semantic(sc);
return e; return e;
} }
@@ -640,9 +678,9 @@ Expression *TraitsExp::semantic(Scope *sc)
unsigned errors = global.startGagging(); unsigned errors = global.startGagging();
unsigned oldspec = global.speculativeGag; unsigned oldspec = global.speculativeGag;
global.speculativeGag = global.gag; global.speculativeGag = global.gag;
sc = sc->push(); Scope *sc2 = sc->push();
sc->speculative = true; sc2->speculative = true;
sc->flags = sc->enclosing->flags & ~SCOPEctfe; // inherit without CTFEing sc2->flags = sc->flags & ~SCOPEctfe | SCOPEcompile;
bool err = false; bool err = false;
RootObject *o = (*args)[i]; RootObject *o = (*args)[i];
@@ -651,10 +689,10 @@ Expression *TraitsExp::semantic(Scope *sc)
if (!e && t) if (!e && t)
{ {
Dsymbol *s; Dsymbol *s;
t->resolve(loc, sc, &e, &t, &s); t->resolve(loc, sc2, &e, &t, &s);
if (t) if (t)
{ {
t->semantic(loc, sc); t->semantic(loc, sc2);
if (t->ty == Terror) if (t->ty == Terror)
err = true; err = true;
} }
@@ -663,13 +701,13 @@ Expression *TraitsExp::semantic(Scope *sc)
} }
if (e) if (e)
{ {
e = e->semantic(sc); e = e->semantic(sc2);
e = e->optimize(WANTvalue); e = e->optimize(WANTvalue);
if (e->op == TOKerror) if (e->op == TOKerror)
err = true; err = true;
} }
sc = sc->pop(); sc2->pop();
global.speculativeGag = oldspec; global.speculativeGag = oldspec;
if (global.endGagging(errors) || err) if (global.endGagging(errors) || err)
{ {
@@ -770,8 +808,7 @@ Expression *TraitsExp::semantic(Scope *sc)
} }
else if (ident == Id::isOverrideFunction) else if (ident == Id::isOverrideFunction)
{ {
FuncDeclaration *f; return isFuncX(&isFuncOverrideFunction);
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isOverride())
} }
else if(ident == Id::getVirtualIndex) else if(ident == Id::getVirtualIndex)
{ {
@@ -807,5 +844,3 @@ Lfalse:
Ltrue: Ltrue:
return new IntegerExp(loc, 1, Type::tbool); return new IntegerExp(loc, 1, Type::tbool);
} }
#endif
+9 -9
View File
@@ -70,7 +70,7 @@ static std::string getOutputName(bool const sharedLib)
if (Module::rootModule) if (Module::rootModule)
result = Module::rootModule->toChars(); result = Module::rootModule->toChars();
else if (global.params.objfiles->dim) else if (global.params.objfiles->dim)
result = FileName::removeExt(static_cast<char*>(global.params.objfiles->data[0])); result = FileName::removeExt(static_cast<const char*>(global.params.objfiles->data[0]));
else else
result = "a.out"; result = "a.out";
@@ -110,14 +110,14 @@ static int linkObjToBinaryGcc(bool sharedLib)
// object files // object files
for (unsigned i = 0; i < global.params.objfiles->dim; i++) for (unsigned i = 0; i < global.params.objfiles->dim; i++)
{ {
char *p = static_cast<char *>(global.params.objfiles->data[i]); const char *p = static_cast<const char *>(global.params.objfiles->data[i]);
args.push_back(p); args.push_back(p);
} }
// user libs // user libs
for (unsigned i = 0; i < global.params.libfiles->dim; i++) for (unsigned i = 0; i < global.params.libfiles->dim; i++)
{ {
char *p = static_cast<char *>(global.params.libfiles->data[i]); const char *p = static_cast<const char *>(global.params.libfiles->data[i]);
args.push_back(p); args.push_back(p);
} }
@@ -155,7 +155,7 @@ static int linkObjToBinaryGcc(bool sharedLib)
// additional linker switches // additional linker switches
for (unsigned i = 0; i < global.params.linkswitches->dim; i++) for (unsigned i = 0; i < global.params.linkswitches->dim; i++)
{ {
char *p = static_cast<char *>(global.params.linkswitches->data[i]); const char *p = static_cast<const char *>(global.params.linkswitches->data[i]);
// Don't push -l and -L switches using -Xlinker, but pass them directly // Don't push -l and -L switches using -Xlinker, but pass them directly
// to GCC. This makes sure user-defined paths take precedence over // to GCC. This makes sure user-defined paths take precedence over
// GCC's builtin LIBRARY_PATHs. // GCC's builtin LIBRARY_PATHs.
@@ -279,14 +279,14 @@ static int linkObjToBinaryWin(bool sharedLib)
// object files // object files
for (unsigned i = 0; i < global.params.objfiles->dim; i++) for (unsigned i = 0; i < global.params.objfiles->dim; i++)
{ {
char *p = static_cast<char *>(global.params.objfiles->data[i]); const char *p = static_cast<const char *>(global.params.objfiles->data[i]);
args.push_back(p); args.push_back(p);
} }
// user libs // user libs
for (unsigned i = 0; i < global.params.libfiles->dim; i++) for (unsigned i = 0; i < global.params.libfiles->dim; i++)
{ {
char *p = static_cast<char *>(global.params.libfiles->data[i]); const char *p = static_cast<const char *>(global.params.libfiles->data[i]);
args.push_back(p); args.push_back(p);
} }
@@ -302,7 +302,7 @@ static int linkObjToBinaryWin(bool sharedLib)
{ {
static const std::string LIBPATH("-L"); static const std::string LIBPATH("-L");
static const std::string LIB("-l"); static const std::string LIB("-l");
std::string str(static_cast<char *>(global.params.linkswitches->data[i])); std::string str(static_cast<const char *>(global.params.linkswitches->data[i]));
if (str.length() > 2) if (str.length() > 2)
{ {
if (std::equal(LIBPATH.begin(), LIBPATH.end(), str.begin())) if (std::equal(LIBPATH.begin(), LIBPATH.end(), str.begin()))
@@ -386,7 +386,7 @@ void createStaticLibrary()
if (Module::rootModule) if (Module::rootModule)
libName = Module::rootModule->toChars(); libName = Module::rootModule->toChars();
else if (global.params.objfiles->dim) else if (global.params.objfiles->dim)
libName = FileName::removeExt(static_cast<char*>(global.params.objfiles->data[0])); libName = FileName::removeExt(static_cast<const char*>(global.params.objfiles->data[0]));
else else
libName = "a.out"; libName = "a.out";
} }
@@ -406,7 +406,7 @@ void createStaticLibrary()
// object files // object files
for (unsigned i = 0; i < global.params.objfiles->dim; i++) for (unsigned i = 0; i < global.params.objfiles->dim; i++)
{ {
char *p = static_cast<char *>(global.params.objfiles->data[i]); const char *p = static_cast<const char *>(global.params.objfiles->data[i]);
args.push_back(p); args.push_back(p);
} }
+15 -18
View File
@@ -139,7 +139,7 @@ static void processVersions(std::vector<std::string>& list, const char* type,
} }
// Helper function to handle -of, -od, etc. // Helper function to handle -of, -od, etc.
static void initFromString(char*& dest, const cl::opt<std::string>& src) { static void initFromString(const char*& dest, const cl::opt<std::string>& src) {
dest = 0; dest = 0;
if (src.getNumOccurrences() != 0) { if (src.getNumOccurrences() != 0) {
if (src.empty()) if (src.empty())
@@ -370,7 +370,7 @@ static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &
{ {
for (unsigned i = 0; i < libs->dim; i++) for (unsigned i = 0; i < libs->dim; i++)
{ {
char* lib = static_cast<char *>(libs->data[i]); const char* lib = static_cast<const char *>(libs->data[i]);
char *arg = static_cast<char *>(mem.malloc(strlen(lib) + 3)); char *arg = static_cast<char *>(mem.malloc(strlen(lib) + 3));
strcpy(arg, "-l"); strcpy(arg, "-l");
strcpy(arg+2, lib); strcpy(arg+2, lib);
@@ -720,9 +720,6 @@ void genCmain(Scope *sc)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
mem.init(); // initialize storage allocator
mem.setStackBottom(&argv);
// stack trace on signals // stack trace on signals
llvm::sys::PrintStackTraceOnErrorSignal(); llvm::sys::PrintStackTraceOnErrorSignal();
@@ -818,7 +815,7 @@ int main(int argc, char **argv)
{ {
for (unsigned i = 0; i < global.params.imppath->dim; i++) for (unsigned i = 0; i < global.params.imppath->dim; i++)
{ {
char *path = static_cast<char *>(global.params.imppath->data[i]); const char *path = static_cast<const char *>(global.params.imppath->data[i]);
Strings *a = FileName::splitPath(path); Strings *a = FileName::splitPath(path);
if (a) if (a)
@@ -835,7 +832,7 @@ int main(int argc, char **argv)
{ {
for (unsigned i = 0; i < global.params.fileImppath->dim; i++) for (unsigned i = 0; i < global.params.fileImppath->dim; i++)
{ {
char *path = static_cast<char *>(global.params.fileImppath->data[i]); const char *path = static_cast<const char *>(global.params.fileImppath->data[i]);
Strings *a = FileName::splitPath(path); Strings *a = FileName::splitPath(path);
if (a) if (a)
@@ -861,7 +858,7 @@ int main(int argc, char **argv)
const char *ext; const char *ext;
const char *name; const char *name;
const char *p = static_cast<char *>(files.data[i]); const char *p = static_cast<const char *>(files.data[i]);
p = FileName::name(p); // strip path p = FileName::name(p); // strip path
ext = FileName::ext(p); ext = FileName::ext(p);
@@ -876,7 +873,7 @@ int main(int argc, char **argv)
Port::stricmp(ext, global.bc_ext) == 0) Port::stricmp(ext, global.bc_ext) == 0)
#endif #endif
{ {
global.params.objfiles->push(static_cast<char *>(files.data[i])); global.params.objfiles->push(static_cast<const char *>(files.data[i]));
continue; continue;
} }
@@ -888,39 +885,39 @@ int main(int argc, char **argv)
if (Port::stricmp(ext, "lib") == 0) if (Port::stricmp(ext, "lib") == 0)
#endif #endif
{ {
global.params.libfiles->push(static_cast<char *>(files.data[i])); global.params.libfiles->push(static_cast<const char *>(files.data[i]));
continue; continue;
} }
if (strcmp(ext, global.ddoc_ext) == 0) if (strcmp(ext, global.ddoc_ext) == 0)
{ {
global.params.ddocfiles->push(static_cast<char *>(files.data[i])); global.params.ddocfiles->push(static_cast<const char *>(files.data[i]));
continue; continue;
} }
if (FileName::equals(ext, global.json_ext)) if (FileName::equals(ext, global.json_ext))
{ {
global.params.doXGeneration = 1; global.params.doXGeneration = 1;
global.params.xfilename = static_cast<char *>(files.data[i]); global.params.xfilename = static_cast<const char *>(files.data[i]);
continue; continue;
} }
#if !POSIX #if !POSIX
if (Port::stricmp(ext, "res") == 0) if (Port::stricmp(ext, "res") == 0)
{ {
global.params.resfile = static_cast<char *>(files.data[i]); global.params.resfile = static_cast<const char *>(files.data[i]);
continue; continue;
} }
if (Port::stricmp(ext, "def") == 0) if (Port::stricmp(ext, "def") == 0)
{ {
global.params.deffile = static_cast<char *>(files.data[i]); global.params.deffile = static_cast<const char *>(files.data[i]);
continue; continue;
} }
if (Port::stricmp(ext, "exe") == 0) if (Port::stricmp(ext, "exe") == 0)
{ {
global.params.exefile = static_cast<char *>(files.data[i]); global.params.exefile = static_cast<const char *>(files.data[i]);
continue; continue;
} }
#endif #endif
@@ -953,14 +950,14 @@ int main(int argc, char **argv)
if (!*p) if (!*p)
{ {
Linvalid: Linvalid:
error("invalid file name '%s'", static_cast<char *>(files.data[i])); error("invalid file name '%s'", static_cast<const char *>(files.data[i]));
fatal(); fatal();
} }
name = p; name = p;
} }
id = Lexer::idPool(name); id = Lexer::idPool(name);
Module *m = new Module(static_cast<char *>(files.data[i]), id, global.params.doDocComments, global.params.doHdrGeneration); Module *m = new Module(static_cast<const char *>(files.data[i]), id, global.params.doDocComments, global.params.doHdrGeneration);
modules.push(m); modules.push(m);
} }
@@ -1168,7 +1165,7 @@ int main(int argc, char **argv)
{ {
Module *m = modules[0]; Module *m = modules[0];
char* oname; const char* oname;
const char* filename; const char* filename;
if ((oname = global.params.exefile) || (oname = global.params.objname)) if ((oname = global.params.exefile) || (oname = global.params.objname))
{ {
+1 -2
View File
@@ -17,10 +17,9 @@
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include <string>
template <typename TYPE> struct Array; template <typename TYPE> struct Array;
typedef Array<char> Strings; typedef Array<const char> Strings;
namespace opts { namespace opts {
namespace cl = llvm::cl; namespace cl = llvm::cl;