"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/dmd/dsymbolsem.d" between
dmd-2.094.1.tar.gz and dmd-2.094.2.tar.gz

About: DMD (Digital Mars D) is the D reference compiler. D is an object-oriented, imperative, multi-paradigm system programming language.

dsymbolsem.d  (dmd-2.094.1):dsymbolsem.d  (dmd-2.094.2)
skipping to change at line 4101 skipping to change at line 4101
if (moduleSymbol.search(funcdecl.loc, Id.CMain)) if (moduleSymbol.search(funcdecl.loc, Id.CMain))
return true; return true;
return false; return false;
} }
// Only mixin `_d_cmain` if it is defined // Only mixin `_d_cmain` if it is defined
if (cmainTemplateExists()) if (cmainTemplateExists())
{ {
// add `mixin _d_cmain!();` to the declaring module // add `mixin _d_cmain!();` to the declaring module
auto tqual = Pool!TypeIdentifier.make(funcdecl.loc, Id.CMain); auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null); auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
sc._module.members.push(tm); sc._module.members.push(tm);
} }
rootHasMain = sc._module; rootHasMain = sc._module;
} }
assert(funcdecl.type.ty != Terror || funcdecl.errors); assert(funcdecl.type.ty != Terror || funcdecl.errors);
// semantic for parameters' UDAs // semantic for parameters' UDAs
skipping to change at line 5928 skipping to change at line 5928
// Get the instantiating module from the scope minst // Get the instantiating module from the scope minst
tempinst.minst = sc.minst; tempinst.minst = sc.minst;
// https://issues.dlang.org/show_bug.cgi?id=10920 // https://issues.dlang.org/show_bug.cgi?id=10920
// If the enclosing function is non-root symbol, // If the enclosing function is non-root symbol,
// this instance should be speculative. // this instance should be speculative.
if (!tempinst.tinst && sc.func && sc.func.inNonRoot()) if (!tempinst.tinst && sc.func && sc.func.inNonRoot())
{ {
tempinst.minst = null; tempinst.minst = null;
} }
// https://issues.dlang.org/show_bug.cgi?id=21299
// If not speculative, this instance should have the same instantiating
// root module as its enclosing template symbol. This can differ when
// the enclosing template gets changed from non-root to a root instance
// in the instantiation graph. When that occurs, this instance also
// needs to be appended to the root module, otherwise there will be
// undefined references at link-time.
if (tempinst.minst && tempinst.tinst)
{
tempinst.minst = tempinst.tinst.minst;
}
tempinst.gagged = (global.gag > 0); tempinst.gagged = (global.gag > 0);
tempinst.semanticRun = PASS.semantic; tempinst.semanticRun = PASS.semantic;
static if (LOG) static if (LOG)
{ {
printf("\tdo semantic\n"); printf("\tdo semantic\n");
} }
/* Find template declaration first, /* Find template declaration first,
skipping to change at line 6057 skipping to change at line 6046
* *
* However, if 'this' second instantiation happened in root module, * However, if 'this' second instantiation happened in root module,
* compiler might need to invoke its codegen * compiler might need to invoke its codegen
* (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang .org/show_bug.cgi?id=2644). * (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang .org/show_bug.cgi?id=2644).
* But whole import graph is not determined until all semantic pass fini shed, * But whole import graph is not determined until all semantic pass fini shed,
* so 'inst' should conservatively finish the semantic3 pass for the cod egen. * so 'inst' should conservatively finish the semantic3 pass for the cod egen.
*/ */
if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst & & tempinst.inst.minst.isRoot())) if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst & & tempinst.inst.minst.isRoot()))
{ {
/* Swap the position of 'inst' and 'this' in the instantiation graph . /* Swap the position of 'inst' and 'this' in the instantiation graph .
* Then, the primary instance `inst` will be changed to a root insta * Then, the primary instance `inst` will be changed to a root insta
nce. nce,
* along with all members of `inst` having their scopes updated.
* *
* Before: * Before:
* non-root -> A!() -> B!()[inst] -> C!() * non-root -> A!() -> B!()[inst] -> C!() { members[non-root] }
* | * |
* root -> D!() -> B!()[this] * root -> D!() -> B!()[this]
* *
* After: * After:
* non-root -> A!() -> B!()[this] * non-root -> A!() -> B!()[this]
* | * |
* root -> D!() -> B!()[inst] -> C!() * root -> D!() -> B!()[inst] -> C!() { members[root] }
*/ */
Module mi = tempinst.minst; Module mi = tempinst.minst;
TemplateInstance ti = tempinst.tinst; TemplateInstance ti = tempinst.tinst;
tempinst.minst = tempinst.inst.minst; tempinst.minst = tempinst.inst.minst;
tempinst.tinst = tempinst.inst.tinst; tempinst.tinst = tempinst.inst.tinst;
tempinst.inst.minst = mi; tempinst.inst.minst = mi;
tempinst.inst.tinst = ti; tempinst.inst.tinst = ti;
/* https://issues.dlang.org/show_bug.cgi?id=21299
`minst` has been updated on the primary instance `inst` so it is
now coming from a root module, however all Dsymbol `inst.members`
of the instance still have their `_scope.minst` pointing at the
original non-root module. We must now propagate `minst` to all
members so that forward referenced dependencies that get
instantiated will also be appended to the root module, otherwise
there will be undefined references at link-time. */
extern (C++) final class InstMemberWalker : Visitor
{
alias visit = Visitor.visit;
TemplateInstance inst;
extern (D) this(TemplateInstance inst)
{
this.inst = inst;
}
override void visit(Dsymbol d)
{
if (d._scope)
d._scope.minst = inst.minst;
}
override void visit(ScopeDsymbol sds)
{
sds.members.foreachDsymbol( s => s.accept(this) );
visit(cast(Dsymbol)sds);
}
override void visit(AttribDeclaration ad)
{
ad.include(null).foreachDsymbol( s => s.accept(this) );
visit(cast(Dsymbol)ad);
}
override void visit(ConditionalDeclaration cd)
{
if (cd.condition.inc)
visit(cast(AttribDeclaration)cd);
else
visit(cast(Dsymbol)cd);
}
}
scope v = new InstMemberWalker(tempinst.inst);
tempinst.inst.accept(v);
if (tempinst.minst) // if inst was not speculative if (tempinst.minst) // if inst was not speculative
{ {
/* Add 'inst' once again to the root module members[], then the /* Add 'inst' once again to the root module members[], then the
* instance members will get codegen chances. * instance members will get codegen chances.
*/ */
tempinst.inst.appendToModuleMember(); tempinst.inst.appendToModuleMember();
} }
} }
// modules imported by an existing instance should be added to the modul e // modules imported by an existing instance should be added to the modul e
 End of changes. 6 change blocks. 
16 lines changed or deleted 53 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)