Increment vgates in static constructors. That fixes static destructors of templates.

This commit is contained in:
Alexey Prokhin 2011-01-02 17:43:02 +03:00
parent a86f414bc1
commit 8a49067776
4 changed files with 39 additions and 13 deletions

View file

@ -3447,7 +3447,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
Statement *s = new DeclarationStatement(0, v); Statement *s = new DeclarationStatement(0, v);
sa->push(s); sa->push(s);
Expression *e = new IdentifierExp(0, id); 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)); e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(0));
s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL); s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
sa->push(s); sa->push(s);

View file

@ -509,9 +509,11 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
} }
} }
// shared static dtor // shared static dtor
else if (fdecl->isSharedStaticDtorDeclaration()) { else if (StaticDtorDeclaration *dtorDecl = fdecl->isSharedStaticDtorDeclaration()) {
if (mustDefineSymbol(fdecl)) { if (mustDefineSymbol(fdecl)) {
gIR->sharedDtors.push_front(fdecl); gIR->sharedDtors.push_front(fdecl);
if (dtorDecl->vgate)
gIR->sharedGates.push_front(dtorDecl->vgate);
} }
} else } else
#endif #endif
@ -522,9 +524,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
} }
} }
// static dtor // static dtor
else if (fdecl->isStaticDtorDeclaration()) { else if (StaticDtorDeclaration *dtorDecl = fdecl->isStaticDtorDeclaration()) {
if (mustDefineSymbol(fdecl)) { 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
} }
} }

View file

@ -161,11 +161,14 @@ struct IRState
// static ctors/dtors/unittests // static ctors/dtors/unittests
typedef std::list<FuncDeclaration*> FuncDeclList; typedef std::list<FuncDeclaration*> FuncDeclList;
typedef std::list<VarDeclaration*> GatesList;
FuncDeclList ctors; FuncDeclList ctors;
FuncDeclList dtors; FuncDeclList dtors;
#if DMDV2 #if DMDV2
FuncDeclList sharedCtors; FuncDeclList sharedCtors;
FuncDeclList sharedDtors; FuncDeclList sharedDtors;
GatesList gates;
GatesList sharedGates;
#endif #endif
FuncDeclList unitTests; FuncDeclList unitTests;

View file

@ -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<FuncDeclaration*> &funcs) static llvm::Function* build_module_function(const std::string &name, const std::list<FuncDeclaration*> &funcs,
const std::list<VarDeclaration*> &gates = std::list<VarDeclaration*>())
{ {
if (funcs.empty()) if (gates.empty()) {
return NULL; if (funcs.empty())
return NULL;
size_t n = funcs.size(); if (funcs.size() == 1)
if (n == 1) return funcs.front()->ir.irFunc->func;
return funcs.front()->ir.irFunc->func; }
std::vector<const LLType*> argsTy; std::vector<const LLType*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::getVoidTy(gIR->context()),argsTy,false); 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()); DtoDwarfSubProgramInternal(name.c_str(), name.c_str());
#endif #endif
typedef std::list<FuncDeclaration*>::const_iterator Iterator; // Call ctor's
for (Iterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) { typedef std::list<FuncDeclaration*>::const_iterator FuncIterator;
for (FuncIterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) {
llvm::Function* f = (*itr)->ir.irFunc->func; llvm::Function* f = (*itr)->ir.irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,""); llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(DtoCallingConv(0, LINKd)); call->setCallingConv(DtoCallingConv(0, LINKd));
} }
// Increment vgate's
typedef std::list<VarDeclaration*>::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(); builder.CreateRetVoid();
return fn; return fn;
} }
@ -430,7 +443,11 @@ llvm::Function* build_module_ctor()
std::string name("_D"); std::string name("_D");
name.append(gIR->dmodule->mangle()); name.append(gIR->dmodule->mangle());
name.append("6__ctorZ"); name.append("6__ctorZ");
#if DMDV2
return build_module_function(name, gIR->ctors, gIR->gates);
#else
return build_module_function(name, gIR->ctors); return build_module_function(name, gIR->ctors);
#endif
} }
// build module dtor // build module dtor
@ -462,7 +479,7 @@ llvm::Function* build_module_shared_ctor()
std::string name("_D"); std::string name("_D");
name.append(gIR->dmodule->mangle()); name.append(gIR->dmodule->mangle());
name.append("13__shared_ctorZ"); 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 // build module shared dtor