Mercurial > projects > ldc
diff dmd/template.c @ 875:330f999ade44
Merged DMD 1.038
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 06 Jan 2009 16:33:51 +0100 |
parents | eef8ac26c66c |
children | 27a379f288bf |
line wrap: on
line diff
--- a/dmd/template.c Tue Jan 06 15:54:48 2009 +0100 +++ b/dmd/template.c Tue Jan 06 16:33:51 2009 +0100 @@ -201,8 +201,10 @@ goto Lnomatch; } } + //printf("match\n"); return 1; // match Lnomatch: + //printf("nomatch\n"); return 0; // nomatch; } @@ -320,7 +322,9 @@ if (sc->func) { +#if DMDV1 error("cannot declare template at function scope %s", sc->func->toChars()); +#endif } if (/*global.params.useArrayBounds &&*/ sc->module) @@ -551,7 +555,9 @@ if (!flag) { - // Any parameter left without a type gets the type of its corresponding arg + /* Any parameter left without a type gets the type of + * its corresponding arg + */ for (int i = 0; i < dedtypes_dim; i++) { if (!dedtypes->data[i]) @@ -561,6 +567,25 @@ } } +#if DMDV2 + if (m && constraint && !(flag & 1)) + { /* Check to see if constraint is satisfied. + */ + Expression *e = constraint->syntaxCopy(); + paramscope->flags |= SCOPEstaticif; + e = e->semantic(paramscope); + e = e->optimize(WANTvalue | WANTinterpret); + if (e->isBool(TRUE)) + ; + else if (e->isBool(FALSE)) + goto Lnomatch; + else + { + e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); + } + } +#endif + #if LOGM // Print out the results printf("--------------------------\n"); @@ -674,7 +699,9 @@ /************************************************* * Match function arguments against a specific template function. * Input: + * loc instantiation location * targsi Expression/Type initial list of template arguments + * ethis 'this' argument if !NULL * fargs arguments to function * Output: * dedargs Expression/Type deduced template arguments @@ -682,7 +709,8 @@ * match level */ -MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, +MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi, + Expression *ethis, Expressions *fargs, Objects *dedargs) { size_t i; @@ -824,6 +852,27 @@ } L2: +#if DMDV2 + // Match 'ethis' to any TemplateThisParameter's + if (ethis) + { + for (size_t i = 0; i < parameters->dim; i++) + { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; + TemplateThisParameter *ttp = tp->isTemplateThisParameter(); + if (ttp) + { MATCH m; + + Type *t = new TypeIdentifier(0, ttp->ident); + m = ethis->type->deduceType(scope, t, parameters, &dedtypes); + if (!m) + goto Lnomatch; + if (m < match) + match = m; // pick worst match + } + } + } +#endif + // Loop through the function parameters for (i = 0; i < nfparams; i++) { @@ -982,7 +1031,7 @@ } } else - { oded = tp->defaultArg(paramscope); + { oded = tp->defaultArg(loc, paramscope); if (!oded) goto Lnomatch; } @@ -991,6 +1040,25 @@ } } +#if DMDV2 + if (constraint) + { /* Check to see if constraint is satisfied. + */ + Expression *e = constraint->syntaxCopy(); + paramscope->flags |= SCOPEstaticif; + e = e->semantic(paramscope); + e = e->optimize(WANTvalue | WANTinterpret); + if (e->isBool(TRUE)) + ; + else if (e->isBool(FALSE)) + goto Lnomatch; + else + { + e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); + } + } +#endif + #if 0 for (i = 0; i < dedargs->dim; i++) { Type *t = (Type *)dedargs->data[i]; @@ -1096,11 +1164,13 @@ * sc instantiation scope * loc instantiation location * targsi initial list of template arguments + * ethis if !NULL, the 'this' pointer argument * fargs arguments to function + * flags 1: do not issue error message on no match, just return NULL */ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, - Objects *targsi, Expressions *fargs) + Objects *targsi, Expression *ethis, Expressions *fargs, int flags) { MATCH m_best = MATCHnomatch; TemplateDeclaration *td_ambig = NULL; @@ -1142,7 +1212,7 @@ MATCH m; Objects dedargs; - m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs); + m = td->deduceFunctionTemplateMatch(loc, targsi, ethis, fargs, &dedargs); //printf("deduceFunctionTemplateMatch = %d\n", m); if (!m) // if no match continue; @@ -1207,14 +1277,26 @@ Lerror: { + HdrGenState hgs; + + OutBuffer bufa; + Objects *args = targsi; + if (args) + { for (int i = 0; i < args->dim; i++) + { + if (i) + bufa.writeByte(','); + Object *oarg = (Object *)args->data[i]; + ObjectToCBuffer(&bufa, &hgs, oarg); + } + } + OutBuffer buf; - HdrGenState hgs; - argExpTypesToCBuffer(&buf, fargs, &hgs); - error(loc, "cannot deduce template function from argument types (%s)", - buf.toChars()); - return NULL; + error(loc, "cannot deduce template function from argument types !(%s)(%s)", + bufa.toChars(), buf.toChars()); } + return NULL; } void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -1237,6 +1319,13 @@ tp->toCBuffer(buf, hgs); } buf->writeByte(')'); +#if DMDV2 + if (constraint) + { buf->writestring(" if ("); + constraint->toCBuffer(buf, hgs); + buf->writeByte(')'); + } +#endif if (hgs->hdrgen) { @@ -1271,6 +1360,13 @@ tp->toCBuffer(&buf, &hgs); } buf.writeByte(')'); +#if DMDV2 + if (constraint) + { buf.writestring(" if ("); + constraint->toCBuffer(&buf, &hgs); + buf.writeByte(')'); + } +#endif buf.writeByte(0); return (char *)buf.extractData(); } @@ -1323,9 +1419,11 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes) { - //printf("Type::deduceType()\n"); - //printf("\tthis = %d, ", ty); print(); - //printf("\ttparam = %d, ", tparam->ty); tparam->print(); +#if 0 + printf("Type::deduceType()\n"); + printf("\tthis = %d, ", ty); print(); + printf("\ttparam = %d, ", tparam->ty); tparam->print(); +#endif if (!tparam) goto Lnomatch; @@ -2027,7 +2125,7 @@ oarg = (Object *)tiargs->data[i]; else { // Get default argument instead - oarg = defaultArg(sc); + oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced @@ -2141,7 +2239,7 @@ } -Object *TemplateTypeParameter::defaultArg(Scope *sc) +Object *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc) { Type *t; @@ -2271,7 +2369,7 @@ oarg = (Object *)tiargs->data[i]; else { // Get default argument instead - oarg = defaultArg(sc); + oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced @@ -2357,7 +2455,7 @@ } -Object *TemplateAliasParameter::defaultArg(Scope *sc) +Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc) { Dsymbol *s = NULL; @@ -2485,7 +2583,7 @@ oarg = (Object *)tiargs->data[i]; else { // Get default argument instead - oarg = defaultArg(sc); + oarg = defaultArg(loc, sc); if (!oarg) { assert(i < dedtypes->dim); // It might have already been deduced @@ -2602,7 +2700,7 @@ } -Object *TemplateValueParameter::defaultArg(Scope *sc) +Object *TemplateValueParameter::defaultArg(Loc loc, Scope *sc) { Expression *e = defaultValue; if (e) @@ -2748,7 +2846,7 @@ } -Object *TemplateTupleParameter::defaultArg(Scope *sc) +Object *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc) { return NULL; } @@ -2778,6 +2876,10 @@ this->tinst = NULL; } +/***************** + * This constructor is only called when we figured out which function + * template to instantiate. + */ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs) : ScopeDsymbol(NULL) @@ -2830,7 +2932,6 @@ Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s) { TemplateInstance *ti; - int i; if (s) ti = (TemplateInstance *)s; @@ -2896,7 +2997,9 @@ } else { - // Run semantic on each argument, place results in tiargs[] + /* Run semantic on each argument, place results in tiargs[] + * (if we havetempdecl, then tiargs is already evaluated) + */ semanticTiargs(sc); tempdecl = findTemplateDeclaration(sc); @@ -2974,12 +3077,26 @@ #if 1 int dosemantic3 = 0; { Array *a; - int i; - - if (sc->scopesym && sc->scopesym->members && !sc->scopesym->isTemplateMixin()) + + Scope *scx = sc; +#if 0 + for (scx = sc; scx; scx = scx->enclosing) + if (scx->scopesym) + break; +#endif + + //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); + if (scx && scx->scopesym && + scx->scopesym->members && !scx->scopesym->isTemplateMixin() && + /* The following test should really be if scx->module recursively + * imports itself. Because if it does, see bugzilla 2500. + */ + //scx->module == tempdecl->getModule() + !scx->module->imports(scx->module) + ) { - //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); - a = sc->scopesym->members; + //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); + a = scx->scopesym->members; } else { Module *m = sc->module->importedFrom; @@ -3395,19 +3512,15 @@ return NULL; } m = td->matchWithInstance(this, &dedtypes, 0); - //printf("m = %d\n", m); + //printf("matchWithInstance = %d\n", m); if (!m) // no match at all continue; -#if 1 if (m < m_best) goto Ltd_best; if (m > m_best) goto Ltd; -#else - if (!m_best) - goto Ltd; -#endif + { // Disambiguate by picking the most specialized TemplateDeclaration int c1 = td->leastAsSpecialized(td_best); @@ -3656,6 +3769,7 @@ buf.writeByte('Z'); id = buf.toChars(); buf.data = NULL; + //printf("\tgenIdent = %s\n", id); return new Identifier(id, TOKidentifier); } @@ -3672,7 +3786,7 @@ { TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i]; //Object *o = (Object *)tiargs->data[i]; - Object *o = (Object *)tdtypes.data[i]; + Object *o = (Object *)tdtypes.data[i]; // initializer for tp //printf("\ttdtypes[%d] = %p\n", i, o); tempdecl->declareParameter(scope, tp, o);