aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-10-27 16:21:54 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-10-27 16:21:54 +0000
commit354e712c81fbb07c0ce5f06180788b25fffa1b56 (patch)
treefdbfd22a1493fb51b2555952ae134f42fd605d35
parent715c92aece8d2861ee5d7aa0a04253407b3b6f92 (diff)
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
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp13
-rw-r--r--lib/CodeGen/CodeGenModule.cpp47
-rw-r--r--lib/CodeGen/CodeGenModule.h10
3 files changed, 45 insertions, 25 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 6d0806424d..6567ffb07d 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -257,11 +257,16 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
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 d35965e2c4..efcdce70a0 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1154,42 +1154,51 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
GV->setConstant(true);
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
-
+
// Set the llvm linkage type as appropriate.
+ 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);
+
+ SetCommonAttributes(D, GV);
+
+ // Emit global variable debug information.
+ if (CGDebugInfo *DI = getDebugInfo()) {
+ DI->setLocation(D->getLocation());
+ DI->EmitGlobalVariable(GV, D);
+ }
+}
+
+llvm::GlobalValue::LinkageTypes
+CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
+ llvm::GlobalVariable *GV) {
GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
if (Linkage == GVA_Internal)
- GV->setLinkage(llvm::Function::InternalLinkage);
+ return llvm::Function::InternalLinkage;
else if (D->hasAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
+ return llvm::Function::DLLImportLinkage;
else if (D->hasAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
+ return llvm::Function::DLLExportLinkage;
else if (D->hasAttr<WeakAttr>()) {
if (GV->isConstant())
- GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage);
+ return llvm::GlobalVariable::WeakODRLinkage;
else
- GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+ 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).
- GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+ 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.
- GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
- // common vars aren't constant even if declared const.
- GV->setConstant(false);
- } else
- GV->setLinkage(llvm::GlobalVariable::ExternalLinkage);
-
- SetCommonAttributes(D, GV);
-
- // Emit global variable debug information.
- if (CGDebugInfo *DI = getDebugInfo()) {
- DI->setLocation(D->getLocation());
- DI->EmitGlobalVariable(GV, D);
+ return llvm::GlobalVariable::CommonLinkage;
}
+ return llvm::GlobalVariable::ExternalLinkage;
}
/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 68898cf5d0..683f175737 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -511,7 +511,13 @@ public:
/// 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 @@ private:
void EmitAliasDefinition(GlobalDecl GD);
void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
-
+
// C++ related functions.
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);