Mercurial > projects > ldc
diff dmd/template.c @ 1587:def7a1d494fd
Merge DMD 1.051
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Fri, 06 Nov 2009 23:58:01 +0100 |
parents | 4dca8ed9d8b7 |
children | 207a8a438dea |
line wrap: on
line diff
--- a/dmd/template.c Fri Nov 06 21:51:41 2009 +0100 +++ b/dmd/template.c Fri Nov 06 23:58:01 2009 +0100 @@ -310,7 +310,7 @@ this->members = decldefs; this->overnext = NULL; this->overroot = NULL; - this->scope = NULL; + this->semanticRun = 0; this->onemember = NULL; } @@ -350,8 +350,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) { @@ -803,16 +804,19 @@ { // Set initial template arguments nargsi = targsi->dim; - if (nargsi > parameters->dim) + size_t n = parameters->dim; + if (nargsi > n) { if (!tp) goto Lnomatch; dedargs->setDim(nargsi); dedargs->zero(); } - - memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); - - for (size_t i = 0; i < nargsi; i++) + else + n = nargsi; + + memcpy(dedargs->data, targsi->data, n * sizeof(*dedargs->data)); + + for (size_t i = 0; i < n; i++) { assert(i < parameters->dim); TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; MATCH m; @@ -844,7 +848,7 @@ fdtype = (TypeFunction *)fd->type; nfparams = Argument::dim(fdtype->parameters); // number of function parameters - nfargs = fargs->dim; // number of function arguments + nfargs = fargs ? fargs->dim : 0; // number of function arguments /* Check for match of function arguments with variadic template * parameter, such as: @@ -854,7 +858,7 @@ */ if (tp) // if variadic { - if (nfparams == 0) // if no function parameters + if (nfparams == 0 && nfargs != 0) // if no function parameters { Tuple *t = new Tuple(); //printf("t = %p\n", t); @@ -1293,7 +1297,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; @@ -1901,14 +1905,21 @@ L2: - for (int i = 0; i < tempinst->tiargs->dim; i++) + for (int i = 0; 1; i++) { //printf("\ttest: tempinst->tiargs[%d]\n", i); + Object *o1; + if (i < tempinst->tiargs->dim) + o1 = (Object *)tempinst->tiargs->data[i]; + else if (i < tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim) + // Pick up default arg + o1 = (Object *)tempinst->tdtypes.data[i]; + else + break; + if (i >= tp->tempinst->tiargs->dim) goto Lnomatch; - int j; - Object *o1 = (Object *)tempinst->tiargs->data[i]; Object *o2 = (Object *)tp->tempinst->tiargs->data[i]; Type *t1 = isType(o1); @@ -1934,6 +1945,7 @@ #endif TemplateTupleParameter *ttp; + int j; if (t2 && t2->ty == Tident && i == tp->tempinst->tiargs->dim - 1 && @@ -3062,7 +3074,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; @@ -3096,7 +3108,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; @@ -3179,13 +3191,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; // get the enclosing template instance from the scope tinst tinst = sc->tinst; @@ -3323,7 +3335,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++) @@ -3344,9 +3356,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; } @@ -3559,6 +3571,7 @@ } else if (ta) { + Ltype: if (ta->ty == Ttuple) { // Expand tuple TypeTuple *tt = (TypeTuple *)ta; @@ -3593,7 +3606,21 @@ 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) { @@ -3736,6 +3763,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; @@ -3752,11 +3796,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 @@ -3964,6 +4004,7 @@ { sinteger_t v; real_t r; + ea = ea->optimize(WANTvalue | WANTinterpret); if (ea->op == TOKvar) { sa = ((VarExp *)ea)->var; @@ -4030,7 +4071,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++) @@ -4040,7 +4081,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); } } @@ -4048,9 +4089,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 @@ -4080,12 +4121,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; @@ -4182,6 +4223,7 @@ #endif if (!inst) { error("cannot resolve forward reference"); + errors = 1; return this; } @@ -4274,7 +4316,6 @@ this->tqual = tqual; this->idents = idents; this->tiargs = tiargs ? tiargs : new Objects(); - this->scope = NULL; } Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s) @@ -4308,18 +4349,22 @@ 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())) - { + if (parent && toParent()->isAggregateDeclaration()) + semanticRun = 1; // do over + else + { #if LOG - printf("\tsemantic done\n"); + printf("\tsemantic done\n"); #endif - return; + return; + } } - if (!semanticdone) - semanticdone = 1; + if (!semanticRun) + semanticRun = 1; #if LOG printf("\tdo semantic\n"); #endif @@ -4394,7 +4439,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 @@ -4402,7 +4447,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; @@ -4420,6 +4465,8 @@ // Run semantic on each argument, place results in tiargs[] semanticTiargs(sc); + if (errors) + return; tempdecl = findBestMatch(sc); if (!tempdecl) @@ -4508,19 +4555,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()); @@ -4531,7 +4578,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; @@ -4574,7 +4621,7 @@ sc2->pop(); - scope->pop(); + argscope->pop(); // if (!isAnonymous()) { @@ -4588,9 +4635,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 @@ -4618,9 +4665,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