If a function definition has any sort of weak linkage, its static local
variables should have that linkage.  Otherwise, its static local
variables should have internal linkage.  To avoid computing this excessively,
set a function's linkage before we emit code for it.

Previously we were assigning weak linkage to the static variables of
static inline functions in C++, with predictably terrible results.  This
fixes that and also gives better linkage than 'weak' when merging is required.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104581 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 74cf113..85222fe 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -206,6 +206,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 
@@ -269,6 +270,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 611ebed..8115e38 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -114,14 +114,14 @@
     llvm::GlobalValue::LinkageTypes Linkage = 
       llvm::GlobalValue::InternalLinkage;
 
-    // If this is a static declaration inside an inline function, it must have
-    // weak linkage so that the linker will merge multiple definitions of it.
-    if (getContext().getLangOptions().CPlusPlus) {
-      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
-        if (FD->isInlined())
-          Linkage = llvm::GlobalValue::WeakAnyLinkage;
-      }
-    }
+    // If the function definition has some sort of weak linkage, its
+    // static variables should also be weak so that they get properly
+    // uniqued.  We can't do this in C, though, because there's no
+    // standard way to agree on which variables are the same (i.e.
+    // there's no mangling).
+    if (getContext().getLangOptions().CPlusPlus)
+      if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
+        Linkage = CurFn->getLinkage();
     
     return EmitStaticBlockVarDecl(D, Linkage);
   }
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index b66b9f8..8bdd458 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2723,7 +2723,7 @@
   CXXThisDecl->Destroy(getContext());
   
   // Set the right linkage.
-  Fn->setLinkage(CGM.getFunctionLinkage(MD));
+  CGM.setFunctionLinkage(MD, Fn);
   
   // Set the right visibility.
   CGM.setGlobalVisibility(Fn, MD);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 05c7a87..2f8404e 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -361,7 +361,6 @@
 /// variables (these details are set in EmitGlobalVarDefinition for variables).
 void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
                                                     llvm::GlobalValue *GV) {
-  GV->setLinkage(getFunctionLinkage(D));
   SetCommonAttributes(D, GV);
 }
 
@@ -1330,6 +1329,7 @@
   }
 
   llvm::Function *Fn = cast<llvm::Function>(Entry);
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(D, Fn);
 
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 0e4f4a9..e225462 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -436,6 +436,10 @@
   llvm::GlobalVariable::LinkageTypes
   getFunctionLinkage(const FunctionDecl *FD);
 
+  void setFunctionLinkage(const FunctionDecl *FD, llvm::GlobalValue *V) {
+    V->setLinkage(getFunctionLinkage(FD));
+  }
+
   /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
   /// and type information of the given class.
   static llvm::GlobalVariable::LinkageTypes