Mercurial > projects > ldc
diff dmd/template.c @ 1195:e961851fb8be
Merged DMD 1.042.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Fri, 03 Apr 2009 17:59:34 +0200 |
parents | 0b26cfb2d445 |
children | 8026319762be |
line wrap: on
line diff
--- a/dmd/template.c Fri Apr 03 17:02:52 2009 +0200 +++ b/dmd/template.c Fri Apr 03 17:59:34 2009 +0200 @@ -14,12 +14,7 @@ #include <assert.h> #if !IN_LLVM -#if _WIN32 -#include <windows.h> -long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); #endif -#endif - #include "root.h" #include "rmem.h" #include "stringtable.h" @@ -36,6 +31,11 @@ #include "dsymbol.h" #include "hdrgen.h" +#if WINDOWS_SEH +#include <windows.h> +long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); +#endif + #define LOG 0 /******************************************** @@ -159,6 +159,8 @@ } } + //printf("t1 = %s\n", t1->toChars()); + //printf("t2 = %s\n", t2->toChars()); if (!t2 || !t1->equals(t2)) goto Lnomatch; } @@ -186,7 +188,7 @@ { goto Lnomatch; } -#if V2 +#if DMDV2 VarDeclaration *v1 = s1->isVarDeclaration(); VarDeclaration *v2 = s2->isVarDeclaration(); if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) @@ -263,7 +265,7 @@ } } -#if V2 +#if DMDV2 Object *objectSyntaxCopy(Object *o) { if (!o) @@ -281,7 +283,8 @@ /* ======================== TemplateDeclaration ============================= */ -TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs) +TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, + TemplateParameters *parameters, Expression *constraint, Array *decldefs) : ScopeDsymbol(id) { #if LOG @@ -303,9 +306,7 @@ this->loc = loc; this->parameters = parameters; this->origParameters = parameters; -#if V2 this->constraint = constraint; -#endif this->members = decldefs; this->overnext = NULL; this->overroot = NULL; @@ -330,13 +331,11 @@ p->data[i] = (void *)tp->syntaxCopy(); } } -#if V2 Expression *e = NULL; if (constraint) e = constraint->syntaxCopy(); -#endif d = Dsymbol::arraySyntaxCopy(members); - td = new TemplateDeclaration(loc, ident, p, d); + td = new TemplateDeclaration(loc, ident, p, e, d); #if IN_LLVM // LDC @@ -673,11 +672,11 @@ /******************************************** * Determine partial specialization order of 'this' vs td2. * Returns: - * 1 this is at least as specialized as td2 + * match this is at least as specialized as td2 * 0 td2 is more specialized than this */ -int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2) +MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2) { /* This works by taking the template parameters to this template * declaration and feeding them to td2 as if it were a template @@ -715,7 +714,8 @@ dedtypes.setDim(td2->parameters->dim); // Attempt a type deduction - if (td2->matchWithInstance(&ti, &dedtypes, 1)) + MATCH m = td2->matchWithInstance(&ti, &dedtypes, 1); + if (m) { /* A non-variadic template is more specialized than a * variadic one. @@ -724,15 +724,15 @@ goto L1; #if LOG_LEASTAS - printf(" matches, so is least as specialized\n"); + printf(" matches %d, so is least as specialized\n", m); #endif - return 1; + return m; } L1: #if LOG_LEASTAS printf(" doesn't match, so is not as specialized\n"); #endif - return 0; + return MATCHnomatch; } @@ -762,7 +762,6 @@ MATCH match = MATCHexact; FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); TypeFunction *fdtype; // type of fd - TemplateTupleParameter *tp; Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T #if 0 @@ -786,7 +785,18 @@ paramsym->parent = scope->parent; Scope *paramscope = scope->push(paramsym); - tp = isVariadic(); + TemplateTupleParameter *tp = isVariadic(); + +#if 0 + for (i = 0; i < dedargs->dim; i++) + { + printf("\tdedarg[%d] = ", i); + Object *oarg = (Object *)dedargs->data[i]; + if (oarg) printf("%s", oarg->toChars()); + printf("\n"); + } +#endif + nargsi = 0; if (targsi) @@ -802,11 +812,11 @@ memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); - for (i = 0; i < nargsi; i++) + for (size_t i = 0; i < nargsi; i++) { assert(i < parameters->dim); TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; MATCH m; - Declaration *sparam; + Declaration *sparam = NULL; m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); //printf("\tdeduceType m = %d\n", m); @@ -820,6 +830,15 @@ goto Lnomatch; } } +#if 0 + for (i = 0; i < dedargs->dim; i++) + { + printf("\tdedarg[%d] = ", i); + Object *oarg = (Object *)dedargs->data[i]; + if (oarg) printf("%s", oarg->toChars()); + printf("\n"); + } +#endif assert(fd->type->ty == Tfunction); fdtype = (TypeFunction *)fd->type; @@ -833,7 +852,6 @@ * template Foo(T, A...) { void Foo(T t, A a); } * void main() { Foo(1,2,3); } */ - tp = isVariadic(); if (tp) // if variadic { if (nfparams == 0) // if no function parameters @@ -906,7 +924,7 @@ { MATCH m; Type *t = new TypeIdentifier(0, ttp->ident); - m = ethis->type->deduceType(scope, t, parameters, &dedtypes); + m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes); if (!m) goto Lnomatch; if (m < match) @@ -946,9 +964,25 @@ printf("\tfarg->type = %s\n", farg->type->toChars()); printf("\tfparam->type = %s\n", fparam->type->toChars()); #endif + Type *argtype = farg->type; + +#if DMDV2 + /* Allow string literals which are type [] to match with [dim] + */ + if (farg->op == TOKstring) + { StringExp *se = (StringExp *)farg; + if (!se->committed && argtype->ty == Tarray && + fparam->type->toBasetype()->ty == Tsarray) + { + argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex)); + argtype = argtype->semantic(se->loc, NULL); + argtype = argtype->invariantOf(); + } + } +#endif MATCH m; - m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes); + m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes); //printf("\tdeduceType m = %d\n", m); /* If no match, see if there's a conversion to a delegate @@ -960,7 +994,7 @@ if (!tf->varargs && Argument::dim(tf->parameters) == 0) { - m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes); + m = farg->type->deduceType(paramscope, tf->next, parameters, &dedtypes); if (!m && tf->next->toBasetype()->ty == Tvoid) m = MATCHconvert; } @@ -988,7 +1022,7 @@ // Perhaps we can do better with this, see TypeFunction::callMatch() case Tsarray: { TypeSArray *tsa = (TypeSArray *)tb; - integer_t sz = tsa->dim->toInteger(); + dinteger_t sz = tsa->dim->toInteger(); if (sz != nfargs - i) goto Lnomatch; } @@ -1020,7 +1054,7 @@ } else { - m = arg->type->deduceType(scope, ta->next, parameters, &dedtypes); + m = arg->type->deduceType(paramscope, ta->next, parameters, &dedtypes); //m = arg->implicitConvTo(ta->next); } if (m == MATCHnomatch) @@ -1053,6 +1087,8 @@ Object *oarg = (Object *)dedargs->data[i]; Object *oded = (Object *)dedtypes.data[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()); if (!oarg) { if (oded) @@ -1134,6 +1170,22 @@ Dsymbol *s; + // See if tp->ident already exists with a matching definition + Dsymbol *scopesym; + s = sc->search(loc, tp->ident, &scopesym); + if (s && scopesym == sc->scopesym) + { + TupleDeclaration *td = s->isTupleDeclaration(); + if (va && td) + { Tuple tup; + tup.objects = *td->objects; + if (match(va, &tup, this, sc)) + { + return; + } + } + } + if (targ) { //printf("type %s\n", targ->toChars()); @@ -1267,8 +1319,8 @@ { // Disambiguate by picking the most specialized TemplateDeclaration - int c1 = td->leastAsSpecialized(td_best); - int c2 = td_best->leastAsSpecialized(td); + MATCH c1 = td->leastAsSpecialized(td_best); + MATCH c2 = td_best->leastAsSpecialized(td); //printf("c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) @@ -1298,7 +1350,7 @@ } if (!td_best) { - error(loc, "does not match any template declaration"); + error(loc, "does not match any function template declaration"); goto Lerror; } if (td_ambig) @@ -1319,6 +1371,9 @@ return fd; Lerror: +#if DMDV2 + if (!(flags & 1)) +#endif { HdrGenState hgs; @@ -1537,8 +1592,29 @@ Lnomatch: return MATCHnomatch; + +#if DMDV2 +Lconst: + return MATCHconst; +#endif } +#if DMDV2 +MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, + Objects *dedtypes) +{ +#if 0 + printf("TypeDArray::deduceType()\n"); + printf("\tthis = %d, ", ty); print(); + printf("\ttparam = %d, ", tparam->ty); tparam->print(); +#endif + return Type::deduceType(sc, tparam, parameters, dedtypes); + + Lnomatch: + return MATCHnomatch; +} +#endif + MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes) { @@ -1765,8 +1841,11 @@ Type *tparam, TemplateParameters *parameters, Objects *dedtypes) { - //printf("TypeInstance::deduceType(tparam = %s) %s\n", tparam->toChars(), toChars()); - //printf("\ttparam = %d, ", tparam->ty); tparam->print(); +#if 0 + printf("TypeInstance::deduceType()\n"); + printf("\tthis = %d, ", ty); print(); + printf("\ttparam = %d, ", tparam->ty); tparam->print(); +#endif // Extra check if (tparam && tparam->ty == Tinstance) @@ -1802,14 +1881,14 @@ TemplateAliasParameter *ta = tpx->isTemplateAliasParameter(); if (!ta) goto Lnomatch; - Dsymbol *sa = tempinst->tempdecl; + Object *sa = tempinst->tempdecl; if (!sa) goto Lnomatch; if (ta->specAlias && sa != ta->specAlias) goto Lnomatch; if (dedtypes->data[i]) { // Must match already deduced symbol - Dsymbol *s = (Dsymbol *)dedtypes->data[i]; + Object *s = (Object *)dedtypes->data[i]; if (s != sa) goto Lnomatch; @@ -1821,12 +1900,13 @@ goto Lnomatch; L2: - if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim) - goto Lnomatch; for (int i = 0; i < tempinst->tiargs->dim; i++) { //printf("\ttest: tempinst->tiargs[%d]\n", i); + 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]; @@ -1853,6 +1933,43 @@ if (v2) printf("v2 = %s\n", v2->toChars()); #endif + TemplateTupleParameter *ttp; + if (t2 && + t2->ty == Tident && + i == tp->tempinst->tiargs->dim - 1 && + i == tempinst->tempdecl->parameters->dim - 1 && + (ttp = tempinst->tempdecl->isVariadic()) != NULL) + { + /* Given: + * struct A(B...) {} + * alias A!(int, float) X; + * static if (!is(X Y == A!(Z), Z)) + * deduce that Z is a tuple(int, float) + */ + + j = templateParameterLookup(t2, parameters); + if (j == -1) + goto Lnomatch; + + /* Create tuple from remaining args + */ + Tuple *vt = new Tuple(); + int 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]; + + Tuple *v = (Tuple *)dedtypes->data[j]; + if (v) + { + if (!match(v, vt, tempinst->tempdecl, sc)) + goto Lnomatch; + } + else + dedtypes->data[j] = vt; + break; //return MATCHexact; + } + if (t1 && t2) { if (!t1->deduceType(sc, t2, parameters, dedtypes)) @@ -3299,12 +3416,10 @@ sc2->parent = /*isnested ? sc->parent :*/ this; sc2->tinst = this; -#if !IN_LLVM -#if _WIN32 +#if WINDOWS_SEH __try { #endif -#endif for (int i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; @@ -3317,8 +3432,7 @@ //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); sc2->module->runDeferredSemantic(); } -#if !IN_LLVM -#if _WIN32 +#if WINDOWS_SEH } __except (__ehfilter(GetExceptionInformation())) { @@ -3327,7 +3441,6 @@ fatal(); } #endif -#endif /* If any of the instantiation members didn't get semantic() run * on them due to forward references, we cannot run semantic2() @@ -3385,10 +3498,15 @@ if (semantictiargsdone) return; semantictiargsdone = 1; - semanticTiargs(loc, sc, tiargs); + semanticTiargs(loc, sc, tiargs, 0); } -void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs) +/********************************** + * Input: + * flags 1: replace const variables with their initializers + */ + +void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) { // Run semantic on each argument, place results in tiargs[] //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); @@ -3636,8 +3754,8 @@ { // Disambiguate by picking the most specialized TemplateDeclaration - int c1 = td->leastAsSpecialized(td_best); - int c2 = td_best->leastAsSpecialized(td); + MATCH c1 = td->leastAsSpecialized(td_best); + MATCH c2 = td_best->leastAsSpecialized(td); //printf("c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) @@ -3667,7 +3785,11 @@ if (!td_best) { - error("%s does not match any template declaration", toChars()); + if (tempdecl && !tempdecl->overnext) + // Only one template, so we can give better error message + error("%s does not match template declaration %s", toChars(), tempdecl->toChars()); + else + error("%s does not match any template declaration", toChars()); return NULL; } if (td_ambig) @@ -3777,7 +3899,7 @@ nested |= 1; } else - error("cannot use local '%s' as template parameter", d->toChars()); + error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); } } else if (va)