mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-05-04 01:11:29 +02:00
[svn r155] Fixed a bunch of linkage problems (especially with templates)
This commit is contained in:
@@ -350,7 +350,7 @@ void DtoDeclareClass(ClassDeclaration* cd)
|
||||
needs_definition = true;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
|
||||
|
||||
// interfaces have no static initializer
|
||||
// same goes for abstract classes
|
||||
@@ -1201,7 +1201,7 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
|
||||
|
||||
const llvm::Type* st = cinfo->type->llvmType->get();
|
||||
|
||||
cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
|
||||
cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module);
|
||||
}
|
||||
|
||||
static llvm::Constant* build_offti_entry(VarDeclaration* vd)
|
||||
@@ -1275,7 +1275,8 @@ static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* i
|
||||
|
||||
std::string name(cd->type->vtinfo->toChars());
|
||||
name.append("__OffsetTypeInfos");
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module);
|
||||
ptr = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(sTy));
|
||||
}
|
||||
else {
|
||||
@@ -1307,7 +1308,7 @@ static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
|
||||
gname.append(cd->mangle());
|
||||
gname.append("12__destructorMFZv");
|
||||
|
||||
llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module);
|
||||
llvm::Function* func = new llvm::Function(fnTy, DtoInternalLinkage(cd), gname, gIR->module);
|
||||
llvm::Value* thisptr = func->arg_begin();
|
||||
thisptr->setName("this");
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
const llvm::FunctionType* functype = DtoFunctionType(fdecl);
|
||||
llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
|
||||
if (!func)
|
||||
func = new llvm::Function(functype, DtoLinkage(fdecl->protection, fdecl->storage_class), mangled_name, gIR->module);
|
||||
func = new llvm::Function(functype, DtoLinkage(fdecl), mangled_name, gIR->module);
|
||||
else
|
||||
assert(func->getFunctionType() == functype);
|
||||
|
||||
@@ -363,21 +363,8 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
// calling convention
|
||||
if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
|
||||
func->setCallingConv(DtoCallingConv(f->linkage));
|
||||
|
||||
// template instances should have weak linkage
|
||||
if (!vafunc && fdecl->llvmInternal != LLVMintrinsic && fdecl->parent && DtoIsTemplateInstance(fdecl->parent))
|
||||
func->setLinkage(llvm::GlobalValue::WeakLinkage);
|
||||
|
||||
// extern(C) functions are always external
|
||||
if (f->linkage == LINKc)
|
||||
func->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
||||
|
||||
// intrinsics are always external C
|
||||
if (fdecl->llvmInternal == LLVMintrinsic)
|
||||
{
|
||||
func->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
||||
else // fall back to C, it should be the right thing to do
|
||||
func->setCallingConv(llvm::CallingConv::C);
|
||||
}
|
||||
|
||||
fdecl->irFunc->func = func;
|
||||
assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
|
||||
|
||||
@@ -332,7 +332,7 @@ void DtoDeclareStruct(StructDeclaration* sd)
|
||||
initname.append(sd->mangle());
|
||||
initname.append("6__initZ");
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd);
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
|
||||
sd->irStruct->init = initvar;
|
||||
|
||||
|
||||
@@ -344,36 +344,71 @@ llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc)
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
|
||||
{
|
||||
// turns out we can't really make anything internal with the way D works :(
|
||||
// the things we can need much more info than this can extract.
|
||||
// TODO : remove this useless function
|
||||
switch(prot)
|
||||
// global variable
|
||||
if (VarDeclaration* vd = sym->isVarDeclaration())
|
||||
{
|
||||
case PROTprivate:
|
||||
//if (stc & STCextern)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
//else
|
||||
// return llvm::GlobalValue::InternalLinkage;
|
||||
|
||||
case PROTpublic:
|
||||
case PROTpackage:
|
||||
case PROTprotected:
|
||||
case PROTexport:
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
|
||||
case PROTundefined:
|
||||
case PROTnone:
|
||||
assert(0 && "Unsupported linkage type");
|
||||
// template
|
||||
if (DtoIsTemplateInstance(sym))
|
||||
return llvm::GlobalValue::WeakLinkage;
|
||||
// local static
|
||||
else if (sym->parent && sym->parent->isFuncDeclaration())
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
}
|
||||
// function
|
||||
else if (FuncDeclaration* fdecl = sym->isFuncDeclaration())
|
||||
{
|
||||
assert(fdecl->type->ty == Tfunction);
|
||||
TypeFunction* ft = (TypeFunction*)fdecl->type;
|
||||
|
||||
// intrinsics are always external
|
||||
if (fdecl->llvmInternal == LLVMintrinsic)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
// template instances should have weak linkage
|
||||
else if (DtoIsTemplateInstance(fdecl))
|
||||
return llvm::GlobalValue::WeakLinkage;
|
||||
// extern(C) functions are always external
|
||||
else if (ft->linkage == LINKc)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
}
|
||||
// class
|
||||
else if (ClassDeclaration* cd = sym->isClassDeclaration())
|
||||
{
|
||||
// template
|
||||
if (DtoIsTemplateInstance(cd))
|
||||
return llvm::GlobalValue::WeakLinkage;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0 && "not global/function");
|
||||
}
|
||||
|
||||
// default to external linkage
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
|
||||
// llvm linkage types
|
||||
/* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage,
|
||||
InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage,
|
||||
GhostLinkage */
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym)
|
||||
{
|
||||
if (DtoIsTemplateInstance(sym))
|
||||
return llvm::GlobalValue::WeakLinkage;
|
||||
else
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym)
|
||||
{
|
||||
if (DtoIsTemplateInstance(sym))
|
||||
return llvm::GlobalValue::WeakLinkage;
|
||||
else
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned DtoCallingConv(LINK l)
|
||||
|
||||
@@ -21,8 +21,10 @@ llvm::Value* DtoNullDelegate(llvm::Value* v);
|
||||
llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
|
||||
llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs);
|
||||
|
||||
// return linkage types for general cases
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc);
|
||||
// return linkage type for symbol using the current ir state for context
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
|
||||
llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym);
|
||||
llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
|
||||
|
||||
// convert DMD calling conv to LLVM
|
||||
unsigned DtoCallingConv(LINK l);
|
||||
|
||||
@@ -519,27 +519,21 @@ void VarDeclaration::toObjFile()
|
||||
|
||||
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
|
||||
|
||||
bool _isconst = isConst();
|
||||
if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer())
|
||||
_isconst = false;
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage;
|
||||
bool istempl = false;
|
||||
// handle static local variables
|
||||
bool static_local = false;
|
||||
if ((storage_class & STCcomdat) || (parent && DtoIsTemplateInstance(parent))) {
|
||||
_linkage = llvm::GlobalValue::WeakLinkage;
|
||||
istempl = true;
|
||||
}
|
||||
else if (parent && parent->isFuncDeclaration()) {
|
||||
_linkage = llvm::GlobalValue::InternalLinkage;
|
||||
bool _isconst = isConst();
|
||||
if (parent && parent->isFuncDeclaration())
|
||||
{
|
||||
static_local = true;
|
||||
if (init && init->isExpInitializer()) {
|
||||
_isconst = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
_linkage = DtoLinkage(protection, storage_class);
|
||||
|
||||
const llvm::Type* _type = irGlobal->type.get();
|
||||
|
||||
Logger::println("Creating global variable");
|
||||
|
||||
const llvm::Type* _type = irGlobal->type.get();
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
|
||||
|
||||
Reference in New Issue
Block a user