Mercurial > projects > ldc
diff dmd2/template.c @ 1526:54b3c1394d62
Merged dmdfe 2.031.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 07 Jul 2009 02:26:11 +0100 |
parents | 638d16625da2 |
children | e4f7b5d9c68a |
line wrap: on
line diff
--- a/dmd2/template.c Mon Jul 06 23:57:27 2009 +0100 +++ b/dmd2/template.c Tue Jul 07 02:26:11 2009 +0100 @@ -308,7 +308,7 @@ this->members = decldefs; this->overnext = NULL; this->overroot = NULL; - this->scope = NULL; + this->semanticRun = 0; this->onemember = NULL; this->literal = 0; } @@ -337,7 +337,6 @@ td = new TemplateDeclaration(loc, ident, p, e, d); #if IN_LLVM - // LDC td->intrinsicName = intrinsicName; #endif @@ -349,8 +348,9 @@ #if LOG printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); #endif - if (scope) + if (semanticRun) return; // semantic() already run + semanticRun = 1; if (sc->func) { @@ -878,8 +878,8 @@ fvarargs = fctor->varargs; } - nfparams = Argument::dim(fparameters); // number of function parameters - nfargs = fargs->dim; // number of function arguments + nfparams = Argument::dim(fparameters); // number of function parameters + nfargs = fargs ? fargs->dim : 0; // number of function arguments /* Check for match of function arguments with variadic template * parameter, such as: @@ -1329,7 +1329,7 @@ for (TemplateDeclaration *td = this; td; td = td->overnext) { - if (!td->scope) + if (!td->semanticRun) { error("forward reference to template %s", td->toChars()); goto Lerror; @@ -3215,7 +3215,7 @@ this->tinst = NULL; this->argsym = NULL; this->aliasdecl = NULL; - this->semanticdone = 0; + this->semanticRun = 0; this->semantictiargsdone = 0; this->withsym = NULL; this->nest = 0; @@ -3249,7 +3249,7 @@ this->tinst = NULL; this->argsym = NULL; this->aliasdecl = NULL; - this->semanticdone = 0; + this->semanticRun = 0; this->semantictiargsdone = 1; this->withsym = NULL; this->nest = 0; @@ -3324,13 +3324,13 @@ // get the enclosing template instance from the scope tinst tinst = sc->tinst; - if (semanticdone != 0) + if (semanticRun != 0) { error(loc, "recursive template expansion"); // inst = this; return; } - semanticdone = 1; + semanticRun = 1; #if IN_LLVM // get the enclosing template instance from the scope tinst tinst = sc->tinst; @@ -3474,7 +3474,7 @@ { Module *m = sc->module->importedFrom; //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); a = m->members; - if (m->semanticdone >= 3) + if (m->semanticRun >= 3) dosemantic3 = 1; } for (int i = 0; 1; i++) @@ -3495,9 +3495,9 @@ // Create our own scope for the template parameters Scope *scope = tempdecl->scope; - if (!scope) + if (!tempdecl->semanticRun) { - error("forward reference to template declaration %s\n", tempdecl->toChars()); + error("template instantiation %s forward references template declaration %s\n", toChars(), tempdecl->toChars()); return; } @@ -3717,6 +3717,7 @@ } else if (ta) { + Ltype: if (ta->ty == Ttuple) { // Expand tuple TypeTuple *tt = (TypeTuple *)ta; @@ -3752,12 +3753,26 @@ ea = ea->optimize(WANTvalue | WANTinterpret); tiargs->data[j] = ea; if (ea->op == TOKtype) - tiargs->data[j] = ea->type; + { ta = ea->type; + goto Ltype; + } + if (ea->op == TOKtuple) + { // Expand tuple + TupleExp *te = (TupleExp *)ea; + size_t dim = te->exps->dim; + tiargs->remove(j); + if (dim) + { tiargs->reserve(dim); + for (size_t i = 0; i < dim; i++) + tiargs->insert(j + i, te->exps->data[i]); + } + j--; + } } else if (sa) { TemplateDeclaration *td = sa->isTemplateDeclaration(); - if (td && !td->scope && td->literal) + if (td && !td->semanticRun && td->literal) td->semantic(sc); } else @@ -3898,6 +3913,23 @@ #if LOG printf("TemplateInstance::findBestMatch()\n"); #endif + // First look for forward references + for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) + { + if (!td->semanticRun) + { + if (td->scope) + { // Try to fix forward reference + td->semantic(td->scope); + } + if (!td->semanticRun) + { + error("%s forward references template declaration %s\n", toChars(), td->toChars()); + return NULL; + } + } + } + for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) { MATCH m; @@ -3914,11 +3946,7 @@ dedtypes.setDim(td->parameters->dim); dedtypes.zero(); - if (!td->scope) - { - error("forward reference to template declaration %s", td->toChars()); - return NULL; - } + assert(td->semanticRun); m = td->matchWithInstance(this, &dedtypes, 0); //printf("matchWithInstance = %d\n", m); if (!m) // no match at all @@ -4212,7 +4240,7 @@ * template instance arguments. */ -void TemplateInstance::declareParameters(Scope *scope) +void TemplateInstance::declareParameters(Scope *sc) { //printf("TemplateInstance::declareParameters()\n"); for (int i = 0; i < tdtypes.dim; i++) @@ -4222,7 +4250,7 @@ Object *o = (Object *)tdtypes.data[i]; // initializer for tp //printf("\ttdtypes[%d] = %p\n", i, o); - tempdecl->declareParameter(scope, tp, o); + tempdecl->declareParameter(sc, tp, o); } } @@ -4230,9 +4258,9 @@ void TemplateInstance::semantic2(Scope *sc) { int i; - if (semanticdone >= 2) + if (semanticRun >= 2) return; - semanticdone = 2; + semanticRun = 2; #if LOG printf("+TemplateInstance::semantic2('%s')\n", toChars()); #endif @@ -4262,12 +4290,12 @@ void TemplateInstance::semantic3(Scope *sc) { #if LOG - printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); + printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun); #endif //if (toChars()[0] == 'D') *(char*)0=0; - if (semanticdone >= 3) + if (semanticRun >= 3) return; - semanticdone = 3; + semanticRun = 3; if (!errors && members) { sc = tempdecl->scope; @@ -4457,7 +4485,6 @@ this->tqual = tqual; this->idents = idents; this->tiargs = tiargs ? tiargs : new Objects(); - this->scope = NULL; } Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) @@ -4491,7 +4518,7 @@ printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this); fflush(stdout); #endif - if (semanticdone && + if (semanticRun && // This for when a class/struct contains mixin members, and // is done over because of forward references (!parent || !toParent()->isAggregateDeclaration())) @@ -4501,8 +4528,8 @@ #endif return; } - if (!semanticdone) - semanticdone = 1; + if (!semanticRun) + semanticRun = 1; #if LOG printf("\tdo semantic\n"); #endif @@ -4577,7 +4604,7 @@ assert(tempdecl); for (TemplateDeclaration *td = tempdecl; td; td = td->overnext) { - if (!td->scope) + if (!td->semanticRun) { /* Cannot handle forward references if mixin is a struct member, * because addField must happen during struct's semantic, not @@ -4585,7 +4612,7 @@ * runDeferred will re-run mixin's semantic outside of the struct's * semantic. */ - semanticdone = 0; + semanticRun = 0; AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); if (ad) ad->sizeok = 2; @@ -4691,19 +4718,19 @@ argsym = new ScopeDsymbol(); argsym->parent = scy->parent; - Scope *scope = scy->push(argsym); + Scope *argscope = scy->push(argsym); unsigned errorsave = global.errors; // Declare each template parameter as an alias for the argument type - declareParameters(scope); + declareParameters(argscope); // Add members to enclosing scope, as well as this scope for (unsigned i = 0; i < members->dim; i++) { Dsymbol *s; s = (Dsymbol *)members->data[i]; - s->addMember(scope, this, i); + s->addMember(argscope, this, i); //sc->insert(s); //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); //printf("s->parent = %s\n", s->parent->toChars()); @@ -4714,7 +4741,7 @@ printf("\tdo semantic() on template instance members '%s'\n", toChars()); #endif Scope *sc2; - sc2 = scope->push(this); + sc2 = argscope->push(this); sc2->offset = sc->offset; static int nest; @@ -4757,7 +4784,7 @@ sc2->pop(); - scope->pop(); + argscope->pop(); // if (!isAnonymous()) { @@ -4771,9 +4798,9 @@ void TemplateMixin::semantic2(Scope *sc) { int i; - if (semanticdone >= 2) + if (semanticRun >= 2) return; - semanticdone = 2; + semanticRun = 2; #if LOG printf("+TemplateMixin::semantic2('%s')\n", toChars()); #endif @@ -4801,9 +4828,9 @@ void TemplateMixin::semantic3(Scope *sc) { int i; - if (semanticdone >= 3) + if (semanticRun >= 3) return; - semanticdone = 3; + semanticRun = 3; #if LOG printf("TemplateMixin::semantic3('%s')\n", toChars()); #endif