Merged dmd 2.059beta

This commit is contained in:
Alexey Prokhin
2012-04-05 11:47:00 +04:00
77 changed files with 6909 additions and 2243 deletions

View File

@@ -201,7 +201,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
{
if (sc1->scopesym == ti1)
{
error("recursive template expansion for template argument %s", t1->toChars());
tempdecl->error("recursive template expansion for template argument %s", t1->toChars());
return 1; // fake a match
}
}
@@ -379,7 +379,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
this->members = decldefs;
this->overnext = NULL;
this->overroot = NULL;
this->semanticRun = 0;
this->semanticRun = PASSinit;
this->onemember = NULL;
this->literal = 0;
this->ismixin = ismixin;
@@ -435,7 +435,7 @@ void TemplateDeclaration::semantic(Scope *sc)
#endif
if (semanticRun)
return; // semantic() already run
semanticRun = 1;
semanticRun = PASSsemantic;
if (sc->module && sc->module->ident == Id::object && ident == Id::AssociativeArray)
{ Type::associativearray = this;
@@ -496,7 +496,7 @@ void TemplateDeclaration::semantic(Scope *sc)
origParameters->setDim(parameters->dim);
for (size_t i = 0; i < parameters->dim; i++)
{
TemplateParameter *tp = parameters->tdata()[i];
TemplateParameter *tp = (*parameters)[i];
origParameters->tdata()[i] = tp->syntaxCopy();
}
}
@@ -510,11 +510,13 @@ void TemplateDeclaration::semantic(Scope *sc)
for (size_t i = 0; i < parameters->dim; i++)
{
TemplateParameter *tp = parameters->tdata()[i];
TemplateParameter *tp = (*parameters)[i];
tp->semantic(paramscope);
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
error("template tuple parameter must be last one");
{ error("template tuple parameter must be last one");
errors = true;
}
}
paramscope->pop();
@@ -688,6 +690,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
#endif
dedtypes->zero();
if (errors)
return MATCHnomatch;
size_t parameters_dim = parameters->dim;
int variadic = isVariadic() != NULL;
@@ -968,6 +973,9 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
dedtypes.setDim(parameters->dim);
dedtypes.zero();
if (errors)
return MATCHnomatch;
// Set up scope for parameters
ScopeDsymbol *paramsym = new ScopeDsymbol();
paramsym->parent = scope->parent;
@@ -1108,6 +1116,14 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
t->objects.setDim(tuple_dim);
for (size_t i = 0; i < tuple_dim; i++)
{ Expression *farg = fargs->tdata()[fptupindex + i];
// Check invalid arguments to detect errors early.
if (farg->op == TOKerror || farg->type->ty == Terror)
goto Lnomatch;
if (!(fparam->storageClass & STClazy) && farg->type->ty == Tvoid)
goto Lnomatch;
unsigned mod = farg->type->mod;
Type *tt;
MATCH m;
@@ -1384,6 +1400,11 @@ L2:
else
{
Expression *farg = fargs->tdata()[i];
// Check invalid arguments to detect errors early.
if (farg->op == TOKerror || farg->type->ty == Terror)
goto Lnomatch;
Lretry:
#if 0
printf("\tfarg->type = %s\n", farg->type->toChars());
@@ -1413,22 +1434,16 @@ Lretry:
if (farg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)farg;
Type *tp = fparam->type;
if (tp->ty == Tdelegate &&
fe->type->ty == Tpointer && fe->type->nextOf()->ty == Tfunction &&
fe->tok == TOKreserved)
{ Type *tdg = new TypeDelegate(fe->type->nextOf());
tdg = tdg->semantic(loc, sc);
farg = fe->inferType(sc, tdg);
}
else if (fe->type == Type::tvoid)
{
farg = fe->inferType(sc, tp);
if (!farg)
goto Lvarargs;
}
Expression *e = fe->inferType(tp, 1, parameters);
if (!e)
goto Lvarargs;
farg = e;
argtype = farg->type;
}
if (!(fparam->storageClass & STClazy) && argtype->ty == Tvoid)
goto Lnomatch;
/* Remove top const for dynamic array types and pointer types
*/
if ((argtype->ty == Tarray || argtype->ty == Tpointer) &&
@@ -1443,12 +1458,11 @@ Lretry:
if (fvarargs == 2 && i + 1 == nfparams && i + 1 < nfargs)
goto Lvarargs;
MATCH m;
m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes,
tf->hasWild() ? &wildmatch : NULL);
unsigned wm = 0;
MATCH m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes, &wm);
//printf("\tdeduceType m = %d\n", m);
//if (tf->hasWild())
// printf("\twildmatch = x%x m = %d\n", wildmatch, m);
//printf("\twildmatch = x%x m = %d\n", wildmatch, m);
wildmatch |= wm;
/* If no match, see if there's a conversion to a delegate
*/
@@ -1483,9 +1497,7 @@ Lretry:
* eg purity(bug 7295), just regard it as not a match.
*/
unsigned olderrors = global.startGagging();
Expression *e = new DotIdExp(farg->loc, farg, ad->aliasthis->ident);
e = e->semantic(sc);
e = resolveProperties(sc, e);
Expression *e = resolveAliasThis(sc, farg);
if (!global.endGagging(olderrors))
{ farg = e;
goto Lretry;
@@ -1542,19 +1554,11 @@ Lretry:
if (arg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)arg;
Type *tp = tb->nextOf();
if (tp->ty == Tdelegate &&
fe->type->ty == Tpointer && fe->type->nextOf()->ty == Tfunction &&
fe->tok == TOKreserved)
{ tp = new TypeDelegate(fe->type->nextOf());
tp = tp->semantic(loc, sc);
arg = fe->inferType(sc, tp);
}
else if (arg->type == Type::tvoid)
{
arg = fe->inferType(sc, tp);
if (!arg)
goto Lnomatch;
}
Expression *e = fe->inferType(tp, 1, parameters);
if (!e)
goto Lnomatch;
arg = e;
}
MATCH m;
@@ -1897,11 +1901,10 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
goto Lerror;
}
MATCH m;
Objects dedargs;
FuncDeclaration *fd = NULL;
m = td->deduceFunctionTemplateMatch(sc, loc, targsi, ethis, fargs, &dedargs);
MATCH m = td->deduceFunctionTemplateMatch(sc, loc, targsi, ethis, fargs, &dedargs);
//printf("deduceFunctionTemplateMatch = %d\n", m);
if (!m) // if no match
continue;
@@ -1930,9 +1933,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
goto Lerror;
}
{
tdargs->setDim(dedargs.dim);
memcpy(tdargs->data, dedargs.data, tdargs->dim * sizeof(void *));
fd = td->doHeaderInstantiation(sc, tdargs, fargs);
fd = td->doHeaderInstantiation(sc, &dedargs, fargs);
if (!fd)
goto Lerror;
}
@@ -1985,13 +1986,14 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
if (!td_best)
{
if (!(flags & 1))
error(loc, "does not match any function template declaration");
::error(loc, "%s %s.%s does not match any function template declaration",
kind(), parent->toPrettyChars(), ident->toChars());
goto Lerror;
}
if (td_ambig)
{
error(loc, "%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
toChars(),
::error(loc, "%s %s.%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
kind(), parent->toPrettyChars(), ident->toChars(),
td_best->loc.filename, td_best->loc.linnum, td_best->toChars(),
td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars());
}
@@ -2005,6 +2007,16 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
fd_best = ti->toAlias()->isFuncDeclaration();
if (!fd_best || !((TypeFunction*)fd_best->type)->callMatch(ethis, fargs, flags))
goto Lerror;
/* As Bugzilla 3682 shows, a template instance can be matched while instantiating
* that same template. Thus, the function type can be incomplete. Complete it.
*/
{ TypeFunction *tf = (TypeFunction *)fd_best->type;
assert(tf->ty == Tfunction);
if (tf->next)
fd_best->type = tf->semantic(loc, sc);
}
return fd_best;
Lerror:
@@ -2028,8 +2040,13 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
OutBuffer buf;
argExpTypesToCBuffer(&buf, fargs, &hgs);
error(loc, "cannot deduce template function from argument types !(%s)(%s)",
bufa.toChars(), buf.toChars());
if (this->overnext)
::error(loc, "%s %s.%s cannot deduce template function from argument types !(%s)(%s)",
kind(), parent->toPrettyChars(), ident->toChars(),
bufa.toChars(), buf.toChars());
else
error("cannot deduce template function from argument types !(%s)(%s)",
bufa.toChars(), buf.toChars());
}
return NULL;
}
@@ -2225,7 +2242,7 @@ int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
* Foo!(int*) // template instantiation
* Input:
* this = int*
* tparam = T
* tparam = T*
* parameters = [ T:T* ] // Array of TemplateParameter's
* Output:
* dedtypes = [ int ] // Array of Expression/Type's
@@ -2287,13 +2304,17 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
{
switch (X(tparam->mod, mod))
{
case X(MODwild, MODwild):
case X(MODwild | MODshared, MODwild | MODshared):
case X(MODwild, 0):
case X(MODwild, MODshared):
case X(MODwild, MODconst):
case X(MODwild, MODconst | MODshared):
case X(MODwild, MODimmutable):
case X(MODwild, MODwild):
case X(MODwild, MODwild | MODshared):
case X(MODwild | MODshared, MODshared):
case X(MODwild | MODshared, MODconst | MODshared):
case X(MODwild | MODshared, MODimmutable):
case X(MODwild | MODshared, MODwild | MODshared):
if (!at)
{
@@ -2407,11 +2428,18 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
}
break;
case X(MODconst, MODshared):
// foo(U:const(U)) shared(T) => shared(T)
if (!at)
{ (*dedtypes)[i] = tt;
goto Lconst;
}
break;
case X(MODimmutable, 0):
case X(MODimmutable, MODconst):
case X(MODimmutable, MODshared):
case X(MODimmutable, MODconst | MODshared):
case X(MODconst, MODshared):
case X(MODshared, 0):
case X(MODshared, MODconst):
case X(MODshared, MODimmutable):
@@ -2534,6 +2562,23 @@ Lconst:
#endif
}
#if DMDV2
MATCH TypeVector::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes, unsigned *wildmatch)
{
#if 0
printf("TypeVector::deduceType()\n");
printf("\tthis = %d, ", ty); print();
printf("\ttparam = %d, ", tparam->ty); tparam->print();
#endif
if (tparam->ty == Tvector)
{ TypeVector *tp = (TypeVector *)tparam;
return basetype->deduceType(sc, tp->basetype, parameters, dedtypes, wildmatch);
}
return Type::deduceType(sc, tparam, parameters, dedtypes, wildmatch);
}
#endif
#if DMDV2
MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes, unsigned *wildmatch)
@@ -3825,7 +3870,16 @@ void TemplateValueParameter::declareParameter(Scope *sc)
void TemplateValueParameter::semantic(Scope *sc)
{
bool wasSame = (sparam->type == valType);
sparam->semantic(sc);
if (sparam->type == Type::terror && wasSame)
{ /* If sparam has a type error, avoid duplicate errors
* The simple solution of leaving that function if sparam->type == Type::terror
* doesn't quite work because it causes failures in xtest46 for bug 6295
*/
valType = Type::terror;
return;
}
valType = valType->semantic(loc, sc);
if (!(valType->isintegral() || valType->isfloating() || valType->isString()) &&
valType->ty != Tident)
@@ -3834,6 +3888,7 @@ void TemplateValueParameter::semantic(Scope *sc)
error(loc, "arithmetic/string type expected for value-parameter, not %s", valType->toChars());
}
#if 0 // defer semantic analysis to arg match
if (specValue)
{ Expression *e = specValue;
@@ -3846,7 +3901,6 @@ void TemplateValueParameter::semantic(Scope *sc)
//e->toInteger();
}
#if 0 // defer semantic analysis to arg match
if (defaultValue)
{ Expression *e = defaultValue;
@@ -3883,8 +3937,8 @@ Lnomatch:
}
MATCH TemplateValueParameter::matchArg(Scope *sc, Objects *tiargs,
size_t i, TemplateParameters *parameters, Objects *dedtypes,
MATCH TemplateValueParameter::matchArg(Scope *sc,
Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
{
//printf("TemplateValueParameter::matchArg()\n");
@@ -3941,7 +3995,7 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, Objects *tiargs,
Expression *e = specValue;
e = e->semantic(sc);
e = e->implicitCastTo(sc, valType);
e = e->implicitCastTo(sc, vt);
e = e->optimize(WANTvalue | WANTinterpret);
ei = ei->syntaxCopy();
@@ -4199,13 +4253,12 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->tinst = NULL;
this->argsym = NULL;
this->aliasdecl = NULL;
this->semanticRun = 0;
this->semanticRun = PASSinit;
this->semantictiargsdone = 0;
this->withsym = NULL;
this->nest = 0;
this->havetempdecl = 0;
this->isnested = NULL;
this->errors = 0;
this->speculative = 0;
this->ignore = true;
@@ -4234,13 +4287,12 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
this->tinst = NULL;
this->argsym = NULL;
this->aliasdecl = NULL;
this->semanticRun = 0;
this->semanticRun = PASSinit;
this->semantictiargsdone = 1;
this->withsym = NULL;
this->nest = 0;
this->havetempdecl = 1;
this->isnested = NULL;
this->errors = 0;
this->speculative = 0;
this->ignore = true;
@@ -4289,23 +4341,96 @@ void TemplateInstance::semantic(Scope *sc)
semantic(sc, NULL);
}
void TemplateInstance::expandMembers(Scope *sc2)
{
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->setScope(sc2);
}
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
//printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
//printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars());
// if (isnested)
// s->parent = sc->parent;
//printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
s->semantic(sc2);
//printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
sc2->module->runDeferredSemantic();
}
}
void TemplateInstance::tryExpandMembers(Scope *sc2)
{
static int nest;
// extracted to a function to allow windows SEH to work without destructors in the same function
//printf("%d\n", nest);
if (++nest > 500)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
#if WINDOWS_SEH
if(nest == 1)
{
// do not catch at every nesting level, because generating the output error might cause more stack
// errors in the __except block otherwise
__try
{
expandMembers(sc2);
}
__except (__ehfilter(GetExceptionInformation()))
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
}
else
#endif
expandMembers(sc2);
nest--;
}
void TemplateInstance::trySemantic3(Scope *sc2)
{
// extracted to a function to allow windows SEH to work without destructors in the same function
static int nest;
if (++nest > 300)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
#if WINDOWS_SEH
if(nest == 1)
{
// do not catch at every nesting level, because generating the output error might cause more stack
// errors in the __except block otherwise
__try
{
semantic3(sc2);
}
__except (__ehfilter(GetExceptionInformation()))
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
}
else
#endif
semantic3(sc2);
--nest;
}
void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
{
//printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc);
if (global.errors && name != Id::AssociativeArray)
{
//printf("not instantiating %s due to %d errors\n", toChars(), global.errors);
if (!global.gag)
{
/* Trying to soldier on rarely generates useful messages
* at this point.
*/
fatal();
}
// return;
}
if (!sc->ignoreTemplates)
ignore = false;
#if LOG
printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
#endif
@@ -4316,11 +4441,15 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
#endif
return;
}
if (!sc->ignoreTemplates)
ignore = false;
// get the enclosing template instance from the scope tinst
tinst = sc->tinst;
if (semanticRun != 0)
if (semanticRun != PASSinit)
{
#if LOG
printf("Recursive template expansion\n");
@@ -4329,7 +4458,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
// inst = this;
return;
}
semanticRun = 1;
semanticRun = PASSsemantic;
#if IN_LLVM
// get the enclosing template instance from the scope tinst
tinst = sc->tinst;
@@ -4368,11 +4497,11 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
//printf("error return %p, %d\n", tempdecl, global.errors);
return; // error recovery
}
unsigned errs = global.errors;
tempdecl = findTemplateDeclaration(sc);
if (tempdecl)
tempdecl = findBestMatch(sc, fargs);
if (!tempdecl || global.errors)
if (!tempdecl || (errs != global.errors))
{ inst = this;
//printf("error return %p, %d\n", tempdecl, global.errors);
return; // error recovery
@@ -4403,10 +4532,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
//printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : "");
continue;
}
#if 0
if (isnested && sc->parent != ti->parent)
continue;
#endif
//printf("parent = %s, ti->parent = %s\n", tempdecl->parent->toPrettyChars(), ti->parent->toPrettyChars());
if (!arrayObjectMatch(&tdtypes, &ti->tdtypes, tempdecl, sc))
goto L1;
@@ -4463,7 +4590,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
}
#if LOG
printf("\tit's a match with instance %p\n", inst);
printf("\tit's a match with instance %p, %d\n", inst, inst->semanticRun);
#endif
return;
@@ -4480,7 +4607,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
unsigned errorsave = global.errors;
inst = this;
// Mark as speculative if we are instantiated from inside is(typeof())
if (global.gag && sc->intypeof)
if (global.gag && sc->speculative)
speculative = 1;
int tempdecl_instance_idx = tempdecl->instances.dim;
@@ -4651,46 +4778,9 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
sc2->parent = /*isnested ? sc->parent :*/ this;
sc2->tinst = this;
#if WINDOWS_SEH
__try
{
#endif
static int nest;
//printf("%d\n", nest);
if (++nest > 500)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
tryExpandMembers(sc2);
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->setScope(sc2);
}
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
//printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
//printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars());
// if (isnested)
// s->parent = sc->parent;
//printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
s->semantic(sc2);
//printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
sc2->module->runDeferredSemantic();
}
--nest;
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
#endif
semanticRun = PASSsemanticdone;
/* If any of the instantiation members didn't get semantic() run
* on them due to forward references, we cannot run semantic2()
@@ -4744,28 +4834,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
if (sc->func || dosemantic3)
{
#if WINDOWS_SEH
__try
{
#endif
static int nest;
if (++nest > 300)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
semantic3(sc2);
--nest;
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
#endif
trySemantic3(sc2);
}
Laftersemantic:
@@ -4795,7 +4864,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
assert(target_symbol_list->tdata()[target_symbol_list_idx] == this);
target_symbol_list->remove(target_symbol_list_idx);
}
semanticRun = 0;
semanticRun = PASSinit;
inst = NULL;
}
}
@@ -5172,13 +5241,14 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc, Expressions *far
// 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());
::error(loc, "%s %s.%s does not match any template declaration",
tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars());
return NULL;
}
if (td_ambig)
{
error("%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
toChars(),
::error(loc, "%s %s.%s matches more than one template declaration, %s(%d):%s and %s(%d):%s",
td_best->kind(), td_best->parent->toPrettyChars(), td_best->ident->toChars(),
td_best->loc.filename, td_best->loc.linnum, td_best->toChars(),
td_ambig->loc.filename, td_ambig->loc.linnum, td_ambig->toChars());
}
@@ -5237,6 +5307,11 @@ int TemplateInstance::hasNestedArgs(Objects *args)
sa = ((VarExp *)ea)->var;
goto Lsa;
}
if (ea->op == TOKthis)
{
sa = ((ThisExp *)ea)->var;
goto Lsa;
}
if (ea->op == TOKfunction)
{
sa = ((FuncExp *)ea)->fd;
@@ -5309,7 +5384,7 @@ Identifier *TemplateInstance::genIdent(Objects *args)
//printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
char *id = tempdecl->ident->toChars();
buf.printf("__T%zu%s", strlen(id), id);
buf.printf("__T%llu%s", (ulonglong)strlen(id), id);
for (size_t i = 0; i < args->dim; i++)
{ Object *o = args->tdata()[i];
Type *ta = isType(o);
@@ -5325,7 +5400,8 @@ Identifier *TemplateInstance::genIdent(Objects *args)
else
{
#ifdef DEBUG
printf("ta = %d, %s\n", ta->ty, ta->toChars());
if (!global.errors)
printf("ta = %d, %s\n", ta->ty, ta->toChars());
#endif
assert(global.errors);
}
@@ -5358,8 +5434,9 @@ Identifier *TemplateInstance::genIdent(Objects *args)
continue;
}
// Now that we know it is not an alias, we MUST obtain a value
unsigned olderr = global.errors;
ea = ea->optimize(WANTvalue | WANTinterpret);
if (ea->op == TOKerror)
if (ea->op == TOKerror || olderr != global.errors)
continue;
#if 1
/* Use deco that matches what it would be for a function parameter
@@ -5404,7 +5481,7 @@ Identifier *TemplateInstance::genIdent(Objects *args)
* Unfortunately, fixing this ambiguity will break existing binary
* compatibility and the demanglers, so we'll leave it as is.
*/
buf.printf("%zu%s", strlen(p), p);
buf.printf("%llu%s", (ulonglong)strlen(p), p);
}
else if (va)
{
@@ -5477,12 +5554,33 @@ int TemplateInstance::needsTypeInference(Scope *sc)
/* Determine if the instance arguments, tiargs, are all that is necessary
* to instantiate the template.
*/
TemplateTupleParameter *tp = td->isVariadic();
//printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, tiargs->dim);
TypeFunction *fdtype = (TypeFunction *)fd->type;
if (Parameter::dim(fdtype->parameters) &&
((tp && td->parameters->dim > 1) || tiargs->dim < td->parameters->dim))
return TRUE;
if (Parameter::dim(fdtype->parameters))
{
TemplateParameter *tp = td->isVariadic();
if (tp && td->parameters->dim > 1)
return TRUE;
if (tiargs->dim < td->parameters->dim)
{ // Can remain tiargs be filled by default arguments?
for (size_t i = tiargs->dim; i < td->parameters->dim; i++)
{ tp = (*td->parameters)[i];
if (TemplateTypeParameter *ttp = tp->isTemplateTypeParameter())
{ if (!ttp->defaultType)
return TRUE;
}
else if (TemplateAliasParameter *tap = tp->isTemplateAliasParameter())
{ if (!tap->defaultAlias)
return TRUE;
}
else if (TemplateValueParameter *tvp = tp->isTemplateValueParameter())
{ if (!tvp->defaultValue)
return TRUE;
}
}
}
}
/* If there is more than one function template which matches, we may
* need type inference (see Bugzilla 4430)
*/
@@ -5496,9 +5594,9 @@ int TemplateInstance::needsTypeInference(Scope *sc)
void TemplateInstance::semantic2(Scope *sc)
{ int i;
if (semanticRun >= 2)
if (semanticRun >= PASSsemantic2)
return;
semanticRun = 2;
semanticRun = PASSsemantic2;
#if LOG
printf("+TemplateInstance::semantic2('%s')\n", toChars());
#endif
@@ -5531,9 +5629,9 @@ void TemplateInstance::semantic3(Scope *sc)
printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun);
#endif
//if (toChars()[0] == 'D') *(char*)0=0;
if (semanticRun >= 3)
if (semanticRun >= PASSsemantic3)
return;
semanticRun = 3;
semanticRun = PASSsemantic3;
if (!errors && members)
{
sc = tempdecl->scope;
@@ -5702,7 +5800,7 @@ void TemplateInstance::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (i)
buf->writeByte(',');
Object *oarg = args->tdata()[i];
Object *oarg = (*args)[i];
ObjectToCBuffer(buf, hgs, oarg);
}
nest--;
@@ -5717,9 +5815,24 @@ Dsymbol *TemplateInstance::toAlias()
printf("TemplateInstance::toAlias()\n");
#endif
if (!inst)
{ error("cannot resolve forward reference");
errors = 1;
return this;
{
// Maybe we can resolve it
if (scope)
{
/* Anything that affects scope->offset must be
* done in lexical order. Fwd ref error if it is affected, otherwise allow.
*/
unsigned offset = scope->offset;
Scope *sc = scope;
semantic(scope);
// if (offset != sc->offset)
// inst = NULL; // trigger fwd ref error
}
if (!inst)
{ error("cannot resolve forward reference");
errors = 1;
return this;
}
}
if (inst != this)
@@ -5851,7 +5964,7 @@ void TemplateMixin::semantic(Scope *sc)
// This for when a class/struct contains mixin members, and
// is done over because of forward references
if (parent && toParent()->isAggregateDeclaration())
semanticRun = 1; // do over
semanticRun = PASSsemantic; // do over
else
{
#if LOG
@@ -5861,12 +5974,12 @@ void TemplateMixin::semantic(Scope *sc)
}
}
if (!semanticRun)
semanticRun = 1;
semanticRun = PASSsemantic;
#if LOG
printf("\tdo semantic\n");
#endif
#if !IN_LLVM
#if !IN_LLVM && !IN_GCC
// dont know what this is
util_progress();
#endif
@@ -5944,10 +6057,10 @@ void TemplateMixin::semantic(Scope *sc)
* runDeferred will re-run mixin's semantic outside of the struct's
* semantic.
*/
semanticRun = 0;
semanticRun = PASSinit;
AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
if (ad)
ad->sizeok = 2;
ad->sizeok = SIZEOKfwd;
else
{
// Forward reference
@@ -5992,11 +6105,11 @@ void TemplateMixin::semantic(Scope *sc)
continue;
for (size_t i = 0; i < tiargs->dim; i++)
{ Object *o = tiargs->tdata()[i];
{ Object *o = (*tiargs)[i];
Type *ta = isType(o);
Expression *ea = isExpression(o);
Dsymbol *sa = isDsymbol(o);
Object *tmo = tm->tiargs->tdata()[i];
Object *tmo = (*tm->tiargs)[i];
if (ta)
{
Type *tmta = isType(tmo);
@@ -6060,10 +6173,8 @@ void TemplateMixin::semantic(Scope *sc)
declareParameters(argscope);
// Add members to enclosing scope, as well as this scope
for (unsigned i = 0; i < members->dim; i++)
{ Dsymbol *s;
s = members->tdata()[i];
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->addMember(argscope, this, i);
//sc->insert(s);
//printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
@@ -6089,7 +6200,7 @@ void TemplateMixin::semantic(Scope *sc)
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->semantic(sc2);
}
@@ -6131,9 +6242,9 @@ void TemplateMixin::semantic(Scope *sc)
void TemplateMixin::semantic2(Scope *sc)
{
if (semanticRun >= 2)
if (semanticRun >= PASSsemantic2)
return;
semanticRun = 2;
semanticRun = PASSsemantic2;
#if LOG
printf("+TemplateMixin::semantic2('%s')\n", toChars());
#endif
@@ -6144,7 +6255,7 @@ void TemplateMixin::semantic2(Scope *sc)
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
#if LOG
printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
#endif
@@ -6160,9 +6271,9 @@ void TemplateMixin::semantic2(Scope *sc)
void TemplateMixin::semantic3(Scope *sc)
{
if (semanticRun >= 3)
if (semanticRun >= PASSsemantic3)
return;
semanticRun = 3;
semanticRun = PASSsemantic3;
#if LOG
printf("TemplateMixin::semantic3('%s')\n", toChars());
#endif
@@ -6195,6 +6306,22 @@ int TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident)
return Dsymbol::oneMember(ps, ident);
}
int TemplateMixin::apply(Dsymbol_apply_ft_t fp, void *param)
{
if (members)
{
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
if (s)
{
if (s->apply(fp, param))
return 1;
}
}
}
return 0;
}
int TemplateMixin::hasPointers()
{
//printf("TemplateMixin::hasPointers() %s\n", toChars());
@@ -6212,6 +6339,17 @@ int TemplateMixin::hasPointers()
return 0;
}
void TemplateMixin::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
if (members)
{
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->setFieldOffset(ad, poffset, isunion);
}
}
}
char *TemplateMixin::toChars()
{
OutBuffer buf;