Introduces the 'decl' matcher which was missing for a while
and became necessary with the change to require BindableMatchers
for binding.
Also fixes PR 13445: "hasSourceExpression only works for implicit casts".
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160716 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 61571e5..a5348d0 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -130,6 +130,17 @@
return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
}
+/// \brief Matches declarations.
+///
+/// Examples matches \c X, \c C, and the friend declaration inside \c C;
+/// \code
+/// void X();
+/// class C {
+/// friend X;
+/// };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl;
+
/// \brief Matches a declaration of anything that could have a name.
///
/// Example matches X, S, the anonymous union type, i, and U;
@@ -1549,15 +1560,14 @@
InnerMatcher.matches(*Operand, Finder, Builder));
}
-/// \brief Matches if the implicit cast's source expression matches the given
-/// matcher.
+/// \brief Matches if the cast's source expression matches the given matcher.
///
/// Example: matches "a string" (matcher =
/// hasSourceExpression(constructorCall()))
///
/// class URL { URL(string); };
/// URL url = "a string";
-AST_MATCHER_P(ImplicitCastExpr, hasSourceExpression,
+AST_MATCHER_P(CastExpr, hasSourceExpression,
internal::Matcher<Expr>, InnerMatcher) {
const Expr* const SubExpression = Node.getSubExpr();
return (SubExpression != NULL &&
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index f76a596..91095eb 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -39,6 +39,12 @@
}
#endif
+TEST(Decl, MatchesDeclarations) {
+ EXPECT_TRUE(notMatches("", decl(usingDecl())));
+ EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
+ decl(usingDecl())));
+}
+
TEST(NameableDeclaration, MatchesVariousDecls) {
DeclarationMatcher NamedX = nameableDeclaration(hasName("X"));
EXPECT_TRUE(matches("typedef int X;", NamedX));
@@ -2037,13 +2043,20 @@
pointsTo(TypeMatcher(anything())))))));
}
-TEST(HasSourceExpression, MatchesSimpleCase) {
+TEST(HasSourceExpression, MatchesImplicitCasts) {
EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
"void r() {string a_string; URL url = a_string; }",
expression(implicitCast(
hasSourceExpression(constructorCall())))));
}
+TEST(HasSourceExpression, MatchesExplicitCasts) {
+ EXPECT_TRUE(matches("float x = static_cast<float>(42);",
+ expression(explicitCast(
+ hasSourceExpression(hasDescendant(
+ expression(integerLiteral())))))));
+}
+
TEST(Statement, DoesNotMatchDeclarations) {
EXPECT_TRUE(notMatches("class X {};", statement()));
}