# HG changeset patch # User lindquist # Date 1206384182 -3600 # Node ID 4c577c2b7229ae34ca11a7483378aee1e1ecd715 # Parent 86d3bb8ca33e08d5893c1bccea062d79ff094158 [svn r155] Fixed a bunch of linkage problems (especially with templates) diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/classes.cpp --- a/gen/classes.cpp Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/classes.cpp Mon Mar 24 19:43:02 2008 +0100 @@ -350,7 +350,7 @@ 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 @@ 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 @@ 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 @@ 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"); diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/functions.cpp --- a/gen/functions.cpp Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/functions.cpp Mon Mar 24 19:43:02 2008 +0100 @@ -353,7 +353,7 @@ 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 @@ // 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(f->llvmType->get())); diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/structs.cpp --- a/gen/structs.cpp Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/structs.cpp Mon Mar 24 19:43:02 2008 +0100 @@ -332,7 +332,7 @@ 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; diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/tollvm.cpp --- a/gen/tollvm.cpp Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/tollvm.cpp Mon Mar 24 19:43:02 2008 +0100 @@ -344,36 +344,71 @@ ////////////////////////////////////////////////////////////////////////////////////////// -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) + // 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; - //else - // return llvm::GlobalValue::InternalLinkage; + // 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"); + } - case PROTpublic: - case PROTpackage: - case PROTprotected: - case PROTexport: - return llvm::GlobalValue::ExternalLinkage; - - case PROTundefined: - case PROTnone: - assert(0 && "Unsupported linkage type"); - } + // 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) diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/tollvm.h --- a/gen/tollvm.h Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/tollvm.h Mon Mar 24 19:43:02 2008 +0100 @@ -21,8 +21,10 @@ 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); diff -r 86d3bb8ca33e -r 4c577c2b7229 gen/toobj.cpp --- a/gen/toobj.cpp Sat Mar 22 12:20:32 2008 +0100 +++ b/gen/toobj.cpp Mon Mar 24 19:43:02 2008 +0100 @@ -519,27 +519,21 @@ 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; + bool _isconst = isConst(); + if (parent && parent->isFuncDeclaration()) + { + static_local = true; + if (init && init->isExpInitializer()) { + _isconst = false; + } } - else if (parent && parent->isFuncDeclaration()) { - _linkage = llvm::GlobalValue::InternalLinkage; - static_local = true; - } - else - _linkage = DtoLinkage(protection, storage_class); + + Logger::println("Creating global variable"); const llvm::Type* _type = irGlobal->type.get(); - - Logger::println("Creating global variable"); + llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this); std::string _name(mangle()); llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module); diff -r 86d3bb8ca33e -r 4c577c2b7229 llvmdc.kdevelop --- a/llvmdc.kdevelop Sat Mar 22 12:20:32 2008 +0100 +++ b/llvmdc.kdevelop Mon Mar 24 19:43:02 2008 +0100 @@ -572,6 +572,94 @@ dmd25/utf.h dmd25/version.c dmd25/version.h + dmd26 + dmd26/access.c + dmd26/aggregate.h + dmd26/array.c + dmd26/arraytypes.h + dmd26/attrib.c + dmd26/attrib.h + dmd26/cast.c + dmd26/class.c + dmd26/complex_t.h + dmd26/cond.c + dmd26/cond.h + dmd26/constfold.c + dmd26/dchar.c + dmd26/dchar.h + dmd26/declaration.c + dmd26/declaration.h + dmd26/delegatize.c + dmd26/doc.c + dmd26/doc.h + dmd26/dsymbol.c + dmd26/dsymbol.h + dmd26/dump.c + dmd26/entity.c + dmd26/enum.c + dmd26/enum.h + dmd26/expression.c + dmd26/expression.h + dmd26/func.c + dmd26/gnuc.c + dmd26/gnuc.h + dmd26/hdrgen.c + dmd26/hdrgen.h + dmd26/html.c + dmd26/html.h + dmd26/identifier.c + dmd26/identifier.h + dmd26/idgen.c + dmd26/impcnvgen.c + dmd26/import.c + dmd26/import.h + dmd26/inifile.c + dmd26/init.c + dmd26/init.h + dmd26/inline.c + dmd26/interpret.c + dmd26/lexer.c + dmd26/lexer.h + dmd26/link.c + dmd26/lstring.c + dmd26/lstring.h + dmd26/macro.c + dmd26/macro.h + dmd26/mangle.c + dmd26/mars.c + dmd26/mars.h + dmd26/mem.c + dmd26/mem.h + dmd26/module.c + dmd26/module.h + dmd26/mtype.c + dmd26/mtype.h + dmd26/opover.c + dmd26/optimize.c + dmd26/parse.c + dmd26/parse.h + dmd26/port.h + dmd26/root.c + dmd26/root.h + dmd26/scope.c + dmd26/scope.h + dmd26/statement.c + dmd26/statement.h + dmd26/staticassert.c + dmd26/staticassert.h + dmd26/stringtable.c + dmd26/stringtable.h + dmd26/struct.c + dmd26/template.c + dmd26/template.h + dmd26/total.h + dmd26/unialpha.c + dmd26/utf.c + dmd26/utf.h + dmd26/version.c + dmd26/version.h + todo + todo/lib.d make diff -r 86d3bb8ca33e -r 4c577c2b7229 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Sat Mar 22 12:20:32 2008 +0100 +++ b/llvmdc.kdevelop.filelist Mon Mar 24 19:43:02 2008 +0100 @@ -765,9 +765,7 @@ tangotests/q.d tangotests/r.d tangotests/s.d -tangotests/stdout1.d tangotests/t.d -tangotests/v.d test test/a.d test/aa1.d diff -r 86d3bb8ca33e -r 4c577c2b7229 tangotests/a.d --- a/tangotests/a.d Sat Mar 22 12:20:32 2008 +0100 +++ b/tangotests/a.d Mon Mar 24 19:43:02 2008 +0100 @@ -27,3 +27,8 @@ { auto bar = new Bar(12); } + +void main() +{ + func(); +}