Merged DMD commit b785b0522f40676c608b1b68aa56a8f806f55175:

improve template arg match
This commit is contained in:
David Nadlinger
2011-04-22 18:54:58 +02:00
parent b937eacc69
commit 7022704598

View File

@@ -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;