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
-----------------------------------
// 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"
// 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;
#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,
if (res)
return res;
+ // Check if any plugin provides this attribute.
+ for (auto &Ptr : getAttributePluginInstances())
+ if (Ptr->hasSpelling(Syntax, Name))
+ return 1;
+
return 0;
}
--- /dev/null
+// 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