changeset 1478:4dca8ed9d8b7

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.
author Christian Kamm <kamm incasoftware de>
date Sat, 06 Jun 2009 09:47:32 +0200
parents 6023f65a3aee
children 4f7d50c744ed
files dmd/template.c gen/irstate.h gen/llvmhelpers.cpp gen/toobj.cpp
diffstat 4 files changed, 26 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/template.c	Fri Jun 05 02:54:34 2009 +0200
+++ b/dmd/template.c	Sat Jun 06 09:47:32 2009 +0200
@@ -3106,7 +3106,7 @@
 
 #if IN_LLVM
     // LDC
-    this->tinst = NULL;
+    this->emittedInModule = NULL;
     this->tmodule = NULL;
 #endif
 
--- a/gen/irstate.h	Fri Jun 05 02:54:34 2009 +0200
+++ b/gen/irstate.h	Sat Jun 06 09:47:32 2009 +0200
@@ -158,6 +158,13 @@
     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;
--- a/gen/llvmhelpers.cpp	Fri Jun 05 02:54:34 2009 +0200
+++ b/gen/llvmhelpers.cpp	Sat Jun 06 09:47:32 2009 +0200
@@ -1409,7 +1409,10 @@
             return true;
     
         if (!tinst->emittedInModule)
+        {
+            gIR->seenTemplateInstances.insert(tinst);
             tinst->emittedInModule = gIR->dmodule;
+        }
         return tinst->emittedInModule == gIR->dmodule;
     }
     
--- a/gen/toobj.cpp	Fri Jun 05 02:54:34 2009 +0200
+++ b/gen/toobj.cpp	Sat Jun 06 09:47:32 2009 +0200
@@ -142,6 +142,21 @@
     // 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();