Skip to content

Commit

Permalink
Merge pull request #3948 from 9rnsr/fix_tinst
Browse files Browse the repository at this point in the history
Add TemplateInstance::tnext to construct instantiation dependency graph
  • Loading branch information
WalterBright committed Sep 14, 2014
2 parents cc8bd65 + fff5dcf commit fc7d446
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 135 deletions.
6 changes: 4 additions & 2 deletions src/clone.c
Expand Up @@ -93,7 +93,8 @@ FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc)

unsigned errors = global.startGagging(); // Do not report errors, even if the
sc = sc->push();
sc->speculative = true;
sc->tinst = NULL;
sc->minst = NULL;

for (size_t i = 0; i < 2; i++)
{
Expand Down Expand Up @@ -406,7 +407,8 @@ FuncDeclaration *hasIdentityOpEquals(AggregateDeclaration *ad, Scope *sc)

unsigned errors = global.startGagging(); // Do not report errors, even if the
sc = sc->push();
sc->speculative = true;
sc->tinst = NULL;
sc->minst = NULL;

for (size_t j = 0; j < 2; j++)
{
Expand Down
2 changes: 1 addition & 1 deletion src/dsymbol.c
Expand Up @@ -812,7 +812,7 @@ bool Dsymbol::inNonRoot()
{
if (ti->isTemplateMixin())
continue;
if (!ti->instantiatingModule || !ti->instantiatingModule->isRoot())
if (!ti->minst || !ti->minst->isRoot())
return true;
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion src/expression.c
Expand Up @@ -5919,7 +5919,8 @@ Expression *IsExp::semantic(Scope *sc)

Type *tded = NULL;
Scope *sc2 = sc->copy(); // keep sc->flags
sc2->speculative = true;
sc2->tinst = NULL;
sc2->minst = NULL;
Type *t = targ->trySemantic(loc, sc2);
sc2->pop();
if (!t)
Expand Down
14 changes: 9 additions & 5 deletions src/scope.c
Expand Up @@ -62,6 +62,7 @@ Scope::Scope()
this->tf = NULL;
this->os = NULL;
this->tinst = NULL;
this->minst = NULL;
this->sbreak = NULL;
this->scontinue = NULL;
this->fes = NULL;
Expand All @@ -78,7 +79,6 @@ Scope::Scope()
this->nofree = 0;
this->noctor = 0;
this->intypeof = 0;
this->speculative = false;
this->lastVar = NULL;
this->callSuper = 0;
this->fieldinit = NULL;
Expand Down Expand Up @@ -112,6 +112,10 @@ Scope *Scope::createGlobal(Module *module)
sc->protection = Prot(PROTpublic);

sc->module = module;

sc->tinst = NULL;
sc->minst = module;

sc->scopesym = new ScopeDsymbol();
sc->scopesym->symtab = new DsymbolTable();

Expand Down Expand Up @@ -216,7 +220,8 @@ Scope *Scope::startCTFE()

// If a template is instantiated from CT evaluated expression,
// compiler can elide its code generation.
sc->speculative = true;
sc->tinst = NULL;
sc->minst = NULL;
#endif
return sc;
}
Expand Down Expand Up @@ -352,9 +357,8 @@ void Scope::mergeFieldInit(Loc loc, unsigned *fies)

Module *Scope::instantiatingModule()
{
if (tinst && tinst->instantiatingModule)
return tinst->instantiatingModule;
return module;
// TODO: in speculative context, returning 'module' is correct?
return minst ? minst : module;
}

Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
Expand Down
10 changes: 8 additions & 2 deletions src/scope.h
Expand Up @@ -80,7 +80,6 @@ struct Scope
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *tf; // enclosing try finally statement
OnScopeStatement *os; // enclosing scope(xxx) statement
TemplateInstance *tinst; // enclosing template instance
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
Expand All @@ -89,9 +88,16 @@ struct Scope
int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp)
bool speculative; // in __traits(compiles) and so on
VarDeclaration *lastVar; // Previous symbol used to prevent goto-skips-init

/* If minst && !tinst, it's in definitely non-speculative scope (eg. module member scope).
* If !minst && !tinst, it's in definitely speculative scope (eg. template constraint).
* If minst && tinst, it's in instantiated code scope without speculation.
* If !minst && tinst, it's in instantiated code scope with speculation.
*/
Module *minst; // root module where the instantiated templates should belong to
TemplateInstance *tinst; // enclosing template instance

unsigned callSuper; // primitive flow analysis for constructors
unsigned *fieldinit;
size_t fieldinit_dim;
Expand Down
3 changes: 2 additions & 1 deletion src/staticassert.c
Expand Up @@ -52,7 +52,8 @@ void StaticAssert::semantic2(Scope *sc)
//printf("StaticAssert::semantic2() %s\n", toChars());
ScopeDsymbol *sds = new ScopeDsymbol();
sc = sc->push(sds);
sc->speculative = true;
sc->tinst = NULL;
sc->minst = NULL;
sc->flags |= SCOPEcondition;

sc = sc->startCTFE();
Expand Down
3 changes: 2 additions & 1 deletion src/struct.c
Expand Up @@ -859,7 +859,8 @@ void StructDeclaration::semantic(Scope *sc)
{
unsigned xerrors = global.startGagging();
sc = sc->push();
sc->speculative = true;
sc->tinst = NULL;
sc->minst = NULL;
FuncDeclaration *fcall = resolveFuncCall(loc, sc, scall, NULL, NULL, NULL, 1);
sc = sc->pop();
global.endGagging(xerrors);
Expand Down

0 comments on commit fc7d446

Please sign in to comment.