[PATCH] D80836: Support GCC [[gnu::attributes]] in C2x mode

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 29 13:41:20 PDT 2020


aaron.ballman created this revision.
aaron.ballman added reviewers: rsmith, erichkeane, dblaikie.
Herald added a subscriber: krytarowski.

GCC 10.1 introduced support for the `[[]]` style spelling of attributes in C mode. Similar to how GCC supports `__attribute__((foo))` as `[[gnu::foo]]` in C++ mode, it now supports the same spelling in C mode as well. This patch makes a change in Clang so that when you use the `GCC` attribute spelling, the attribute is automatically available in all three spellings by default. However, like Clang, GCC has some attributes it only recognizes in C++ mode (specifically, `abi_tag` and `init_priority`), which this patch also honors.


https://reviews.llvm.org/D80836

Files:
  clang/include/clang/Basic/Attr.td
  clang/test/Sema/attr-c2x.c
  clang/utils/TableGen/ClangAttrEmitter.cpp


Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -82,9 +82,10 @@
     StringRef Variety = Spelling->getValueAsString("Variety");
     StringRef Name = Spelling->getValueAsString("Name");
     if (Variety == "GCC") {
-      // Gin up two new spelling objects to add into the list.
       Ret.emplace_back("GNU", std::string(Name), "", true);
       Ret.emplace_back("CXX11", std::string(Name), "gnu", true);
+      if (Spelling->getValueAsBit("AllowInC"))
+        Ret.emplace_back("C2x", std::string(Name), "gnu", true);
     } else if (Variety == "Clang") {
       Ret.emplace_back("GNU", std::string(Name), "", false);
       Ret.emplace_back("CXX11", std::string(Name), "clang", false);
Index: clang/test/Sema/attr-c2x.c
===================================================================
--- clang/test/Sema/attr-c2x.c
+++ clang/test/Sema/attr-c2x.c
@@ -27,3 +27,15 @@
 
 [[nodiscard]] int without_underscores(void);
 [[__nodiscard__]] int underscores(void);
+
+// Match GCC's behavior for C attributes as well.
+[[gnu::constructor]] void ctor_func(void);
+[[gnu::destructor]] void dtor_func(void);
+[[gnu::hot]] void hot_func(void);
+[[__gnu__::hot]] void hot_func2(void);
+[[gnu::__hot__]] void hot_func3(void);
+[[__gnu__::__hot__]] void hot_func4(void);
+
+// Note how not all GCC attributes are supported in C.
+[[gnu::abi_tag("")]] void abi_func(void); // expected-warning {{unknown attribute 'abi_tag' ignored}}
+struct S s [[gnu::init_priority(1)]]; // expected-warning {{unknown attribute 'init_priority' ignored}}
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -277,11 +277,12 @@
   string Namespace = namespace;
 }
 
-// The GCC spelling implies GNU<name> and CXX11<"gnu", name> and also sets
-// KnownToGCC to 1. This spelling should be used for any GCC-compatible
-// attributes.
-class GCC<string name> : Spelling<name, "GCC"> {
+// The GCC spelling implies GNU<name>, CXX11<"gnu", name>, and optionally,
+// C2x<"gnu", name>, and also sets KnownToGCC to 1. This spelling should be
+// used for any GCC-compatible attributes.
+class GCC<string name, bit allowInC = 1> : Spelling<name, "GCC"> {
   let KnownToGCC = 1;
+  bit AllowInC = allowInC;
 }
 
 // The Clang spelling implies GNU<name>, CXX11<"clang", name>, and optionally,
@@ -605,7 +606,7 @@
 //
 
 def AbiTag : Attr {
-  let Spellings = [GCC<"abi_tag">];
+  let Spellings = [GCC<"abi_tag", /*AllowInC*/0>];
   let Args = [VariadicStringArgument<"Tags">];
   let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>;
   let MeaningfulToClassTemplateDefinition = 1;
@@ -2113,7 +2114,7 @@
 }
 
 def InitPriority : InheritableAttr {
-  let Spellings = [GCC<"init_priority">];
+  let Spellings = [GCC<"init_priority", /*AllowInC*/0>];
   let Args = [UnsignedArgument<"Priority">];
   let Subjects = SubjectList<[Var], ErrorDiag>;
   let Documentation = [Undocumented];


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80836.267353.patch
Type: text/x-patch
Size: 3162 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200529/376e4be5/attachment-0001.bin>


More information about the cfe-commits mailing list