diff --git a/dmd2/access.c b/dmd2/access.c index 69f527ef..d1d1f4f2 100644 --- a/dmd2/access.c +++ b/dmd2/access.c @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -76,18 +76,15 @@ enum PROT ClassDeclaration::getAccess(Dsymbol *smember) } else { - enum PROT access; - int i; - if (smember->isDeclaration()->isStatic()) { access_ret = smember->prot(); } - for (i = 0; i < baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)baseclasses->data[i]; + for (size_t i = 0; i < baseclasses->dim; i++) + { BaseClass *b = (*baseclasses)[i]; - access = b->base->getAccess(smember); + enum PROT access = b->base->getAccess(smember); switch (access) { case PROTnone: @@ -153,11 +150,9 @@ static int accessCheckX( ClassDeclaration *cdthis = dthis->isClassDeclaration(); if (cdthis) { - for (int i = 0; i < cdthis->baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)cdthis->baseclasses->data[i]; - enum PROT access; - - access = b->base->getAccess(smember); + for (size_t i = 0; i < cdthis->baseclasses->dim; i++) + { BaseClass *b = (*cdthis->baseclasses)[i]; + enum PROT access = b->base->getAccess(smember); if (access >= PROTprotected || accessCheckX(smember, sfunc, b->base, cdscope) ) @@ -174,8 +169,8 @@ static int accessCheckX( ClassDeclaration *cdthis = dthis->isClassDeclaration(); if (cdthis) { - for (int i = 0; i < cdthis->baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)cdthis->baseclasses->data[i]; + for (size_t i = 0; i < cdthis->baseclasses->dim; i++) + { BaseClass *b = (*cdthis->baseclasses)[i]; if (accessCheckX(smember, sfunc, b->base, cdscope)) return 1; @@ -219,12 +214,12 @@ void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember) //assert(smember->parent->isBaseOf(this, NULL)); if (smemberparent == this) - { enum PROT access = smember->prot(); + { enum PROT access2 = smember->prot(); - result = access >= PROTpublic || + result = access2 >= PROTpublic || hasPrivateAccess(f) || isFriendOf(cdscope) || - (access == PROTpackage && hasPackageAccess(sc, this)); + (access2 == PROTpackage && hasPackageAccess(sc, this)); #if LOG printf("result1 = %d\n", result); #endif diff --git a/dmd2/aggregate.h b/dmd2/aggregate.h index 776f8b60..af85a260 100644 --- a/dmd2/aggregate.h +++ b/dmd2/aggregate.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2008 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -62,7 +62,7 @@ struct AggregateDeclaration : ScopeDsymbol unsigned alignsize; // size of struct for alignment purposes unsigned structalign; // struct member alignment in effect int hasUnions; // set if aggregate has overlapping fields - Array fields; // VarDeclaration fields + VarDeclarations fields; // VarDeclaration fields unsigned sizeok; // set when structsize contains valid data // 0: no size // 1: size is correct @@ -84,6 +84,7 @@ struct AggregateDeclaration : ScopeDsymbol Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration CtorDeclaration *defaultCtor; // default constructor Dsymbol *aliasthis; // forward unresolved lookups to aliasthis + bool noDefaultCtor; // no default construction #endif FuncDeclarations dtors; // Array of destructors @@ -209,17 +210,17 @@ struct BaseClass ClassDeclaration *base; int offset; // 'this' pointer offset - Array vtbl; // for interfaces: Array of FuncDeclaration's + FuncDeclarations vtbl; // for interfaces: Array of FuncDeclaration's // making up the vtbl[] - int baseInterfaces_dim; + size_t baseInterfaces_dim; BaseClass *baseInterfaces; // if BaseClass is an interface, these // are a copy of the InterfaceDeclaration::interfaces BaseClass(); BaseClass(Type *type, enum PROT protection); - int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance); + int fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance); void copyBaseInterfaces(BaseClasses *); }; @@ -244,13 +245,13 @@ struct ClassDeclaration : AggregateDeclaration #endif FuncDeclaration *staticCtor; FuncDeclaration *staticDtor; - Array vtbl; // Array of FuncDeclaration's making up the vtbl[] - Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] + Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[] + Dsymbols vtblFinal; // More FuncDeclaration's that aren't in vtbl[] BaseClasses *baseclasses; // Array of BaseClass's; first is super, // rest are Interface's - int interfaces_dim; + size_t interfaces_dim; BaseClass **interfaces; // interfaces[interfaces_dim] for this class // (does not include baseClass) diff --git a/dmd2/aliasthis.c b/dmd2/aliasthis.c index b379d26e..fab0dd2f 100644 --- a/dmd2/aliasthis.c +++ b/dmd2/aliasthis.c @@ -51,6 +51,8 @@ void AliasThis::semantic(Scope *sc) error("there can be only one alias this"); assert(ad->members); Dsymbol *s = ad->search(loc, ident, 0); + if (!s) + ::error(loc, "undefined identifier %s", ident->toChars()); ad->aliasthis = s; } else diff --git a/dmd2/argtypes.c b/dmd2/argtypes.c index 8e6b533d..1ebf5ea7 100644 --- a/dmd2/argtypes.c +++ b/dmd2/argtypes.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 2010-2010 by Digital Mars +// Copyright (c) 2010-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -155,8 +155,9 @@ TypeTuple *TypeDelegate::toArgTypes() TypeTuple *TypeStruct::toArgTypes() { - int sz = size(0); - switch (sz) + d_uns64 sz = size(0); + assert(sz < 0xFFFFFFFF); + switch ((unsigned)sz) { case 1: return new TypeTuple(Type::tint8); diff --git a/dmd2/arrayop.c b/dmd2/arrayop.c index 9ed42729..36db8199 100644 --- a/dmd2/arrayop.c +++ b/dmd2/arrayop.c @@ -326,7 +326,7 @@ Expression *BinExp::arrayOp(Scope *sc) Parameters *fparams = new Parameters(); Expression *loopbody = buildArrayLoop(fparams); - Parameter *p = (Parameter *)fparams->data[0 /*fparams->dim - 1*/]; + Parameter *p = fparams->tdata()[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)); @@ -443,6 +443,9 @@ X(Mod) X(Xor) X(And) X(Or) +#if DMDV2 +X(Pow) +#endif #undef X @@ -476,6 +479,9 @@ X(Mod) X(Xor) X(And) X(Or) +#if DMDV2 +X(Pow) +#endif #undef X @@ -531,7 +537,7 @@ Expression *AssignExp::buildArrayLoop(Parameters *fparams) ex2 = new CastExp(0, ex2, e1->type->nextOf()); #endif Expression *ex1 = e1->buildArrayLoop(fparams); - Parameter *param = (Parameter *)fparams->data[0]; + Parameter *param = fparams->tdata()[0]; param->storageClass = 0; Expression *e = new AssignExp(0, ex1, ex2); return e; @@ -544,7 +550,7 @@ Expression *Str##AssignExp::buildArrayLoop(Parameters *fparams) \ */ \ Expression *ex2 = e2->buildArrayLoop(fparams); \ Expression *ex1 = e1->buildArrayLoop(fparams); \ - Parameter *param = (Parameter *)fparams->data[0]; \ + Parameter *param = fparams->tdata()[0]; \ param->storageClass = 0; \ Expression *e = new Str##AssignExp(0, ex1, ex2); \ return e; \ @@ -558,6 +564,9 @@ X(Mod) X(Xor) X(And) X(Or) +#if DMDV2 +X(Pow) +#endif #undef X @@ -594,6 +603,9 @@ X(Mod) X(Xor) X(And) X(Or) +#if DMDV2 +X(Pow) +#endif #undef X diff --git a/dmd2/arraytypes.h b/dmd2/arraytypes.h index ef3d6fe4..be854a62 100644 --- a/dmd2/arraytypes.h +++ b/dmd2/arraytypes.h @@ -18,34 +18,60 @@ #include "root.h" -struct Expression; -struct Statement; -struct BaseClass; -struct TemplateParameter; -struct FuncDeclaration; -struct Identifier; -struct Initializer; +typedef ArrayBase TemplateParameters; -struct TemplateParameters : Array { }; +typedef ArrayBase Expressions; -struct Expressions : Array { }; +typedef ArrayBase Statements; -struct Statements : Array { }; +typedef ArrayBase BaseClasses; -struct BaseClasses : Array { }; +typedef ArrayBase ClassDeclarations; -struct ClassDeclarations : Array { }; +typedef ArrayBase Dsymbols; -struct Dsymbols : Array { }; +typedef ArrayBase Objects; -struct Objects : Array { }; +typedef ArrayBase FuncDeclarations; -struct FuncDeclarations : Array { }; +typedef ArrayBase Parameters; -struct Parameters : Array { }; +typedef ArrayBase Identifiers; -struct Identifiers : Array { }; +typedef ArrayBase Initializers; -struct Initializers : Array { }; +typedef ArrayBase VarDeclarations; + +typedef ArrayBase Types; + +typedef ArrayBase ScopeDsymbols; + +typedef ArrayBase Catches; + +typedef ArrayBase StaticDtorDeclarations; + +typedef ArrayBase SharedStaticDtorDeclarations; + +typedef ArrayBase AliasDeclarations; + +typedef ArrayBase Modules; + +typedef ArrayBase Files; + +typedef ArrayBase CaseStatements; + +typedef ArrayBase CompoundStatements; + +typedef ArrayBase GotoCaseStatements; + +typedef ArrayBase TemplateInstances; + +//typedef ArrayBase Strings; + +typedef ArrayBase Voids; + +typedef ArrayBase Blocks; + +typedef ArrayBase Symbols; #endif diff --git a/dmd2/attrib.c b/dmd2/attrib.c index bb62a768..5d5b42c5 100644 --- a/dmd2/attrib.c +++ b/dmd2/attrib.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -70,7 +70,7 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; //printf("\taddMember %s to %s\n", s->toChars(), sd->toChars()); m |= s->addMember(sc, sd, m | memnum); } @@ -101,7 +101,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc, newsc->structalign = structalign; } for (unsigned i = 0; i < decl->dim; i++) - { Dsymbol *s = (Dsymbol *)decl->data[i]; + { Dsymbol *s = decl->tdata()[i]; s->setScope(newsc); // yes, the only difference from semanticNewSc() } @@ -136,7 +136,7 @@ void AttribDeclaration::semanticNewSc(Scope *sc, newsc->structalign = structalign; } for (unsigned i = 0; i < decl->dim; i++) - { Dsymbol *s = (Dsymbol *)decl->data[i]; + { Dsymbol *s = decl->tdata()[i]; s->semantic(newsc); } @@ -157,7 +157,7 @@ void AttribDeclaration::semantic(Scope *sc) { for (unsigned i = 0; i < d->dim; i++) { - Dsymbol *s = (Dsymbol *)d->data[i]; + Dsymbol *s = d->tdata()[i]; s->semantic(sc); } @@ -171,7 +171,7 @@ void AttribDeclaration::semantic2(Scope *sc) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->semantic2(sc); } } @@ -184,7 +184,7 @@ void AttribDeclaration::semantic3(Scope *sc) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->semantic3(sc); } } @@ -197,7 +197,7 @@ void AttribDeclaration::inlineScan() if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; //printf("AttribDeclaration::inlineScan %s\n", s->toChars()); s->inlineScan(); } @@ -214,7 +214,7 @@ void AttribDeclaration::addComment(unsigned char *comment) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; //printf("AttribDeclaration::addComment %s\n", s->toChars()); s->addComment(comment); } @@ -239,7 +239,7 @@ void AttribDeclaration::emitComment(Scope *sc) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; //printf("AttribDeclaration::emitComment %s\n", s->toChars()); s->emitComment(sc); } @@ -255,7 +255,7 @@ void AttribDeclaration::toObjFile(int multiobj) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->toObjFile(multiobj); } } @@ -270,7 +270,7 @@ int AttribDeclaration::cvMember(unsigned char *p) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; n = s->cvMember(p); if (p) p += n; @@ -289,7 +289,7 @@ int AttribDeclaration::hasPointers() { for (size_t i = 0; i < d->dim; i++) { - Dsymbol *s = (Dsymbol *)d->data[i]; + Dsymbol *s = d->tdata()[i]; if (s->hasPointers()) return 1; } @@ -316,7 +316,7 @@ void AttribDeclaration::checkCtorConstInit() if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->checkCtorConstInit(); } } @@ -332,7 +332,7 @@ void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses) if (d) { for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->addLocalClass(aclasses); } } @@ -346,7 +346,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) if (decl->dim == 0) buf->writestring("{}"); else if (decl->dim == 1) - ((Dsymbol *)decl->data[0])->toCBuffer(buf, hgs); + (decl->tdata()[0])->toCBuffer(buf, hgs); else { buf->writenl(); @@ -354,7 +354,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; buf->writestring(" "); s->toCBuffer(buf, hgs); @@ -546,7 +546,7 @@ void LinkDeclaration::semantic3(Scope *sc) sc->linkage = linkage; for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; s->semantic3(sc); } @@ -626,9 +626,9 @@ void ProtDeclaration::importAll(Scope *sc) newsc->explicitProtection = 1; } - for (int i = 0; i < decl->dim; i++) + for (size_t i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = (*decl)[i]; s->importAll(newsc); } @@ -790,7 +790,7 @@ void AnonDeclaration::semantic(Scope *sc) for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; s->semantic(sc); if (isunion) @@ -842,7 +842,7 @@ void AnonDeclaration::semantic(Scope *sc) //printf("\tadding members of aad to '%s'\n", ad->toChars()); for (unsigned i = 0; i < aad.fields.dim; i++) { - VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; + VarDeclaration *v = aad.fields.tdata()[i]; #if IN_LLVM v->offset2 = sc->offset; @@ -883,7 +883,7 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; //buf->writestring(" "); s->toCBuffer(buf, hgs); @@ -943,15 +943,16 @@ void PragmaDeclaration::setScope(Scope *sc) } else { - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - args->data[0] = (void *)e; - if (e->op != TOKstring) + args->tdata()[0] = e; + StringExp* se = e->toString(); + if (!se) { error("string expected, not '%s'", e->toChars()); } - PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast(e)); + PragmaScope* pragma = new PragmaScope(this, sc->parent, se); assert(sc); pragma->setScope(sc); @@ -980,13 +981,13 @@ void PragmaDeclaration::semantic(Scope *sc) { for (size_t i = 0; i < args->dim; i++) { - Expression *e = (Expression *)args->data[i]; + Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - if (e->op == TOKstring) + StringExp *se = e->toString(); + if (se) { - StringExp *se = (StringExp *)e; fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else @@ -1002,18 +1003,18 @@ void PragmaDeclaration::semantic(Scope *sc) error("string expected for library name"); else { - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - args->data[0] = (void *)e; + args->tdata()[0] = e; if (e->op == TOKerror) goto Lnodecl; - if (e->op != TOKstring) + StringExp *se = e->toString(); + if (!se) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { - StringExp *se = (StringExp *)e; char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; @@ -1034,7 +1035,7 @@ void PragmaDeclaration::semantic(Scope *sc) Declaration *d = NULL; StringExp *s = NULL; - e = (Expression *)args->data[0]; + e = args->tdata()[0]; e = e->semantic(sc); if (e->op == TOKvar) { @@ -1045,10 +1046,11 @@ void PragmaDeclaration::semantic(Scope *sc) if (!d) error("first argument of GNU_asm must be a function or variable declaration"); - e = (Expression *)args->data[1]; + e = args->tdata()[1]; e = e->semantic(sc); - e = e->optimize(WANTvalue); - if (e->op == TOKstring && ((StringExp *)e)->sz == 1) + e = e->optimize(WANTvalue | WANTinterpret); + e = e->toString(); + if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); @@ -1066,10 +1068,10 @@ void PragmaDeclaration::semantic(Scope *sc) error("function name expected for start address"); else { - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - args->data[0] = (void *)e; + args->tdata()[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); @@ -1220,11 +1222,11 @@ void PragmaDeclaration::semantic(Scope *sc) { for (size_t i = 0; i < args->dim; i++) { + Expression *e = args->tdata()[i]; // ignore errors in ignored pragmas. global.gag++; unsigned errors_save = global.errors; - Expression *e = (Expression *)args->data[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) @@ -1250,7 +1252,7 @@ void PragmaDeclaration::semantic(Scope *sc) { for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; s->semantic(sc); @@ -1399,7 +1401,7 @@ void PragmaDeclaration::toObjFile(int multiobj) { assert(args && args->dim == 1); - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; assert(e->op == TOKstring); @@ -1418,7 +1420,7 @@ void PragmaDeclaration::toObjFile(int multiobj) * so instead append the library name to the list to be passed * to the linker. */ - global.params.libfiles->push((void *) name); + global.params.libfiles->push(name); #else error("pragma lib not supported"); #endif @@ -1427,7 +1429,7 @@ void PragmaDeclaration::toObjFile(int multiobj) else if (ident == Id::startaddress) { assert(args && args->dim == 1); - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; Dsymbol *sa = getDsymbol(e); FuncDeclaration *f = sa->isFuncDeclaration(); assert(f); @@ -1500,7 +1502,7 @@ void ConditionalDeclaration::emitComment(Scope *sc) */ Dsymbols *d = decl ? decl : elsedecl; for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; s->emitComment(sc); } } @@ -1524,7 +1526,7 @@ void ConditionalDeclaration::setScope(Scope *sc) { for (unsigned i = 0; i < d->dim; i++) { - Dsymbol *s = (Dsymbol *)d->data[i]; + Dsymbol *s = d->tdata()[i]; s->setScope(sc); } @@ -1540,7 +1542,7 @@ void ConditionalDeclaration::importAll(Scope *sc) { for (unsigned i = 0; i < d->dim; i++) { - Dsymbol *s = (Dsymbol *)d->data[i]; + Dsymbol *s = d->tdata()[i]; s->importAll(sc); } @@ -1566,7 +1568,7 @@ void ConditionalDeclaration::addComment(unsigned char *comment) for (unsigned i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)d->data[i]; + s = d->tdata()[i]; //printf("ConditionalDeclaration::addComment %s\n", s->toChars()); s->addComment(comment); } @@ -1588,7 +1590,7 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { for (unsigned i = 0; i < decl->dim; i++) { - Dsymbol *s = (Dsymbol *)decl->data[i]; + Dsymbol *s = decl->tdata()[i]; buf->writestring(" "); s->toCBuffer(buf, hgs); @@ -1604,7 +1606,7 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); for (unsigned i = 0; i < elsedecl->dim; i++) { - Dsymbol *s = (Dsymbol *)elsedecl->data[i]; + Dsymbol *s = elsedecl->tdata()[i]; buf->writestring(" "); s->toCBuffer(buf, hgs); @@ -1690,7 +1692,7 @@ void StaticIfDeclaration::semantic(Scope *sc) for (unsigned i = 0; i < d->dim; i++) { - Dsymbol *s = (Dsymbol *)d->data[i]; + Dsymbol *s = d->tdata()[i]; s->semantic(sc); } @@ -1742,12 +1744,12 @@ void CompileDeclaration::compileIt(Scope *sc) exp = exp->semantic(sc); exp = resolveProperties(sc, exp); exp = exp->optimize(WANTvalue | WANTinterpret); - if (exp->op != TOKstring) + StringExp *se = exp->toString(); + if (!se) { exp->error("argument to mixin must be a string, not (%s)", exp->toChars()); } else { - StringExp *se = (StringExp *)exp; se = se->toUTF8(sc); Parser p(sc->module, (unsigned char *)se->string, se->len, 0); p.loc = loc; diff --git a/dmd2/builtin.c b/dmd2/builtin.c index 6ec705e6..fbd42b3e 100644 --- a/dmd2/builtin.c +++ b/dmd2/builtin.c @@ -92,7 +92,7 @@ enum BUILTIN FuncDeclaration::isBuiltin() Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments) { assert(arguments && arguments->dim); - Expression *arg0 = (Expression *)arguments->data[0]; + Expression *arg0 = arguments->tdata()[0]; Expression *e = NULL; switch (builtin) { diff --git a/dmd2/cast.c b/dmd2/cast.c index aa110a62..30af0fb5 100644 --- a/dmd2/cast.c +++ b/dmd2/cast.c @@ -427,8 +427,8 @@ MATCH StructLiteralExp::implicitConvTo(Type *t) ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym) { m = MATCHconst; - for (int i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + for (size_t i = 0; i < elements->dim; i++) + { Expression *e = (*elements)[i]; Type *te = e->type; te = te->castMod(t->mod); MATCH m2 = e->implicitConvTo(te); @@ -442,8 +442,7 @@ MATCH StructLiteralExp::implicitConvTo(Type *t) #endif MATCH StringExp::implicitConvTo(Type *t) -{ MATCH m; - +{ #if 0 printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", toChars(), committed, type->toChars(), t->toChars()); @@ -536,8 +535,8 @@ MATCH ArrayLiteralExp::implicitConvTo(Type *t) result = MATCHnomatch; } - for (int i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + for (size_t i = 0; i < elements->dim; i++) + { Expression *e = (*elements)[i]; MATCH m = (MATCH)e->implicitConvTo(tb->nextOf()); if (m < result) result = m; // remember worst match @@ -558,13 +557,13 @@ MATCH AssocArrayLiteralExp::implicitConvTo(Type *t) if (tb->ty == Taarray && typeb->ty == Taarray) { for (size_t i = 0; i < keys->dim; i++) - { Expression *e = (Expression *)keys->data[i]; + { Expression *e = keys->tdata()[i]; MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->index); if (m < result) result = m; // remember worst match if (result == MATCHnomatch) break; // no need to check for worse - e = (Expression *)values->data[i]; + e = values->tdata()[i]; m = (MATCH)e->implicitConvTo(tb->nextOf()); if (m < result) result = m; // remember worst match @@ -577,6 +576,26 @@ MATCH AssocArrayLiteralExp::implicitConvTo(Type *t) return Expression::implicitConvTo(t); } +MATCH CallExp::implicitConvTo(Type *t) +{ +#if 0 + printf("CalLExp::implicitConvTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif + + MATCH m = Expression::implicitConvTo(t); + if (m) + return m; + + /* Allow the result of strongly pure functions to + * convert to immutable + */ + if (f && f->isPure() == PUREstrong) + return type->invariantOf()->implicitConvTo(t); + + return MATCHnomatch; +} + MATCH AddrExp::implicitConvTo(Type *t) { #if 0 @@ -598,8 +617,8 @@ MATCH AddrExp::implicitConvTo(Type *t) (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction) { OverExp *eo = (OverExp *)e1; FuncDeclaration *f = NULL; - for (int i = 0; i < eo->vars->a.dim; i++) - { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; + for (size_t i = 0; i < eo->vars->a.dim; i++) + { Dsymbol *s = eo->vars->a[i]; FuncDeclaration *f2 = s->isFuncDeclaration(); assert(f2); if (f2->overloadExactMatch(t->nextOf(), m)) @@ -686,11 +705,10 @@ MATCH DelegateExp::implicitConvTo(Type *t) if (result == MATCHnomatch) { // Look for pointers to functions where the functions are overloaded. - FuncDeclaration *f; t = t->toBasetype(); - if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction && - t->ty == Tdelegate && t->nextOf()->ty == Tfunction) + if (type->ty == Tdelegate && + t->ty == Tdelegate) { if (func && func->overloadExactMatch(t->nextOf(), m)) result = MATCHexact; @@ -819,9 +837,9 @@ Expression *Expression::castTo(Scope *sc, Type *t) * cast(to)e1.aliasthis */ Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident); - Expression *e = new CastExp(loc, e1, tb); - e = e->semantic(sc); - return e; + Expression *e2 = new CastExp(loc, e1, tb); + e2 = e2->semantic(sc); + return e2; } } else if (typeb->ty == Tclass) @@ -840,9 +858,9 @@ Expression *Expression::castTo(Scope *sc, Type *t) * cast(to)e1.aliasthis */ Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident); - Expression *e = new CastExp(loc, e1, tb); - e = e->semantic(sc); - return e; + Expression *e2 = new CastExp(loc, e1, tb); + e2 = e2->semantic(sc); + return e2; } L1: ; } @@ -989,7 +1007,9 @@ Expression *StringExp::castTo(Scope *sc, Type *t) if (committed && tb->ty == Tsarray && typeb->ty == Tarray) { se = (StringExp *)copy(); - se->sz = tb->nextOf()->size(); + d_uns64 szx = tb->nextOf()->size(); + assert(szx <= 255); + se->sz = (unsigned char)szx; se->len = (len * sz) / se->sz; se->committed = 1; se->type = t; @@ -1124,7 +1144,12 @@ Expression *StringExp::castTo(Scope *sc, Type *t) } se->string = buffer.extractData(); se->len = newlen; - se->sz = tb->nextOf()->size(); + + { + d_uns64 szx = tb->nextOf()->size(); + assert(szx <= 255); + se->sz = (unsigned char)szx; + } break; default: @@ -1139,9 +1164,9 @@ L2: // See if need to truncate or extend the literal if (tb->ty == Tsarray) { - int dim2 = ((TypeSArray *)tb)->dim->toInteger(); + dinteger_t dim2 = ((TypeSArray *)tb)->dim->toInteger(); - //printf("dim from = %d, to = %d\n", se->len, dim2); + //printf("dim from = %d, to = %d\n", (int)se->len, (int)dim2); // Changing dimensions if (dim2 != se->len) @@ -1189,8 +1214,8 @@ Expression *AddrExp::castTo(Scope *sc, Type *t) (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction) { OverExp *eo = (OverExp *)e1; FuncDeclaration *f = NULL; - for (int i = 0; i < eo->vars->a.dim; i++) - { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; + for (size_t i = 0; i < eo->vars->a.dim; i++) + { Dsymbol *s = eo->vars->a[i]; FuncDeclaration *f2 = s->isFuncDeclaration(); assert(f2); if (f2->overloadExactMatch(t->nextOf(), m)) @@ -1297,9 +1322,9 @@ Expression *TupleExp::castTo(Scope *sc, Type *t) { TupleExp *e = (TupleExp *)copy(); e->exps = (Expressions *)exps->copy(); for (size_t i = 0; i < e->exps->dim; i++) - { Expression *ex = (Expression *)e->exps->data[i]; + { Expression *ex = e->exps->tdata()[i]; ex = ex->castTo(sc, t); - e->exps->data[i] = (void *)ex; + e->exps->tdata()[i] = ex; } return e; } @@ -1329,10 +1354,10 @@ Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t) e = (ArrayLiteralExp *)copy(); e->elements = (Expressions *)elements->copy(); - for (int i = 0; i < elements->dim; i++) - { Expression *ex = (Expression *)elements->data[i]; + for (size_t i = 0; i < elements->dim; i++) + { Expression *ex = (*elements)[i]; ex = ex->castTo(sc, tb->nextOf()); - e->elements->data[i] = (void *)ex; + (*e->elements)[i] = ex; } e->type = t; return e; @@ -1364,18 +1389,17 @@ Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) e->values = (Expressions *)values->copy(); assert(keys->dim == values->dim); for (size_t i = 0; i < keys->dim; i++) - { Expression *ex = (Expression *)values->data[i]; + { Expression *ex = values->tdata()[i]; ex = ex->castTo(sc, tb->nextOf()); - e->values->data[i] = (void *)ex; + e->values->tdata()[i] = ex; - ex = (Expression *)keys->data[i]; + ex = keys->tdata()[i]; ex = ex->castTo(sc, ((TypeAArray *)tb)->index); - e->keys->data[i] = (void *)ex; + e->keys->tdata()[i] = ex; } e->type = t; return e; } -L1: return e->Expression::castTo(sc, t); } @@ -1464,8 +1488,8 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t) // Look for delegates to functions where the functions are overloaded. FuncDeclaration *f; - if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && - tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) + if (typeb->ty == Tdelegate && + tb->ty == Tdelegate) { if (func) { @@ -1600,7 +1624,7 @@ bool isVoidArrayLiteral(Expression *e, Type *other) while (e->op == TOKarrayliteral && e->type->ty == Tarray && (((ArrayLiteralExp *)e)->elements->dim == 1)) { - e = (Expression *)((ArrayLiteralExp *)e)->elements->data[0]; + e = ((ArrayLiteralExp *)e)->elements->tdata()[0]; if (other->ty == Tsarray || other->ty == Tarray) other = other->nextOf(); else @@ -1712,6 +1736,41 @@ Lagain: t = t2; else if (t2n->ty == Tvoid) ; + else if (t1n->ty == Tfunction && t2n->ty == Tfunction) + { + if (t1->implicitConvTo(t2)) + goto Lt2; + if (t2->implicitConvTo(t1)) + goto Lt1; + + TypeFunction *tf1 = (TypeFunction *)t1n; + TypeFunction *tf2 = (TypeFunction *)t2n; + TypeFunction *d = (TypeFunction *)tf1->syntaxCopy(); + + if (tf1->purity != tf2->purity) + d->purity = PUREimpure; + assert(d->purity != PUREfwdref); + + d->isnothrow = (tf1->isnothrow && tf2->isnothrow); + + if (tf1->trust == tf2->trust) + d->trust = tf1->trust; + else if (tf1->trust <= TRUSTsystem || tf2->trust <= TRUSTsystem) + d->trust = TRUSTsystem; + else + d->trust = TRUSTtrusted; + + Type *tx = d->pointerTo(); + + if (t1->implicitConvTo(tx) && t2->implicitConvTo(tx)) + { + t = tx; + e1 = e1->castTo(sc, t); + e2 = e2->castTo(sc, t); + goto Lret; + } + goto Lincompatible; + } else if (t1n->mod != t2n->mod) { t1 = t1n->mutableOf()->constOf()->pointerTo(); @@ -1851,14 +1910,71 @@ Lagain: else goto Lincompatible; } + else if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis) + { + e1 = new DotIdExp(e1->loc, e1, ((TypeStruct *)t1)->sym->aliasthis->ident); + e1 = e1->semantic(sc); + e1 = resolveProperties(sc, e1); + t1 = e1->type; + continue; + } + else if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis) + { + e2 = new DotIdExp(e2->loc, e2, ((TypeStruct *)t2)->sym->aliasthis->ident); + e2 = e2->semantic(sc); + e2 = resolveProperties(sc, e2); + t2 = e2->type; + continue; + } else goto Lincompatible; } } else if (t1->ty == Tstruct && t2->ty == Tstruct) { - if (((TypeStruct *)t1)->sym != ((TypeStruct *)t2)->sym) - goto Lincompatible; + TypeStruct *ts1 = (TypeStruct *)t1; + TypeStruct *ts2 = (TypeStruct *)t2; + if (ts1->sym != ts2->sym) + { + if (!ts1->sym->aliasthis && !ts2->sym->aliasthis) + goto Lincompatible; + + int i1 = 0; + int i2 = 0; + + Expression *e1b = NULL; + Expression *e2b = NULL; + if (ts2->sym->aliasthis) + { + e2b = new DotIdExp(e2->loc, e2, ts2->sym->aliasthis->ident); + e2b = e2b->semantic(sc); + e2b = resolveProperties(sc, e2b); + i1 = e2b->implicitConvTo(t1); + } + if (ts1->sym->aliasthis) + { + e1b = new DotIdExp(e1->loc, e1, ts1->sym->aliasthis->ident); + e1b = e1b->semantic(sc); + e1b = resolveProperties(sc, e1b); + i2 = e1b->implicitConvTo(t2); + } + assert(!(i1 && i2)); + + if (i1) + goto Lt1; + else if (i2) + goto Lt2; + + if (e1b) + { e1 = e1b; + t1 = e1b->type->toBasetype(); + } + if (e2b) + { e2 = e2b; + t2 = e2b->type->toBasetype(); + } + goto Lagain; + } } else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2)) { diff --git a/dmd2/class.c b/dmd2/class.c index ad2c694b..42c3bab0 100644 --- a/dmd2/class.c +++ b/dmd2/class.c @@ -232,11 +232,11 @@ Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) cd->storage_class |= storage_class; cd->baseclasses->setDim(this->baseclasses->dim); - for (int i = 0; i < cd->baseclasses->dim; i++) + for (size_t i = 0; i < cd->baseclasses->dim; i++) { - BaseClass *b = (BaseClass *)this->baseclasses->data[i]; + BaseClass *b = this->baseclasses->tdata()[i]; BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); - cd->baseclasses->data[i] = b2; + cd->baseclasses->tdata()[i] = b2; } ScopeDsymbol::syntaxCopy(cd); @@ -244,9 +244,7 @@ Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) } void ClassDeclaration::semantic(Scope *sc) -{ int i; - unsigned offset; - +{ //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); //printf("sc->stc = %x\n", sc->stc); @@ -300,8 +298,8 @@ void ClassDeclaration::semantic(Scope *sc) error("cannot create C++ classes"); // Expand any tuples in baseclasses[] - for (i = 0; i < baseclasses->dim; ) - { BaseClass *b = (BaseClass *)baseclasses->data[i]; + for (size_t i = 0; i < baseclasses->dim; ) + { BaseClass *b = baseclasses->tdata()[i]; //printf("test1 %s %s\n", toChars(), b->type->toChars()); b->type = b->type->semantic(loc, sc); //printf("test2\n"); @@ -328,7 +326,7 @@ void ClassDeclaration::semantic(Scope *sc) BaseClass *b; Type *tb; - b = (BaseClass *)baseclasses->data[0]; + b = baseclasses->tdata()[0]; //b->type = b->type->semantic(loc, sc); tb = b->type->toBasetype(); if (tb->ty != Tclass) @@ -392,12 +390,12 @@ void ClassDeclaration::semantic(Scope *sc) // Treat the remaining entries in baseclasses as interfaces // Check for errors, handle forward references - for (i = (baseClass ? 1 : 0); i < baseclasses->dim; ) + for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; ) { TypeClass *tc; BaseClass *b; Type *tb; - b = (BaseClass *)baseclasses->data[i]; + b = baseclasses->tdata()[i]; b->type = b->type->semantic(loc, sc); tb = b->type->toBasetype(); if (tb->ty == Tclass) @@ -426,7 +424,7 @@ void ClassDeclaration::semantic(Scope *sc) // Check for duplicate interfaces for (size_t j = (baseClass ? 1 : 0); j < i; j++) { - BaseClass *b2 = (BaseClass *)baseclasses->data[j]; + BaseClass *b2 = baseclasses->tdata()[j]; if (b2->base == tc->sym) error("inherits from duplicate interface %s", b2->base->toChars()); } @@ -480,7 +478,7 @@ void ClassDeclaration::semantic(Scope *sc) } interfaces_dim = baseclasses->dim; - interfaces = (BaseClass **)baseclasses->data; + interfaces = baseclasses->tdata(); if (baseClass) @@ -493,7 +491,7 @@ void ClassDeclaration::semantic(Scope *sc) // Copy vtbl[] from base class vtbl.setDim(baseClass->vtbl.dim); - memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim); + memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim); // Inherit properties from base class com = baseClass->isCOMclass(); @@ -515,9 +513,9 @@ void ClassDeclaration::semantic(Scope *sc) { interfaceSemantic(sc); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->addMember(sc, this, 1); } @@ -561,9 +559,9 @@ void ClassDeclaration::semantic(Scope *sc) if (ad) t = ad->handle; else if (fd) - { AggregateDeclaration *ad = fd->isMember2(); - if (ad) - t = ad->handle; + { AggregateDeclaration *ad2 = fd->isMember2(); + if (ad2) + t = ad2->handle; else { t = Type::tvoidptr; @@ -629,14 +627,14 @@ void ClassDeclaration::semantic(Scope *sc) } structsize = sc->offset; Scope scsave = *sc; - int members_dim = members->dim; + size_t members_dim = members->dim; sizeok = 0; /* Set scope so if there are forward references, we still might be able to * resolve individual members like enums. */ - for (i = 0; i < members_dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members_dim; i++) + { Dsymbol *s = members->tdata()[i]; /* There are problems doing this in the general case because * Scope keeps track of things like 'offset' */ @@ -647,8 +645,8 @@ void ClassDeclaration::semantic(Scope *sc) } } - for (i = 0; i < members_dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members_dim; i++) + { Dsymbol *s = members->tdata()[i]; s->semantic(sc); } @@ -724,9 +722,9 @@ void ClassDeclaration::semantic(Scope *sc) #endif // Allocate instance of each new interface - for (i = 0; i < vtblInterfaces->dim; i++) + for (size_t i = 0; i < vtblInterfaces->dim; i++) { - BaseClass *b = (BaseClass *)vtblInterfaces->data[i]; + BaseClass *b = vtblInterfaces->tdata()[i]; unsigned thissize = PTRSIZE; alignmember(structalign, thissize, &sc->offset); @@ -760,7 +758,7 @@ void ClassDeclaration::semantic(Scope *sc) // Fill in base class vtbl[]s for (i = 0; i < vtblInterfaces->dim; i++) { - BaseClass *b = (BaseClass *)vtblInterfaces->data[i]; + BaseClass *b = vtblInterfaces->tdata()[i]; //b->fillVtbl(this, &b->vtbl, 1); } @@ -783,9 +781,9 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) if (baseclasses->dim) buf->writestring(" : "); } - for (int i = 0; i < baseclasses->dim; i++) + for (size_t i = 0; i < baseclasses->dim; i++) { - BaseClass *b = (BaseClass *)baseclasses->data[i]; + BaseClass *b = baseclasses->tdata()[i]; if (i) buf->writeByte(','); @@ -797,9 +795,9 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); buf->writeByte('{'); buf->writenl(); - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; buf->writestring(" "); s->toCBuffer(buf, hgs); @@ -833,8 +831,8 @@ int ClassDeclaration::isBaseOf2(ClassDeclaration *cd) if (!cd) return 0; //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); - for (int i = 0; i < cd->baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)cd->baseclasses->data[i]; + for (size_t i = 0; i < cd->baseclasses->dim; i++) + { BaseClass *b = cd->baseclasses->tdata()[i]; if (b->base == this || isBaseOf2(b->base)) return 1; @@ -879,8 +877,8 @@ int ClassDeclaration::isBaseInfoComplete() { if (!baseClass) return ident == Id::Object; - for (int i = 0; i < baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)baseclasses->data[i]; + for (size_t i = 0; i < baseclasses->dim; i++) + { BaseClass *b = baseclasses->tdata()[i]; if (!b->base || !b->base->isBaseInfoComplete()) return 0; } @@ -911,11 +909,9 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) { // Search bases classes in depth-first, left to right order - int i; - - for (i = 0; i < baseclasses->dim; i++) + for (size_t i = 0; i < baseclasses->dim; i++) { - BaseClass *b = (BaseClass *)baseclasses->data[i]; + BaseClass *b = baseclasses->tdata()[i]; if (b->base) { @@ -962,9 +958,9 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) OverloadSet *os = s->isOverloadSet(); if (os) { - for (int i = 0; i < os->a.dim; i++) - { Dsymbol *s = (Dsymbol *)os->a.data[i]; - FuncDeclaration *f2 = s->isFuncDeclaration(); + for (size_t i = 0; i < os->a.dim; i++) + { Dsymbol *s2 = os->a.tdata()[i]; + FuncDeclaration *f2 = s2->isFuncDeclaration(); if (f2 && overloadApply(getModule(), f2, &isf, fd)) return 0; } @@ -989,12 +985,12 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars()); ClassDeclaration *cd = this; - Array *vtbl = &cd->vtbl; + Dsymbols *vtbl = &cd->vtbl; while (1) { for (size_t i = 0; i < vtbl->dim; i++) { - FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration(); + FuncDeclaration *fd = vtbl->tdata()[i]->isFuncDeclaration(); if (!fd) continue; // the first entry might be a ClassInfo @@ -1069,9 +1065,9 @@ int ClassDeclaration::isAbstract() { if (isabstract) return TRUE; - for (int i = 1; i < vtbl.dim; i++) + for (size_t i = 1; i < vtbl.dim; i++) { - FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); + FuncDeclaration *fd = vtbl.tdata()[i]->isFuncDeclaration(); //printf("\tvtbl[%d] = %p\n", i, fd); if (!fd || fd->isAbstract()) @@ -1139,8 +1135,7 @@ Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) } void InterfaceDeclaration::semantic(Scope *sc) -{ int i; - +{ //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); if (inuse) return; @@ -1177,8 +1172,8 @@ void InterfaceDeclaration::semantic(Scope *sc) } // Expand any tuples in baseclasses[] - for (i = 0; i < baseclasses->dim; ) - { BaseClass *b = (BaseClass *)baseclasses->data[0]; + for (size_t i = 0; i < baseclasses->dim; ) + { BaseClass *b = baseclasses->tdata()[0]; b->type = b->type->semantic(loc, sc); Type *tb = b->type->toBasetype(); @@ -1201,12 +1196,12 @@ void InterfaceDeclaration::semantic(Scope *sc) cpp = 1; // Check for errors, handle forward references - for (i = 0; i < baseclasses->dim; ) + for (size_t i = 0; i < baseclasses->dim; ) { TypeClass *tc; BaseClass *b; Type *tb; - b = (BaseClass *)baseclasses->data[i]; + b = baseclasses->tdata()[i]; b->type = b->type->semantic(loc, sc); tb = b->type->toBasetype(); if (tb->ty == Tclass) @@ -1224,7 +1219,7 @@ void InterfaceDeclaration::semantic(Scope *sc) // Check for duplicate interfaces for (size_t j = 0; j < i; j++) { - BaseClass *b2 = (BaseClass *)baseclasses->data[j]; + BaseClass *b2 = baseclasses->tdata()[j]; if (b2->base == tc->sym) error("inherits from duplicate interface %s", b2->base->toChars()); } @@ -1260,7 +1255,7 @@ void InterfaceDeclaration::semantic(Scope *sc) } interfaces_dim = baseclasses->dim; - interfaces = (BaseClass **)baseclasses->data; + interfaces = baseclasses->tdata(); interfaceSemantic(sc); @@ -1268,7 +1263,7 @@ void InterfaceDeclaration::semantic(Scope *sc) vtbl.push(this); // leave room at vtbl[0] for classinfo // Cat together the vtbl[]'s from base interfaces - for (i = 0; i < interfaces_dim; i++) + for (size_t i = 0; i < interfaces_dim; i++) { BaseClass *b = interfaces[i]; // Skip if b has already appeared @@ -1285,7 +1280,7 @@ void InterfaceDeclaration::semantic(Scope *sc) { vtbl.reserve(d - 1); for (int j = 1; j < d; j++) - vtbl.push(b->base->vtbl.data[j]); + vtbl.push(b->base->vtbl.tdata()[j]); } } else @@ -1300,9 +1295,9 @@ void InterfaceDeclaration::semantic(Scope *sc) protection = sc->protection; storage_class |= sc->stc & STC_TYPECTOR; - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->addMember(sc, this, 1); } @@ -1319,9 +1314,9 @@ void InterfaceDeclaration::semantic(Scope *sc) structalign = sc->structalign; sc->offset = PTRSIZE * 2; inuse++; - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic(sc); } inuse--; @@ -1414,8 +1409,8 @@ int InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset) int InterfaceDeclaration::isBaseInfoComplete() { assert(!baseClass); - for (int i = 0; i < baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)baseclasses->data[i]; + for (size_t i = 0; i < baseclasses->dim; i++) + { BaseClass *b = baseclasses->tdata()[i]; if (!b->base || !b->base->isBaseInfoComplete ()) return 0; } @@ -1487,10 +1482,9 @@ BaseClass::BaseClass(Type *type, enum PROT protection) * by base classes) */ -int BaseClass::fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance) +int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance) { ClassDeclaration *id = base; - int j; int result = 0; //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", base->toChars(), cd->toChars()); @@ -1498,9 +1492,9 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance) vtbl->setDim(base->vtbl.dim); // first entry is ClassInfo reference - for (j = base->vtblOffset(); j < base->vtbl.dim; j++) + for (size_t j = base->vtblOffset(); j < base->vtbl.dim; j++) { - FuncDeclaration *ifd = ((Dsymbol *)base->vtbl.data[j])->isFuncDeclaration(); + FuncDeclaration *ifd = base->vtbl.tdata()[j]->isFuncDeclaration(); FuncDeclaration *fd; TypeFunction *tf; @@ -1537,7 +1531,7 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance) fd = NULL; } if (vtbl) - vtbl->data[j] = fd; + vtbl->tdata()[j] = fd; } return result; diff --git a/dmd2/clone.c b/dmd2/clone.c index cb40c76d..6b509025 100644 --- a/dmd2/clone.c +++ b/dmd2/clone.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -44,7 +44,7 @@ int StructDeclaration::needOpAssign() */ for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); if (v->storage_class & STCref) @@ -87,7 +87,7 @@ int StructDeclaration::needOpEquals() */ for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); if (v->storage_class & STCref) @@ -104,7 +104,6 @@ int StructDeclaration::needOpEquals() goto Lneed; } } -Ldontneed: if (X) printf("\tdontneed\n"); return 0; @@ -185,9 +184,9 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc) /* Instead of running the destructor on s, run it * on tmp. This avoids needing to copy tmp back in to s. */ - Expression *ec = new DotVarExp(0, new VarExp(0, tmp), dtor, 0); - ec = new CallExp(0, ec); - e = Expression::combine(e, ec); + Expression *ec2 = new DotVarExp(0, new VarExp(0, tmp), dtor, 0); + ec2 = new CallExp(0, ec2); + e = Expression::combine(e, ec2); } } else @@ -196,7 +195,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc) //printf("\tmemberwise copy\n"); for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); // this.v = s.v; @@ -267,7 +266,7 @@ FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc) //printf("\tmemberwise compare\n"); for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); if (v->storage_class & STCref) @@ -390,13 +389,13 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc) for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); if (v->storage_class & STCref) continue; Type *tv = v->type->toBasetype(); - size_t dim = (tv->ty == Tsarray ? 1 : 0); + dinteger_t dim = (tv->ty == Tsarray ? 1 : 0); while (tv->ty == Tsarray) { TypeSArray *ta = (TypeSArray *)tv; dim *= ((TypeSArray *)tv)->dim->toInteger(); @@ -458,12 +457,12 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc) return NULL; case 1: - return (FuncDeclaration *)postblits.data[0]; + return postblits.tdata()[0]; default: e = NULL; for (size_t i = 0; i < postblits.dim; i++) - { FuncDeclaration *fd = (FuncDeclaration *)postblits.data[i]; + { FuncDeclaration *fd = postblits.tdata()[i]; stc |= fd->storage_class & STCdisable; if (stc & STCdisable) { @@ -502,13 +501,13 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc) #if DMDV2 for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); if (v->storage_class & STCref) continue; Type *tv = v->type->toBasetype(); - size_t dim = (tv->ty == Tsarray ? 1 : 0); + dinteger_t dim = (tv->ty == Tsarray ? 1 : 0); while (tv->ty == Tsarray) { TypeSArray *ta = (TypeSArray *)tv; dim *= ((TypeSArray *)tv)->dim->toInteger(); @@ -563,12 +562,12 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc) return NULL; case 1: - return (FuncDeclaration *)dtors.data[0]; + return dtors.tdata()[0]; default: e = NULL; for (size_t i = 0; i < dtors.dim; i++) - { FuncDeclaration *fd = (FuncDeclaration *)dtors.data[i]; + { FuncDeclaration *fd = dtors.tdata()[i]; Expression *ex = new ThisExp(0); ex = new DotVarExp(0, ex, fd, 0); ex = new CallExp(0, ex); diff --git a/dmd2/cond.c b/dmd2/cond.c index 51557961..a37f2738 100644 --- a/dmd2/cond.c +++ b/dmd2/cond.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2008 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -23,13 +23,13 @@ #include "mtype.h" #include "scope.h" -int findCondition(Array *ids, Identifier *ident) +int findCondition(Strings *ids, Identifier *ident) { if (ids) { - for (int i = 0; i < ids->dim; i++) + for (size_t i = 0; i < ids->dim; i++) { - const char *id = (const char *)ids->data[i]; + const char *id = ids->tdata()[i]; if (strcmp(id, ident->toChars()) == 0) return TRUE; @@ -72,8 +72,8 @@ void DebugCondition::setGlobalLevel(unsigned level) void DebugCondition::addGlobalIdent(const char *ident) { if (!global.params.debugids) - global.params.debugids = new Array(); - global.params.debugids->push((void *)ident); + global.params.debugids = new Strings(); + global.params.debugids->push((char *)ident); } @@ -96,7 +96,7 @@ int DebugCondition::include(Scope *sc, ScopeDsymbol *s) inc = 1; else { if (!mod->debugidsNot) - mod->debugidsNot = new Array(); + mod->debugidsNot = new Strings(); mod->debugidsNot->push(ident->toChars()); } } @@ -173,8 +173,8 @@ void VersionCondition::addGlobalIdent(const char *ident) void VersionCondition::addPredefinedGlobalIdent(const char *ident) { if (!global.params.versionids) - global.params.versionids = new Array(); - global.params.versionids->push((void *)ident); + global.params.versionids = new Strings(); + global.params.versionids->push((char *)ident); } @@ -199,7 +199,7 @@ int VersionCondition::include(Scope *sc, ScopeDsymbol *s) else { if (!mod->versionidsNot) - mod->versionidsNot = new Array(); + mod->versionidsNot = new Strings(); mod->versionidsNot->push(ident->toChars()); } } @@ -327,19 +327,19 @@ int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd) TemplateParameters parameters; parameters.setDim(1); - parameters.data[0] = (void *)&tp; + parameters.tdata()[0] = &tp; Objects dedtypes; dedtypes.setDim(1); - m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes); + m = targ->deduceType(sc, tspec, ¶meters, &dedtypes); if (m == MATCHnomatch || (m != MATCHexact && tok == TOKequal)) inc = 2; else { inc = 1; - Type *tded = (Type *)dedtypes.data[0]; + Type *tded = (Type *)dedtypes.tdata()[0]; if (!tded) tded = targ; Dsymbol *s = new AliasDeclaration(loc, id, tded); diff --git a/dmd2/cond.h b/dmd2/cond.h index e3cde453..789503a4 100644 --- a/dmd2/cond.h +++ b/dmd2/cond.h @@ -22,7 +22,7 @@ struct DebugCondition; enum TOK; struct HdrGenState; -int findCondition(Array *ids, Identifier *ident); +int findCondition(Strings *ids, Identifier *ident); struct Condition { diff --git a/dmd2/constfold.c b/dmd2/constfold.c index 784bac21..65ee10b8 100644 --- a/dmd2/constfold.c +++ b/dmd2/constfold.c @@ -534,6 +534,21 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) e2 = new IntegerExp(loc, 1, e2->type); n2 = 1; } + if (n2 == -1 && !type->isunsigned()) + { // Check for int.min % -1 + if (n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64) + { + e2->error("integer overflow: int.min % -1"); + e2 = new IntegerExp(loc, 1, e2->type); + n2 = 1; + } + else if (n1 == 0x8000000000000000LL) // long.min % -1 + { + e2->error("integer overflow: long.min % -1"); + e2 = new IntegerExp(loc, 1, e2->type); + n2 = 1; + } + } if (e1->type->isunsigned() || e2->type->isunsigned()) n = ((d_uns64) n1) % ((d_uns64) n2); else @@ -556,7 +571,9 @@ Expression *Shr(Type *type, Expression *e1, Expression *e2) Loc loc = e1->loc; dinteger_t value = e1->toInteger(); - unsigned count = e2->toInteger(); + dinteger_t dcount = e2->toInteger(); + assert(dcount <= 0xFFFFFFFF); + unsigned count = (unsigned)dcount; switch (e1->type->toBasetype()->ty) { case Tint8: @@ -606,18 +623,20 @@ Expression *Ushr(Type *type, Expression *e1, Expression *e2) Loc loc = e1->loc; dinteger_t value = e1->toInteger(); - unsigned count = e2->toInteger(); + dinteger_t dcount = e2->toInteger(); + assert(dcount <= 0xFFFFFFFF); + unsigned count = (unsigned)dcount; switch (e1->type->toBasetype()->ty) { case Tint8: case Tuns8: - assert(0); // no way to trigger this + // Possible only with >>>=. >>> always gets promoted to int. value = (value & 0xFF) >> count; break; case Tint16: case Tuns16: - assert(0); // no way to trigger this + // Possible only with >>>=. >>> always gets promoted to int. value = (value & 0xFFFF) >> count; break; @@ -730,8 +749,8 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) else { for (size_t i = 0; i < es1->elements->dim; i++) - { Expression *ee1 = (Expression *)es1->elements->data[i]; - Expression *ee2 = (Expression *)es2->elements->data[i]; + { Expression *ee1 = (*es1->elements)[i]; + Expression *ee2 = (*es2->elements)[i]; Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); if (v == EXP_CANT_INTERPRET) @@ -744,9 +763,9 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) } else if (e1->op == TOKarrayliteral && e2->op == TOKstring) { // Swap operands and use common code - Expression *e = e1; + Expression *etmp = e1; e1 = e2; - e2 = e; + e2 = etmp; goto Lsa; } else if (e1->op == TOKstring && e2->op == TOKarrayliteral) @@ -760,10 +779,11 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) cmp = 0; else { + cmp = 1; // if dim1 winds up being 0 for (size_t i = 0; i < dim1; i++) { uinteger_t c = es1->charAt(i); - Expression *ee2 = (Expression *)es2->elements->data[i]; + Expression *ee2 = (*es2->elements)[i]; if (ee2->isConst() != 1) return EXP_CANT_INTERPRET; cmp = (c == ee2->toInteger()); @@ -789,8 +809,8 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) { cmp = 1; for (size_t i = 0; i < es1->elements->dim; i++) - { Expression *ee1 = (Expression *)es1->elements->data[i]; - Expression *ee2 = (Expression *)es2->elements->data[i]; + { Expression *ee1 = (*es1->elements)[i]; + Expression *ee2 = (*es2->elements)[i]; if (ee1 == ee2) continue; @@ -1187,7 +1207,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1) assert(sd); Expressions *elements = new Expressions; for (size_t i = 0; i < sd->fields.dim; i++) - { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + { Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); @@ -1252,8 +1272,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) if (i >= es1->len) e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); else - { unsigned value = es1->charAt(i); - e = new IntegerExp(loc, value, type); + { + e = new IntegerExp(loc, es1->charAt(i), type); } } else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64) @@ -1266,7 +1286,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) } else if (e1->op == TOKarrayliteral) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; - e = (Expression *)ale->elements->data[i]; + e = ale->elements->tdata()[i]; e->type = type; if (e->checkSideEffect(2)) e = EXP_CANT_INTERPRET; @@ -1282,7 +1302,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) { e1->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); } else - { e = (Expression *)ale->elements->data[i]; + { e = ale->elements->tdata()[i]; e->type = type; if (e->checkSideEffect(2)) e = EXP_CANT_INTERPRET; @@ -1297,12 +1317,12 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) for (size_t i = ae->keys->dim; i;) { i--; - Expression *ekey = (Expression *)ae->keys->data[i]; + Expression *ekey = ae->keys->tdata()[i]; Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); if (ex == EXP_CANT_INTERPRET) return ex; if (ex->isBool(TRUE)) - { e = (Expression *)ae->values->data[i]; + { e = ae->values->tdata()[i]; e->type = type; if (e->checkSideEffect(2)) e = EXP_CANT_INTERPRET; @@ -1335,7 +1355,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) if (iupr > es1->len || ilwr > iupr) e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); else - { dinteger_t value; + { void *s; size_t len = iupr - ilwr; int sz = es1->sz; @@ -1365,9 +1385,9 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) { Expressions *elements = new Expressions(); elements->setDim(iupr - ilwr); - memcpy(elements->data, - es1->elements->data + ilwr, - (iupr - ilwr) * sizeof(es1->elements->data[0])); + memcpy(elements->tdata(), + es1->elements->tdata() + ilwr, + (iupr - ilwr) * sizeof(es1->elements->tdata()[0])); e = new ArrayLiteralExp(e1->loc, elements); e->type = type; } @@ -1447,7 +1467,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) StringExp *es1 = (StringExp *)e1; StringExp *es2 = (StringExp *)e2; StringExp *es; - Type *t; size_t len = es1->len + es2->len; int sz = es1->sz; @@ -1469,10 +1488,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) es = new StringExp(loc, s, len); es->sz = sz; es->committed = es1->committed | es2->committed; - if (es1->committed) - t = es1->type; - else - t = es2->type; es->type = type; e = es; } @@ -1487,8 +1502,8 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) void *s = mem.malloc((len + 1) * sz); memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz); - for (int i = 0; i < es2->elements->dim; i++) - { Expression *es2e = (Expression *)es2->elements->data[i]; + for (size_t i = 0; i < es2->elements->dim; i++) + { Expression *es2e = es2->elements->tdata()[i]; if (es2e->op != TOKint64) return EXP_CANT_INTERPRET; dinteger_t v = es2e->toInteger(); @@ -1515,8 +1530,8 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) void *s = mem.malloc((len + 1) * sz); memcpy(s, es1->string, es1->len * sz); - for (int i = 0; i < es2->elements->dim; i++) - { Expression *es2e = (Expression *)es2->elements->data[i]; + for (size_t i = 0; i < es2->elements->dim; i++) + { Expression *es2e = es2->elements->tdata()[i]; if (es2e->op != TOKint64) return EXP_CANT_INTERPRET; dinteger_t v = es2e->toInteger(); @@ -1538,7 +1553,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) void *s; StringExp *es1 = (StringExp *)e1; StringExp *es; - Type *t; int sz = es1->sz; dinteger_t v = e2->toInteger(); @@ -1561,7 +1575,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) es = new StringExp(loc, s, len); es->sz = sz; es->committed = es1->committed; - t = es1->type; es->type = type; e = es; } @@ -1571,7 +1584,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) void *s; StringExp *es2 = (StringExp *)e2; StringExp *es; - Type *t; size_t len = 1 + es2->len; int sz = es2->sz; dinteger_t v = e1->toInteger(); @@ -1586,7 +1598,6 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2) es = new StringExp(loc, s, len); es->sz = sz; es->committed = es2->committed; - t = es2->type; es->type = type; e = es; } diff --git a/dmd2/cppmangle.c b/dmd2/cppmangle.c index f6f436cc..a6ef4c26 100644 --- a/dmd2/cppmangle.c +++ b/dmd2/cppmangle.c @@ -40,14 +40,14 @@ struct CppMangleState { - static Array components; + static Voids components; int substitute(OutBuffer *buf, void *p); int exist(void *p); void store(void *p); }; -Array CppMangleState::components; +Voids CppMangleState::components; void writeBase36(OutBuffer *buf, unsigned i) @@ -69,7 +69,7 @@ int CppMangleState::substitute(OutBuffer *buf, void *p) { for (size_t i = 0; i < components.dim; i++) { - if (p == components.data[i]) + if (p == components.tdata()[i]) { /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ... */ @@ -88,7 +88,7 @@ int CppMangleState::exist(void *p) { for (size_t i = 0; i < components.dim; i++) { - if (p == components.data[i]) + if (p == components.tdata()[i]) { return 1; } @@ -409,7 +409,7 @@ void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *a if (arguments) { for (size_t i = 0; i < arguments->dim; i++) - { Parameter *arg = (Parameter *)arguments->data[i]; + { Parameter *arg = arguments->tdata()[i]; Type *t = arg->type; if (arg->storageClass & (STCout | STCref)) t = t->referenceTo(); diff --git a/dmd2/declaration.c b/dmd2/declaration.c index 49081815..2f04f8d2 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -83,6 +83,7 @@ enum PROT Declaration::prot() */ #if DMDV2 + void Declaration::checkModify(Loc loc, Scope *sc, Type *t) { if (sc->incontract && isParameter()) @@ -91,40 +92,10 @@ void Declaration::checkModify(Loc loc, Scope *sc, Type *t) if (sc->incontract && isResult()) error(loc, "cannot modify result '%s' in contract", toChars()); - if (isCtorinit() && !t->isMutable()) + if (isCtorinit() && !t->isMutable() || + (storage_class & STCnodefaultctor)) { // It's only modifiable if inside the right constructor - Dsymbol *s = sc->func; - while (1) - { - FuncDeclaration *fd = NULL; - if (s) - fd = s->isFuncDeclaration(); - if (fd && - ((fd->isCtorDeclaration() && storage_class & STCfield) || - (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) && - fd->toParent() == toParent() - ) - { - VarDeclaration *v = isVarDeclaration(); - assert(v); - v->ctorinit = 1; - //printf("setting ctorinit\n"); - } - else - { - if (s) - { s = s->toParent2(); - continue; - } - else - { - const char *p = isStatic() ? "static " : ""; - error(loc, "can only initialize %sconst %s inside %sconstructor", - p, toChars(), p); - } - } - break; - } + modifyFieldVar(loc, sc, isVarDeclaration(), NULL); } else { @@ -185,7 +156,7 @@ Type *TupleDeclaration::getType() /* It's only a type tuple if all the Object's are types */ for (size_t i = 0; i < objects->dim; i++) - { Object *o = (Object *)objects->data[i]; + { Object *o = objects->tdata()[i]; if (o->dyncast() != DYNCAST_TYPE) { @@ -196,12 +167,13 @@ Type *TupleDeclaration::getType() /* We know it's a type tuple, so build the TypeTuple */ + Types *types = (Types *)objects; Parameters *args = new Parameters(); args->setDim(objects->dim); OutBuffer buf; int hasdeco = 1; - for (size_t i = 0; i < objects->dim; i++) - { Type *t = (Type *)objects->data[i]; + for (size_t i = 0; i < types->dim; i++) + { Type *t = types->tdata()[i]; //printf("type = %s\n", t->toChars()); #if 0 @@ -212,7 +184,7 @@ Type *TupleDeclaration::getType() #else Parameter *arg = new Parameter(0, t, NULL, NULL); #endif - args->data[i] = (void *)arg; + args->tdata()[i] = arg; if (!t->deco) hasdeco = 0; } @@ -229,7 +201,7 @@ int TupleDeclaration::needThis() { //printf("TupleDeclaration::needThis(%s)\n", toChars()); for (size_t i = 0; i < objects->dim; i++) - { Object *o = (Object *)objects->data[i]; + { Object *o = objects->tdata()[i]; if (o->dyncast() == DYNCAST_EXPRESSION) { Expression *e = (Expression *)o; if (e->op == TOKdsymbol) @@ -753,7 +725,7 @@ void VarDeclaration::semantic(Scope *sc) printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); printf(" type = %s\n", type ? type->toChars() : "null"); printf(" stc = x%x\n", sc->stc); - printf(" storage_class = x%x\n", storage_class); + printf(" storage_class = x%llx\n", storage_class); printf("linkage = %d\n", sc->linkage); //if (strcmp(toChars(), "mul") == 0) halt(); #endif @@ -854,8 +826,8 @@ void VarDeclaration::semantic(Scope *sc) Dsymbol *s = type->toDsymbol(sc); if (s) { - AggregateDeclaration *ad = s->isAggregateDeclaration(); - if (ad && ad->hasUnions) + AggregateDeclaration *ad2 = s->isAggregateDeclaration(); + if (ad2 && ad2->hasUnions) { if (sc->func->setUnsafe()) error("unions containing pointers are not allowed in @safe functions"); @@ -899,6 +871,103 @@ void VarDeclaration::semantic(Scope *sc) Objects *exps = new Objects(); exps->setDim(nelems); Expression *ie = init ? init->toExpression() : NULL; + if (ie) ie = ie->semantic(sc); + + if (nelems > 0 && ie) + { + Expressions *iexps = new Expressions(); + iexps->push(ie); + + Expressions *exps = new Expressions(); + + for (size_t pos = 0; pos < iexps->dim; pos++) + { + Lexpand1: + Expression *e = iexps->tdata()[pos]; + Parameter *arg = Parameter::getNth(tt->arguments, pos); + arg->type = arg->type->semantic(loc, sc); + //printf("[%d] iexps->dim = %d, ", pos, iexps->dim); + //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars()); + //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); + + if (e != ie) + { + if (iexps->dim > nelems) + goto Lnomatch; + if (e->type->implicitConvTo(arg->type)) + continue; + } + + if (e->op == TOKtuple) + { + TupleExp *te = (TupleExp *)e; + if (iexps->dim - 1 + te->exps->dim > nelems) + goto Lnomatch; + + iexps->remove(pos); + iexps->insert(pos, te->exps); + goto Lexpand1; + } + else if (isAliasThisTuple(e)) + { + Identifier *id = Lexer::uniqueId("__tup"); + ExpInitializer *ei = new ExpInitializer(e->loc, e); + VarDeclaration *v = new VarDeclaration(loc, NULL, id, ei); + v->storage_class = STCctfe | STCref | STCforeach; + VarExp *ve = new VarExp(loc, v); + ve->type = e->type; + + exps->setDim(1); + (*exps)[0] = ve; + expandAliasThisTuples(exps, 0); + + for (size_t u = 0; u < exps->dim ; u++) + { + Lexpand2: + Expression *ee = (*exps)[u]; + Parameter *arg = Parameter::getNth(tt->arguments, pos + u); + arg->type = arg->type->semantic(loc, sc); + //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("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); + + size_t iexps_dim = iexps->dim - 1 + exps->dim; + if (iexps_dim > nelems) + goto Lnomatch; + if (ee->type->implicitConvTo(arg->type)) + continue; + + if (expandAliasThisTuples(exps, u) != -1) + goto Lexpand2; + } + + if ((*exps)[0] != ve) + { + Expression *e0 = (*exps)[0]; + (*exps)[0] = new CommaExp(loc, new DeclarationExp(loc, v), e0); + (*exps)[0]->type = e0->type; + + iexps->remove(pos); + iexps->insert(pos, exps); + goto Lexpand1; + } + } + } + if (iexps->dim < nelems) + goto Lnomatch; + + ie = new TupleExp(init->loc, iexps); + } +Lnomatch: + + if (ie && ie->op == TOKtuple) + { size_t tedim = ((TupleExp *)ie)->exps->dim; + if (tedim != 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 + ((TupleExp *)ie)->exps->push(new ErrorExp()); + } + } for (size_t i = 0; i < nelems; i++) { Parameter *arg = Parameter::getNth(tt->arguments, i); @@ -911,7 +980,7 @@ void VarDeclaration::semantic(Scope *sc) Expression *einit = ie; if (ie && ie->op == TOKtuple) - { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; + { einit = ((TupleExp *)ie)->exps->tdata()[i]; } Initializer *ti = init; if (einit) @@ -932,7 +1001,7 @@ void VarDeclaration::semantic(Scope *sc) } #endif Expression *e = new DsymbolExp(loc, v); - exps->data[i] = e; + exps->tdata()[i] = e; } TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); v2->isexp = 1; @@ -940,7 +1009,6 @@ void VarDeclaration::semantic(Scope *sc) return; } -Lagain: /* Storage class can modify the type */ type = type->addStorageClass(storage_class); @@ -991,12 +1059,19 @@ Lagain: if (storage_class & (STCconst | STCimmutable) && init) { - if (!type->toBasetype()->isTypeBasic()) + if (!tb->isTypeBasic()) storage_class |= STCstatic; } else -#endif + { aad->addField(sc, this); + if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor || + tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor) + aad->noDefaultCtor = TRUE; + } +#else + aad->addField(sc, this); +#endif } InterfaceDeclaration *id = parent->isInterfaceDeclaration(); @@ -1020,10 +1095,10 @@ Lagain: } // If it's a member template - AggregateDeclaration *ad = ti->tempdecl->isMember(); - if (ad && storage_class != STCundefined) + AggregateDeclaration *ad2 = ti->tempdecl->isMember(); + if (ad2 && storage_class != STCundefined) { - error("cannot use template to add field to aggregate '%s'", ad->toChars()); + error("cannot use template to add field to aggregate '%s'", ad2->toChars()); } } } @@ -1041,6 +1116,21 @@ Lagain: { error("only fields, parameters or stack based variables can be inout"); } + + if (!(storage_class & (STCctfe | STCref)) && tb->ty == Tstruct && + ((TypeStruct *)tb)->sym->noDefaultCtor) + { + if (!init) + { if (storage_class & STCfield) + /* For fields, we'll check the constructor later to make sure it is initialized + */ + storage_class |= STCnodefaultctor; + else if (storage_class & STCparameter) + ; + else + error("initializer required for type %s", type->toChars()); + } + } #endif if (type->isscope() && !noscope) @@ -1173,7 +1263,7 @@ Lagain: ei->exp = ei->exp->semantic(sc); if (!ei->exp->implicitConvTo(type)) { - int dim = ((TypeSArray *)t)->dim->toInteger(); + dinteger_t dim = ((TypeSArray *)t)->dim->toInteger(); // If multidimensional static array, treat as one large array while (1) { @@ -1335,15 +1425,15 @@ Lagain: * because the postblit doesn't get run on the initialization of w. */ - Type *tb = e->type->toBasetype(); - if (tb->ty == Tstruct) - { StructDeclaration *sd = ((TypeStruct *)tb)->sym; + Type *tb2 = e->type->toBasetype(); + if (tb2->ty == Tstruct) + { StructDeclaration *sd = ((TypeStruct *)tb2)->sym; Type *typeb = type->toBasetype(); /* Look to see if initializer involves a copy constructor * (which implies a postblit) */ if (sd->cpctor && // there is a copy constructor - typeb->equals(tb)) // rvalue is the same struct + typeb->equals(tb2)) // rvalue is the same struct { // The only allowable initializer is a (non-copy) constructor if (e->op == TOKcall) @@ -1571,8 +1661,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) if (loc.filename) fdthis->getLevel(loc, fdv); - for (int i = 0; i < nestedrefs.dim; i++) - { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i]; + for (size_t i = 0; i < nestedrefs.dim; i++) + { FuncDeclaration *f = nestedrefs.tdata()[i]; if (f == fdthis) goto L1; } @@ -1580,8 +1670,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) L1: ; - for (int i = 0; i < fdv->closureVars.dim; i++) - { Dsymbol *s = (Dsymbol *)fdv->closureVars.data[i]; + for (size_t i = 0; i < fdv->closureVars.dim; i++) + { Dsymbol *s = fdv->closureVars.tdata()[i]; if (s == this) goto L2; } @@ -1834,6 +1924,15 @@ Expression *VarDeclaration::callScopeDtor(Scope *sc) return e; } +/****************************************** + */ + +void ObjectNotFound(Identifier *id) +{ + Type::error(0, "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars()); + fatal(); +} + /********************************* ClassInfoDeclaration ****************************/ @@ -1905,6 +2004,10 @@ void TypeInfoDeclaration::semantic(Scope *sc) TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoconst) + { + ObjectNotFound(Id::TypeInfo_Const); + } type = Type::typeinfoconst->type; } #endif @@ -1915,6 +2018,10 @@ TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoinvariant) + { + ObjectNotFound(Id::TypeInfo_Invariant); + } type = Type::typeinfoinvariant->type; } #endif @@ -1925,6 +2032,10 @@ TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoshared) + { + ObjectNotFound(Id::TypeInfo_Shared); + } type = Type::typeinfoshared->type; } #endif @@ -1935,6 +2046,10 @@ TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfowild) + { + ObjectNotFound(Id::TypeInfo_Wild); + } type = Type::typeinfowild->type; } #endif @@ -1944,6 +2059,10 @@ TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo) TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfostruct) + { + ObjectNotFound(Id::TypeInfo_Struct); + } type = Type::typeinfostruct->type; } @@ -1952,6 +2071,10 @@ TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoclass) + { + ObjectNotFound(Id::TypeInfo_Class); + } type = Type::typeinfoclass->type; } @@ -1960,6 +2083,10 @@ TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfointerface) + { + ObjectNotFound(Id::TypeInfo_Interface); + } type = Type::typeinfointerface->type; } @@ -1968,6 +2095,10 @@ TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfotypedef) + { + ObjectNotFound(Id::TypeInfo_Typedef); + } type = Type::typeinfotypedef->type; } @@ -1976,6 +2107,10 @@ TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfopointer) + { + ObjectNotFound(Id::TypeInfo_Pointer); + } type = Type::typeinfopointer->type; } @@ -1984,6 +2119,10 @@ TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoarray) + { + ObjectNotFound(Id::TypeInfo_Array); + } type = Type::typeinfoarray->type; } @@ -1992,6 +2131,10 @@ TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfostaticarray) + { + ObjectNotFound(Id::TypeInfo_StaticArray); + } type = Type::typeinfostaticarray->type; } @@ -2000,6 +2143,10 @@ TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoassociativearray) + { + ObjectNotFound(Id::TypeInfo_AssociativeArray); + } type = Type::typeinfoassociativearray->type; } @@ -2008,6 +2155,10 @@ TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *t TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfoenum) + { + ObjectNotFound(Id::TypeInfo_Enum); + } type = Type::typeinfoenum->type; } @@ -2016,6 +2167,10 @@ TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfofunction) + { + ObjectNotFound(Id::TypeInfo_Function); + } type = Type::typeinfofunction->type; } @@ -2024,6 +2179,10 @@ TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfodelegate) + { + ObjectNotFound(Id::TypeInfo_Delegate); + } type = Type::typeinfodelegate->type; } @@ -2032,6 +2191,10 @@ TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) : TypeInfoDeclaration(tinfo, 0) { + if (!Type::typeinfotypelist) + { + ObjectNotFound(Id::TypeInfo_Tuple); + } type = Type::typeinfotypelist->type; } diff --git a/dmd2/declaration.h b/dmd2/declaration.h index d1d53a33..7941a0eb 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -95,6 +95,7 @@ enum PURE; #define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static #define STCdisable 0x2000000000LL // for functions that are not callable #define STCresult 0x4000000000LL // for result variables passed to out contracts +#define STCnodefaultctor 0x8000000000LL // must be set inside constructor struct Match { @@ -159,7 +160,7 @@ struct Declaration : Dsymbol int isParameter() { return storage_class & STCparameter; } int isDeprecated() { return storage_class & STCdeprecated; } int isOverride() { return storage_class & STCoverride; } - int isResult() { return storage_class & STCresult; } + StorageClass isResult() { return storage_class & STCresult; } int isIn() { return storage_class & STCin; } int isOut() { return storage_class & STCout; } @@ -689,7 +690,7 @@ enum BUILTIN { }; struct FuncDeclaration : Declaration { - Array *fthrows; // Array of Type's of exceptions (not used) + Types *fthrows; // Array of Type's of exceptions (not used) Statement *frequire; Statement *fensure; Statement *fbody; @@ -710,7 +711,7 @@ struct FuncDeclaration : Declaration VarDeclaration *v_argptr; // '_argptr' variable #endif VarDeclaration *v_argsave; // save area for args passed in registers for variadic functions - Dsymbols *parameters; // Array of VarDeclaration's for parameters + VarDeclarations *parameters; // Array of VarDeclaration's for parameters DsymbolTable *labtab; // statement label symbol table Declaration *overnext; // next in overload list Loc endloc; // location of closing curly bracket @@ -749,7 +750,7 @@ struct FuncDeclaration : Declaration int tookAddressOf; // set if someone took the address of // this function - Dsymbols closureVars; // local variables in this function + VarDeclarations closureVars; // local variables in this function // which are referenced by nested // functions @@ -773,7 +774,7 @@ struct FuncDeclaration : Declaration void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); int overrides(FuncDeclaration *fd); - int findVtblIndex(Array *vtbl, int dim); + int findVtblIndex(Dsymbols *vtbl, int dim); int overloadInsert(Dsymbol *s); FuncDeclaration *overloadExactMatch(Type *t, Module* from); FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0, Module* from=NULL); @@ -796,6 +797,7 @@ struct FuncDeclaration : Declaration int isCodeseg(); int isOverloadable(); enum PURE isPure(); + enum PURE isPureBypassingInference(); bool setImpure(); int isSafe(); int isTrusted(); @@ -809,7 +811,7 @@ struct FuncDeclaration : Declaration Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL); void inlineScan(); int canInline(int hasthis, int hdrscan = 0); - Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments); + Expression *doInline(InlineScanState *iss, Expression *ethis, Expressions *arguments); const char *kind(); void toDocBuffer(OutBuffer *buf); FuncDeclaration *isUnique(); diff --git a/dmd2/delegatize.c b/dmd2/delegatize.c index 3f5b7257..2f174159 100644 --- a/dmd2/delegatize.c +++ b/dmd2/delegatize.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2007 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -60,8 +60,8 @@ void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a) //printf("arrayExpressionScanForNestedRef(%p)\n", a); if (a) { - for (int i = 0; i < a->dim; i++) - { Expression *e = (Expression *)a->data[i]; + for (size_t i = 0; i < a->dim; i++) + { Expression *e = (*a)[i]; if (e) { diff --git a/dmd2/doc.c b/dmd2/doc.c index 9debd549..4b980056 100644 --- a/dmd2/doc.c +++ b/dmd2/doc.c @@ -65,9 +65,11 @@ struct MacroSection : Section void write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf); }; +typedef ArrayBase
Sections; + struct DocComment { - Array sections; // Section*[] + Sections sections; // Section*[] Section *summary; Section *copyright; @@ -223,9 +225,9 @@ void Module::gendocfile() global.params.ddocfiles->shift(p); // Override with the ddoc macro files from the command line - for (int i = 0; i < global.params.ddocfiles->dim; i++) + for (size_t i = 0; i < global.params.ddocfiles->dim; i++) { - FileName f((char *)global.params.ddocfiles->data[i], 0); + FileName f(global.params.ddocfiles->tdata()[i], 0); File file(&f); file.readv(); // BUG: convert file contents to UTF-8 before use @@ -250,12 +252,14 @@ void Module::gendocfile() Macro::define(¯otable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p)); } - time_t t; - time(&t); - char *p = ctime(&t); - p = mem.strdup(p); - Macro::define(¯otable, (unsigned char *)"DATETIME", 8, (unsigned char *)p, strlen(p)); - Macro::define(¯otable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4); + // Set time macros + { time_t t; + time(&t); + char *p = ctime(&t); + p = mem.strdup(p); + Macro::define(¯otable, (unsigned char *)"DATETIME", 8, (unsigned char *)p, strlen(p)); + Macro::define(¯otable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4); + } char *docfilename = docfile->toChars(); Macro::define(¯otable, (unsigned char *)"DOCFILENAME", 11, (unsigned char *)docfilename, strlen(docfilename)); @@ -526,9 +530,9 @@ void ScopeDsymbol::emitMemberComments(Scope *sc) buf->writestring(m); unsigned offset2 = buf->offset; // to see if we write anything sc = sc->push(this); - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = (*members)[i]; //printf("\ts = '%s'\n", s->toChars()); s->emitComment(sc); } @@ -698,9 +702,9 @@ void EnumDeclaration::emitComment(Scope *sc) // if (!comment) { if (isAnonymous() && members) { - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = (*members)[i]; s->emitComment(sc); } return; @@ -957,8 +961,8 @@ void ClassDeclaration::toDocBuffer(OutBuffer *buf) buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); } int any = 0; - for (int i = 0; i < baseclasses->dim; i++) - { BaseClass *bc = (BaseClass *)baseclasses->data[i]; + for (size_t i = 0; i < baseclasses->dim; i++) + { BaseClass *bc = (*baseclasses)[i]; if (bc->protection == PROTprivate) continue; @@ -1013,8 +1017,7 @@ DocComment::DocComment() } DocComment *DocComment::parse(Scope *sc, Dsymbol *s, unsigned char *comment) -{ unsigned idlen; - +{ //printf("parse(%s): '%s'\n", s->toChars(), comment); if (sc->lastdc && isDitto(comment)) return NULL; @@ -1025,16 +1028,16 @@ DocComment *DocComment::parse(Scope *sc, Dsymbol *s, unsigned char *comment) dc->parseSections(comment); - for (int i = 0; i < dc->sections.dim; i++) - { Section *s = (Section *)dc->sections.data[i]; + for (size_t i = 0; i < dc->sections.dim; i++) + { Section *sec = dc->sections[i]; - if (icmp("copyright", s->name, s->namelen) == 0) + if (icmp("copyright", sec->name, sec->namelen) == 0) { - dc->copyright = s; + dc->copyright = sec; } - if (icmp("macros", s->name, s->namelen) == 0) + if (icmp("macros", sec->name, sec->namelen) == 0) { - dc->macros = s; + dc->macros = sec; } } @@ -1170,8 +1173,8 @@ void DocComment::writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf) if (sections.dim) { buf->writestring("$(DDOC_SECTIONS \n"); - for (int i = 0; i < sections.dim; i++) - { Section *sec = (Section *)sections.data[i]; + for (size_t i = 0; i < sections.dim; i++) + { Section *sec = sections[i]; if (sec->nooutput) continue; @@ -1748,7 +1751,7 @@ Parameter *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len) if (tf->parameters) { for (size_t k = 0; k < tf->parameters->dim; k++) - { Parameter *arg = (Parameter *)tf->parameters->data[k]; + { Parameter *arg = (*tf->parameters)[k]; if (arg->ident && cmp(arg->ident->toChars(), p, len) == 0) { @@ -2007,7 +2010,6 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset) break; } } - Ldone: if (inCode) s->error("unmatched --- in DDoc comment"); ; diff --git a/dmd2/dsymbol.c b/dmd2/dsymbol.c index 3ba307be..ef664030 100644 --- a/dmd2/dsymbol.c +++ b/dmd2/dsymbol.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -123,15 +123,15 @@ int Dsymbol::oneMember(Dsymbol **ps) * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. */ -int Dsymbol::oneMembers(Array *members, Dsymbol **ps) +int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps) { //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); Dsymbol *s = NULL; if (members) { - for (int i = 0; i < members->dim; i++) - { Dsymbol *sx = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *sx = (*members)[i]; int x = sx->oneMember(ps); //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); @@ -216,7 +216,6 @@ const char *Dsymbol::toPrettyChars() char *Dsymbol::locToChars() { OutBuffer buf; - char *p; if (!loc.filename) // avoid bug 5861. { @@ -459,14 +458,20 @@ AggregateDeclaration *Dsymbol::isThis() return NULL; } -ClassDeclaration *Dsymbol::isClassMember() // are we a member of a class? +AggregateDeclaration *Dsymbol::isAggregateMember() // are we a member of an aggregate? { Dsymbol *parent = toParent(); - if (parent && parent->isClassDeclaration()) - return (ClassDeclaration *)parent; + if (parent && parent->isAggregateDeclaration()) + return (AggregateDeclaration *)parent; return NULL; } +ClassDeclaration *Dsymbol::isClassMember() // are we a member of a class? +{ + AggregateDeclaration *ad = isAggregateMember(); + return ad ? ad->isClassDeclaration() : NULL; +} + void Dsymbol::defineRef(Dsymbol *s) { assert(0); @@ -616,13 +621,13 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc) goto L1; } - for (; sc; sc = sc->enclosing) + for (Scope *sc2 = sc; sc2; sc2 = sc2->enclosing) { - if (sc->scopesym && sc->scopesym->isDeprecated()) + if (sc2->scopesym && sc2->scopesym->isDeprecated()) goto L1; // If inside a StorageClassDeclaration that is deprecated - if (sc->stc & STCdeprecated) + if (sc2->stc & STCdeprecated) goto L1; } @@ -653,6 +658,10 @@ Module *Dsymbol::getModule() Dsymbol *s; //printf("Dsymbol::getModule()\n"); + TemplateDeclaration *td = getFuncTemplateDecl(this); + if (td) + return td->getModule(); + s = this; while (s) { @@ -713,12 +722,12 @@ Dsymbols *Dsymbol::arraySyntaxCopy(Dsymbols *a) if (a) { b = (Dsymbols *)a->copy(); - for (int i = 0; i < b->dim; i++) + for (size_t i = 0; i < b->dim; i++) { - Dsymbol *s = (Dsymbol *)b->data[i]; + Dsymbol *s = (*b)[i]; s = s->syntaxCopy(NULL); - b->data[i] = (void *)s; + (*b)[i] = s; } } return b; @@ -823,8 +832,8 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) OverloadSet *a = NULL; // Look in imported modules - for (int i = 0; i < imports->dim; i++) - { ScopeDsymbol *ss = (ScopeDsymbol *)imports->data[i]; + for (size_t i = 0; i < imports->dim; i++) + { ScopeDsymbol *ss = (*imports)[i]; Dsymbol *s2; // If private import, don't search it @@ -871,12 +880,12 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) a = new OverloadSet(); /* Don't add to a[] if s2 is alias of previous sym */ - for (int j = 0; j < a->a.dim; j++) - { Dsymbol *s3 = (Dsymbol *)a->a.data[j]; + for (size_t j = 0; j < a->a.dim; j++) + { Dsymbol *s3 = a->a[j]; if (s2->toAlias() == s3->toAlias()) { if (s3->isDeprecated()) - a->a.data[j] = (void *)s2; + a->a[j] = s2; goto Lcontinue; } } @@ -922,13 +931,11 @@ void ScopeDsymbol::importScope(ScopeDsymbol *s, enum PROT protection) if (s != this) { if (!imports) - imports = new Array(); + imports = new ScopeDsymbols(); else { - for (int i = 0; i < imports->dim; i++) - { ScopeDsymbol *ss; - - ss = (ScopeDsymbol *) imports->data[i]; + for (size_t i = 0; i < imports->dim; i++) + { ScopeDsymbol *ss = (*imports)[i]; if (ss == s) // if already imported { if (protection > prots[i]) @@ -1017,13 +1024,13 @@ Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s) */ #if DMDV2 -size_t ScopeDsymbol::dim(Array *members) +size_t ScopeDsymbol::dim(Dsymbols *members) { size_t n = 0; if (members) { for (size_t i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + { Dsymbol *s = (*members)[i]; AttribDeclaration *a = s->isAttribDeclaration(); if (a) @@ -1047,15 +1054,17 @@ size_t ScopeDsymbol::dim(Array *members) */ #if DMDV2 -Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) +Dsymbol *ScopeDsymbol::getNth(Dsymbols *members, size_t nth, size_t *pn) { if (!members) return NULL; size_t n = 0; for (size_t i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + { Dsymbol *s = (*members)[i]; AttribDeclaration *a = s->isAttribDeclaration(); + TemplateMixin *tm = s->isTemplateMixin(); + TemplateInstance *ti = s->isTemplateInstance(); if (a) { @@ -1063,6 +1072,14 @@ Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) if (s) return s; } + else if (tm) + { + s = getNth(tm->members, nth - n, &n); + if (s) + return s; + } + else if (ti) + ; else if (n == nth) return s; else diff --git a/dmd2/dsymbol.h b/dmd2/dsymbol.h index 7bd458ad..930cae6d 100644 --- a/dmd2/dsymbol.h +++ b/dmd2/dsymbol.h @@ -187,7 +187,8 @@ struct Dsymbol : Object virtual int isforwardRef(); virtual void defineRef(Dsymbol *s); virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member - virtual ClassDeclaration *isClassMember(); // are we a member of a class? + AggregateDeclaration *isAggregateMember(); // are we a member of an aggregate? + ClassDeclaration *isClassMember(); // are we a member of a class? virtual int isExport(); // is Dsymbol exported? virtual int isImportedSymbol(); // is Dsymbol imported? virtual int isDeprecated(); // is Dsymbol deprecated? @@ -202,7 +203,7 @@ struct Dsymbol : Object virtual enum PROT prot(); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees virtual int oneMember(Dsymbol **ps); - static int oneMembers(Array *members, Dsymbol **ps); + static int oneMembers(Dsymbols *members, Dsymbol **ps); virtual int hasPointers(); virtual void addLocalClass(ClassDeclarations *) { } virtual void checkCtorConstInit() { } @@ -288,7 +289,7 @@ struct ScopeDsymbol : Dsymbol Dsymbols *members; // all Dsymbol's in this scope DsymbolTable *symtab; // members[] sorted into table - Array *imports; // imported ScopeDsymbol's + ScopeDsymbols *imports; // imported ScopeDsymbol's unsigned char *prots; // array of PROT, one for each import ScopeDsymbol(); @@ -306,8 +307,8 @@ struct ScopeDsymbol : Dsymbol void emitMemberComments(Scope *sc); - static size_t dim(Array *members); - static Dsymbol *getNth(Array *members, size_t nth, size_t *pn = NULL); + static size_t dim(Dsymbols *members); + static Dsymbol *getNth(Dsymbols *members, size_t nth, size_t *pn = NULL); ScopeDsymbol *isScopeDsymbol() { return this; } }; diff --git a/dmd2/dump.c b/dmd2/dump.c index c443d94e..4fd0d04e 100644 --- a/dmd2/dump.c +++ b/dmd2/dump.c @@ -36,7 +36,7 @@ void dumpExpressions(int i, Expressions *exps) if (exps) { for (size_t j = 0; j < exps->dim; j++) - { Expression *e = (Expression *)exps->data[j]; + { Expression *e = exps->tdata()[j]; indent(i); printf("(\n"); e->dump(i + 2); diff --git a/dmd2/enum.c b/dmd2/enum.c index 1fa4ad71..881ba2d8 100644 --- a/dmd2/enum.c +++ b/dmd2/enum.c @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -71,9 +71,9 @@ void EnumDeclaration::semantic0(Scope *sc) return; if (!isAnonymous() || memtype) return; - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); + EnumMember *em = (*members)[i]->isEnumMember(); if (em && (em->type || em->value)) return; } @@ -165,9 +165,9 @@ void EnumDeclaration::semantic(Scope *sc) error("enum %s must have at least one member", toChars()); int first = 1; Expression *elast = NULL; - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); + EnumMember *em = (*members)[i]->isEnumMember(); Expression *e; if (!em) @@ -242,13 +242,13 @@ void EnumDeclaration::semantic(Scope *sc) { /* Anonymous enum members get added to enclosing scope. */ - for (Scope *scx = sce; scx; scx = scx->enclosing) + for (Scope *sct = sce; sct; sct = sct->enclosing) { - if (scx->scopesym) + if (sct->scopesym) { - if (!scx->scopesym->symtab) - scx->scopesym->symtab = new DsymbolTable(); - em->addMember(sce, scx->scopesym, 1); + if (!sct->scopesym->symtab) + sct->scopesym->symtab = new DsymbolTable(); + em->addMember(sce, sct->scopesym, 1); break; } } @@ -308,8 +308,7 @@ int EnumDeclaration::oneMember(Dsymbol **ps) } void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -{ int i; - +{ buf->writestring("enum "); if (ident) { buf->writestring(ident->toChars()); @@ -329,9 +328,9 @@ void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); buf->writeByte('{'); buf->writenl(); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); + EnumMember *em = (*members)[i]->isEnumMember(); if (!em) continue; //buf->writestring(" "); diff --git a/dmd2/expression.c b/dmd2/expression.c index 67bf6e67..253c4176 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -40,7 +40,9 @@ int isnan(double); #include "rmem.h" #if IN_DMD #include "port.h" +#include "root.h" #endif + #include "mtype.h" #include "init.h" #include "expression.h" @@ -61,7 +63,7 @@ int isnan(double); #include "doc.h" #if IN_DMD -Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim); +Expression *createTypeInfoArray(Scope *sc, Expression *args[], unsigned dim); #endif Expression *expandVar(int result, VarDeclaration *v); @@ -191,15 +193,16 @@ FuncDeclaration *hasThis(Scope *sc) break; Dsymbol *parent = fd->parent; - while (parent) + while (1) { + if (!parent) + goto Lno; TemplateInstance *ti = parent->isTemplateInstance(); if (ti) parent = ti->parent; else break; } - fd = parent->isFuncDeclaration(); } @@ -276,10 +279,10 @@ Expressions *arrayExpressionSemantic(Expressions *exps, Scope *sc) if (exps) { for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; if (e) { e = e->semantic(sc); - exps->data[i] = (void *)e; + (*exps)[i] = e; } } } @@ -297,7 +300,7 @@ int arrayExpressionCanThrow(Expressions *exps, bool mustNotThrow) if (exps) { for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; if (e && e->canThrow(mustNotThrow)) return 1; } @@ -316,7 +319,7 @@ void expandTuples(Expressions *exps) if (exps) { for (size_t i = 0; i < exps->dim; i++) - { Expression *arg = (Expression *)exps->data[i]; + { Expression *arg = (*exps)[i]; if (!arg) continue; @@ -345,12 +348,83 @@ void expandTuples(Expressions *exps) exps->insert(i, te->exps); // replace with tuple contents if (i == exps->dim) return; // empty tuple, no more arguments - arg = (Expression *)exps->data[i]; + arg = (*exps)[i]; } } } } +/**************************************** + * Expand alias this tuples. + */ + +TupleDeclaration *isAliasThisTuple(Expression *e) +{ + if (e->type) + { + Type *t = e->type->toBasetype(); + AggregateDeclaration *ad; + if (t->ty == Tstruct) + { + ad = ((TypeStruct *)t)->sym; + goto L1; + } + else if (t->ty == Tclass) + { + ad = ((TypeClass *)t)->sym; + L1: + Dsymbol *s = ad->aliasthis; + if (s && s->isVarDeclaration()) + { + TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration(); + if (td && td->isexp) + return td; + } + } + } + return NULL; +} + +int expandAliasThisTuples(Expressions *exps, int starti) +{ + if (!exps || exps->dim == 0) + return -1; + + for (size_t u = starti; u < exps->dim; u++) + { + Expression *exp = exps->tdata()[u]; + TupleDeclaration *td = isAliasThisTuple(exp); + if (td) + { + exps->remove(u); + for (size_t i = 0; iobjects->dim; ++i) + { + Expression *e = isExpression(td->objects->tdata()[i]); + assert(e); + assert(e->op == TOKdsymbol); + DsymbolExp *se = (DsymbolExp *)e; + Declaration *d = se->s->isDeclaration(); + assert(d); + e = new DotVarExp(exp->loc, exp, d); + assert(d->type); + e->type = d->type; + exps->insert(u + i, e); + } + #if 0 + printf("expansion ->\n"); + for (size_t i = 0; idim; ++i) + { + Expression *e = exps->tdata()[i]; + printf("\texps[%d] e = %s %s\n", i, Token::tochars[e->op], e->toChars()); + } + #endif + return u; + } + } + + return -1; +} + Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt) { #if DMDV1 @@ -358,7 +432,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt */ Type *t0 = NULL; for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; if (!e->type) { error("%s has no value", e->toChars()); @@ -370,7 +444,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt t0 = e->type; else e = e->implicitCastTo(sc, t0); - exps->data[i] = (void *)e; + (*exps)[i] = e; } if (!t0) @@ -397,7 +471,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt Expression *e0; int j0; for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; e = resolveProperties(sc, e); if (!e->type) @@ -416,7 +490,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt condexp.e2 = e; condexp.loc = e->loc; condexp.semantic(sc); - exps->data[j0] = (void *)condexp.e1; + (*exps)[j0] = condexp.e1; e = condexp.e2; j0 = i; e0 = e; @@ -428,15 +502,15 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt e0 = e; t0 = e->type; } - exps->data[i] = (void *)e; + (*exps)[i] = e; } if (t0) { for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; e = e->implicitCastTo(sc, t0); - exps->data[i] = (void *)e; + (*exps)[i] = e; } } else @@ -449,6 +523,29 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt #endif } +/**************************************** + * Get TemplateDeclaration enclosing FuncDeclaration. + */ + +TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s) +{ + FuncDeclaration *f = s->isFuncDeclaration(); + if (f && f->parent) + { TemplateInstance *ti = f->parent->isTemplateInstance(); + + if (ti && + !ti->isTemplateMixin() && + (ti->name == f->ident || + ti->toAlias()->ident == f->ident) + && + ti->tempdecl && ti->tempdecl->onemember) + { + return ti->tempdecl; + } + } + return NULL; +} + /**************************************** * Preprocess arguments to function. */ @@ -460,7 +557,7 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps) expandTuples(exps); for (size_t i = 0; i < exps->dim; i++) - { Expression *arg = (Expression *)exps->data[i]; + { Expression *arg = (*exps)[i]; if (!arg->type) { @@ -473,7 +570,7 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps) } arg = resolveProperties(sc, arg); - exps->data[i] = (void *) arg; + (*exps)[i] = arg; //arg->rvalue(); #if 0 @@ -481,7 +578,7 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps) { arg = new AddrExp(arg->loc, arg); arg = arg->semantic(sc); - exps->data[i] = (void *) arg; + (*exps)[i] = arg; } #endif } @@ -569,12 +666,17 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, { //printf("functionParameters()\n"); assert(arguments); + assert(fd || tf->next); size_t nargs = arguments ? arguments->dim : 0; size_t nparams = Parameter::dim(tf->parameters); if (nargs > nparams && tf->varargs == 0) error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); + // If inferring return type, and semantic3() needs to be run if not already run + if (!tf->next && fd->inferRetType) + fd->semantic3(fd->scope); + unsigned n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) unsigned wildmatch = 0; @@ -584,7 +686,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expression *arg; if (i < nargs) - arg = (Expression *)arguments->data[i]; + arg = arguments->tdata()[i]; else arg = NULL; Type *tb; @@ -643,7 +745,9 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Identifier *id = Lexer::uniqueId("__arrayArg"); Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i)); t = t->semantic(loc, sc); - VarDeclaration *v = new VarDeclaration(loc, t, id, fd->isSafe() ? NULL : new VoidInitializer(loc)); + bool isSafe = fd ? fd->isSafe() : tf->trust == TRUSTsafe; + VarDeclaration *v = new VarDeclaration(loc, t, id, + isSafe ? NULL : new VoidInitializer(loc)); v->storage_class |= STCctfe; v->semantic(sc); v->parent = sc->parent; @@ -653,7 +757,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, c->type = v->type; for (size_t u = i; u < nargs; u++) - { Expression *a = (Expression *)arguments->data[u]; + { Expression *a = arguments->tdata()[u]; if (tret && !((TypeArray *)tb)->next->equals(a->type)) a = a->toDelegate(sc, tret); @@ -677,7 +781,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *args = new Expressions(); args->setDim(nargs - i); for (size_t u = i; u < nargs; u++) - args->data[u - i] = arguments->data[u]; + args->tdata()[u - i] = arguments->tdata()[u]; arg = new NewExp(loc, NULL, NULL, p->type, args); break; } @@ -880,7 +984,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, } arg = arg->optimize(WANTvalue); L3: - arguments->data[i] = (void *) arg; + arguments->tdata()[i] = arg; if (done) break; } @@ -890,15 +994,11 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, if (tf->linkage == LINKd && tf->varargs == 1) { assert(arguments->dim >= nparams); - Expression *e = createTypeInfoArray(sc, (Expression **)&arguments->data[nparams], + Expression *e = createTypeInfoArray(sc, (Expression **)&arguments->tdata()[nparams], arguments->dim - nparams); arguments->insert(0, e); } #endif - // If inferring return type, and semantic3() needs to be run if not already run - if (!tf->next && fd->inferRetType) - fd->semantic3(fd->scope); - Type *tret = tf->next; if (wildmatch) { /* Adjust function return type based on wildmatch @@ -957,7 +1057,7 @@ void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs) if (arguments) { for (size_t i = 0; i < arguments->dim; i++) - { Expression *arg = (Expression *)arguments->data[i]; + { Expression *arg = arguments->tdata()[i]; if (arg) { if (i) @@ -978,7 +1078,7 @@ void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *h { OutBuffer argbuf; for (size_t i = 0; i < arguments->dim; i++) - { Expression *arg = (Expression *)arguments->data[i]; + { Expression *arg = arguments->tdata()[i]; if (i) buf->writeByte(','); @@ -1172,6 +1272,11 @@ complex_t Expression::toComplex() #endif } +StringExp *Expression::toString() +{ + return NULL; +} + void Expression::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring(Token::toChars(op)); @@ -1302,14 +1407,14 @@ void Expression::checkPurity(Scope *sc, FuncDeclaration *f) FuncDeclaration *outerfunc = sc->func; // Find the closest pure parent of the calling function while (outerfunc->toParent2() && - !outerfunc->isPure() && + !outerfunc->isPureBypassingInference() && outerfunc->toParent2()->isFuncDeclaration()) { outerfunc = outerfunc->toParent2()->isFuncDeclaration(); } // Find the closest pure parent of the called function FuncDeclaration *calledparent = f; - while (calledparent->toParent2() && !calledparent->isPure() + while (calledparent->toParent2() && !calledparent->isPureBypassingInference() && calledparent->toParent2()->isFuncDeclaration() ) { calledparent = calledparent->toParent2()->isFuncDeclaration(); @@ -1374,33 +1479,6 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v, Expression *ethis) } else { - if (ethis) - { - Type *t1 = ethis->type->toBasetype(); - - if (t1->isImmutable() || - (t1->ty == Tpointer && t1->nextOf()->isImmutable())) - { - goto L1; - } - if (ethis->op == TOKvar) - { VarExp *ve = (VarExp *)ethis; - - v = ve->var->isVarDeclaration(); - if (v) - checkPurity(sc, v, NULL); - return; - } - if (ethis->op == TOKdotvar) - { DotVarExp *ve = (DotVarExp *)ethis; - - v = ve->var->isVarDeclaration(); - if (v) - checkPurity(sc, v, ve->e1); - return; - } - } - /* Given: * void f() * { int fx; @@ -1415,32 +1493,22 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v, Expression *ethis) * i() can modify hx and gx but not fx */ - /* Back up until we find the parent function of v, - * requiring each function in between to be impure. - */ Dsymbol *vparent = v->toParent2(); - Dsymbol *s = sc->func, *snext = s->toParent2(); - // Make sure we're really finding parent *functions*, not parent - // class. - if (vparent->isFuncDeclaration() || snext != vparent) + for (Dsymbol *s = sc->func; s; s = s->toParent2()) { - for (; s; s = s->toParent2()) - { - if (s == vparent) + if (s == vparent) break; - FuncDeclaration *ff = s->isFuncDeclaration(); - if (!ff) - break; - if (ff->setImpure()) - { error("pure nested function '%s' cannot access mutable data '%s'", - ff->toChars(), v->toChars()); - break; - } + FuncDeclaration *ff = s->isFuncDeclaration(); + if (!ff) + break; + if (ff->setImpure()) + { error("pure nested function '%s' cannot access mutable data '%s'", + ff->toChars(), v->toChars()); + break; } } } - /* Do not allow safe functions to access __gshared data */ if (v->storage_class & STCgshared) @@ -1449,8 +1517,6 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v, Expression *ethis) error("safe function '%s' cannot access __gshared data '%s'", sc->func->toChars(), v->toChars()); } - - L1: ; } } @@ -1528,6 +1594,7 @@ Expression *Expression::checkToBoolean(Scope *sc) { Expression *e = new DotIdExp(loc, this, ad->aliasthis->ident); e = e->semantic(sc); + e = resolveProperties(sc, e); e = e->checkToBoolean(sc); return e; } @@ -1571,11 +1638,12 @@ Expression *Expression::checkToPointer() Expression *Expression::addressOf(Scope *sc) { Expression *e; + Type *t = type; //printf("Expression::addressOf()\n"); e = toLvalue(sc, NULL); e = new AddrExp(loc, e); - e->type = type->pointerTo(); + e->type = t->pointerTo(); return e; } @@ -1646,12 +1714,12 @@ Expressions *Expression::arraySyntaxCopy(Expressions *exps) { a = new Expressions(); a->setDim(exps->dim); - for (int i = 0; i < a->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + for (size_t i = 0; i < a->dim; i++) + { Expression *e = (*exps)[i]; if (e) e = e->syntaxCopy(); - a->data[i] = e; + a->tdata()[i] = e; } } return a; @@ -2454,17 +2522,10 @@ Expression *IdentifierExp::semantic(Scope *sc) * then replace f with the function template declaration. */ FuncDeclaration *f = s->isFuncDeclaration(); - if (f && f->parent) - { TemplateInstance *ti = f->parent->isTemplateInstance(); - - if (ti && - !ti->isTemplateMixin() && - (ti->name == f->ident || - ti->toAlias()->ident == f->ident) - && - ti->tempdecl && ti->tempdecl->onemember) + if (f) + { TemplateDeclaration *tempdecl = getFuncTemplateDecl(f); + if (tempdecl) { - TemplateDeclaration *tempdecl = ti->tempdecl; if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's tempdecl = tempdecl->overroot; // then get the start e = new TemplateExp(loc, tempdecl); @@ -2478,6 +2539,20 @@ Expression *IdentifierExp::semantic(Scope *sc) return e->semantic(sc); } #if DMDV2 + if (hasThis(sc)) + { + AggregateDeclaration *ad = sc->getStructClassScope(); + if (ad->aliasthis) + { + Expression *e; + e = new IdentifierExp(loc, Id::This); + e = new DotIdExp(loc, e, ad->aliasthis->ident); + e = new DotIdExp(loc, e, ident); + e = e->trySemantic(sc); + if (e) + return e; + } + } if (ident == Id::ctfe) { // Create the magic __ctfe bool variable VarDeclaration *vd = new VarDeclaration(loc, Type::tbool, Id::ctfe, NULL); @@ -2561,7 +2636,6 @@ Lagain: FuncDeclaration *f; FuncLiteralDeclaration *fld; OverloadSet *o; - Declaration *d; ClassDeclaration *cd; ClassDeclaration *thiscd = NULL; Import *imp; @@ -2742,7 +2816,6 @@ Lagain: return e; } -Lerr: error("%s '%s' is not a variable", s->kind(), s->toChars()); return new ErrorExp(); } @@ -2993,6 +3066,17 @@ int NullExp::isBool(int result) return result ? FALSE : TRUE; } +StringExp *NullExp::toString() +{ + if (implicitConvTo(Type::tstring)) + { + StringExp *se = new StringExp(loc, (char*)mem.calloc(1, 1), 0); + se->type = Type::tstring; + return se; + } + return NULL; +} + void NullExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring("null"); @@ -3193,6 +3277,11 @@ size_t StringExp::length() return result; } +StringExp *StringExp::toString() +{ + return this; +} + /**************************************** * Convert string to char[]. */ @@ -3452,7 +3541,7 @@ int ArrayLiteralExp::checkSideEffect(int flag) { int f = 0; for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; f |= e->checkSideEffect(2); } @@ -3477,6 +3566,35 @@ int ArrayLiteralExp::canThrow(bool mustNotThrow) } #endif +StringExp *ArrayLiteralExp::toString() +{ + TY telem = type->nextOf()->toBasetype()->ty; + + if (telem == Tchar || telem == Twchar || telem == Tdchar || + (telem == Tvoid && (!elements || elements->dim == 0))) + { + OutBuffer buf; + if (elements) + for (int i = 0; i < elements->dim; ++i) + { + Expression *ch = elements->tdata()[i]; + if (ch->op != TOKint64) + return NULL; + buf.writedchar(ch->toInteger()); + } + buf.writebyte(0); + + char prefix = 'c'; + if (telem == Twchar) prefix = 'w'; + else if (telem == Tdchar) prefix = 'd'; + + StringExp *se = new StringExp(loc, buf.extractData(), buf.size - 1, prefix); + se->type = type; + return se; + } + return NULL; +} + void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writeByte('['); @@ -3489,7 +3607,7 @@ void ArrayLiteralExp::toMangleBuffer(OutBuffer *buf) size_t dim = elements ? elements->dim : 0; buf->printf("A%zu", dim); for (size_t i = 0; i < dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; e->toMangleBuffer(buf); } } @@ -3514,8 +3632,7 @@ Expression *AssocArrayLiteralExp::syntaxCopy() } Expression *AssocArrayLiteralExp::semantic(Scope *sc) -{ Expression *e; - +{ #if LOGSEMANTIC printf("AssocArrayLiteralExp::semantic('%s')\n", toChars()); #endif @@ -3548,8 +3665,8 @@ int AssocArrayLiteralExp::checkSideEffect(int flag) { int f = 0; for (size_t i = 0; i < keys->dim; i++) - { Expression *key = (Expression *)keys->data[i]; - Expression *value = (Expression *)values->data[i]; + { Expression *key = keys->tdata()[i]; + Expression *value = values->tdata()[i]; f |= key->checkSideEffect(2); f |= value->checkSideEffect(2); @@ -3580,8 +3697,8 @@ void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writeByte('['); for (size_t i = 0; i < keys->dim; i++) - { Expression *key = (Expression *)keys->data[i]; - Expression *value = (Expression *)values->data[i]; + { Expression *key = keys->tdata()[i]; + Expression *value = values->tdata()[i]; if (i) buf->writeByte(','); @@ -3597,8 +3714,8 @@ void AssocArrayLiteralExp::toMangleBuffer(OutBuffer *buf) size_t dim = keys->dim; buf->printf("A%zu", dim); for (size_t i = 0; i < dim; i++) - { Expression *key = (Expression *)keys->data[i]; - Expression *value = (Expression *)values->data[i]; + { Expression *key = keys->tdata()[i]; + Expression *value = values->tdata()[i]; key->toMangleBuffer(buf); value->toMangleBuffer(buf); @@ -3629,7 +3746,7 @@ Expression *StructLiteralExp::syntaxCopy() Expression *StructLiteralExp::semantic(Scope *sc) { Expression *e; - int nfields = sd->fields.dim - sd->isnested; + size_t nfields = sd->fields.dim - sd->isnested; #if LOGSEMANTIC printf("StructLiteralExp::semantic('%s')\n", toChars()); @@ -3641,7 +3758,7 @@ Expression *StructLiteralExp::semantic(Scope *sc) expandTuples(elements); size_t offset = 0; for (size_t i = 0; i < elements->dim; i++) - { e = (Expression *)elements->data[i]; + { e = elements->tdata()[i]; if (!e) continue; @@ -3654,7 +3771,7 @@ Expression *StructLiteralExp::semantic(Scope *sc) { error("more initializers than fields of %s", sd->toChars()); return new ErrorExp(); } - Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); if (v->offset < offset) @@ -3675,13 +3792,13 @@ Expression *StructLiteralExp::semantic(Scope *sc) e = e->implicitCastTo(sc, telem); - elements->data[i] = (void *)e; + elements->tdata()[i] = e; } /* Fill out remainder of elements[] with default initializers for fields[] */ for (size_t i = elements->dim; i < nfields; i++) - { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + { Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); assert(!v->isThisDeclaration()); @@ -3753,7 +3870,7 @@ Expression *StructLiteralExp::getField(Type *type, unsigned offset) { //printf("\ti = %d\n", i); assert(i < elements->dim); - e = (Expression *)elements->data[i]; + e = elements->tdata()[i]; if (e) { //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars()); @@ -3767,7 +3884,7 @@ Expression *StructLiteralExp::getField(Type *type, unsigned offset) Expressions *z = new Expressions; z->setDim(length); for (int q = 0; q < length; ++q) - z->data[q] = e->copy(); + z->tdata()[q] = e->copy(); e = new ArrayLiteralExp(loc, z); e->type = type; } @@ -3794,13 +3911,13 @@ int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) { for (size_t i = 0; i < sd->fields.dim; i++) { - Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); if (offset == v->offset && type->size() == v->type->size()) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; if (e) { return i; @@ -3829,7 +3946,7 @@ int StructLiteralExp::checkSideEffect(int flag) { int f = 0; for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; if (!e) continue; @@ -3860,7 +3977,7 @@ void StructLiteralExp::toMangleBuffer(OutBuffer *buf) size_t dim = elements ? elements->dim : 0; buf->printf("S%zu", dim); for (size_t i = 0; i < dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; if (e) e->toMangleBuffer(buf); else @@ -3996,6 +4113,14 @@ void ScopeExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { sds->toCBuffer(buf, hgs); } + else if (hgs != NULL && hgs->ddoc) + { // fixes bug 6491 + Module *module = sds->isModule(); + if (module) + buf->writestring(module->md->toChars()); + else + buf->writestring(sds->toChars()); + } else { buf->writestring(sds->kind()); @@ -4052,7 +4177,7 @@ Expression *NewExp::syntaxCopy() Expression *NewExp::semantic(Scope *sc) -{ int i; +{ Type *tb; ClassDeclaration *cdthis = NULL; @@ -4098,8 +4223,7 @@ Lagain: } if (tb->ty == Tclass) - { TypeFunction *tf; - + { TypeClass *tc = (TypeClass *)(tb); ClassDeclaration *cd = tc->sym->isClassDeclaration(); if (cd->isInterfaceDeclaration()) @@ -4108,13 +4232,17 @@ Lagain: } else if (cd->isAbstract()) { error("cannot create instance of abstract class %s", cd->toChars()); - for (int i = 0; i < cd->vtbl.dim; i++) - { FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); + for (size_t i = 0; i < cd->vtbl.dim; i++) + { FuncDeclaration *fd = cd->vtbl.tdata()[i]->isFuncDeclaration(); if (fd && fd->isAbstract()) error("function %s is abstract", fd->toChars()); } goto Lerr; } + + if (cd->noDefaultCtor && (!arguments || !arguments->dim)) + error("default construction is disabled for type %s", cd->toChars()); + checkDeprecated(sc, cd); if (cd->isNested()) { /* We need a 'this' pointer for the nested class. @@ -4226,7 +4354,7 @@ Lagain: cd->accessCheck(loc, sc, member); - tf = (TypeFunction *)f->type; + TypeFunction *tf = (TypeFunction *)f->type; if (!arguments) arguments = new Expressions(); @@ -4254,7 +4382,7 @@ Lagain: allocator = f->isNewDeclaration(); assert(allocator); - tf = (TypeFunction *)f->type; + TypeFunction *tf = (TypeFunction *)f->type; functionParameters(loc, sc, tf, newargs, f); } else @@ -4271,6 +4399,9 @@ Lagain: StructDeclaration *sd = ts->sym; TypeFunction *tf; + if (sd->noDefaultCtor && (!arguments || !arguments->dim)) + error("default construction is disabled for type %s", sd->toChars()); + FuncDeclaration *f = NULL; if (sd->ctor) f = resolveFuncCall(sc, loc, sd->ctor, NULL, NULL, arguments, 0); @@ -4339,7 +4470,7 @@ Lagain: goto Lerr; } - Expression *arg = (Expression *)arguments->data[i]; + Expression *arg = arguments->tdata()[i]; arg = resolveProperties(sc, arg); arg = arg->implicitCastTo(sc, Type::tsize_t); arg = arg->optimize(WANTvalue); @@ -4347,7 +4478,7 @@ Lagain: { error("negative array index %s", arg->toChars()); goto Lerr; } - arguments->data[i] = (void *) arg; + arguments->tdata()[i] = arg; tb = ((TypeDArray *)tb)->next->toBasetype(); } } @@ -4403,8 +4534,7 @@ int NewExp::canThrow(bool mustNotThrow) #endif void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -{ int i; - +{ if (thisexp) { expToCBuffer(buf, hgs, thisexp, PREC_primary); buf->writeByte('.'); @@ -4478,8 +4608,7 @@ int NewAnonClassExp::canThrow(bool mustNotThrow) #endif void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -{ int i; - +{ if (thisexp) { expToCBuffer(buf, hgs, thisexp, PREC_primary); buf->writeByte('.'); @@ -4596,8 +4725,7 @@ int VarExp::equals(Object *o) } Expression *VarExp::semantic(Scope *sc) -{ FuncLiteralDeclaration *fd; - +{ #if LOGSEMANTIC printf("VarExp::semantic(%s)\n", toChars()); #endif @@ -4760,7 +4888,7 @@ TupleExp::TupleExp(Loc loc, TupleDeclaration *tup) exps->reserve(tup->objects->dim); for (size_t i = 0; i < tup->objects->dim; i++) - { Object *o = (Object *)tup->objects->data[i]; + { Object *o = tup->objects->tdata()[i]; if (o->dyncast() == DYNCAST_EXPRESSION) { Expression *e = (Expression *)o; @@ -4788,8 +4916,7 @@ TupleExp::TupleExp(Loc loc, TupleDeclaration *tup) } int TupleExp::equals(Object *o) -{ TupleExp *ne; - +{ if (this == o) return 1; if (((Expression *)o)->op == TOKtuple) @@ -4798,8 +4925,8 @@ int TupleExp::equals(Object *o) if (exps->dim != te->exps->dim) return 0; for (size_t i = 0; i < exps->dim; i++) - { Expression *e1 = (Expression *)exps->data[i]; - Expression *e2 = (Expression *)te->exps->data[i]; + { Expression *e1 = (*exps)[i]; + Expression *e2 = (*te->exps)[i]; if (!e1->equals(e2)) return 0; @@ -4824,20 +4951,20 @@ Expression *TupleExp::semantic(Scope *sc) // Run semantic() on each argument for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; e = e->semantic(sc); if (!e->type) { error("%s has no value", e->toChars()); e = new ErrorExp(); } - exps->data[i] = (void *)e; + (*exps)[i] = e; } expandTuples(exps); if (0 && exps->dim == 1) { - return (Expression *)exps->data[0]; + return (*exps)[0]; } type = new TypeTuple(exps); type = type->semantic(loc, sc); @@ -4855,8 +4982,8 @@ void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) int TupleExp::checkSideEffect(int flag) { int f = 0; - for (int i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + for (size_t i = 0; i < exps->dim; i++) + { Expression *e = (*exps)[i]; f |= e->checkSideEffect(2); } @@ -4875,7 +5002,7 @@ int TupleExp::canThrow(bool mustNotThrow) void TupleExp::checkEscape() { for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = (*exps)[i]; e->checkEscape(); } } @@ -4982,7 +5109,7 @@ Expression *DeclarationExp::semantic(Scope *sc) if (ad) { if (ad->decl && ad->decl->dim == 1) - s = (Dsymbol *)ad->decl->data[0]; + s = ad->decl->tdata()[0]; } if (s->isVarDeclaration()) @@ -5075,12 +5202,12 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow) ad = s->isAttribDeclaration(); if (ad) { - Array *decl = ad->include(NULL, NULL); + Dsymbols *decl = ad->include(NULL, NULL); if (decl && decl->dim) { for (size_t i = 0; i < decl->dim; i++) { - s = (Dsymbol *)decl->data[i]; + s = decl->tdata()[i]; if (Dsymbol_canThrow(s, mustNotThrow)) return 1; } @@ -5113,7 +5240,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow) { for (size_t i = 0; i < tm->members->dim; i++) { - Dsymbol *sm = (Dsymbol *)tm->members->data[i]; + Dsymbol *sm = tm->members->tdata()[i]; if (Dsymbol_canThrow(sm, mustNotThrow)) return 1; } @@ -5122,7 +5249,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow) else if ((td = s->isTupleDeclaration()) != NULL) { for (size_t i = 0; i < td->objects->dim; i++) - { Object *o = (Object *)td->objects->data[i]; + { Object *o = td->objects->tdata()[i]; if (o->dyncast() == DYNCAST_EXPRESSION) { Expression *eo = (Expression *)o; if (eo->op == TOKdsymbol) @@ -5255,10 +5382,10 @@ void TraitsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writestring(ident->toChars()); if (args) { - for (int i = 0; i < args->dim; i++) + for (size_t i = 0; i < args->dim; i++) { buf->writeByte(','); - Object *oarg = (Object *)args->data[i]; + Object *oarg = args->tdata()[i]; ObjectToCBuffer(buf, hgs, oarg); } } @@ -5314,9 +5441,9 @@ Expression *IsExp::syntaxCopy() { p = new TemplateParameters(); p->setDim(parameters->dim); - for (int i = 0; i < p->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; - p->data[i] = (void *)tp->syntaxCopy(); + for (size_t i = 0; i < p->dim; i++) + { TemplateParameter *tp = parameters->tdata()[i]; + p->tdata()[i] = tp->syntaxCopy(); } } @@ -5426,7 +5553,7 @@ Expression *IsExp::semantic(Scope *sc) Parameters *args = new Parameters; args->reserve(cd->baseclasses->dim); for (size_t i = 0; i < cd->baseclasses->dim; i++) - { BaseClass *b = (BaseClass *)cd->baseclasses->data[i]; + { BaseClass *b = cd->baseclasses->tdata()[i]; args->push(new Parameter(STCin, b->type, NULL, NULL)); } tded = new TypeTuple(args); @@ -5513,7 +5640,7 @@ Expression *IsExp::semantic(Scope *sc) dedtypes.setDim(parameters->dim); dedtypes.zero(); - MATCH m = targ->deduceType(NULL, tspec, parameters, &dedtypes); + MATCH m = targ->deduceType(sc, tspec, parameters, &dedtypes); //printf("targ: %s\n", targ->toChars()); //printf("tspec: %s\n", tspec->toChars()); if (m == MATCHnomatch || @@ -5523,18 +5650,18 @@ Expression *IsExp::semantic(Scope *sc) } else { - tded = (Type *)dedtypes.data[0]; + tded = (Type *)dedtypes.tdata()[0]; if (!tded) tded = targ; #if DMDV2 Objects tiargs; tiargs.setDim(1); - tiargs.data[0] = (void *)targ; + tiargs.tdata()[0] = targ; /* Declare trailing parameters */ - for (int i = 1; i < parameters->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + for (size_t i = 1; i < parameters->dim; i++) + { TemplateParameter *tp = parameters->tdata()[i]; Declaration *s = NULL; m = tp->matchArg(sc, &tiargs, i, parameters, &dedtypes, &s); @@ -5542,7 +5669,7 @@ Expression *IsExp::semantic(Scope *sc) goto Lno; s->semantic(sc); #if 0 - Object *o = (Object *)dedtypes.data[i]; + Type *o = dedtypes.tdata()[i]; Dsymbol *s = TemplateDeclaration::declareParameter(loc, sc, tp, o); #endif if (sc->sd) @@ -5600,9 +5727,6 @@ Lyes: Lno: //printf("Lno\n"); return new IntegerExp(loc, 0, Type::tbool); - -Lerr: - return new ErrorExp(); } void IsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -5624,10 +5748,10 @@ void IsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) #if DMDV2 if (parameters) { // First parameter is already output, so start with second - for (int i = 1; i < parameters->dim; i++) + for (size_t i = 1; i < parameters->dim; i++) { buf->writeByte(','); - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; tp->toCBuffer(buf, hgs); } } @@ -5988,11 +6112,11 @@ Expression *CompileExp::semantic(Scope *sc) return new ErrorExp(); } e1 = e1->optimize(WANTvalue | WANTinterpret); - if (e1->op != TOKstring) + StringExp *se = e1->toString(); + if (!se) { error("argument to mixin must be a string, not (%s)", e1->toChars()); return new ErrorExp(); } - StringExp *se = (StringExp *)e1; se = se->toUTF8(sc); Parser p(sc->module, (unsigned char *)se->string, se->len, 0); p.loc = loc; @@ -6068,7 +6192,6 @@ Expression *FileExp::semantic(Scope *sc) se = new StringExp(loc, f.buffer, f.len); } } - Lret: return se->semantic(sc); Lerror: @@ -6238,6 +6361,22 @@ Expression *DotIdExp::semantic(Scope *sc, int flag) UnaExp::semantic(sc); + if (ident == Id::mangleof) + { // symbol.mangleof + Dsymbol *ds; + switch (e1->op) + { + case TOKimport: ds = ((ScopeExp *)e1)->sds; goto L1; + case TOKvar: ds = ((VarExp *)e1)->var; goto L1; + case TOKdotvar: ds = ((DotVarExp *)e1)->var; goto L1; + L1: + char* s = ds->mangle(); + e = new StringExp(loc, s, strlen(s), 'c'); + e = e->semantic(sc); + return e; + } + } + if (e1->op == TOKdotexp) { DotExp *de = (DotExp *)e1; @@ -6258,11 +6397,11 @@ Expression *DotIdExp::semantic(Scope *sc, int flag) TupleExp *te = (TupleExp *)e1; Expressions *exps = new Expressions(); exps->setDim(te->exps->dim); - for (int i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)te->exps->data[i]; + for (size_t i = 0; i < exps->dim; i++) + { Expression *e = (*te->exps)[i]; e = e->semantic(sc); e = new DotIdExp(e->loc, e, Id::offsetof); - exps->data[i] = (void *)e; + (*exps)[i] = e; } e = new TupleExp(loc, exps); e = e->semantic(sc); @@ -6529,7 +6668,7 @@ Expression *DotVarExp::semantic(Scope *sc) exps->reserve(tup->objects->dim); for (size_t i = 0; i < tup->objects->dim; i++) - { Object *o = (Object *)tup->objects->data[i]; + { Object *o = tup->objects->tdata()[i]; if (o->dyncast() != DYNCAST_EXPRESSION) { error("%s is not an expression", o->toChars()); @@ -6579,8 +6718,6 @@ Expression *DotVarExp::semantic(Scope *sc) accessCheck(loc, sc, e1, var); VarDeclaration *v = var->isVarDeclaration(); - if (v) - checkPurity(sc, v, e1); Expression *e = expandVar(WANTvalue, v); if (e) return e; @@ -6620,6 +6757,46 @@ Expression *DotVarExp::toLvalue(Scope *sc, Expression *e) return this; } +/*********************************************** + * Mark variable v as modified if it is inside a constructor that var + * is a field in. + */ +void modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1) +{ + //printf("modifyFieldVar(var = %s)\n", var->toChars()); + Dsymbol *s = sc->func; + while (1) + { + FuncDeclaration *fd = NULL; + if (s) + fd = s->isFuncDeclaration(); + if (fd && + ((fd->isCtorDeclaration() && var->storage_class & STCfield) || + (fd->isStaticCtorDeclaration() && !(var->storage_class & STCfield))) && + fd->toParent2() == var->toParent() && + (!e1 || e1->op == TOKthis) + ) + { + var->ctorinit = 1; + //printf("setting ctorinit\n"); + } + else + { + if (s) + { s = s->toParent2(); + continue; + } + else if (var->storage_class & STCctorinit) + { + const char *p = var->isStatic() ? "static " : ""; + error(loc, "can only initialize %sconst member %s inside %sconstructor", + p, var->toChars(), p); + } + } + break; + } +} + Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) { #if 0 @@ -6639,45 +6816,17 @@ Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) { if (var->isCtorinit()) { // It's only modifiable if inside the right constructor - Dsymbol *s = sc->func; - while (1) - { - FuncDeclaration *fd = NULL; - if (s) - fd = s->isFuncDeclaration(); - if (fd && - ((fd->isCtorDeclaration() && var->storage_class & STCfield) || - (fd->isStaticCtorDeclaration() && !(var->storage_class & STCfield))) && - fd->toParent() == var->toParent() && - e1->op == TOKthis - ) - { - VarDeclaration *v = var->isVarDeclaration(); - assert(v); - v->ctorinit = 1; - //printf("setting ctorinit\n"); - } - else - { - if (s) - { s = s->toParent2(); - continue; - } - else - { - const char *p = var->isStatic() ? "static " : ""; - error("can only initialize %sconst member %s inside %sconstructor", - p, var->toChars(), p); - } - } - break; - } + modifyFieldVar(loc, sc, var->isVarDeclaration(), e1); } else { error("cannot modify const/immutable/inout expression %s", toChars()); } } + else if (var->storage_class & STCnodefaultctor) + { + modifyFieldVar(loc, sc, var->isVarDeclaration(), e1); + } return this; } @@ -6802,6 +6951,11 @@ L1: else if (e->op == TOKdotexp) { DotExp *de = (DotExp *)e; + if (de->e2->op == TOKoverloadset) + { + return e; + } + if (de->e2->op == TOKimport) { // This should *really* be moved to ScopeExp::semantic() ScopeExp *se = (ScopeExp *)de->e2; @@ -6908,6 +7062,7 @@ CallExp::CallExp(Loc loc, Expression *e, Expressions *exps) : UnaExp(loc, TOKcall, sizeof(CallExp), e) { this->arguments = exps; + this->f = NULL; } CallExp::CallExp(Loc loc, Expression *e) @@ -6922,7 +7077,7 @@ CallExp::CallExp(Loc loc, Expression *e, Expression *earg1) Expressions *arguments = new Expressions(); if (earg1) { arguments->setDim(1); - arguments->data[0] = (void *)earg1; + arguments->tdata()[0] = earg1; } this->arguments = arguments; } @@ -6932,8 +7087,8 @@ CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2) { Expressions *arguments = new Expressions(); arguments->setDim(2); - arguments->data[0] = (void *)earg1; - arguments->data[1] = (void *)earg2; + arguments->tdata()[0] = earg1; + arguments->tdata()[1] = earg2; this->arguments = arguments; } @@ -6947,12 +7102,11 @@ Expression *CallExp::syntaxCopy() Expression *CallExp::semantic(Scope *sc) { TypeFunction *tf; - FuncDeclaration *f; - int i; Type *t1; int istemp; Objects *targsi = NULL; // initial list of template arguments TemplateInstance *tierror = NULL; + Expression *ethis = NULL; #if LOGSEMANTIC printf("CallExp::semantic() %s\n", toChars()); @@ -6962,7 +7116,7 @@ Expression *CallExp::semantic(Scope *sc) #if 0 if (arguments && arguments->dim) { - Expression *earg = (Expression *)arguments->data[0]; + Expression *earg = arguments->tdata()[0]; earg->print(); if (earg->type) earg->type->print(); } @@ -6995,7 +7149,7 @@ Expression *CallExp::semantic(Scope *sc) { error("expected key as argument to aa.remove()"); return new ErrorExp(); } - Expression *key = (Expression *)arguments->data[0]; + Expression *key = arguments->tdata()[0]; key = key->semantic(sc); key = resolveProperties(sc, key); key->rvalue(); @@ -7154,6 +7308,12 @@ Lagain: { DotExp *de = (DotExp *) e1; + if (de->e2->op == TOKoverloadset) + { + ethis = de->e1; + e1 = de->e2; + } + if (de->e2->op == TOKimport) { // This should *really* be moved to ScopeExp::semantic() ScopeExp *se = (ScopeExp *)de->e2; @@ -7258,8 +7418,8 @@ Lagain: // return an error without trying to resolve the function call. if (arguments && arguments->dim) { - for (int k = 0; k < arguments->dim; k++) - { Expression *checkarg = (Expression *)arguments->data[k]; + for (size_t k = 0; k < arguments->dim; k++) + { Expression *checkarg = arguments->tdata()[k]; if (checkarg->op == TOKerror) return checkarg; } @@ -7331,10 +7491,15 @@ Lagain: else { if (e1->op == TOKdotvar) + { dve->var = f; + e1->type = f->type; + } else + { e1 = new DotVarExp(loc, dte->e1, f); - e1->type = f->type; + e1 = e1->semantic(sc); + } #if 0 printf("ue->e1 = %s\n", ue->e1->toChars()); printf("f = %s\n", f->toChars()); @@ -7426,6 +7591,7 @@ Lagain: } f = resolveFuncCall(sc, loc, cd->baseClass->ctor, NULL, NULL, arguments, 0); + accessCheck(loc, sc, NULL, f); checkDeprecated(sc, f); #if DMDV2 checkPurity(sc, f); @@ -7487,17 +7653,17 @@ Lagain: OverExp *eo = (OverExp *)e1; FuncDeclaration *f = NULL; Dsymbol *s = NULL; - for (int i = 0; i < eo->vars->a.dim; i++) - { s = (Dsymbol *)eo->vars->a.data[i]; + for (size_t i = 0; i < eo->vars->a.dim; i++) + { s = eo->vars->a.tdata()[i]; FuncDeclaration *f2 = s->isFuncDeclaration(); if (f2) { - f2 = f2->overloadResolve(loc, NULL, arguments, 1); + f2 = f2->overloadResolve(loc, ethis, arguments, 1); } else { TemplateDeclaration *td = s->isTemplateDeclaration(); assert(td); - f2 = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments, 1); + f2 = td->deduceFunctionTemplate(sc, loc, targsi, ethis, arguments, 1); } if (f2) { if (f) @@ -7515,7 +7681,10 @@ Lagain: error("no overload matches for %s", s->toChars()); return new ErrorExp(); } - e1 = new VarExp(loc, f); + if (ethis) + e1 = new DotVarExp(loc, ethis, f); + else + e1 = new VarExp(loc, f); goto Lagain; } else if (!t1) @@ -7531,7 +7700,10 @@ Lagain: tf = (TypeFunction *)(td->next); if (sc->func && !tf->purity && !(sc->flags & SCOPEdebug)) { - if (sc->func->setImpure()) + if (e1->op == TOKvar && ((VarExp *)e1)->var->storage_class & STClazy) + { // lazy paramaters can be called without violating purity + // since they are checked explicitly + } else if (sc->func->setImpure()) error("pure function '%s' cannot call impure delegate '%s'", sc->func->toChars(), e1->toChars()); } if (sc->func && tf->trust <= TRUSTsystem) @@ -7679,7 +7851,7 @@ int CallExp::checkSideEffect(int flag) /* If any of the arguments have side effects, this expression does */ for (size_t i = 0; i < arguments->dim; i++) - { Expression *e = (Expression *)arguments->data[i]; + { Expression *e = arguments->tdata()[i]; result |= e->checkSideEffect(1); } @@ -7764,13 +7936,6 @@ Expression *CallExp::addDtorHook(Scope *sc) { /* Type needs destruction, so declare a tmp * which the back end will recognize and call dtor on */ - if (e1->op == TOKdotvar) - { - DotVarExp* dve = (DotVarExp*)e1; - if (dve->e1->isTemp() != NULL) - goto Lnone; // already got a tmp - } - Identifier *idtmp = Lexer::uniqueId("__tmpfordtor"); VarDeclaration *tmp = new VarDeclaration(loc, type, idtmp, new ExpInitializer(loc, this)); tmp->storage_class |= STCctfe; @@ -8315,8 +8480,6 @@ Expression *CastExp::syntaxCopy() Expression *CastExp::semantic(Scope *sc) { Expression *e; - BinExp *b; - UnaExp *u; #if LOGSEMANTIC printf("CastExp::semantic('%s')\n", toChars()); @@ -8417,6 +8580,22 @@ Expression *CastExp::semantic(Scope *sc) if (!tob->hasPointers()) goto Lsafe; + if (tob->ty == Tclass && t1b->ty == Tclass) + { + ClassDeclaration *cdfrom = t1b->isClassHandle(); + ClassDeclaration *cdto = tob->isClassHandle(); + + int offset; + if (!cdfrom->isBaseOf(cdto, &offset)) + goto Lunsafe; + + if (cdfrom->isCPPinterface() || + cdto->isCPPinterface()) + goto Lunsafe; + + goto Lsafe; + } + if (tob->ty == Tarray && t1b->ty == Tarray) { Type* tobn = tob->nextOf()->toBasetype(); @@ -8540,6 +8719,7 @@ Expression *SliceExp::semantic(Scope *sc) if (type) return this; +Lagain: UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); @@ -8586,6 +8766,11 @@ Expression *SliceExp::semantic(Scope *sc) e = e->semantic(sc); return e; } + if (ad->aliasthis) + { + e1 = new DotIdExp(e1->loc, e1, ad->aliasthis->ident); + goto Lagain; + } goto Lerror; } else if (t->ty == Ttuple) @@ -8661,8 +8846,8 @@ Expression *SliceExp::semantic(Scope *sc) { Expressions *exps = new Expressions; exps->setDim(j2 - j1); for (size_t i = 0; i < j2 - j1; i++) - { Expression *e = (Expression *)te->exps->data[j1 + i]; - exps->data[i] = (void *)e; + { Expression *e = (*te->exps)[j1 + i]; + (*exps)[i] = e; } e = new TupleExp(loc, exps); } @@ -8735,6 +8920,11 @@ Expression *SliceExp::modifiableLvalue(Scope *sc, Expression *e) return this; } +int SliceExp::isBool(int result) +{ + return e1->isBool(result); +} + void SliceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { expToCBuffer(buf, hgs, e1, precedence[op]); @@ -8879,27 +9069,10 @@ Expression *ArrayExp::semantic(Scope *sc) { error("only one index allowed to index %s", t1->toChars()); goto Lerr; } - e = new IndexExp(loc, e1, (Expression *)arguments->data[0]); + e = new IndexExp(loc, e1, arguments->tdata()[0]); return e->semantic(sc); } - // Run semantic() on each argument - for (size_t i = 0; i < arguments->dim; i++) - { e = (Expression *)arguments->data[i]; - - e = e->semantic(sc); - if (!e->type) - { error("%s has no value", e->toChars()); - goto Lerr; - } - else if (e->type == Type::terror) - goto Lerr; - arguments->data[i] = (void *)e; - } - - expandTuples(arguments); - assert(arguments && arguments->dim); - e = op_overload(sc); if (!e) { error("no [] operator overload for type %s", e1->type->toChars()); @@ -9070,8 +9243,6 @@ IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2) Expression *IndexExp::semantic(Scope *sc) { Expression *e; - BinExp *b; - UnaExp *u; Type *t1; ScopeDsymbol *sym; @@ -9105,6 +9276,8 @@ Expression *IndexExp::semantic(Scope *sc) error("%s has no value", e2->toChars()); goto Lerr; } + if (e2->type->ty == Ttuple && ((TupleExp *)e2)->exps->dim == 1) // bug 4444 fix + e2 = (Expression *)((TupleExp *)e2)->exps->data[0]; e2 = resolveProperties(sc, e2); if (e2->type == Type::terror) goto Lerr; @@ -9180,7 +9353,7 @@ Expression *IndexExp::semantic(Scope *sc) { if (e1->op == TOKtuple) - e = (Expression *)te->exps->data[(size_t)index]; + e = (*te->exps)[(size_t)index]; else e = new TypeExp(e1->loc, Parameter::getNth(tup->arguments, (size_t)index)->type); } @@ -9399,7 +9572,7 @@ Expression *AssignExp::semantic(Scope *sc) if (e1->op == TOKarray) { ArrayExp *ae = (ArrayExp *)e1; - AggregateDeclaration *ad; + AggregateDeclaration *ad = NULL; Identifier *id = Id::index; ae->e1 = ae->e1->semantic(sc); @@ -9435,13 +9608,31 @@ Expression *AssignExp::semantic(Scope *sc) return new ErrorExp(); } - e = new CallExp(loc, e, (Expression *)ae->arguments->data[0], e2); + e = new CallExp(loc, e, ae->arguments->tdata()[0], e2); e = e->semantic(sc); return e; } } #endif } + + // No opIndexAssign found yet, but there might be an alias this to try. + if (ad && ad->aliasthis) + { Expression *at = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); + at = at->semantic(sc); + Type *attype = at->type->toBasetype(); + + if (attype->ty == Tstruct) + { + ad = ((TypeStruct *)attype)->sym; + goto L1; + } + else if (attype->ty == Tclass) + { + ad = ((TypeClass *)attype)->sym; + goto L1; + } + } } /* Look for operator overloading of a[i..j]=value. * Do it before semantic() otherwise the a[i..j] will have been @@ -9450,7 +9641,7 @@ Expression *AssignExp::semantic(Scope *sc) if (e1->op == TOKslice) { Type *t1; SliceExp *ae = (SliceExp *)e1; - AggregateDeclaration *ad; + AggregateDeclaration *ad = NULL; Identifier *id = Id::index; ae->e1 = ae->e1->semantic(sc); @@ -9483,6 +9674,24 @@ Expression *AssignExp::semantic(Scope *sc) return e; } } + + // No opSliceAssign found yet, but there might be an alias this to try. + if (ad && ad->aliasthis) + { Expression *at = new DotIdExp(loc, ae->e1, ad->aliasthis->ident); + at = at->semantic(sc); + Type *attype = at->type->toBasetype(); + + if (attype->ty == Tstruct) + { + ad = ((TypeStruct *)attype)->sym; + goto L2; + } + else if (attype->ty == Tclass) + { + ad = ((TypeClass *)attype)->sym; + goto L2; + } + } } Expression *e = BinExp::semantic(sc); @@ -9501,6 +9710,7 @@ Expression *AssignExp::semantic(Scope *sc) /* Rewrite tuple assignment as a tuple of assignments. */ +Ltupleassign: if (e1->op == TOKtuple && e2->op == TOKtuple) { TupleExp *tup1 = (TupleExp *)e1; TupleExp *tup2 = (TupleExp *)e2; @@ -9514,10 +9724,10 @@ Expression *AssignExp::semantic(Scope *sc) { Expressions *exps = new Expressions; exps->setDim(dim); - for (int i = 0; i < dim; i++) - { Expression *ex1 = (Expression *)tup1->exps->data[i]; - Expression *ex2 = (Expression *)tup2->exps->data[i]; - exps->data[i] = (void *) new AssignExp(loc, ex1, ex2); + for (size_t i = 0; i < dim; i++) + { Expression *ex1 = (*tup1->exps)[i]; + Expression *ex2 = (*tup2->exps)[i]; + (*exps)[i] = new AssignExp(loc, ex1, ex2); } Expression *e = new TupleExp(loc, exps); e = e->semantic(sc); @@ -9525,6 +9735,51 @@ Expression *AssignExp::semantic(Scope *sc) } } + if (e1->op == TOKtuple) + { + if (TupleDeclaration *td = isAliasThisTuple(e2)) + { + assert(e1->type->ty == Ttuple); + TypeTuple *tt = (TypeTuple *)e1->type; + + Identifier *id = Lexer::uniqueId("__tup"); + VarDeclaration *v = new VarDeclaration(e2->loc, NULL, id, new ExpInitializer(e2->loc, e2)); + v->storage_class = STCctfe | STCref | STCforeach; + Expression *ve = new VarExp(e2->loc, v); + ve->type = e2->type; + + Expressions *iexps = new Expressions(); + iexps->push(ve); + + for (size_t u = 0; u < iexps->dim ; u++) + { + Lexpand: + Expression *e = iexps->tdata()[u]; + + Parameter *arg = Parameter::getNth(tt->arguments, u); + //printf("[%d] iexps->dim = %d, ", u, iexps->dim); + //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars()); + //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); + + if (!e->type->implicitConvTo(arg->type)) + { + // expand initializer to tuple + if (expandAliasThisTuples(iexps, u) != -1) + goto Lexpand; + + goto Lnomatch; + } + } + iexps->tdata()[0] = new CommaExp(loc, new DeclarationExp(e2->loc, v), iexps->tdata()[0]); + e2 = new TupleExp(e2->loc, iexps); + e2 = e2->semantic(sc); + goto Ltupleassign; + + Lnomatch: + ; + } + } + // Determine if this is an initialization of a reference int refinit = 0; if (op == TOKconstruct && e1->op == TOKvar) @@ -9566,6 +9821,17 @@ Expression *AssignExp::semantic(Scope *sc) StructDeclaration *sd = ((TypeStruct *)t1)->sym; if (op == TOKassign) { + /* See if we need to set ctorinit, i.e. track + * assignments to fields. An assignment to a field counts even + * if done through an opAssign overload. + */ + if (e1->op == TOKdotvar) + { DotVarExp *dve = (DotVarExp *)e1; + VarDeclaration *v = dve->var->isVarDeclaration(); + if (v && v->storage_class & STCnodefaultctor) + modifyFieldVar(loc, sc, v, dve->e1); + } + Expression *e = op_overload(sc); if (e && e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray) @@ -9576,7 +9842,7 @@ Expression *AssignExp::semantic(Scope *sc) Type * aaValueType = ((TypeAArray *)((IndexExp*)e1)->e1->type->toBasetype())->next; Identifier *id = Lexer::uniqueId("__aatmp"); VarDeclaration *v = new VarDeclaration(loc, aaValueType, - id, new VoidInitializer(NULL)); + id, new VoidInitializer(0)); v->storage_class |= STCctfe; v->semantic(sc); v->parent = sc->parent; @@ -9670,6 +9936,14 @@ Expression *AssignExp::semantic(Scope *sc) } else { + Type *t2 = e2->type->toBasetype(); + // Convert e2 to e2[], unless e2-> e1[0] + if (t2->ty == Tsarray && !t2->implicitConvTo(t1->nextOf())) + { + e2 = new SliceExp(e2->loc, e2, NULL, NULL); + e2 = e2->semantic(sc); + } + // Convert e1 to e1[] Expression *e = new SliceExp(e1->loc, e1, NULL, NULL); e1 = e->semantic(sc); @@ -9742,6 +10016,9 @@ Expression *AssignExp::semantic(Scope *sc) e2->op == TOKmul || e2->op == TOKdiv || e2->op == TOKmod || e2->op == TOKxor || e2->op == TOKand || e2->op == TOKor || +#if DMDV2 + e2->op == TOKpow || +#endif e2->op == TOKtilde || e2->op == TOKneg)) { type = e1->type; @@ -10356,8 +10633,30 @@ Expression *PowAssignExp::semantic(Scope *sc) if (e) return e; - e1 = e1->modifiableLvalue(sc, e1); assert(e1->type && e2->type); + if (e1->op == TOKslice) + { // T[] ^^= ... + e = typeCombine(sc); + if (e->op == TOKerror) + return e; + + // Check element types are arithmetic + Type *tb1 = e1->type->nextOf()->toBasetype(); + Type *tb2 = e2->type->toBasetype(); + if (tb2->ty == Tarray || tb2->ty == Tsarray) + tb2 = tb2->nextOf()->toBasetype(); + + if ( (tb1->isintegral() || tb1->isfloating()) && + (tb2->isintegral() || tb2->isfloating())) + { + type = e1->type; + return arrayOp(sc); + } + } + else + { + e1 = e1->modifiableLvalue(sc, e1); + } if ( (e1->type->isintegral() || e1->type->isfloating()) && (e2->type->isintegral() || e2->type->isfloating())) @@ -10861,6 +11160,22 @@ Expression *PowExp::semantic(Scope *sc) return e; assert(e1->type && e2->type); + if (e1->op == TOKslice) + { + // Check element types are arithmetic + Type *tb1 = e1->type->nextOf()->toBasetype(); + Type *tb2 = e2->type->toBasetype(); + if (tb2->ty == Tarray || tb2->ty == Tsarray) + tb2 = tb2->nextOf()->toBasetype(); + + if ( (tb1->isintegral() || tb1->isfloating()) && + (tb2->isintegral() || tb2->isfloating())) + { + type = e1->type; + return this; + } + } + if ( (e1->type->isintegral() || e1->type->isfloating()) && (e2->type->isintegral() || e2->type->isfloating())) { @@ -10894,7 +11209,7 @@ Expression *PowExp::semantic(Scope *sc) if ((e2->op == TOKint64 && e2->toInteger() == 0) || (e2->op == TOKfloat64 && e2->toReal() == 0.0)) { - if (e1->op == TOKint64) + if (e1->type->isintegral()) e = new IntegerExp(loc, 1, e1->type); else e = new RealExp(loc, 1.0, e1->type); @@ -10959,8 +11274,8 @@ Expression *PowExp::semantic(Scope *sc) if (!importMathChecked) { importMathChecked = 1; - for (int i = 0; i < Module::amodules.dim; i++) - { Module *mi = (Module *)Module::amodules.data[i]; + for (size_t i = 0; i < Module::amodules.dim; i++) + { Module *mi = Module::amodules.tdata()[i]; //printf("\t[%d] %s\n", i, mi->toChars()); if (mi->ident == Id::math && mi->parent->ident == Id::std && @@ -11440,7 +11755,7 @@ Expression *CmpExp::semantic(Scope *sc) error("recursive opCmp expansion"); e = new ErrorExp(); } - else + else if (e->op == TOKcall) { e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); e = e->semantic(sc); } @@ -11580,7 +11895,7 @@ Expression *EqualExp::semantic(Scope *sc) e = op_overload(sc); if (e) { - if (op == TOKnotequal) + if (e->op == TOKcall && op == TOKnotequal) { e = new NotExp(e->loc, e); e = e->semantic(sc); @@ -11771,10 +12086,7 @@ Expression *CondExp::toLvalue(Scope *sc, Expression *ex) e = new PtrExp(loc, this, type); e1 = e1->addressOf(sc); - //e1 = e1->toLvalue(sc, NULL); - e2 = e2->addressOf(sc); - //e2 = e2->toLvalue(sc, NULL); typeCombine(sc); diff --git a/dmd2/expression.h b/dmd2/expression.h index 35dd9d10..604bc428 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -48,6 +48,7 @@ struct Symbol; // back end symbol #endif struct OverloadSet; struct Initializer; +struct StringExp; #if IN_LLVM struct AssignExp; #endif @@ -86,10 +87,15 @@ void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Mo void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs); void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs); void expandTuples(Expressions *exps); +TupleDeclaration *isAliasThisTuple(Expression *e); +int expandAliasThisTuples(Expressions *exps, int starti = 0); FuncDeclaration *hasThis(Scope *sc); Expression *fromConstInitializer(int result, Expression *e); int arrayExpressionCanThrow(Expressions *exps, bool mustNotThrow); +TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s); void valueNoDtor(Expression *e); +void modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1); + /* Interpreter: what form of return value expression is required? */ @@ -132,6 +138,7 @@ struct Expression : Object virtual real_t toReal(); virtual real_t toImaginary(); virtual complex_t toComplex(); + virtual StringExp *toString(); virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); virtual void toMangleBuffer(OutBuffer *buf); virtual int isLvalue(); @@ -391,6 +398,7 @@ struct NullExp : Expression Expression *semantic(Scope *sc); int isBool(int result); int isConst(); + StringExp *toString(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); MATCH implicitConvTo(Type *t); @@ -422,6 +430,7 @@ struct StringExp : Expression Expression *semantic(Scope *sc); Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); size_t length(); + StringExp *toString(); StringExp *toUTF8(Scope *sc); Expression *implicitCastTo(Scope *sc, Type *t); MATCH implicitConvTo(Type *t); @@ -485,6 +494,7 @@ struct ArrayLiteralExp : Expression Expression *semantic(Scope *sc); int isBool(int result); int checkSideEffect(int flag); + StringExp *toString(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); void scanForNestedRef(Scope *sc); @@ -795,6 +805,7 @@ struct FuncExp : Expression void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #if IN_DMD elem *toElem(IRState *irs); + dt_t **toDt(dt_t **pdt); #endif int inlineCost(InlineCostState *ics); @@ -1114,6 +1125,7 @@ struct DotTypeExp : UnaExp struct CallExp : UnaExp { Expressions *arguments; // function arguments + FuncDeclaration *f; // symbol to call CallExp(Loc loc, Expression *e, Expressions *exps); CallExp(Loc loc, Expression *e); @@ -1135,6 +1147,7 @@ struct CallExp : UnaExp Expression *toLvalue(Scope *sc, Expression *e); int canThrow(bool mustNotThrow); Expression *addDtorHook(Scope *sc); + MATCH implicitConvTo(Type *t); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); @@ -1341,6 +1354,7 @@ struct SliceExp : UnaExp int isLvalue(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); + int isBool(int result); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Expression *optimize(int result); Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); @@ -1566,6 +1580,8 @@ struct PowAssignExp : BinAssignExp { PowAssignExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); + void buildArrayIdent(OutBuffer *buf, Expressions *arguments); + Expression *buildArrayLoop(Parameters *fparams); // For operator overloading Identifier *opId(); @@ -1715,6 +1731,8 @@ struct PowExp : BinExp { PowExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); + void buildArrayIdent(OutBuffer *buf, Expressions *arguments); + Expression *buildArrayLoop(Parameters *fparams); // For operator overloading Identifier *opId(); diff --git a/dmd2/func.c b/dmd2/func.c index 2aecdfd6..60bc0fa6 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -306,6 +306,9 @@ void FuncDeclaration::semantic(Scope *sc) if (isAbstract() && !isVirtual()) error("non-virtual functions cannot be abstract"); + if (isOverride() && !isVirtual()) + error("cannot override a non-virtual function"); + if ((f->isConst() || f->isImmutable()) && !isThis()) error("without 'this' cannot be const/immutable"); @@ -458,7 +461,7 @@ void FuncDeclaration::semantic(Scope *sc) /* Find index of existing function in base class's vtbl[] to override * (the index will be the same as in cd's current vtbl[]) */ - vi = cd->baseClass ? findVtblIndex(&cd->baseClass->vtbl, cd->baseClass->vtbl.dim) + vi = cd->baseClass ? findVtblIndex((Dsymbols*)&cd->baseClass->vtbl, cd->baseClass->vtbl.dim) : -1; switch (vi) @@ -504,7 +507,7 @@ void FuncDeclaration::semantic(Scope *sc) return; default: - { FuncDeclaration *fdv = (FuncDeclaration *)cd->baseClass->vtbl.data[vi]; + { FuncDeclaration *fdv = (FuncDeclaration *)cd->baseClass->vtbl.tdata()[vi]; // This function is covariant with fdv if (fdv->isFinal()) error("cannot override final function %s", fdv->toPrettyChars()); @@ -531,7 +534,7 @@ void FuncDeclaration::semantic(Scope *sc) ) error("multiple overrides of same function"); } - cd->vtbl.data[vi] = (void *)this; + cd->vtbl.tdata()[vi] = this; vtblIndex = vi; /* Remember which functions this overrides @@ -570,7 +573,7 @@ void FuncDeclaration::semantic(Scope *sc) for (int i = 0; i < cd->interfaces_dim; i++) { BaseClass *b = cd->interfaces[i]; - vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim); + vi = findVtblIndex((Dsymbols *)&b->base->vtbl, b->base->vtbl.dim); switch (vi) { case -1: @@ -582,7 +585,7 @@ void FuncDeclaration::semantic(Scope *sc) return; default: - { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; + { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.tdata()[vi]; Type *ti = NULL; /* Remember which functions this overrides @@ -867,7 +870,7 @@ void FuncDeclaration::semantic3(Scope *sc) { for (int i = 0; i < fthrows->dim; i++) { - Type *t = (Type *)fthrows->data[i]; + Type *t = fthrows->tdata()[i]; t = t->semantic(loc, sc); if (!t->isClassHandle()) @@ -880,7 +883,7 @@ void FuncDeclaration::semantic3(Scope *sc) { for (int i = 0; i < foverrides.dim; i++) { - FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; + FuncDeclaration *fdv = foverrides.tdata()[i]; if (fdv->fbody && !fdv->frequire) { @@ -1094,7 +1097,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (f->parameters) { for (size_t i = 0; i < f->parameters->dim; i++) - { Parameter *arg = (Parameter *)f->parameters->data[i]; + { Parameter *arg = f->parameters->tdata()[i]; //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars()); if (arg->type->ty == Ttuple) @@ -1117,7 +1120,7 @@ void FuncDeclaration::semantic3(Scope *sc) { /* parameters[] has all the tuples removed, as the back end * doesn't know about tuples */ - parameters = new Dsymbols(); + parameters = new VarDeclarations(); parameters->reserve(nparams); for (size_t i = 0; i < nparams; i++) { @@ -1154,7 +1157,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (f->parameters) { for (size_t i = 0; i < f->parameters->dim; i++) - { Parameter *arg = (Parameter *)f->parameters->data[i]; + { Parameter *arg = f->parameters->tdata()[i]; if (!arg->ident) continue; // never used, so ignore @@ -1169,7 +1172,7 @@ void FuncDeclaration::semantic3(Scope *sc) VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration(); assert(v); Expression *e = new VarExp(v->loc, v); - exps->data[j] = (void *)e; + exps->tdata()[j] = e; } assert(arg->ident); TupleDeclaration *v = new TupleDeclaration(loc, arg->ident, exps); @@ -1327,14 +1330,14 @@ void FuncDeclaration::semantic3(Scope *sc) sc2->incontract--; if (fbody) - { ClassDeclaration *cd = isClassMember(); + { AggregateDeclaration *ad = isAggregateMember(); /* If this is a class constructor */ - if (isCtorDeclaration() && cd) + if (ad && isCtorDeclaration()) { - for (int i = 0; i < cd->fields.dim; i++) - { VarDeclaration *v = (VarDeclaration *)cd->fields.data[i]; + for (size_t i = 0; i < ad->fields.dim; i++) + { VarDeclaration *v = ad->fields[i]; v->ctorinit = 0; } @@ -1363,37 +1366,51 @@ void FuncDeclaration::semantic3(Scope *sc) */ Dsymbol *p = toParent(); - ScopeDsymbol *ad = p->isScopeDsymbol(); - if (!ad) + ScopeDsymbol *pd = p->isScopeDsymbol(); + if (!pd) { error("static constructor can only be member of struct/class/module, not %s %s", p->kind(), p->toChars()); } else { - for (int i = 0; i < ad->members->dim; i++) - { Dsymbol *s = (Dsymbol *)ad->members->data[i]; + for (size_t i = 0; i < pd->members->dim; i++) + { Dsymbol *s = pd->members->tdata()[i]; s->checkCtorConstInit(); } } } - if (isCtorDeclaration() && cd) + if (isCtorDeclaration() && ad) { //printf("callSuper = x%x\n", sc2->callSuper); + ClassDeclaration *cd = ad->isClassDeclaration(); + // Verify that all the ctorinit fields got initialized if (!(sc2->callSuper & CSXthis_ctor)) { - for (int i = 0; i < cd->fields.dim; i++) - { VarDeclaration *v = (VarDeclaration *)cd->fields.data[i]; + for (size_t i = 0; i < ad->fields.dim; i++) + { VarDeclaration *v = ad->fields[i]; - if (v->ctorinit == 0 && v->isCtorinit() && !v->type->isMutable()) - error("missing initializer for final field %s", v->toChars()); + if (v->ctorinit == 0) + { + /* Current bugs in the flow analysis: + * 1. union members should not produce error messages even if + * not assigned to + * 2. structs should recognize delegating opAssign calls as well + * as delegating calls to other constructors + */ + if (v->isCtorinit() && !v->type->isMutable() && cd) + error("missing initializer for final field %s", v->toChars()); + else if (v->storage_class & STCnodefaultctor) + error("field %s must be initialized in constructor", v->toChars()); + } } } - if (!(sc2->callSuper & CSXany_ctor) && + if (cd && + !(sc2->callSuper & CSXany_ctor) && cd->baseClass && cd->baseClass->ctor) { sc2->callSuper = 0; @@ -1488,7 +1505,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (parameters) { for (size_t i = 0; i < parameters->dim; i++) { - VarDeclaration *v = (VarDeclaration *)parameters->data[i]; + VarDeclaration *v = parameters->tdata()[i]; if (v->storage_class & STCout) { assert(v->init); @@ -1511,7 +1528,7 @@ void FuncDeclaration::semantic3(Scope *sc) v_argptr->init = new VoidInitializer(loc); #else Type *t = argptr->type; - if (global.params.isX86_64) + if (global.params.is64bit) { // Initialize _argptr to point to v_argsave Expression *e1 = new VarExp(0, argptr); Expression *e = new SymOffExp(0, v_argsave, 6*8 + 8*16); @@ -1530,7 +1547,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (parameters && parameters->dim) { int lastNonref = parameters->dim -1; - p = (VarDeclaration *)parameters->data[lastNonref]; + p = parameters->tdata()[lastNonref]; /* The trouble with out and ref parameters is that taking * the address of it doesn't work, because later processing * adds in an extra level of indirection. So we skip over them. @@ -1544,7 +1561,7 @@ void FuncDeclaration::semantic3(Scope *sc) p = v_arguments; break; } - p = (VarDeclaration *)parameters->data[lastNonref]; + p = parameters->tdata()[lastNonref]; } } else @@ -1738,7 +1755,7 @@ void FuncDeclaration::semantic3(Scope *sc) if (parameters) { for (size_t i = 0; i < parameters->dim; i++) { - VarDeclaration *v = (VarDeclaration *)parameters->data[i]; + VarDeclaration *v = parameters->tdata()[i]; if (v->storage_class & (STCref | STCout)) continue; @@ -1929,7 +1946,7 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf) */ for (int i = 0; i < foverrides.dim; i++) { - FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; + FuncDeclaration *fdv = foverrides.tdata()[i]; /* The semantic pass on the contracts of the overridden functions must * be completed before code generation occurs (bug 3602). @@ -1956,7 +1973,7 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf) Statement *s2 = new ExpStatement(loc, e); Catch *c = new Catch(loc, NULL, NULL, sf); - Array *catches = new Array(); + Catches *catches = new Catches(); catches->push(c); sf = new TryCatchStatement(loc, s2, catches); } @@ -1984,7 +2001,7 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf) */ for (int i = 0; i < foverrides.dim; i++) { - FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; + FuncDeclaration *fdv = foverrides.tdata()[i]; /* The semantic pass on the contracts of the overridden functions must * be completed before code generation occurs (bug 3602 and 5230). @@ -2051,13 +2068,13 @@ int FuncDeclaration::overrides(FuncDeclaration *fd) * -2 can't determine because of forward references */ -int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) +int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim) { FuncDeclaration *mismatch = NULL; int bestvi = -1; for (int vi = 0; vi < dim; vi++) { - FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); + FuncDeclaration *fdv = vtbl->tdata()[vi]->isFuncDeclaration(); if (fdv && fdv->ident == ident) { if (type->equals(fdv->type)) // if exact match @@ -2406,7 +2423,7 @@ if (arguments) for (i = 0; i < arguments->dim; i++) { Expression *arg; - arg = (Expression *)arguments->data[i]; + arg = arguments->tdata()[i]; assert(arg->type); printf("\t%s: ", arg->toChars()); arg->type->print(); @@ -2449,7 +2466,7 @@ if (arguments) OutBuffer buf2; tf->modToBuffer(&buf2); - //printf("tf = %s, args = %s\n", tf->deco, ((Expression *)arguments->data[0])->type->deco); + //printf("tf = %s, args = %s\n", tf->deco, arguments->tdata()[0]->type->deco); error(loc, "%s%s is not callable using argument types %s", Parameter::argsTypesToChars(tf->parameters, tf->varargs), buf2.toChars(), @@ -2535,7 +2552,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g) } else e = p->type->defaultInit(); - args.data[u] = e; + args.tdata()[u] = e; } MATCH m = (MATCH) tg->callMatch(NULL, &args, 1); @@ -2855,6 +2872,14 @@ enum PURE FuncDeclaration::isPure() return purity; } +enum PURE FuncDeclaration::isPureBypassingInference() +{ + if (flags & FUNCFLAGpurityInprocess) + return PUREfwdref; + else + return isPure(); +} + /************************************** * The function is doing something impure, * so mark it as impure. @@ -3026,12 +3051,12 @@ int FuncDeclaration::needsClosure() //printf("FuncDeclaration::needsClosure() %s\n", toChars()); for (int i = 0; i < closureVars.dim; i++) - { VarDeclaration *v = (VarDeclaration *)closureVars.data[i]; + { VarDeclaration *v = closureVars.tdata()[i]; assert(v->isVarDeclaration()); //printf("\tv = %s\n", v->toChars()); for (int j = 0; j < v->nestedrefs.dim; j++) - { FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j]; + { FuncDeclaration *f = v->nestedrefs.tdata()[j]; assert(f != this); //printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf); @@ -3258,8 +3283,17 @@ void CtorDeclaration::semantic(Scope *sc) // See if it's the default constructor if (ad && tf->varargs == 0 && Parameter::dim(tf->parameters) == 0) - { if (ad->isStructDeclaration()) - error("default constructor not allowed for structs"); + { + StructDeclaration *sd = ad->isStructDeclaration(); + if (sd) + { + if (fbody || !(storage_class & STCdisable)) + { error("default constructor for structs only allowed with @disable and no body"); + storage_class |= STCdisable; + fbody = NULL; + } + sd->noDefaultCtor = TRUE; + } else ad->defaultCtor = this; } diff --git a/dmd2/hdrgen.c b/dmd2/hdrgen.c index e11c212f..78dd4001 100644 --- a/dmd2/hdrgen.c +++ b/dmd2/hdrgen.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // Initial header generation implementation by Dave Fladebo // http://www.digitalmars.com @@ -46,7 +46,7 @@ #include "mtype.h" #include "hdrgen.h" -void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs); +void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs); void Module::genhdrfile() { @@ -83,8 +83,8 @@ void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); } - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; s->toHBuffer(buf, hgs); } diff --git a/dmd2/idgen.c b/dmd2/idgen.c index df8230c6..c4eb46e1 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -34,6 +34,7 @@ Msgtable msgtable[] = { "max" }, { "min" }, { "This", "this" }, + { "super" }, { "ctor", "__ctor" }, { "dtor", "__dtor" }, { "cpctor", "__cpctor" }, diff --git a/dmd2/import.c b/dmd2/import.c index 18b2850c..e3106cd8 100644 --- a/dmd2/import.c +++ b/dmd2/import.c @@ -25,7 +25,7 @@ /********************************* Import ****************************/ -Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId, +Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId, int isstatic) : Dsymbol(id) { @@ -42,7 +42,7 @@ Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId, this->ident = aliasId; // Kludge to change Import identifier to first package else if (packages && packages->dim) - this->ident = (Identifier *)packages->data[0]; + this->ident = packages->tdata()[0]; } void Import::addAlias(Identifier *name, Identifier *alias) @@ -73,7 +73,7 @@ Dsymbol *Import::syntaxCopy(Dsymbol *s) for (size_t i = 0; i < names.dim; i++) { - si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]); + si->addAlias(names.tdata()[i], aliases.tdata()[i]); } return si; @@ -186,7 +186,14 @@ void Import::semantic(Scope *sc) enum PROT prot = sc->protection; if (!sc->explicitProtection) prot = PROTprivate; - sc->scopesym->importScope(mod, prot); + for (Scope *scd = sc; scd; scd = scd->enclosing) + { + if (scd->scopesym) + { + scd->scopesym->importScope(mod, prot); + break; + } + } } mod->semantic(); @@ -198,11 +205,11 @@ void Import::semantic(Scope *sc) sc = sc->push(mod); for (size_t i = 0; i < aliasdecls.dim; i++) - { Dsymbol *s = (Dsymbol *)aliasdecls.data[i]; + { Dsymbol *s = aliasdecls.tdata()[i]; //printf("\tImport alias semantic('%s')\n", s->toChars()); - if (!mod->search(loc, (Identifier *)names.data[i], 0)) - error("%s not found", ((Identifier *)names.data[i])->toChars()); + if (!mod->search(loc, names.tdata()[i], 0)) + error("%s not found", (names.tdata()[i])->toChars()); s->semantic(sc); } @@ -240,7 +247,7 @@ void Import::semantic(Scope *sc) { for (size_t i = 0; i < packages->dim; i++) { - Identifier *pid = (Identifier *)packages->data[i]; + Identifier *pid = packages->tdata()[i]; ob->printf("%s.", pid->toChars()); } } @@ -260,8 +267,8 @@ void Import::semantic(Scope *sc) else ob->writebyte(','); - Identifier *name = (Identifier *)names.data[i]; - Identifier *alias = (Identifier *)aliases.data[i]; + Identifier *name = names.tdata()[i]; + Identifier *alias = aliases.tdata()[i]; if (!alias) { @@ -317,8 +324,8 @@ int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) */ for (size_t i = 0; i < names.dim; i++) { - Identifier *name = (Identifier *)names.data[i]; - Identifier *alias = (Identifier *)aliases.data[i]; + Identifier *name = names.tdata()[i]; + Identifier *alias = aliases.tdata()[i]; if (!alias) alias = name; @@ -367,7 +374,7 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) if (packages && packages->dim) { for (size_t i = 0; i < packages->dim; i++) - { Identifier *pid = (Identifier *)packages->data[i]; + { Identifier *pid = packages->tdata()[i]; buf->printf("%s.", pid->toChars()); } diff --git a/dmd2/import.h b/dmd2/import.h index 4f442de5..40765f56 100644 --- a/dmd2/import.h +++ b/dmd2/import.h @@ -28,21 +28,21 @@ struct HdrGenState; struct Import : Dsymbol { - Array *packages; // array of Identifier's representing packages + Identifiers *packages; // array of Identifier's representing packages Identifier *id; // module Identifier Identifier *aliasId; int isstatic; // !=0 if static import // Pairs of alias=name to bind into current namespace - Array names; - Array aliases; + Identifiers names; + Identifiers aliases; - Array aliasdecls; // AliasDeclarations for names/aliases + AliasDeclarations aliasdecls; // AliasDeclarations for names/aliases Module *mod; Package *pkg; // leftmost package/module - Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId, + Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId, int isstatic); void addAlias(Identifier *name, Identifier *alias); diff --git a/dmd2/inifile.c b/dmd2/inifile.c index ede7a76c..1bed9fe7 100644 --- a/dmd2/inifile.c +++ b/dmd2/inifile.c @@ -70,8 +70,6 @@ const char *inifile(const char *argv0x, const char *inifilex) char *path; // need path for @P macro char *filename; OutBuffer buf; - int i; - int k; int envsection = 0; #if LOG @@ -137,7 +135,7 @@ const char *inifile(const char *argv0x, const char *inifilex) if (1){ // Search PATH for argv0 const char *p = getenv("PATH"); - Array *paths = FileName::splitPath(p); + Strings *paths = FileName::splitPath(p); filename = FileName::searchPath(paths, argv0, 0); if (!filename) goto Letc; // argv0 not found on path @@ -145,10 +143,9 @@ const char *inifile(const char *argv0x, const char *inifilex) if (FileName::exists(filename)) goto Ldone; } -#endif - // Search /etc/ for inifile Letc: +#endif filename = FileName::combine((char *)"/etc/", inifile); Ldone: @@ -169,9 +166,9 @@ const char *inifile(const char *argv0x, const char *inifilex) // Parse into lines int eof = 0; - for (i = 0; i < file.len && !eof; i++) + for (size_t i = 0; i < file.len && !eof; i++) { - int linestart = i; + size_t linestart = i; for (; i < file.len; i++) { @@ -199,7 +196,7 @@ const char *inifile(const char *argv0x, const char *inifilex) // The line is file.buffer[linestart..i] char *line; - int len; + size_t len; char *p; char *pn; @@ -211,13 +208,11 @@ const char *inifile(const char *argv0x, const char *inifilex) // First, expand the macros. // Macros are bracketed by % characters. - for (k = 0; k < len; k++) + for (size_t k = 0; k < len; k++) { if (line[k] == '%') { - int j; - - for (j = k + 1; j < len; j++) + for (size_t j = k + 1; j < len; j++) { if (line[j] == '%') { @@ -229,16 +224,16 @@ const char *inifile(const char *argv0x, const char *inifilex) p = (char *)"."; } else - { int len = j - k; + { size_t len2 = j - k; char tmp[10]; // big enough most of the time - if (len <= sizeof(tmp)) + if (len2 <= sizeof(tmp)) p = tmp; else - p = (char *)alloca(len); - len--; - memcpy(p, &line[k + 1], len); - p[len] = 0; + p = (char *)alloca(len2); + len2--; + memcpy(p, &line[k + 1], len2); + p[len2] = 0; strupr(p); p = getenv(p); if (!p) @@ -273,7 +268,7 @@ const char *inifile(const char *argv0x, const char *inifilex) case '[': // look for [Environment] p = skipspace(p + 1); - for (pn = p; isalnum(*pn); pn++) + for (pn = p; isalnum((unsigned char)*pn); pn++) ; if (pn - p == 11 && memicmp(p, "Environment", 11) == 0 && @@ -292,14 +287,14 @@ const char *inifile(const char *argv0x, const char *inifilex) // Convert name to upper case; // remove spaces bracketing = for (p = pn; *p; p++) - { if (islower(*p)) + { if (islower((unsigned char)*p)) *p &= ~0x20; - else if (isspace(*p)) + else if (isspace((unsigned char)*p)) memmove(p, p + 1, strlen(p)); else if (*p == '=') { p++; - while (isspace(*p)) + while (isspace((unsigned char)*p)) memmove(p, p + 1, strlen(p)); break; } @@ -326,7 +321,7 @@ const char *inifile(const char *argv0x, const char *inifilex) char *skipspace(const char *p) { - while (isspace(*p)) + while (isspace((unsigned char)*p)) p++; return (char *)p; } diff --git a/dmd2/init.c b/dmd2/init.c index 417a2ab4..b046b181 100644 --- a/dmd2/init.c +++ b/dmd2/init.c @@ -52,11 +52,11 @@ Initializers *Initializer::arraySyntaxCopy(Initializers *ai) { a = new Initializers(); a->setDim(ai->dim); - for (int i = 0; i < a->dim; i++) - { Initializer *e = (Initializer *)ai->data[i]; + for (size_t i = 0; i < a->dim; i++) + { Initializer *e = ai->tdata()[i]; e = e->syntaxCopy(); - a->data[i] = e; + a->tdata()[i] = e; } } return a; @@ -123,13 +123,13 @@ Initializer *StructInitializer::syntaxCopy() assert(field.dim == value.dim); ai->field.setDim(field.dim); ai->value.setDim(value.dim); - for (int i = 0; i < field.dim; i++) + for (size_t i = 0; i < field.dim; i++) { - ai->field.data[i] = field.data[i]; + ai->field.tdata()[i] = field.tdata()[i]; - Initializer *init = (Initializer *)value.data[i]; + Initializer *init = value.tdata()[i]; init = init->syntaxCopy(); - ai->value.data[i] = init; + ai->value.tdata()[i] = init; } return ai; } @@ -157,16 +157,18 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) if (ad->ctor) error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", ad->kind(), ad->toChars(), ad->toChars()); + size_t nfields = ad->fields.dim; + if (((StructDeclaration *)ad)->isnested) nfields--; for (size_t i = 0; i < field.dim; i++) { - Identifier *id = (Identifier *)field.data[i]; - Initializer *val = (Initializer *)value.data[i]; + Identifier *id = field.tdata()[i]; + Initializer *val = value.tdata()[i]; Dsymbol *s; VarDeclaration *v; if (id == NULL) { - if (fieldi >= ad->fields.dim) + if (fieldi >= nfields) { error(loc, "too many initializers for %s", ad->toChars()); errors = 1; field.remove(i); @@ -175,7 +177,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) } else { - s = (Dsymbol *)ad->fields.data[fieldi]; + s = ad->fields.tdata()[fieldi]; } } else @@ -192,22 +194,22 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) // Find out which field index it is for (fieldi = 0; 1; fieldi++) { - if (fieldi >= ad->fields.dim) + if (fieldi >= nfields) { error(loc, "%s.%s is not a per-instance initializable field", t->toChars(), s->toChars()); errors = 1; break; } - if (s == (Dsymbol *)ad->fields.data[fieldi]) + if (s == ad->fields.tdata()[fieldi]) break; } } if (s && (v = s->isVarDeclaration()) != NULL) { val = val->semantic(sc, v->type, needInterpret); - value.data[i] = (void *)val; - vars.data[i] = (void *)v; + value.tdata()[i] = val; + vars.tdata()[i] = v; } else { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars()); @@ -260,15 +262,20 @@ Expression *StructInitializer::toExpression() if (!sd) return NULL; Expressions *elements = new Expressions(); - elements->setDim(ad->fields.dim); - for (int i = 0; i < elements->dim; i++) + size_t nfields = ad->fields.dim; +#if DMDV2 + if (sd->isnested) + nfields--; +#endif + elements->setDim(nfields); + for (size_t i = 0; i < elements->dim; i++) { - elements->data[i] = NULL; + elements->tdata()[i] = NULL; } unsigned fieldi = 0; - for (int i = 0; i < value.dim; i++) + for (size_t i = 0; i < value.dim; i++) { - Identifier *id = (Identifier *)field.data[i]; + Identifier *id = field.tdata()[i]; if (id) { Dsymbol * s = ad->search(loc, id, 0); @@ -281,52 +288,52 @@ Expression *StructInitializer::toExpression() // Find out which field index it is for (fieldi = 0; 1; fieldi++) { - if (fieldi >= ad->fields.dim) + if (fieldi >= nfields) { s->error("is not a per-instance initializable field"); goto Lno; } - if (s == (Dsymbol *)ad->fields.data[fieldi]) + if (s == ad->fields.tdata()[fieldi]) break; } } - else if (fieldi >= ad->fields.dim) + else if (fieldi >= nfields) { error(loc, "too many initializers for '%s'", ad->toChars()); goto Lno; } - Initializer *iz = (Initializer *)value.data[i]; + Initializer *iz = value.tdata()[i]; if (!iz) goto Lno; Expression *ex = iz->toExpression(); if (!ex) goto Lno; - if (elements->data[fieldi]) + if (elements->tdata()[fieldi]) { error(loc, "duplicate initializer for field '%s'", - ((Dsymbol *)ad->fields.data[fieldi])->toChars()); + ad->fields.tdata()[fieldi]->toChars()); goto Lno; } - elements->data[fieldi] = ex; + elements->tdata()[fieldi] = ex; ++fieldi; } // Now, fill in any missing elements with default initializers. // We also need to validate any anonymous unions offset = 0; - for (int i = 0; i < elements->dim; ) + for (size_t i = 0; i < elements->dim; ) { - VarDeclaration * vd = ((Dsymbol *)ad->fields.data[i])->isVarDeclaration(); + VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration(); //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset); if (vd->offset < offset) { // Only the first field of a union can have an initializer - if (elements->data[i]) + if (elements->tdata()[i]) goto Lno; } else { - if (!elements->data[i]) + if (!elements->tdata()[i]) // Default initialize - elements->data[i] = vd->type->defaultInit(); + elements->tdata()[i] = vd->type->defaultInit(); } offset = vd->offset + vd->type->size(); i++; @@ -334,15 +341,15 @@ Expression *StructInitializer::toExpression() int unionSize = ad->numFieldsInUnion(i); if (unionSize == 1) { // Not a union -- default initialize if missing - if (!elements->data[i]) - elements->data[i] = vd->type->defaultInit(); + if (!elements->tdata()[i]) + elements->tdata()[i] = vd->type->defaultInit(); } else { // anonymous union -- check for errors int found = -1; // index of the first field with an initializer for (int j = i; j < i + unionSize; ++j) { - if (!elements->data[j]) + if (!elements->tdata()[j]) continue; if (found >= 0) { @@ -379,17 +386,17 @@ void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { //printf("StructInitializer::toCBuffer()\n"); buf->writebyte('{'); - for (int i = 0; i < field.dim; i++) + for (size_t i = 0; i < field.dim; i++) { if (i > 0) buf->writebyte(','); - Identifier *id = (Identifier *)field.data[i]; + Identifier *id = field.tdata()[i]; if (id) { buf->writestring(id->toChars()); buf->writebyte(':'); } - Initializer *iz = (Initializer *)value.data[i]; + Initializer *iz = value.tdata()[i]; if (iz) iz->toCBuffer(buf, hgs); } @@ -415,15 +422,15 @@ Initializer *ArrayInitializer::syntaxCopy() assert(index.dim == value.dim); ai->index.setDim(index.dim); ai->value.setDim(value.dim); - for (int i = 0; i < ai->value.dim; i++) - { Expression *e = (Expression *)index.data[i]; + for (size_t i = 0; i < ai->value.dim; i++) + { Expression *e = index.tdata()[i]; if (e) e = e->syntaxCopy(); - ai->index.data[i] = e; + ai->index.tdata()[i] = e; - Initializer *init = (Initializer *)value.data[i]; + Initializer *init = value.tdata()[i]; init = init->syntaxCopy(); - ai->value.data[i] = init; + ai->value.tdata()[i] = init; } return ai; } @@ -462,17 +469,17 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret) length = 0; for (i = 0; i < index.dim; i++) { - Expression *idx = (Expression *)index.data[i]; + Expression *idx = index.tdata()[i]; if (idx) { idx = idx->semantic(sc); idx = idx->optimize(WANTvalue | WANTinterpret); - index.data[i] = (void *)idx; + index.tdata()[i] = idx; length = idx->toInteger(); } - Initializer *val = (Initializer *)value.data[i]; + Initializer *val = value.tdata()[i]; val = val->semantic(sc, t->nextOf(), needInterpret); - value.data[i] = (void *)val; + value.tdata()[i] = val; length++; if (length == 0) { error(loc, "array dimension overflow"); @@ -508,7 +515,6 @@ Lerr: Expression *ArrayInitializer::toExpression() { Expressions *elements; - Expression *e; //printf("ArrayInitializer::toExpression(), dim = %d\n", dim); //static int i; if (++i == 2) halt(); @@ -529,8 +535,8 @@ Expression *ArrayInitializer::toExpression() case Tpointer: case Tarray: - edim = dim; - break; + edim = dim; + break; default: assert(0); @@ -541,8 +547,8 @@ Expression *ArrayInitializer::toExpression() edim = value.dim; for (size_t i = 0, j = 0; i < value.dim; i++, j++) { - if (index.data[i]) - j = ((Expression *)index.data[i])->toInteger(); + if (index.tdata()[i]) + j = index.tdata()[i]->toInteger(); if (j >= edim) edim = j + 1; } @@ -553,10 +559,10 @@ Expression *ArrayInitializer::toExpression() elements->zero(); for (size_t i = 0, j = 0; i < value.dim; i++, j++) { - if (index.data[i]) - j = ((Expression *)index.data[i])->toInteger(); + if (index.tdata()[i]) + j = (index.tdata()[i])->toInteger(); assert(j < edim); - Initializer *iz = (Initializer *)value.data[i]; + Initializer *iz = value.tdata()[i]; if (!iz) goto Lno; Expression *ex = iz->toExpression(); @@ -564,7 +570,7 @@ Expression *ArrayInitializer::toExpression() { goto Lno; } - elements->data[j] = ex; + elements->tdata()[j] = ex; } /* Fill in any missing elements with the default initializer @@ -573,13 +579,13 @@ Expression *ArrayInitializer::toExpression() Expression *init = NULL; for (size_t i = 0; i < edim; i++) { - if (!elements->data[i]) + if (!elements->tdata()[i]) { if (!type) goto Lno; if (!init) init = ((TypeNext *)t)->next->defaultInit(); - elements->data[i] = init; + elements->tdata()[i] = init; } } @@ -610,18 +616,18 @@ Expression *ArrayInitializer::toAssocArrayLiteral() for (size_t i = 0; i < value.dim; i++) { - e = (Expression *)index.data[i]; + e = index.tdata()[i]; if (!e) goto Lno; - keys->data[i] = (void *)e; + keys->tdata()[i] = e; - Initializer *iz = (Initializer *)value.data[i]; + Initializer *iz = value.tdata()[i]; if (!iz) goto Lno; e = iz->toExpression(); if (!e) goto Lno; - values->data[i] = (void *)e; + values->tdata()[i] = e; } e = new AssocArrayLiteralExp(loc, keys, values); return e; @@ -637,7 +643,7 @@ int ArrayInitializer::isAssociativeArray() { for (size_t i = 0; i < value.dim; i++) { - if (index.data[i]) + if (index.tdata()[i]) return 1; } return 0; @@ -695,17 +701,17 @@ Laa: void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writebyte('['); - for (int i = 0; i < index.dim; i++) + for (size_t i = 0; i < index.dim; i++) { if (i > 0) buf->writebyte(','); - Expression *ex = (Expression *)index.data[i]; + Expression *ex = index.tdata()[i]; if (ex) { ex->toCBuffer(buf, hgs); buf->writebyte(':'); } - Initializer *iz = (Initializer *)value.data[i]; + Initializer *iz = value.tdata()[i]; if (iz) iz->toCBuffer(buf, hgs); } @@ -782,9 +788,9 @@ bool arrayHasNonConstPointers(Expressions *elems) { for (size_t i = 0; i < elems->dim; i++) { - if (!(Expression *)elems->data[i]) + if (!elems->tdata()[i]) continue; - if (hasNonConstPointers((Expression *)elems->data[i])) + if (hasNonConstPointers(elems->tdata()[i])) return true; } return false; diff --git a/dmd2/init.h b/dmd2/init.h index 252dfa95..d9038cca 100644 --- a/dmd2/init.h +++ b/dmd2/init.h @@ -76,7 +76,7 @@ struct StructInitializer : Initializer Identifiers field; // of Identifier *'s Initializers value; // parallel array of Initializer *'s - Array vars; // parallel array of VarDeclaration *'s + VarDeclarations vars; // parallel array of VarDeclaration *'s AggregateDeclaration *ad; // which aggregate this is for StructInitializer(Loc loc); diff --git a/dmd2/inline.c b/dmd2/inline.c index 824e9ee3..63a33f22 100644 --- a/dmd2/inline.c +++ b/dmd2/inline.c @@ -54,7 +54,7 @@ int CompoundStatement::inlineCost(InlineCostState *ics) { int cost = 0; for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { cost += s->inlineCost(ics); @@ -69,7 +69,7 @@ int UnrolledLoopStatement::inlineCost(InlineCostState *ics) { int cost = 0; for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { cost += s->inlineCost(ics); @@ -141,13 +141,13 @@ int ImportStatement::inlineCost(InlineCostState *ics) /* -------------------------- */ -int arrayInlineCost(InlineCostState *ics, Array *arguments) +int arrayInlineCost(InlineCostState *ics, Expressions *arguments) { int cost = 0; if (arguments) { - for (int i = 0; i < arguments->dim; i++) - { Expression *e = (Expression *)arguments->data[i]; + for (size_t i = 0; i < arguments->dim; i++) + { Expression *e = arguments->tdata()[i]; if (e) cost += e->inlineCost(ics); @@ -246,7 +246,7 @@ int DeclarationExp::inlineCost(InlineCostState *ics) return COST_MAX; // finish DeclarationExp::doInline #else for (size_t i = 0; i < td->objects->dim; i++) - { Object *o = (Object *)td->objects->data[i]; + { Object *o = td->objects->tdata()[i]; if (o->dyncast() != DYNCAST_EXPRESSION) return COST_MAX; Expression *eo = (Expression *)o; @@ -354,8 +354,8 @@ int CondExp::inlineCost(InlineCostState *ics) struct InlineDoState { VarDeclaration *vthis; - Array from; // old Dsymbols - Array to; // parallel array of new Dsymbols + Dsymbols from; // old Dsymbols + Dsymbols to; // parallel array of new Dsymbols Dsymbol *parent; // new parent }; @@ -379,7 +379,7 @@ Expression *CompoundStatement::doInline(InlineDoState *ids) //printf("CompoundStatement::doInline() %d\n", statements->dim); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { Expression *e2 = s->doInline(ids); @@ -411,7 +411,7 @@ Expression *UnrolledLoopStatement::doInline(InlineDoState *ids) //printf("UnrolledLoopStatement::doInline() %d\n", statements->dim); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { Expression *e2 = s->doInline(ids); @@ -488,12 +488,12 @@ Expressions *arrayExpressiondoInline(Expressions *a, InlineDoState *ids) newa = new Expressions(); newa->setDim(a->dim); - for (int i = 0; i < a->dim; i++) - { Expression *e = (Expression *)a->data[i]; + for (size_t i = 0; i < a->dim; i++) + { Expression *e = a->tdata()[i]; if (e) e = e->doInline(ids); - newa->data[i] = (void *)e; + newa->tdata()[i] = e; } } return newa; @@ -507,16 +507,14 @@ Expression *Expression::doInline(InlineDoState *ids) Expression *SymOffExp::doInline(InlineDoState *ids) { - int i; - //printf("SymOffExp::doInline(%s)\n", toChars()); - for (i = 0; i < ids->from.dim; i++) + for (size_t i = 0; i < ids->from.dim; i++) { - if (var == (Declaration *)ids->from.data[i]) + if (var == ids->from.tdata()[i]) { SymOffExp *se = (SymOffExp *)copy(); - se->var = (Declaration *)ids->to.data[i]; + se->var = (Declaration *)ids->to.tdata()[i]; return se; } } @@ -525,16 +523,14 @@ Expression *SymOffExp::doInline(InlineDoState *ids) Expression *VarExp::doInline(InlineDoState *ids) { - int i; - //printf("VarExp::doInline(%s)\n", toChars()); - for (i = 0; i < ids->from.dim; i++) + for (size_t i = 0; i < ids->from.dim; i++) { - if (var == (Declaration *)ids->from.data[i]) + if (var == ids->from.tdata()[i]) { VarExp *ve = (VarExp *)copy(); - ve->var = (Declaration *)ids->to.data[i]; + ve->var = (Declaration *)ids->to.tdata()[i]; return ve; } } @@ -578,7 +574,7 @@ Expression *DeclarationExp::doInline(InlineDoState *ids) if (td) { for (size_t i = 0; i < td->objects->dim; i++) - { DsymbolExp *se = (DsymbolExp *)td->objects->data[i]; + { DsymbolExp *se = td->objects->tdata()[i]; assert(se->op == TOKdsymbol); se->s; } @@ -847,9 +843,9 @@ Statement *ExpStatement::inlineScan(InlineScanState *iss) Statement *CompoundStatement::inlineScan(InlineScanState *iss) { for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) - statements->data[i] = (void *)s->inlineScan(iss); + statements->tdata()[i] = s->inlineScan(iss); } return this; } @@ -857,9 +853,9 @@ Statement *CompoundStatement::inlineScan(InlineScanState *iss) Statement *UnrolledLoopStatement::inlineScan(InlineScanState *iss) { for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) - statements->data[i] = (void *)s->inlineScan(iss); + statements->tdata()[i] = s->inlineScan(iss); } return this; } @@ -942,11 +938,11 @@ Statement *SwitchStatement::inlineScan(InlineScanState *iss) sdefault = (DefaultStatement *)sdefault->inlineScan(iss); if (cases) { - for (int i = 0; i < cases->dim; i++) - { Statement *s; + for (size_t i = 0; i < cases->dim; i++) + { CaseStatement *s; - s = (Statement *) cases->data[i]; - cases->data[i] = (void *)s->inlineScan(iss); + s = cases->tdata()[i]; + cases->tdata()[i] = (CaseStatement *)s->inlineScan(iss); } } return this; @@ -1008,8 +1004,8 @@ Statement *TryCatchStatement::inlineScan(InlineScanState *iss) body = body->inlineScan(iss); if (catches) { - for (int i = 0; i < catches->dim; i++) - { Catch *c = (Catch *)catches->data[i]; + for (size_t i = 0; i < catches->dim; i++) + { Catch *c = catches->tdata()[i]; if (c->handler) c->handler = c->handler->inlineScan(iss); @@ -1054,17 +1050,17 @@ Statement *LabelStatement::inlineScan(InlineScanState *iss) /* -------------------------- */ -void arrayInlineScan(InlineScanState *iss, Array *arguments) +void arrayInlineScan(InlineScanState *iss, Expressions *arguments) { if (arguments) { - for (int i = 0; i < arguments->dim; i++) - { Expression *e = (Expression *)arguments->data[i]; + for (size_t i = 0; i < arguments->dim; i++) + { Expression *e = arguments->tdata()[i]; if (e) { e = e->inlineScan(iss); - arguments->data[i] = (void *)e; + arguments->tdata()[i] = e; } } } @@ -1084,7 +1080,7 @@ void scanVar(Dsymbol *s, InlineScanState *iss) if (td) { for (size_t i = 0; i < td->objects->dim; i++) - { DsymbolExp *se = (DsymbolExp *)td->objects->data[i]; + { DsymbolExp *se = (DsymbolExp *)td->objects->tdata()[i]; assert(se->op == TOKdsymbol); scanVar(se->s, iss); } @@ -1389,9 +1385,9 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) #if 0 if (parameters) { - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - VarDeclaration *v = (VarDeclaration *)parameters->data[i]; + VarDeclaration *v = parameters->tdata()[i]; if ( #if DMDV1 v->isOut() || v->isRef() || @@ -1419,7 +1415,6 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) inlineScan(); #endif -Lyes: if (!hdrscan) // Don't modify inlineStatus for header content scan inlineStatus = ILSyes; #if CANINLINE_LOG @@ -1436,7 +1431,7 @@ Lno: return 0; } -Expression *FuncDeclaration::doInline(InlineScanState *iss, Expression *ethis, Array *arguments) +Expression *FuncDeclaration::doInline(InlineScanState *iss, Expression *ethis, Expressions *arguments) { InlineDoState ids; DeclarationExp *de; @@ -1510,11 +1505,11 @@ Expression *FuncDeclaration::doInline(InlineScanState *iss, Expression *ethis, A { assert(parameters->dim == arguments->dim); - for (int i = 0; i < arguments->dim; i++) + for (size_t i = 0; i < arguments->dim; i++) { - VarDeclaration *vfrom = (VarDeclaration *)parameters->data[i]; + VarDeclaration *vfrom = parameters->tdata()[i]; VarDeclaration *vto; - Expression *arg = (Expression *)arguments->data[i]; + Expression *arg = arguments->tdata()[i]; ExpInitializer *ei; VarExp *ve; diff --git a/dmd2/interpret.c b/dmd2/interpret.c index 386491e9..6d6b0d29 100644 --- a/dmd2/interpret.c +++ b/dmd2/interpret.c @@ -23,6 +23,7 @@ #include "declaration.h" #include "aggregate.h" #include "id.h" +#include "utf.h" #define LOG 0 #define LOGASSIGN 0 @@ -31,7 +32,7 @@ struct InterState { InterState *caller; // calling function's InterState FuncDeclaration *fd; // function being interpreted - Dsymbols vars; // variables used in this function + VarDeclarations vars; // variables used in this function Statement *start; // if !=NULL, start execution at this statement Statement *gotoTarget; /* target of EXP_GOTO_INTERPRET result; also * target of labelled EXP_BREAK_INTERPRET or @@ -48,14 +49,6 @@ InterState::InterState() memset(this, 0, sizeof(InterState)); } -Expression *interpret_aaLen(InterState *istate, Expressions *arguments); -Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); -Expression *interpret_aaValues(InterState *istate, Expressions *arguments); - -Expression *interpret_length(InterState *istate, Expression *earg); -Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd); -Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd); - Expression * resolveReferences(Expression *e, Expression *thisval, bool *isReference = NULL); Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal); VarDeclaration *findParentVar(Expression *e, Expression *thisval); @@ -63,11 +56,14 @@ void addVarToInterstate(InterState *istate, VarDeclaration *v); bool needToCopyLiteral(Expression *expr); Expression *copyLiteral(Expression *e); Expression *paintTypeOntoLiteral(Type *type, Expression *lit); +bool evaluateIfBuiltin(Expression **result, InterState *istate, + FuncDeclaration *fd, Expressions *arguments, Expression *pthis); // Used for debugging only -void showCtfeExpr(Expression *e) +void showCtfeExpr(Expression *e, int level = 0) { + for (int i = level; i>0; --i) printf(" "); Expressions *elements = NULL; // We need the struct definition to detect block assignment StructDeclaration *sd = NULL; @@ -87,41 +83,49 @@ void showCtfeExpr(Expression *e) } else if (e->op == TOKstring) { - printf(" STRING %s %p\n", e->toChars(), ((StringExp *)e)->string); + printf("STRING %s %p\n", e->toChars(), ((StringExp *)e)->string); } else if (e->op == TOKslice) { - printf(" SLICE %p: %s\n", e, e->toChars()); - showCtfeExpr(((SliceExp *)e)->e1); + printf("SLICE %p: %s\n", e, e->toChars()); + showCtfeExpr(((SliceExp *)e)->e1, level + 1); } - else printf(" VALUE %p: %s\n", e, e->toChars()); + else if (e->op == TOKvar) + { + printf("VAR %p %s\n", e, e->toChars()); + VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration(); + if (v && v->getValue()) + showCtfeExpr(v->getValue(), level + 1); + } + else printf("VALUE %p: %s\n", e, e->toChars()); if (elements) { for (size_t i = 0; i < elements->dim; i++) - { Expression *z = (Expression *)elements->data[i]; + { Expression *z = elements->tdata()[i]; if (sd) { - Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); // If it is a void assignment, use the default initializer if (!z) { + for (int j = level; j>0; --j) printf(" "); printf(" field:void\n"); continue; } if ((v->type->ty != z->type->ty) && v->type->ty == Tsarray) { + for (int j = level; --j;) printf(" "); printf(" field: block initalized static array\n"); continue; } } - showCtfeExpr(z); + showCtfeExpr(z, level + 1); } } } - /************************************* * Attempt to interpret a function given the arguments. * Input: @@ -140,29 +144,10 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument #endif if (global.errors) return NULL; -#if DMDV2 - if (thisarg && - (!arguments || arguments->dim == 0)) - { - if (ident == Id::length) - return interpret_length(istate, thisarg); - else if (ident == Id::keys) - return interpret_keys(istate, thisarg, this); - else if (ident == Id::values) - return interpret_values(istate, thisarg, this); - } -#endif if (cantInterpret || semanticRun == PASSsemantic3) return NULL; - if (!fbody) - { cantInterpret = 1; - error("cannot be interpreted at compile time," - " because it has no available source code"); - return NULL; - } - if (semanticRun < PASSsemantic3 && scope) { int olderrors = global.errors; @@ -214,7 +199,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument eargs.setDim(dim); for (size_t i = 0; i < dim; i++) - { Expression *earg = (Expression *)arguments->data[i]; + { Expression *earg = arguments->tdata()[i]; Parameter *arg = Parameter::getNth(tf->parameters, i); if (arg->storageClass & (STCout | STCref)) @@ -247,14 +232,14 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument if (earg == EXP_CANT_INTERPRET) return NULL; } - eargs.data[i] = earg; + eargs.tdata()[i] = earg; } for (size_t i = 0; i < dim; i++) - { Expression *earg = (Expression *)eargs.data[i]; + { Expression *earg = eargs.tdata()[i]; Parameter *arg = Parameter::getNth(tf->parameters, i); - VarDeclaration *v = (VarDeclaration *)parameters->data[i]; - vsave.data[i] = v->getValue(); + VarDeclaration *v = parameters->tdata()[i]; + vsave.tdata()[i] = v->getValue(); #if LOG printf("arg[%d] = %s\n", i, earg->toChars()); #endif @@ -270,10 +255,10 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument v->setValueWithoutChecking(earg); /* Don't restore the value of v2 upon function return */ - for (size_t i = 0; i < (istate ? istate->vars.dim : 0); i++) - { VarDeclaration *vx = (VarDeclaration *)istate->vars.data[i]; + for (size_t j = 0; j < (istate ? istate->vars.dim : 0); j++) + { VarDeclaration *vx = istate->vars.tdata()[j]; if (vx == v2) - { istate->vars.data[i] = NULL; + { istate->vars.tdata()[j] = NULL; break; } } @@ -295,9 +280,9 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument if (!thisvar) // it's a reference. Find which variable it refers to. thisvar = findParentVar(thisarg->interpret(istate), istate->localThis); for (size_t i = 0; i < istate->vars.dim; i++) - { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; + { VarDeclaration *v = istate->vars.tdata()[i]; if (v == thisvar) - { istate->vars.data[i] = NULL; + { istate->vars.tdata()[i] = NULL; break; } } @@ -311,11 +296,15 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument //printf("saving local variables...\n"); valueSaves.setDim(istate->vars.dim); for (size_t i = 0; i < istate->vars.dim; i++) - { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; - if (v && v->parent == this) + { VarDeclaration *v = istate->vars.tdata()[i]; + bool isParentVar = false; + /* Nested functions only restore their own local variables + * (not variables in the parent function) + */ + if (v && (!isNested() || v->parent == this)) { //printf("\tsaving [%d] %s = %s\n", i, v->toChars(), v->getValue() ? v->getValue()->toChars() : ""); - valueSaves.data[i] = v->getValue(); + valueSaves.tdata()[i] = v->getValue(); v->setValueNull(); } } @@ -353,8 +342,8 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument */ for (size_t i = 0; i < dim; i++) { - VarDeclaration *v = (VarDeclaration *)parameters->data[i]; - v->setValueWithoutChecking((Expression *)vsave.data[i]); + VarDeclaration *v = parameters->tdata()[i]; + v->setValueWithoutChecking(vsave.tdata()[i]); } /* Clear __result. (Bug 6049). */ @@ -367,9 +356,12 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument */ //printf("restoring local variables...\n"); for (size_t i = 0; i < istate->vars.dim; i++) - { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; - if (v && v->parent == this) - { v->setValueWithoutChecking((Expression *)valueSaves.data[i]); + { VarDeclaration *v = istate->vars.tdata()[i]; + /* Nested functions only restore their own local variables + * (not variables in the parent function) + */ + if (v && (!isNested() || v->parent == this)) + { v->setValueWithoutChecking(valueSaves.tdata()[i]); //printf("\trestoring [%d] %s = %s\n", i, v->toChars(), v->getValue() ? v->getValue()->toChars() : ""); } } @@ -433,7 +425,7 @@ Expression *CompoundStatement::interpret(InterState *istate) if (statements) { for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { @@ -460,7 +452,7 @@ Expression *UnrolledLoopStatement::interpret(InterState *istate) if (statements) { for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; e = s->interpret(istate); if (e == EXP_CANT_INTERPRET) @@ -489,6 +481,12 @@ Expression *UnrolledLoopStatement::interpret(InterState *istate) return e; } +// For CTFE only. Returns true if 'e' is TRUE or a non-null pointer. +int isTrueBool(Expression *e) +{ + return e->isBool(TRUE) || (e->type->ty == Tpointer && e->op != TOKnull); +} + Expression *IfStatement::interpret(InterState *istate) { #if LOG @@ -512,7 +510,7 @@ Expression *IfStatement::interpret(InterState *istate) //if (e == EXP_CANT_INTERPRET) printf("cannot interpret\n"); if (e != EXP_CANT_INTERPRET) { - if (e->isBool(TRUE)) + if (isTrueBool(e)) e = ifbody ? ifbody->interpret(istate) : NULL; else if (e->isBool(FALSE)) e = elsebody ? elsebody->interpret(istate) : NULL; @@ -571,6 +569,17 @@ uinteger_t resolveArrayLength(Expression *e) return 0; } +// As Equal, but resolves slices before comparing +Expression *ctfeEqual(enum TOK op, Type *type, Expression *e1, Expression *e2) +{ + if (e1->op == TOKslice) + e1 = resolveSlice(e1); + if (e2->op == TOKslice) + e2 = resolveSlice(e2); + return Equal(op, type, e1, e2); +} + + void scrubArray(Expressions *elems); /* All results destined for use outside of CTFE need to have their CTFE-specific @@ -606,11 +615,11 @@ void scrubArray(Expressions *elems) { for (size_t i = 0; i < elems->dim; i++) { - Expression *m = (Expression *)elems->data[i]; + Expression *m = elems->tdata()[i]; if (!m) continue; m = scrubReturnValue(m); - elems->data[i] = m; + elems->tdata()[i] = m; } } @@ -789,7 +798,7 @@ Expression *DoStatement::interpret(InterState *istate) { e = EXP_CANT_INTERPRET; break; } - if (e->isBool(TRUE)) + if (isTrueBool(e)) { } else if (e->isBool(FALSE)) @@ -857,7 +866,7 @@ Expression *ForStatement::interpret(InterState *istate) { e = EXP_CANT_INTERPRET; break; } - if (e->isBool(TRUE)) + if (isTrueBool(e)) { Lhead: e = body ? body->interpret(istate) : NULL; @@ -1156,8 +1165,8 @@ Expression *SwitchStatement::interpret(InterState *istate) { for (size_t i = 0; i < cases->dim; i++) { - CaseStatement *cs = (CaseStatement *)cases->data[i]; - e = Equal(TOKequal, Type::tint32, econdition, cs->exp); + CaseStatement *cs = cases->tdata()[i]; + e = ctfeEqual(TOKequal, Type::tint32, econdition, cs->exp); if (e == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; if (e->isBool(TRUE)) @@ -1402,7 +1411,7 @@ Expression *StringExp::interpret(InterState *istate, CtfeGoal goal) * may crash), it hardly seems worth the massive performance hit. */ #if DMDV2 - if (!((TypeNext *)type)->next->mod & (MODconst | MODimmutable)) + if (!(((TypeNext *)type)->next->mod & (MODconst | MODimmutable))) { // It seems this happens only when there has been an explicit cast error("cannot cast a read-only string literal to mutable in CTFE"); return EXP_CANT_INTERPRET; @@ -1437,6 +1446,22 @@ Expression *SymOffExp::interpret(InterState *istate, CtfeGoal goal) Expression *val = getVarExp(loc, istate, var, goal); if (val->type->ty == Tarray || val->type->ty == Tsarray) { + // Check for unsupported type painting operations + Type *elemtype = ((TypeArray *)(val->type))->next; + if ( +#if DMDV2 + elemtype->castMod(0) != pointee->castMod(0) +#else + elemtype != pointee +#endif + && !(elemtype->isintegral() && pointee->isintegral() + && elemtype->size() == pointee->size())) + { + error("reinterpreting cast from %s to %s is not supported in CTFE", + val->type->toChars(), type->toChars()); + return EXP_CANT_INTERPRET; + } + TypeArray *tar = (TypeArray *)val->type; dinteger_t sz = pointee->size(); dinteger_t indx = offset/sz; @@ -1458,7 +1483,13 @@ Expression *SymOffExp::interpret(InterState *istate, CtfeGoal goal) return ie; } } - else if (offset == 0 && pointee == var->type) + else if (offset == 0 && +#if DMDV2 + pointee->castMod(0) == var->type->castMod(0) +#else + pointee == var->type +#endif + ) { if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef) { @@ -1472,7 +1503,7 @@ Expression *SymOffExp::interpret(InterState *istate, CtfeGoal goal) return e; } - error("Cannot interpret %s at compile time", toChars()); + error("Cannot convert &%s to %s at compile time", var->type->toChars(), type->toChars()); return EXP_CANT_INTERPRET; } @@ -1482,7 +1513,7 @@ Expression *AddrExp::interpret(InterState *istate, CtfeGoal goal) printf("AddrExp::interpret() %s\n", toChars()); #endif #if IN_LLVM - if (e1->op == TOKvar) + if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; if (ve->var->isFuncDeclaration()) return this; @@ -1536,8 +1567,12 @@ Expression *AddrExp::interpret(InterState *istate, CtfeGoal goal) } } #endif - - Expression *e = e1->interpret(istate, ctfeNeedLvalue); + + // For reference types, we need to return an lvalue ref. + TY tb = e1->type->toBasetype()->ty; + bool needRef = (tb == Tarray || tb == Taarray || tb == Tclass); + Expression *e = e1->interpret(istate, needRef ? ctfeNeedLvalueRef : ctfeNeedLvalue); + if (e == EXP_CANT_INTERPRET) return e; // Return a simplified address expression @@ -1684,9 +1719,10 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal error(loc, "variable %s is used before initialization", v->toChars()); else if (e == EXP_CANT_INTERPRET) return e; - else if ((goal == ctfeNeedLvalue) || e->op == TOKaddress + else if ((goal == ctfeNeedLvalue) || e->op == TOKstring || e->op == TOKstructliteral || e->op == TOKarrayliteral - || e->op == TOKassocarrayliteral || e->op == TOKslice) + || e->op == TOKassocarrayliteral || e->op == TOKslice + || e->type->toBasetype()->ty == Tpointer) return e; // it's already an Lvalue else e = e->interpret(istate, goal); @@ -1713,7 +1749,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal #endif } else - error(loc, "cannot interpret variable %s at compile time", v->toChars()); + error(loc, "cannot interpret declaration %s at compile time", d->toChars()); return e; } @@ -1821,7 +1857,7 @@ Expression *TupleExp::interpret(InterState *istate, CtfeGoal goal) Expressions *expsx = NULL; for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = exps->tdata()[i]; Expression *ex; ex = e->interpret(istate); @@ -1848,10 +1884,10 @@ Expression *TupleExp::interpret(InterState *istate, CtfeGoal goal) expsx->setDim(exps->dim); for (size_t j = 0; j < i; j++) { - expsx->data[j] = exps->data[j]; + expsx->tdata()[j] = exps->tdata()[j]; } } - expsx->data[i] = (void *)ex; + expsx->tdata()[i] = ex; } } if (expsx) @@ -1872,9 +1908,11 @@ Expression *ArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) if (elements) { for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; Expression *ex; + if (e->op == TOKindex) // segfault bug 6250 + assert( ((IndexExp*)e)->e1 != this); ex = e->interpret(istate); if (ex == EXP_CANT_INTERPRET) goto Lerror; @@ -1888,10 +1926,10 @@ Expression *ArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) expsx->setDim(elements->dim); for (size_t j = 0; j < elements->dim; j++) { - expsx->data[j] = elements->data[j]; + expsx->tdata()[j] = elements->tdata()[j]; } } - expsx->data[i] = (void *)ex; + expsx->tdata()[i] = ex; } } } @@ -1927,8 +1965,8 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) printf("AssocArrayLiteralExp::interpret() %s\n", toChars()); #endif for (size_t i = 0; i < keys->dim; i++) - { Expression *ekey = (Expression *)keys->data[i]; - Expression *evalue = (Expression *)values->data[i]; + { Expression *ekey = keys->tdata()[i]; + Expression *evalue = values->tdata()[i]; Expression *ex; ex = ekey->interpret(istate); @@ -1941,7 +1979,7 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) { if (keysx == keys) keysx = (Expressions *)keys->copy(); - keysx->data[i] = (void *)ex; + keysx->tdata()[i] = ex; } ex = evalue->interpret(istate); @@ -1954,7 +1992,7 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) { if (valuesx == values) valuesx = (Expressions *)values->copy(); - valuesx->data[i] = (void *)ex; + valuesx->tdata()[i] = ex; } } if (keysx != keys) @@ -1967,11 +2005,12 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal) /* Remove duplicate keys */ for (size_t i = 1; i < keysx->dim; i++) - { Expression *ekey = (Expression *)keysx->data[i - 1]; - + { Expression *ekey = keysx->tdata()[i - 1]; + if (ekey->op == TOKslice) + ekey = resolveSlice(ekey); for (size_t j = i; j < keysx->dim; j++) - { Expression *ekey2 = (Expression *)keysx->data[j]; - Expression *ex = Equal(TOKequal, Type::tbool, ekey, ekey2); + { Expression *ekey2 = keysx->tdata()[j]; + Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, ekey2); if (ex == EXP_CANT_INTERPRET) goto Lerr; if (ex->isBool(TRUE)) // if a match @@ -2022,7 +2061,7 @@ Expression *StructLiteralExp::interpret(InterState *istate, CtfeGoal goal) if (elements) { for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; if (!e) continue; @@ -2041,10 +2080,10 @@ Expression *StructLiteralExp::interpret(InterState *istate, CtfeGoal goal) expsx->setDim(elements->dim); for (size_t j = 0; j < elements->dim; j++) { - expsx->data[j] = elements->data[j]; + expsx->tdata()[j] = elements->tdata()[j]; } } - expsx->data[i] = (void *)ex; + expsx->tdata()[i] = ex; } } } @@ -2072,7 +2111,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expressions *elements = new Expressions(); elements->setDim(dim); for (size_t i = 0; i < dim; i++) - elements->data[i] = elem; + elements->tdata()[i] = elem; ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements); ae->type = type; return ae; @@ -2087,7 +2126,7 @@ StringExp *createBlockDuplicatedStringLiteral(Type *type, { unsigned char *s; s = (unsigned char *)mem.calloc(dim + 1, sz); - for (int elemi=0; elemitype = type; + se->sz = sz; + se->committed = true; return se; } +// Create an array literal of type 'newtype' with dimensions given by +// 'arguments'[argnum..$] +Expression *recursivelyCreateArrayLiteral(Type *newtype, InterState *istate, + Expressions *arguments, int argnum) +{ + Expression *lenExpr = ((arguments->tdata()[argnum]))->interpret(istate); + if (lenExpr == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + size_t len = (size_t)(lenExpr->toInteger()); + Type *elemType = ((TypeArray *)newtype)->next; + if (elemType->ty == Tarray) + { + assert(argnum < arguments->dim - 1); + Expression *elem = recursivelyCreateArrayLiteral(elemType, istate, + arguments, argnum + 1); + if (elem == EXP_CANT_INTERPRET) + return elem; + + Expressions *elements = new Expressions(); + elements->setDim(len); + for (size_t i = 0; i < len; i++) + elements->tdata()[i] = copyLiteral(elem); + ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements); + ae->type = newtype; + return ae; + } + assert(argnum == arguments->dim - 1); + if (elemType->ty == Tchar || elemType->ty == Twchar + || elemType->ty == Tdchar) + return createBlockDuplicatedStringLiteral(newtype, + (unsigned)(elemType->defaultInitLiteral()->toInteger()), + len, elemType->size()); + return createBlockDuplicatedArrayLiteral(newtype, + elemType->defaultInitLiteral(), + len); +} + Expression *NewExp::interpret(InterState *istate, CtfeGoal goal) { #if LOG printf("NewExp::interpret() %s\n", toChars()); #endif - if (newtype->ty == Tarray && arguments && arguments->dim == 1) - { - Expression *lenExpr = ((Expression *)(arguments->data[0]))->interpret(istate); - if (lenExpr == EXP_CANT_INTERPRET) - return EXP_CANT_INTERPRET; - return createBlockDuplicatedArrayLiteral(newtype, - ((TypeArray *)newtype)->next->defaultInitLiteral(), - lenExpr->toInteger()); - } + if (newtype->ty == Tarray && arguments) + return recursivelyCreateArrayLiteral(newtype, istate, arguments, 0); + if (newtype->toBasetype()->ty == Tstruct) { Expression *se = newtype->defaultInitLiteral(); @@ -2252,18 +2324,21 @@ Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type, TypeArray *tar = (TypeArray *)val->type; dinteger_t indx = ofs1; #if IN_LLVM // LDC: llvm uses typesafe pointer arithmetic - if (op == TOKadd || op == TOKaddass) + if (op == TOKadd || op == TOKaddass || op == TOKplusplus) indx += ofs2; - else if (op == TOKmin || op == TOKminass) + else if (op == TOKmin || op == TOKminass || op == TOKminusminus) indx -= ofs2; #else - if (op == TOKadd || op == TOKaddass) + if (op == TOKadd || op == TOKaddass || op == TOKplusplus) indx = indx + ofs2/sz; - else if (op == TOKmin || op == TOKminass) + else if (op == TOKmin || op == TOKminass || op == TOKminusminus) indx -= ofs2/sz; #endif else + { error(loc, "CTFE Internal compiler error: bad pointer operation"); + return EXP_CANT_INTERPRET; + } if (val->op != TOKarrayliteral && val->op != TOKstring) { error(loc, "CTFE Internal compiler error: pointer arithmetic %s", val->toChars()); @@ -2295,6 +2370,8 @@ Expression *BinExp::interpretCommon(InterState *istate, CtfeGoal goal, fp_t fp) { e1 = this->e1->interpret(istate, ctfeNeedLvalue); e2 = this->e2->interpret(istate, ctfeNeedLvalue); + if (e1 == EXP_CANT_INTERPRET || e2 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; return pointerDifference(loc, type, e1, e2); } if (this->e1->type->ty == Tpointer && this->e2->type->isintegral()) @@ -2305,10 +2382,12 @@ Expression *BinExp::interpretCommon(InterState *istate, CtfeGoal goal, fp_t fp) return EXP_CANT_INTERPRET; return pointerArithmetic(loc, op, type, e1, e2); } - if (this->e2->type->ty == Tpointer && this->e1->type->ty == TOKint64 && op==TOKadd) + if (this->e2->type->ty == Tpointer && this->e1->type->isintegral() && op==TOKadd) { e2 = this->e2->interpret(istate, ctfeNeedLvalue); e1 = this->e1->interpret(istate); + if (e1 == EXP_CANT_INTERPRET || e2 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; return pointerArithmetic(loc, op, type, e2, e1); } if (this->e1->type->ty == Tpointer || this->e2->type->ty == Tpointer) @@ -2411,7 +2490,7 @@ Expression *comparePointers(Loc loc, enum TOK op, Type *type, Expression *e1, Ex } } if (op == TOKnotidentity || op == TOKnotequal) - cmp ^= -1; + cmp ^= 1; return new IntegerExp(loc, cmp, type); } @@ -2427,6 +2506,8 @@ Expression *BinExp::interpretCommon2(InterState *istate, CtfeGoal goal, fp2_t fp { e1 = this->e1->interpret(istate, ctfeNeedLvalue); e2 = this->e2->interpret(istate, ctfeNeedLvalue); + if (e1 == EXP_CANT_INTERPRET || e2 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; e = comparePointers(loc, op, type, e1, e2); if (e == EXP_CANT_INTERPRET) { @@ -2491,16 +2572,16 @@ BIN_INTERPRET2(Cmp) /*************************************** * Duplicate the elements array, then set field 'indexToChange' = newelem. */ -Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, void *newelem) +Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, Expression *newelem) { Expressions *expsx = new Expressions(); expsx->setDim(oldelems->dim); for (size_t j = 0; j < expsx->dim; j++) { if (j == indexToChange) - expsx->data[j] = newelem; + expsx->tdata()[j] = newelem; else - expsx->data[j] = oldelems->data[j]; + expsx->tdata()[j] = oldelems->tdata()[j]; } return expsx; } @@ -2519,7 +2600,7 @@ void addVarToInterstate(InterState *istate, VarDeclaration *v) //printf("\tadding %s to istate\n", v->toChars()); break; } - if (v == (VarDeclaration *)istate->vars.data[i]) + if (v == istate->vars.tdata()[i]) break; } } @@ -2553,12 +2634,12 @@ Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae, Expressi int updated = 0; for (size_t j = valuesx->dim; j; ) { j--; - Expression *ekey = (Expression *)aae->keys->data[j]; - Expression *ex = Equal(TOKequal, Type::tbool, ekey, index); + Expression *ekey = aae->keys->tdata()[j]; + Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, index); if (ex == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; if (ex->isBool(TRUE)) - { valuesx->data[j] = (void *)newval; + { valuesx->tdata()[j] = newval; updated = 1; } } @@ -2659,7 +2740,7 @@ Expressions *copyLiteralArray(Expressions *oldelems) Expressions *newelems = new Expressions(); newelems->setDim(oldelems->dim); for (size_t i = 0; i < oldelems->dim; i++) - newelems->data[i] = copyLiteral((Expression *)(oldelems->data[i])); + newelems->tdata()[i] = copyLiteral(oldelems->tdata()[i]); return newelems; } @@ -2710,27 +2791,27 @@ Expression *copyLiteral(Expression *e) newelems->setDim(oldelems->dim); for (size_t i = 0; i < newelems->dim; i++) { - Expression *m = (Expression *)oldelems->data[i]; + Expression *m = oldelems->tdata()[i]; // We need the struct definition to detect block assignment StructDeclaration *sd = se->sd; - Dsymbol *s = (Dsymbol *)sd->fields.data[i]; + Dsymbol *s = sd->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v); // If it is a void assignment, use the default initializer if (!m) m = v->type->defaultInitLiteral(e->loc); - if (m->op == TOKslice) - m = resolveSlice(m); + if (m->op == TOKslice) + m = resolveSlice(m); if ((v->type->ty != m->type->ty) && v->type->ty == Tsarray) { // Block assignment from inside struct literals TypeSArray *tsa = (TypeSArray *)v->type; uinteger_t length = tsa->dim->toInteger(); - m = createBlockDuplicatedArrayLiteral(v->type, m, length); + m = createBlockDuplicatedArrayLiteral(v->type, m, (size_t)length); } else if (v->type->ty != Tarray) // NOTE: do not copy array references m = copyLiteral(m); - newelems->data[i] = m; + newelems->tdata()[i] = m; } #if DMDV2 StructLiteralExp *r = new StructLiteralExp(e->loc, se->sd, newelems, se->stype); @@ -2740,10 +2821,48 @@ Expression *copyLiteral(Expression *e) r->type = e->type; return r; } - - Expression *r = e->syntaxCopy(); - r->type = e->type; - return r; + else if (e->op == TOKfunction || e->op == TOKdelegate + || e->op == TOKsymoff || e->op == TOKnull + || e->op == TOKvar + || e->op == TOKint64 || e->op == TOKfloat64 + || e->op == TOKchar || e->op == TOKcomplex80) + { // Simple value types + Expression *r = e->syntaxCopy(); + r->type = e->type; + return r; + } + else if (e->type->ty == Tpointer && e->type->nextOf()->ty != Tfunction) + { // For pointers, we only do a shallow copy. + Expression *r; + if (e->op == TOKaddress) + r = new AddrExp(e->loc, ((AddrExp *)e)->e1); + else if (e->op == TOKindex) + r = new IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2); + else if (e->op == TOKdotvar) + r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1, + ((DotVarExp *)e)->var +#if DMDV2 + , ((DotVarExp *)e)->hasOverloads +#endif + ); + else + assert(0); + r->type = e->type; + return r; + } + else if (e->op == TOKslice) + { // Array slices only do a shallow copy + Expression *r = new SliceExp(e->loc, ((SliceExp *)e)->e1, + ((SliceExp *)e)->lwr, ((SliceExp *)e)->upr); + r->type = e->type; + return r; + } + else + { + e->error("Internal Compiler Error: CTFE literal %s", e->toChars()); + assert(0); + return e; + } } /* Deal with type painting. @@ -2810,7 +2929,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *n assert(0); break; } - existingAE->elements->data[j+firstIndex] + existingAE->elements->tdata()[j+firstIndex] = new IntegerExp(newval->loc, val, elemType); } } @@ -2823,7 +2942,7 @@ void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *n unsigned char *s = (unsigned char *)existingSE->string; for (size_t j = 0; j < newae->elements->dim; j++) { - unsigned value = ((Expression *)(newae->elements->data[j]))->toInteger(); + unsigned value = (unsigned)(newae->elements->tdata()[j]->toInteger()); switch (existingSE->sz) { case 1: s[j+firstIndex] = value; break; @@ -2892,8 +3011,8 @@ void assignInPlace(Expression *dest, Expression *src) for (size_t i= 0; i < oldelems->dim; ++i) { - Expression *e = (Expression *)newelems->data[i]; - Expression *o = (Expression *)oldelems->data[i]; + Expression *e = newelems->tdata()[i]; + Expression *o = oldelems->tdata()[i]; if (e->op == TOKstructliteral) { assert(o->op == e->op); @@ -2905,7 +3024,7 @@ void assignInPlace(Expression *dest, Expression *src) } else { - oldelems->data[i] = newelems->data[i]; + oldelems->tdata()[i] = newelems->tdata()[i]; } } } @@ -2926,16 +3045,16 @@ void recursiveBlockAssign(ArrayLiteralExp *ae, Expression *val, bool wantRef) for (size_t k = 0; k < ae->elements->dim; k++) { - if (!directblk && ((Expression *)(ae->elements->data[k]))->op == TOKarrayliteral) + if (!directblk && ae->elements->tdata()[k]->op == TOKarrayliteral) { - recursiveBlockAssign((ArrayLiteralExp *)(ae->elements->data[k]), val, wantRef); + recursiveBlockAssign((ArrayLiteralExp *)ae->elements->tdata()[k], val, wantRef); } else { if (wantRef || cow) - ae->elements->data[k] = val; + ae->elements->tdata()[k] = val; else - assignInPlace((Expression *)ae->elements->data[k], val); + assignInPlace(ae->elements->tdata()[k], val); } } } @@ -2989,6 +3108,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ if (!fp && this->e1->type->toBasetype() == this->e2->type->toBasetype() && (e1->type->toBasetype()->ty == Tarray || e1->type->toBasetype()->ty == Taarray || e1->type->toBasetype()->ty == Tclass) + // e = *x is never a reference, because *x is always a value + && this->e2->op != TOKstar ) { #if DMDV2 @@ -3062,6 +3183,13 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ e1 = e1->interpret(istate, ctfeNeedLvalue); if (e1 == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + if (!(e1->op == TOKvar || e1->op == TOKdotvar || e1->op == TOKindex + || e1->op == TOKslice)) + { + error("cannot dereference invalid pointer %s", + this->e1->toChars()); + return EXP_CANT_INTERPRET; + } } if (!(e1->op == TOKarraylength || e1->op == TOKvar || e1->op == TOKdotvar @@ -3077,7 +3205,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ // return a value OR a pointer assert(e1); assert(e1->type); - if ((e1->type->ty == Tpointer && e1->type->nextOf()->ty != Tfunction) && (e2->op == TOKsymoff || e2->op==TOKaddress || e2->op==TOKvar)) // && (e1->op==TOKaddress)) //TOKsymoff || e1->op==TOKdotvar)) + if ((e1->type->ty == Tpointer && e1->type->nextOf()->ty != Tfunction) && (e2->op == TOKsymoff || e2->op==TOKaddress || e2->op==TOKvar)) newval = this->e2->interpret(istate, ctfeNeedLvalue); else newval = this->e2->interpret(istate); @@ -3114,11 +3242,14 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ newval = copyLiteral(newval); if (newval->op == TOKslice) newval = resolveSlice(newval); + // It becomes a reference assignment + wantRef = true; } if (oldval->op == TOKslice) oldval = resolveSlice(oldval); if (this->e1->type->ty == Tpointer && this->e2->type->isintegral() - && (op==TOKaddass || op == TOKminass)) + && (op==TOKaddass || op == TOKminass || + op == TOKplusplus || op == TOKminusminus)) { oldval = this->e1->interpret(istate, ctfeNeedLvalue); newval = this->e2->interpret(istate); @@ -3180,18 +3311,18 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ assert(oldval->op == TOKarrayliteral); ArrayLiteralExp *ae = (ArrayLiteralExp *)oldval; for (size_t i = 0; i < copylen; i++) - elements->data[i] = ae->elements->data[i]; + elements->tdata()[i] = ae->elements->tdata()[i]; if (elemType->ty == Tstruct || elemType->ty == Tsarray) { /* If it is an aggregate literal representing a value type, * we need to create a unique copy for each element */ for (size_t i = copylen; i < newlen; i++) - elements->data[i] = copyLiteral(defaultElem); + elements->tdata()[i] = copyLiteral(defaultElem); } else { for (size_t i = copylen; i < newlen; i++) - elements->data[i] = defaultElem; + elements->tdata()[i] = defaultElem; } ArrayLiteralExp *aae = new ArrayLiteralExp(0, elements); aae->type = t; @@ -3199,6 +3330,12 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ // We have changed it into a reference assignment // Note that returnValue is still the new length. wantRef = true; + if (e1->op == TOKstar) + { // arr.length+=n becomes (t=&arr, *(t).length=*(t).length+n); + e1 = e1->interpret(istate, ctfeNeedLvalue); + if (e1 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + } } else { @@ -3239,16 +3376,16 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ } // This happens inside compiler-generated foreach statements. - if (op==TOKconstruct && this->e1->op==TOKvar && this->e2->op != TOKthis - && this->e2->op != TOKcomma + if (op==TOKconstruct && this->e1->op==TOKvar && + this->e2->op == TOKindex && ((VarExp*)this->e1)->var->storage_class & STCref) { VarDeclaration *v = ((VarExp *)e1)->var->isVarDeclaration(); - v->setValueNull(); - v->createStackValue(e2); #if (LOGASSIGN) printf("FOREACH ASSIGN %s=%s\n", v->toChars(), e2->toChars()); #endif + v->setValueNull(); + v->createStackValue(e2); return e2; } @@ -3265,7 +3402,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ // Deal with reference assignment // (We already have 'newval' for arraylength operations) // --------------------------------------- - if (wantRef && this->e1->op != TOKarraylength) + if (wantRef && !fp && this->e1->op != TOKarraylength) { newval = this->e2->interpret(istate, ctfeNeedLvalue); if (newval == EXP_CANT_INTERPRET) @@ -3389,9 +3526,9 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ return EXP_CANT_INTERPRET; assert(fieldi>=0 && fieldi < se->elements->dim); if (newval->op == TOKstructliteral) - assignInPlace((Expression *)(se->elements->data[fieldi]), newval); + assignInPlace(se->elements->tdata()[fieldi], newval); else - se->elements->data[fieldi] = newval; + se->elements->tdata()[fieldi] = newval; if (ultimateVar && !destinationIsReference) addVarToInterstate(istate, ultimateVar); return returnValue; @@ -3405,7 +3542,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ uinteger_t destarraylen = 0; // not for AAs // Set the $ variable, and find the array literal to modify - if (ie->e1->type->toBasetype()->ty != Taarray) + if (ie->e1->type->toBasetype()->ty != Taarray && ie->e1->type->toBasetype()->ty != Tpointer) { Expression *oldval = ie->e1->interpret(istate); if (oldval->op == TOKnull) @@ -3433,15 +3570,41 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ if (index == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + if (index->op == TOKslice) // only happens with AA assignment + index = resolveSlice(index); + ArrayLiteralExp *existingAE = NULL; StringExp *existingSE = NULL; AssocArrayLiteralExp *existingAA = NULL; + Expression *aggregate = resolveReferences(ie->e1, istate->localThis); + // Set the index to modify (for non-AAs), and check that it is in range - int indexToModify = 0; + dinteger_t indexToModify = 0; if (ie->e1->type->toBasetype()->ty != Taarray) { indexToModify = index->toInteger(); + if (ie->e1->type->toBasetype()->ty == Tpointer) + { + dinteger_t ofs; + aggregate = aggregate->interpret(istate, ctfeNeedLvalue); + if (aggregate == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + if (aggregate->op == TOKnull) + { + error("cannot index through null pointer %s", ie->e1->toChars()); + return EXP_CANT_INTERPRET; + } + if (aggregate->op == TOKint64) + { + error("cannot index through invalid pointer %s of value %s", + ie->e1->toChars(), aggregate->toChars()); + return EXP_CANT_INTERPRET; + } + aggregate = getAggregateFromPointer(aggregate, &ofs); + indexToModify += ofs; + destarraylen = resolveArrayLength(aggregate); + } if (indexToModify >= destarraylen) { error("array index %d is out of bounds [0..%d]", indexToModify, @@ -3450,17 +3613,22 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ } } - Expression *aggregate = resolveReferences(ie->e1, istate->localThis); - /* The only possible indexable LValue aggregates are array literals, * slices of array literals, and AA literals. */ if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || - aggregate->op == TOKslice || aggregate->op == TOKcall) + aggregate->op == TOKslice || aggregate->op == TOKcall || + aggregate->op == TOKstar) { aggregate = aggregate->interpret(istate, ctfeNeedLvalue); if (aggregate == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + // The array could be an index of an AA. Resolve it if so. + if (aggregate->op == TOKindex) + { + IndexExp *ix = (IndexExp *)aggregate; + aggregate = Index(ix->type, ix->e1, ix->e2); + } } if (aggregate->op == TOKvar) { @@ -3473,11 +3641,11 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ { // Assign to empty associative array Expressions *valuesx = new Expressions(); Expressions *keysx = new Expressions(); - Expression *index = ie->e2->interpret(istate); - if (index == EXP_CANT_INTERPRET) + Expression *indx = ie->e2->interpret(istate); + if (indx == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; valuesx->push(newval); - keysx->push(index); + keysx->push(indx); Expression *aae2 = new AssocArrayLiteralExp(loc, keysx, valuesx); aae2->type = v->type; newval = aae2; @@ -3520,9 +3688,9 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ if (existingAE) { if (newval->op == TOKstructliteral) - assignInPlace((Expression *)(existingAE->elements->data[indexToModify]), newval); + assignInPlace((Expression *)(existingAE->elements->tdata()[indexToModify]), newval); else - existingAE->elements->data[indexToModify] = newval; + existingAE->elements->tdata()[indexToModify] = newval; return returnValue; } if (existingSE) @@ -3596,8 +3764,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ if (upper == EXP_CANT_INTERPRET || lower == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; - int dim = dollar; - int upperbound = upper ? upper->toInteger() : dim; + size_t dim = dollar; + size_t upperbound = upper ? upper->toInteger() : dim; int lowerbound = lower ? lower->toInteger() : 0; if (!assignmentToSlicedPointer && (((int)lowerbound < 0) || (upperbound > dim))) @@ -3610,7 +3778,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ return newval; Expression *aggregate = resolveReferences(((SliceExp *)e1)->e1, istate->localThis); - int firstIndex = lowerbound; + dinteger_t firstIndex = lowerbound; ArrayLiteralExp *existingAE = NULL; StringExp *existingSE = NULL; @@ -3620,11 +3788,18 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ */ if (aggregate->op == TOKindex || aggregate->op == TOKdotvar || - aggregate->op == TOKslice || aggregate->op == TOKcall) + aggregate->op == TOKslice || + aggregate->op == TOKstar || aggregate->op == TOKcall) { aggregate = aggregate->interpret(istate, ctfeNeedLvalue); if (aggregate == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + // The array could be an index of an AA. Resolve it if so. + if (aggregate->op == TOKindex) + { + IndexExp *ie = (IndexExp *)aggregate; + aggregate = Index(ie->type, ie->e1, ie->e2); + } } if (aggregate->op == TOKvar) { @@ -3693,7 +3868,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ Expressions *newelems = ((ArrayLiteralExp *)newval)->elements; for (size_t j = 0; j < newelems->dim; j++) { - oldelems->data[j + firstIndex] = newelems->data[j]; + oldelems->tdata()[j + firstIndex] = newelems->tdata()[j]; } return newval; } @@ -3763,13 +3938,13 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ { if (!directblk) // Multidimensional array block assign - recursiveBlockAssign((ArrayLiteralExp *)w->data[j+firstIndex], newval, wantRef); + recursiveBlockAssign((ArrayLiteralExp *)w->tdata()[j+firstIndex], newval, wantRef); else { if (wantRef || cow) - existingAE->elements->data[j+firstIndex] = newval; + existingAE->elements->tdata()[j+firstIndex] = newval; else - assignInPlace((Expression *)existingAE->elements->data[j+firstIndex], newval); + assignInPlace(existingAE->elements->tdata()[j+firstIndex], newval); } } if (goal == ctfeNeedNothing) @@ -3844,14 +4019,14 @@ Expression *AndAndExp::interpret(InterState *istate, CtfeGoal goal) { if (e->isBool(FALSE)) e = new IntegerExp(e1->loc, 0, type); - else if (e->isBool(TRUE)) + else if (isTrueBool(e)) { e = e2->interpret(istate); if (e != EXP_CANT_INTERPRET) { if (e->isBool(FALSE)) e = new IntegerExp(e1->loc, 0, type); - else if (e->isBool(TRUE)) + else if (isTrueBool(e)) e = new IntegerExp(e1->loc, 1, type); else e = EXP_CANT_INTERPRET; @@ -3871,7 +4046,7 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal) Expression *e = e1->interpret(istate); if (e != EXP_CANT_INTERPRET) { - if (e->isBool(TRUE)) + if (isTrueBool(e)) e = new IntegerExp(e1->loc, 1, type); else if (e->isBool(FALSE)) { @@ -3880,7 +4055,7 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal) { if (e->isBool(FALSE)) e = new IntegerExp(e1->loc, 0, type); - else if (e->isBool(TRUE)) + else if (isTrueBool(e)) e = new IntegerExp(e1->loc, 1, type); else e = EXP_CANT_INTERPRET; @@ -3892,7 +4067,6 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal) return e; } - Expression *CallExp::interpret(InterState *istate, CtfeGoal goal) { Expression *e = EXP_CANT_INTERPRET; @@ -3987,101 +4161,60 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal) error("cannot evaluate %s at compile time", toChars()); return EXP_CANT_INTERPRET; } - if (pthis && fd) - { // Member function call - if (pthis->op == TOKthis) - pthis = istate ? istate->localThis : NULL; - else if (pthis->op == TOKcomma) - pthis = pthis->interpret(istate); - if (pthis == EXP_CANT_INTERPRET) - return NULL; - // Evaluate 'this' - if (pthis->op != TOKvar) - pthis = pthis->interpret(istate, ctfeNeedLvalue); - if (pthis == EXP_CANT_INTERPRET) - return NULL; - - if (!fd->fbody) - { - error("%s cannot be interpreted at compile time," - " because it has no available source code", fd->toChars()); - return EXP_CANT_INTERPRET; - } - Expression *eresult = fd->interpret(istate, arguments, pthis); - if (eresult) - e = eresult; - else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) - e = EXP_VOID_INTERPRET; - else - error("cannot evaluate %s at compile time", toChars()); - return e; - } - else if (fd) - { // function call -#if DMDV2 - enum BUILTIN b = fd->isBuiltin(); - if (b) - { Expressions args; - args.setDim(arguments->dim); - for (size_t i = 0; i < args.dim; i++) - { - Expression *earg = (Expression *)arguments->data[i]; - earg = earg->interpret(istate); - if (earg == EXP_CANT_INTERPRET) - return earg; - args.data[i] = (void *)earg; - } - e = eval_builtin(b, &args); - if (!e) - e = EXP_CANT_INTERPRET; - } - else -#endif - -#if DMDV1 - if (fd->ident == Id::aaLen) - return interpret_aaLen(istate, arguments); - else if (fd->ident == Id::aaKeys) - return interpret_aaKeys(istate, arguments); - else if (fd->ident == Id::aaValues) - return interpret_aaValues(istate, arguments); -#endif - - // Inline .dup - if (fd->ident == Id::adDup && arguments && arguments->dim == 2) - { - e = (Expression *)arguments->data[1]; - e = e->interpret(istate); - if (e != EXP_CANT_INTERPRET) - { - if (e->op == TOKslice) - e= resolveSlice(e); - e = expType(type, e); - e = copyLiteral(e); - } - } - else - { - if (!fd->fbody) - { - error("%s cannot be interpreted at compile time," - " because it has no available source code", fd->toChars()); - return EXP_CANT_INTERPRET; - } - Expression *eresult = fd->interpret(istate, arguments); - if (eresult) - e = eresult; - else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) - e = EXP_VOID_INTERPRET; - else - error("cannot evaluate %s at compile time", toChars()); - } - } - else + if (!fd) { error("cannot evaluate %s at compile time", toChars()); return EXP_CANT_INTERPRET; } + if (pthis) + { // Member function call + if (pthis->op == TOKthis) + pthis = istate ? istate->localThis : NULL; + else + { + if (pthis->op == TOKcomma) + pthis = pthis->interpret(istate); + if (pthis == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + // Evaluate 'this' + if (pthis->op != TOKvar) + pthis = pthis->interpret(istate, ctfeNeedLvalue); + if (pthis == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + } + } + // Check for built-in functions + Expression *eresult; + if (evaluateIfBuiltin(&eresult, istate, fd, arguments, pthis)) + return eresult; + + // Inline .dup. Special case because it needs the return type. + if (!pthis && fd->ident == Id::adDup && arguments && arguments->dim == 2) + { + e = arguments->tdata()[1]; + e = e->interpret(istate); + if (e != EXP_CANT_INTERPRET) + { + if (e->op == TOKslice) + e= resolveSlice(e); + e = expType(type, e); + e = copyLiteral(e); + } + return e; + } + if (!fd->fbody) + { + error("%s cannot be interpreted at compile time," + " because it has no available source code", fd->toChars()); + return EXP_CANT_INTERPRET; + } + eresult = fd->interpret(istate, arguments, pthis); + if (eresult) + e = eresult; + else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) + e = EXP_VOID_INTERPRET; + else + error("cannot evaluate %s at compile time", toChars()); return e; } @@ -4120,6 +4253,8 @@ Expression *CommaExp::interpret(InterState *istate, CtfeGoal goal) // initializer is a void function (the variable is modified // through a reference parameter instead). newval = newval->interpret(istate); + if (newval == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; if (newval != EXP_VOID_INTERPRET) { // v isn't necessarily null. @@ -4154,7 +4289,7 @@ Expression *CondExp::interpret(InterState *istate, CtfeGoal goal) e = econd->interpret(istate); if (e != EXP_CANT_INTERPRET) { - if (e->isBool(TRUE)) + if (isTrueBool(e)) e = e1->interpret(istate, goal); else if (e->isBool(FALSE)) e = e2->interpret(istate, goal); @@ -4203,8 +4338,8 @@ Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2) for (size_t i = ae->keys->dim; i;) { i--; - Expression *ekey = (Expression *)ae->keys->data[i]; - Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); + Expression *ekey = ae->keys->tdata()[i]; + Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, e2); if (ex == EXP_CANT_INTERPRET) { error("cannot evaluate %s==%s at compile time", @@ -4213,7 +4348,7 @@ Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2) } if (ex->isBool(TRUE)) { - return (Expression *)ae->values->data[i]; + return ae->values->tdata()[i]; } } return NULL; @@ -4227,7 +4362,35 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal) #if LOG printf("IndexExp::interpret() %s\n", toChars()); #endif + if (this->e1->type->toBasetype()->ty == Tpointer) + { + // Indexing a pointer. Note that there is no $ in this case. + e1 = this->e1->interpret(istate); + if (e1 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + e2 = this->e2->interpret(istate); + if (e2 == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + dinteger_t indx = e2->toInteger(); + dinteger_t ofs; + Expression *agg = getAggregateFromPointer(e1, &ofs); + if (agg->op == TOKnull) + { + error("cannot index null pointer %s", this->e1->toChars()); + return EXP_CANT_INTERPRET; + } + assert(agg->op == TOKarrayliteral || agg->op == TOKstring); + dinteger_t len = ArrayLength(Type::tsize_t, agg)->toInteger(); + Type *pointee = ((TypePointer *)agg->type)->next; + if ((indx + ofs) < 0 || (indx+ofs) > len) + { + error("pointer index [%jd] exceeds allocated memory block [0..%jd]", + indx+ofs, len); + return EXP_CANT_INTERPRET; + } + return Index(type, agg, new IntegerExp(loc, indx+ofs, Type::tsize_t)); + } e1 = this->e1->interpret(istate); if (e1 == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; @@ -4281,6 +4444,8 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal) } if (e1->op == TOKassocarrayliteral) { + if (e2->op == TOKslice) + e2 = resolveSlice(e2); e = findKeyInAA((AssocArrayLiteralExp *)e1, e2); if (!e) { @@ -4324,6 +4489,12 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal) e1 = this->e1->interpret(istate); if (e1 == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + if (e1->op == TOKint64) + { + error("cannot slice invalid pointer %s of value %s", + this->e1->toChars(), e1->toChars()); + return EXP_CANT_INTERPRET; + } /* Evaluate lower and upper bounds of slice */ @@ -4344,8 +4515,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal) { if (iupr == ilwr) { - IntegerExp * zero = new IntegerExp(loc, 0, Type::tsize_t); - e = new SliceExp(loc, agg, zero, zero); + e = new NullExp(loc); e->type = type; return e; } @@ -4378,8 +4548,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal) { if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef) return e1; - Expression *e = e1->castTo(NULL, type); - return e->interpret(istate); + return paintTypeOntoLiteral(type, e1); } /* Set the $ variable @@ -4476,6 +4645,8 @@ Expression *InExp::interpret(InterState *istate, CtfeGoal goal) error(" %s cannot be interpreted at compile time", toChars()); return EXP_CANT_INTERPRET; } + if (e1->op == TOKslice) + e1 = resolveSlice(e1); e = findKeyInAA((AssocArrayLiteralExp *)e2, e1); if (e == EXP_CANT_INTERPRET) return e; @@ -4533,6 +4704,26 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal) goto Lcant; if (to->ty == Tpointer && e1->op != TOKnull) { // Deal with casts from char[] to char * + if (e1->type->ty == Tarray || e1->type->ty == Tsarray) + { + // Check for unsupported type painting operations + Type *elemtype = ((TypeArray *)(e1->type))->next; + Type *pointee = ((TypePointer *)type)->next; + if ( +#if DMDV2 + e1->type->nextOf()->castMod(0) != to->nextOf()->castMod(0) +#else + e1->type->nextOf() != to->nextOf() +#endif + && !(elemtype->isintegral() && pointee->isintegral() + && elemtype->size() == pointee->size())) + { + error("reinterpreting cast from %s to %s is not supported in CTFE", + e1->type->toChars(), type->toChars()); + return EXP_CANT_INTERPRET; + } + } + if (e1->op == TOKslice) { if ( ((SliceExp *)e1)->e1->op == TOKnull) @@ -4553,6 +4744,20 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal) { return e1; } + if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type != e1->type) + { // type painting operation + IndexExp *ie = (IndexExp *)e1; + e = new IndexExp(e1->loc, ie->e1, ie->e2); + e->type = type; + return e; + } + if (e1->op == TOKint64) + { // Happens with Windows HANDLEs, for example. + return paintTypeOntoLiteral(to, e1); + } + error("pointer cast from %s to %s is not supported at compile time", + e1->type->toChars(), to->toChars()); + return EXP_CANT_INTERPRET; } if (to->ty == Tarray && e1->op == TOKslice) { @@ -4629,7 +4834,7 @@ Expression *AssertExp::interpret(InterState *istate, CtfeGoal goal) e1 = this->e1->interpret(istate); if (e1 == EXP_CANT_INTERPRET) goto Lcant; - if ((this->e1->op == TOKaddress && e1->op != TOKnull) || e1->isBool(TRUE)) + if (isTrueBool(e1)) { } else if (e1->isBool(FALSE)) @@ -4673,7 +4878,7 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) { if (ex->op == TOKstructliteral) { StructLiteralExp *se = (StructLiteralExp *)ex; - unsigned offset = ae->e2->toInteger(); + dinteger_t offset = ae->e2->toInteger(); e = se->getField(type, offset); if (!e) e = EXP_CANT_INTERPRET; @@ -4697,8 +4902,12 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) e = e1->interpret(istate, ctfeNeedLvalue); if (e == EXP_CANT_INTERPRET) return e; - if (e->op == TOKaddress) - e = ((AddrExp*)e)->e1; + if (!(e->op == TOKvar || e->op == TOKdotvar || e->op == TOKindex + || e->op == TOKslice || e->op == TOKaddress)) + { + error("dereference of invalid pointer '%s'", e->toChars()); + return EXP_CANT_INTERPRET; + } if (goal != ctfeNeedLvalue) { if (e->op == TOKindex && e->type->ty == Tpointer) @@ -4719,6 +4928,8 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) } return Index(type, ie->e1, ie->e2); } + if (ie->e1->op == TOKassocarrayliteral) + return Index(type, ie->e1, ie->e2); } if (e->op == TOKstructliteral) return e; @@ -4731,13 +4942,15 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) } if (e == EXP_CANT_INTERPRET) return e; - e->type = type; } + else if (e->op == TOKaddress) + e = ((AddrExp*)e)->e1; // *(&x) ==> x if (e->op == TOKnull) { error("dereference of null pointer '%s'", e1->toChars()); return EXP_CANT_INTERPRET; } + e->type = type; } #if LOG @@ -4773,7 +4986,7 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal) error("couldn't find field %s in %s", v->toChars(), type->toChars()); return EXP_CANT_INTERPRET; } - e = (Expression *)se->elements->data[i]; + e = se->elements->tdata()[i]; // If it is an lvalue literal, return it... if (e->op == TOKstructliteral) return e; @@ -4831,7 +5044,7 @@ Expression *interpret_aaLen(InterState *istate, Expressions *arguments) { if (!arguments || arguments->dim != 1) return NULL; - Expression *earg = (Expression *)arguments->data[0]; + Expression *earg = arguments->tdata()[0]; earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; @@ -4849,7 +5062,7 @@ Expression *interpret_aaKeys(InterState *istate, Expressions *arguments) #endif if (!arguments || arguments->dim != 2) return NULL; - Expression *earg = (Expression *)arguments->data[0]; + Expression *earg = arguments->tdata()[0]; earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; @@ -4871,7 +5084,7 @@ Expression *interpret_aaValues(InterState *istate, Expressions *arguments) #endif if (!arguments || arguments->dim != 3) return NULL; - Expression *earg = (Expression *)arguments->data[0]; + Expression *earg = arguments->tdata()[0]; earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; @@ -4951,6 +5164,362 @@ Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclarati #endif +#if DMDV2 +// Return true if t is an AA, or AssociativeArray!(key, value) +bool isAssocArray(Type *t) +{ + t = t->toBasetype(); + if (t->ty == Taarray) + return true; + if (t->ty != Tstruct) + return false; + StructDeclaration *sym = ((TypeStruct *)t)->sym; + if (sym->ident == Id::AssociativeArray) + return true; + return false; +} +#endif + +/* Decoding UTF strings for foreach loops. Duplicates the functionality of + * the twelve _aApplyXXn functions in aApply.d in the runtime. + */ +Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *deleg, bool rvs) +{ +#if LOG + printf("foreachApplyUtf(%s, %s)\n", str->toChars(), deleg->toChars()); +#endif + FuncDeclaration *fd = NULL; + Expression *pthis = NULL; + if (deleg->op == TOKdelegate) + { + fd = ((DelegateExp *)deleg)->func; + pthis = ((DelegateExp *)deleg)->e1; + } + else if (deleg->op == TOKfunction) + fd = ((FuncExp*)deleg)->fd; + + assert(fd && fd->fbody); + assert(fd->parameters); + int numParams = fd->parameters->dim; + assert(numParams == 1 || numParams==2); + Type *charType = fd->parameters->tdata()[numParams-1]->type; + Type *indexType = numParams == 2 ? fd->parameters->tdata()[0]->type + : Type::tsize_t; + uinteger_t len = resolveArrayLength(str); + if (len == 0) + return new IntegerExp(deleg->loc, 0, indexType); + + if (str->op == TOKslice) + str = resolveSlice(str); + + StringExp *se = NULL; + ArrayLiteralExp *ale = NULL; + if (str->op == TOKstring) + se = (StringExp *) str; + else if (str->op == TOKarrayliteral) + ale = (ArrayLiteralExp *)str; + else + { error("CTFE internal error: cannot foreach %s", str->toChars()); + return EXP_CANT_INTERPRET; + } + Expressions args; + args.setDim(numParams); + + Expression *eresult; + + // Buffers for encoding; also used for decoding array literals + unsigned char utf8buf[4]; + unsigned short utf16buf[2]; + + size_t start = rvs ? len : 0; + size_t end = rvs ? 0: len; + for (size_t indx = start; indx != end;) + { + // Step 1: Decode the next dchar from the string. + + const char *errmsg = NULL; // Used for reporting decoding errors + dchar_t rawvalue; // Holds the decoded dchar + size_t currentIndex = indx; // The index of the decoded character + + if (ale) + { // If it is an array literal, copy the code points into the buffer + int buflen = 1; // #code points in the buffer + size_t n = 1; // #code points in this char + size_t sz = ale->type->nextOf()->size(); + + switch(sz) + { + case 1: + if (rvs) + { // find the start of the string + --indx; + buflen = 1; + while (indx > 0 && buflen < 4) + { Expression * r = ale->elements->tdata()[indx]; + assert(r->op == TOKint64); + unsigned char x = (unsigned char)(((IntegerExp *)r)->value); + if ( (x & 0xC0) != 0x80) + break; + ++buflen; + } + } + else + buflen = (indx + 4 > len) ? len - indx : 4; + for (int i=0; i < buflen; ++i) + { + Expression * r = ale->elements->tdata()[indx + i]; + assert(r->op == TOKint64); + utf8buf[i] = (unsigned char)(((IntegerExp *)r)->value); + } + n = 0; + errmsg = utf_decodeChar(&utf8buf[0], buflen, &n, &rawvalue); + break; + case 2: + if (rvs) + { // find the start of the string + --indx; + buflen = 1; + Expression * r = ale->elements->tdata()[indx]; + assert(r->op == TOKint64); + unsigned short x = (unsigned short)(((IntegerExp *)r)->value); + if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF) + { + --indx; + ++buflen; + } + } + else + buflen = (indx + 2 > len) ? len - indx : 2; + for (int i=0; i < buflen; ++i) + { + Expression * r = ale->elements->tdata()[indx + i]; + assert(r->op == TOKint64); + utf16buf[i] = (unsigned short)(((IntegerExp *)r)->value); + } + n = 0; + errmsg = utf_decodeWchar(&utf16buf[0], buflen, &n, &rawvalue); + break; + case 4: + { + if (rvs) + --indx; + + Expression * r = ale->elements->tdata()[indx]; + assert(r->op == TOKint64); + rawvalue = ((IntegerExp *)r)->value; + n = 1; + } + break; + default: + assert(0); + } + if (!rvs) + indx += n; + } + else + { // String literals + size_t saveindx; // used for reverse iteration + + switch (se->sz) + { + case 1: + if (rvs) + { // find the start of the string + unsigned char *s = (unsigned char *)se->string; + --indx; + while (indx > 0 && ((s[indx]&0xC0)==0x80)) + --indx; + saveindx = indx; + } + errmsg = utf_decodeChar((unsigned char *)se->string, se->len, &indx, &rawvalue); + if (rvs) + indx = saveindx; + break; + case 2: + if (rvs) + { // find the start + unsigned short *s = (unsigned short *)se->string; + --indx; + if (s[indx] >= 0xDC00 && s[indx]<= 0xDFFF) + --indx; + saveindx = indx; + } + errmsg = utf_decodeWchar((unsigned short *)se->string, se->len, &indx, &rawvalue); + if (rvs) + indx = saveindx; + break; + case 4: + if (rvs) + --indx; + rawvalue = ((unsigned *)(se->string))[indx]; + if (!rvs) + ++indx; + break; + default: + assert(0); + } + } + if (errmsg) + { deleg->error("%s", errmsg); + return EXP_CANT_INTERPRET; + } + + // Step 2: encode the dchar in the target encoding + + int charlen = 1; // How many codepoints are involved? + switch(charType->size()) + { + case 1: + charlen = utf_codeLengthChar(rawvalue); + utf_encodeChar(&utf8buf[0], rawvalue); + break; + case 2: + charlen = utf_codeLengthWchar(rawvalue); + utf_encodeWchar(&utf16buf[0], rawvalue); + break; + case 4: + break; + default: + assert(0); + } + if (rvs) + currentIndex = indx; + + // Step 3: call the delegate once for each code point + + // The index only needs to be set once + if (numParams == 2) + args.tdata()[0] = new IntegerExp(deleg->loc, currentIndex, indexType); + + Expression *val = NULL; + + for (int k= 0; k < charlen; ++k) + { + dchar_t codepoint; + switch(charType->size()) + { + case 1: + codepoint = utf8buf[k]; + break; + case 2: + codepoint = utf16buf[k]; + break; + case 4: + codepoint = rawvalue; + break; + default: + assert(0); + } + val = new IntegerExp(str->loc, codepoint, charType); + + args.tdata()[numParams - 1] = val; + + eresult = fd->interpret(istate, &args, pthis); + if (eresult == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + + assert(eresult->op == TOKint64); + if (((IntegerExp *)eresult)->value != 0) + return eresult; + } + } + return eresult; +} + +/* If this is a built-in function, set 'result' to the interpreted result, + * and return true. + * Otherwise, return false + */ +bool evaluateIfBuiltin(Expression **result, InterState *istate, + FuncDeclaration *fd, Expressions *arguments, Expression *pthis) +{ + Expression *e = NULL; + int nargs = arguments ? arguments->dim : 0; +#if DMDV2 + if (pthis && isAssocArray(pthis->type) && nargs==0) + { + if (fd->ident == Id::length) + e = interpret_length(istate, pthis); + else if (fd->ident == Id::keys) + e = interpret_keys(istate, pthis, fd); + else if (fd->ident == Id::values) + e = interpret_values(istate, pthis, fd); + else if (fd->ident == Id::rehash) + e = pthis; // rehash is a no-op + } + if (!pthis) + { + enum BUILTIN b = fd->isBuiltin(); + if (b) + { Expressions args; + args.setDim(nargs); + for (size_t i = 0; i < args.dim; i++) + { + Expression *earg = arguments->tdata()[i]; + earg = earg->interpret(istate); + if (earg == EXP_CANT_INTERPRET) + { + *result = EXP_CANT_INTERPRET; + return true; + } + args.tdata()[i] = earg; + } + e = eval_builtin(b, &args); + if (!e) + e = EXP_CANT_INTERPRET; + } + } +#endif +#if DMDV1 + if (!pthis) + { + if (fd->ident == Id::aaLen) + e = interpret_aaLen(istate, arguments); + else if (fd->ident == Id::aaKeys) + e = interpret_aaKeys(istate, arguments); + else if (fd->ident == Id::aaValues) + e = interpret_aaValues(istate, arguments); + else if (fd->ident == Id::aaRehash && nargs == 2) + { // rehash is a no-op + Expression *earg = (Expression *)(arguments->data[0]); + return earg->interpret(istate, ctfeNeedLvalue); + } + } +#endif + if (!pthis) + { + size_t idlen = strlen(fd->ident->string); + if (nargs == 2 && (idlen == 10 || idlen == 11) + && !strncmp(fd->ident->string, "_aApply", 7)) + { // Functions from aApply.d and aApplyR.d in the runtime + bool rvs = (idlen == 11); // true if foreach_reverse + char c = fd->ident->string[idlen-3]; // char width: 'c', 'w', or 'd' + char s = fd->ident->string[idlen-2]; // string width: 'c', 'w', or 'd' + char n = fd->ident->string[idlen-1]; // numParams: 1 or 2. + // There are 12 combinations + if ( (n == '1' || n == '2') && + (c == 'c' || c == 'w' || c == 'd') && + (s == 'c' || s == 'w' || s == 'd') && c != s) + { Expression *str = arguments->tdata()[0]; + str = str->interpret(istate); + if (str == EXP_CANT_INTERPRET) + { + *result = EXP_CANT_INTERPRET; + return true; + } + *result = foreachApplyUtf(istate, str, arguments->tdata()[1], rvs); + return true; + } + } + } + if (!e) + return false; + *result = e; + return true; +} + +/*************************** CTFE Sanity Checks ***************************/ + /* Setter functions for CTFE variable values. * These functions exist to check for compiler CTFE bugs. */ @@ -4971,6 +5540,10 @@ bool isStackValueValid(Expression *newval) } if (newval->op == TOKvar) return true; + if (newval->type->nextOf()->ty == Tarray && newval->op == TOKslice) + return true; + if (newval->op == TOKint64) + return true; // Result of a cast, but cannot be dereferenced newval->error("CTFE internal error: illegal pointer value %s\n", newval->toChars()); return false; } @@ -5028,6 +5601,7 @@ bool isStackValueValid(Expression *newval) newval->error("CTFE internal error: illegal stack value %s\n", newval->toChars()); return false; } + bool isRefValueValid(Expression *newval) { assert(newval); diff --git a/dmd2/intrange.c b/dmd2/intrange.c index 12128ca2..0c0ed521 100644 --- a/dmd2/intrange.c +++ b/dmd2/intrange.c @@ -458,8 +458,8 @@ void IntRange::splitBySign(IntRange& negRange, bool& hasNegRange, const IntRange& IntRange::dump(const char* funcName, Expression *e) const { printf("[(%c)%#018llx, (%c)%#018llx] @ %s ::: %s\n", - imin.negative?'-':'+', imin.value, - imax.negative?'-':'+', imax.value, + imin.negative?'-':'+', (unsigned long long)imin.value, + imax.negative?'-':'+', (unsigned long long)imax.value, funcName, e->toChars()); return *this; } diff --git a/dmd2/irstate.h b/dmd2/irstate.h index 1b318aa9..75194b6f 100644 --- a/dmd2/irstate.h +++ b/dmd2/irstate.h @@ -20,8 +20,8 @@ struct Identifier; struct Symbol; struct FuncDeclaration; struct Blockx; -struct Array; struct elem; +#include "arraytypes.h" struct IRState { @@ -34,12 +34,10 @@ struct IRState Symbol *sthis; // 'this' parameter to function (member and nested) Symbol *sclosure; // pointer to closure instance Blockx *blx; - Array *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later + Dsymbols *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later elem *ehidden; // transmit hidden pointer to CallExp::toElem() Symbol *startaddress; -#if DMDV2 - Array *varsInScope; // variables that are in scope that will need destruction later -#endif + VarDeclarations *varsInScope; // variables that are in scope that will need destruction later block *breakBlock; block *contBlock; diff --git a/dmd2/json.c b/dmd2/json.c index 1adf3709..d3efacf5 100644 --- a/dmd2/json.c +++ b/dmd2/json.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2009 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -43,15 +43,17 @@ const char Pline[] = "line"; const char Ptype[] = "type"; const char Pcomment[] = "comment"; const char Pmembers[] = "members"; +const char Pprotection[] = "protection"; +const char* Pprotectionnames[] = {NULL, "none", "private", "package", "protected", "public", "export"}; void JsonRemoveComma(OutBuffer *buf); -void json_generate(Array *modules) +void json_generate(Modules *modules) { OutBuffer buf; buf.writestring("[\n"); - for (int i = 0; i < modules->dim; i++) - { Module *m = (Module *)modules->data[i]; + for (size_t i = 0; i < modules->dim; i++) + { Module *m = modules->tdata()[i]; if (global.params.verbose) printf("json gen %s\n", m->toChars()); m->toJsonBuffer(&buf); @@ -64,7 +66,7 @@ void json_generate(Array *modules) char *arg = global.params.xfilename; if (!arg || !*arg) { // Generate lib file name from first obj name - char *n = (char *)global.params.objfiles->data[0]; + char *n = global.params.objfiles->tdata()[0]; n = FileName::name(n); FileName *fn = FileName::forceExt(n, global.json_ext); @@ -192,8 +194,8 @@ void Module::toJsonBuffer(OutBuffer *buf) buf->writestring(" : [\n"); size_t offset = buf->offset; - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; @@ -211,13 +213,13 @@ void AttribDeclaration::toJsonBuffer(OutBuffer *buf) { //printf("AttribDeclaration::toJsonBuffer()\n"); - Array *d = include(NULL, NULL); + Dsymbols *d = include(NULL, NULL); if (d) { size_t offset = buf->offset; for (unsigned i = 0; i < d->dim; i++) - { Dsymbol *s = (Dsymbol *)d->data[i]; + { Dsymbol *s = d->tdata()[i]; //printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars()); if (offset != buf->offset) { buf->writestring(",\n"); @@ -259,6 +261,10 @@ void Declaration::toJsonBuffer(OutBuffer *buf) JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); + + if (prot()) + JsonProperty(buf, Pprotection, Pprotectionnames[prot()]); + if (type) JsonProperty(buf, Ptype, type->toChars()); @@ -285,8 +291,13 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf) JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); + + if (prot()) + JsonProperty(buf, Pprotection, Pprotectionnames[prot()]); + if (comment) JsonProperty(buf, Pcomment, (const char *)comment); + if (loc.linnum) JsonProperty(buf, Pline, loc.linnum); @@ -302,7 +313,7 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf) JsonString(buf, "interfaces"); buf->writestring(" : [\n"); size_t offset = buf->offset; - for (int i = 0; i < cd->interfaces_dim; i++) + for (size_t i = 0; i < cd->interfaces_dim; i++) { BaseClass *b = cd->interfaces[i]; if (offset != buf->offset) { buf->writestring(",\n"); @@ -320,8 +331,8 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf) JsonString(buf, Pmembers); buf->writestring(" : [\n"); size_t offset = buf->offset; - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; @@ -344,6 +355,10 @@ void TemplateDeclaration::toJsonBuffer(OutBuffer *buf) JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); + + if (prot()) + JsonProperty(buf, Pprotection, Pprotectionnames[prot()]); + if (comment) JsonProperty(buf, Pcomment, (const char *)comment); @@ -353,8 +368,8 @@ void TemplateDeclaration::toJsonBuffer(OutBuffer *buf) JsonString(buf, Pmembers); buf->writestring(" : [\n"); size_t offset = buf->offset; - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; @@ -374,9 +389,9 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf) { if (members) { - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->toJsonBuffer(buf); buf->writestring(",\n"); } @@ -389,6 +404,10 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf) JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); + + if (prot()) + JsonProperty(buf, Pprotection, Pprotectionnames[prot()]); + if (comment) JsonProperty(buf, Pcomment, (const char *)comment); @@ -403,8 +422,8 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf) JsonString(buf, Pmembers); buf->writestring(" : [\n"); size_t offset = buf->offset; - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; @@ -427,6 +446,9 @@ void EnumMember::toJsonBuffer(OutBuffer *buf) JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); + if (prot()) + JsonProperty(buf, Pprotection, Pprotectionnames[prot()]); + if (comment) JsonProperty(buf, Pcomment, (const char *)comment); diff --git a/dmd2/json.h b/dmd2/json.h index 9633d170..2c7e2e60 100644 --- a/dmd2/json.h +++ b/dmd2/json.h @@ -16,9 +16,9 @@ #pragma once #endif /* __DMC__ */ -struct Array; +#include "arraytypes.h" -void json_generate(Array *); +void json_generate(Modules *); #endif /* DMD_JSON_H */ diff --git a/dmd2/lexer.c b/dmd2/lexer.c index b3bef3f0..08001dc5 100644 --- a/dmd2/lexer.c +++ b/dmd2/lexer.c @@ -728,7 +728,6 @@ void Lexer::scan(Token *t) t->ustring = (unsigned char *)timestamp; Lstr: t->value = TOKstring; - Llen: t->postfix = 0; t->len = strlen((char *)t->ustring); } @@ -739,7 +738,7 @@ void Lexer::scan(Token *t) for (const char *p = global.version + 1; 1; p++) { char c = *p; - if (isdigit(c)) + if (isdigit((unsigned char)c)) minor = minor * 10 + c - '0'; else if (c == '.') { major = minor; @@ -1981,7 +1980,6 @@ TOK Lexer::number(Token *t) }; enum FLAGS flags = FLAGS_decimal; - int i; int base; unsigned c; unsigned char *start; @@ -2226,7 +2224,7 @@ done: p += 2, r = 16; else if (p[1] == 'b' || p[1] == 'B') p += 2, r = 2; - else if (isdigit(p[1])) + else if (isdigit((unsigned char)p[1])) p += 1, r = 8; } @@ -2572,7 +2570,10 @@ void Lexer::pragma() scan(&tok); if (tok.value == TOKint32v || tok.value == TOKint64v) - linnum = tok.uns64value - 1; + { linnum = tok.uns64value - 1; + if (linnum != tok.uns64value - 1) + error("line number out of range"); + } else goto Lerr; diff --git a/dmd2/lib.h b/dmd2/lib.h index 31ac1f99..abd31cb2 100644 --- a/dmd2/lib.h +++ b/dmd2/lib.h @@ -23,11 +23,16 @@ struct ObjSymbol ObjModule *om; }; +#include "arraytypes.h" + +typedef ArrayBase ObjModules; +typedef ArrayBase ObjSymbols; + struct Library { File *libfile; - Array objmodules; // ObjModule[] - Array objsymbols; // ObjSymbol[] + ObjModules objmodules; // ObjModule[] + ObjSymbols objsymbols; // ObjSymbol[] StringTable tab; diff --git a/dmd2/macro.h b/dmd2/macro.h index 1b8c73aa..7c939621 100644 --- a/dmd2/macro.h +++ b/dmd2/macro.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -19,8 +19,9 @@ #include "root.h" -class Macro +struct Macro { + private: Macro *next; // next in list unsigned char *name; // macro name diff --git a/dmd2/mars.c b/dmd2/mars.c index 8673fbe3..233364b5 100644 --- a/dmd2/mars.c +++ b/dmd2/mars.c @@ -100,7 +100,7 @@ Global::Global() "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; #endif ; - version = "v2.054"; + version = "v2.055"; #if IN_LLVM ldc_version = "LDC trunk"; llvm_version = "LLVM 2.9"; @@ -238,8 +238,6 @@ void halt() #endif } -extern signed char tyalignsize[]; - /*********************************** * Parse and append contents of environment variable envvar * to argc and argv[]. @@ -261,7 +259,7 @@ void getenv_setargv(const char *envvar, int *pargc, char** *pargv) env = mem.strdup(env); // create our own writable copy int argc = *pargc; - Array *argv = new Array(); + Strings *argv = new Strings(); argv->setDim(argc); int argc_left = 0; @@ -276,14 +274,13 @@ void getenv_setargv(const char *envvar, int *pargc, char** *pargv) argv->setDim(i); break; } else { - argv->data[i] = (void *)(*pargv)[i]; } } // HACK to stop required values from command line being drawn from DFLAGS argv->push((char*)""); argc++; - int j = 1; // leave argv[0] alone + size_t j = 1; // leave argv[0] alone while (1) { int wildcard = 1; // do wildcard expansion @@ -362,5 +359,5 @@ Ldone: argv->data[argc++] = (void *)(*pargv)[i]; *pargc = argc; - *pargv = (char **)argv->data; + *pargv = argv->tdata(); } diff --git a/dmd2/mars.h b/dmd2/mars.h index 8efc2664..29ddcd1c 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -29,6 +29,7 @@ Macros defined by the compiler, not the code: __DMC__ Digital Mars compiler _MSC_VER Microsoft compiler __GNUC__ Gnu compiler + __clang__ Clang compiler Host operating system: _WIN32 Microsoft NT, Windows 95, Windows 98, Win32s, @@ -113,8 +114,12 @@ void unittests(); */ #if _WIN32 +#ifndef TARGET_WINDOS #define TARGET_WINDOS 1 // Windows dmd generates Windows targets -#define OMFOBJ 1 +#endif +#ifndef OMFOBJ +#define OMFOBJ TARGET_WINDOS +#endif #endif #if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS @@ -130,9 +135,13 @@ void unittests(); #endif -struct Array; struct OutBuffer; +// Can't include arraytypes.h here, need to declare these directly. +template struct ArrayBase; +typedef ArrayBase Identifiers; +typedef ArrayBase Strings; + #if IN_LLVM enum ARCH { @@ -180,9 +189,9 @@ struct Param #endif ARCH cpu; // target CPU OS os; - bool is64bit; // generate X86_64 bit code char map; // generate linker .map file bool isLE; // generate little endian code + bool is64bit; // generate 64 bit code bool useDeprecated; // allow use of deprecated features bool useAssert; // generate runtime code for assert()'s bool useInvariants; // generate class invariant checks @@ -197,15 +206,15 @@ struct Param char enforcePropertySyntax; char *argv0; // program name - Array *imppath; // array of char*'s of where to look for import modules - Array *fileImppath; // array of char*'s of where to look for file import modules + 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 char *objdir; // .obj file output directory char *objname; // .obj file output name bool doDocComments; // process embedded documentation comments char *docdir; // write documentation file to docdir directory char *docname; // write documentation file to docname - Array *ddocfiles; // macro include files for Ddoc + Strings *ddocfiles; // macro include files for Ddoc bool doHdrGeneration; // process embedded documentation comments char *hdrdir; // write 'header' file to docdir directory @@ -215,15 +224,15 @@ struct Param char *xfilename; // write JSON file to xfilename unsigned debuglevel; // debug level - Array *debugids; // debug identifiers + Strings *debugids; // debug identifiers unsigned versionlevel; // version level - Array *versionids; // version identifiers + Strings *versionids; // version identifiers bool dump_source; - Array *defaultlibnames; // default libraries for non-debug builds - Array *debuglibnames; // default libraries for debug builds + Strings *defaultlibnames; // default libraries for non-debug builds + Strings *debuglibnames; // default libraries for debug builds char *moduleDepsFile; // filename for deps output OutBuffer *moduleDeps; // contents to be written to deps file @@ -241,9 +250,9 @@ struct Param bool run; // run resulting executable // Linker stuff - Array *objfiles; - Array *linkswitches; - Array *libfiles; + Strings *objfiles; + Strings *linkswitches; + Strings *libfiles; char *deffile; char *resfile; char *exefile; @@ -288,8 +297,8 @@ struct Global const char *map_ext; // for .map files const char *copyright; const char *written; - Array *path; // Array of char*'s which form the import lookup path - Array *filePath; // Array of char*'s which form the file import lookup path + Strings *path; // Array of char*'s which form the import lookup path + Strings *filePath; // Array of char*'s which form the file import lookup path int structalign; const char *version; #if IN_LLVM diff --git a/dmd2/module.c b/dmd2/module.c index 244dfad3..e9a7974e 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -64,9 +64,9 @@ AggregateDeclaration *Module::moduleinfo; Module *Module::rootModule; DsymbolTable *Module::modules; -Array Module::amodules; +Modules Module::amodules; -Array Module::deferred; // deferred Dsymbol's needing semantic() run on them +Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them unsigned Module::dprogress; void Module::init() @@ -79,8 +79,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen { FileName *srcfilename; #if IN_DMD - FileName *cfilename; - FileName *hfilename; FileName *objfilename; FileName *symfilename; #endif @@ -424,7 +422,7 @@ const char *Module::kind() return "module"; } -Module *Module::load(Loc loc, Array *packages, Identifier *ident) +Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) { Module *m; char *filename; @@ -438,10 +436,9 @@ Module *Module::load(Loc loc, Array *packages, Identifier *ident) if (packages && packages->dim) { OutBuffer buf; - int i; - for (i = 0; i < packages->dim; i++) - { Identifier *pid = (Identifier *)packages->data[i]; + for (size_t i = 0; i < packages->dim; i++) + { Identifier *pid = packages->tdata()[i]; buf.writestring(pid->toChars()); #if _WIN32 @@ -478,7 +475,7 @@ Module *Module::load(Loc loc, Array *packages, Identifier *ident) { for (size_t i = 0; i < global.path->dim; i++) { - char *p = (char *)global.path->data[i]; + char *p = global.path->tdata()[i]; char *n = FileName::combine(p, sdi); if (FileName::exists(n)) { result = n; @@ -502,7 +499,7 @@ Module *Module::load(Loc loc, Array *packages, Identifier *ident) if (packages) { for (size_t i = 0; i < packages->dim; i++) - { Identifier *pid = (Identifier *)packages->data[i]; + { Identifier *pid = packages->tdata()[i]; printf("%s.", pid->toChars()); } } @@ -529,10 +526,10 @@ void Module::read(Loc loc) */ if (global.path) { - for (int i = 0; i < global.path->dim; i++) + for (size_t i = 0; i < global.path->dim; i++) { - char *p = (char *)global.path->data[i]; - fprintf(stdmsg, "import path[%d] = %s\n", i, p); + char *p = global.path->tdata()[i]; + fprintf(stdmsg, "import path[%zd] = %s\n", i, p); } } else @@ -858,7 +855,7 @@ void Module::importAll(Scope *prevsc) // Add import of "object" if this module isn't "object" if (ident != Id::object) { - if (members->dim == 0 || ((Dsymbol *)members->data[0])->ident != Id::object) + if (members->dim == 0 || members->tdata()[0]->ident != Id::object) { Import *im = new Import(0, NULL, Id::object, NULL, 0); members->shift(im); @@ -869,9 +866,9 @@ void Module::importAll(Scope *prevsc) { // Add all symbols into module's symbol table symtab = new DsymbolTable(); - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->addMember(NULL, sc->scopesym, 1); } } @@ -883,14 +880,14 @@ void Module::importAll(Scope *prevsc) * before any semantic() on any of them. */ setScope(sc); // remember module scope for semantic - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; s->setScope(sc); } - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->importAll(sc); } @@ -927,7 +924,7 @@ void Module::semantic(Scope* unused_sc) // Add all symbols into module's symbol table symtab = new DsymbolTable(); - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->addMember(NULL, sc->scopesym, 1); } @@ -937,23 +934,23 @@ void Module::semantic(Scope* unused_sc) * If this works out well, it can be extended to all modules * before any semantic() on any of them. */ - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->setScope(sc); } #endif // Do semantic() on members that don't depend on others - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; //printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars()); s->semantic0(sc); } // Pass 1 semantic routines: do public side of the definition - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars()); s->semantic(sc); @@ -969,13 +966,12 @@ void Module::semantic(Scope* unused_sc) } void Module::semantic2(Scope* unused_sc) -{ int i; - +{ if (deferred.dim) { - for (int i = 0; i < deferred.dim; i++) + for (size_t i = 0; i < deferred.dim; i++) { - Dsymbol *sd = (Dsymbol *)deferred.data[i]; + Dsymbol *sd = deferred.tdata()[i]; sd->error("unable to resolve forward reference in definition"); } @@ -994,10 +990,10 @@ void Module::semantic2(Scope* unused_sc) //printf("Module = %p\n", sc.scopesym); // Pass 2 semantic routines: do initializers and function bodies - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { Dsymbol *s; - s = (Dsymbol *)members->data[i]; + s = members->tdata()[i]; s->semantic2(sc); } @@ -1008,8 +1004,7 @@ void Module::semantic2(Scope* unused_sc) } void Module::semantic3(Scope* unused_sc) -{ int i; - +{ //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent); if (semanticstarted >= 3) return; @@ -1023,10 +1018,10 @@ void Module::semantic3(Scope* unused_sc) //printf("Module = %p\n", sc.scopesym); // Pass 3 semantic routines: do initializers and function bodies - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { Dsymbol *s; - s = (Dsymbol *)members->data[i]; + s = members->tdata()[i]; //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars()); s->semantic3(sc); } @@ -1048,8 +1043,8 @@ void Module::inlineScan() // gets imported, it is unaffected by context. //printf("Module = %p\n", sc.scopesym); - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; //if (global.params.verbose) //printf("inline scan symbol %s\n", s->toChars()); @@ -1073,8 +1068,8 @@ void Module::gensymfile() buf.printf("// Sym file generated from '%s'", srcfile->toChars()); buf.writenl(); - for (int i = 0; i < members->dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members->dim; i++) + { Dsymbol *s = members->tdata()[i]; s->toCBuffer(&buf, &hgs); } @@ -1134,8 +1129,8 @@ Dsymbol *Module::symtabInsert(Dsymbol *s) void Module::clearCache() { - for (int i = 0; i < amodules.dim; i++) - { Module *m = (Module *)amodules.data[i]; + for (size_t i = 0; i < amodules.dim; i++) + { Module *m = amodules.tdata()[i]; m->searchCacheIdent = NULL; } } @@ -1147,9 +1142,9 @@ void Module::clearCache() void Module::addDeferredSemantic(Dsymbol *s) { // Don't add it if it is already there - for (int i = 0; i < deferred.dim; i++) + for (size_t i = 0; i < deferred.dim; i++) { - Dsymbol *sd = (Dsymbol *)deferred.data[i]; + Dsymbol *sd = deferred.tdata()[i]; if (sd == s) return; @@ -1194,10 +1189,10 @@ void Module::runDeferredSemantic() todo = (Dsymbol **)alloca(len * sizeof(Dsymbol *)); assert(todo); } - memcpy(todo, deferred.data, len * sizeof(Dsymbol *)); + memcpy(todo, deferred.tdata(), len * sizeof(Dsymbol *)); deferred.setDim(0); - for (int i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) { Dsymbol *s = todo[i]; @@ -1221,13 +1216,13 @@ int Module::imports(Module *m) //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); int aimports_dim = aimports.dim; #if 0 - for (int i = 0; i < aimports.dim; i++) + for (size_t i = 0; i < aimports.dim; i++) { Module *mi = (Module *)aimports.data[i]; printf("\t[%d] %s\n", i, mi->toChars()); } #endif - for (int i = 0; i < aimports.dim; i++) - { Module *mi = (Module *)aimports.data[i]; + for (size_t i = 0; i < aimports.dim; i++) + { Module *mi = aimports.tdata()[i]; if (mi == m) return TRUE; if (!mi->insearch) @@ -1250,16 +1245,16 @@ int Module::selfImports() //printf("Module::selfImports() %s\n", toChars()); if (!selfimports) { - for (int i = 0; i < amodules.dim; i++) - { Module *mi = (Module *)amodules.data[i]; + for (size_t i = 0; i < amodules.dim; i++) + { Module *mi = amodules.tdata()[i]; //printf("\t[%d] %s\n", i, mi->toChars()); mi->insearch = 0; } selfimports = imports(this) + 1; - for (int i = 0; i < amodules.dim; i++) - { Module *mi = (Module *)amodules.data[i]; + for (size_t i = 0; i < amodules.dim; i++) + { Module *mi = amodules.tdata()[i]; //printf("\t[%d] %s\n", i, mi->toChars()); mi->insearch = 0; } @@ -1270,7 +1265,7 @@ int Module::selfImports() /* =========================== ModuleDeclaration ===================== */ -ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) +ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe) { this->packages = packages; this->id = id; @@ -1280,12 +1275,11 @@ ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) char *ModuleDeclaration::toChars() { OutBuffer buf; - int i; if (packages && packages->dim) { - for (i = 0; i < packages->dim; i++) - { Identifier *pid = (Identifier *)packages->data[i]; + for (size_t i = 0; i < packages->dim; i++) + { Identifier *pid = packages->tdata()[i]; buf.writestring(pid->toChars()); buf.writeByte('.'); @@ -1310,7 +1304,7 @@ const char *Package::kind() } -DsymbolTable *Package::resolve(Array *packages, Dsymbol **pparent, Package **ppkg) +DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg) { DsymbolTable *dst = Module::modules; Dsymbol *parent = NULL; @@ -1320,10 +1314,9 @@ DsymbolTable *Package::resolve(Array *packages, Dsymbol **pparent, Package **ppk *ppkg = NULL; if (packages) - { int i; - - for (i = 0; i < packages->dim; i++) - { Identifier *pid = (Identifier *)packages->data[i]; + { + for (size_t i = 0; i < packages->dim; i++) + { Identifier *pid = packages->tdata()[i]; Dsymbol *p; p = dst->lookup(pid); diff --git a/dmd2/module.h b/dmd2/module.h index dc66a981..a931db25 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -51,7 +51,7 @@ struct Package : ScopeDsymbol Package(Identifier *ident); const char *kind(); - static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg); + static DsymbolTable *resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg); Package *isPackage() { return this; } @@ -62,8 +62,8 @@ struct Module : Package { static Module *rootModule; static DsymbolTable *modules; // symbol table of all modules - static Array amodules; // array of all modules - static Array deferred; // deferred Dsymbol's needing semantic() run on them + static Modules amodules; // array of all modules + static Dsymbols deferred; // deferred Dsymbol's needing semantic() run on them static unsigned dprogress; // progress resolving the deferred list static void init(); @@ -103,19 +103,19 @@ struct Module : Package // i.e. a module that will be taken all the // way to an object file - Array *decldefs; // top level declarations for this Module + Dsymbols *decldefs; // top level declarations for this Module - Array aimports; // all imported modules + Modules aimports; // all imported modules ModuleInfoDeclaration *vmoduleinfo; unsigned debuglevel; // debug level - Array *debugids; // debug identifiers - Array *debugidsNot; // forward referenced debug identifiers + Strings *debugids; // debug identifiers + Strings *debugidsNot; // forward referenced debug identifiers unsigned versionlevel; // version level - Array *versionids; // version identifiers - Array *versionidsNot; // forward referenced version identifiers + Strings *versionids; // version identifiers + Strings *versionidsNot; // forward referenced version identifiers Macro *macrotable; // document comment macros Escape *escapetable; // document comment escapes @@ -130,7 +130,7 @@ struct Module : Package Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen); ~Module(); - static Module *load(Loc loc, Array *packages, Identifier *ident); + static Module *load(Loc loc, Identifiers *packages, Identifier *ident); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toJsonBuffer(OutBuffer *buf); @@ -221,10 +221,10 @@ struct Module : Package struct ModuleDeclaration { Identifier *id; - Array *packages; // array of Identifier's representing packages + Identifiers *packages; // array of Identifier's representing packages bool safe; - ModuleDeclaration(Array *packages, Identifier *id, bool safe); + ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe); char *toChars(); }; diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 1ad0fb57..f2c9fb84 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -60,6 +60,7 @@ unsigned GetTypeAlignment(Ir* ir, Type* t); #endif FuncDeclaration *hasThis(Scope *sc); +void ObjectNotFound(Identifier *id); #define LOGDOTEXP 0 // log ::dotExp() @@ -196,16 +197,13 @@ void Type::init(Ir* _sir) #else void Type::init() #endif -{ int i; - int j; - +{ Lexer::initKeywords(); - for (i = 0; i < TMAX; i++) + for (size_t i = 0; i < TMAX; i++) sizeTy[i] = sizeof(TypeBasic); sizeTy[Tsarray] = sizeof(TypeSArray); sizeTy[Tarray] = sizeof(TypeDArray); - //sizeTy[Tnarray] = sizeof(TypeNArray); sizeTy[Taarray] = sizeof(TypeAArray); sizeTy[Tpointer] = sizeof(TypePointer); sizeTy[Treference] = sizeof(TypeReference); @@ -224,7 +222,6 @@ void Type::init() mangleChar[Tarray] = 'A'; mangleChar[Tsarray] = 'G'; - mangleChar[Tnarray] = '@'; mangleChar[Taarray] = 'H'; mangleChar[Tpointer] = 'P'; mangleChar[Treference] = 'R'; @@ -270,9 +267,9 @@ void Type::init() mangleChar[Tslice] = '@'; mangleChar[Treturn] = '@'; - for (i = 0; i < TMAX; i++) + for (size_t i = 0; i < TMAX; i++) { if (!mangleChar[i]) - fprintf(stdmsg, "ty = %d\n", i); + fprintf(stdmsg, "ty = %zd\n", i); assert(mangleChar[i]); } @@ -285,7 +282,7 @@ void Type::init() Tbool, Tascii, Twchar, Tdchar }; - for (i = 0; i < sizeof(basetab) / sizeof(basetab[0]); i++) + for (size_t i = 0; i < sizeof(basetab) / sizeof(basetab[0]); i++) { Type *t = new TypeBasic(basetab[i]); t = t->merge(); basic[basetab[i]] = t; @@ -382,7 +379,7 @@ Type *Type::trySemantic(Loc loc, Scope *sc) * Determine if converting 'this' to 'to' is an identity operation, * a conversion to const operation, or the types aren't the same. * Returns: - * MATCHequal 'this' == 'to' + * MATCHexact 'this' == 'to' * MATCHconst 'to' is const * MATCHnomatch conversion to mutable or invariant */ @@ -909,7 +906,7 @@ void Type::check() } Type *tn = nextOf(); - if (tn && ty != Tfunction && ty != Tdelegate) + if (tn && ty != Tfunction && tn->ty != Tfunction) { // Verify transitivity switch (mod) { @@ -1915,17 +1912,6 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident) ident != Id::stringof && ident != Id::offsetof) { - /* See if we should forward to the alias this. - */ - if (sym->aliasthis) - { /* Rewrite e.ident as: - * e.aliasthis.ident - */ - e = new DotIdExp(e->loc, e, sym->aliasthis->ident); - e = new DotIdExp(e->loc, e, ident); - return e->semantic(sc); - } - /* Look for overloaded opDot() to see if we should forward request * to it. */ @@ -1962,6 +1948,17 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident) return e; //return e->semantic(sc); } + + /* See if we should forward to the alias this. + */ + if (sym->aliasthis) + { /* Rewrite e.ident as: + * e.aliasthis.ident + */ + e = new DotIdExp(e->loc, e, sym->aliasthis->ident); + e = new DotIdExp(e->loc, e, ident); + return e->semantic(sc); + } } return Type::dotExp(sc, e, ident); @@ -2217,7 +2214,7 @@ Type *TypeNext::makeConst() return cto; } TypeNext *t = (TypeNext *)Type::makeConst(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable() && !next->isConst()) { if (next->isShared()) @@ -2241,7 +2238,7 @@ Type *TypeNext::makeInvariant() return ito; } TypeNext *t = (TypeNext *)Type::makeInvariant(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable()) { t->next = next->invariantOf(); @@ -2261,7 +2258,7 @@ Type *TypeNext::makeShared() return sto; } TypeNext *t = (TypeNext *)Type::makeShared(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable() && !next->isShared()) { @@ -2286,7 +2283,7 @@ Type *TypeNext::makeSharedConst() return scto; } TypeNext *t = (TypeNext *)Type::makeSharedConst(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable() && !next->isSharedConst()) { @@ -2308,7 +2305,7 @@ Type *TypeNext::makeWild() return wto; } TypeNext *t = (TypeNext *)Type::makeWild(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable() && !next->isConst() && !next->isWild()) { @@ -2333,7 +2330,7 @@ Type *TypeNext::makeSharedWild() return swto; } TypeNext *t = (TypeNext *)Type::makeSharedWild(); - if (ty != Tfunction && ty != Tdelegate && + if (ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && !next->isImmutable() && !next->isSharedConst()) { @@ -2351,7 +2348,7 @@ Type *TypeNext::makeMutable() { //printf("TypeNext::makeMutable() %p, %s\n", this, toChars()); TypeNext *t = (TypeNext *)Type::makeMutable(); - if ((ty != Tfunction && ty != Tdelegate && + if ((ty != Tfunction && next->ty != Tfunction && //(next->deco || next->ty == Tfunction) && next->isWild()) || ty == Tsarray) { @@ -2571,12 +2568,12 @@ unsigned TypeBasic::alignsize() #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS case Tint64: case Tuns64: - sz = global.params.isX86_64 ? 8 : 4; + sz = global.params.is64bit ? 8 : 4; break; case Tfloat64: case Timaginary64: - sz = global.params.isX86_64 ? 8 : 4; + sz = global.params.is64bit ? 8 : 4; break; case Tcomplex32: @@ -2584,7 +2581,7 @@ unsigned TypeBasic::alignsize() break; case Tcomplex64: - sz = global.params.isX86_64 ? 8 : 4; + sz = global.params.is64bit ? 8 : 4; break; #endif #if IN_DMD @@ -2832,7 +2829,6 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident) } } -Ldefault: return Type::getProperty(loc, ident); Livalue: @@ -3420,7 +3416,7 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol { error(loc, "tuple index %ju exceeds length %u", d, td->objects->dim); goto Ldefault; } - Object *o = (Object *)td->objects->data[(size_t)d]; + Object *o = td->objects->tdata()[(size_t)d]; if (o->dyncast() == DYNCAST_DSYMBOL) { *ps = (Dsymbol *)o; @@ -3440,7 +3436,7 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol */ Objects *objects = new Objects; objects->setDim(1); - objects->data[0] = o; + objects->tdata()[0] = o; TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects); *ps = tds; @@ -3474,7 +3470,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) { error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim); return Type::terror; } - Object *o = (Object *)sd->objects->data[(size_t)d]; + Object *o = sd->objects->tdata()[(size_t)d]; if (o->dyncast() != DYNCAST_TYPE) { error(loc, "%s is not a type", toChars()); return Type::terror; @@ -3551,7 +3547,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); goto Lerror; } - Parameter *arg = (Parameter *)tt->arguments->data[(size_t)d]; + Parameter *arg = tt->arguments->tdata()[(size_t)d]; return arg->type; } case Tstruct: @@ -3737,7 +3733,7 @@ Expression *TypeSArray::defaultInitLiteral(Loc loc) Expressions *elements = new Expressions(); elements->setDim(d); for (size_t i = 0; i < d; i++) - elements->data[i] = elementinit; + elements->tdata()[i] = elementinit; ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements); ae->type = this; return ae; @@ -3973,87 +3969,6 @@ int TypeDArray::hasPointers() } -/***************************** TypeNewArray *****************************/ - -#if 0 - -TypeNewArray::TypeNewArray(Type *telement) - : TypeArray(Tnewarray, telement) -{ - sym = NULL; -} - -Type *TypeNewArray::syntaxCopy() -{ - Type *t = next->syntaxCopy(); - if (t == next) - t = this; - else - { t = new TypeNewArray(t); - t->mod = mod; - } - return t; -} - -d_uns64 TypeNewArray::size(Loc loc) -{ - //printf("TypeNewArray::size()\n"); - return PTRSIZE; -} - -unsigned TypeNewArray::alignsize() -{ - return PTRSIZE; -} - -Type *TypeNewArray::semantic(Loc loc, Scope *sc) -{ Type *tn = next; - - tn = next->semantic(loc,sc); - Type *tbn = tn->toBasetype(); - switch (tbn->ty) - { - case Tfunction: - case Tnone: - case Ttuple: - error(loc, "can't have array of %s", tbn->toChars()); - tn = next = tint32; - break; - case Tstruct: - { TypeStruct *ts = (TypeStruct *)tbn; - if (0 && ts->sym->isnested) - error(loc, "cannot have array of inner structs %s", ts->toChars()); - break; - } - } - if (tn->isscope()) - error(loc, "cannot have array of scope %s", tn->toChars()); - - next = tn; - transitive(); - return merge(); -} - -void TypeNewArray::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - buf->writeByte('e'); - if (next) - next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); -} - -void TypeNewArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -{ - if (mod != this->mod) - { toCBuffer3(buf, hgs, mod); - return; - } - next->toCBuffer2(buf, hgs, this->mod); - buf->writestring("[new]"); -} - -#endif - /***************************** TypeAArray *****************************/ TypeAArray::TypeAArray(Type *t, Type *index) @@ -4190,6 +4105,10 @@ StructDeclaration *TypeAArray::getImpl() // Create AssociativeArray!(index, next) #if 1 + if (! Type::associativearray) + { + ObjectNotFound(Id::AssociativeArray); + } TemplateInstance *ti = new TemplateInstance(loc, Type::associativearray, tiargs); #else //Expression *e = new IdentifierExp(loc, Id::object); @@ -4343,11 +4262,18 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident) } else #endif + if (ident != Id::__sizeof && + ident != Id::__xalignof && + ident != Id::init && + ident != Id::mangleof && + ident != Id::stringof && + ident != Id::offsetof) { e->type = getImpl()->type; e = e->type->dotExp(sc, e, ident); - //e = Type::dotExp(sc, e, ident); } + else + e = Type::dotExp(sc, e, ident); return e; } @@ -4501,14 +4427,35 @@ MATCH TypePointer::implicitConvTo(Type *to) if (equals(to)) return MATCHexact; - if (to->ty == Tpointer) + if (next->ty == Tfunction) + { + if (to->ty == Tpointer) + { + TypePointer *tp = (TypePointer*)to; + if (tp->next->ty == Tfunction) + { + if (next->equals(tp->next)) + return MATCHconst; + + if (next->covariant(tp->next) == 1) + return MATCHconvert; + } + else if (tp->next->ty == Tvoid) + { + // Allow conversions to void* + return MATCHconvert; + } + } + return MATCHnomatch; + } + else if (to->ty == Tpointer) { TypePointer *tp = (TypePointer *)to; assert(tp->next); if (!MODimplicitConv(next->mod, tp->next->mod)) return MATCHnomatch; // not const-compatible - /* Alloc conversion to void[] + /* Alloc conversion to void* */ if (next->ty != Tvoid && tp->next->ty == Tvoid) { @@ -4532,6 +4479,18 @@ MATCH TypePointer::implicitConvTo(Type *to) return MATCHnomatch; } +MATCH TypePointer::constConv(Type *to) +{ + if (next->ty == Tfunction) + { + if (to->nextOf() && next->equals(((TypeNext*)to)->next)) + return Type::constConv(to); + else + return MATCHnomatch; + } + return TypeNext::constConv(to); +} + int TypePointer::isscalar() { return TRUE; @@ -4990,9 +4949,9 @@ void TypeFunction::toCBufferWithAttributes(OutBuffer *buf, Identifier *ident, Hd } if (td) { buf->writeByte('('); - for (int i = 0; i < td->origParameters->dim; i++) + for (size_t i = 0; i < td->origParameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)td->origParameters->data[i]; + TemplateParameter *tp = td->origParameters->tdata()[i]; if (i) buf->writestring(", "); tp->toCBuffer(buf, hgs); @@ -5093,10 +5052,10 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) if (parameters) { tf->parameters = (Parameters *)parameters->copy(); for (size_t i = 0; i < parameters->dim; i++) - { Parameter *arg = (Parameter *)parameters->data[i]; + { Parameter *arg = parameters->tdata()[i]; Parameter *cpy = (Parameter *)mem.malloc(sizeof(Parameter)); memcpy(cpy, arg, sizeof(Parameter)); - tf->parameters->data[i] = (void *)cpy; + tf->parameters->tdata()[i] = cpy; } } @@ -5220,7 +5179,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) { size_t tdim = tt->arguments->dim; for (size_t j = 0; j < tdim; j++) - { Parameter *narg = (Parameter *)tt->arguments->data[j]; + { Parameter *narg = tt->arguments->tdata()[j]; narg->storageClass |= fparam->storageClass; } fparam->storageClass = 0; @@ -5240,7 +5199,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) if (fparam->storageClass & STCauto) { if (fargs && i < fargs->dim) - { Expression *farg = (Expression *)fargs->data[i]; + { Expression *farg = fargs->tdata()[i]; if (farg->isLvalue()) ; // ref parameter else @@ -5297,10 +5256,8 @@ void TypeFunction::purityLevel() { Parameter *fparam = Parameter::getNth(tf->parameters, i); if (fparam->storageClass & STClazy) { - /* We could possibly allow this by doing further analysis on the - * lazy parameter to see if it's pure. - */ - error(0, "cannot have lazy parameters to a pure function"); + tf->purity = PUREweak; + break; } if (fparam->storageClass & STCout) { @@ -5413,7 +5370,7 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag) goto L1; goto Nomatch; // not enough arguments } - arg = (Expression *)args->data[u]; + arg = args->tdata()[u]; assert(arg); //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars()); @@ -5490,7 +5447,7 @@ int TypeFunction::callMatch(Expression *ethis, Expressions *args, int flag) { TypeArray *ta = (TypeArray *)tb; for (; u < nargs; u++) { - arg = (Expression *)args->data[u]; + arg = args->tdata()[u]; assert(arg); #if 1 /* If lazy array of delegates, @@ -5758,9 +5715,9 @@ void TypeQualified::syntaxCopyHelper(TypeQualified *t) { //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars()); idents.setDim(t->idents.dim); - for (int i = 0; i < idents.dim; i++) + for (size_t i = 0; i < idents.dim; i++) { - Identifier *id = (Identifier *)t->idents.data[i]; + Identifier *id = t->idents.tdata()[i]; if (id->dyncast() == DYNCAST_DSYMBOL) { TemplateInstance *ti = (TemplateInstance *)id; @@ -5768,7 +5725,7 @@ void TypeQualified::syntaxCopyHelper(TypeQualified *t) ti = (TemplateInstance *)ti->syntaxCopy(NULL); id = (Identifier *)ti; } - idents.data[i] = id; + idents.tdata()[i] = id; } } @@ -5780,10 +5737,8 @@ void TypeQualified::addIdent(Identifier *ident) void TypeQualified::toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs) { - int i; - - for (i = 0; i < idents.dim; i++) - { Identifier *id = (Identifier *)idents.data[i]; + for (size_t i = 0; i < idents.dim; i++) + { Identifier *id = idents.tdata()[i]; buf->writeByte('.'); @@ -5816,9 +5771,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) { VarDeclaration *v; - FuncDeclaration *fd; EnumMember *em; - TupleDeclaration *td; Expression *e; #if 0 @@ -5835,9 +5788,9 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, s->checkDeprecated(loc, sc); // check for deprecated aliases s = s->toAlias(); //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); - for (int i = 0; i < idents.dim; i++) + for (size_t i = 0; i < idents.dim; i++) { - Identifier *id = (Identifier *)idents.data[i]; + Identifier *id = idents.tdata()[i]; Dsymbol *sm = s->searchX(loc, sc, id); //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); //printf("\tgetType = '%s'\n", s->getType()->toChars()); @@ -5855,12 +5808,12 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, goto Lerror; goto L3; } - else if (v && id == Id::stringof) + else if (v && (id == Id::stringof || id == Id::offsetof)) { e = new DsymbolExp(loc, s, 0); do { - id = (Identifier *)idents.data[i]; + id = idents.tdata()[i]; e = new DotIdExp(loc, e, id); } while (++i < idents.dim); e = e->semantic(sc); @@ -5886,7 +5839,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, L3: for (; i < idents.dim; i++) { - id = (Identifier *)idents.data[i]; + id = idents.tdata()[i]; //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type); if (id == Id::offsetof || !e->type) { e = new DotIdExp(e->loc, e, id); @@ -6057,6 +6010,29 @@ void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsy Dsymbol *scopesym; //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); + + if ((ident->equals(Id::super) || ident->equals(Id::This)) && !hasThis(sc)) + { + AggregateDeclaration *ad = sc->getStructClassScope(); + if (ad) + { + ClassDeclaration *cd = ad->isClassDeclaration(); + if (cd) + { + if (ident->equals(Id::This)) + ident = cd->ident; + else if (cd->baseClass && ident->equals(Id::super)) + ident = cd->baseClass->ident; + } + else + { + StructDeclaration *sd = ad->isStructDeclaration(); + if (sd && ident->equals(Id::This)) + ident = sd->ident; + } + } + } + Dsymbol *s = sc->search(loc, ident, &scopesym); resolveHelper(loc, sc, s, scopesym, pe, pt, ps); if (*pt) @@ -6079,9 +6055,9 @@ Dsymbol *TypeIdentifier::toDsymbol(Scope *sc) Dsymbol *s = sc->search(loc, ident, &scopesym); if (s) { - for (int i = 0; i < idents.dim; i++) + for (size_t i = 0; i < idents.dim; i++) { - Identifier *id = (Identifier *)idents.data[i]; + Identifier *id = idents.tdata()[i]; s = s->searchX(loc, sc, id); if (!s) // failed to find a symbol { //printf("\tdidn't find a symbol\n"); @@ -6139,9 +6115,9 @@ Type *TypeIdentifier::reliesOnTident() Expression *TypeIdentifier::toExpression() { Expression *e = new IdentifierExp(loc, ident); - for (int i = 0; i < idents.dim; i++) + for (size_t i = 0; i < idents.dim; i++) { - Identifier *id = (Identifier *)idents.data[i]; + Identifier *id = idents.tdata()[i]; e = new DotIdExp(loc, e, id); } @@ -6311,7 +6287,7 @@ void TypeTypeof::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) } Type *TypeTypeof::semantic(Loc loc, Scope *sc) -{ Expression *e; +{ Type *t; //printf("TypeTypeof::semantic() %s\n", toChars()); @@ -6409,7 +6385,7 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc) { if (!s) break; - Identifier *id = (Identifier *)idents.data[i]; + Identifier *id = idents.tdata()[i]; s = s->searchX(loc, sc, id); } @@ -6489,7 +6465,7 @@ Type *TypeReturn::semantic(Loc loc, Scope *sc) { if (!s) break; - Identifier *id = (Identifier *)idents.data[i]; + Identifier *id = idents.tdata()[i]; s = s->searchX(loc, sc, id); } if (s) @@ -7134,8 +7110,7 @@ void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) } Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) -{ unsigned offset; - +{ VarDeclaration *v; Dsymbol *s; DotVarExp *de; @@ -7161,7 +7136,7 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) Expressions *exps = new Expressions; exps->reserve(sym->fields.dim); for (size_t i = 0; i < sym->fields.dim; i++) - { VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; + { VarDeclaration *v = sym->fields.tdata()[i]; Expression *fe = new DotVarExp(e->loc, e, v); exps->push(fe); } @@ -7264,21 +7239,11 @@ L1: OverloadSet *o = s->isOverloadSet(); if (o) - { /* We really should allow this, triggered by: - * template c() - * { - * void a(); - * void b () { this.a(); } - * } - * struct S - * { - * mixin c; - * mixin c; - * } - * alias S e; - */ - error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); - return new ErrorExp(); + { + OverExp *oe = new OverExp(o); + if (e->op == TOKtype) + return oe; + return new DotExp(e->loc, e, oe); } d = s->isDeclaration(); @@ -7372,7 +7337,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc) structelems->setDim(sym->fields.dim); for (size_t j = 0; j < structelems->dim; j++) { - VarDeclaration *vd = (VarDeclaration *)(sym->fields.data[j]); + VarDeclaration *vd = sym->fields.tdata()[j]; Expression *e; if (vd->init) { if (vd->init->isVoidInitializer()) @@ -7382,7 +7347,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc) } else e = vd->type->defaultInitLiteral(); - structelems->data[j] = e; + structelems->tdata()[j] = e; } StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems); // Why doesn't the StructLiteralExp constructor do this, when @@ -7416,7 +7381,7 @@ int TypeStruct::isAssignable() * then one cannot assign this struct. */ for (size_t i = 0; i < sym->fields.dim; i++) - { VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; + { VarDeclaration *v = sym->fields.tdata()[i]; //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind()); if (i == 0) ; @@ -7450,7 +7415,7 @@ int TypeStruct::hasPointers() sym->size(0); // give error for forward references for (size_t i = 0; i < s->fields.dim; i++) { - Dsymbol *sm = (Dsymbol *)s->fields.data[i]; + Dsymbol *sm = s->fields.tdata()[i]; Declaration *d = sm->isDeclaration(); if (d->storage_class & STCref || d->hasPointers()) return TRUE; @@ -7515,8 +7480,8 @@ MATCH TypeStruct::implicitConvTo(Type *to) { /* Check all the fields. If they can all be converted, * allow the conversion. */ - for (int i = 0; i < sym->fields.dim; i++) - { Dsymbol *s = (Dsymbol *)sym->fields.data[i]; + for (size_t i = 0; i < sym->fields.dim; i++) + { Dsymbol *s = sym->fields.tdata()[i]; VarDeclaration *v = s->isVarDeclaration(); assert(v && v->storage_class & STCfield); @@ -7614,9 +7579,7 @@ void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) } Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) -{ unsigned offset; - - Expression *b; +{ VarDeclaration *v; Dsymbol *s; @@ -7645,7 +7608,7 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) Expressions *exps = new Expressions; exps->reserve(sym->fields.dim); for (size_t i = 0; i < sym->fields.dim; i++) - { VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; + { VarDeclaration *v = sym->fields.tdata()[i]; // Don't include hidden 'this' pointer if (v->isThisDeclaration()) continue; @@ -7867,10 +7830,11 @@ L1: OverloadSet *o = s->isOverloadSet(); if (o) - { /* We really should allow this - */ - error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); - return new ErrorExp(); + { + OverExp *oe = new OverExp(o); + if (e->op == TOKtype) + return oe; + return new DotExp(e->loc, e, oe); } Declaration *d = s->isDeclaration(); @@ -8056,7 +8020,7 @@ TypeTuple::TypeTuple(Parameters *arguments) { for (size_t i = 0; i < arguments->dim; i++) { - Parameter *arg = (Parameter *)arguments->data[i]; + Parameter *arg = arguments->tdata()[i]; assert(arg && arg->type); } } @@ -8076,11 +8040,11 @@ TypeTuple::TypeTuple(Expressions *exps) { arguments->setDim(exps->dim); for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = exps->tdata()[i]; if (e->type->ty == Ttuple) e->error("cannot form tuple of tuples"); Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL); - arguments->data[i] = (void *)arg; + arguments->tdata()[i] = arg; } } this->arguments = arguments; @@ -8147,8 +8111,8 @@ int TypeTuple::equals(Object *o) if (arguments->dim == tt->arguments->dim) { for (size_t i = 0; i < tt->arguments->dim; i++) - { Parameter *arg1 = (Parameter *)arguments->data[i]; - Parameter *arg2 = (Parameter *)tt->arguments->data[i]; + { Parameter *arg1 = arguments->tdata()[i]; + Parameter *arg2 = tt->arguments->tdata()[i]; if (!arg1->type->equals(arg2->type)) return 0; @@ -8165,7 +8129,7 @@ Type *TypeTuple::reliesOnTident() { for (size_t i = 0; i < arguments->dim; i++) { - Parameter *arg = (Parameter *)arguments->data[i]; + Parameter *arg = arguments->tdata()[i]; Type *t = arg->type->reliesOnTident(); if (t) return t; @@ -8184,9 +8148,9 @@ Type *TypeTuple::makeConst() t->arguments = new Parameters(); t->arguments->setDim(arguments->dim); for (size_t i = 0; i < arguments->dim; i++) - { Parameter *arg = (Parameter *)arguments->data[i]; + { Parameter *arg = arguments->tdata()[i]; Parameter *narg = new Parameter(arg->storageClass, arg->type->constOf(), arg->ident, arg->defaultArg); - t->arguments->data[i] = (Parameter *)narg; + t->arguments->tdata()[i] = (Parameter *)narg; } return t; } @@ -8274,7 +8238,7 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc) Parameters *args = new Parameters; args->reserve(i2 - i1); for (size_t i = i1; i < i2; i++) - { Parameter *arg = (Parameter *)tt->arguments->data[i]; + { Parameter *arg = tt->arguments->tdata()[i]; args->push(arg); } @@ -8330,7 +8294,7 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol objects->setDim(i2 - i1); for (size_t i = 0; i < objects->dim; i++) { - objects->data[i] = td->objects->data[(size_t)i1 + i]; + objects->tdata()[i] = td->objects->tdata()[(size_t)i1 + i]; } TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects); @@ -8358,27 +8322,6 @@ void TypeSlice::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) buf->printf("%s]", upr->toChars()); } -/***************************** TypeNewArray *****************************/ - -/* T[new] - */ - -TypeNewArray::TypeNewArray(Type *next) - : TypeNext(Tnarray, next) -{ - //printf("TypeNewArray\n"); -} - -void TypeNewArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) -{ - if (mod != this->mod) - { toCBuffer3(buf, hgs, mod); - return; - } - next->toCBuffer2(buf, hgs, this->mod); - buf->writestring("[new]"); -} - /***************************** Parameter *****************************/ Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg) @@ -8406,10 +8349,10 @@ Parameters *Parameter::arraySyntaxCopy(Parameters *args) a = new Parameters(); a->setDim(args->dim); for (size_t i = 0; i < a->dim; i++) - { Parameter *arg = (Parameter *)args->data[i]; + { Parameter *arg = args->tdata()[i]; arg = arg->syntaxCopy(); - a->data[i] = (void *)arg; + a->tdata()[i] = arg; } } return a; @@ -8428,10 +8371,10 @@ char *Parameter::argsTypesToChars(Parameters *args, int varargs) { OutBuffer argbuf; HdrGenState hgs; - for (int i = 0; i < args->dim; i++) + for (size_t i = 0; i < args->dim; i++) { if (i) buf->writeByte(','); - Parameter *arg = (Parameter *)args->data[i]; + Parameter *arg = args->tdata()[i]; argbuf.reset(); arg->type->toCBuffer2(&argbuf, &hgs, 0); buf->write(&argbuf); @@ -8452,14 +8395,14 @@ void Parameter::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *argu { buf->writeByte('('); if (arguments) - { int i; + { OutBuffer argbuf; - for (i = 0; i < arguments->dim; i++) + for (size_t i = 0; i < arguments->dim; i++) { if (i) buf->writestring(", "); - Parameter *arg = (Parameter *)arguments->data[i]; + Parameter *arg = arguments->tdata()[i]; if (arg->storageClass & STCauto) buf->writestring("auto "); @@ -8499,7 +8442,7 @@ void Parameter::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *argu } if (varargs) { - if (i && varargs == 1) + if (arguments->dim && varargs == 1) buf->writeByte(','); buf->writestring("..."); } @@ -8620,7 +8563,7 @@ size_t Parameter::dim(Parameters *args) if (args) { for (size_t i = 0; i < args->dim; i++) - { Parameter *arg = (Parameter *)args->data[i]; + { Parameter *arg = args->tdata()[i]; Type *t = arg->type->toBasetype(); if (t->ty == Ttuple) @@ -8649,7 +8592,7 @@ Parameter *Parameter::getNth(Parameters *args, size_t nth, size_t *pn) size_t n = 0; for (size_t i = 0; i < args->dim; i++) - { Parameter *arg = (Parameter *)args->data[i]; + { Parameter *arg = args->tdata()[i]; Type *t = arg->type->toBasetype(); if (t->ty == Ttuple) diff --git a/dmd2/mtype.h b/dmd2/mtype.h index ed0c96cc..74b179b2 100644 --- a/dmd2/mtype.h +++ b/dmd2/mtype.h @@ -63,7 +63,6 @@ enum ENUMTY { Tarray, // slice array, aka T[] Tsarray, // static array, aka T[dimension] - Tnarray, // resizable array, aka T[new] Taarray, // associative array, aka T[type] Tpointer, Treference, @@ -549,6 +548,7 @@ struct TypePointer : TypeNext d_uns64 size(Loc loc); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); MATCH implicitConvTo(Type *to); + MATCH constConv(Type *to); int isscalar(); // LDC: pointers are unsigned int isunsigned() { return TRUE; }; @@ -690,7 +690,7 @@ struct TypeDelegate : TypeNext struct TypeQualified : Type { Loc loc; - Array idents; // array of Identifier's representing ident.ident.ident etc. + Identifiers idents; // array of Identifier's representing ident.ident.ident etc. TypeQualified(TY ty, Loc loc); void syntaxCopyHelper(TypeQualified *t); @@ -966,12 +966,6 @@ struct TypeSlice : TypeNext void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); }; -struct TypeNewArray : TypeNext -{ - TypeNewArray(Type *next); - void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); -}; - /**************************************************************/ //enum InOut { None, In, Out, InOut, Lazy }; diff --git a/dmd2/opover.c b/dmd2/opover.c index ae402ee8..62088a7e 100644 --- a/dmd2/opover.c +++ b/dmd2/opover.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -475,6 +475,11 @@ Expression *BinExp::op_overload(Scope *sc) Objects *targsi = NULL; #if DMDV2 + if (op == TOKplusplus || op == TOKminusminus) + { // Bug4099 fix + if (ad1 && search_function(ad1, Id::opUnary)) + return NULL; + } if (!s && !s_r && op != TOKequal && op != TOKnotequal && op != TOKassign && op != TOKplusplus && op != TOKminusminus) { @@ -504,9 +509,9 @@ Expression *BinExp::op_overload(Scope *sc) */ args1.setDim(1); - args1.data[0] = (void*) e1; + args1.tdata()[0] = e1; args2.setDim(1); - args2.data[0] = (void*) e2; + args2.tdata()[0] = e2; argsset = 1; Match m; @@ -597,9 +602,9 @@ L1: if (!argsset) { args1.setDim(1); - args1.data[0] = (void*) e1; + args1.tdata()[0] = e1; args2.setDim(1); - args2.data[0] = (void*) e2; + args2.tdata()[0] = e2; } Match m; @@ -755,9 +760,9 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id) Expressions args2; args1.setDim(1); - args1.data[0] = (void*) e1; + args1.tdata()[0] = e1; args2.setDim(1); - args2.data[0] = (void*) e2; + args2.tdata()[0] = e2; Match m; memset(&m, 0, sizeof(m)); @@ -895,12 +900,17 @@ Expression *EqualExp::op_overload(Scope *sc) if (t1->ty == Tclass && t2->ty == Tclass) { /* Rewrite as: - * .object.opEquals(e1, e2) + * .object.opEquals(cast(Object)e1, cast(Object)e2) + * The explicit cast is necessary for interfaces, + * see http://d.puremagic.com/issues/show_bug.cgi?id=4088 */ + Expression *e1x = e1; //new CastExp(loc, e1, ClassDeclaration::object->getType()); + Expression *e2x = e2; //new CastExp(loc, e2, ClassDeclaration::object->getType()); + Expression *e = new IdentifierExp(loc, Id::empty); e = new DotIdExp(loc, e, Id::object); e = new DotIdExp(loc, e, Id::eq); - e = new CallExp(loc, e, e1, e2); + e = new CallExp(loc, e, e1x, e2x); e = e->semantic(sc); return e; } @@ -940,8 +950,8 @@ Expression *BinAssignExp::op_overload(Scope *sc) { Expressions *a = new Expressions(); a->push(e2); - for (int i = 0; i < ae->arguments->dim; i++) - a->push(ae->arguments->data[i]); + for (size_t i = 0; i < ae->arguments->dim; i++) + a->push(ae->arguments->tdata()[i]); Objects *targsi = opToArg(sc, op); Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi); @@ -1054,7 +1064,7 @@ Expression *BinAssignExp::op_overload(Scope *sc) */ args2.setDim(1); - args2.data[0] = (void*) e2; + args2.tdata()[0] = e2; Match m; memset(&m, 0, sizeof(m)); @@ -1194,7 +1204,7 @@ void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Mo for (size_t u = 0; 1; u++) { if (u == arguments->dim) return; - Parameter *arg = (Parameter *)arguments->data[u]; + Parameter *arg = arguments->tdata()[u]; if (!arg->type) break; } @@ -1202,7 +1212,7 @@ void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Mo Dsymbol *s; AggregateDeclaration *ad; - Parameter *arg = (Parameter *)arguments->data[0]; + Parameter *arg = arguments->tdata()[0]; Type *taggr = aggr->type; if (!taggr) return; @@ -1216,7 +1226,7 @@ void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Mo { if (!arg->type) arg->type = Type::tsize_t; // key type - arg = (Parameter *)arguments->data[1]; + arg = arguments->tdata()[1]; } if (!arg->type && tab->ty != Ttuple) arg->type = tab->nextOf(); // value type @@ -1229,7 +1239,7 @@ void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Mo { if (!arg->type) arg->type = taa->index; // key type - arg = (Parameter *)arguments->data[1]; + arg = arguments->tdata()[1]; } if (!arg->type) arg->type = taa->next; // value type @@ -1365,7 +1375,7 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *arguments) for (size_t u = 0; u < nparams; u++) { - Parameter *arg = (Parameter *)arguments->data[u]; + Parameter *arg = arguments->tdata()[u]; Parameter *param = Parameter::getNth(tf->parameters, u); if (arg->type) { if (!arg->type->equals(param->type)) @@ -1409,7 +1419,7 @@ void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments) } if (!td->parameters || td->parameters->dim != 1) continue; - TemplateParameter *tp = (TemplateParameter *)td->parameters->data[0]; + TemplateParameter *tp = td->parameters->tdata()[0]; TemplateAliasParameter *tap = tp->isTemplateAliasParameter(); if (!tap || !tap->specType || tap->specType->ty != Tfunction) continue; diff --git a/dmd2/optimize.c b/dmd2/optimize.c index 24e63b0f..c7560f34 100644 --- a/dmd2/optimize.c +++ b/dmd2/optimize.c @@ -202,10 +202,10 @@ Expression *VarExp::optimize(int result) Expression *TupleExp::optimize(int result) { for (size_t i = 0; i < exps->dim; i++) - { Expression *e = (Expression *)exps->data[i]; + { Expression *e = exps->tdata()[i]; e = e->optimize(WANTvalue | (result & WANTinterpret)); - exps->data[i] = (void *)e; + exps->tdata()[i] = e; } return this; } @@ -215,10 +215,10 @@ Expression *ArrayLiteralExp::optimize(int result) if (elements) { for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); - elements->data[i] = (void *)e; + elements->tdata()[i] = e; } } return this; @@ -228,14 +228,14 @@ Expression *AssocArrayLiteralExp::optimize(int result) { assert(keys->dim == values->dim); for (size_t i = 0; i < keys->dim; i++) - { Expression *e = (Expression *)keys->data[i]; + { Expression *e = keys->tdata()[i]; e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); - keys->data[i] = (void *)e; + keys->tdata()[i] = e; - e = (Expression *)values->data[i]; + e = values->tdata()[i]; e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); - values->data[i] = (void *)e; + values->tdata()[i] = e; } return this; } @@ -245,11 +245,11 @@ Expression *StructLiteralExp::optimize(int result) if (elements) { for (size_t i = 0; i < elements->dim; i++) - { Expression *e = (Expression *)elements->data[i]; + { Expression *e = elements->tdata()[i]; if (!e) continue; e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand))); - elements->data[i] = (void *)e; + elements->tdata()[i] = e; } } return this; @@ -494,20 +494,20 @@ Expression *NewExp::optimize(int result) if (newargs) { for (size_t i = 0; i < newargs->dim; i++) - { Expression *e = (Expression *)newargs->data[i]; + { Expression *e = newargs->tdata()[i]; e = e->optimize(WANTvalue); - newargs->data[i] = (void *)e; + newargs->tdata()[i] = e; } } if (arguments) { for (size_t i = 0; i < arguments->dim; i++) - { Expression *e = (Expression *)arguments->data[i]; + { Expression *e = arguments->tdata()[i]; e = e->optimize(WANTvalue); - arguments->data[i] = (void *)e; + arguments->tdata()[i] = e; } } if (result & WANTinterpret) @@ -526,10 +526,10 @@ Expression *CallExp::optimize(int result) if (arguments) { for (size_t i = 0; i < arguments->dim; i++) - { Expression *e = (Expression *)arguments->data[i]; + { Expression *e = arguments->tdata()[i]; e = e->optimize(WANTvalue); - arguments->data[i] = (void *)e; + arguments->tdata()[i] = e; } } diff --git a/dmd2/parse.c b/dmd2/parse.c index c1eb0fff..b0477ac0 100644 --- a/dmd2/parse.c +++ b/dmd2/parse.c @@ -62,6 +62,7 @@ Parser::Parser(Module *module, unsigned char *base, unsigned length, int doDocCo linkage = LINKd; endloc = 0; inBrackets = 0; + lookingForElse = 0; //nextToken(); // start up the scanner } @@ -101,14 +102,14 @@ Dsymbols *Parser::parseModule() } else { - Array *a = NULL; + Identifiers *a = NULL; Identifier *id; id = token.ident; while (nextToken() == TOKdot) { if (!a) - a = new Array(); + a = new Identifiers(); a->push(id); nextToken(); if (token.value != TOKidentifier) @@ -227,6 +228,7 @@ Dsymbols *Parser::parseDeclDefs(int once) case TOKalias: case TOKtypedef: case TOKidentifier: + case TOKsuper: case TOKtypeof: case TOKdot: Ldeclaration: @@ -235,7 +237,10 @@ Dsymbols *Parser::parseDeclDefs(int once) continue; case TOKthis: - s = parseCtor(); + if (peekNext() == TOKdot) + goto Ldeclaration; + else + s = parseCtor(); break; #if 0 // dead end, use this(this){} instead @@ -293,11 +298,17 @@ Dsymbols *Parser::parseDeclDefs(int once) s = parseStaticAssert(); else if (token.value == TOKif) { condition = parseStaticIfCondition(); + Loc lookingForElseSave = lookingForElse; + lookingForElse = loc; a = parseBlock(); + lookingForElse = lookingForElseSave; aelse = NULL; if (token.value == TOKelse) - { nextToken(); + { + Loc elseloc = this->loc; + nextToken(); aelse = parseBlock(); + checkDanglingElse(elseloc); } s = new StaticIfDeclaration(condition, a, aelse); break; @@ -575,11 +586,19 @@ Dsymbols *Parser::parseDeclDefs(int once) goto Lcondition; Lcondition: - a = parseBlock(); + { + Loc lookingForElseSave = lookingForElse; + lookingForElse = loc; + a = parseBlock(); + lookingForElse = lookingForElseSave; + } aelse = NULL; if (token.value == TOKelse) - { nextToken(); + { + Loc elseloc = this->loc; + nextToken(); aelse = parseBlock(); + checkDanglingElse(elseloc); } s = new ConditionalDeclaration(condition, a, aelse); break; @@ -695,7 +714,6 @@ StorageClass Parser::parsePostfix() Dsymbols *Parser::parseBlock() { Dsymbols *a = NULL; - Dsymbol *s; //printf("parseBlock()\n"); switch (token.value) @@ -710,6 +728,10 @@ Dsymbols *Parser::parseBlock() break; case TOKlcurly: + { + Loc lookingForElseSave = lookingForElse; + lookingForElse = 0; + nextToken(); a = parseDeclDefs(0); if (token.value != TOKrcurly) @@ -718,7 +740,9 @@ Dsymbols *Parser::parseBlock() } else nextToken(); + lookingForElse = lookingForElseSave; break; + } case TOKcolon: nextToken(); @@ -914,8 +938,6 @@ Condition *Parser::parseVersionCondition() Condition *Parser::parseStaticIfCondition() { Expression *exp; Condition *condition; - Array *aif; - Array *aelse; Loc loc = this->loc; nextToken(); @@ -1217,7 +1239,7 @@ Parameters *Parser::parseParameters(int *pvarargs) check(TOKlparen); while (1) - { Type *tb; + { Identifier *ai = NULL; Type *at; Parameter *a; @@ -1346,7 +1368,7 @@ Parameters *Parser::parseParameters(int *pvarargs) nextToken(); break; } - L3: + L3: a = new Parameter(storageClass, at, ai, ae); arguments->push(a); if (token.value == TOKcomma) @@ -1864,7 +1886,7 @@ Dsymbol *Parser::parseMixin() Identifier *id; Type *tqual; Objects *tiargs; - Array *idents; + Identifiers *idents; //printf("parseMixin()\n"); nextToken(); @@ -1890,7 +1912,7 @@ Dsymbol *Parser::parseMixin() nextToken(); } - idents = new Array(); + idents = new Identifiers(); while (1) { tiargs = NULL; @@ -1990,8 +2012,8 @@ Objects *Parser::parseTemplateArgumentList2() * a deduced type. */ TemplateParameters *tpl = NULL; - for (int i = 0; i < tf->parameters->dim; i++) - { Parameter *param = (Parameter *)tf->parameters->data[i]; + for (size_t i = 0; i < tf->parameters->dim; i++) + { Parameter *param = tf->parameters->tdata()[i]; if (param->ident == NULL && param->type && param->type->ty == Tident && @@ -2098,7 +2120,7 @@ Import *Parser::parseImport(Dsymbols *decldefs, int isstatic) { Import *s; Identifier *id; Identifier *aliasid = NULL; - Array *a; + Identifiers *a; Loc loc; //printf("Parser::parseImport()\n"); @@ -2123,7 +2145,7 @@ Import *Parser::parseImport(Dsymbols *decldefs, int isstatic) while (token.value == TOKdot) { if (!a) - a = new Array(); + a = new Identifiers(); a->push(id); nextToken(); if (token.value != TOKidentifier) @@ -2272,6 +2294,8 @@ Type *Parser::parseBasicType() nextToken(); break; + case TOKthis: + case TOKsuper: case TOKidentifier: id = token.ident; nextToken(); @@ -3052,7 +3076,7 @@ L1: #if 0 // Dumped feature case TOKthrow: if (!f->fthrows) - f->fthrows = new Array(); + f->fthrows = new Types(); nextToken(); check(TOKlparen); while (1) @@ -3156,7 +3180,7 @@ Initializer *Parser::parseInitializer() is = new StructInitializer(loc); nextToken(); - comma = 0; + comma = 2; while (1) { switch (token.value) @@ -3180,6 +3204,8 @@ Initializer *Parser::parseInitializer() continue; case TOKcomma: + if (comma == 2) + error("expression expected, not ','"); nextToken(); comma = 2; continue; @@ -3243,7 +3269,7 @@ Initializer *Parser::parseInitializer() ia = new ArrayInitializer(loc); nextToken(); - comma = 0; + comma = 2; while (1) { switch (token.value) @@ -3280,6 +3306,8 @@ Initializer *Parser::parseInitializer() continue; case TOKcomma: + if (comma == 2) + error("expression expected, not ','"); nextToken(); comma = 2; continue; @@ -3342,6 +3370,20 @@ Expression *Parser::parseDefaultInitExp() } #endif +/***************************************** + */ + +void Parser::checkDanglingElse(Loc elseloc) +{ + if (token.value != TOKelse && + token.value != TOKcatch && + token.value != TOKfinally && + lookingForElse.linnum != 0) + { + warning(elseloc, "else is dangling, add { } after condition at %s", lookingForElse.toChars()); + } +} + /***************************************** * Input: * flags PSxxxx @@ -3501,16 +3543,16 @@ Statement *Parser::parseStatement(int flags) #endif // case TOKtypeof: Ldeclaration: - { Array *a; + { Dsymbols *a; a = parseDeclarations(STCundefined, NULL); if (a->dim > 1) { Statements *as = new Statements(); as->reserve(a->dim); - for (int i = 0; i < a->dim; i++) + for (size_t i = 0; i < a->dim; i++) { - Dsymbol *d = (Dsymbol *)a->data[i]; + Dsymbol *d = a->tdata()[i]; s = new ExpStatement(loc, d); as->push(s); } @@ -3518,7 +3560,7 @@ Statement *Parser::parseStatement(int flags) } else if (a->dim == 1) { - Dsymbol *d = (Dsymbol *)a->data[0]; + Dsymbol *d = a->tdata()[0]; s = new ExpStatement(loc, d); } else @@ -3586,6 +3628,9 @@ Statement *Parser::parseStatement(int flags) case TOKlcurly: { + Loc lookingForElseSave = lookingForElse; + lookingForElse = 0; + nextToken(); //if (token.value == TOKsemicolon) //error("use '{ }' for an empty statement, not a ';'"); @@ -3599,6 +3644,7 @@ Statement *Parser::parseStatement(int flags) if (flags & (PSscope | PScurlyscope)) s = new ScopeStatement(loc, s); check(TOKrcurly, "compound statement"); + lookingForElse = lookingForElseSave; break; } @@ -3627,7 +3673,10 @@ Statement *Parser::parseStatement(int flags) Expression *condition; nextToken(); + Loc lookingForElseSave = lookingForElse; + lookingForElse = 0; body = parseStatement(PSscope); + lookingForElse = lookingForElseSave; check(TOKwhile); check(TOKlparen); condition = parseExpression(); @@ -3650,7 +3699,11 @@ Statement *Parser::parseStatement(int flags) nextToken(); } else - { init = parseStatement(0); + { + Loc lookingForElseSave = lookingForElse; + lookingForElse = 0; + init = parseStatement(0); + lookingForElse = lookingForElseSave; } if (token.value == TOKsemicolon) { @@ -3728,7 +3781,7 @@ Statement *Parser::parseStatement(int flags) Expression *aggr = parseExpression(); if (token.value == TOKslice && arguments->dim == 1) { - Parameter *a = (Parameter *)arguments->data[0]; + Parameter *a = arguments->tdata()[0]; delete arguments; nextToken(); Expression *upr = parseExpression(); @@ -3802,11 +3855,18 @@ Statement *Parser::parseStatement(int flags) condition = parseExpression(); check(TOKrparen); - ifbody = parseStatement(PSscope); + { + Loc lookingForElseSave = lookingForElse; + lookingForElse = loc; + ifbody = parseStatement(PSscope); + lookingForElse = lookingForElseSave; + } if (token.value == TOKelse) { + Loc elseloc = this->loc; nextToken(); elsebody = parseStatement(PSscope); + checkDanglingElse(elseloc); } else elsebody = NULL; @@ -3856,12 +3916,19 @@ Statement *Parser::parseStatement(int flags) goto Lcondition; Lcondition: - ifbody = parseStatement(0 /*PSsemi*/); + { + Loc lookingForElseSave = lookingForElse; + lookingForElse = loc; + ifbody = parseStatement(0 /*PSsemi*/); + lookingForElse = lookingForElseSave; + } elsebody = NULL; if (token.value == TOKelse) { + Loc elseloc = this->loc; nextToken(); elsebody = parseStatement(0 /*PSsemi*/); + checkDanglingElse(elseloc); } s = new ConditionalStatement(loc, condition, ifbody, elsebody); break; @@ -3911,7 +3978,7 @@ Statement *Parser::parseStatement(int flags) case TOKcase: { Expression *exp; Statements *statements; - Array cases; // array of Expression's + Expressions cases; // array of Expression's Expression *last = NULL; while (1) @@ -3958,9 +4025,9 @@ Statement *Parser::parseStatement(int flags) #endif { // Keep cases in order by building the case statements backwards - for (int i = cases.dim; i; i--) + for (size_t i = cases.dim; i; i--) { - exp = (Expression *)cases.data[i - 1]; + exp = cases.tdata()[i - 1]; s = new CaseStatement(loc, exp, s); } } @@ -4098,11 +4165,14 @@ Statement *Parser::parseStatement(int flags) case TOKtry: { Statement *body; - Array *catches = NULL; + Catches *catches = NULL; Statement *finalbody = NULL; nextToken(); + Loc lookingForElseSave = lookingForElse; + lookingForElse = 0; body = parseStatement(PSscope); + lookingForElse = lookingForElseSave; while (token.value == TOKcatch) { Statement *handler; @@ -4127,7 +4197,7 @@ Statement *Parser::parseStatement(int flags) handler = parseStatement(0); c = new Catch(loc, t, id, handler); if (!catches) - catches = new Array(); + catches = new Catches(); catches->push(c); } @@ -4362,8 +4432,6 @@ int Parser::isBasicType(Token **pt) { // This code parallels parseBasicType() Token *t = *pt; - Token *t2; - int parens; int haveId = 0; switch (t->value) @@ -4731,7 +4799,6 @@ int Parser::isParameters(Token **pt) break; } } - L3: if (t->value == TOKcomma) { continue; @@ -5178,7 +5245,6 @@ Expression *Parser::parsePrimaryExp() case BASIC_TYPES_X(t): nextToken(); - L1: check(TOKdot, t->toChars()); if (token.value != TOKidentifier) { error("found '%s' when expecting identifier following '%s.'", token.toChars(), t->toChars()); @@ -5469,7 +5535,7 @@ Expression *Parser::parsePostExp(Expression *e) { Identifier *id = token.ident; nextToken(); - if (token.value == TOKnot && peekNext() != TOKis) + if (token.value == TOKnot && peekNext() != TOKis && peekNext() != TOKin) { // identifier!(template-argument-list) TemplateInstance *tempinst = new TemplateInstance(loc, id); Objects *tiargs; @@ -6356,7 +6422,7 @@ enum PREC precedence[TOKMAX]; void initPrecedence() { - for (int i = 0; i < TOKMAX; i++) + for (size_t i = 0; i < TOKMAX; i++) precedence[i] = PREC_zero; precedence[TOKtype] = PREC_expr; diff --git a/dmd2/parse.h b/dmd2/parse.h index 9319503a..2f03a7df 100644 --- a/dmd2/parse.h +++ b/dmd2/parse.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2009 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -65,6 +65,7 @@ struct Parser : Lexer enum LINK linkage; Loc endloc; // set to location of last right curly int inBrackets; // inside [] of array index or slice + Loc lookingForElse; // location of lonely if looking for an else Parser(Module *module, unsigned char *base, unsigned length, int doDocComment); @@ -110,6 +111,7 @@ struct Parser : Lexer Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL, StorageClass storage_class = 0); Dsymbols *parseDeclarations(StorageClass storage_class, unsigned char *comment); void parseContracts(FuncDeclaration *f); + void checkDanglingElse(Loc elseloc); Statement *parseStatement(int flags); Initializer *parseInitializer(); Expression *parseDefaultInitExp(); diff --git a/dmd2/root/array.c b/dmd2/root/array.c index e1828598..f3440445 100644 --- a/dmd2/root/array.c +++ b/dmd2/root/array.c @@ -190,7 +190,8 @@ char *Array::toChars() char *str; char *p; - buf = (char **)alloca(dim * sizeof(char *)); + buf = (char **)malloc(dim * sizeof(char *)); + assert(buf); len = 2; for (u = 0; u < dim; u++) { @@ -211,6 +212,7 @@ char *Array::toChars() } *p++ = ']'; *p = 0; + free(buf); return str; } diff --git a/dmd2/root/dchar.h b/dmd2/root/dchar.h index d578373f..2b8df523 100644 --- a/dmd2/root/dchar.h +++ b/dmd2/root/dchar.h @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -161,14 +161,14 @@ struct Dchar static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); } static int isDigit(dchar c) { return '0' <= c && c <= '9'; } #ifndef GCC_SAFE_DMD - static int isAlpha(dchar c) { return isalpha(c); } - static int isUpper(dchar c) { return isupper(c); } - static int isLower(dchar c) { return islower(c); } - static int isLocaleUpper(dchar c) { return isupper(c); } - static int isLocaleLower(dchar c) { return islower(c); } - static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; } + static int isAlpha(dchar c) { return isalpha((unsigned char)c); } + static int isUpper(dchar c) { return isupper((unsigned char)c); } + static int isLower(dchar c) { return islower((unsigned char)c); } + static int isLocaleUpper(dchar c) { return isupper((unsigned char)c); } + static int isLocaleLower(dchar c) { return islower((unsigned char)c); } + static int toLower(dchar c) { return isupper((unsigned char)c) ? tolower(c) : c; } static int toLower(dchar *p) { return toLower(*p); } - static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; } + static int toUpper(dchar c) { return islower((unsigned char)c) ? toupper(c) : c; } static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory? #endif static dchar *chr(dchar *p, int c) { return strchr(p, c); } diff --git a/dmd2/root/port.c b/dmd2/root/port.c index b7beef5c..9718c3fe 100644 --- a/dmd2/root/port.c +++ b/dmd2/root/port.c @@ -216,9 +216,11 @@ unsigned _int64 Port::strtoull(const char *p, char **pend, int base) unsigned _int64 number = 0; int c; int error; +#ifndef ULLONG_MAX #define ULLONG_MAX ((unsigned _int64)~0I64) +#endif - while (isspace(*p)) /* skip leading white space */ + while (isspace((unsigned char)*p)) /* skip leading white space */ p++; if (*p == '+') p++; diff --git a/dmd2/root/response.c b/dmd2/root/response.c index 56c350af..2096f11b 100644 --- a/dmd2/root/response.c +++ b/dmd2/root/response.c @@ -1,5 +1,5 @@ // Copyright (C) 1990-1998 by Symantec -// Copyright (C) 2000-2009 by Digital Mars +// Copyright (C) 2000-2011 by Digital Mars // All Rights Reserved // http://www.digitalmars.com // Written by Walter Bright @@ -13,6 +13,7 @@ #include #include #include +#include #if _WIN32 #include @@ -66,12 +67,18 @@ struct Narg static int addargp(struct Narg *n, char *p) { /* The 2 is to always allow room for a NULL argp at the end */ - if (n->argc + 2 >= n->argvmax) + if (n->argc + 2 > n->argvmax) { n->argvmax = n->argc + 2; - n->argv = (char **) realloc(n->argv,n->argvmax * sizeof(char *)); - if (!n->argv) + char **ap = n->argv; + ap = (char **) realloc(ap,n->argvmax * sizeof(char *)); + if (!ap) + { if (n->argv) + free(n->argv); + memset(n, 0, sizeof(*n)); return 1; + } + n->argv = ap; } n->argv[n->argc++] = p; return 0; @@ -129,7 +136,7 @@ int response_expand(int *pargc, char ***pargv) bufend = &buffer[len]; /* Read file into buffer */ #if _WIN32 - fd = open(cp,O_RDONLY|O_BINARY); + fd = _open(cp,O_RDONLY|O_BINARY); #else fd = open(cp,O_RDONLY); #endif @@ -257,7 +264,15 @@ int response_expand(int *pargc, char ***pargv) else if (addargp(&n,(*pargv)[i])) goto noexpand; } - n.argv[n.argc] = NULL; + if (n.argvmax == 0) + { + n.argvmax = 1; + n.argv = (char **) calloc(n.argvmax, sizeof(char *)); + if (!n.argv) + return 1; + } + else + n.argv[n.argc] = NULL; if (recurse) { /* Recursively expand @filename */ diff --git a/dmd2/root/root.c b/dmd2/root/root.c index 5513e195..1988f672 100644 --- a/dmd2/root/root.c +++ b/dmd2/root/root.c @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -363,21 +363,21 @@ FileName::FileName(char *path, char *name) } // Split a path into an Array of paths -Array *FileName::splitPath(const char *path) +Strings *FileName::splitPath(const char *path) { char c = 0; // unnecessary initializer is for VC /W4 const char *p; OutBuffer buf; - Array *array; + Strings *array; - array = new Array(); + array = new Strings(); if (path) { p = path; do { char instring = 0; - while (isspace(*p)) // skip leading whitespace + while (isspace((unsigned char)*p)) // skip leading whitespace p++; buf.reserve(strlen(p) + 1); // guess size of path for (; ; p++) @@ -792,7 +792,7 @@ void FileName::CopyTo(FileName *to) * cwd if !=0, search current directory before searching path */ -char *FileName::searchPath(Array *path, const char *name, int cwd) +char *FileName::searchPath(Strings *path, const char *name, int cwd) { if (absolute(name)) { @@ -808,7 +808,7 @@ char *FileName::searchPath(Array *path, const char *name, int cwd) for (i = 0; i < path->dim; i++) { - char *p = (char *)path->data[i]; + char *p = path->tdata()[i]; char *n = combine(p, name); if (exists(n)) @@ -832,7 +832,7 @@ char *FileName::searchPath(Array *path, const char *name, int cwd) * !=NULL mem.malloc'd file name */ -char *FileName::safeSearchPath(Array *path, const char *name) +char *FileName::safeSearchPath(Strings *path, const char *name) { #if _WIN32 /* Disallow % / \ : and .. in name characters @@ -869,7 +869,7 @@ char *FileName::safeSearchPath(Array *path, const char *name) for (i = 0; i < path->dim; i++) { char *cname = NULL; - char *cpath = canonicalName((char *)path->data[i]); + char *cpath = canonicalName(path->tdata()[i]); //printf("FileName::safeSearchPath(): name=%s; path=%s; cpath=%s\n", // name, (char *)path->data[i], cpath); if (cpath == NULL) @@ -959,7 +959,7 @@ void FileName::ensurePathExists(const char *path) { //printf("mkdir(%s)\n", path); #if _WIN32 - if (mkdir(path)) + if (_mkdir(path)) #endif #if POSIX if (mkdir(path, 0777)) @@ -1081,7 +1081,7 @@ int File::read() //printf("File::read('%s')\n",name); fd = open(name, O_RDONLY); if (fd == -1) - { result = errno; + { //printf("\topen error, errno = %d\n",errno); goto err1; } @@ -1447,23 +1447,23 @@ void File::remove() #endif } -Array *File::match(char *n) +Files *File::match(char *n) { return match(new FileName(n, 0)); } -Array *File::match(FileName *n) +Files *File::match(FileName *n) { #if POSIX return NULL; #elif _WIN32 HANDLE h; WIN32_FIND_DATAA fileinfo; - Array *a; + Files *a; char *c; char *name; - a = new Array(); + a = new Files(); c = n->toChars(); name = n->name(); h = FindFirstFileA(c,&fileinfo); @@ -1556,11 +1556,11 @@ OutBuffer::~OutBuffer() mem.free(data); } -void *OutBuffer::extractData() +char *OutBuffer::extractData() { - void *p; + char *p; - p = (void *)data; + p = (char *)data; data = NULL; offset = 0; size = 0; diff --git a/dmd2/root/root.h b/dmd2/root/root.h index a0b34cea..bac6036e 100644 --- a/dmd2/root/root.h +++ b/dmd2/root/root.h @@ -1,6 +1,6 @@ -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -13,6 +13,9 @@ #include #include +#ifdef DEBUG +#include +#endif #if __DMC__ #pragma once @@ -60,7 +63,12 @@ longlong randomx(); */ struct OutBuffer; -struct Array; + +// Can't include arraytypes.h here, need to declare these directly. +template struct ArrayBase; +typedef ArrayBase Files; +typedef ArrayBase Strings; + struct Object { @@ -141,14 +149,14 @@ struct FileName : String static const char *replaceName(const char *path, const char *name); static char *combine(const char *path, const char *name); - static Array *splitPath(const char *path); + static Strings *splitPath(const char *path); static FileName *defaultExt(const char *name, const char *ext); static FileName *forceExt(const char *name, const char *ext); int equalsExt(const char *ext); void CopyTo(FileName *to); - static char *searchPath(Array *path, const char *name, int cwd); - static char *safeSearchPath(Array *path, const char *name); + static char *searchPath(Strings *path, const char *name, int cwd); + static char *safeSearchPath(Strings *path, const char *name); static int exists(const char *name); static void ensurePathExists(const char *path); static char *canonicalName(const char *name); @@ -233,8 +241,8 @@ struct File : Object * matching File's. */ - static Array *match(char *); - static Array *match(FileName *); + static Files *match(char *); + static Files *match(FileName *); // Compare file times. // Return <0 this < f @@ -267,7 +275,7 @@ struct OutBuffer : Object OutBuffer(); ~OutBuffer(); - void *extractData(); + char *extractData(); void mark(); void reserve(unsigned nbytes); @@ -340,6 +348,48 @@ struct Array : Object Array *copy(); }; +template +struct ArrayBase : Array +{ + TYPE **tdata() + { + return (TYPE **)data; + } + + TYPE*& operator[] (size_t index) + { +#ifdef DEBUG + assert(index < dim); +#endif + return ((TYPE **)data)[index]; + } + + void insert(size_t index, TYPE *v) + { + Array::insert(index, (void *)v); + } + + void insert(size_t index, ArrayBase *a) + { + Array::insert(index, (Array *)a); + } + + void append(ArrayBase *a) + { + Array::append((Array *)a); + } + + void push(TYPE *a) + { + Array::push((void *)a); + } + + ArrayBase *copy() + { + return (ArrayBase *)Array::copy(); + } +}; + struct Bits : Object { unsigned bitdim; diff --git a/dmd2/root/speller.c b/dmd2/root/speller.c index 845f5756..d6437379 100644 --- a/dmd2/root/speller.c +++ b/dmd2/root/speller.c @@ -111,7 +111,7 @@ void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg, /* Deletions */ memcpy(buf, seed + 1, seedlen); - for (int i = 0; i < seedlen; i++) + for (size_t i = 0; i < seedlen; i++) { //printf("del buf = '%s'\n", buf); void *p; @@ -129,7 +129,7 @@ void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg, if (!flag) { memcpy(buf, seed, seedlen + 1); - for (int i = 0; i + 1 < seedlen; i++) + for (size_t i = 0; i + 1 < seedlen; i++) { // swap [i] and [i + 1] buf[i] = seed[i + 1]; @@ -148,7 +148,7 @@ void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg, { /* Substitutions */ memcpy(buf, seed, seedlen + 1); - for (int i = 0; i < seedlen; i++) + for (size_t i = 0; i < seedlen; i++) { for (const char *s = charset; *s; s++) { @@ -168,7 +168,7 @@ void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg, /* Insertions */ memcpy(buf + 1, seed, seedlen + 1); - for (int i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations + for (size_t i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations { for (const char *s = charset; *s; s++) { diff --git a/dmd2/scope.h b/dmd2/scope.h index de1f78f4..7eafd6be 100644 --- a/dmd2/scope.h +++ b/dmd2/scope.h @@ -16,7 +16,6 @@ struct Dsymbol; struct ScopeDsymbol; -struct Array; struct Identifier; struct Module; struct Statement; diff --git a/dmd2/statement.c b/dmd2/statement.c index 401df707..3f735b06 100644 --- a/dmd2/statement.c +++ b/dmd2/statement.c @@ -362,7 +362,7 @@ Statement *ExpStatement::scopeCode(Scope *sc, Statement **sentry, Statement **se e->type = Type::tbool; } #endif - *sfinally = new ExpStatement(loc, e); + *sfinally = new DtorExpStatement(loc, e, v); } v->noscope = 1; // don't add in dtor again } @@ -372,6 +372,21 @@ Statement *ExpStatement::scopeCode(Scope *sc, Statement **sentry, Statement **se } +/******************************** DtorExpStatement ***************************/ + +DtorExpStatement::DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v) + : ExpStatement(loc, exp) +{ + this->var = v; +} + +Statement *DtorExpStatement::syntaxCopy() +{ + Expression *e = exp ? exp->syntaxCopy() : NULL; + DtorExpStatement *es = new DtorExpStatement(loc, e, var); + return es; +} + /******************************** CompileStatement ***************************/ CompileStatement::CompileStatement(Loc loc, Expression *exp) @@ -404,11 +419,11 @@ Statements *CompileStatement::flatten(Scope *sc) exp = exp->optimize(WANTvalue | WANTinterpret); if (exp->op == TOKerror) return NULL; - if (exp->op != TOKstring) + StringExp *se = exp->toString(); + if (!se) { error("argument to mixin must be a string, not (%s)", exp->toChars()); return NULL; } - StringExp *se = (StringExp *)exp; se = se->toUTF8(sc); Parser p(sc->module, (unsigned char *)se->string, se->len, 0); p.loc = loc; @@ -464,10 +479,10 @@ Statement *CompoundStatement::syntaxCopy() Statements *a = new Statements(); a->setDim(statements->dim); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) s = s->syntaxCopy(); - a->data[i] = s; + a->tdata()[i] = s; } CompoundStatement *cs = new CompoundStatement(loc, a); return cs; @@ -482,7 +497,7 @@ Statement *CompoundStatement::semantic(Scope *sc) #if 0 for (size_t i = 0; i < statements->dim; i++) { - s = (Statement *) statements->data[i]; + s = statements->tdata()[i]; if (s) printf("[%d]: %s", i, s->toChars()); } @@ -490,7 +505,7 @@ Statement *CompoundStatement::semantic(Scope *sc) for (size_t i = 0; i < statements->dim; ) { - s = (Statement *) statements->data[i]; + s = statements->tdata()[i]; if (s) { Statements *a = s->flatten(sc); @@ -501,14 +516,14 @@ Statement *CompoundStatement::semantic(Scope *sc) continue; } s = s->semantic(sc); - statements->data[i] = s; + statements->tdata()[i] = s; if (s) { Statement *sentry; Statement *sexception; Statement *sfinally; - statements->data[i] = s->scopeCode(sc, &sentry, &sexception, &sfinally); + statements->tdata()[i] = s->scopeCode(sc, &sentry, &sexception, &sfinally); if (sentry) { sentry = sentry->semantic(sc); @@ -531,14 +546,12 @@ Statement *CompoundStatement::semantic(Scope *sc) * catch (Object __o) * { sexception; throw __o; } */ - Statement *body; Statements *a = new Statements(); - - for (int j = i + 1; j < statements->dim; j++) + for (size_t j = i + 1; j < statements->dim; j++) { - a->push(statements->data[j]); + a->push(statements->tdata()[j]); } - body = new CompoundStatement(0, a); + Statement *body = new CompoundStatement(0, a); body = new ScopeStatement(0, body); Identifier *id = Lexer::uniqueId("__o"); @@ -546,7 +559,7 @@ Statement *CompoundStatement::semantic(Scope *sc) Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id)); handler = new CompoundStatement(0, sexception, handler); - Array *catches = new Array(); + Catches *catches = new Catches(); Catch *ctch = new Catch(0, NULL, id, handler); catches->push(ctch); s = new TryCatchStatement(0, body, catches); @@ -572,14 +585,12 @@ Statement *CompoundStatement::semantic(Scope *sc) * As: * s; try { s1; s2; } finally { sfinally; } */ - Statement *body; Statements *a = new Statements(); - - for (int j = i + 1; j < statements->dim; j++) + for (size_t j = i + 1; j < statements->dim; j++) { - a->push(statements->data[j]); + a->push(statements->tdata()[j]); } - body = new CompoundStatement(0, a); + Statement *body = new CompoundStatement(0, a); s = new TryFinallyStatement(0, body, sfinally); s = s->semantic(sc); statements->setDim(i + 1); @@ -593,7 +604,7 @@ Statement *CompoundStatement::semantic(Scope *sc) } if (statements->dim == 1 && !isAsmBlockStatement()) { - return (Statement *)statements->data[0]; + return statements->tdata()[0]; } return this; } @@ -607,8 +618,8 @@ ReturnStatement *CompoundStatement::isReturnStatement() { ReturnStatement *rs = NULL; - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; if (s) { rs = s->isReturnStatement(); @@ -624,7 +635,7 @@ Statement *CompoundStatement::last() Statement *s = NULL; for (size_t i = statements->dim; i; --i) - { s = (Statement *) statements->data[i - 1]; + { s = statements->tdata()[i - 1]; if (s) { s = s->last(); @@ -637,8 +648,8 @@ Statement *CompoundStatement::last() void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; if (s) s->toCBuffer(buf, hgs); } @@ -646,8 +657,8 @@ void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) int CompoundStatement::usesEH() { - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; if (s && s->usesEH()) return TRUE; } @@ -660,7 +671,7 @@ int CompoundStatement::blockExit(bool mustNotThrow) int result = BEfallthru; Statement *slast = NULL; for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { //printf("result = x%x\n", result); @@ -703,8 +714,8 @@ int CompoundStatement::comeFrom() { int comefrom = FALSE; //printf("CompoundStatement::comeFrom()\n"); - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; if (!s) continue; @@ -716,8 +727,8 @@ int CompoundStatement::comeFrom() int CompoundStatement::isEmpty() { - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; if (s && !s->isEmpty()) return FALSE; } @@ -738,10 +749,10 @@ Statement *CompoundDeclarationStatement::syntaxCopy() Statements *a = new Statements(); a->setDim(statements->dim); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) s = s->syntaxCopy(); - a->data[i] = s; + a->tdata()[i] = s; } CompoundDeclarationStatement *cs = new CompoundDeclarationStatement(loc, a); return cs; @@ -750,8 +761,8 @@ Statement *CompoundDeclarationStatement::syntaxCopy() void CompoundDeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { int nwritten = 0; - for (int i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = statements->tdata()[i]; ExpStatement *ds; if (s && (ds = s->isExpStatement()) != NULL && @@ -815,10 +826,10 @@ Statement *UnrolledLoopStatement::syntaxCopy() Statements *a = new Statements(); a->setDim(statements->dim); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) s = s->syntaxCopy(); - a->data[i] = s; + a->tdata()[i] = s; } UnrolledLoopStatement *cs = new UnrolledLoopStatement(loc, a); return cs; @@ -836,12 +847,12 @@ Statement *UnrolledLoopStatement::semantic(Scope *sc) for (size_t i = 0; i < statements->dim; i++) { - Statement *s = (Statement *) statements->data[i]; + Statement *s = statements->tdata()[i]; if (s) { //printf("[%d]: %s\n", i, s->toChars()); s = s->semantic(scd); - statements->data[i] = s; + statements->tdata()[i] = s; } } @@ -858,7 +869,7 @@ void UnrolledLoopStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) for (size_t i = 0; i < statements->dim; i++) { Statement *s; - s = (Statement *) statements->data[i]; + s = statements->tdata()[i]; if (s) s->toCBuffer(buf, hgs); } @@ -880,7 +891,7 @@ int UnrolledLoopStatement::hasContinue() int UnrolledLoopStatement::usesEH() { for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s && s->usesEH()) return TRUE; } @@ -891,7 +902,7 @@ int UnrolledLoopStatement::blockExit(bool mustNotThrow) { int result = BEfallthru; for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *) statements->data[i]; + { Statement *s = statements->tdata()[i]; if (s) { int r = s->blockExit(mustNotThrow); @@ -907,7 +918,7 @@ int UnrolledLoopStatement::comeFrom() //printf("UnrolledLoopStatement::comeFrom()\n"); for (size_t i = 0; i < statements->dim; i++) - { Statement *s = (Statement *)statements->data[i]; + { Statement *s = statements->tdata()[i]; if (!s) continue; @@ -1401,6 +1412,7 @@ Statement *ForeachStatement::semantic(Scope *sc) if (func->fes) func = func->fes->func; +Lretry: aggr = aggr->semantic(sc); aggr = resolveProperties(sc, aggr); aggr = aggr->optimize(WANTvalue); @@ -1421,6 +1433,25 @@ Statement *ForeachStatement::semantic(Scope *sc) return this; } + Expression *prelude = NULL; + if (aggr->op == TOKcomma) + { + Expression **pe = &aggr; + while (((CommaExp *)(*pe))->e2->op == TOKcomma) + pe = &((CommaExp *)(*pe))->e2; + if (pe == &aggr) + { + prelude = ((CommaExp *)(*pe))->e1; + aggr = ((CommaExp *)(*pe))->e2; + } + else + { + prelude = aggr; + aggr = ((CommaExp *)(*pe))->e2; + *pe = ((CommaExp *)(*pe))->e1; + } + } + Type *tab = aggr->type->toBasetype(); if (tab->ty == Ttuple) // don't generate new scope for tuple loops @@ -1451,10 +1482,10 @@ Statement *ForeachStatement::semantic(Scope *sc) Expression *e; Type *t; if (te) - e = (Expression *)te->exps->data[k]; + e = te->exps->tdata()[k]; else t = Parameter::getNth(tuple->arguments, k)->type; - Parameter *arg = (Parameter *)arguments->data[0]; + Parameter *arg = arguments->tdata()[0]; Statements *st = new Statements(); if (dim == 2) @@ -1477,7 +1508,7 @@ Statement *ForeachStatement::semantic(Scope *sc) var->storage_class |= STCmanifest; DeclarationExp *de = new DeclarationExp(loc, var); st->push(new ExpStatement(loc, de)); - arg = (Parameter *)arguments->data[1]; // value + arg = arguments->tdata()[1]; // value } // Declare value if (arg->storageClass & (STCout | STCref | STClazy)) @@ -1494,8 +1525,10 @@ Statement *ForeachStatement::semantic(Scope *sc) arg->type = e->type; Initializer *ie = new ExpInitializer(0, e); VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie); - if (e->isConst() || e->op == TOKstring) + if (e->isConst()) v->storage_class |= STCconst; + if (e->op == TOKstring) + v->storage_class |= STCmanifest; var = v; } } @@ -1513,6 +1546,9 @@ Statement *ForeachStatement::semantic(Scope *sc) } s = new UnrolledLoopStatement(loc, statements); + if (prelude) + s = new CompoundStatement(loc, + new ExpStatement(prelude->loc, prelude), s); s = s->semantic(sc); return s; } @@ -1548,7 +1584,7 @@ Lagain: { Parameter *arg; int i = (dim == 1) ? 0 : 1; // index of value - arg = (Parameter *)arguments->data[i]; + arg = arguments->tdata()[i]; arg->type = arg->type->semantic(loc, sc); tnv = arg->type->toBasetype(); if (tnv->ty != tn->ty && @@ -1557,7 +1593,7 @@ Lagain: if (arg->storageClass & STCref) error("foreach: value of UTF conversion cannot be ref"); if (dim == 2) - { arg = (Parameter *)arguments->data[0]; + { arg = arguments->tdata()[0]; if (arg->storageClass & STCref) error("foreach: key cannot be ref"); } @@ -1567,7 +1603,7 @@ Lagain: for (size_t i = 0; i < dim; i++) { // Declare args - Parameter *arg = (Parameter *)arguments->data[i]; + Parameter *arg = arguments->tdata()[i]; Type *argtype = arg->type->semantic(loc, sc); VarDeclaration *var; @@ -1615,8 +1651,8 @@ Lagain: if (!key) { - Identifier *id = Lexer::uniqueId("__key"); - key = new VarDeclaration(loc, Type::tsize_t, id, NULL); + Identifier *idkey = Lexer::uniqueId("__key"); + key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL); } if (op == TOKforeach_reverse) key->init = new ExpInitializer(loc, tmp_length); @@ -1647,8 +1683,11 @@ Lagain: body = new CompoundStatement(loc, ds, body); - ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body); - s = fs->semantic(sc); + s = new ForStatement(loc, forinit, cond, increment, body); + if (prelude) + s = new CompoundStatement(loc, + new ExpStatement(prelude->loc, prelude), s); + s = s->semantic(sc); break; } #else @@ -1665,7 +1704,7 @@ Lagain: { if (key->type->ty != Tint32 && key->type->ty != Tuns32) { - if (global.params.isX86_64) + if (global.params.is64bit) { if (key->type->ty != Tint64 && key->type->ty != Tuns64) error("foreach: key type must be int or uint, long or ulong, not %s", key->type->toChars()); @@ -1711,9 +1750,6 @@ Lagain: #if DMDV2 /* Prefer using opApply, if it exists */ - if (dim != 1) // only one argument allowed with ranges - goto Lapply; - sapply = search_function((AggregateDeclaration *)tab->toDsymbol(sc), idapply); if (sapply) goto Lapply; @@ -1742,7 +1778,24 @@ Lagain: } Dsymbol *shead = search_function(ad, idhead); if (!shead) + { + if (ad->aliasthis) + { + Identifier *id = Lexer::uniqueId("__tup"); + ExpInitializer *ei = new ExpInitializer(aggr->loc, aggr); + VarDeclaration *vd = new VarDeclaration(loc, NULL, id, ei); + vd->storage_class |= STCctfe | STCref | STCforeach; + + aggr = new CommaExp(aggr->loc, + new DeclarationExp(loc, vd), + new DotIdExp(aggr->loc, + new VarExp(loc, vd), + ad->aliasthis->ident)); + + goto Lretry; + } goto Lapply; + } /* Generate a temporary __r and initialize it with the aggregate. */ @@ -1752,10 +1805,7 @@ Lagain: if (!rinit) // if application of [] failed rinit = aggr; VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, rinit)); -// r->semantic(sc); -//printf("r: %s, init: %s\n", r->toChars(), r->init->toChars()); Statement *init = new ExpStatement(loc, r); -//printf("init: %s\n", init->toChars()); // !__r.empty Expression *e = new VarExp(loc, r); @@ -1771,26 +1821,84 @@ Lagain: */ e = new VarExp(loc, r); Expression *einit = new DotIdExp(loc, e, idhead); -// einit = einit->semantic(sc); - Parameter *arg = (Parameter *)arguments->data[0]; - VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); - ve->storage_class |= STCforeach; - ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR); + Statement *makeargs, *forbody; + if (dim == 1) + { + Parameter *arg = arguments->tdata()[0]; + VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); + ve->storage_class |= STCforeach; + ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR); - DeclarationExp *de = new DeclarationExp(loc, ve); + DeclarationExp *de = new DeclarationExp(loc, ve); + makeargs = new ExpStatement(loc, de); + } + else + { + Identifier *id = Lexer::uniqueId("__front"); + ExpInitializer *ei = new ExpInitializer(loc, einit); + VarDeclaration *vd = new VarDeclaration(loc, NULL, id, ei); + vd->storage_class |= STCctfe | STCref | STCforeach; - Statement *body = new CompoundStatement(loc, - new ExpStatement(loc, de), this->body); + Expression *de = new DeclarationExp(loc, vd); + makeargs = new ExpStatement(loc, de); - s = new ForStatement(loc, init, condition, increment, body); + Expression *ve = new VarExp(loc, vd); + ve->type = shead->isDeclaration()->type; + if (ve->type->toBasetype()->ty == Tfunction) + ve->type = ve->type->toBasetype()->nextOf(); + if (!ve->type || ve->type->ty == Terror) + goto Lrangeerr; + + Expressions *exps = new Expressions(); + exps->push(ve); + int pos = 0; + while (exps->dim < dim) + { + pos = expandAliasThisTuples(exps, pos); + if (pos == -1) + break; + } + if (exps->dim > dim) + goto Lrangeerr; + + for (size_t i = 0; i < dim; i++) + { + Parameter *arg = arguments->tdata()[i]; + Expression *exp = exps->tdata()[i]; + #if 0 + printf("[%d] arg = %s %s, exp = %s %s\n", i, + arg->type ? arg->type->toChars() : "?", arg->ident->toChars(), + exp->type->toChars(), exp->toChars()); + #endif + if (arg->type && !exp->implicitConvTo(arg->type)) + goto Lrangeerr; + if (!arg->type) + arg->type = exp->type; + + VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, exp)); + var->storage_class |= STCctfe | STCref | STCforeach; + DeclarationExp *de = new DeclarationExp(loc, var); + makeargs = new CompoundStatement(loc, makeargs, new ExpStatement(loc, de)); + } + + } + + forbody = new CompoundStatement(loc, + makeargs, this->body); + + s = new ForStatement(loc, init, condition, increment, forbody); #if 0 printf("init: %s\n", init->toChars()); printf("condition: %s\n", condition->toChars()); printf("increment: %s\n", increment->toChars()); - printf("body: %s\n", body->toChars()); + printf("body: %s\n", forbody->toChars()); #endif s = s->semantic(sc); break; + + Lrangeerr: + error("cannot infer argument types"); + break; } #endif case Tdelegate: @@ -1828,7 +1936,7 @@ Lagain: */ Parameters *args = new Parameters(); for (size_t i = 0; i < dim; i++) - { Parameter *arg = (Parameter *)arguments->data[i]; + { Parameter *arg = arguments->tdata()[i]; Identifier *id; arg->type = arg->type->semantic(loc, sc); @@ -1848,8 +1956,8 @@ Lagain: args->push(a); } Type *t = new TypeFunction(args, Type::tint32, 0, LINKd); - cases = new Array(); - gotos = new Array(); + cases = new Statements(); + gotos = new CompoundStatements(); FuncLiteralDeclaration *fld = new FuncLiteralDeclaration(loc, 0, t, TOKdelegate, this); fld->fbody = body; Expression *flde = new FuncExp(loc, fld); @@ -1858,28 +1966,28 @@ Lagain: // Resolve any forward referenced goto's for (size_t i = 0; i < gotos->dim; i++) - { CompoundStatement *cs = (CompoundStatement *)gotos->data[i]; - GotoStatement *gs = (GotoStatement *)cs->statements->data[0]; + { CompoundStatement *cs = gotos->tdata()[i]; + GotoStatement *gs = (GotoStatement *)cs->statements->tdata()[0]; if (!gs->label->statement) { // 'Promote' it to this scope, and replace with a return cases->push(gs); s = new ReturnStatement(0, new IntegerExp(cases->dim + 1)); - cs->statements->data[0] = (void *)s; + cs->statements->tdata()[0] = s; } } - if (tab->ty == Taarray) + if (taa) { // Check types - Parameter *arg = (Parameter *)arguments->data[0]; + Parameter *arg = arguments->tdata()[0]; if (dim == 2) { if (arg->storageClass & STCref) error("foreach: index cannot be ref"); if (!arg->type->equals(taa->index)) error("foreach: index must be type %s, not %s", taa->index->toChars(), arg->type->toChars()); - arg = (Parameter *)arguments->data[1]; + arg = arguments->tdata()[1]; } if (!arg->type->equals(taa->nextOf())) error("foreach: value must be type %s, not %s", taa->nextOf()->toChars(), arg->type->toChars()); @@ -1897,21 +2005,21 @@ Lagain: Parameters* dgargs = new Parameters; dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); args->push(new Parameter(STCin, aaApply2_dg, NULL, NULL)); - aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2"); + aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply2"); } static FuncDeclaration *aaApply_fd = NULL; - static TypeDelegate* aaApply_dg; + static TypeDelegate* aaApply_dg; if(!aaApply_fd) { Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); + args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); // FIXME: Real parameter type is AA. args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); Parameters* dgargs = new Parameters; dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); + aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); args->push(new Parameter(STCin, aaApply_dg, NULL, NULL)); - aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply"); + aaApply_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply"); } if (dim == 2) { fdapply = aaApply2_fd; @@ -1937,7 +2045,7 @@ Lagain: #endif exps->push(flde); e = new CallExp(loc, ec, exps); - e->type = Type::tindex; // don't run semantic() on e + e->type = Type::tint32; // don't run semantic() on e } else if (tab->ty == Tarray || tab->ty == Tsarray) { @@ -1977,18 +2085,18 @@ Lagain: Parameters* args = new Parameters; args->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL)); if (dim == 2) { - Parameters* dgargs = new Parameters; - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); - args->push(new Parameter(STCin, dgty, NULL, NULL)); - fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); + Parameters* dgargs = new Parameters; + dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); + dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); + dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); + args->push(new Parameter(STCin, dgty, NULL, NULL)); + fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); } else { - Parameters* dgargs = new Parameters; - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); - args->push(new Parameter(STCin, dgty, NULL, NULL)); - fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); + Parameters* dgargs = new Parameters; + dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); + dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); + args->push(new Parameter(STCin, dgty, NULL, NULL)); + fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); } ec = new VarExp(0, fdapply); @@ -2005,7 +2113,7 @@ Lagain: } exps->push(flde); e = new CallExp(loc, ec, exps); - e->type = Type::tindex; // don't run semantic() on e + e->type = Type::tint32; // don't run semantic() on e } else if (tab->ty == Tdelegate) { @@ -2070,17 +2178,20 @@ Lagain: a->push(s); // cases 2... - for (int i = 0; i < cases->dim; i++) + for (size_t i = 0; i < cases->dim; i++) { - s = (Statement *)cases->data[i]; + s = cases->tdata()[i]; s = new CaseStatement(0, new IntegerExp(i + 2), s); a->push(s); } s = new CompoundStatement(loc, a); s = new SwitchStatement(loc, e, s, FALSE); - s = s->semantic(sc); } + if (prelude) + s = new CompoundStatement(loc, + new ExpStatement(prelude->loc, prelude), s); + s = s->semantic(sc); break; } case Terror: @@ -2101,7 +2212,7 @@ bool ForeachStatement::checkForArgTypes() { bool result = TRUE; for (size_t i = 0; i < arguments->dim; i++) - { Parameter *arg = (Parameter *)arguments->data[i]; + { Parameter *arg = arguments->tdata()[i]; if (!arg->type) { error("cannot infer type for %s", arg->ident->toChars()); @@ -2152,9 +2263,9 @@ void ForeachStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring(Token::toChars(op)); buf->writestring(" ("); - for (int i = 0; i < arguments->dim; i++) + for (size_t i = 0; i < arguments->dim; i++) { - Parameter *a = (Parameter *)arguments->data[i]; + Parameter *a = arguments->tdata()[i]; if (i) buf->writestring(", "); if (a->storageClass & STCref) @@ -2207,7 +2318,6 @@ Statement *ForeachRangeStatement::syntaxCopy() Statement *ForeachRangeStatement::semantic(Scope *sc) { //printf("ForeachRangeStatement::semantic() %p\n", this); - ScopeDsymbol *sym; Statement *s = this; lwr = lwr->semantic(sc); @@ -2699,13 +2809,13 @@ Statement *PragmaStatement::semantic(Scope *sc) { for (size_t i = 0; i < args->dim; i++) { - Expression *e = (Expression *)args->data[i]; + Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - if (e->op == TOKstring) + StringExp *se = e->toString(); + if (se) { - StringExp *se = (StringExp *)e; fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else @@ -2725,16 +2835,16 @@ Statement *PragmaStatement::semantic(Scope *sc) error("string expected for library name"); else { - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - args->data[0] = (void *)e; - if (e->op != TOKstring) + args->tdata()[0] = e; + StringExp *se = e->toString(); + if (!se) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { - StringExp *se = (StringExp *)e; char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; @@ -2757,10 +2867,10 @@ Statement *PragmaStatement::semantic(Scope *sc) error("function name expected for start address"); else { - Expression *e = (Expression *)args->data[0]; + Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); - args->data[0] = (void *)e; + args->tdata()[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); @@ -2914,15 +3024,15 @@ Statement *SwitchStatement::semantic(Scope *sc) sc->sbreak = this; sc->sw = this; - cases = new Array(); + cases = new CaseStatements(); sc->noctor++; // BUG: should use Scope::mergeCallSuper() for each case instead body = body->semantic(sc); sc->noctor--; // Resolve any goto case's with exp - for (int i = 0; i < gotoCases.dim; i++) + for (size_t i = 0; i < gotoCases.dim; i++) { - GotoCaseStatement *gcs = (GotoCaseStatement *)gotoCases.data[i]; + GotoCaseStatement *gcs = gotoCases.tdata()[i]; if (!gcs->exp) { @@ -2934,9 +3044,9 @@ Statement *SwitchStatement::semantic(Scope *sc) { if (!scx->sw) continue; - for (int j = 0; j < scx->sw->cases->dim; j++) + for (size_t j = 0; j < scx->sw->cases->dim; j++) { - CaseStatement *cs = (CaseStatement *)scx->sw->cases->data[j]; + CaseStatement *cs = scx->sw->cases->tdata()[j]; if (cs->exp->equals(gcs->exp)) { @@ -2997,11 +3107,11 @@ Statement *SwitchStatement::semantic(Scope *sc) size_t dim = ed->members->dim; for (size_t i = 0; i < dim; i++) { - EnumMember *em = ((Dsymbol *)ed->members->data[i])->isEnumMember(); + EnumMember *em = ed->members->tdata()[i]->isEnumMember(); if (em) { for (size_t j = 0; j < cases->dim; j++) - { CaseStatement *cs = (CaseStatement *)cases->data[j]; + { CaseStatement *cs = cases->tdata()[j]; if (cs->exp->equals(em->value)) goto L1; } @@ -3133,9 +3243,9 @@ Statement *CaseStatement::semantic(Scope *sc) } L1: - for (int i = 0; i < sw->cases->dim; i++) + for (size_t i = 0; i < sw->cases->dim; i++) { - CaseStatement *cs = (CaseStatement *)sw->cases->data[i]; + CaseStatement *cs = sw->cases->tdata()[i]; //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars()); if (cs->exp->equals(exp)) @@ -3147,9 +3257,9 @@ Statement *CaseStatement::semantic(Scope *sc) sw->cases->push(this); // Resolve any goto case's with no exp to this case statement - for (int i = 0; i < sw->gotoCases.dim; i++) + for (size_t i = 0; i < sw->gotoCases.dim; i++) { - GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i]; + GotoCaseStatement *gcs = sw->gotoCases.tdata()[i]; if (!gcs->exp) { @@ -3560,9 +3670,9 @@ Statement *ReturnStatement::semantic(Scope *sc) fd->nrvo_can = 0; else if (!v || v->isOut() || v->isRef()) fd->nrvo_can = 0; - else if (tbret->ty == Tstruct && ((TypeStruct *)tbret)->sym->dtor) - // Struct being returned has destructors - fd->nrvo_can = 0; +// else if (tbret->ty == Tstruct && ((TypeStruct *)tbret)->sym->dtor) +// // Struct being returned has destructors +// fd->nrvo_can = 0; else if (fd->nrvo_var == NULL) { if (!v->isDataseg() && !v->isParameter() && v->toParent2() == fd) { //printf("Setting nrvo to %s\n", v->toChars()); @@ -3630,6 +3740,13 @@ Statement *ReturnStatement::semantic(Scope *sc) } else if (tbret->ty != Tvoid) { + if (fd->isPureBypassingInference() == PUREstrong && + !exp->type->implicitConvTo(tret) && + exp->type->invariantOf()->implicitConvTo(tret)) + { + exp = exp->castTo(sc, exp->type->invariantOf()); + } + exp = exp->implicitCastTo(sc, tret); if (!((TypeFunction *)fd->type)->isref) exp = exp->optimize(WANTvalue); @@ -3724,16 +3841,7 @@ Statement *ReturnStatement::semantic(Scope *sc) #if IN_LLVM if (!fd->isCtorDeclaration() && fd->returnLabel && tbret->ty != Tvoid) #else - if (fd->returnLabel && tbret->ty != Tvoid) #endif - { - assert(fd->vresult); - VarExp *v = new VarExp(0, fd->vresult); - - exp = new ConstructExp(loc, v, exp); - exp = exp->semantic(sc); - } - if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()) { // Function returns a reference if (tbret->isMutable()) @@ -3749,6 +3857,15 @@ Statement *ReturnStatement::semantic(Scope *sc) //exp->print(); exp->checkEscape(); } + + if (fd->returnLabel && tbret->ty != Tvoid) + { + assert(fd->vresult); + VarExp *v = new VarExp(0, fd->vresult); + + exp = new ConstructExp(loc, v, exp); + exp = exp->semantic(sc); + } } /* BUG: need to issue an error on: @@ -4085,10 +4202,10 @@ Statement *SynchronizedStatement::semantic(Scope *sc) cs->push(new ExpStatement(loc, tmp)); #if IN_LLVM - // LDC: Build args - Parameters* args = new Parameters; - args->push(new Parameter(STCin, ClassDeclaration::object->type, NULL, NULL)); - FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter); + // LDC: Build args + Parameters* args = new Parameters; + args->push(new Parameter(STCin, ClassDeclaration::object->type, NULL, NULL)); + FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter); #else FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorenter); #endif @@ -4313,7 +4430,7 @@ int WithStatement::blockExit(bool mustNotThrow) /******************************** TryCatchStatement ***************************/ -TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) +TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Catches *catches) : Statement(loc) { this->body = body; @@ -4322,14 +4439,14 @@ TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) Statement *TryCatchStatement::syntaxCopy() { - Array *a = new Array(); + Catches *a = new Catches(); a->setDim(catches->dim); - for (int i = 0; i < a->dim; i++) + for (size_t i = 0; i < a->dim; i++) { Catch *c; - c = (Catch *)catches->data[i]; + c = catches->tdata()[i]; c = c->syntaxCopy(); - a->data[i] = c; + a->tdata()[i] = c; } TryCatchStatement *s = new TryCatchStatement(loc, body->syntaxCopy(), a); return s; @@ -4342,12 +4459,12 @@ Statement *TryCatchStatement::semantic(Scope *sc) /* Even if body is NULL, still do semantic analysis on catches */ for (size_t i = 0; i < catches->dim; i++) - { Catch *c = (Catch *)catches->data[i]; + { Catch *c = catches->tdata()[i]; c->semantic(sc); // Determine if current catch 'hides' any previous catches for (size_t j = 0; j < i; j++) - { Catch *cj = (Catch *)catches->data[j]; + { Catch *cj = catches->tdata()[j]; char *si = c->loc.toChars(); char *sj = cj->loc.toChars(); @@ -4381,7 +4498,7 @@ int TryCatchStatement::blockExit(bool mustNotThrow) int catchresult = 0; for (size_t i = 0; i < catches->dim; i++) { - Catch *c = (Catch *)catches->data[i]; + Catch *c = catches->tdata()[i]; if (c->type == Type::terror) continue; @@ -4411,7 +4528,7 @@ void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) body->toCBuffer(buf, hgs); for (size_t i = 0; i < catches->dim; i++) { - Catch *c = (Catch *)catches->data[i]; + Catch *c = catches->tdata()[i]; c->toCBuffer(buf, hgs); } } @@ -4759,11 +4876,11 @@ Statements *VolatileStatement::flatten(Scope *sc) a = statement ? statement->flatten(sc) : NULL; if (a) - { for (int i = 0; i < a->dim; i++) - { Statement *s = (Statement *)a->data[i]; + { for (size_t i = 0; i < a->dim; i++) + { Statement *s = a->tdata()[i]; s = new VolatileStatement(loc, s); - a->data[i] = s; + a->tdata()[i] = s; } } @@ -4821,10 +4938,10 @@ Statements *DebugStatement::flatten(Scope *sc) Statements *a = statement ? statement->flatten(sc) : NULL; if (a) { for (size_t i = 0; i < a->dim; i++) - { Statement *s = (Statement *)a->data[i]; + { Statement *s = a->tdata()[i]; s = new DebugStatement(loc, s); - a->data[i] = s; + a->tdata()[i] = s; } } @@ -4874,7 +4991,7 @@ Statement *GotoStatement::semantic(Scope *sc) * list. */ Statements *a = new Statements(); - Statement *s; + CompoundStatement *s; a->push(this); s = new CompoundStatement(loc, a); @@ -4962,10 +5079,10 @@ Statements *LabelStatement::flatten(Scope *sc) { a->push(new ExpStatement(loc, (Expression *)NULL)); } - Statement *s = (Statement *)a->data[0]; + Statement *s = a->tdata()[0]; s = new LabelStatement(loc, ident, s); - a->data[0] = s; + a->tdata()[0] = s; } } @@ -5094,17 +5211,17 @@ Statement *ImportStatement::syntaxCopy() { Dsymbols *m = new Dsymbols(); m->setDim(imports->dim); - for (int i = 0; i < imports->dim; i++) - { Dsymbol *s = (Dsymbol *)imports->data[i]; - m->data[i] = (void *)s->syntaxCopy(NULL); + for (size_t i = 0; i < imports->dim; i++) + { Dsymbol *s = imports->tdata()[i]; + m->tdata()[i] = s->syntaxCopy(NULL); } return new ImportStatement(loc, m); } Statement *ImportStatement::semantic(Scope *sc) { - for (int i = 0; i < imports->dim; i++) - { Dsymbol *s = (Dsymbol *)imports->data[i]; + for (size_t i = 0; i < imports->dim; i++) + { Dsymbol *s = imports->tdata()[i]; s->semantic(sc); sc->insert(s); } @@ -5123,8 +5240,8 @@ int ImportStatement::isEmpty() void ImportStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { - for (int i = 0; i < imports->dim; i++) - { Dsymbol *s = (Dsymbol *)imports->data[i]; + for (size_t i = 0; i < imports->dim; i++) + { Dsymbol *s = imports->tdata()[i]; s->toCBuffer(buf, hgs); } } diff --git a/dmd2/statement.h b/dmd2/statement.h index 11a86978..da8588d6 100644 --- a/dmd2/statement.h +++ b/dmd2/statement.h @@ -189,6 +189,18 @@ struct ExpStatement : Statement #endif }; +struct DtorExpStatement : ExpStatement +{ + /* Wraps an expression that is the destruction of 'var' + */ + + VarDeclaration *var; + + DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v); + Statement *syntaxCopy(); + void toIR(IRState *irs); +}; + struct CompileStatement : Statement { Expression *exp; @@ -365,8 +377,8 @@ struct ForeachStatement : Statement FuncDeclaration *func; // function we're lexically in - Array *cases; // put breaks, continues, gotos and returns here - Array *gotos; // forward referenced goto's go here + Statements *cases; // put breaks, continues, gotos and returns here + CompoundStatements *gotos; // forward referenced goto's go here ForeachStatement(Loc loc, enum TOK op, Parameters *arguments, Expression *aggr, Statement *body); Statement *syntaxCopy(); @@ -492,8 +504,8 @@ struct SwitchStatement : Statement DefaultStatement *sdefault; - Array gotoCases; // array of unresolved GotoCaseStatement's - Array *cases; // array of CaseStatement's + GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's + CaseStatements *cases; // array of CaseStatement's int hasNoDefault; // !=0 if no default statement int hasVars; // !=0 if has variable case values @@ -738,9 +750,9 @@ struct WithStatement : Statement struct TryCatchStatement : Statement { Statement *body; - Array *catches; + Catches *catches; - TryCatchStatement(Loc loc, Statement *body, Array *catches); + TryCatchStatement(Loc loc, Statement *body, Catches *catches); Statement *syntaxCopy(); Statement *semantic(Scope *sc); int hasBreak(); @@ -874,7 +886,7 @@ struct LabelStatement : Statement Statement* enclosingScopeExit; block *lblock; // back end - Array *fwdrefs; // forward references to this LabelStatement + Blocks *fwdrefs; // forward references to this LabelStatement LabelStatement(Loc loc, Identifier *ident, Statement *statement); Statement *syntaxCopy(); diff --git a/dmd2/struct.c b/dmd2/struct.c index 92c8c418..d75dc024 100644 --- a/dmd2/struct.c +++ b/dmd2/struct.c @@ -55,6 +55,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) ctor = NULL; defaultCtor = NULL; aliasthis = NULL; + noDefaultCtor = FALSE; #endif dtor = NULL; @@ -80,7 +81,7 @@ void AggregateDeclaration::semantic2(Scope *sc) sc = sc->push(this); for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic2(sc); } sc->pop(); @@ -88,8 +89,7 @@ void AggregateDeclaration::semantic2(Scope *sc) } void AggregateDeclaration::semantic3(Scope *sc) -{ int i; - +{ #if IN_LLVM if (!global.params.useAvailableExternally) availableExternally = false; @@ -99,9 +99,9 @@ void AggregateDeclaration::semantic3(Scope *sc) if (members) { sc = sc->push(this); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic3(sc); } sc->pop(); @@ -109,14 +109,13 @@ void AggregateDeclaration::semantic3(Scope *sc) } void AggregateDeclaration::inlineScan() -{ int i; - +{ //printf("AggregateDeclaration::inlineScan(%s)\n", toChars()); if (members) { - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; //printf("inline scan aggregate symbol '%s'\n", s->toChars()); s->inlineScan(); } @@ -161,7 +160,7 @@ void AggregateDeclaration::alignmember( if (salign > 1) { assert(size != 3); - int sa = size; + unsigned sa = size; if (sa == 0 || salign < sa) sa = salign; *poffset = (*poffset + sa - 1) & ~(sa - 1); @@ -263,13 +262,13 @@ int AggregateDeclaration::firstFieldInUnion(int indx) { if (isUnionDeclaration()) return 0; - VarDeclaration * vd = (VarDeclaration *)fields.data[indx]; + VarDeclaration * vd = fields.tdata()[indx]; int firstNonZero = indx; // first index in the union with non-zero size for (; ;) { if (indx == 0) return firstNonZero; - VarDeclaration * v = (VarDeclaration *)fields.data[indx - 1]; + VarDeclaration * v = fields.tdata()[indx - 1]; if (v->offset != vd->offset) return firstNonZero; --indx; @@ -288,7 +287,7 @@ int AggregateDeclaration::firstFieldInUnion(int indx) */ int AggregateDeclaration::numFieldsInUnion(int firstIndex) { - VarDeclaration * vd = (VarDeclaration *)fields.data[firstIndex]; + VarDeclaration * vd = fields.tdata()[firstIndex]; /* If it is a zero-length field, AND we can't find an earlier non-zero * sized field with the same offset, we assume it's not part of a union. */ @@ -296,9 +295,9 @@ int AggregateDeclaration::numFieldsInUnion(int firstIndex) firstFieldInUnion(firstIndex) == firstIndex) return 1; int count = 1; - for (int i = firstIndex+1; i < fields.dim; ++i) + for (size_t i = firstIndex+1; i < fields.dim; ++i) { - VarDeclaration * v = (VarDeclaration *)fields.data[i]; + VarDeclaration * v = fields.tdata()[i]; // If offsets are different, they are not in the same union if (v->offset != vd->offset) break; @@ -403,9 +402,9 @@ void StructDeclaration::semantic(Scope *sc) if (sizeok == 0) // if not already done the addMember step { int hasfunctions = 0; - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); s->addMember(sc, this, 1); if (s->isFuncDeclaration()) @@ -455,13 +454,13 @@ void StructDeclaration::semantic(Scope *sc) sc2->protection = PROTpublic; sc2->explicitProtection = 0; - int members_dim = members->dim; + size_t members_dim = members->dim; /* Set scope so if there are forward references, we still might be able to * resolve individual members like enums. */ - for (int i = 0; i < members_dim; i++) - { Dsymbol *s = (Dsymbol *)members->data[i]; + for (size_t i = 0; i < members_dim; i++) + { Dsymbol *s = members->tdata()[i]; /* There are problems doing this in the general case because * Scope keeps track of things like 'offset' */ @@ -472,9 +471,9 @@ void StructDeclaration::semantic(Scope *sc) } } - for (int i = 0; i < members_dim; i++) + for (size_t i = 0; i < members_dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic(sc2); #if 0 if (sizeok == 2) @@ -639,9 +638,9 @@ void StructDeclaration::semantic(Scope *sc) // Determine if struct is all zeros or not zeroInit = 1; - for (int i = 0; i < fields.dim; i++) + for (size_t i = 0; i < fields.dim; i++) { - Dsymbol *s = (Dsymbol *)fields.data[i]; + Dsymbol *s = fields.tdata()[i]; VarDeclaration *vd = s->isVarDeclaration(); if (vd && !vd->isDataseg()) { @@ -700,8 +699,7 @@ Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags) } void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) -{ int i; - +{ buf->printf("%s ", kind()); if (!isAnonymous()) buf->writestring(toChars()); @@ -714,9 +712,9 @@ void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); buf->writeByte('{'); buf->writenl(); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; buf->writestring(" "); s->toCBuffer(buf, hgs); diff --git a/dmd2/template.c b/dmd2/template.c index e6d2ebf9..2eb509a5 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -98,7 +98,7 @@ int arrayObjectIsError(Objects *args) { for (size_t i = 0; i < args->dim; i++) { - Object *o = (Object *)args->data[i]; + Object *o = args->tdata()[i]; if (isError(o)) return 1; } @@ -157,16 +157,35 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc) Expression *e2 = isExpression(o2); Dsymbol *s1 = isDsymbol(o1); Dsymbol *s2 = isDsymbol(o2); - Tuple *v1 = isTuple(o1); - Tuple *v2 = isTuple(o2); + Tuple *u1 = isTuple(o1); + Tuple *u2 = isTuple(o2); - //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2); + //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, u1 %p u2 %p\n", t1,t2,e1,e2,s1,s2,u1,u2); /* A proper implementation of the various equals() overrides * should make it possible to just do o1->equals(o2), but * we'll do that another day. */ + if (s1) + { + VarDeclaration *v1 = s1->isVarDeclaration(); + if (v1 && v1->storage_class & STCmanifest) + { ExpInitializer *ei1 = v1->init->isExpInitializer(); + if (ei1) + e1 = ei1->exp, s1 = NULL; + } + } + if (s2) + { + VarDeclaration *v2 = s2->isVarDeclaration(); + if (v2 && v2->storage_class & STCmanifest) + { ExpInitializer *ei2 = v2->init->isExpInitializer(); + if (ei2) + e2 = ei2->exp, s2 = NULL; + } + } + if (t1) { /* if t1 is an instance of ti, then give error @@ -213,48 +232,25 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc) else if (s1) { if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) - { - if (s2) - { - VarDeclaration *v1 = s1->isVarDeclaration(); - VarDeclaration *v2 = s2->isVarDeclaration(); - if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) - { ExpInitializer *ei1 = v1->init->isExpInitializer(); - ExpInitializer *ei2 = v2->init->isExpInitializer(); - if (ei1 && ei2 && ei1->exp->equals(ei2->exp)) - goto Lmatch; - } - } goto Lnomatch; - } -#if DMDV2 - VarDeclaration *v1 = s1->isVarDeclaration(); - VarDeclaration *v2 = s2->isVarDeclaration(); - if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) - { ExpInitializer *ei1 = v1->init->isExpInitializer(); - ExpInitializer *ei2 = v2->init->isExpInitializer(); - if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) - goto Lnomatch; - } -#endif } - else if (v1) + else if (u1) { - if (!v2) + if (!u2) goto Lnomatch; - if (v1->objects.dim != v2->objects.dim) + if (u1->objects.dim != u2->objects.dim) goto Lnomatch; - for (size_t i = 0; i < v1->objects.dim; i++) + for (size_t i = 0; i < u1->objects.dim; i++) { - if (!match((Object *)v1->objects.data[i], - (Object *)v2->objects.data[i], + if (!match(u1->objects.tdata()[i], + u2->objects.tdata()[i], tempdecl, sc)) goto Lnomatch; } } -Lmatch: //printf("match\n"); return 1; // match + Lnomatch: //printf("nomatch\n"); return 0; // nomatch; @@ -271,8 +267,8 @@ int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, if (oa1->dim != oa2->dim) return 0; for (size_t j = 0; j < oa1->dim; j++) - { Object *o1 = (Object *)oa1->data[j]; - Object *o2 = (Object *)oa2->data[j]; + { Object *o1 = oa1->tdata()[j]; + Object *o2 = oa2->tdata()[j]; if (!match(o1, o2, tempdecl, sc)) { return 0; @@ -309,7 +305,7 @@ void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg) { if (i) buf->writeByte(','); - Object *o = (Object *)args->data[i]; + Object *o = args->tdata()[i]; ObjectToCBuffer(buf, hgs, o); } } @@ -354,7 +350,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, #if 0 if (parameters) for (int i = 0; i < parameters->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + { TemplateParameter *tp = parameters->tdata()[i]; //printf("\tparameter[%d] = %p\n", i, tp); TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); @@ -403,9 +399,9 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) { p = new TemplateParameters(); p->setDim(parameters->dim); - for (int i = 0; i < p->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; - p->data[i] = (void *)tp->syntaxCopy(); + for (size_t i = 0; i < p->dim; i++) + { TemplateParameter *tp = (*parameters)[i]; + p->tdata()[i] = tp->syntaxCopy(); } } Expression *e = NULL; @@ -489,23 +485,23 @@ void TemplateDeclaration::semantic(Scope *sc) { origParameters = new TemplateParameters(); origParameters->setDim(parameters->dim); - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; - origParameters->data[i] = (void *)tp->syntaxCopy(); + TemplateParameter *tp = parameters->tdata()[i]; + origParameters->tdata()[i] = tp->syntaxCopy(); } } - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; tp->declareParameter(paramscope); } - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; tp->semantic(paramscope); if (i + 1 != parameters->dim && tp->isTemplateTupleParameter()) @@ -569,9 +565,9 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s) if (f->parameters->dim != f2->parameters->dim) goto Lcontinue; - for (int i = 0; i < f->parameters->dim; i++) - { TemplateParameter *p1 = (TemplateParameter *)f->parameters->data[i]; - TemplateParameter *p2 = (TemplateParameter *)f2->parameters->data[i]; + for (size_t i = 0; i < f->parameters->dim; i++) + { TemplateParameter *p1 = f->parameters->tdata()[i]; + TemplateParameter *p2 = f2->parameters->tdata()[i]; if (!p1->overloadMatch(p2)) goto Lcontinue; @@ -599,7 +595,7 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s) * Declare all the function parameters as variables * and add them to the scope */ -void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope) +void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope, Expressions *fargs) { /* We do this ONLY if there is only one function in the template. */ @@ -611,7 +607,7 @@ void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope) int fvarargs; // function varargs Parameters *fparameters = fd->getParameters(&fvarargs); size_t nfparams = Parameter::dim(fparameters); // Num function parameters - for (int i = 0; i < nfparams; i++) + for (size_t i = 0; i < nfparams; i++) { Parameter *fparam = Parameter::getNth(fparameters, i)->syntaxCopy(); if (!fparam->ident) @@ -629,6 +625,17 @@ void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope) v->storage_class |= STCvariadic; v->storage_class |= fparam->storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); + if (fparam->storageClass & STCauto) + { + if (fargs && i < fargs->dim) + { Expression *farg = fargs->tdata()[i]; + if (farg->isLvalue()) + ; // ref parameter + else + v->storage_class &= ~STCref; // value parameter + } + } + v->semantic(paramscope); if (!paramscope->insert(v)) error("parameter %s.%s is already defined", toChars(), v->toChars()); @@ -651,9 +658,9 @@ void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope) */ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, - Objects *dedtypes, int flag) + Objects *dedtypes, Expressions *fargs, int flag) { MATCH m; - int dedtypes_dim = dedtypes->dim; + size_t dedtypes_dim = dedtypes->dim; #define LOGM 0 #if LOGM @@ -665,11 +672,11 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, if (ti->tiargs->dim) printf("ti->tiargs->dim = %d, [0] = %p\n", ti->tiargs->dim, - ti->tiargs->data[0]); + ti->tiargs->tdata()[0]); #endif dedtypes->zero(); - int parameters_dim = parameters->dim; + size_t parameters_dim = parameters->dim; int variadic = isVariadic() != NULL; // If more arguments than parameters, no match @@ -693,9 +700,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, // Attempt type deduction m = MATCHexact; - for (int i = 0; i < dedtypes_dim; i++) + for (size_t i = 0; i < dedtypes_dim; i++) { MATCH m2; - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; Declaration *sparam; //printf("\targument [%d]\n", i); @@ -736,20 +743,20 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, /* Any parameter left without a type gets the type of * its corresponding arg */ - for (int i = 0; i < dedtypes_dim; i++) + for (size_t i = 0; i < dedtypes_dim; i++) { - if (!dedtypes->data[i]) + if (!dedtypes->tdata()[i]) { assert(i < ti->tiargs->dim); - dedtypes->data[i] = ti->tiargs->data[i]; + dedtypes->tdata()[i] = (Type *)ti->tiargs->tdata()[i]; } } } #if DMDV2 - if (m && constraint && !(flag & 1)) + if (m && !(m == MATCHexact && flag == 2) && constraint && !(flag & 1)) { /* Check to see if constraint is satisfied. */ - makeParamNamesVisibleInConstraint(paramscope); + makeParamNamesVisibleInConstraint(paramscope, fargs); Expression *e = constraint->syntaxCopy(); Scope *sc = paramscope->push(); sc->flags |= SCOPEstaticif; @@ -774,18 +781,18 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti, printf("instance %s\n", ti->toChars()); if (m) { - for (int i = 0; i < dedtypes_dim; i++) + for (size_t i = 0; i < dedtypes_dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; Object *oarg; printf(" [%d]", i); if (i < ti->tiargs->dim) - oarg = (Object *)ti->tiargs->data[i]; + oarg = ti->tiargs->tdata()[i]; else oarg = NULL; - tp->print(oarg, (Object *)dedtypes->data[i]); + tp->print(oarg, dedtypes->tdata()[i]); } } else @@ -818,7 +825,7 @@ Lret: * 0 td2 is more specialized than this */ -MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2) +MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs) { /* This works by taking the template parameters to this template * declaration and feeding them to td2 as if it were a template @@ -840,13 +847,13 @@ MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2) // generated from the parameters to this template declaration ti.tiargs = new Objects(); ti.tiargs->setDim(parameters->dim); - for (int i = 0; i < ti.tiargs->dim; i++) + for (size_t i = 0; i < ti.tiargs->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; - void *p = tp->dummyArg(); + Object *p = (Object *)tp->dummyArg(); if (p) - ti.tiargs->data[i] = p; + ti.tiargs->tdata()[i] = p; else ti.tiargs->setDim(i); } @@ -856,7 +863,7 @@ MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2) dedtypes.setDim(td2->parameters->dim); // Attempt a type deduction - MATCH m = td2->matchWithInstance(&ti, &dedtypes, 1); + MATCH m = td2->matchWithInstance(&ti, &dedtypes, fargs, 1); if (m) { /* A non-variadic template is more specialized than a @@ -895,7 +902,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec Expression *ethis, Expressions *fargs, Objects *dedargs) { - size_t i; size_t nfparams; size_t nfargs; size_t nargsi; // array size of targsi @@ -910,7 +916,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec #if 0 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); for (i = 0; i < fargs->dim; i++) - { Expression *e = (Expression *)fargs->data[i]; + { Expression *e = fargs->tdata()[i]; printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); } printf("fd = %s\n", fd->toChars()); @@ -937,10 +943,10 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec int tp_is_declared = 0; #if 0 - for (i = 0; i < dedargs->dim; i++) + for (size_t i = 0; i < dedargs->dim; i++) { printf("\tdedarg[%d] = ", i); - Object *oarg = (Object *)dedargs->data[i]; + Object *oarg = dedargs->tdata()[i]; if (oarg) printf("%s", oarg->toChars()); printf("\n"); } @@ -964,13 +970,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec */ Tuple *t = new Tuple(); assert(parameters->dim); - dedargs->data[parameters->dim - 1] = (void *)t; + dedargs->tdata()[parameters->dim - 1] = t; tuple_dim = nargsi - n; t->objects.setDim(tuple_dim); for (size_t i = 0; i < tuple_dim; i++) { - t->objects.data[i] = (void *)targsi->data[n + i]; + t->objects.tdata()[i] = targsi->tdata()[n + i]; } declareParameter(paramscope, tp, t); tp_is_declared = 1; @@ -978,11 +984,11 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec else n = nargsi; - memcpy(dedargs->data, targsi->data, n * sizeof(*dedargs->data)); + memcpy(dedargs->tdata(), targsi->tdata(), n * sizeof(*dedargs->tdata())); for (size_t i = 0; i < n; i++) { assert(i < parameters->dim); - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; MATCH m; Declaration *sparam = NULL; @@ -999,10 +1005,10 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec } } #if 0 - for (i = 0; i < dedargs->dim; i++) + for (size_t i = 0; i < dedargs->dim; i++) { printf("\tdedarg[%d] = ", i); - Object *oarg = (Object *)dedargs->data[i]; + Object *oarg = dedargs->tdata()[i]; if (oarg) printf("%s", oarg->toChars()); printf("\n"); } @@ -1026,7 +1032,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec goto L2; Tuple *t = new Tuple(); //printf("t = %p\n", t); - dedargs->data[parameters->dim - 1] = (void *)t; + dedargs->tdata()[parameters->dim - 1] = t; declareParameter(paramscope, tp, t); goto L2; } @@ -1041,7 +1047,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec */ for (fptupindex = 0; fptupindex < nfparams; fptupindex++) { - Parameter *fparam = (Parameter *)fparameters->data[fptupindex]; + Parameter *fparam = fparameters->tdata()[fptupindex]; if (fparam->type->ty != Tident) continue; TypeIdentifier *tid = (TypeIdentifier *)fparam->type; @@ -1058,13 +1064,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec * now form the tuple argument. */ Tuple *t = new Tuple(); - dedargs->data[parameters->dim - 1] = (void *)t; + dedargs->tdata()[parameters->dim - 1] = t; tuple_dim = nfargs - (nfparams - 1); t->objects.setDim(tuple_dim); - for (i = 0; i < tuple_dim; i++) - { Expression *farg = (Expression *)fargs->data[fptupindex + i]; - t->objects.data[i] = (void *)farg->type; + for (size_t i = 0; i < tuple_dim; i++) + { Expression *farg = fargs->tdata()[fptupindex + i]; + t->objects.tdata()[i] = farg->type; } declareParameter(paramscope, tp, t); goto L2; @@ -1089,7 +1095,7 @@ L2: { // Match 'ethis' to any TemplateThisParameter's for (size_t i = 0; i < parameters->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + { TemplateParameter *tp = parameters->tdata()[i]; TemplateThisParameter *ttp = tp->isTemplateThisParameter(); if (ttp) { MATCH m; @@ -1157,7 +1163,7 @@ L2: * arg [fptupindex..fptupindex+tuple_dim] == param[fptupindex] * arg[fputupindex+dim.. ] == param[fptupindex+1.. ] */ - i = parami; + size_t i = parami; if (fptupindex >= 0 && parami > fptupindex) i += tuple_dim - 1; @@ -1173,7 +1179,7 @@ L2: } } else - { Expression *farg = (Expression *)fargs->data[i]; + { Expression *farg = fargs->tdata()[i]; #if 0 printf("\tfarg->type = %s\n", farg->type->toChars()); printf("\tfparam->type = %s\n", fparam->type->toChars()); @@ -1244,7 +1250,7 @@ L2: { TypeArray *ta = (TypeArray *)tb; for (; i < nfargs; i++) { - Expression *arg = (Expression *)fargs->data[i]; + Expression *arg = fargs->tdata()[i]; assert(arg); MATCH m; /* If lazy array of delegates, @@ -1289,15 +1295,15 @@ L2: Lmatch: - for (i = nargsi; i < dedargs->dim; i++) + for (size_t i = nargsi; i < dedargs->dim; i++) { - TemplateParameter *tparam = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tparam = parameters->tdata()[i]; //printf("tparam[%d] = %s\n", i, tparam->ident->toChars()); /* For T:T*, the dedargs is the T*, dedtypes is the T * But for function templates, we really need them to match */ - Object *oarg = (Object *)dedargs->data[i]; - Object *oded = (Object *)dedtypes.data[i]; + Object *oarg = dedargs->tdata()[i]; + Object *oded = dedtypes.tdata()[i]; //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); //if (oarg) printf("oarg: %s\n", oarg->toChars()); //if (oded) printf("oded: %s\n", oded->toChars()); @@ -1310,14 +1316,14 @@ Lmatch: * the oded == oarg */ Declaration *sparam; - dedargs->data[i] = (void *)oded; + dedargs->tdata()[i] = oded; MATCH m2 = tparam->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0); //printf("m2 = %d\n", m2); if (!m2) goto Lnomatch; if (m2 < match) match = m2; // pick worst match - if (dedtypes.data[i] != oded) + if (dedtypes.tdata()[i] != oded) error("specialization not allowed for deduced parameter %s", tparam->ident->toChars()); } } @@ -1336,7 +1342,7 @@ Lmatch: } } declareParameter(paramscope, tparam, oded); - dedargs->data[i] = (void *)oded; + dedargs->tdata()[i] = oded; } } @@ -1344,7 +1350,7 @@ Lmatch: if (constraint) { /* Check to see if constraint is satisfied. */ - makeParamNamesVisibleInConstraint(paramscope); + makeParamNamesVisibleInConstraint(paramscope, fargs); Expression *e = constraint->syntaxCopy(); paramscope->flags |= SCOPEstaticif; @@ -1402,7 +1408,7 @@ Lmatch: #if 0 for (i = 0; i < dedargs->dim; i++) - { Type *t = (Type *)dedargs->data[i]; + { Type *t = dedargs->tdata()[i]; printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars()); } #endif @@ -1496,7 +1502,7 @@ TemplateTupleParameter *isVariadic(TemplateParameters *parameters) TemplateTupleParameter *tp = NULL; if (dim) - tp = ((TemplateParameter *)parameters->data[dim - 1])->isTemplateTupleParameter(); + tp = (parameters->tdata()[dim - 1])->isTemplateTupleParameter(); return tp; } @@ -1541,14 +1547,14 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars()); printf(" targsi:\n"); if (targsi) - { for (int i = 0; i < targsi->dim; i++) - { Object *arg = (Object *)targsi->data[i]; + { for (size_t i = 0; i < targsi->dim; i++) + { Object *arg = targsi->tdata()[i]; printf("\t%s\n", arg->toChars()); } } printf(" fargs:\n"); - for (int i = 0; i < fargs->dim; i++) - { Expression *arg = (Expression *)fargs->data[i]; + for (size_t i = 0; i < fargs->dim; i++) + { Expression *arg = fargs->tdata()[i]; printf("\t%s %s\n", arg->type->toChars(), arg->toChars()); //printf("\tty = %d\n", arg->type->ty); } @@ -1583,8 +1589,8 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, { // Disambiguate by picking the most specialized TemplateDeclaration - MATCH c1 = td->leastAsSpecialized(td_best); - MATCH c2 = td_best->leastAsSpecialized(td); + MATCH c1 = td->leastAsSpecialized(td_best, fargs); + MATCH c2 = td_best->leastAsSpecialized(td, fargs); //printf("c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) @@ -1609,7 +1615,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, td_best = td; m_best = m; tdargs->setDim(dedargs.dim); - memcpy(tdargs->data, dedargs.data, tdargs->dim * sizeof(void *)); + memcpy(tdargs->tdata(), dedargs.tdata(), tdargs->dim * sizeof(void *)); continue; } if (!td_best) @@ -1647,11 +1653,11 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, OutBuffer bufa; Objects *args = targsi; if (args) - { for (int i = 0; i < args->dim; i++) + { for (size_t i = 0; i < args->dim; i++) { if (i) bufa.writeByte(','); - Object *oarg = (Object *)args->data[i]; + Object *oarg = args->tdata()[i]; ObjectToCBuffer(&bufa, &hgs, oarg); } } @@ -1677,11 +1683,11 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writeByte(' '); buf->writestring(ident->toChars()); buf->writeByte('('); - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; if (hgs->ddoc) - tp = (TemplateParameter *)origParameters->data[i]; + tp = origParameters->tdata()[i]; if (i) buf->writeByte(','); tp->toCBuffer(buf, hgs); @@ -1701,9 +1707,9 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); buf->writebyte('{'); buf->writenl(); - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->toCBuffer(buf, hgs); } buf->writebyte('}'); @@ -1720,9 +1726,9 @@ char *TemplateDeclaration::toChars() memset(&hgs, 0, sizeof(hgs)); buf.writestring(ident->toChars()); buf.writeByte('('); - for (int i = 0; i < parameters->dim; i++) + for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; if (i) buf.writeByte(','); tp->toCBuffer(&buf, &hgs); @@ -1749,7 +1755,7 @@ char *TemplateDeclaration::toChars() int templateIdentifierLookup(Identifier *id, TemplateParameters *parameters) { for (size_t i = 0; i < parameters->dim; i++) - { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + { TemplateParameter *tp = parameters->tdata()[i]; if (tp->ident->equals(id)) return i; @@ -1812,7 +1818,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Loc loc; if (parameters->dim) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[0]; + TemplateParameter *tp = parameters->tdata()[0]; loc = tp->loc; } @@ -1824,13 +1830,13 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, return deduceType(sc, tparam, parameters, dedtypes); } - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; // Found the corresponding parameter tp if (!tp->isTemplateTypeParameter()) goto Lnomatch; Type *tt = this; - Type *at = (Type *)dedtypes->data[i]; + Type *at = (Type *)dedtypes->tdata()[i]; // 7*7 == 49 cases @@ -1852,7 +1858,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, // foo(U:U) wild(T) => wild(T) // foo(U:U) wild(shared(T)) => wild(shared(T)) if (!at) - { dedtypes->data[i] = (void *)tt; + { dedtypes->tdata()[i] = tt; goto Lexact; } break; @@ -1871,7 +1877,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, // foo(U:wild(shared(U)) wild(shared(T)) => T tt = mutableOf()->unSharedOf(); if (!at) - { dedtypes->data[i] = (void *)tt; + { dedtypes->tdata()[i] = tt; goto Lexact; } break; @@ -1889,7 +1895,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, // foo(U:const(U)) wild(shared(T)) => shared(T) tt = mutableOf(); if (!at) - { dedtypes->data[i] = (void *)tt; + { dedtypes->tdata()[i] = tt; goto Lconst; } break; @@ -1902,7 +1908,7 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, // foo(U:shared(U)) wild(shared(T)) => wild(T) tt = unSharedOf(); if (!at) - { dedtypes->data[i] = (void *)tt; + { dedtypes->tdata()[i] = tt; goto Lconst; } break; @@ -2021,9 +2027,6 @@ MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame printf("\ttparam = %d, ", tparam->ty); tparam->print(); #endif return Type::deduceType(sc, tparam, parameters, dedtypes); - - Lnomatch: - return MATCHnomatch; } #endif @@ -2049,11 +2052,11 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame // This code matches code in TypeInstance::deduceType() if (i == -1) goto Lnomatch; - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; TemplateValueParameter *tvp = tp->isTemplateValueParameter(); if (!tvp) goto Lnomatch; - Expression *e = (Expression *)dedtypes->data[i]; + Expression *e = (Expression *)dedtypes->tdata()[i]; if (e) { if (!dim->equals(e)) @@ -2064,7 +2067,7 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame MATCH m = (MATCH)dim->implicitConvTo(vt); if (!m) goto Lnomatch; - dedtypes->data[i] = dim; + dedtypes->tdata()[i] = dim; } } else if (dim->toInteger() != tp->dim->toInteger()) @@ -2081,7 +2084,7 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame for (size_t i = 0; i < parameters->dim; i++) { - TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tp = parameters->tdata()[i]; if (tp->ident->equals(id)) { // Found the corresponding template parameter @@ -2089,13 +2092,13 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame if (!tvp || !tvp->valType->isintegral()) goto Lnomatch; - if (dedtypes->data[i]) + if (dedtypes->tdata()[i]) { - if (!dim->equals((Object *)dedtypes->data[i])) + if (!dim->equals(dedtypes->tdata()[i])) goto Lnomatch; } else - { dedtypes->data[i] = (void *)dim; + { dedtypes->tdata()[i] = dim; } return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes); } @@ -2155,6 +2158,15 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para size_t nfargs = Parameter::dim(this->parameters); size_t nfparams = Parameter::dim(tp->parameters); + // bug 2579 fix: Apply function parameter storage classes to parameter types + for (size_t i = 0; i < nfparams; i++) + { + Parameter *fparam = Parameter::getNth(tp->parameters, i); + fparam->type = fparam->type->addStorageClass(fparam->storageClass); + } + //printf("\t-> this = %d, ", ty); print(); + //printf("\t-> tparam = %d, ", tparam->ty); tparam->print(); + /* See if tuple match */ if (nfparams > 0 && nfargs >= nfparams - 1) @@ -2177,7 +2189,7 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para for (; 1; tupi++) { if (tupi == parameters->dim) goto L1; - TemplateParameter *t = (TemplateParameter *)parameters->data[tupi]; + TemplateParameter *t = parameters->tdata()[tupi]; TemplateTupleParameter *tup = t->isTemplateTupleParameter(); if (tup && tup->ident->equals(tid->ident)) break; @@ -2186,11 +2198,11 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para /* The types of the function arguments [nfparams - 1 .. nfargs] * now form the tuple argument. */ - int tuple_dim = nfargs - (nfparams - 1); + size_t tuple_dim = nfargs - (nfparams - 1); /* See if existing tuple, and whether it matches or not */ - Object *o = (Object *)dedtypes->data[tupi]; + Object *o = dedtypes->tdata()[tupi]; if (o) { // Existing deduced argument must be a tuple, and must match Tuple *t = isTuple(o); @@ -2198,7 +2210,7 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para return MATCHnomatch; for (size_t i = 0; i < tuple_dim; i++) { Parameter *arg = Parameter::getNth(this->parameters, nfparams - 1 + i); - if (!arg->type->equals((Object *)t->objects.data[i])) + if (!arg->type->equals(t->objects.tdata()[i])) return MATCHnomatch; } } @@ -2208,9 +2220,9 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para t->objects.setDim(tuple_dim); for (size_t i = 0; i < tuple_dim; i++) { Parameter *arg = Parameter::getNth(this->parameters, nfparams - 1 + i); - t->objects.data[i] = (void *)arg->type; + t->objects.tdata()[i] = arg->type; } - dedtypes->data[tupi] = (void *)t; + dedtypes->tdata()[tupi] = t; } nfparams--; // don't consider the last parameter for type deduction goto L2; @@ -2239,10 +2251,10 @@ MATCH TypeIdentifier::deduceType(Scope *sc, Type *tparam, TemplateParameters *pa { TypeIdentifier *tp = (TypeIdentifier *)tparam; - for (int i = 0; i < idents.dim; i++) + for (size_t i = 0; i < idents.dim; i++) { - Identifier *id1 = (Identifier *)idents.data[i]; - Identifier *id2 = (Identifier *)tp->idents.data[i]; + Identifier *id1 = idents.tdata()[i]; + Identifier *id2 = tp->idents.tdata()[i]; if (!id1->equals(id2)) return MATCHnomatch; @@ -2290,7 +2302,7 @@ MATCH TypeInstance::deduceType(Scope *sc, } goto Lnomatch; } - TemplateParameter *tpx = (TemplateParameter *)parameters->data[i]; + TemplateParameter *tpx = parameters->tdata()[i]; // This logic duplicates tpx->matchArg() TemplateAliasParameter *ta = tpx->isTemplateAliasParameter(); if (!ta) @@ -2300,14 +2312,14 @@ MATCH TypeInstance::deduceType(Scope *sc, goto Lnomatch; if (ta->specAlias && sa != ta->specAlias) goto Lnomatch; - if (dedtypes->data[i]) + if (dedtypes->tdata()[i]) { // Must match already deduced symbol - Object *s = (Object *)dedtypes->data[i]; + Object *s = dedtypes->tdata()[i]; if (s != sa) goto Lnomatch; } - dedtypes->data[i] = sa; + dedtypes->tdata()[i] = sa; } } else if (tempinst->tempdecl != tp->tempinst->tempdecl) @@ -2315,22 +2327,22 @@ MATCH TypeInstance::deduceType(Scope *sc, L2: - for (int i = 0; 1; i++) + for (size_t i = 0; 1; i++) { //printf("\ttest: tempinst->tiargs[%d]\n", i); Object *o1; if (i < tempinst->tiargs->dim) - o1 = (Object *)tempinst->tiargs->data[i]; + o1 = tempinst->tiargs->tdata()[i]; else if (i < tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim) // Pick up default arg - o1 = (Object *)tempinst->tdtypes.data[i]; + o1 = tempinst->tdtypes.tdata()[i]; else break; if (i >= tp->tempinst->tiargs->dim) goto Lnomatch; - Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; + Object *o2 = tp->tempinst->tiargs->tdata()[i]; Type *t1 = isType(o1); Type *t2 = isType(o2); @@ -2376,19 +2388,19 @@ MATCH TypeInstance::deduceType(Scope *sc, /* Create tuple from remaining args */ Tuple *vt = new Tuple(); - int vtdim = tempinst->tiargs->dim - i; + size_t vtdim = tempinst->tiargs->dim - i; vt->objects.setDim(vtdim); for (size_t k = 0; k < vtdim; k++) - vt->objects.data[k] = (void *)tempinst->tiargs->data[i + k]; + vt->objects.tdata()[k] = tempinst->tiargs->tdata()[i + k]; - Tuple *v = (Tuple *)dedtypes->data[j]; + Tuple *v = (Tuple *)dedtypes->tdata()[j]; if (v) { if (!match(v, vt, tempinst->tempdecl, sc)) goto Lnomatch; } else - dedtypes->data[j] = vt; + dedtypes->tdata()[j] = vt; break; //return MATCHexact; } @@ -2417,12 +2429,12 @@ MATCH TypeInstance::deduceType(Scope *sc, L1: if (j == -1) goto Lnomatch; - TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; + TemplateParameter *tp = parameters->tdata()[j]; // BUG: use tp->matchArg() instead of the following TemplateValueParameter *tv = tp->isTemplateValueParameter(); if (!tv) goto Lnomatch; - Expression *e = (Expression *)dedtypes->data[j]; + Expression *e = (Expression *)dedtypes->tdata()[j]; if (e) { if (!e1->equals(e)) @@ -2433,7 +2445,7 @@ MATCH TypeInstance::deduceType(Scope *sc, MATCH m = (MATCH)e1->implicitConvTo(vt); if (!m) goto Lnomatch; - dedtypes->data[j] = e1; + dedtypes->tdata()[j] = e1; } } else if (s1 && t2 && t2->ty == Tident) @@ -2441,12 +2453,12 @@ MATCH TypeInstance::deduceType(Scope *sc, j = templateParameterLookup(t2, parameters); if (j == -1) goto Lnomatch; - TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; + TemplateParameter *tp = parameters->tdata()[j]; // BUG: use tp->matchArg() instead of the following TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); if (!ta) goto Lnomatch; - Dsymbol *s = (Dsymbol *)dedtypes->data[j]; + Dsymbol *s = (Dsymbol *)dedtypes->tdata()[j]; if (s) { if (!s1->equals(s)) @@ -2454,7 +2466,7 @@ MATCH TypeInstance::deduceType(Scope *sc, } else { - dedtypes->data[j] = s1; + dedtypes->tdata()[j] = s1; } } else if (s1 && s2) @@ -2499,7 +2511,7 @@ MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame */ TypeInstance *tpi = (TypeInstance *)tparam; if (tpi->idents.dim) - { Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1]; + { Identifier *id = tpi->idents.tdata()[tpi->idents.dim - 1]; if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id)) { Type *tparent = sym->parent->getType(); @@ -2581,7 +2593,7 @@ void deduceBaseClassParameters(BaseClass *b, // Make a temporary copy of dedtypes so we don't destroy it Objects *tmpdedtypes = new Objects(); tmpdedtypes->setDim(dedtypes->dim); - memcpy(tmpdedtypes->data, dedtypes->data, dedtypes->dim * sizeof(void *)); + memcpy(tmpdedtypes->tdata(), dedtypes->tdata(), dedtypes->dim * sizeof(void *)); TypeInstance *t = new TypeInstance(0, parti); MATCH m = t->deduceType(sc, tparam, parameters, tmpdedtypes); @@ -2589,13 +2601,13 @@ void deduceBaseClassParameters(BaseClass *b, { // If this is the first ever match, it becomes our best estimate if (numBaseClassMatches==0) - memcpy(best->data, tmpdedtypes->data, tmpdedtypes->dim * sizeof(void *)); + memcpy(best->tdata(), tmpdedtypes->tdata(), tmpdedtypes->dim * sizeof(void *)); else for (size_t k = 0; k < tmpdedtypes->dim; ++k) { // If we've found more than one possible type for a parameter, // mark it as unknown. - if (tmpdedtypes->data[k] != best->data[k]) - best->data[k] = dedtypes->data[k]; + if (tmpdedtypes->tdata()[k] != best->tdata()[k]) + best->tdata()[k] = dedtypes->tdata()[k]; } ++numBaseClassMatches; } @@ -2637,7 +2649,7 @@ MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *paramet */ TypeInstance *tpi = (TypeInstance *)tparam; if (tpi->idents.dim) - { Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1]; + { Identifier *id = tpi->idents.tdata()[tpi->idents.dim - 1]; if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id)) { Type *tparent = sym->parent->getType(); @@ -2673,7 +2685,7 @@ MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *paramet while(s && s->baseclasses->dim > 0) { // Test the base class - deduceBaseClassParameters((BaseClass *)(s->baseclasses->data[0]), + deduceBaseClassParameters((s->baseclasses->tdata()[0]), sc, tparam, parameters, dedtypes, best, numBaseClassMatches); @@ -2684,14 +2696,14 @@ MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *paramet deduceBaseClassParameters(b, sc, tparam, parameters, dedtypes, best, numBaseClassMatches); } - s = ((BaseClass *)(s->baseclasses->data[0]))->base; + s = ((s->baseclasses->tdata()[0]))->base; } if (numBaseClassMatches == 0) return MATCHnomatch; // If we got at least one match, copy the known types into dedtypes - memcpy(dedtypes->data, best->data, best->dim * sizeof(void *)); + memcpy(dedtypes->tdata(), best->tdata(), best->dim * sizeof(void *)); return MATCHconvert; } @@ -2833,7 +2845,7 @@ Lnomatch: */ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, - int i, TemplateParameters *parameters, Objects *dedtypes, + size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags) { //printf("TemplateTypeParameter::matchArg()\n"); @@ -2843,14 +2855,14 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, Type *ta; if (i < tiargs->dim) - oarg = (Object *)tiargs->data[i]; + oarg = tiargs->tdata()[i]; else { // Get default argument instead oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced - oarg = (Object *)dedtypes->data[i]; + oarg = dedtypes->tdata()[i]; if (!oarg) { goto Lnomatch; @@ -2867,7 +2879,7 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, } //printf("ta is %s\n", ta->toChars()); - t = (Type *)dedtypes->data[i]; + t = (Type *)dedtypes->tdata()[i]; if (specType) { @@ -2880,12 +2892,13 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, if (m2 < m) m = m2; - t = (Type *)dedtypes->data[i]; + t = (Type *)dedtypes->tdata()[i]; } else { // So that matches with specializations are better - m = MATCHconvert; + if (!(flags & 1)) + m = MATCHconvert; /* This is so that: * template Foo(T), Foo!(const int), => ta == int @@ -2906,7 +2919,7 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, if (!t) { - dedtypes->data[i] = ta; + dedtypes->tdata()[i] = ta; t = ta; } *psparam = new AliasDeclaration(loc, ident, t); @@ -3111,7 +3124,7 @@ Lnomatch: } MATCH TemplateAliasParameter::matchArg(Scope *sc, - Objects *tiargs, int i, TemplateParameters *parameters, + Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags) { @@ -3123,14 +3136,14 @@ MATCH TemplateAliasParameter::matchArg(Scope *sc, //printf("TemplateAliasParameter::matchArg()\n"); if (i < tiargs->dim) - oarg = (Object *)tiargs->data[i]; + oarg = tiargs->tdata()[i]; else { // Get default argument instead oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced - oarg = (Object *)dedtypes->data[i]; + oarg = dedtypes->tdata()[i]; if (!oarg) goto Lnomatch; } @@ -3172,14 +3185,14 @@ MATCH TemplateAliasParameter::matchArg(Scope *sc, if (sa != specAlias) goto Lnomatch; } - else if (dedtypes->data[i]) + else if (dedtypes->tdata()[i]) { // Must match already deduced symbol - Object *s = (Object *)dedtypes->data[i]; + Object *si = dedtypes->tdata()[i]; - if (!sa || s != sa) + if (!sa || si != sa) goto Lnomatch; } - dedtypes->data[i] = sa; + dedtypes->tdata()[i] = sa; s = isDsymbol(sa); if (s) @@ -3218,8 +3231,8 @@ void TemplateAliasParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring("alias "); if (specType) - { HdrGenState hgs; - specType->toCBuffer(buf, ident, &hgs); + { HdrGenState hgs1; + specType->toCBuffer(buf, ident, &hgs1); } else buf->writestring(ident->toChars()); @@ -3376,7 +3389,7 @@ Lnomatch: MATCH TemplateValueParameter::matchArg(Scope *sc, - Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, + Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags) { //printf("TemplateValueParameter::matchArg()\n"); @@ -3388,14 +3401,14 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, Object *oarg; if (i < tiargs->dim) - oarg = (Object *)tiargs->data[i]; + oarg = tiargs->tdata()[i]; else { // Get default argument instead oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced - oarg = (Object *)dedtypes->data[i]; + oarg = dedtypes->tdata()[i]; if (!oarg) goto Lnomatch; } @@ -3433,14 +3446,14 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, if (!ei->equals(e)) goto Lnomatch; } - else if (dedtypes->data[i]) + else if (dedtypes->tdata()[i]) { // Must match already deduced value - Expression *e = (Expression *)dedtypes->data[i]; + Expression *e = (Expression *)dedtypes->tdata()[i]; if (!ei || !ei->equals(e)) goto Lnomatch; } -Lmatch: + //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty); vt = valType->semantic(0, sc); //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars()); @@ -3452,7 +3465,7 @@ Lmatch: if (!m) goto Lnomatch; } - dedtypes->data[i] = ei; + dedtypes->tdata()[i] = ei; init = new ExpInitializer(loc, ei); sparam = new VarDeclaration(loc, vt, ident, init); @@ -3572,12 +3585,11 @@ int TemplateTupleParameter::overloadMatch(TemplateParameter *tp) return 1; // match } -Lnomatch: return 0; } MATCH TemplateTupleParameter::matchArg(Scope *sc, - Objects *tiargs, int i, TemplateParameters *parameters, + Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags) { @@ -3589,11 +3601,11 @@ MATCH TemplateTupleParameter::matchArg(Scope *sc, assert(i + 1 == dedtypes->dim); // must be the last one Tuple *ovar; - if (dedtypes->data[i] && isTuple((Object *)dedtypes->data[i])) + if (dedtypes->tdata()[i] && isTuple(dedtypes->tdata()[i])) // It was already been deduced - ovar = isTuple((Object *)dedtypes->data[i]); - else if (i + 1 == tiargs->dim && isTuple((Object *)tiargs->data[i])) - ovar = isTuple((Object *)tiargs->data[i]); + ovar = isTuple(dedtypes->tdata()[i]); + else if (i + 1 == tiargs->dim && isTuple(tiargs->tdata()[i])) + ovar = isTuple(tiargs->tdata()[i]); else { ovar = new Tuple(); @@ -3603,11 +3615,11 @@ MATCH TemplateTupleParameter::matchArg(Scope *sc, //printf("i = %d, tiargs->dim = %d\n", i, tiargs->dim); ovar->objects.setDim(tiargs->dim - i); for (size_t j = 0; j < ovar->objects.dim; j++) - ovar->objects.data[j] = tiargs->data[i + j]; + ovar->objects.tdata()[j] = tiargs->tdata()[i + j]; } } *psparam = new TupleDeclaration(loc, ident, &ovar->objects); - dedtypes->data[i] = (void *)ovar; + dedtypes->tdata()[i] = ovar; return MATCHexact; } @@ -3619,12 +3631,12 @@ void TemplateTupleParameter::print(Object *oarg, Object *oded) assert(v); //printf("|%d| ", v->objects.dim); - for (int i = 0; i < v->objects.dim; i++) + for (size_t i = 0; i < v->objects.dim; i++) { if (i) printf(", "); - Object *o = (Object *)v->objects.data[i]; + Object *o = v->objects.tdata()[i]; Dsymbol *sa = isDsymbol(o); if (sa) @@ -3745,7 +3757,7 @@ Objects *TemplateInstance::arraySyntaxCopy(Objects *objs) a->setDim(objs->dim); for (size_t i = 0; i < objs->dim; i++) { - a->data[i] = objectSyntaxCopy((Object *)objs->data[i]); + a->tdata()[i] = objectSyntaxCopy(objs->tdata()[i]); } } return a; @@ -3831,7 +3843,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) assert((size_t)tempdecl->scope > 0x10000); // Deduce tdtypes tdtypes.setDim(tempdecl->parameters->dim); - if (!tempdecl->matchWithInstance(this, &tdtypes, 2)) + if (!tempdecl->matchWithInstance(this, &tdtypes, fargs, 2)) { error("incompatible arguments for template instantiation"); inst = this; @@ -3852,7 +3864,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) tempdecl = findTemplateDeclaration(sc); if (tempdecl) - tempdecl = findBestMatch(sc); + tempdecl = findBestMatch(sc, fargs); if (!tempdecl || global.errors) { inst = this; //printf("error return %p, %d\n", tempdecl, global.errors); @@ -3872,7 +3884,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) for (size_t i = 0; i < tempdecl->instances.dim; i++) { - TemplateInstance *ti = (TemplateInstance *)tempdecl->instances.data[i]; + TemplateInstance *ti = tempdecl->instances.tdata()[i]; #if LOG printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars()); #endif @@ -3901,9 +3913,9 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) { Parameters *fparameters = fd->getParameters(NULL); size_t nfparams = Parameter::dim(fparameters); // Num function parameters - for (int i = 0; i < nfparams && i < fargs->dim; i++) - { Parameter *fparam = Parameter::getNth(fparameters, i); - Expression *farg = (Expression *)fargs->data[i]; + for (size_t j = 0; j < nfparams && j < fargs->dim; j++) + { Parameter *fparam = Parameter::getNth(fparameters, j); + Expression *farg = fargs->tdata()[j]; if (fparam->storageClass & STCauto) // if "auto ref" { if (farg->isLvalue()) @@ -3953,10 +3965,16 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) //printf("parent = '%s'\n", parent->kind()); // Add 'this' to the enclosing scope's members[] so the semantic routines - // will get called on the instance members + // will get called on the instance members. Store the place we added it to + // in target_symbol_list(_idx) so we can remove it later if we encounter + // an error. #if 1 int dosemantic3 = 0; - { Array *a; + Dsymbols *target_symbol_list = NULL; + int target_symbol_list_idx; + + if (!sc->parameterSpecialization) + { Dsymbols *a; Scope *scx = sc; #if 0 @@ -3995,10 +4013,12 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) { if (i == a->dim) { + target_symbol_list = a; + target_symbol_list_idx = i; a->push(this); break; } - if (this == (Dsymbol *)a->data[i]) // if already in Array + if (this == a->tdata()[i]) // if already in Array break; } } @@ -4033,9 +4053,9 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) // parent = scope->scopesym; symtab = new DsymbolTable(); int memnum = 0; - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; #if LOG printf("\t[%d] adding member '%s' %p kind %s to '%s', memnum = %d\n", i, s->toChars(), s, s->kind(), this->toChars(), memnum); #endif @@ -4114,9 +4134,9 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) error("recursive expansion"); fatal(); } - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars()); //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars()); // if (isnested) @@ -4142,7 +4162,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) * or semantic3() yet. */ for (size_t i = 0; i < Module::deferred.dim; i++) - { Dsymbol *sd = (Dsymbol *)Module::deferred.data[i]; + { Dsymbol *sd = Module::deferred.tdata()[i]; if (sd->parent == this) { @@ -4206,14 +4226,16 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) } errors = 1; if (global.gag) - { // Try to reset things so we can try again later to instantiate it - //printf("remove %s\n", toChars()); + { + // Errors are gagged, so remove the template instance from the + // instance/symbol lists we added it to and reset our state to + // finish clean and so we can try to instantiate it again later + // (see bugzilla 4302 and 6602). tempdecl->instances.remove(tempdecl_instance_idx); - if (!(sc->flags & SCOPEstaticif)) - { // Bugzilla 4302 for discussion - semanticRun = 0; - inst = NULL; - } + if (target_symbol_list) + target_symbol_list->remove(target_symbol_list_idx); + semanticRun = 0; + inst = NULL; } } @@ -4245,13 +4267,12 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f return; for (size_t j = 0; j < tiargs->dim; j++) { - - Object *o = (Object *)tiargs->data[j]; + Object *o = tiargs->tdata()[j]; Type *ta = isType(o); Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); - //printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta); + //printf("1: tiargs->tdata()[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta); if (ta) { //printf("type %s\n", ta->toChars()); @@ -4269,10 +4290,10 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f ea = ea->optimize(WANTvalue); else if (ea->op != TOKvar) ea = ea->optimize(WANTvalue | WANTinterpret); - tiargs->data[j] = ea; + tiargs->tdata()[j] = ea; } else if (sa) - { tiargs->data[j] = sa; + { tiargs->tdata()[j] = sa; TupleDeclaration *d = sa->toAlias()->isTupleDeclaration(); if (d) { @@ -4293,19 +4314,19 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f if (dim) { tiargs->reserve(dim); for (size_t i = 0; i < dim; i++) - { Parameter *arg = (Parameter *)tt->arguments->data[i]; + { Parameter *arg = tt->arguments->tdata()[i]; tiargs->insert(j + i, arg->type); } } j--; } else - tiargs->data[j] = ta; + tiargs->tdata()[j] = ta; } else { assert(global.errors); - tiargs->data[j] = Type::terror; + tiargs->tdata()[j] = Type::terror; } } else if (ea) @@ -4320,7 +4341,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f ea = ea->optimize(WANTvalue); else if (ea->op != TOKvar) ea = ea->optimize(WANTvalue | WANTinterpret); - tiargs->data[j] = ea; + tiargs->tdata()[j] = ea; if (ea->op == TOKtype) { ta = ea->type; goto Ltype; @@ -4333,7 +4354,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f if (dim) { tiargs->reserve(dim); for (size_t i = 0; i < dim; i++) - tiargs->insert(j + i, te->exps->data[i]); + tiargs->insert(j + i, te->exps->tdata()[i]); } j--; } @@ -4348,13 +4369,13 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f { assert(0); } - //printf("1: tiargs->data[%d] = %p\n", j, tiargs->data[j]); + //printf("1: tiargs->tdata()[%d] = %p\n", j, tiargs->tdata()[j]); } #if 0 printf("-TemplateInstance::semanticTiargs()\n"); for (size_t j = 0; j < tiargs->dim; j++) { - Object *o = (Object *)tiargs->data[j]; + Object *o = tiargs->tdata()[j]; Type *ta = isType(o); Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); @@ -4381,7 +4402,6 @@ TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) Dsymbol *s; Dsymbol *scopesym; Identifier *id; - int i; id = name; s = sc->search(loc, id, &scopesym); @@ -4400,8 +4420,8 @@ TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) OverloadSet *os = s->isOverloadSet(); if (os) { s = NULL; - for (int i = 0; i < os->a.dim; i++) - { Dsymbol *s2 = (Dsymbol *)os->a.data[i]; + for (size_t i = 0; i < os->a.dim; i++) + { Dsymbol *s2 = os->a.tdata()[i]; if (s2->isTemplateDeclaration()) { if (s) @@ -4491,7 +4511,7 @@ TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) return tempdecl; } -TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) +TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs) { /* Since there can be multiple TemplateDeclaration's with the same * name, look for the best match. @@ -4525,7 +4545,7 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) { MATCH m; -//if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]); +//if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->tdata()[0]); // If more arguments than parameters, // then this is no match. @@ -4538,7 +4558,7 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) dedtypes.setDim(td->parameters->dim); dedtypes.zero(); assert(td->semanticRun); - m = td->matchWithInstance(this, &dedtypes, 0); + m = td->matchWithInstance(this, &dedtypes, fargs, 0); //printf("matchWithInstance = %d\n", m); if (!m) // no match at all continue; @@ -4550,8 +4570,8 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) { // Disambiguate by picking the most specialized TemplateDeclaration - MATCH c1 = td->leastAsSpecialized(td_best); - MATCH c2 = td_best->leastAsSpecialized(td); + MATCH c1 = td->leastAsSpecialized(td_best, fargs); + MATCH c2 = td_best->leastAsSpecialized(td, fargs); //printf("c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) @@ -4575,7 +4595,7 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) td_best = td; m_best = m; tdtypes.setDim(dedtypes.dim); - memcpy(tdtypes.data, dedtypes.data, tdtypes.dim * sizeof(void *)); + memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.dim * sizeof(void *)); continue; } @@ -4604,9 +4624,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) /* Cast any value arguments to be same type as value parameter */ for (size_t i = 0; i < tiargs->dim; i++) - { Object *o = (Object *)tiargs->data[i]; + { Object *o = tiargs->tdata()[i]; Expression *ea = isExpression(o); // value argument - TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; + TemplateParameter *tp = tempdecl->parameters->tdata()[i]; assert(tp); TemplateValueParameter *tvp = tp->isTemplateValueParameter(); if (tvp) @@ -4614,7 +4634,7 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc) assert(ea); ea = ea->castTo(tvp->valType); ea = ea->optimize(WANTvalue | WANTinterpret); - tiargs->data[i] = (Object *)ea; + tiargs->tdata()[i] = (Object *)ea; } } #endif @@ -4639,7 +4659,7 @@ int TemplateInstance::hasNestedArgs(Objects *args) * symbol that is on the stack. */ for (size_t i = 0; i < args->dim; i++) - { Object *o = (Object *)args->data[i]; + { Object *o = args->tdata()[i]; Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); Tuple *va = isTuple(o); @@ -4723,8 +4743,8 @@ Identifier *TemplateInstance::genIdent(Objects *args) //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); char *id = tempdecl->ident->toChars(); buf.printf("__T%zu%s", strlen(id), id); - for (int i = 0; i < args->dim; i++) - { Object *o = (Object *)args->data[i]; + for (size_t i = 0; i < args->dim; i++) + { Object *o = args->tdata()[i]; Type *ta = isType(o); Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); @@ -4745,9 +4765,6 @@ Identifier *TemplateInstance::genIdent(Objects *args) } else if (ea) { - Lea: - sinteger_t v; - real_t r; // Don't interpret it yet, it might actually be an alias ea = ea->optimize(WANTvalue); if (ea->op == TOKvar) @@ -4781,7 +4798,7 @@ Identifier *TemplateInstance::genIdent(Objects *args) buf.writestring(ea->type->deco); #else // Use type of parameter, not type of argument - TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; + TemplateParameter *tp = tempdecl->parameters->tdata()[i]; assert(tp); TemplateValueParameter *tvp = tp->isTemplateValueParameter(); assert(tvp); @@ -4845,11 +4862,11 @@ Identifier *TemplateInstance::genIdent(Objects *args) void TemplateInstance::declareParameters(Scope *sc) { //printf("TemplateInstance::declareParameters()\n"); - for (int i = 0; i < tdtypes.dim; i++) + for (size_t i = 0; i < tdtypes.dim; i++) { - TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; - //Object *o = (Object *)tiargs->data[i]; - Object *o = (Object *)tdtypes.data[i]; // initializer for tp + TemplateParameter *tp = tempdecl->parameters->tdata()[i]; + //Object *o = tiargs->tdata()[i]; + Object *o = tdtypes.tdata()[i]; // initializer for tp //printf("\ttdtypes[%d] = %p\n", i, o); tempdecl->declareParameter(sc, tp, o); @@ -4921,7 +4938,7 @@ void TemplateInstance::semantic2(Scope *sc) sc->tinst = this; for (i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; #if LOG printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind()); #endif @@ -4950,9 +4967,9 @@ void TemplateInstance::semantic3(Scope *sc) sc = sc->push(argsym); sc = sc->push(this); sc->tinst = this; - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic3(sc); } sc = sc->pop(); @@ -4972,7 +4989,7 @@ void TemplateInstance::printInstantiationTrace() if (global.gag) return; - const int max_shown = 6; + const unsigned max_shown = 6; const char format[] = "%s: instantiated from here: %s\n"; // determine instantiation depth and number of recursive instantiations @@ -5025,7 +5042,7 @@ void TemplateInstance::printInstantiationTrace() { // Even after collapsing the recursions, the depth is too deep. // Just display the first few and last few instantiations. - size_t i = 0; + unsigned i = 0; for (TemplateInstance *cur = this; cur; cur = cur->tinst) { if (i == max_shown / 2) @@ -5051,9 +5068,9 @@ void TemplateInstance::toObjFile(int multiobj) obj_append(this); else { - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->toObjFile(multiobj); } } @@ -5069,9 +5086,9 @@ void TemplateInstance::inlineScan() #endif if (!errors && members) { - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->inlineScan(); } } @@ -5094,7 +5111,7 @@ void TemplateInstance::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { if (i) buf->writeByte(','); - Object *oarg = (Object *)args->data[i]; + Object *oarg = args->tdata()[i]; ObjectToCBuffer(buf, hgs, oarg); } nest--; @@ -5197,8 +5214,8 @@ void TemplateInstance::printInstantiationTrace() /* ======================== TemplateMixin ================================ */ TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, - Array *idents, Objects *tiargs) - : TemplateInstance(loc, (Identifier *)idents->data[idents->dim - 1]) + Identifiers *idents, Objects *tiargs) + : TemplateInstance(loc, idents->tdata()[idents->dim - 1]) { //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); this->ident = ident; @@ -5210,11 +5227,11 @@ TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) { TemplateMixin *tm; - Array *ids = new Array(); + Identifiers *ids = new Identifiers(); ids->setDim(idents->dim); - for (int i = 0; i < idents->dim; i++) + for (size_t i = 0; i < idents->dim; i++) { // Matches TypeQualified::syntaxCopyHelper() - Identifier *id = (Identifier *)idents->data[i]; + Identifier *id = idents->tdata()[i]; if (id->dyncast() == DYNCAST_DSYMBOL) { TemplateInstance *ti = (TemplateInstance *)id; @@ -5222,7 +5239,7 @@ Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) ti = (TemplateInstance *)ti->syntaxCopy(NULL); id = (Identifier *)ti; } - ids->data[i] = id; + ids->tdata()[i] = id; } tm = new TemplateMixin(loc, ident, @@ -5273,7 +5290,7 @@ void TemplateMixin::semantic(Scope *sc) // Follow qualifications to find the TemplateDeclaration if (!tempdecl) { Dsymbol *s; - int i; + size_t i; Identifier *id; if (tqual) @@ -5283,7 +5300,7 @@ void TemplateMixin::semantic(Scope *sc) else { i = 1; - id = (Identifier *)idents->data[0]; + id = idents->tdata()[0]; switch (id->dyncast()) { case DYNCAST_IDENTIFIER: @@ -5306,7 +5323,7 @@ void TemplateMixin::semantic(Scope *sc) { if (!s) break; - id = (Identifier *)idents->data[i]; + id = idents->tdata()[i]; s = s->searchX(loc, sc, id); } if (!s) @@ -5357,7 +5374,7 @@ void TemplateMixin::semantic(Scope *sc) if (errors) return; - tempdecl = findBestMatch(sc); + tempdecl = findBestMatch(sc, NULL); if (!tempdecl) { inst = this; return; // error recovery @@ -5383,12 +5400,12 @@ void TemplateMixin::semantic(Scope *sc) if (tiargs->dim != tm->tiargs->dim) continue; - for (int i = 0; i < tiargs->dim; i++) - { Object *o = (Object *)tiargs->data[i]; + for (size_t i = 0; i < tiargs->dim; i++) + { Object *o = tiargs->tdata()[i]; Type *ta = isType(o); Expression *ea = isExpression(o); Dsymbol *sa = isDsymbol(o); - Object *tmo = (Object *)tm->tiargs->data[i]; + Object *tmo = tm->tiargs->tdata()[i]; if (ta) { Type *tmta = isType(tmo); @@ -5455,7 +5472,7 @@ void TemplateMixin::semantic(Scope *sc) for (unsigned i = 0; i < members->dim; i++) { Dsymbol *s; - s = (Dsymbol *)members->data[i]; + s = members->tdata()[i]; s->addMember(argscope, this, i); //sc->insert(s); //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); @@ -5479,9 +5496,9 @@ void TemplateMixin::semantic(Scope *sc) fatal(); } - for (int i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic(sc2); } @@ -5522,8 +5539,7 @@ void TemplateMixin::semantic(Scope *sc) } void TemplateMixin::semantic2(Scope *sc) -{ int i; - +{ if (semanticRun >= 2) return; semanticRun = 2; @@ -5535,9 +5551,9 @@ void TemplateMixin::semantic2(Scope *sc) assert(sc); sc = sc->push(argsym); sc = sc->push(this); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; #if LOG printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind()); #endif @@ -5552,8 +5568,7 @@ void TemplateMixin::semantic2(Scope *sc) } void TemplateMixin::semantic3(Scope *sc) -{ int i; - +{ if (semanticRun >= 3) return; semanticRun = 3; @@ -5564,9 +5579,9 @@ void TemplateMixin::semantic3(Scope *sc) { sc = sc->push(argsym); sc = sc->push(this); - for (i = 0; i < members->dim; i++) + for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; s->semantic3(sc); } sc = sc->pop(); @@ -5594,7 +5609,7 @@ int TemplateMixin::hasPointers() //printf("TemplateMixin::hasPointers() %s\n", toChars()); for (size_t i = 0; i < members->dim; i++) { - Dsymbol *s = (Dsymbol *)members->data[i]; + Dsymbol *s = members->tdata()[i]; //printf(" s = %s %s\n", s->kind(), s->toChars()); if (s->hasPointers()) { @@ -5620,8 +5635,8 @@ void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring("mixin "); - for (int i = 0; i < idents->dim; i++) - { Identifier *id = (Identifier *)idents->data[i]; + for (size_t i = 0; i < idents->dim; i++) + { Identifier *id = idents->tdata()[i]; if (i) buf->writeByte('.'); @@ -5630,10 +5645,10 @@ void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writestring("!("); if (tiargs) { - for (int i = 0; i < tiargs->dim; i++) + for (size_t i = 0; i < tiargs->dim; i++) { if (i) buf->writebyte(','); - Object *oarg = (Object *)tiargs->data[i]; + Object *oarg = tiargs->tdata()[i]; Type *t = isType(oarg); Expression *e = isExpression(oarg); Dsymbol *s = isDsymbol(oarg); diff --git a/dmd2/template.h b/dmd2/template.h index 154592f7..436a86f6 100644 --- a/dmd2/template.h +++ b/dmd2/template.h @@ -56,7 +56,7 @@ struct TemplateDeclaration : ScopeDsymbol TemplateParameters *origParameters; // originals for Ddoc Expression *constraint; - Array instances; // array of TemplateInstance's + TemplateInstances instances; // array of TemplateInstance's TemplateDeclaration *overnext; // next overloaded TemplateDeclaration TemplateDeclaration *overroot; // first in overnext list @@ -88,8 +88,8 @@ struct TemplateDeclaration : ScopeDsymbol void toJsonBuffer(OutBuffer *buf); // void toDocBuffer(OutBuffer *buf); - MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); - MATCH leastAsSpecialized(TemplateDeclaration *td2); + MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag); + MATCH leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs); MATCH deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs); FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0); @@ -100,7 +100,7 @@ struct TemplateDeclaration : ScopeDsymbol TemplateTupleParameter *isVariadic(); int isOverloadable(); - void makeParamNamesVisibleInConstraint(Scope *paramscope); + void makeParamNamesVisibleInConstraint(Scope *paramscope, Expressions *fargs); #if IN_LLVM // LDC std::string intrinsicName; @@ -150,7 +150,7 @@ struct TemplateParameter /* Match actual argument against parameter. */ - virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0; + virtual MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0; /* Create dummy argument based on parameter. */ @@ -176,7 +176,7 @@ struct TemplateTypeParameter : TemplateParameter Object *specialization(); Object *defaultArg(Loc loc, Scope *sc); int overloadMatch(TemplateParameter *); - MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); + MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); void *dummyArg(); }; @@ -220,7 +220,7 @@ struct TemplateValueParameter : TemplateParameter Object *specialization(); Object *defaultArg(Loc loc, Scope *sc); int overloadMatch(TemplateParameter *); - MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); + MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); void *dummyArg(); }; @@ -247,7 +247,7 @@ struct TemplateAliasParameter : TemplateParameter Object *specialization(); Object *defaultArg(Loc loc, Scope *sc); int overloadMatch(TemplateParameter *); - MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); + MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); void *dummyArg(); }; @@ -268,7 +268,7 @@ struct TemplateTupleParameter : TemplateParameter Object *specialization(); Object *defaultArg(Loc loc, Scope *sc); int overloadMatch(TemplateParameter *); - MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); + MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags); void *dummyArg(); }; @@ -280,7 +280,7 @@ struct TemplateInstance : ScopeDsymbol * tiargs = args */ Identifier *name; - //Array idents; + //Identifiers idents; Objects *tiargs; // Array of Types/Expressions of template // instance arguments [int*, char, 10*10] @@ -334,7 +334,7 @@ struct TemplateInstance : ScopeDsymbol static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags); void semanticTiargs(Scope *sc); TemplateDeclaration *findTemplateDeclaration(Scope *sc); - TemplateDeclaration *findBestMatch(Scope *sc); + TemplateDeclaration *findBestMatch(Scope *sc, Expressions *fargs); void declareParameters(Scope *sc); int hasNestedArgs(Objects *tiargs); Identifier *genIdent(Objects *args); @@ -353,10 +353,10 @@ struct TemplateInstance : ScopeDsymbol struct TemplateMixin : TemplateInstance { - Array *idents; + Identifiers *idents; Type *tqual; - TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs); + TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Identifiers *idents, Objects *tiargs); Dsymbol *syntaxCopy(Dsymbol *s); void semantic(Scope *sc); void semantic2(Scope *sc); diff --git a/dmd2/traits.c b/dmd2/traits.c index b085b0ed..86e34a15 100644 --- a/dmd2/traits.c +++ b/dmd2/traits.c @@ -82,13 +82,11 @@ Expression *TraitsExp::semantic(Scope *sc) TemplateInstance::semanticTiargs(loc, sc, args, 1); } size_t dim = args ? args->dim : 0; - Object *o; Declaration *d; - FuncDeclaration *f; #define ISTYPE(cond) \ for (size_t i = 0; i < dim; i++) \ - { Type *t = getType((Object *)args->data[i]); \ + { Type *t = getType(args->tdata()[i]); \ if (!t) \ goto Lfalse; \ if (!(cond)) \ @@ -100,7 +98,7 @@ Expression *TraitsExp::semantic(Scope *sc) #define ISDSYMBOL(cond) \ for (size_t i = 0; i < dim; i++) \ - { Dsymbol *s = getDsymbol((Object *)args->data[i]); \ + { Dsymbol *s = getDsymbol(args->tdata()[i]); \ if (!s) \ goto Lfalse; \ if (!(cond)) \ @@ -150,19 +148,23 @@ Expression *TraitsExp::semantic(Scope *sc) } else if (ident == Id::isAbstractFunction) { + FuncDeclaration *f; ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isAbstract()) } else if (ident == Id::isVirtualFunction) { + FuncDeclaration *f; ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isVirtual()) } else if (ident == Id::isFinalFunction) { + FuncDeclaration *f; ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinal()) } #if DMDV2 else if (ident == Id::isStaticFunction) { + FuncDeclaration *f; ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && !f->needThis() && !f->isNested()) } else if (ident == Id::isRef) @@ -186,7 +188,7 @@ Expression *TraitsExp::semantic(Scope *sc) if (dim != 1) goto Ldimerror; - Object *o = (Object *)args->data[0]; + Object *o = args->tdata()[0]; Dsymbol *s = getDsymbol(o); if (!s || !s->ident) { @@ -200,7 +202,7 @@ Expression *TraitsExp::semantic(Scope *sc) { if (dim != 1) goto Ldimerror; - Object *o = (Object *)args->data[0]; + Object *o = args->tdata()[0]; Dsymbol *s = getDsymbol(o); if (s) s = s->toParent(); @@ -220,18 +222,18 @@ Expression *TraitsExp::semantic(Scope *sc) { if (dim != 2) goto Ldimerror; - Object *o = (Object *)args->data[0]; - Expression *e = isExpression((Object *)args->data[1]); + Object *o = args->tdata()[0]; + Expression *e = isExpression(args->tdata()[1]); if (!e) { error("expression expected as second argument of __traits %s", ident->toChars()); goto Lfalse; } e = e->optimize(WANTvalue | WANTinterpret); - if (e->op != TOKstring) + StringExp *se = e->toString(); + if (!se || se->length() == 0) { error("string expected as second argument of __traits %s instead of %s", ident->toChars(), e->toChars()); goto Lfalse; } - StringExp *se = (StringExp *)e; se = se->toUTF8(sc); if (se->sz != 1) { error("string must be chars"); @@ -312,7 +314,7 @@ Expression *TraitsExp::semantic(Scope *sc) { if (dim != 1) goto Ldimerror; - Object *o = (Object *)args->data[0]; + Object *o = args->tdata()[0]; Dsymbol *s = getDsymbol(o); ClassDeclaration *cd; if (!s || (cd = s->isClassDeclaration()) == NULL) @@ -326,7 +328,7 @@ Expression *TraitsExp::semantic(Scope *sc) { if (dim != 1) goto Ldimerror; - Object *o = (Object *)args->data[0]; + Object *o = args->tdata()[0]; Dsymbol *s = getDsymbol(o); ScopeDsymbol *sd; if (!s) @@ -341,10 +343,12 @@ Expression *TraitsExp::semantic(Scope *sc) } Expressions *exps = new Expressions; while (1) - { size_t dim = ScopeDsymbol::dim(sd->members); - for (size_t i = 0; i < dim; i++) + { size_t sddim = ScopeDsymbol::dim(sd->members); + for (size_t i = 0; i < sddim; i++) { Dsymbol *sm = ScopeDsymbol::getNth(sd->members, i); + if (!sm) + break; //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars()); if (sm->ident) { @@ -354,7 +358,7 @@ Expression *TraitsExp::semantic(Scope *sc) /* Skip if already present in exps[] */ for (size_t j = 0; j < exps->dim; j++) - { StringExp *se2 = (StringExp *)exps->data[j]; + { StringExp *se2 = (StringExp *)exps->tdata()[j]; if (strcmp(str, (char *)se2->string) == 0) goto Lnext; } @@ -393,7 +397,7 @@ Expression *TraitsExp::semantic(Scope *sc) goto Lfalse; for (size_t i = 0; i < dim; i++) - { Object *o = (Object *)args->data[i]; + { Object *o = args->tdata()[i]; Expression *e; unsigned errors = global.errors; @@ -433,8 +437,8 @@ Expression *TraitsExp::semantic(Scope *sc) if (dim != 2) goto Ldimerror; TemplateInstance::semanticTiargs(loc, sc, args, 0); - Object *o1 = (Object *)args->data[0]; - Object *o2 = (Object *)args->data[1]; + Object *o1 = args->tdata()[0]; + Object *o2 = args->tdata()[1]; Dsymbol *s1 = getDsymbol(o1); Dsymbol *s2 = getDsymbol(o2); @@ -482,10 +486,6 @@ Expression *TraitsExp::semantic(Scope *sc) return NULL; -Lnottype: - error("%s is not a type", o->toChars()); - goto Lfalse; - Ldimerror: error("wrong number of arguments %d", (int)dim); goto Lfalse; diff --git a/dmd2/version.c b/dmd2/version.c index c3a0e582..37f33c06 100644 --- a/dmd2/version.c +++ b/dmd2/version.c @@ -63,7 +63,7 @@ int DebugSymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) if (findCondition(m->debugidsNot, ident)) error("defined after use"); if (!m->debugids) - m->debugids = new Array(); + m->debugids = new Strings(); m->debugids->push(ident->toChars()); } } @@ -144,7 +144,7 @@ int VersionSymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) if (findCondition(m->versionidsNot, ident)) error("defined after use"); if (!m->versionids) - m->versionids = new Array(); + m->versionids = new Strings(); m->versionids->push(ident->toChars()); } } diff --git a/gen/cl_helpers.cpp b/gen/cl_helpers.cpp index 71e43dd7..0fdb1dde 100644 --- a/gen/cl_helpers.cpp +++ b/gen/cl_helpers.cpp @@ -62,12 +62,12 @@ void MultiSetter::operator=(bool val) { } -void ArrayAdapter::push_back(const char* cstr) { +void StringsAdapter::push_back(const char* cstr) { if (!cstr || !*cstr) error("Expected argument to '-%s'", name); if (!*arrp) - *arrp = new Array; + *arrp = new Strings; (*arrp)->push(mem.strdup(cstr)); } diff --git a/gen/cl_helpers.h b/gen/cl_helpers.h index 86518609..ec19e5c0 100644 --- a/gen/cl_helpers.h +++ b/gen/cl_helpers.h @@ -6,7 +6,13 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#if DMDV1 struct Array; +typedef Array Strings; +#else +template struct ArrayBase; +typedef ArrayBase Strings; +#endif namespace opts { namespace cl = llvm::cl; @@ -40,13 +46,13 @@ namespace opts { void operator=(bool val); }; - /// Helper class to fill Array with char* when given strings + /// Helper class to fill Strings with char* when given strings /// (Errors on empty strings) - class ArrayAdapter { + class StringsAdapter { const char* name; - Array** arrp; + Strings** arrp; public: - ArrayAdapter(const char* name_, Array*& arr) { + StringsAdapter(const char* name_, Strings*& arr) { name = name_; arrp = &arr; assert(name); diff --git a/gen/cl_options.cpp b/gen/cl_options.cpp index 7d500aa3..252fc5ca 100644 --- a/gen/cl_options.cpp +++ b/gen/cl_options.cpp @@ -154,8 +154,8 @@ static cl::opt unittest("unittest", cl::location(global.params.useUnitTests)); -static ArrayAdapter strImpPathStore("J", global.params.fileImppath); -static cl::list stringImportPaths("J", +static StringsAdapter strImpPathStore("J", global.params.fileImppath); +static cl::list stringImportPaths("J", cl::desc("Where to look for string imports"), cl::value_desc("path"), cl::location(strImpPathStore), @@ -205,8 +205,8 @@ cl::list versions("d-version", cl::CommaSeparated); -static ArrayAdapter linkSwitchStore("L", global.params.linkswitches); -static cl::list linkerSwitches("L", +static StringsAdapter linkSwitchStore("L", global.params.linkswitches); +static cl::list linkerSwitches("L", cl::desc("Pass to the linker"), cl::value_desc("linkerflag"), cl::location(linkSwitchStore), diff --git a/gen/main.cpp b/gen/main.cpp index b3b0cb83..b4894276 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -49,6 +49,10 @@ using namespace opts; #include "gen/configfile.h" +#if DMDV1 +typedef Array Modules; +#endif + extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv); extern void backend_init(); extern void backend_term(); @@ -57,22 +61,22 @@ static cl::opt noDefaultLib("nodefaultlib", cl::desc("Don't add a default library for linking implicitly"), cl::ZeroOrMore); -static ArrayAdapter impPathsStore("I", global.params.imppath); -static cl::list importPaths("I", +static StringsAdapter impPathsStore("I", global.params.imppath); +static cl::list importPaths("I", cl::desc("Where to look for imports"), cl::value_desc("path"), cl::location(impPathsStore), cl::Prefix); -static ArrayAdapter defaultLibStore("defaultlib", global.params.defaultlibnames); -static cl::list defaultlibs("defaultlib", +static StringsAdapter defaultLibStore("defaultlib", global.params.defaultlibnames); +static cl::list defaultlibs("defaultlib", cl::desc("Set default libraries for non-debug build"), cl::value_desc("lib,..."), cl::location(defaultLibStore), cl::CommaSeparated); -static ArrayAdapter debugLibStore("debuglib", global.params.debuglibnames); -static cl::list debuglibs("debuglib", +static StringsAdapter debugLibStore("debuglib", global.params.debuglibnames); +static cl::list debuglibs("debuglib", cl::desc("Set default libraries for debug build"), cl::value_desc("lib,..."), cl::location(debugLibStore), @@ -128,7 +132,7 @@ int main(int argc, char** argv) // stack trace on signals llvm::sys::PrintStackTraceOnErrorSignal(); - Array files; + Strings files; char *p, *ext; Module *m; int status = EXIT_SUCCESS; @@ -143,10 +147,10 @@ int main(int argc, char** argv) #endif global.params.useSwitchError = 1; - global.params.linkswitches = new Array(); - global.params.libfiles = new Array(); - global.params.objfiles = new Array(); - global.params.ddocfiles = new Array(); + global.params.linkswitches = new Strings(); + global.params.libfiles = new Strings(); + global.params.objfiles = new Strings(); + global.params.ddocfiles = new Strings(); global.params.moduleDeps = NULL; global.params.moduleDepsFile = NULL; @@ -647,12 +651,12 @@ LDC_TARGETS for (int i = 0; i < global.params.imppath->dim; i++) { char *path = (char *)global.params.imppath->data[i]; - Array *a = FileName::splitPath(path); + Strings *a = FileName::splitPath(path); if (a) { if (!global.path) - global.path = new Array(); + global.path = new Strings(); global.path->append(a); } } @@ -664,19 +668,19 @@ LDC_TARGETS for (int i = 0; i < global.params.fileImppath->dim; i++) { char *path = (char *)global.params.fileImppath->data[i]; - Array *a = FileName::splitPath(path); + Strings *a = FileName::splitPath(path); if (a) { if (!global.filePath) - global.filePath = new Array(); + global.filePath = new Strings(); global.filePath->append(a); } } } // Create Modules - Array modules; + Modules modules; modules.reserve(files.dim); for (int i = 0; i < files.dim; i++) { Identifier *id; @@ -697,7 +701,7 @@ LDC_TARGETS stricmp(ext, global.bc_ext) == 0) #endif { - global.params.objfiles->push(files.data[i]); + global.params.objfiles->push((char *)files.data[i]); continue; } @@ -709,13 +713,13 @@ LDC_TARGETS if (stricmp(ext, "lib") == 0) #endif { - global.params.libfiles->push(files.data[i]); + global.params.libfiles->push((char *)files.data[i]); continue; } if (strcmp(ext, global.ddoc_ext) == 0) { - global.params.ddocfiles->push(files.data[i]); + global.params.ddocfiles->push((char *)files.data[i]); continue; } diff --git a/gen/statements.cpp b/gen/statements.cpp index adb52f71..d31361ec 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -210,6 +210,29 @@ void ExpStatement::toIR(IRState* p) ////////////////////////////////////////////////////////////////////////////// +#if DMDV2 + +void DtorExpStatement::toIR(IRState *irs) +{ + assert(irs->func()); + FuncDeclaration *fd = irs->func()->decl; + assert(fd); + if (fd->nrvo_can && fd->nrvo_var == var) + /* Do not call destructor, because var is returned as the nrvo variable. + * This is done at this stage because nrvo can be turned off at a + * very late stage in semantic analysis. + */ + ; + else + { + ExpStatement::toIR(irs); + } +} + +#endif + +////////////////////////////////////////////////////////////////////////////// + void IfStatement::toIR(IRState* p) { Logger::println("IfStatement::toIR(): %s", loc.toChars()); diff --git a/ir/irclass.cpp b/ir/irclass.cpp index 844cb08f..4890b6d9 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -366,7 +366,7 @@ llvm::GlobalVariable * IrStruct::getInterfaceVtbl(BaseClass * b, bool new_instan ClassDeclaration* cd = aggrdecl->isClassDeclaration(); assert(cd && "not a class aggregate"); - Array vtbl_array; + FuncDeclarations vtbl_array; b->fillVtbl(cd, &vtbl_array, new_instance); std::vector constants; diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index 16ce3131..2d66fdd5 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -181,7 +181,7 @@ void IrTypeClass::addBaseClassData( BaseClass* b = it2.get(); IF_LOG Logger::println("Adding interface vtbl for %s", b->base->toPrettyChars()); - Array arr; + FuncDeclarations arr; b->fillVtbl(cd, &arr, new_instances); const llvm::Type* ivtbl_type = buildVtblType(first, &arr);