[clang] 1285a49 - [clang][pp] Handle attributes defined by plugin in __has_attribute

Anders Waldenborg via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 13 08:48:36 PDT 2023


Author: Anders Waldenborg
Date: 2023-03-13T16:47:51+01:00
New Revision: 1285a495d5886b99f8d193c90b258a56f89c8937

URL: https://github.com/llvm/llvm-project/commit/1285a495d5886b99f8d193c90b258a56f89c8937
DIFF: https://github.com/llvm/llvm-project/commit/1285a495d5886b99f8d193c90b258a56f89c8937.diff

LOG: [clang][pp] Handle attributes defined by plugin in __has_attribute

When using attributes by plugins (both in clang and clang-tidy) the
preprocessor functions `__has_attribute`, `__has_c_attribute`,
`__has_cpp_attribute` still returned 0.

That problem is fixed by having the "hasAttribute" function also check
if any of the plugins provide that attribute.

This also adds C2x spelling to the example plugin for attributes so that
`__has_c_attribute` can be tested.

Differential Revision: https://reviews.llvm.org/D144405

Added: 
    clang/test/Frontend/plugin-attribute-pp.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/examples/Attribute/Attribute.cpp
    clang/lib/Basic/Attributes.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47fee3ef6b248..440fd04274777 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -147,6 +147,8 @@ Attribute Changes in Clang
   uses the optional USR value when indexing Clang's AST. This value is expected
   to be generated by an external compiler when generating C++ bindings during
   the compilation of the foreign language sources (e.g. Swift).
+- The ``__has_attribute``, ``__has_c_attribute`` and ``__has_cpp_attribute``
+  preprocessor operators now return 1 also for attributes defined by plugins.
 
 Improvements to Clang's diagnostics
 -----------------------------------

diff  --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp
index 159b09e4b154d..24b95dde4e559 100644
--- a/clang/examples/Attribute/Attribute.cpp
+++ b/clang/examples/Attribute/Attribute.cpp
@@ -9,6 +9,8 @@
 // Example clang plugin which adds an an annotation to file-scope declarations
 // with the 'example' attribute.
 //
+// This plugin is used by clang/test/Frontend/plugin-attribute tests.
+//
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
@@ -27,9 +29,10 @@ struct ExampleAttrInfo : public ParsedAttrInfo {
     // number of arguments. This just illustrates how many arguments a
     // `ParsedAttrInfo` can hold, we will not use that much in this example.
     OptArgs = 15;
-    // GNU-style __attribute__(("example")) and C++-style [[example]] and
+    // GNU-style __attribute__(("example")) and C++/C2x-style [[example]] and
     // [[plugin::example]] supported.
     static constexpr Spelling S[] = {{ParsedAttr::AS_GNU, "example"},
+                                     {ParsedAttr::AS_C2x, "example"},
                                      {ParsedAttr::AS_CXX11, "example"},
                                      {ParsedAttr::AS_CXX11, "plugin::example"}};
     Spellings = S;

diff  --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 5c168ec67da11..da339d5b1bab6 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -2,6 +2,7 @@
 #include "clang/Basic/AttrSubjectMatchRules.h"
 #include "clang/Basic/AttributeCommonInfo.h"
 #include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/ParsedAttrInfo.h"
 using namespace clang;
 
 static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
@@ -40,6 +41,11 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
   if (res)
     return res;
 
+  // Check if any plugin provides this attribute.
+  for (auto &Ptr : getAttributePluginInstances())
+    if (Ptr->hasSpelling(Syntax, Name))
+      return 1;
+
   return 0;
 }
 

diff  --git a/clang/test/Frontend/plugin-attribute-pp.cpp b/clang/test/Frontend/plugin-attribute-pp.cpp
new file mode 100644
index 0000000000000..94ba14e272eef
--- /dev/null
+++ b/clang/test/Frontend/plugin-attribute-pp.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %s | FileCheck %s
+// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %s -x c | FileCheck %s
+// REQUIRES: plugins, examples
+
+#ifdef __cplusplus
+# define HAS_ATTR(a) __has_cpp_attribute (a)
+#else
+# define HAS_ATTR(a) __has_c_attribute (a)
+#endif
+
+#if __has_attribute(example)
+// CHECK: has_attribute(example) was true
+has_attribute(example) was true
+#endif
+#if HAS_ATTR(example)
+// CHECK: has_$LANG_attribute(example) was true
+has_$LANG_attribute(example) was true
+#endif
+
+#if __has_attribute(doesnt_exist)
+// CHECK-NOT: has_attribute(doesnt_exist) unexpectedly was true
+has_attribute(doesnt_exist) unexpectedly was true
+#endif
+
+#if HAS_ATTR(doesnt_exist)
+// CHECK-NOT: has_$LANG_attribute(doesnt_exist) unexpectedly was true
+has_$LANG_attribute(doesnt_exist) unexpectedly was true
+#endif


        


More information about the cfe-commits mailing list