diff gen/tollvm.cpp @ 149:4c577c2b7229 trunk

[svn r155] Fixed a bunch of linkage problems (especially with templates)
author lindquist
date Mon, 24 Mar 2008 19:43:02 +0100
parents a27941d00351
children 7f92f477ff53
line wrap: on
line diff
--- 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)