mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-21 22:23:14 +01:00
Merged DMD commit b785b0522f40676c608b1b68aa56a8f806f55175:
improve template arg match
This commit is contained in:
104
dmd/template.c
104
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;
|
||||
|
||||
Reference in New Issue
Block a user