Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void obj_write_deferred(Library *library)

md->genobjfile(0);
}

/* Set object file name to be source name with sequence number,
* as mangled symbol names get way too long.
*/
Expand Down Expand Up @@ -532,6 +532,7 @@ void FuncDeclaration::toObjFile(int multiobj)
int has_arguments;

//printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", func, parent->toChars(), func->toChars());

//if (type) printf("type = %s\n", func->type->toChars());
#if 0
//printf("line = %d\n",func->getWhere() / LINEINC);
Expand Down Expand Up @@ -580,6 +581,17 @@ void FuncDeclaration::toObjFile(int multiobj)
assert(semanticRun == PASSsemantic3done);
semanticRun = PASSobj;

/* Skip generating code if this part of a TemplateInstance that is instantiated
* only by non-root modules (i.e. modules not listed on the command line).
*/
TemplateInstance *ti = inTemplateInstance();
if (!global.params.useUnitTests &&
ti && ti->instantiatingModule && !ti->instantiatingModule->root)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today, Module::root field is not used properly. Instead, you can check whether a module m is a root by using m->importedFrom == m.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I'll deal with this after it passes the test suite, maybe refactor things a bit.

{
//printf("instantiated by %s %s\n", ti->instantiatingModule->toChars(), ti->toChars());
return;
}

if (global.params.verbose)
printf("function %s\n",func->toPrettyChars());

Expand Down
1 change: 1 addition & 0 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,7 @@ Language changes listed by -transition=id:\n\
for (size_t filei = 0, modi = 0; filei < filecount; filei++, modi++)
{
m = modules[modi];
m->root = TRUE;
if (global.params.verbose)
printf("parse %s\n", m->toChars());
if (!Module::rootModule)
Expand Down
1 change: 1 addition & 0 deletions src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -4680,6 +4680,7 @@ StructDeclaration *TypeAArray::getImpl()
#endif
// Instantiate on the root module of import dependency graph.
Scope *scx = sc->push(sc->module->importedFrom);
scx->instantiatingModule = sc->module->importedFrom;
ti->semantic(scx);
ti->semantic2(scx);
ti->semantic3(scx);
Expand Down
2 changes: 2 additions & 0 deletions src/scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Scope::Scope()

//printf("Scope::Scope() %p\n", this);
this->module = NULL;
this->instantiatingModule = NULL;
this->scopesym = NULL;
this->sd = NULL;
this->enclosing = NULL;
Expand Down Expand Up @@ -88,6 +89,7 @@ Scope::Scope(Scope *enclosing)
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
assert(!(enclosing->flags & SCOPEfree));
this->module = enclosing->module;
this->instantiatingModule = enclosing->instantiatingModule;
this->func = enclosing->func;
this->parent = enclosing->parent;
this->scopesym = NULL;
Expand Down
3 changes: 2 additions & 1 deletion src/scope.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Copyright (c) 1999-2012 by Digital Mars
// Copyright (c) 1999-2013 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
Expand Down Expand Up @@ -65,6 +65,7 @@ struct Scope
Scope *enclosing; // enclosing Scope

Module *module; // Root module
Module *instantiatingModule; // top level module that started a chain of template instantiations
ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember()
Expand Down
7 changes: 4 additions & 3 deletions src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ void AggregateDeclaration::semantic3(Scope *sc)
Dsymbol *s = ti->toAlias();
Expression *e = new DsymbolExp(Loc(), s, 0);

Scope *sc = ti->tempdecl->scope->startCTFE();
e = e->semantic(sc);
sc->endCTFE();
Scope *sc2 = ti->tempdecl->scope->startCTFE();
sc2->instantiatingModule = sc->instantiatingModule ? sc->instantiatingModule : sc->module;
e = e->semantic(sc2);
sc2->endCTFE();

e = e->ctfeInterpret();
getRTInfo = e;
Expand Down
67 changes: 55 additions & 12 deletions src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ void TemplateDeclaration::makeParamNamesVisibleInConstraint(Scope *paramscope, E
* Return match level.
*/

MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
Objects *dedtypes, Expressions *fargs, int flag)
{ MATCH m;
size_t dedtypes_dim = dedtypes->dim;
Expand Down Expand Up @@ -849,6 +849,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
ScopeDsymbol *paramsym = new ScopeDsymbol();
paramsym->parent = scope->parent;
Scope *paramscope = scope->push(paramsym);
paramscope->instantiatingModule = sc->instantiatingModule;
paramscope->stc = 0;

// Attempt type deduction
Expand Down Expand Up @@ -1004,7 +1005,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
* 0 td2 is more specialized than this
*/

MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs)
MATCH TemplateDeclaration::leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs)
{
/* This works by taking the template parameters to this template
* declaration and feeding them to td2 as if it were a template
Expand Down Expand Up @@ -1042,7 +1043,7 @@ MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2, Expressi
dedtypes.setDim(td2->parameters->dim);

// Attempt a type deduction
MATCH m = td2->matchWithInstance(&ti, &dedtypes, fargs, 1);
MATCH m = td2->matchWithInstance(sc, &ti, &dedtypes, fargs, 1);
if (m)
{
/* A non-variadic template is more specialized than a
Expand Down Expand Up @@ -1127,6 +1128,12 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
ScopeDsymbol *paramsym = new ScopeDsymbol();
paramsym->parent = scope->parent;
Scope *paramscope = scope->push(paramsym);

paramscope->instantiatingModule = sc->instantiatingModule;
Module *mi = sc->instantiatingModule ? sc->instantiatingModule : sc->module;
if (!sc->instantiatingModule || sc->instantiatingModule->root)
paramscope->instantiatingModule = mi;

paramscope->callsc = sc;
paramscope->stc = 0;

Expand Down Expand Up @@ -2348,7 +2355,7 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
Objects dedtypes;
dedtypes.setDim(td->parameters->dim);
assert(td->semanticRun != PASSinit);
MATCH mta = td->matchWithInstance(ti, &dedtypes, fargs, 0);
MATCH mta = td->matchWithInstance(sc, ti, &dedtypes, fargs, 0);
//printf("matchWithInstance = %d\n", mta);
if (!mta || mta < ta_last) // no match or less match
return 0;
Expand Down Expand Up @@ -2433,8 +2440,8 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
if (td_best)
{
// Disambiguate by picking the most specialized TemplateDeclaration
MATCH c1 = td->leastAsSpecialized(td_best, fargs);
MATCH c2 = td_best->leastAsSpecialized(td, fargs);
MATCH c1 = td->leastAsSpecialized(sc, td_best, fargs);
MATCH c2 = td_best->leastAsSpecialized(sc, td, fargs);
//printf("1: c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2) goto Ltd;
if (c1 < c2) goto Ltd_best;
Expand Down Expand Up @@ -2621,7 +2628,7 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
ti->tinst = sc->tinst;
{
ti->tdtypes.setDim(parameters->dim);
if (!matchWithInstance(ti, &ti->tdtypes, fargs, 2))
if (!matchWithInstance(sc, ti, &ti->tdtypes, fargs, 2))
return NULL;
}

Expand All @@ -2640,6 +2647,7 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(Scope *sc,
ti->argsym = new ScopeDsymbol();
ti->argsym->parent = scope->parent;
scope = scope->push(ti->argsym);
scope->instantiatingModule = sc->instantiatingModule;

bool hasttp = false;

Expand Down Expand Up @@ -5154,6 +5162,7 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->name = ident;
this->tiargs = NULL;
this->tempdecl = NULL;
this->instantiatingModule = NULL;
this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL;
Expand Down Expand Up @@ -5183,6 +5192,7 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
this->name = td->ident;
this->tiargs = tiargs;
this->tempdecl = td;
this->instantiatingModule = NULL;
this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL;
Expand Down Expand Up @@ -5329,6 +5339,28 @@ void TemplateInstance::trySemantic3(Scope *sc2)
void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
{
//printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc);
#if 0
for (Dsymbol *s = this; s; s = s->parent)
{
printf("\t%s\n", s->toChars());
}
printf("Scope\n");
for (Scope *scx = sc; scx; scx = scx->enclosing)
{
printf("\t%s parent %s instantiatingModule %p\n", scx->module ? scx->module->toChars() : "null", scx->parent ? scx->parent->toChars() : "null", scx->instantiatingModule);
}
#endif

Module *mi = sc->instantiatingModule ? sc->instantiatingModule : sc->module;

/* If a TemplateInstance is ever instantiated by non-root modules,
* we do not have to generate code for it,
* because it will be generated when the non-root module is compiled.
*/
if (!instantiatingModule || instantiatingModule->root)
instantiatingModule = mi;
//printf("mi = %s\n", mi->toChars());

#if LOG
printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
#endif
Expand Down Expand Up @@ -5414,6 +5446,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
#if LOG
printf("\tit's a match with instance %p, %d\n", inst, inst->semanticRun);
#endif
if (!inst->instantiatingModule || inst->instantiatingModule->root)
inst->instantiatingModule = mi;
return;
}
L1: ;
Expand Down Expand Up @@ -5579,6 +5613,8 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
argsym = new ScopeDsymbol();
argsym->parent = scope->parent;
scope = scope->push(argsym);
if (!scope->instantiatingModule || scope->instantiatingModule->root)
scope->instantiatingModule = mi;
// scope->stc = 0;

// Declare each template parameter as an alias for the argument type
Expand Down Expand Up @@ -6234,7 +6270,7 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
assert(tempdecl->scope);
// Deduce tdtypes
tdtypes.setDim(tempdecl->parameters->dim);
if (!tempdecl->matchWithInstance(this, &tdtypes, fargs, 2))
if (!tempdecl->matchWithInstance(sc, this, &tdtypes, fargs, 2))
{
error("incompatible arguments for template instantiation");
return false;
Expand All @@ -6250,6 +6286,7 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
struct ParamBest
{
// context
Scope *sc;
TemplateInstance *ti;
Objects dedtypes;
// result
Expand Down Expand Up @@ -6283,7 +6320,7 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
dedtypes.setDim(td->parameters->dim);
dedtypes.zero();
assert(td->semanticRun != PASSinit);
MATCH m = td->matchWithInstance(ti, &dedtypes, ti->fargs, 0);
MATCH m = td->matchWithInstance(sc, ti, &dedtypes, ti->fargs, 0);
//printf("matchWithInstance = %d\n", m);
if (!m) // no match at all
return 0;
Expand All @@ -6293,8 +6330,8 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)

{
// Disambiguate by picking the most specialized TemplateDeclaration
MATCH c1 = td->leastAsSpecialized(td_best, ti->fargs);
MATCH c2 = td_best->leastAsSpecialized(td, ti->fargs);
MATCH c1 = td->leastAsSpecialized(sc, td_best, ti->fargs);
MATCH c2 = td_best->leastAsSpecialized(sc, td, ti->fargs);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2) goto Ltd;
if (c1 < c2) goto Ltd_best;
Expand All @@ -6320,6 +6357,7 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
ParamBest p;
// context
p.ti = this;
p.sc = sc;

/* Since there can be multiple TemplateDeclaration's with the same
* name, look for the best match.
Expand Down Expand Up @@ -6713,6 +6751,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
struct ParamNeedsInf
{
// context
Scope *sc;
TemplateInstance *ti;
int flag;
// result
Expand Down Expand Up @@ -6809,7 +6848,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
dedtypes.setDim(td->parameters->dim);
dedtypes.zero();
assert(td->semanticRun != PASSinit);
MATCH m = td->matchWithInstance(ti, &dedtypes, NULL, 0);
MATCH m = td->matchWithInstance(sc, ti, &dedtypes, NULL, 0);
if (m == MATCHnomatch)
return 0;
}
Expand All @@ -6826,6 +6865,7 @@ bool TemplateInstance::needsTypeInference(Scope *sc, int flag)
ParamNeedsInf p;
// context
p.ti = this;
p.sc = sc;
p.flag = flag;
// result
p.count = 0;
Expand Down Expand Up @@ -6854,6 +6894,7 @@ void TemplateInstance::semantic2(Scope *sc)
sc = tempdecl->scope;
assert(sc);
sc = sc->push(argsym);
sc->instantiatingModule = instantiatingModule;
sc = sc->push(this);
sc->tinst = this;
for (size_t i = 0; i < members->dim; i++)
Expand Down Expand Up @@ -6885,6 +6926,7 @@ void TemplateInstance::semantic3(Scope *sc)
{
sc = tempdecl->scope;
sc = sc->push(argsym);
sc->instantiatingModule = instantiatingModule;
sc = sc->push(this);
sc->tinst = this;
int needGagging = (speculative && !global.gag);
Expand Down Expand Up @@ -7585,6 +7627,7 @@ void TemplateMixin::semantic3(Scope *sc)
if (members)
{
sc = sc->push(argsym);
sc->instantiatingModule = instantiatingModule;
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Expand Down
5 changes: 3 additions & 2 deletions src/template.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class TemplateDeclaration : public ScopeDsymbol
PROT prot();
// void toDocBuffer(OutBuffer *buf);

MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag);
MATCH leastAsSpecialized(TemplateDeclaration *td2, Expressions *fargs);
MATCH matchWithInstance(Scope *sc, TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag);
MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);

MATCH deduceFunctionTemplateMatch(FuncDeclaration *f, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs, Objects *dedargs);
RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
Expand Down Expand Up @@ -319,6 +319,7 @@ class TemplateInstance : public ScopeDsymbol
Dsymbol *enclosing; // if referencing local symbols, this is the context
hash_t hash; // cached result of hashCode()
Expressions *fargs; // for function template, these are the function arguments
Module *instantiatingModule; // the top module that instantiated this instance
#ifdef IN_GCC
/* On some targets, it is necessary to know whether a symbol
will be emitted in the output or not before the symbol
Expand Down
9 changes: 9 additions & 0 deletions test/runnable/imports/test10441b.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

public import test10441c;

auto foo()()
if (boo(1))
{
return 1;
}

6 changes: 6 additions & 0 deletions test/runnable/imports/test10441c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

auto boo(T)(T t)
{
return 1;
}

10 changes: 10 additions & 0 deletions test/runnable/test10441.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// EXTRA_SOURCES: imports/test10441b.d imports/test10441c.d

import test10441b;

void main()
{
boo(1);
foo();
}