[clang] 9936b96 - Support the standards-based dates for __has_c_attribute

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 13 05:49:31 PDT 2020


Author: Aaron Ballman
Date: 2020-08-13T08:47:40-04:00
New Revision: 9936b96d5333af4e6dff55025943366bb5f07272

URL: https://github.com/llvm/llvm-project/commit/9936b96d5333af4e6dff55025943366bb5f07272
DIFF: https://github.com/llvm/llvm-project/commit/9936b96d5333af4e6dff55025943366bb5f07272.diff

LOG: Support the standards-based dates for __has_c_attribute

WG14 N2481 was adopted with minor modifications at the latest WG14 meetings.
The only modification to the paper was to correct the date for the deprecated
attribute to be 201904L (the corrected date value will be present in WG14
N2553 when it gets published).

Added: 
    

Modified: 
    clang/include/clang/Basic/Attr.td
    clang/test/Preprocessor/has_c_attribute.c
    clang/utils/TableGen/ClangAttrEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index f9bf3f0acd553..3d8ad705f91fc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -267,8 +267,10 @@ class CXX11<string namespace, string name, int version = 1>
   string Namespace = namespace;
   int Version = version;
 }
-class C2x<string namespace, string name> : Spelling<name, "C2x"> {
+class C2x<string namespace, string name, int version = 1>
+    : Spelling<name, "C2x"> {
   string Namespace = namespace;
+  int Version = version;
 }
 
 class Keyword<string name> : Spelling<name, "Keyword">;
@@ -1221,7 +1223,8 @@ def RenderScriptKernel : Attr {
 
 def Deprecated : InheritableAttr {
   let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
-                   CXX11<"","deprecated", 201309>, C2x<"", "deprecated">];
+                   CXX11<"","deprecated", 201309>,
+                   C2x<"", "deprecated", 201904>];
   let Args = [StringArgument<"Message", 1>,
               // An optional string argument that enables us to provide a
               // Fix-It.
@@ -1278,7 +1281,8 @@ def ExtVectorType : Attr {
 }
 
 def FallThrough : StmtAttr {
-  let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">,
+  let Spellings = [CXX11<"", "fallthrough", 201603>,
+                   C2x<"", "fallthrough", 201904>,
                    CXX11<"clang", "fallthrough">, GCC<"fallthrough">];
 //  let Subjects = [NullStmt];
   let Documentation = [FallthroughDocs];
@@ -2442,7 +2446,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
 
 def Unused : InheritableAttr {
   let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
-                   C2x<"", "maybe_unused">];
+                   C2x<"", "maybe_unused", 201904>];
   let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
                               Field, ObjCMethod, FunctionLike]>;
   let Documentation = [WarnMaybeUnusedDocs];
@@ -2528,7 +2532,8 @@ def WarnUnused : InheritableAttr {
 }
 
 def WarnUnusedResult : InheritableAttr {
-  let Spellings = [CXX11<"", "nodiscard", 201907>, C2x<"", "nodiscard">,
+  let Spellings = [CXX11<"", "nodiscard", 201907>,
+                   C2x<"", "nodiscard", 201904>,
                    CXX11<"clang", "warn_unused_result">,
                    GCC<"warn_unused_result">];
   let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;

diff  --git a/clang/test/Preprocessor/has_c_attribute.c b/clang/test/Preprocessor/has_c_attribute.c
index f8b0b364faa5f..670e42a97926e 100644
--- a/clang/test/Preprocessor/has_c_attribute.c
+++ b/clang/test/Preprocessor/has_c_attribute.c
@@ -1,22 +1,44 @@
-// RUN: %clang_cc1 -fdouble-square-bracket-attributes -std=c11 -E %s -o - | FileCheck %s
-// RUN: %clang_cc1 -std=c2x -E %s -o - | FileCheck %s
-
-// CHECK: has_fallthrough
-#if __has_c_attribute(fallthrough)
-  int has_fallthrough();
-#endif
-
-// CHECK: does_not_have_selectany
-#if !__has_c_attribute(selectany)
-  int does_not_have_selectany();
-#endif
-
-// CHECK: has_nodiscard_underscore
-#if __has_c_attribute(__nodiscard__)
-  int has_nodiscard_underscore();
-#endif
-
-// CHECK: has_clang_annotate
-#if __has_c_attribute(clang::annotate)
-  int has_clang_annotate();
-#endif
+// RUN: %clang_cc1 -fdouble-square-bracket-attributes -std=c11 -E -P %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c2x -E -P %s -o - | FileCheck %s
+
+#define C2x(x) x: __has_c_attribute(x)
+
+// CHECK: fallthrough: 201904L
+C2x(fallthrough)
+
+// CHECK: __nodiscard__: 201904L
+C2x(__nodiscard__)
+
+// CHECK: selectany: 0
+C2x(selectany); // Known attribute not supported in C mode
+
+// CHECK: frobble: 0
+C2x(frobble) // Unknown attribute
+
+// CHECK: frobble::frobble: 0
+C2x(frobble::frobble) // Unknown vendor namespace
+
+// CHECK: clang::annotate: 1
+C2x(clang::annotate)
+
+// CHECK: deprecated: 201904L
+C2x(deprecated)
+
+// CHECK: maybe_unused: 201904L
+C2x(maybe_unused)
+
+// CHECK: __gnu__::warn_unused_result: 201904L
+C2x(__gnu__::warn_unused_result)
+
+// CHECK: gnu::__warn_unused_result__: 201904L
+C2x(gnu::__warn_unused_result__)
+
+// We do somewhat support the __clang__ vendor namespace, but it is a
+// predefined macro and thus we encourage users to use _Clang instead.
+// Because of this, we do not support __has_c_attribute for that
+// vendor namespace.
+//
+// Note, we can't use C2x here because it will expand __clang__ to 1
+// too early.
+// CHECK: 1::fallthrough: 0
+__clang__::fallthrough: __has_c_attribute(__clang__::fallthrough)

diff  --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index bd20e447a9506..e21d68d8f9214 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3064,18 +3064,22 @@ static void GenerateHasAttrSpellingStringSwitch(
     // attribute version information should be taken from the SD-6 standing
     // document, which can be found at:
     // https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
+    //
+    // C2x-style attributes have the same kind of version information
+    // associated with them. The unscoped attribute version information should
+    // be taken from the specification of the attribute in the C Standard.
     int Version = 1;
 
-    if (Variety == "CXX11") {
-        std::vector<Record *> Spellings = Attr->getValueAsListOfDefs("Spellings");
-        for (const auto &Spelling : Spellings) {
-          if (Spelling->getValueAsString("Variety") == "CXX11") {
-            Version = static_cast<int>(Spelling->getValueAsInt("Version"));
-            if (Scope.empty() && Version == 1)
-              PrintError(Spelling->getLoc(), "C++ standard attributes must "
-              "have valid version information.");
-            break;
-          }
+    if (Variety == "CXX11" || Variety == "C2x") {
+      std::vector<Record *> Spellings = Attr->getValueAsListOfDefs("Spellings");
+      for (const auto &Spelling : Spellings) {
+        if (Spelling->getValueAsString("Variety") == Variety) {
+          Version = static_cast<int>(Spelling->getValueAsInt("Version"));
+          if (Scope.empty() && Version == 1)
+            PrintError(Spelling->getLoc(), "Standard attributes must have "
+                                           "valid version information.");
+          break;
+        }
       }
     }
 


        


More information about the cfe-commits mailing list