r205972 - CodeGen: Clean up CommonLinkage calculation

David Majnemer david.majnemer at gmail.com
Thu Apr 10 09:53:16 PDT 2014


Author: majnemer
Date: Thu Apr 10 11:53:16 2014
New Revision: 205972

URL: http://llvm.org/viewvc/llvm-project?rev=205972&view=rev
Log:
CodeGen: Clean up CommonLinkage calculation

No functionality change.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=205972&r1=205971&r2=205972&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Apr 10 11:53:16 2014
@@ -1928,6 +1928,34 @@ void CodeGenModule::EmitGlobalVarDefinit
       DI->EmitGlobalVariable(GV, D);
 }
 
+static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
+  // Don't give variables common linkage if -fno-common was specified unless it
+  // was overridden by a NoCommon attribute.
+  if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
+    return true;
+
+  // C11 6.9.2/2:
+  //   A declaration of an identifier for an object that has file scope without
+  //   an initializer, and without a storage-class specifier or with the
+  //   storage-class specifier static, constitutes a tentative definition.
+  if (D->getInit() || D->hasExternalStorage())
+    return true;
+
+  // A variable cannot be both common and exist in a section.
+  if (D->hasAttr<SectionAttr>())
+    return true;
+
+  // Thread local vars aren't considered common linkage.
+  if (D->getTLSKind())
+    return true;
+
+  // Tentative definitions marked with WeakImportAttr are true definitions.
+  if (D->hasAttr<WeakImportAttr>())
+    return true;
+
+  return false;
+}
+
 llvm::GlobalValue::LinkageTypes
 CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {
   GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
@@ -1950,21 +1978,18 @@ CodeGenModule::GetLLVMLinkageVarDefiniti
       return llvm::GlobalVariable::WeakAnyLinkage;
   } else if (Linkage == GVA_TemplateInstantiation || Linkage == GVA_StrongODR)
     return llvm::GlobalVariable::WeakODRLinkage;
-  else if (!getLangOpts().CPlusPlus && 
-           ((!CodeGenOpts.NoCommon && !D->hasAttr<NoCommonAttr>()) ||
-             D->hasAttr<CommonAttr>()) &&
-           !D->hasExternalStorage() && !D->getInit() &&
-           !D->hasAttr<SectionAttr>() && !D->getTLSKind() &&
-           !D->hasAttr<WeakImportAttr>()) {
-    // Thread local vars aren't considered common linkage.
-    return llvm::GlobalVariable::CommonLinkage;
-  } else if (D->getTLSKind() == VarDecl::TLS_Dynamic &&
-             getTarget().getTriple().isMacOSX())
+  else if (D->getTLSKind() == VarDecl::TLS_Dynamic &&
+           getTarget().getTriple().isMacOSX())
     // On Darwin, the backing variable for a C++11 thread_local variable always
     // has internal linkage; all accesses should just be calls to the
     // Itanium-specified entry point, which has the normal linkage of the
     // variable.
     return llvm::GlobalValue::InternalLinkage;
+  // C++ doesn't have tentative definitions and thus cannot have common linkage.
+  else if (!getLangOpts().CPlusPlus &&
+           !isVarDeclStrongDefinition(D, CodeGenOpts.NoCommon))
+    return llvm::GlobalVariable::CommonLinkage;
+
   return llvm::GlobalVariable::ExternalLinkage;
 }
 





More information about the cfe-commits mailing list