mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-09 17:04:12 +02:00
[svn r175] merged dmd 1.029
This commit is contained in:
264
dmd/template.c
264
dmd/template.c
@@ -130,6 +130,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
Dsymbol *s2 = isDsymbol(o2);
|
||||
Tuple *v1 = isTuple(o1);
|
||||
Tuple *v2 = isTuple(o2);
|
||||
//printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2);
|
||||
|
||||
/* A proper implementation of the various equals() overrides
|
||||
* should make it possible to just do o1->equals(o2), but
|
||||
@@ -158,7 +159,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
}
|
||||
|
||||
if (!t2 || !t1->equals(t2))
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (e1)
|
||||
{
|
||||
@@ -168,33 +169,39 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
printf("match %d\n", e1->equals(e2));
|
||||
e1->print();
|
||||
e2->print();
|
||||
e1->type->print();
|
||||
e2->type->print();
|
||||
}
|
||||
#endif
|
||||
if (!e2 || !e1->equals(e2))
|
||||
goto L1;
|
||||
if (!e2)
|
||||
goto Lnomatch;
|
||||
if (!e1->equals(e2))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else if (s1)
|
||||
{
|
||||
//printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
|
||||
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
|
||||
goto L1;
|
||||
{
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
else if (v1)
|
||||
{
|
||||
if (!v2)
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
if (v1->objects.dim != v2->objects.dim)
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
for (size_t i = 0; i < v1->objects.dim; i++)
|
||||
{
|
||||
if (!match((Object *)v1->objects.data[i],
|
||||
(Object *)v2->objects.data[i],
|
||||
tempdecl, sc))
|
||||
goto L1;
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
return 1; // match
|
||||
L1:
|
||||
Lnomatch:
|
||||
return 0; // nomatch;
|
||||
}
|
||||
|
||||
@@ -268,6 +275,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
|
||||
#endif
|
||||
this->loc = loc;
|
||||
this->parameters = parameters;
|
||||
this->origParameters = parameters;
|
||||
this->members = decldefs;
|
||||
this->overnext = NULL;
|
||||
this->overroot = NULL;
|
||||
@@ -336,6 +344,17 @@ void TemplateDeclaration::semantic(Scope *sc)
|
||||
Scope *paramscope = sc->push(paramsym);
|
||||
paramscope->parameterSpecialization = 1;
|
||||
|
||||
if (global.params.doDocComments)
|
||||
{
|
||||
origParameters = new TemplateParameters();
|
||||
origParameters->setDim(parameters->dim);
|
||||
for (int i = 0; i < parameters->dim; i++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
origParameters->data[i] = (void *)tp->syntaxCopy();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < parameters->dim; i++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
@@ -348,6 +367,8 @@ void TemplateDeclaration::semantic(Scope *sc)
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
|
||||
tp->semantic(paramscope);
|
||||
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
|
||||
error("template tuple parameter must be last one");
|
||||
}
|
||||
|
||||
paramscope->pop();
|
||||
@@ -437,6 +458,7 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s)
|
||||
* those deduced types in dedtypes[].
|
||||
* Input:
|
||||
* flag 1: don't do semantic() because of dummy types
|
||||
* 2: don't change types in matchArg()
|
||||
* Output:
|
||||
* dedtypes deduced arguments
|
||||
* Return match level.
|
||||
@@ -447,8 +469,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
{ MATCH m;
|
||||
int dedtypes_dim = dedtypes->dim;
|
||||
|
||||
#if LOG
|
||||
printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||
#define LOGM 0
|
||||
#if LOGM
|
||||
printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@@ -466,7 +489,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
// If more arguments than parameters, no match
|
||||
if (ti->tiargs->dim > parameters_dim && !variadic)
|
||||
{
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" no match: more arguments than parameters\n");
|
||||
#endif
|
||||
return MATCHnomatch;
|
||||
@@ -489,7 +512,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
Declaration *sparam;
|
||||
|
||||
//printf("\targument [%d]\n", i);
|
||||
#if 0
|
||||
#if LOGM
|
||||
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
||||
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
|
||||
if (ttp)
|
||||
@@ -528,7 +551,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if LOGM
|
||||
// Print out the results
|
||||
printf("--------------------------\n");
|
||||
printf("template %s\n", toChars());
|
||||
@@ -553,20 +576,20 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
||||
goto Lnomatch;
|
||||
#endif
|
||||
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" match = %d\n", m);
|
||||
#endif
|
||||
goto Lret;
|
||||
|
||||
Lnomatch:
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf(" no match\n");
|
||||
#endif
|
||||
m = MATCHnomatch;
|
||||
|
||||
Lret:
|
||||
paramscope->pop();
|
||||
#if LOG
|
||||
#if LOGM
|
||||
printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
|
||||
#endif
|
||||
return m;
|
||||
@@ -645,6 +668,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
|
||||
* fargs arguments to function
|
||||
* Output:
|
||||
* dedargs Expression/Type deduced template arguments
|
||||
* Returns:
|
||||
* match level
|
||||
*/
|
||||
|
||||
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
|
||||
@@ -652,12 +677,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
{
|
||||
size_t i;
|
||||
size_t nfparams;
|
||||
size_t nfparams2;
|
||||
size_t nfargs;
|
||||
size_t nargsi;
|
||||
size_t nargsi; // array size of targsi
|
||||
int fptupindex = -1;
|
||||
int tuple_dim = 0;
|
||||
MATCH match = MATCHexact;
|
||||
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
|
||||
TypeFunction *fdtype;
|
||||
TypeFunction *fdtype; // type of fd
|
||||
TemplateTupleParameter *tp;
|
||||
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
|
||||
|
||||
@@ -682,13 +708,19 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
paramsym->parent = scope->parent;
|
||||
Scope *paramscope = scope->push(paramsym);
|
||||
|
||||
tp = isVariadic();
|
||||
|
||||
nargsi = 0;
|
||||
if (targsi)
|
||||
{ // Set initial template arguments
|
||||
|
||||
nargsi = targsi->dim;
|
||||
if (nargsi > parameters->dim)
|
||||
goto Lnomatch;
|
||||
{ if (!tp)
|
||||
goto Lnomatch;
|
||||
dedargs->setDim(nargsi);
|
||||
dedargs->zero();
|
||||
}
|
||||
|
||||
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
|
||||
|
||||
@@ -698,6 +730,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
Declaration *sparam;
|
||||
|
||||
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
||||
//printf("\tdeduceType m = %d\n", m);
|
||||
if (m == MATCHnomatch)
|
||||
goto Lnomatch;
|
||||
if (m < match)
|
||||
@@ -713,7 +746,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
fdtype = (TypeFunction *)fd->type;
|
||||
|
||||
nfparams = Argument::dim(fdtype->parameters); // number of function parameters
|
||||
nfparams2 = nfparams;
|
||||
nfargs = fargs->dim; // number of function arguments
|
||||
|
||||
/* Check for match of function arguments with variadic template
|
||||
@@ -723,7 +755,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
* void main() { Foo(1,2,3); }
|
||||
*/
|
||||
tp = isVariadic();
|
||||
if (tp)
|
||||
if (tp) // if variadic
|
||||
{
|
||||
if (nfparams == 0) // if no function parameters
|
||||
{
|
||||
@@ -736,33 +768,38 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
||||
goto L1;
|
||||
else
|
||||
{
|
||||
/* See if 'A' of the template parameter matches 'A'
|
||||
* of the type of the last function parameter.
|
||||
/* Figure out which of the function parameters matches
|
||||
* the tuple template parameter. Do this by matching
|
||||
* type identifiers.
|
||||
* Set the index of this function parameter to fptupindex.
|
||||
*/
|
||||
Argument *fparam = (Argument *)fdtype->parameters->data[nfparams - 1];
|
||||
if (fparam->type->ty != Tident)
|
||||
goto L1;
|
||||
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
||||
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
||||
goto L1;
|
||||
for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
|
||||
{
|
||||
Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
|
||||
if (fparam->type->ty != Tident)
|
||||
continue;
|
||||
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
||||
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
||||
continue;
|
||||
|
||||
if (fdtype->varargs) // variadic function doesn't
|
||||
goto Lnomatch; // go with variadic template
|
||||
if (fdtype->varargs) // variadic function doesn't
|
||||
goto Lnomatch; // go with variadic template
|
||||
|
||||
/* The types of the function arguments [nfparams - 1 .. nfargs]
|
||||
* now form the tuple argument.
|
||||
*/
|
||||
Tuple *t = new Tuple();
|
||||
dedargs->data[parameters->dim - 1] = (void *)t;
|
||||
/* The types of the function arguments
|
||||
* now form the tuple argument.
|
||||
*/
|
||||
Tuple *t = new Tuple();
|
||||
dedargs->data[parameters->dim - 1] = (void *)t;
|
||||
|
||||
int tuple_dim = nfargs - (nfparams - 1);
|
||||
t->objects.setDim(tuple_dim);
|
||||
for (i = 0; i < tuple_dim; i++)
|
||||
{ Expression *farg = (Expression *)fargs->data[nfparams - 1 + i];
|
||||
t->objects.data[i] = (void *)farg->type;
|
||||
tuple_dim = nfargs - (nfparams - 1);
|
||||
t->objects.setDim(tuple_dim);
|
||||
for (i = 0; i < tuple_dim; i++)
|
||||
{ Expression *farg = (Expression *)fargs->data[fptupindex + i];
|
||||
t->objects.data[i] = (void *)farg->type;
|
||||
}
|
||||
goto L2;
|
||||
}
|
||||
nfparams2--; // don't consider the last parameter for type deduction
|
||||
goto L2;
|
||||
fptupindex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,11 +815,19 @@ L1:
|
||||
|
||||
L2:
|
||||
// Loop through the function parameters
|
||||
for (i = 0; i < nfparams2; i++)
|
||||
for (i = 0; i < nfparams; i++)
|
||||
{
|
||||
/* Skip over function parameters which wound up
|
||||
* as part of a template tuple parameter.
|
||||
*/
|
||||
if (i == fptupindex)
|
||||
{ if (fptupindex == nfparams - 1)
|
||||
break;
|
||||
i += tuple_dim - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
Argument *fparam = Argument::getNth(fdtype->parameters, i);
|
||||
Expression *farg;
|
||||
MATCH m;
|
||||
|
||||
if (i >= nfargs) // if not enough arguments
|
||||
{
|
||||
@@ -794,12 +839,13 @@ L2:
|
||||
}
|
||||
}
|
||||
else
|
||||
{ farg = (Expression *)fargs->data[i];
|
||||
{ Expression *farg = (Expression *)fargs->data[i];
|
||||
#if 0
|
||||
printf("\tfarg->type = %s\n", farg->type->toChars());
|
||||
printf("\tfparam->type = %s\n", fparam->type->toChars());
|
||||
#endif
|
||||
|
||||
MATCH m;
|
||||
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
|
||||
//printf("\tdeduceType m = %d\n", m);
|
||||
|
||||
@@ -852,30 +898,40 @@ Lmatch:
|
||||
for (i = nargsi; i < dedargs->dim; i++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
//printf("tp[%d] = %s\n", i, tp->ident->toChars());
|
||||
/* For T:T*, the dedargs is the T*, dedtypes is the T
|
||||
* But for function templates, we really need them to match
|
||||
*/
|
||||
Object *oarg = (Object *)dedargs->data[i];
|
||||
Object *o = (Object *)dedtypes.data[i];
|
||||
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, o);
|
||||
Object *oded = (Object *)dedtypes.data[i];
|
||||
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
|
||||
if (!oarg)
|
||||
{
|
||||
if (o)
|
||||
if (oded)
|
||||
{
|
||||
if (tp->specialization())
|
||||
error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
|
||||
{ /* The specialization can work as long as afterwards
|
||||
* the oded == oarg
|
||||
*/
|
||||
Declaration *sparam;
|
||||
dedargs->data[i] = (void *)oded;
|
||||
MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
||||
//printf("m2 = %d\n", m2);
|
||||
if (!m2)
|
||||
goto Lnomatch;
|
||||
if (m2 < match)
|
||||
match = m2; // pick worst match
|
||||
if (dedtypes.data[i] != oded)
|
||||
error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{ o = tp->defaultArg(paramscope);
|
||||
if (!o)
|
||||
{ oded = tp->defaultArg(paramscope);
|
||||
if (!oded)
|
||||
goto Lnomatch;
|
||||
#if 0
|
||||
Match m;
|
||||
Declaration *sparam;
|
||||
m = tp->matchArg(paramscope, dedargs, i, parameters, &sparam);
|
||||
if (!m)
|
||||
goto Lnomatch;
|
||||
#endif
|
||||
}
|
||||
declareParameter(paramscope, tp, o);
|
||||
dedargs->data[i] = (void *)o;
|
||||
declareParameter(paramscope, tp, oded);
|
||||
dedargs->data[i] = (void *)oded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,7 +943,7 @@ Lmatch:
|
||||
#endif
|
||||
|
||||
paramscope->pop();
|
||||
//printf("\tmatch\n");
|
||||
//printf("\tmatch %d\n", match);
|
||||
return match;
|
||||
|
||||
Lnomatch:
|
||||
@@ -1044,9 +1100,9 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
|
||||
int c2 = td_best->leastAsSpecialized(td);
|
||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||
|
||||
if (c1 && !c2)
|
||||
if (c1 > c2)
|
||||
goto Ltd;
|
||||
else if (!c1 && c2)
|
||||
else if (c1 < c2)
|
||||
goto Ltd_best;
|
||||
else
|
||||
goto Lambig;
|
||||
@@ -1116,6 +1172,8 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
for (int i = 0; i < parameters->dim; i++)
|
||||
{
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
if (hgs->ddoc)
|
||||
tp = (TemplateParameter *)origParameters->data[i];
|
||||
if (i)
|
||||
buf->writeByte(',');
|
||||
tp->toCBuffer(buf, hgs);
|
||||
@@ -1516,7 +1574,19 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
*/
|
||||
int i = templateIdentifierLookup(tp->tempinst->name, parameters);
|
||||
if (i == -1)
|
||||
{ /* Didn't find it as a parameter identifier. Try looking
|
||||
* it up and seeing if is an alias. See Bugzilla 1454
|
||||
*/
|
||||
Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
|
||||
if (s)
|
||||
{
|
||||
s = s->toAlias();
|
||||
TemplateDeclaration *td = s->isTemplateDeclaration();
|
||||
if (td && td == tempinst->tempdecl)
|
||||
goto L2;
|
||||
}
|
||||
goto Lnomatch;
|
||||
}
|
||||
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
|
||||
// This logic duplicates tpx->matchArg()
|
||||
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
|
||||
@@ -1540,12 +1610,14 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
else if (tempinst->tempdecl != tp->tempinst->tempdecl)
|
||||
goto Lnomatch;
|
||||
|
||||
L2:
|
||||
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
|
||||
goto Lnomatch;
|
||||
|
||||
for (int i = 0; i < tempinst->tiargs->dim; i++)
|
||||
{
|
||||
//printf("test: [%d]\n", i);
|
||||
//printf("\ttest: tempinst->tiargs[%d]\n", i);
|
||||
int j;
|
||||
Object *o1 = (Object *)tempinst->tiargs->data[i];
|
||||
Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
|
||||
|
||||
@@ -1570,18 +1642,29 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
else if (e1 && e2)
|
||||
{
|
||||
if (!e1->equals(e2))
|
||||
{ if (e2->op == TOKvar)
|
||||
{
|
||||
/*
|
||||
* (T:Number!(e2), int e2)
|
||||
*/
|
||||
j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
|
||||
goto L1;
|
||||
}
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
else if (e1 && t2 && t2->ty == Tident)
|
||||
{ int i = templateParameterLookup(t2, parameters);
|
||||
if (i == -1)
|
||||
{
|
||||
j = templateParameterLookup(t2, parameters);
|
||||
L1:
|
||||
if (j == -1)
|
||||
goto Lnomatch;
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
|
||||
// BUG: use tp->matchArg() instead of the following
|
||||
TemplateValueParameter *tv = tp->isTemplateValueParameter();
|
||||
if (!tv)
|
||||
goto Lnomatch;
|
||||
Expression *e = (Expression *)dedtypes->data[i];
|
||||
Expression *e = (Expression *)dedtypes->data[j];
|
||||
if (e)
|
||||
{
|
||||
if (!e1->equals(e))
|
||||
@@ -1592,7 +1675,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
||||
MATCH m = (MATCH)e1->implicitConvTo(vt);
|
||||
if (!m)
|
||||
goto Lnomatch;
|
||||
dedtypes->data[i] = e1;
|
||||
dedtypes->data[j] = e1;
|
||||
}
|
||||
}
|
||||
// BUG: Need to handle alias and tuple parameters
|
||||
@@ -2351,6 +2434,7 @@ Lmatch:
|
||||
return m;
|
||||
|
||||
Lnomatch:
|
||||
//printf("\tno match\n");
|
||||
*psparam = NULL;
|
||||
return MATCHnomatch;
|
||||
}
|
||||
@@ -2780,7 +2864,7 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
if (m->semanticdone >= 3)
|
||||
dosemantic3 = 1;
|
||||
}
|
||||
for (i = 0; 1; i++)
|
||||
for (int i = 0; 1; i++)
|
||||
{
|
||||
if (i == a->dim)
|
||||
{
|
||||
@@ -2953,7 +3037,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
|
||||
Expression *ea = isExpression(o);
|
||||
Dsymbol *sa = isDsymbol(o);
|
||||
|
||||
//printf("1: tiargs->data[%d] = %p, %p, %p\n", j, o, isDsymbol(o), isTuple(o));
|
||||
//printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
|
||||
if (ta)
|
||||
{
|
||||
//printf("type %s\n", ta->toChars());
|
||||
@@ -3196,9 +3280,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
|
||||
int c2 = td_best->leastAsSpecialized(td);
|
||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||
|
||||
if (c1 && !c2)
|
||||
if (c1 > c2)
|
||||
goto Ltd;
|
||||
else if (!c1 && c2)
|
||||
else if (c1 < c2)
|
||||
goto Ltd_best;
|
||||
else
|
||||
goto Lambig;
|
||||
@@ -3305,10 +3389,30 @@ int TemplateInstance::isNested(Objects *args)
|
||||
{
|
||||
// if module level template
|
||||
if (tempdecl->toParent()->isModule())
|
||||
{
|
||||
if (isnested && isnested != d->toParent())
|
||||
error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars());
|
||||
isnested = d->toParent();
|
||||
{ Dsymbol *dparent = d->toParent();
|
||||
if (!isnested)
|
||||
isnested = dparent;
|
||||
else if (isnested != dparent)
|
||||
{
|
||||
/* Select the more deeply nested of the two.
|
||||
* Error if one is not nested inside the other.
|
||||
*/
|
||||
for (Dsymbol *p = isnested; p; p = p->parent)
|
||||
{
|
||||
if (p == dparent)
|
||||
goto L1; // isnested is most nested
|
||||
}
|
||||
for (Dsymbol *p = dparent; 1; p = p->parent)
|
||||
{
|
||||
if (p == isnested)
|
||||
{ isnested = dparent;
|
||||
goto L1; // dparent is most nested
|
||||
}
|
||||
}
|
||||
error("is nested in both %s and %s", isnested->toChars(), dparent->toChars());
|
||||
}
|
||||
L1:
|
||||
//printf("\tnested inside %s\n", isnested->toChars());
|
||||
nested |= 1;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user