Skip to content

Commit

Permalink
[Refactoring] Reduce unnecessary symtab generation
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Mar 5, 2014
1 parent c50f0bb commit eb453af
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 42 deletions.
35 changes: 20 additions & 15 deletions src/expression.c
Expand Up @@ -4546,7 +4546,8 @@ Expression *ScopeExp::semantic(Scope *sc)
e = new DotTemplateInstanceExp(loc, e, ti);
return e->semantic(sc);
}
if (ti->needsTypeInference(sc))
if (!ti->semanticRun &&
ti->needsTypeInference(sc))
{
if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration())
{
Expand All @@ -4572,7 +4573,6 @@ Expression *ScopeExp::semantic(Scope *sc)
}
return this;
}
unsigned olderrs = global.errors;
if (!ti->semanticRun)
ti->semantic(sc);
if (ti->inst)
Expand Down Expand Up @@ -4605,8 +4605,6 @@ Expression *ScopeExp::semantic(Scope *sc)
}
//printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
}
if (olderrs != global.errors)
return new ErrorExp();
}
else
{
Expand Down Expand Up @@ -5474,15 +5472,24 @@ void FuncExp::genIdent(Scope *sc)
}
else
{
symtab = sc->parent->isScopeDsymbol()->symtab;
L1:
assert(symtab);
int num = (int)_aaLen(symtab->tab) + 1;
Identifier *id = Lexer::uniqueId(s, num);
fd->ident = id;
if (td) td->ident = id;
symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
ScopeDsymbol *sds = sc->parent->isScopeDsymbol();
if (!sds->symtab)
{
// Inside template constraint, symtab may not be set yet.
// Initialize it lazily.
assert(sds->isTemplateInstance());
sds->symtab = new DsymbolTable();
}
symtab = sds->symtab;
}
if (!symtab)
return;
L1:
int num = (int)_aaLen(symtab->tab) + 1;
Identifier *id = Lexer::uniqueId(s, num);
fd->ident = id;
if (td) td->ident = id;
symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
}
}

Expand Down Expand Up @@ -7889,9 +7896,7 @@ Expression *CallExp::semantic(Scope *sc)
}
else
{
ti->semantic(sc);
if (ti->errors)
e1 = new ErrorExp();
e1 = e1->semantic(sc);
}
}
}
Expand Down
65 changes: 38 additions & 27 deletions src/template.c
Expand Up @@ -711,7 +711,7 @@ bool TemplateDeclaration::overloadInsert(Dsymbol *s)
*/
bool TemplateDeclaration::evaluateConstraint(
TemplateInstance *ti, Scope *sc, Scope *paramscope,
Objects *dedtypes, FuncDeclaration *fd)
Objects *dedargs, FuncDeclaration *fd)
{
/* Detect recursive attempts to instantiate this template declaration,
* Bugzilla 4072
Expand All @@ -729,7 +729,7 @@ bool TemplateDeclaration::evaluateConstraint(
int nmatches = 0;
for (TemplatePrevious *p = previous; p; p = p->prev)
{
if (arrayObjectMatch(p->dedargs, dedtypes))
if (arrayObjectMatch(p->dedargs, dedargs))
{
//printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
/* It must be a subscope of p->sc, other scope chains are not recursive
Expand All @@ -748,7 +748,7 @@ bool TemplateDeclaration::evaluateConstraint(
TemplatePrevious pr;
pr.prev = previous;
pr.sc = paramscope;
pr.dedargs = dedtypes;
pr.dedargs = dedargs;
previous = ≺ // add this to threaded list

int nerrors = global.errors;
Expand All @@ -757,6 +757,7 @@ bool TemplateDeclaration::evaluateConstraint(
scx->parent = ti;
scx->tinst = ti;

assert(!ti->symtab);
if (fd)
{
/* Declare all the function parameters as variables and add them to the scope
Expand Down Expand Up @@ -787,6 +788,8 @@ bool TemplateDeclaration::evaluateConstraint(
VarDeclaration *v = new VarDeclaration(loc, fparam->type, fparam->ident, NULL);
v->storage_class = fparam->storageClass;
v->semantic(scx);
if (!ti->symtab)
ti->symtab = new DsymbolTable();
if (!scx->insert(v))
error("parameter %s.%s is already defined", toChars(), v->toChars());
else
Expand All @@ -802,11 +805,13 @@ bool TemplateDeclaration::evaluateConstraint(

scx = scx->startCTFE();
scx->flags |= SCOPEstaticif;
assert(ti->inst == NULL);

//printf("\tscx->parent = %s %s\n", scx->parent->kind(), scx->parent->toPrettyChars());
e = e->semantic(scx);
e = resolveProperties(scx, e);

ti->symtab = NULL;
scx = scx->endCTFE();

scx = scx->pop();
Expand Down Expand Up @@ -942,9 +947,6 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,

if (m > MATCHnomatch && constraint && !flag)
{
// minimum requred settings
ti->symtab = new DsymbolTable();
//ti->parent = this->parent;
if (ti->hasNestedArgs(ti->tiargs, this->isstatic)) // TODO: should gag error
ti->parent = ti->enclosing;
else
Expand Down Expand Up @@ -973,6 +975,7 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
goto Lnomatch;
}

// TODO: dedtypes => ti->tiargs ?
if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd))
goto Lnomatch;
}
Expand Down Expand Up @@ -1123,13 +1126,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
MATCH matchTiargs = MATCHexact;
Parameters *fparameters; // function parameter list
int fvarargs; // function varargs
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
unsigned wildmatch = 0;
TemplateParameters *inferparams = parameters;

Loc loc = ti->loc;
Objects *tiargs = ti->tiargs;
Objects *dedargs = &ti->tdtypes;
Objects *dedargs = new Objects();
Objects* dedtypes = &ti->tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T

#if 0
printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars());
Expand All @@ -1149,8 +1152,8 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
dedargs->setDim(parameters->dim);
dedargs->zero();

dedtypes.setDim(parameters->dim);
dedtypes.zero();
dedtypes->setDim(parameters->dim);
dedtypes->zero();

if (errors || fd->errors)
return MATCHnomatch;
Expand Down Expand Up @@ -1215,7 +1218,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
{
assert(i < parameters->dim);
Declaration *sparam = NULL;
MATCH m = (*parameters)[i]->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, &sparam);
MATCH m = (*parameters)[i]->matchArg(loc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
if (m <= MATCHnomatch)
goto Lnomatch;
Expand Down Expand Up @@ -1316,7 +1319,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
hasttp = true;

Type *t = new TypeIdentifier(Loc(), ttp->ident);
MATCH m = deduceType(tthis, paramscope, t, parameters, &dedtypes);
MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes);
if (m <= MATCHnomatch)
goto Lnomatch;
if (m < match)
Expand Down Expand Up @@ -1573,7 +1576,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
goto Lvarargs;

unsigned wm = 0;
MATCH m = deduceType(farg, paramscope, prmtype, parameters, &dedtypes, &wm);
MATCH m = deduceType(farg, paramscope, prmtype, parameters, dedtypes, &wm);
//printf("\tdeduceType m = %d\n", m);
//printf("\twildmatch = x%x m = %d\n", wildmatch, m);
wildmatch |= wm;
Expand All @@ -1597,7 +1600,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(

if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
{
m = deduceType(farg->type, paramscope, tf->next, parameters, &dedtypes);
m = deduceType(farg->type, paramscope, tf->next, parameters, dedtypes);
if (m == MATCHnomatch && tf->next->toBasetype()->ty == Tvoid)
m = MATCHconvert;
}
Expand Down Expand Up @@ -1703,7 +1706,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
TemplateValueParameter *tvp = tprm->isTemplateValueParameter();
if (!tvp)
goto Lnomatch;
Expression *e = (Expression *)dedtypes[i];
Expression *e = (Expression *)(*dedtypes)[i];
if (e)
{
if (!dim->equals(e))
Expand All @@ -1715,7 +1718,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
MATCH m = (MATCH)dim->implicitConvTo(vt);
if (m <= MATCHnomatch)
goto Lnomatch;
dedtypes[i] = dim;
(*dedtypes)[i] = dim;
}
}
}
Expand Down Expand Up @@ -1761,7 +1764,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
}
else
{
m = deduceType(arg->type, paramscope, ta->next, parameters, &dedtypes);
m = deduceType(arg->type, paramscope, ta->next, parameters, dedtypes);
//m = arg->implicitConvTo(ta->next);
}
if (m == MATCHnomatch)
Expand All @@ -1787,11 +1790,11 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(

Lmatch:

for (size_t i = 0; i < dedtypes.dim; i++)
for (size_t i = 0; i < dedtypes->dim; i++)
{
Type *at = isType(dedtypes[i]);
Type *at = isType((*dedtypes)[i]);
if (at && at->ty == Ttypeof)
dedtypes[i] = ((TypeTypeof *)at)->exp->type; // 'unbox'
(*dedtypes)[i] = ((TypeTypeof *)at)->exp->type; // 'unbox'
}
for (size_t i = ntargs; i < dedargs->dim; i++)
{
Expand All @@ -1801,7 +1804,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
* But for function templates, we really need them to match
*/
RootObject *oarg = (*dedargs)[i];
RootObject *oded = dedtypes[i];
RootObject *oded = (*dedtypes)[i];
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
//if (oarg) printf("oarg: %s\n", oarg->toChars());
//if (oded) printf("oded: %s\n", oded->toChars());
Expand All @@ -1815,13 +1818,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
* the oded == oarg
*/
(*dedargs)[i] = oded;
MATCH m2 = tparam->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, NULL);
MATCH m2 = tparam->matchArg(loc, paramscope, dedargs, i, parameters, dedtypes, NULL);
//printf("m2 = %d\n", m2);
if (m2 <= MATCHnomatch)
goto Lnomatch;
if (m2 < matchTiargs)
matchTiargs = m2; // pick worst match
if (dedtypes[i] != oded)
if ((*dedtypes)[i] != oded)
error("specialization not allowed for deduced parameter %s", tparam->ident->toChars());
}
else
Expand Down Expand Up @@ -1872,6 +1875,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
if (!fd)
goto Lnomatch;
}
ti->tiargs = dedargs;
if (constraint)
{
if (!evaluateConstraint(ti, sc, paramscope, dedargs, fd))
Expand All @@ -1885,7 +1889,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(
printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars());
}
#endif
ti->tiargs = &ti->tdtypes; // for better error message

paramscope->pop();
//printf("\tmatch %d\n", match);
Expand Down Expand Up @@ -2299,15 +2302,15 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
if (f->type->ty != Tfunction || f->errors)
goto Lerror;

/* This is a 'dummy' instance to evaluate constraint properly.
*/
TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
ti->tinst = td->getInstantiating(sc);
if (ti->tinst)
ti->instantiatingModule = ti->tinst->instantiatingModule;
else
ti->instantiatingModule = sc->instantiatingModule();
ti->parent = td->parent; // Maybe calculating valid 'enclosing' is unnecessary.
ti->semantictiargsdone = true;
ti->symtab = new DsymbolTable();

FuncDeclaration *fd = f;
int x = td->deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);
Expand Down Expand Up @@ -2441,7 +2444,7 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
assert(p.td_best->scope);
if (!sc) sc = p.td_best->scope; // workaround for Type::aliasthisOf

TemplateInstance *ti = new TemplateInstance(loc, p.td_best, &p.ti_best->tdtypes); // TODO?
TemplateInstance *ti = new TemplateInstance(loc, p.td_best, p.ti_best->tiargs);
ti->semantic(sc, fargs);

m->lastf = ti->toAlias()->isFuncDeclaration();
Expand Down Expand Up @@ -6915,11 +6918,19 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)

OverloadSet *tovers = tempdecl->isOverloadSet();
size_t overs_dim = tovers ? tovers->a.dim : 1;
unsigned olderrs = global.errors;
for (size_t oi = 0; oi < overs_dim; oi++)
{
if (int r = overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamNeedsInf::fp))
return true;
}
if (olderrs != global.errors)
{
errorSupplemental(loc, "while looking for match for %s", toChars());
semanticRun = PASSsemanticdone;
inst = this;
errors = true;
}
//printf("false\n");
return false;
}
Expand Down
15 changes: 15 additions & 0 deletions test/runnable/template9.d
Expand Up @@ -1651,6 +1651,21 @@ void test14()
static assert( Params[2] == 1);
}

/**********************************/
// test for evaluateConstraint assertion

bool canSearchInCodeUnits15(C)(dchar c)
if (is(C == char))
{
return true;
}

void test15()
{
int needle = 0;
auto b = canSearchInCodeUnits15!char(needle);
}

/**********************************/
// 8129

Expand Down

0 comments on commit eb453af

Please sign in to comment.