r216379 - Add hasAttr matcher for declarations.
Manuel Klimek
klimek at google.com
Mon Aug 25 04:23:51 PDT 2014
Author: klimek
Date: Mon Aug 25 06:23:50 2014
New Revision: 216379
URL: http://llvm.org/viewvc/llvm-project?rev=216379&view=rev
Log:
Add hasAttr matcher for declarations.
Delete special-case CUDA attribute matchers.
Patch by Jacques Pienaar.
Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Mon Aug 25 06:23:50 2014
@@ -1612,30 +1612,13 @@ and reference to that variable declarati
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('hasCudaDeviceAttr0')"><a name="hasCudaDeviceAttr0Anchor">hasCudaDeviceAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaDeviceAttr0"><pre>Matches declaration that has CUDA device attribute.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('hasAttr0')"><a name="hasAttr0Anchor">hasAttr</a></td><td>attr::Kind AttrKind</td></tr>
+<tr><td colspan="4" class="doc" id="hasAttr0"><pre>Matches declaration that has a given attribute.
Given
__attribute__((device)) void f() { ... }
-matches the function declaration of f.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('hasCudaGlobalAttr0')"><a name="hasCudaGlobalAttr0Anchor">hasCudaGlobalAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaGlobalAttr0"><pre>Matches declaration that has CUDA global attribute.
-
-Given
- __attribute__((global)) void f() { ... }
-matches the function declaration of f.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('hasCudaHostAttr0')"><a name="hasCudaHostAttr0Anchor">hasCudaHostAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaHostAttr0"><pre>Matches declaration that has CUDA host attribute.
-
-Given
- __attribute__((host)) void f() { ... }
-matches the function declaration of f.
+decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
+f.
</pre></td></tr>
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Aug 25 06:23:50 2014
@@ -3658,47 +3658,30 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant,
return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
}
-/// \brief Matches CUDA kernel call expression.
-///
-/// Example matches,
-/// \code
-/// kernel<<<i,j>>>();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
- CUDAKernelCallExpr;
-
-/// \brief Matches declaration that has CUDA device attribute.
+/// \brief Matches declaration that has a given attribute.
///
/// Given
/// \code
/// __attribute__((device)) void f() { ... }
/// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaDeviceAttr) {
- return Node.hasAttr<clang::CUDADeviceAttr>();
-}
-
-/// \brief Matches declaration that has CUDA host attribute.
-///
-/// Given
-/// \code
-/// __attribute__((host)) void f() { ... }
-/// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaHostAttr) {
- return Node.hasAttr<clang::CUDAHostAttr>();
+/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
+/// f.
+AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
+ for (const auto *Attr : Node.attrs()) {
+ if (Attr->getKind() == AttrKind)
+ return true;
+ }
+ return false;
}
-/// \brief Matches declaration that has CUDA global attribute.
+/// \brief Matches CUDA kernel call expression.
///
-/// Given
+/// Example matches,
/// \code
-/// __attribute__((global)) void f() { ... }
+/// kernel<<<i,j>>>();
/// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaGlobalAttr) {
- return Node.hasAttr<clang::CUDAGlobalAttr>();
-}
+const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+ CUDAKernelCallExpr;
} // end namespace ast_matchers
} // end namespace clang
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Mon Aug 25 06:23:50 2014
@@ -76,6 +76,27 @@ template <> struct ArgTypeTraits<unsigne
}
};
+template <> struct ArgTypeTraits<attr::Kind> {
+private:
+ static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
+ return llvm::StringSwitch<attr::Kind>(AttrKind)
+#define ATTR(X) .Case("attr::" #X, attr:: X)
+#include "clang/Basic/AttrList.inc"
+ .Default(attr::Kind(-1));
+ }
+public:
+ static bool is(const VariantValue &Value) {
+ return Value.isString() &&
+ getAttrKind(Value.getString()) != attr::Kind(-1);
+ }
+ static attr::Kind get(const VariantValue &Value) {
+ return getAttrKind(Value.getString());
+ }
+ static ArgKind getKind() {
+ return ArgKind(ArgKind::AK_String);
+ }
+};
+
/// \brief Matcher descriptor interface.
///
/// Provides a \c create() method that constructs the matcher from the provided
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Mon Aug 25 06:23:50 2014
@@ -176,15 +176,13 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasAnyUsingShadowDecl);
REGISTER_MATCHER(hasArgument);
REGISTER_MATCHER(hasArgumentOfType);
+ REGISTER_MATCHER(hasAttr);
REGISTER_MATCHER(hasBase);
REGISTER_MATCHER(hasBody);
REGISTER_MATCHER(hasCanonicalType);
REGISTER_MATCHER(hasCaseConstant);
REGISTER_MATCHER(hasCondition);
REGISTER_MATCHER(hasConditionVariableStatement);
- REGISTER_MATCHER(hasCudaDeviceAttr);
- REGISTER_MATCHER(hasCudaGlobalAttr);
- REGISTER_MATCHER(hasCudaHostAttr);
REGISTER_MATCHER(hasDeclContext);
REGISTER_MATCHER(hasDeclaration);
REGISTER_MATCHER(hasDeducedType);
Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Mon Aug 25 06:23:50 2014
@@ -649,22 +649,23 @@ TEST(DeclarationMatcher, HasDescendantMe
EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
}
+TEST(DeclarationMatcher, HasAttr) {
+ EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
+ decl(hasAttr(clang::attr::WarnUnused))));
+ EXPECT_FALSE(matches("struct X {};",
+ decl(hasAttr(clang::attr::WarnUnused))));
+}
+
TEST(DeclarationMatcher, MatchCudaDecl) {
EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
"void g() { f<<<1, 2>>>(); }",
CUDAKernelCallExpr()));
EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
- hasCudaDeviceAttr()));
- EXPECT_TRUE(matchesWithCuda("__attribute__((host)) void f() {}",
- hasCudaHostAttr()));
- EXPECT_TRUE(matchesWithCuda("__attribute__((global)) void f() {}",
- hasCudaGlobalAttr()));
- EXPECT_FALSE(matchesWithCuda("void f() {}",
- hasCudaGlobalAttr()));
+ hasAttr(clang::attr::CUDADevice)));
EXPECT_TRUE(notMatchesWithCuda("void f() {}",
- hasCudaGlobalAttr()));
+ CUDAKernelCallExpr()));
EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
- hasCudaGlobalAttr()));
+ hasAttr(clang::attr::CUDAGlobal)));
}
// Implements a run method that returns whether BoundNodes contains a
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=216379&r1=216378&r2=216379&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Mon Aug 25 06:23:50 2014
@@ -472,6 +472,14 @@ TEST_F(RegistryTest, Completion) {
"Matcher<NamedDecl> hasName(string)"));
}
+TEST_F(RegistryTest, HasArgs) {
+ Matcher<Decl> Value = constructMatcher(
+ "decl", constructMatcher("hasAttr", std::string("attr::WarnUnused")))
+ .getTypedMatcher<Decl>();
+ EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};", Value));
+ EXPECT_FALSE(matches("struct X {};", Value));
+}
+
} // end anonymous namespace
} // end namespace dynamic
} // end namespace ast_matchers
More information about the cfe-commits
mailing list