]> granicus.if.org Git - clang/commitdiff
CodeGen: Cleanup variable linkage calculation
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 25 Apr 2014 17:08:41 +0000 (17:08 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 25 Apr 2014 17:08:41 +0000 (17:08 +0000)
Almost all linkage calculation for VarDecls occured inside of
GetLLVMLinkageVarDefinition except for static data members.  Centralize
the logic so that it can be more readily reused.

No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207241 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp

index bac9b22befc54842c4e1c177c9c27465c75141e0..34673bf29adcbf81fab3c862632f7229b4ddc3a4 100644 (file)
@@ -1565,6 +1565,18 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
   return true;
 }
 
+static bool isVarDeclInlineInitializedStaticDataMember(const VarDecl *VD) {
+  if (!VD->isStaticDataMember())
+    return false;
+  const VarDecl *InitDecl;
+  const Expr *InitExpr = VD->getAnyInitializer(InitDecl);
+  if (!InitExpr)
+    return false;
+  if (InitDecl->isThisDeclarationADefinition())
+    return false;
+  return true;
+}
+
 /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
 /// create and return an llvm GlobalVariable with the specified type.  If there
 /// is something in the module with the specified name, return it potentially
@@ -1633,8 +1645,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
     // If required by the ABI, treat declarations of static data members with
     // inline initializers as definitions.
     if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
-        D->isStaticDataMember() && D->hasInit() &&
-        !D->isThisDeclarationADefinition())
+        isVarDeclInlineInitializedStaticDataMember(D))
       EmitGlobalVarDefinition(D);
   }
 
@@ -1900,13 +1911,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
   else if (D->hasAttr<DLLExportAttr>())
     GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
 
-  // If required by the ABI, give definitions of static data members with inline
-  // initializers linkonce_odr linkage.
-  if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
-      D->isStaticDataMember() && InitExpr &&
-      !InitDecl->isThisDeclarationADefinition())
-    GV->setLinkage(llvm::GlobalVariable::LinkOnceODRLinkage);
-
   if (Linkage == llvm::GlobalVariable::CommonLinkage)
     // common vars aren't constant even if declared const.
     GV->setConstant(false);
@@ -1992,6 +1996,11 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {
     // Itanium-specified entry point, which has the normal linkage of the
     // variable.
     return llvm::GlobalValue::InternalLinkage;
+  else if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
+           isVarDeclInlineInitializedStaticDataMember(D))
+    // If required by the ABI, give definitions of static data members with inline
+    // initializers linkonce_odr linkage.
+    return llvm::GlobalVariable::LinkOnceODRLinkage;
   // C++ doesn't have tentative definitions and thus cannot have common linkage.
   else if (!getLangOpts().CPlusPlus &&
            !isVarDeclStrongDefinition(D, CodeGenOpts.NoCommon))