Do the guarding of instantiated static data members
on if its linkage is weak. Currently this is the
case but may change in the future. (part of radar
8562966).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117452 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 6d08064..6567ffb 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -257,11 +257,16 @@
D->getInstantiatedFromStaticDataMember() && D->getInit()){
llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(DeclPtr);
assert(GV && "GenerateCXXGlobalVarDeclInitFunc - GV is null");
- GV->setConstant(false);
- EmitCXXStaticLocalInit(*D, GV);
+ llvm::GlobalValue::LinkageTypes Linkage =
+ CGM.GetLLVMLinkageVarDefinition(D, GV);
+ if (Linkage == llvm::GlobalVariable::WeakAnyLinkage) {
+ GV->setConstant(false);
+ EmitCXXStaticLocalInit(*D, GV);
+ FinishFunction();
+ return;
+ }
}
- else
- EmitCXXGlobalVarDeclInit(*D, DeclPtr);
+ EmitCXXGlobalVarDeclInit(*D, DeclPtr);
FinishFunction();
}
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d35965e..efcdce7 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1154,34 +1154,14 @@
GV->setConstant(true);
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
-
+
// Set the llvm linkage type as appropriate.
- GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
- if (Linkage == GVA_Internal)
- GV->setLinkage(llvm::Function::InternalLinkage);
- else if (D->hasAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->hasAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->hasAttr<WeakAttr>()) {
- if (GV->isConstant())
- GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage);
- else
- GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
- } else if (Linkage == GVA_TemplateInstantiation ||
- Linkage == GVA_ExplicitTemplateInstantiation)
- // FIXME: It seems like we can provide more specific linkage here
- // (LinkOnceODR, WeakODR).
- GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
- else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon &&
- !D->hasExternalStorage() && !D->getInit() &&
- !D->getAttr<SectionAttr>() && !D->isThreadSpecified()) {
- // Thread local vars aren't considered common linkage.
- GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
+ llvm::GlobalValue::LinkageTypes Linkage =
+ GetLLVMLinkageVarDefinition(D, GV);
+ GV->setLinkage(Linkage);
+ if (Linkage == llvm::GlobalVariable::CommonLinkage)
// common vars aren't constant even if declared const.
GV->setConstant(false);
- } else
- GV->setLinkage(llvm::GlobalVariable::ExternalLinkage);
SetCommonAttributes(D, GV);
@@ -1192,6 +1172,35 @@
}
}
+llvm::GlobalValue::LinkageTypes
+CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
+ llvm::GlobalVariable *GV) {
+ GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
+ if (Linkage == GVA_Internal)
+ return llvm::Function::InternalLinkage;
+ else if (D->hasAttr<DLLImportAttr>())
+ return llvm::Function::DLLImportLinkage;
+ else if (D->hasAttr<DLLExportAttr>())
+ return llvm::Function::DLLExportLinkage;
+ else if (D->hasAttr<WeakAttr>()) {
+ if (GV->isConstant())
+ return llvm::GlobalVariable::WeakODRLinkage;
+ else
+ return llvm::GlobalVariable::WeakAnyLinkage;
+ } else if (Linkage == GVA_TemplateInstantiation ||
+ Linkage == GVA_ExplicitTemplateInstantiation)
+ // FIXME: It seems like we can provide more specific linkage here
+ // (LinkOnceODR, WeakODR).
+ return llvm::GlobalVariable::WeakAnyLinkage;
+ else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon &&
+ !D->hasExternalStorage() && !D->getInit() &&
+ !D->getAttr<SectionAttr>() && !D->isThreadSpecified()) {
+ // Thread local vars aren't considered common linkage.
+ return llvm::GlobalVariable::CommonLinkage;
+ }
+ return llvm::GlobalVariable::ExternalLinkage;
+}
+
/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we
/// implement a function with no prototype, e.g. "int foo() {}". If there are
/// existing call uses of the old function in the module, this adjusts them to
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 68898cf..683f175 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -511,7 +511,13 @@
/// GetTargetTypeStoreSize - Return the store size, in character units, of
/// the given LLVM type.
CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const;
-
+
+ /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global
+ /// variable.
+ llvm::GlobalValue::LinkageTypes
+ GetLLVMLinkageVarDefinition(const VarDecl *D,
+ llvm::GlobalVariable *GV);
+
std::vector<const CXXRecordDecl*> DeferredVTables;
private:
@@ -552,7 +558,7 @@
void EmitAliasDefinition(GlobalDecl GD);
void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
-
+
// C++ related functions.
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);