Fix #318 by making a list of all seen template instances in a module for

singleobj compilation and then making sure they get emitted in their entirety.
This commit is contained in:
Christian Kamm
2009-06-06 09:47:32 +02:00
parent c6946d4072
commit b4f8bd6e52
4 changed files with 26 additions and 1 deletions

View File

@@ -3106,7 +3106,7 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
#if IN_LLVM
// LDC
this->tinst = NULL;
this->emittedInModule = NULL;
this->tmodule = NULL;
#endif

View File

@@ -158,6 +158,13 @@ struct IRState
FuncDeclVector ctors;
FuncDeclVector dtors;
FuncDeclVector unitTests;
// all template instances that had members emitted
// currently only filled for singleobj
// used to make sure the complete template instance gets emitted in the
// first file that touches a member, see #318
typedef std::set<TemplateInstance*> TemplateInstanceSet;
TemplateInstanceSet seenTemplateInstances;
// for inline asm
IRAsmBlock* asmBlock;

View File

@@ -1409,7 +1409,10 @@ bool mustDefineSymbol(Dsymbol* s)
return true;
if (!tinst->emittedInModule)
{
gIR->seenTemplateInstances.insert(tinst);
tinst->emittedInModule = gIR->dmodule;
}
return tinst->emittedInModule == gIR->dmodule;
}

View File

@@ -142,6 +142,21 @@ llvm::Module* Module::genLLVMModule(Ir* sir)
// emit function bodies
sir->emitFunctionBodies();
// for singleobj-compilation, fully emit all seen template instances
if (opts::singleObj)
{
while (!ir.seenTemplateInstances.empty())
{
IRState::TemplateInstanceSet::iterator it, end = ir.seenTemplateInstances.end();
for (it = ir.seenTemplateInstances.begin(); it != end; ++it)
(*it)->codegen(sir);
ir.seenTemplateInstances.clear();
// emit any newly added function bodies
sir->emitFunctionBodies();
}
}
// generate ModuleInfo
genmoduleinfo();