wanders created this revision. wanders added a reviewer: aaron.ballman. Herald added a subscriber: jdoerfert. Herald added a project: All. wanders requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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. Depends on D144404 <https://reviews.llvm.org/D144404> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D144405 Files: clang/examples/Attribute/Attribute.cpp clang/lib/Basic/Attributes.cpp clang/test/Frontend/plugin-attribute-pp.cpp Index: clang/test/Frontend/plugin-attribute-pp.cpp =================================================================== --- /dev/null +++ clang/test/Frontend/plugin-attribute-pp.cpp @@ -0,0 +1,36 @@ +// RUN: split-file %s %t +// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %t/has_attr.cpp | FileCheck %t/has_attr.cpp +// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %t/has_attr.c | FileCheck %t/has_attr.c +// REQUIRES: plugins, examples + + +//--- has_attr.cpp +#if __has_attribute (example) +// CHECK: YES - It did exist +YES - It did exist +#endif +#if __has_cpp_attribute (example) +// CHECK: YES - It did cpp-exist +YES - It did cpp-exist +#endif + +#if __has_attribute (doesnt_exist) +// CHECK-NOT: NO - There is no such attribute +NO - There is no such attribute +#endif + + +//--- has_attr.c +#if __has_attribute (example) +// CHECK: YES - It did exist +YES - It did exist +#endif +#if __has_c_attribute (example) +// CHECK: YES - It did c-exist +YES - It did c-exist +#endif + +#if __has_attribute (doesnt_exist) +// CHECK-NOT: NO - There is no such attribute +NO - There is no such attribute +#endif Index: clang/lib/Basic/Attributes.cpp =================================================================== --- clang/lib/Basic/Attributes.cpp +++ 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,13 @@ if (res) return res; + // Check if any plugin provides this attribute. + for (auto &AttrPlugin : getAttributePluginInstances()) { + for (auto &S : AttrPlugin->Spellings) + if (S.Syntax == Syntax && S.NormalizedFullName == Name) + return 1; + } + return 0; } Index: clang/examples/Attribute/Attribute.cpp =================================================================== --- clang/examples/Attribute/Attribute.cpp +++ 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 @@ // 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;
Index: clang/test/Frontend/plugin-attribute-pp.cpp =================================================================== --- /dev/null +++ clang/test/Frontend/plugin-attribute-pp.cpp @@ -0,0 +1,36 @@ +// RUN: split-file %s %t +// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %t/has_attr.cpp | FileCheck %t/has_attr.cpp +// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -E %t/has_attr.c | FileCheck %t/has_attr.c +// REQUIRES: plugins, examples + + +//--- has_attr.cpp +#if __has_attribute (example) +// CHECK: YES - It did exist +YES - It did exist +#endif +#if __has_cpp_attribute (example) +// CHECK: YES - It did cpp-exist +YES - It did cpp-exist +#endif + +#if __has_attribute (doesnt_exist) +// CHECK-NOT: NO - There is no such attribute +NO - There is no such attribute +#endif + + +//--- has_attr.c +#if __has_attribute (example) +// CHECK: YES - It did exist +YES - It did exist +#endif +#if __has_c_attribute (example) +// CHECK: YES - It did c-exist +YES - It did c-exist +#endif + +#if __has_attribute (doesnt_exist) +// CHECK-NOT: NO - There is no such attribute +NO - There is no such attribute +#endif Index: clang/lib/Basic/Attributes.cpp =================================================================== --- clang/lib/Basic/Attributes.cpp +++ 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,13 @@ if (res) return res; + // Check if any plugin provides this attribute. + for (auto &AttrPlugin : getAttributePluginInstances()) { + for (auto &S : AttrPlugin->Spellings) + if (S.Syntax == Syntax && S.NormalizedFullName == Name) + return 1; + } + return 0; } Index: clang/examples/Attribute/Attribute.cpp =================================================================== --- clang/examples/Attribute/Attribute.cpp +++ 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 @@ // 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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits