From 7022704598afdef58a2c433119a530b768e6f78d Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Fri, 22 Apr 2011 18:54:58 +0200 Subject: [PATCH] Merged DMD commit b785b0522f40676c608b1b68aa56a8f806f55175: improve template arg match --- dmd/template.c | 104 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 14 deletions(-) diff --git a/dmd/template.c b/dmd/template.c index 8457a1a5..f4b0aecd 100644 --- a/dmd/template.c +++ b/dmd/template.c @@ -213,21 +213,31 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc) } else if (s1) { - //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); - if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) + //printf("%p %s %s, %p %s %s\n", s1, s1->kind(), s1->toChars(), s2, s2->kind(), s2->toChars()); + if (!s2) { goto Lnomatch; } + if (!s1->equals(s2)) + { #if DMDV2 - VarDeclaration *v1 = s1->isVarDeclaration(); - VarDeclaration *v2 = s2->isVarDeclaration(); - if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) - { ExpInitializer *ei1 = v1->init->isExpInitializer(); - ExpInitializer *ei2 = v2->init->isExpInitializer(); - if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) + VarDeclaration *v1 = s1->isVarDeclaration(); + VarDeclaration *v2 = s2->isVarDeclaration(); + if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) + { ExpInitializer *ei1 = v1->init->isExpInitializer(); + ExpInitializer *ei2 = v2->init->isExpInitializer(); + if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) + goto Lnomatch; + goto Lmatch; + } + else +#endif goto Lnomatch; } -#endif + if (s1->parent != s2->parent) + { + goto Lnomatch; + } } else if (v1) { @@ -243,6 +253,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc) goto Lnomatch; } } +Lmatch: //printf("match\n"); return 1; // match Lnomatch: @@ -250,6 +261,28 @@ Lnomatch: return 0; // nomatch; } + +/************************************ + * Match an array of them. + * This should match what genIdent() does. + */ +int arrayObjectMatch(Objects *oa1, Objects *oa2, TemplateDeclaration *tempdecl, Scope *sc) +{ + if (oa1 == oa2) + return 1; + if (oa1->dim != oa2->dim) + return 0; + for (size_t j = 0; j < oa1->dim; j++) + { Object *o1 = (Object *)oa1->data[j]; + Object *o2 = (Object *)oa2->data[j]; + if (!match(o1, o2, tempdecl, sc)) + { + return 0; + } + } + return 1; +} + /**************************************** */ @@ -349,7 +382,6 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) //printf("TemplateDeclaration::syntaxCopy()\n"); TemplateDeclaration *td; TemplateParameters *p; - Array *d; p = NULL; if (parameters) @@ -364,7 +396,7 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) Expression *e = NULL; if (constraint) e = constraint->syntaxCopy(); - d = Dsymbol::arraySyntaxCopy(members); + Array *d = Dsymbol::arraySyntaxCopy(members); td = new TemplateDeclaration(loc, ident, p, e, d); #if IN_LLVM @@ -379,6 +411,8 @@ void TemplateDeclaration::semantic(Scope *sc) { #if LOG printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars()); + printf("sc->stc = %llx\n", sc->stc); + printf("sc->module = %s\n", sc->module->toChars()); #endif if (semanticRun) return; // semantic() already run @@ -955,9 +989,9 @@ L1: L2: #if DMDV2 - // Match 'ethis' to any TemplateThisParameter's if (ethis) { + // Match 'ethis' to any TemplateThisParameter's for (size_t i = 0; i < parameters->dim; i++) { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; TemplateThisParameter *ttp = tp->isTemplateThisParameter(); @@ -972,6 +1006,34 @@ L2: match = m; // pick worst match } } + + // Match attributes of ethis against attributes of fd + if (fd->type) + { + Type *tthis = ethis->type; + unsigned mod = fd->type->mod; + StorageClass stc = scope->stc; + if (stc & (STCshared | STCsynchronized)) + mod |= MODshared; + if (stc & STCimmutable) + mod |= MODimmutable; + if (stc & STCconst) + mod |= MODconst; + if (stc & STCwild) + mod |= MODwild; + // Fix mod + if (mod & MODimmutable) + mod = MODimmutable; + if (mod & MODconst) + mod &= ~STCwild; + if (tthis->mod != mod) + { + if (!MODimplicitConv(tthis->mod, mod)) + goto Lnomatch; + if (MATCHconst < match) + match = MATCHconst; + } + } } #endif @@ -1338,6 +1400,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, printf("\t%s %s\n", arg->type->toChars(), arg->toChars()); //printf("\tty = %d\n", arg->type->ty); } + printf("stc = %llx\n", scope->stc); #endif for (TemplateDeclaration *td = this; td; td = td->overnext) @@ -1632,8 +1695,14 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, } if (ty != tparam->ty) - return implicitConvTo(tparam); -// goto Lnomatch; + { +#if DMDV2 + // Can't instantiate AssociativeArray!() without a scope + if (tparam->ty == Taarray && !((TypeAArray*)tparam)->sc) + ((TypeAArray*)tparam)->sc = sc; +#endif + return implicitConvTo(tparam); + } if (nextOf()) return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes); @@ -1802,6 +1871,8 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para * of the type of the last function parameter. */ Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1); + assert(fparam); + assert(fparam->type); if (fparam->type->ty != Tident) goto L1; TypeIdentifier *tid = (TypeIdentifier *)fparam->type; @@ -2107,6 +2178,7 @@ MATCH TypeInstance::deduceType(Scope *sc, return Type::deduceType(sc, tparam, parameters, dedtypes); Lnomatch: + //printf("no match\n"); return MATCHnomatch; } @@ -2465,6 +2537,7 @@ Lnomatch: * parameters[] template parameters * dedtypes[] deduced arguments to template instance * *psparam set to symbol declared and initialized to dedtypes[i] + * flags 1: don't do 'toHeadMutable()' */ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, @@ -3345,6 +3418,9 @@ void TemplateInstance::semantic(Scope *sc) if (semanticRun != 0) { +#if LOG + printf("Recursive template expansion\n"); +#endif error(loc, "recursive template expansion"); // inst = this; return;