From 72f34e3d8e2a8d8973b7da71eb9f032364d6046a Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Wed, 30 Oct 2013 21:52:45 +0100 Subject: [PATCH] Update source to eb1b004. This brings the source beyond beta4. --- dmd2/declaration.c | 10 +- dmd2/expression.c | 223 +++++++++++++++++++++++++----------- dmd2/expression.h | 2 +- dmd2/init.c | 280 +++++++++++++++------------------------------ dmd2/init.h | 1 - dmd2/mars.c | 15 +-- dmd2/mars.h | 4 +- dmd2/module.c | 13 ++- 8 files changed, 270 insertions(+), 278 deletions(-) diff --git a/dmd2/declaration.c b/dmd2/declaration.c index 9b3fa956..0b7c6489 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -1572,17 +1572,19 @@ Lnomatch: */ storage_class &= ~(STCref | STCforeach | STCparameter); - Expression *e; + Expression *e = new VarExp(loc, this); if (sd->zeroInit == 1) { - e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32)); + e = new ConstructExp(loc, e, new IntegerExp(loc, 0, Type::tint32)); } else if (sd->isNested()) - { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInitLiteral(loc)); + { + e = new AssignExp(loc, e, t->defaultInitLiteral(loc)); e->op = TOKblit; } else - { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); + { + e = new AssignExp(loc, e, t->defaultInit(loc)); e->op = TOKblit; } e->type = t; diff --git a/dmd2/expression.c b/dmd2/expression.c index c11e7424..5a32fe83 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -414,7 +414,7 @@ Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL) tthis = NULL; goto Lfd; } - else if (e1->op == TOKdotvar && e1->type->toBasetype()->ty == Tfunction) + else if (e1->op == TOKdotvar && e1->type && e1->type->toBasetype()->ty == Tfunction) { DotVarExp *dve = (DotVarExp *)e1; s = dve->var->isFuncDeclaration(); @@ -422,7 +422,7 @@ Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL) tthis = dve->e1->type; goto Lfd; } - else if (e1->op == TOKvar && e1->type->toBasetype()->ty == Tfunction) + else if (e1->op == TOKvar && e1->type && e1->type->toBasetype()->ty == Tfunction) { s = ((VarExp *)e1)->var->isFuncDeclaration(); tiargs = NULL; @@ -4618,7 +4618,6 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions * this->soffset = 0; this->fillHoles = 1; this->ownedByCtfe = false; - this->ctorinit = 0; #if IN_LLVM this->inProgressMemory = NULL; this->globalVar = NULL; @@ -4729,52 +4728,17 @@ Expression *StructLiteralExp::semantic(Scope *sc) /* Fill out remainder of elements[] with default initializers for fields[] */ - for (size_t i = elements->dim; i < nfields; i++) + Expression *e = fill(false); + if (e->op == TOKerror) { - Expression *e; - VarDeclaration *v = sd->fields[i]; - assert(!v->isThisDeclaration()); - - if (v->offset < offset) - { - e = NULL; - sd->hasUnions = 1; - } - else - { - if (v->init) - { - if (v->init->isVoidInitializer()) - e = NULL; - else - e = v->getConstInitializer(false); - } - else - { - if ((v->storage_class & STCnodefaultctor) && !ctorinit) - { - error("field %s.%s must be initialized because it has no default constructor", - sd->type->toChars(), v->toChars()); - } - if (v->type->needsNested() && ctorinit) - e = v->type->defaultInit(loc); - else - e = v->type->defaultInitLiteral(loc); - } - offset = v->offset + v->type->size(); - } - if (e && e->op == TOKerror) - { - /* An error in the initializer needs to be recorded as an error - * in the enclosing function or template, since the initializer - * will be part of the stuct declaration. - */ - global.increaseErrorCount(); - return e; - } - elements->push(e); + /* An error in the initializer needs to be recorded as an error + * in the enclosing function or template, since the initializer + * will be part of the stuct declaration. + */ + global.increaseErrorCount(); + return e; } - + assert(e == this); type = stype ? stype : sd->type; /* If struct requires a destructor, rewrite as: @@ -4795,6 +4759,115 @@ Expression *StructLiteralExp::semantic(Scope *sc) return this; } +Expression *StructLiteralExp::fill(bool ctorinit) +{ + assert(sd && sd->sizeok == SIZEOKdone); + size_t nfields = sd->fields.dim - sd->isNested(); + + size_t dim = elements->dim; + elements->setDim(nfields); + for (size_t i = dim; i < nfields; i++) + (*elements)[i] = NULL; + + // Fill in missing any elements with default initializers + for (size_t i = 0; i < nfields; i++) + { + if ((*elements)[i]) + continue; + VarDeclaration *vd = sd->fields[i]; + VarDeclaration *vx = vd; + if (vd->init && vd->init->isVoidInitializer()) + vx = NULL; + // Find overlapped fields with the hole [vd->offset .. vd->offset->size()]. + size_t fieldi = i; + for (size_t j = 0; j < nfields; j++) + { + if (i == j) + continue; + VarDeclaration *v2 = sd->fields[j]; + if (v2->init && v2->init->isVoidInitializer()) + continue; + + bool overlap = (vd->offset < v2->offset + v2->type->size() && + v2->offset < vd->offset + vd->type->size()); + if (!overlap) + continue; + + sd->hasUnions = 1; // note that directly unrelated... + + if ((*elements)[j]) + { + vx = NULL; + break; + } + +#if 1 + /* Prefer first found non-void-initialized field + * union U { int a; int b = 2; } + * U u; // Error: overlapping initialization for field a and b + */ + if (!vx) + vx = v2, fieldi = j; + else if (v2->init) + { + error("overlapping initialization for field %s and %s", + v2->toChars(), vd->toChars()); + } +#else // fix Bugzilla 1432 + /* Prefer explicitly initialized field + * union U { int a; int b = 2; } + * U u; // OK (u.b == 2) + */ + if (!vx || !vx->init && v2->init) + vx = v2, fieldi = j; + else if (vx != vd && + !(vx->offset < v2->offset + v2->type->size() && + v2->offset < vx->offset + vx->type->size())) + { + // Both vx and v2 fills vd, but vx and v2 does not overlap + } + else if (vx->init && v2->init) + { + error("overlapping default initialization for field %s and %s", + v2->toChars(), vd->toChars()); + } + else + assert(vx->init || !vx->init && !v2->init); +#endif + } + if (vx) + { + Expression *e; + if (vx->init) + { + assert(!vx->init->isVoidInitializer()); + e = vx->getConstInitializer(false); + } + else + { + if ((vx->storage_class & STCnodefaultctor) && !ctorinit) + { + error("field %s.%s must be initialized because it has no default constructor", + sd->type->toChars(), vx->toChars()); + } + if (vx->type->needsNested() && ctorinit) + e = vx->type->defaultInit(loc); + else + e = vx->type->defaultInitLiteral(loc); + } + (*elements)[fieldi] = e; + } + } + + for (size_t i = 0; i < elements->dim; i++) + { + Expression *e = (*elements)[i]; + if (e && e->op == TOKerror) + return e; + } + return this; +} + /************************************** * Gets expression at offset of type. * Returns NULL if not found. @@ -7885,7 +7958,9 @@ Expression *DotVarExp::semantic(Scope *sc) Identifier *id = Lexer::uniqueId("__tup"); ExpInitializer *ei = new ExpInitializer(e1->loc, e1); VarDeclaration *v = new VarDeclaration(e1->loc, NULL, id, ei); - v->storage_class |= STCctfe | STCref | STCforeach; + v->storage_class |= STCctfe; + if (e1->isLvalue()) + v->storage_class |= STCref | STCforeach; e0 = new DeclarationExp(e1->loc, v); ev = new VarExp(e1->loc, v); e0 = e0->semantic(sc); @@ -8732,8 +8807,8 @@ Lagain: // Check for call operator overload if (t1) - { AggregateDeclaration *ad; - + { + AggregateDeclaration *ad; if (t1->ty == Tstruct) { ad = ((TypeStruct *)t1)->sym; @@ -8762,29 +8837,29 @@ Lagain: ExpInitializer *ei = NULL; if (t1->needsNested()) { - Expressions *args = new Expressions(); - StructLiteralExp *se = new StructLiteralExp(loc, (StructDeclaration *)ad, args); - se->ctorinit = 1; - ei = new ExpInitializer(loc, se); + StructLiteralExp *sle = new StructLiteralExp(loc, (StructDeclaration *)ad, NULL, e1->type); + Expression *e = sle->fill(true); + if (e->op == TOKerror) + return e; + sle->type = type; + ei = new ExpInitializer(loc, sle); } - VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, ei); tmp->storage_class |= STCctfe; - Expression *av = new DeclarationExp(loc, tmp); - av = new CommaExp(loc, av, new VarExp(loc, tmp)); - Expression *e; + Expression *e = new DeclarationExp(loc, tmp); + e = new CommaExp(loc, e, new VarExp(loc, tmp)); if (CtorDeclaration *cf = ad->ctor->isCtorDeclaration()) { - e = new DotVarExp(loc, av, cf, 1); + e = new DotVarExp(loc, e, cf, 1); } else if (TemplateDeclaration *td = ad->ctor->isTemplateDeclaration()) { - e = new DotTemplateExp(loc, av, td); + e = new DotTemplateExp(loc, e, td); } else if (OverloadSet *os = ad->ctor->isOverloadSet()) { - e = new DotExp(loc, av, new OverExp(loc, os)); + e = new DotExp(loc, e, new OverExp(loc, os)); } else assert(0); @@ -11446,7 +11521,9 @@ Ltupleassign: Identifier *id = Lexer::uniqueId("__tup"); ExpInitializer *ei = new ExpInitializer(e2->loc, e2); VarDeclaration *v = new VarDeclaration(e2->loc, NULL, id, ei); - v->storage_class = STCctfe | STCref | STCforeach; + v->storage_class = STCctfe; + if (e2->isLvalue()) + v->storage_class = STCref | STCforeach; Expression *e0 = new DeclarationExp(e2->loc, v); Expression *ev = new VarExp(e2->loc, v); ev->type = e2->type; @@ -11532,6 +11609,8 @@ Ltupleassign: VarDeclaration *v = new VarDeclaration(loc, ie->e1->type, Lexer::uniqueId("__aatmp"), new ExpInitializer(loc, ie->e1)); v->storage_class |= STCctfe; + if (ea->isLvalue()) + v->storage_class |= STCforeach | STCref; v->semantic(sc); e0 = combine(e0, new DeclarationExp(loc, v)); ea = new VarExp(loc, v); @@ -11541,6 +11620,8 @@ Ltupleassign: VarDeclaration *v = new VarDeclaration(loc, ie->e2->type, Lexer::uniqueId("__aakey"), new ExpInitializer(loc, ie->e2)); v->storage_class |= STCctfe; + if (ek->isLvalue()) + v->storage_class |= STCforeach | STCref; v->semantic(sc); e0 = combine(e0, new DeclarationExp(loc, v)); ek = new VarExp(loc, v); @@ -11550,6 +11631,8 @@ Ltupleassign: VarDeclaration *v = new VarDeclaration(loc, e2->type, Lexer::uniqueId("__aaval"), new ExpInitializer(loc, e2)); v->storage_class |= STCctfe; + if (ev->isLvalue()) + v->storage_class |= STCforeach | STCref; v->semantic(sc); e0 = combine(e0, new DeclarationExp(loc, v)); ev = new VarExp(loc, v); @@ -11761,7 +11844,7 @@ Ltupleassign: e2 = new SliceExp(e2->loc, e2, NULL, NULL); e2 = e2->semantic(sc); } - else if (global.params.warnings && !global.gag && op == TOKassign && + else if (0 && global.params.warnings && !global.gag && op == TOKassign && e2->op != TOKarrayliteral && e2->op != TOKstring && !e2->implicitConvTo(t1)) { // Disallow sa = da (Converted to sa[] = da[]) @@ -11891,7 +11974,7 @@ Ltupleassign: { e2->checkPostblit(sc, t2->nextOf()); } - if (global.params.warnings && !global.gag && op == TOKassign && + if (0 && global.params.warnings && !global.gag && op == TOKassign && e2->op != TOKslice && e2->op != TOKassign && e2->op != TOKarrayliteral && e2->op != TOKstring && !(e2->op == TOKadd || e2->op == TOKmin || @@ -11915,7 +11998,7 @@ Ltupleassign: } else { - if (global.params.warnings && !global.gag && op == TOKassign && + if (0 && global.params.warnings && !global.gag && op == TOKassign && t1->ty == Tarray && t2->ty == Tsarray && e2->op != TOKslice && //e2->op != TOKarrayliteral && t2->implicitConvTo(t1)) @@ -13976,7 +14059,8 @@ Expression *extractOpDollarSideEffect(Scope *sc, UnaExp *ue) Identifier *id = Lexer::uniqueId("__dop"); ExpInitializer *ei = new ExpInitializer(ue->loc, ue->e1); VarDeclaration *v = new VarDeclaration(ue->loc, ue->e1->type, id, ei); - v->storage_class |= STCctfe | STCforeach | STCref; + v->storage_class |= STCctfe + | (ue->e1->isLvalue() ? (STCforeach | STCref) : 0); e0 = new DeclarationExp(ue->loc, v); e0 = e0->semantic(sc); ue->e1 = new VarExp(ue->loc, v); @@ -14098,9 +14182,9 @@ Expression *BinExp::reorderSettingAAElem(Scope *sc) { Identifier *id = Lexer::uniqueId("__aatmp"); VarDeclaration *vd = new VarDeclaration(ie->e1->loc, ie->e1->type, id, new ExpInitializer(ie->e1->loc, ie->e1)); - vd->storage_class |= STCref | STCforeach; Expression *de = new DeclarationExp(ie->e1->loc, vd); - + if (ie->e1->isLvalue()) + vd->storage_class |= STCref | STCforeach; ec = de; ie->e1 = new VarExp(ie->e1->loc, vd); } @@ -14108,7 +14192,8 @@ Expression *BinExp::reorderSettingAAElem(Scope *sc) { Identifier *id = Lexer::uniqueId("__aakey"); VarDeclaration *vd = new VarDeclaration(ie->e2->loc, ie->e2->type, id, new ExpInitializer(ie->e2->loc, ie->e2)); - vd->storage_class |= STCref | STCforeach; + if (ie->e2->isLvalue()) + vd->storage_class |= STCref | STCforeach; Expression *de = new DeclarationExp(ie->e2->loc, vd); ec = ec ? new CommaExp(loc, ec, de) : de; diff --git a/dmd2/expression.h b/dmd2/expression.h index f5c98f04..5bb7395d 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -604,7 +604,6 @@ public: size_t soffset; // offset from start of s int fillHoles; // fill alignment 'holes' with zero bool ownedByCtfe; // true = created in CTFE - int ctorinit; StructLiteralExp *origin; // pointer to the origin instance of the expression. // once a new expression is created, origin is set to 'this'. @@ -622,6 +621,7 @@ public: Expression *syntaxCopy(); int apply(apply_fp_t fp, void *param); Expression *semantic(Scope *sc); + Expression *fill(bool ctorinit); Expression *getField(Type *type, unsigned offset); int getFieldIndex(Type *type, unsigned offset); elem *toElem(IRState *irs); diff --git a/dmd2/init.c b/dmd2/init.c index b25e4da3..9b2c89b7 100644 --- a/dmd2/init.c +++ b/dmd2/init.c @@ -189,11 +189,101 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needI sd->kind(), sd->toChars(), sd->toChars()); return new ErrorInitializer(); } + sd->size(loc); + if (sd->sizeok != SIZEOKdone) + return new ErrorInitializer(); + size_t nfields = sd->fields.dim - sd->isNested(); - Expression *e = fill(sc, t, needInterpret); + //expandTuples for non-identity arguments? + + Expressions *elements = new Expressions(); + elements->setDim(nfields); + for (size_t i = 0; i < elements->dim; i++) + (*elements)[i] = NULL; + + // Run semantic for explicitly given initializers + // TODO: this part is slightly different from StructLiteralExp::semantic. + bool errors = false; + for (size_t fieldi = 0, i = 0; i < field.dim; i++) + { + if (Identifier *id = field[i]) + { + Dsymbol *s = sd->search(loc, id, 0); + if (!s) + { + s = sd->search_correct(id); + if (s) + error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?", + id->toChars(), sd->toChars(), s->kind(), s->toChars()); + else + error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); + return new ErrorInitializer(); + } + s = s->toAlias(); + + // Find out which field index it is + for (fieldi = 0; 1; fieldi++) + { + if (fieldi >= nfields) + { + error(loc, "%s.%s is not a per-instance initializable field", + sd->toChars(), s->toChars()); + return new ErrorInitializer(); + } + if (s == sd->fields[fieldi]) + break; + } + } + else if (fieldi >= nfields) + { + error(loc, "too many initializers for %s", sd->toChars()); + return new ErrorInitializer(); + } + + VarDeclaration *vd = sd->fields[fieldi]; + if ((*elements)[fieldi]) + { + error(loc, "duplicate initializer for field '%s'", vd->toChars()); + errors = true; + continue; + } + for (size_t j = 0; j < nfields; j++) + { + VarDeclaration *v2 = sd->fields[j]; + bool overlap = (vd->offset < v2->offset + v2->type->size() && + v2->offset < vd->offset + vd->type->size()); + if (overlap && (*elements)[j]) + { + error(loc, "overlapping initialization for field %s and %s", + v2->toChars(), vd->toChars()); + errors = true; + continue; + } + } + + assert(sc); + Initializer *iz = value[i]; + iz = iz->semantic(sc, vd->type->addMod(t->mod), needInterpret); + Expression *ex = iz->toExpression(); + if (ex->op == TOKerror) + { + errors = true; + continue; + } + value[i] = iz; + (*elements)[fieldi] = ex; + ++fieldi; + } + if (errors) + return new ErrorInitializer(); + + StructLiteralExp *sle = new StructLiteralExp(loc, sd, elements, t); + Expression *e = sle->fill(false); if (e->op == TOKerror) return new ErrorInitializer(); + e->type = t; + ExpInitializer *ie = new ExpInitializer(loc, e); return ie->semantic(sc, t, needInterpret); } @@ -226,194 +316,6 @@ Expression *StructInitializer::toExpression(Type *t) return NULL; } -Expression *StructInitializer::fill(Scope *sc, Type *t, NeedInterpret needInterpret) -{ - //printf("StructInitializer::fill(sc = %p, '%s')\n", sc, toChars()); - assert(t->ty == Tstruct); - StructDeclaration *sd = ((TypeStruct *)t)->sym; - sd->size(loc); - if (sd->sizeok != SIZEOKdone) - return new ErrorExp(); - size_t nfields = sd->fields.dim - sd->isNested(); - - Expressions *elements = new Expressions(); - elements->setDim(nfields); - for (size_t i = 0; i < elements->dim; i++) - (*elements)[i] = NULL; - - // Run semantic for explicitly given initializers - bool errors = false; - for (size_t fieldi = 0, i = 0; i < field.dim; i++) - { - if (Identifier *id = field[i]) - { - Dsymbol *s = sd->search(loc, id, 0); - if (!s) - { - s = sd->search_correct(id); - if (s) - error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?", - id->toChars(), sd->toChars(), s->kind(), s->toChars()); - else - error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); - return new ErrorExp(); - } - s = s->toAlias(); - - // Find out which field index it is - for (fieldi = 0; 1; fieldi++) - { - if (fieldi >= nfields) - { - error(loc, "%s.%s is not a per-instance initializable field", - sd->toChars(), s->toChars()); - return new ErrorExp(); - } - if (s == sd->fields[fieldi]) - break; - } - } - else if (fieldi >= nfields) - { - error(loc, "too many initializers for %s", sd->toChars()); - return new ErrorExp(); - } - - VarDeclaration *vd = sd->fields[fieldi]; - if ((*elements)[fieldi]) - { - error(loc, "duplicate initializer for field '%s'", vd->toChars()); - errors = true; - continue; - } - for (size_t j = 0; j < nfields; j++) - { - VarDeclaration *v2 = sd->fields[j]; - bool overlap = (vd->offset < v2->offset + v2->type->size() && - v2->offset < vd->offset + vd->type->size()); - if (overlap && (*elements)[j]) - { - error(loc, "overlapping initialization for field %s and %s", - v2->toChars(), vd->toChars()); - errors = true; - continue; - } - } - - assert(sc); - Initializer *iz = value[i]; - iz = iz->semantic(sc, vd->type->addMod(t->mod), needInterpret); - Expression *ex = iz->toExpression(); - if (ex->op == TOKerror) - { - errors = true; - continue; - } - value[i] = iz; - (*elements)[fieldi] = ex; - ++fieldi; - } - if (errors) - return new ErrorExp(); - - // Fill in missing any elements with default initializers - for (size_t i = 0; i < elements->dim; i++) - { - if ((*elements)[i]) - continue; - VarDeclaration *vd = sd->fields[i]; - VarDeclaration *vx = vd; - if (vd->init && vd->init->isVoidInitializer()) - vx = NULL; - // Find overlapped fields with the hole [vd->offset .. vd->offset->size()]. - size_t fieldi = i; - for (size_t j = 0; j < nfields; j++) - { - if (i == j) - continue; - VarDeclaration *v2 = sd->fields[j]; - if (v2->init && v2->init->isVoidInitializer()) - continue; - - bool overlap = (vd->offset < v2->offset + v2->type->size() && - v2->offset < vd->offset + vd->type->size()); - if (!overlap) - continue; - - if ((*elements)[j]) - { - vx = NULL; - break; - } - - #if 1 - /* Prefer first found non-void-initialized field - * union U { int a; int b = 2; } - * U u; // Error: overlapping initialization for field a and b - */ - if (!vx) - vx = v2, fieldi = j; - else if (v2->init) - { - error(loc, "overlapping initialization for field %s and %s", - v2->toChars(), vd->toChars()); - } - #else // fix Bugzilla 1432 - /* Prefer explicitly initialized field - * union U { int a; int b = 2; } - * U u; // OK (u.b == 2) - */ - if (!vx || !vx->init && v2->init) - vx = v2, fieldi = j; - else if (vx->init && v2->init) - { - error(loc, "overlapping default initialization for field %s and %s", - v2->toChars(), vd->toChars()); - } - else - assert(vx->init || !vx->init && !v2->init); - #endif - } - if (vx) - { - if (vx->init) - { - assert(!vx->init->isVoidInitializer()); - if (vx->scope) - { - // Do deferred semantic analysis - Initializer *i2 = vx->init->syntaxCopy(); - i2 = i2->semantic(vx->scope, vx->type, INITinterpret); - (*elements)[fieldi] = i2->toExpression(); - if (!global.gag) - { - vx->scope = NULL; - vx->init = i2; // save result - } - } - else - (*elements)[fieldi] = vx->init->toExpression(); - } - else - (*elements)[fieldi] = vx->type->defaultInit(); - } - } - - for (size_t i = 0; i < elements->dim; i++) - { - Expression *e = (*elements)[i]; - if (e && e->op == TOKerror) - return e; - } - - Expression *e = new StructLiteralExp(loc, sd, elements, t); - if (sc) - e = e->semantic(sc); - else - e->type = sd->type; // from glue layer - return e; -} - void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { //printf("StructInitializer::toCBuffer()\n"); diff --git a/dmd2/init.h b/dmd2/init.h index de545ff4..7779b7a4 100644 --- a/dmd2/init.h +++ b/dmd2/init.h @@ -105,7 +105,6 @@ public: void addInit(Identifier *field, Initializer *value); Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret); Expression *toExpression(Type *t = NULL); - Expression *fill(Scope *sc, Type *t, NeedInterpret needInterpret); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #if IN_DMD diff --git a/dmd2/mars.c b/dmd2/mars.c index 4ecc5ee7..2d0841ac 100644 --- a/dmd2/mars.c +++ b/dmd2/mars.c @@ -368,6 +368,7 @@ Usage:\n\ \n\ files.d D source files\n\ @cmdfile read arguments from cmdfile\n\ + -allinst generate code for all template instantiations\n\ -c do not link\n\ -cov do code coverage analysis\n\ -cov=nnn require at least nnn%% code coverage\n\ @@ -634,7 +635,9 @@ int tryMain(size_t argc, char *argv[]) p = argv[i]; if (*p == '-') { - if (strcmp(p + 1, "de") == 0) + if (strcmp(p + 1, "allinst") == 0) + global.params.allInst = true; + else if (strcmp(p + 1, "de") == 0) global.params.useDeprecated = 0; else if (strcmp(p + 1, "d") == 0) global.params.useDeprecated = 1; @@ -1713,12 +1716,7 @@ Language changes listed by -transition=id:\n\ fprintf(global.stdmsg, "code %s\n", m->toChars()); m->genobjfile(0); if (entrypoint && m == entrypoint->importedFrom) - { - char v = global.params.verbose; - global.params.verbose = 0; entrypoint->genobjfile(0); - global.params.verbose = v; - } if (!global.errors && global.params.doDocComments) m->gendocfile(); } @@ -1739,12 +1737,7 @@ Language changes listed by -transition=id:\n\ obj_start(m->srcfile->toChars()); m->genobjfile(global.params.multiobj); if (entrypoint && m == entrypoint->importedFrom) - { - char v = global.params.verbose; - global.params.verbose = 0; entrypoint->genobjfile(global.params.multiobj); - global.params.verbose = v; - } obj_end(library, m->objfile); obj_write_deferred(library); } diff --git a/dmd2/mars.h b/dmd2/mars.h index 2bb54e8a..12318450 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2012 by Digital Mars +// Copyright (c) 1999-2013 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -218,6 +218,7 @@ struct Param bool ignoreUnsupportedPragmas; // rather than error on them bool enforcePropertySyntax; bool addMain; // LDC_FIXME: Implement. + bool allInst; // LDC_FIXME: Implement. #else bool pic; // generate position-independent-code for shared libs bool cov; // generate code coverage data @@ -227,6 +228,7 @@ struct Param char enforcePropertySyntax; char betterC; // be a "better C" compiler; no dependency on D runtime bool addMain; // add a default main() function + bool allInst; // generate code for all template instantiations #endif char *argv0; // program name diff --git a/dmd2/module.c b/dmd2/module.c index 4339a4bb..f8a33483 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -1274,8 +1274,12 @@ const char *lookForSourceFile(const char *filename) { /* The filename exists and it's a directory. * Therefore, the result should be: filename/package.d + * iff filename/package.d is a file */ - return FileName::combine(filename, "package.d"); + const char *n = FileName::combine(filename, "package.d"); + if (FileName::exists(n) == 1) + return n; + FileName::free(n); } if (FileName::absolute(filename)) @@ -1302,7 +1306,12 @@ const char *lookForSourceFile(const char *filename) n = FileName::combine(p, b); FileName::free(b); if (FileName::exists(n) == 2) - return FileName::combine(n, "package.d"); + { + const char *n2 = FileName::combine(n, "package.d"); + if (FileName::exists(n2) == 1) + return n2; + FileName::free(n2); + } FileName::free(n); } return NULL;