diff gen/toobj.cpp @ 88:058d3925950e trunk

[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
author lindquist
date Tue, 06 Nov 2007 10:03:14 +0100
parents fd32135dca3e
children ccca1c13e13a
line wrap: on
line diff
--- a/gen/toobj.cpp	Sat Nov 03 14:48:33 2007 +0100
+++ b/gen/toobj.cpp	Tue Nov 06 10:03:14 2007 +0100
@@ -36,6 +36,7 @@
 #include "gen/logger.h"
 #include "gen/tollvm.h"
 #include "gen/arrays.h"
+#include "gen/structs.h"
 #include "gen/todebug.h"
 #include "gen/runtime.h"
 
@@ -287,6 +288,8 @@
         gIR->module->addTypeName(mangle(),ts->llvmType);
     }
 
+    llvmUnion = new DUnion; // uses gIR->topstruct()
+
     // generate static data
     llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
     llvm::Constant* _init = 0;
@@ -572,6 +575,7 @@
 
     if (aliassym)
     {
+        Logger::println("alias sym");
         toAlias()->toObjFile();
         return;
     }
@@ -608,35 +612,13 @@
         Logger::println("Creating global variable");
         std::string _name(mangle());
 
-        llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M);
-        llvmValue = gvar;
+        bool emitRTstaticInit = false;
 
         if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl))
         {
             if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) {
                 _init = DtoConstInitializer(t, NULL);
-                // create a flag to make sure initialization only happens once
-                llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage;
-                std::string gflagname(_name);
-                gflagname.append("__initflag");
-                llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,M);
-
-                // check flag and do init if not already done
-                llvm::BasicBlock* oldend = gIR->scopeend();
-                llvm::BasicBlock* initbb = new llvm::BasicBlock("ifnotinit",gIR->topfunc(),oldend);
-                llvm::BasicBlock* endinitbb = new llvm::BasicBlock("ifnotinitend",gIR->topfunc(),oldend);
-                llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
-                gIR->ir->CreateCondBr(cond, initbb, endinitbb);
-                gIR->scope() = IRScope(initbb,endinitbb);
-                elem* ie = DtoInitializer(init);
-                if (!ie->inPlace()) {
-                    DValue* dst = new DVarValue(t, gvar, true);
-                    DtoAssign(dst, ie);
-                    delete dst;
-                }
-                gIR->ir->CreateStore(DtoConstBool(true), gflag);
-                gIR->ir->CreateBr(endinitbb);
-                gIR->scope() = IRScope(endinitbb,oldend);
+                emitRTstaticInit = true;
             }
             else {
                 _init = DtoConstInitializer(t, init);
@@ -668,10 +650,15 @@
                     //assert(0);
                 }
             }
+        }
 
-            Logger::cout() << "final init = " << *_init << '\n';
-            gvar->setInitializer(_init);
-        }
+        if (_init && _init->getType() != _type)
+            _type = _init->getType();
+        llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,_init,_name,M);
+        llvmValue = gvar;
+
+        if (emitRTstaticInit)
+            DtoLazyStaticInit(istempl, gvar, init, t);
 
         llvmDModule = gIR->dmodule;