diff --git a/dmd2/func.c b/dmd2/func.c index 9f581356..27806134 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -3447,7 +3447,7 @@ void StaticDtorDeclaration::semantic(Scope *sc) Statement *s = new DeclarationStatement(0, v); sa->push(s); Expression *e = new IdentifierExp(0, id); - e = new AddAssignExp(0, e, new IntegerExp((uint64_t)-1)); + e = new AddAssignExp(0, e, new IntegerExp((uint64_t)-1)); e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(0)); s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL); sa->push(s); diff --git a/gen/functions.cpp b/gen/functions.cpp index 39097d1c..eaa4e25a 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -509,9 +509,11 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) } } // shared static dtor - else if (fdecl->isSharedStaticDtorDeclaration()) { + else if (StaticDtorDeclaration *dtorDecl = fdecl->isSharedStaticDtorDeclaration()) { if (mustDefineSymbol(fdecl)) { gIR->sharedDtors.push_front(fdecl); + if (dtorDecl->vgate) + gIR->sharedGates.push_front(dtorDecl->vgate); } } else #endif @@ -522,9 +524,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) } } // static dtor - else if (fdecl->isStaticDtorDeclaration()) { + else if (StaticDtorDeclaration *dtorDecl = fdecl->isStaticDtorDeclaration()) { if (mustDefineSymbol(fdecl)) { - gIR->dtors.insert(gIR->dtors.begin(), fdecl); + gIR->dtors.push_front(fdecl); +#if DMDV2 + if (dtorDecl->vgate) + gIR->gates.push_front(dtorDecl->vgate); +#endif } } diff --git a/gen/irstate.h b/gen/irstate.h index 66c5819f..4323a3d8 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -161,11 +161,14 @@ struct IRState // static ctors/dtors/unittests typedef std::list FuncDeclList; + typedef std::list GatesList; FuncDeclList ctors; FuncDeclList dtors; #if DMDV2 FuncDeclList sharedCtors; FuncDeclList sharedDtors; + GatesList gates; + GatesList sharedGates; #endif FuncDeclList unitTests; diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 1a19a734..a564ede7 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -388,14 +388,16 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath) /* ================================================================== */ -static llvm::Function* build_module_function(const std::string &name, const std::list &funcs) +static llvm::Function* build_module_function(const std::string &name, const std::list &funcs, + const std::list &gates = std::list()) { - if (funcs.empty()) - return NULL; + if (gates.empty()) { + if (funcs.empty()) + return NULL; - size_t n = funcs.size(); - if (n == 1) - return funcs.front()->ir.irFunc->func; + if (funcs.size() == 1) + return funcs.front()->ir.irFunc->func; + } std::vector argsTy; const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); @@ -412,13 +414,24 @@ static llvm::Function* build_module_function(const std::string &name, const std: DtoDwarfSubProgramInternal(name.c_str(), name.c_str()); #endif - typedef std::list::const_iterator Iterator; - for (Iterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) { + // Call ctor's + typedef std::list::const_iterator FuncIterator; + for (FuncIterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) { llvm::Function* f = (*itr)->ir.irFunc->func; llvm::CallInst* call = builder.CreateCall(f,""); call->setCallingConv(DtoCallingConv(0, LINKd)); } + // Increment vgate's + typedef std::list::const_iterator GatesIterator; + for (GatesIterator itr = gates.begin(), end = gates.end(); itr != end; ++itr) { + assert((*itr)->ir.irGlobal); + llvm::Value* val = (*itr)->ir.irGlobal->value; + llvm::Value* rval = builder.CreateLoad(val, "vgate"); + llvm::Value* res = builder.CreateAdd(rval, DtoConstUint(1), "vgate"); + builder.CreateStore(res, val); + } + builder.CreateRetVoid(); return fn; } @@ -430,7 +443,11 @@ llvm::Function* build_module_ctor() std::string name("_D"); name.append(gIR->dmodule->mangle()); name.append("6__ctorZ"); +#if DMDV2 + return build_module_function(name, gIR->ctors, gIR->gates); +#else return build_module_function(name, gIR->ctors); +#endif } // build module dtor @@ -462,7 +479,7 @@ llvm::Function* build_module_shared_ctor() std::string name("_D"); name.append(gIR->dmodule->mangle()); name.append("13__shared_ctorZ"); - return build_module_function(name, gIR->sharedCtors); + return build_module_function(name, gIR->sharedCtors, gIR->sharedGates); } // build module shared dtor