From a6cf1e709b96865210b81bd611d41e9a2d41500a Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 2 Dec 2010 02:45:55 +0000 Subject: [PATCH] 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 --- include/clang/Basic/Attr.td | 8 ++++++++ include/clang/Sema/AttributeList.h | 2 ++ lib/CodeGen/CodeGenModule.cpp | 4 +++- lib/Sema/AttributeList.cpp | 2 ++ lib/Sema/SemaDeclAttr.cpp | 12 ++++++++++++ test/CodeGen/no-common.c | 9 +++++++++ 6 files changed, 36 insertions(+), 1 deletion(-) 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()) || + D->getAttr()) && !D->hasExternalStorage() && !D->getInit() && !D->getAttr() && !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 -- 2.40.0