aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2010-12-02 02:45:55 +0000
committerEric Christopher <echristo@apple.com>2010-12-02 02:45:55 +0000
commita6cf1e709b96865210b81bd611d41e9a2d41500a (patch)
tree7457fa81e5da2e3e5075164bfb5afde7dd557c07
parent7b3982b40665e995ea62ca1b03923cbcc2391c14 (diff)
Add support for the common and nocommon attributes.
rdar://8560647 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120650 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/Attr.td8
-rw-r--r--include/clang/Sema/AttributeList.h2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--lib/Sema/AttributeList.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp12
-rw-r--r--test/CodeGen/no-common.c9
6 files changed, 36 insertions, 1 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index ad913a4901..ec88da13b4 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -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"];
}
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index bc1c2e29fb..4862ff5b12 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -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,
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index a3cf69b675..1dab027455 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -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.
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 409e2488bd..b2ceb53cc5 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -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);
}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index df74e00de0..ee03d1f7f1 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -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:
diff --git a/test/CodeGen/no-common.c b/test/CodeGen/no-common.c
index a8f2b2b277..7beefc7b69 100644
--- a/test/CodeGen/no-common.c
+++ b/test/CodeGen/no-common.c
@@ -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