]> granicus.if.org Git - clang/commitdiff
Add support for the common and nocommon attributes.
authorEric Christopher <echristo@apple.com>
Thu, 2 Dec 2010 02:45:55 +0000 (02:45 +0000)
committerEric Christopher <echristo@apple.com>
Thu, 2 Dec 2010 02:45:55 +0000 (02:45 +0000)
rdar://8560647

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

include/clang/Basic/Attr.td
include/clang/Sema/AttributeList.h
lib/CodeGen/CodeGenModule.cpp
lib/Sema/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGen/no-common.c

index ad913a49011d306d8c1e630a9886cdfa0c4f52e9..ec88da13b4a558af69105c36100a5065a1b38e9f 100644 (file)
@@ -161,6 +161,10 @@ def Cleanup : Attr {
   let Args = [FunctionArgument<"FunctionDecl">];
 }
 
+def Common : Attr {
+  let Spellings = ["common"];
+}
+
 def Const : Attr {
   let Spellings = ["const"];
 }
@@ -274,6 +278,10 @@ def Naked : Attr {
   let Spellings = ["naked"];
 }
 
+def NoCommon : Attr {
+  let Spellings = ["nocommon"];
+}
+
 def NoDebug : Attr {
   let Spellings = ["nodebug"];
 }
index bc1c2e29fbf83c71871c05b84f6fc26b165bd8d0..4862ff5b12f87e1e470d2c88af544bf83eaf0ba9 100644 (file)
@@ -91,6 +91,7 @@ public:
     AT_carries_dependency,
     AT_cdecl,
     AT_cleanup,
+    AT_common,
     AT_const,
     AT_constant,
     AT_constructor,
@@ -117,6 +118,7 @@ public:
     AT_nodebug,
     AT_noinline,
     AT_no_instrument_function,
+    AT_nocommon,
     AT_nonnull,
     AT_noreturn,
     AT_nothrow,
index a3cf69b675cd27320a4ffa4b58c1403f3c51011e..1dab0274556b9fa92a4845e156e282dfbfc9e887 100644 (file)
@@ -1214,7 +1214,9 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
     // FIXME: It seems like we can provide more specific linkage here
     // (LinkOnceODR, WeakODR).
     return llvm::GlobalVariable::WeakAnyLinkage;
-  else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon &&
+  else if (!getLangOptions().CPlusPlus && 
+           ((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||
+             D->getAttr<CommonAttr>()) &&
            !D->hasExternalStorage() && !D->getInit() &&
            !D->getAttr<SectionAttr>() && !D->isThreadSpecified()) {
     // Thread local vars aren't considered common linkage.
index 409e2488bde375236c192c5963372f4e679d3790..b2ceb53cc534aeb0d13224c02c1693a577d1de21 100644 (file)
@@ -130,5 +130,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
     .Case("global", AT_global)
     .Case("host", AT_host)
     .Case("shared", AT_shared)
+    .Case("common", AT_common)
+    .Case("nocommon", AT_nocommon)
     .Default(UnknownAttribute);
 }
index df74e00de0b9a7a475d41674c4699373e6524cd4..ee03d1f7f18b9fee2077b1ca81fa82aa888b6668 100644 (file)
@@ -743,6 +743,16 @@ static void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
 }
 
+static void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  assert(Attr.isInvalid() == false);
+  d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  assert(Attr.isInvalid() == false);
+  d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
+}
+
 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
   assert(Attr.isInvalid() == false);
@@ -2474,6 +2484,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
   case AttributeList::AT_carries_dependency:
                                       HandleDependencyAttr  (D, Attr, S); break;
+  case AttributeList::AT_common:      HandleCommonAttr      (D, Attr, S); break;
   case AttributeList::AT_constant:    HandleConstantAttr    (D, Attr, S); break;
   case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
   case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
@@ -2492,6 +2503,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
   case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
   case AttributeList::AT_may_alias:   HandleMayAliasAttr    (D, Attr, S); break;
+  case AttributeList::AT_nocommon:    HandleNoCommonAttr    (D, Attr, S); break;
   case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
   case AttributeList::AT_ownership_returns:
   case AttributeList::AT_ownership_takes:
index a8f2b2b277317e52969a7d68a64057edd75f28fe..7beefc7b690d8479595f977c8abe8488ec47e1ee 100644 (file)
@@ -4,3 +4,12 @@
 // CHECK-DEFAULT: @x = common global
 // CHECK-NOCOMMON: @x = global
 int x;
+
+// CHECK-DEFAULT: @ABC = global
+// CHECK-NOCOMMON: @ABC = global
+typedef void* (*fn_t)(long a, long b, char *f, int c);
+fn_t ABC __attribute__ ((nocommon));
+
+// CHECK-DEFAULT: @y = common global
+// CHECK-NOCOMMON: @y = common global
+int y __attribute__((common));
\ No newline at end of file