From 75e52725e44d2eb0be569e67da37ab49fd1bf792 Mon Sep 17 00:00:00 2001 From: Etienne Bergeron Date: Fri, 13 May 2016 19:36:55 +0000 Subject: Add an AST matcher for CastExpr kind Summary: This AST matcher will match a given CastExpr kind. It's an narrowing matcher on CastExpr. Reviewers: klimek, alexfh, sbenza, aaron.ballman Subscribers: Prazek, jroelofs, aaron.ballman, klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D19871 llvm-svn: 269460 --- clang/docs/LibASTMatchersReference.html | 9 +++++++++ clang/include/clang/ASTMatchers/ASTMatchers.h | 11 +++++++++++ clang/lib/ASTMatchers/Dynamic/Marshallers.h | 22 ++++++++++++++++++++++ clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 9 +++++++++ 5 files changed, 52 insertions(+) (limited to 'clang') diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 2d4b8c19997..c0b1253ba9e 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2159,6 +2159,15 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) +Matcher<CastExpr>hasCastKindCastKind Kind +
Matches casts that has a given cast kind.
+
+Example: matches the implicit cast around 0
+(matcher = castExpr(hasCastKind(CK_NullToPointer)))
+  int *p = 0;
+
+ + Matcher<CharacterLiteral>equalsValueT Value
Matches literals that are equal to the given value.
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 74206b9a5c5..26ac4fd9e75 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -3551,6 +3551,17 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
           InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index f28abb06f90..7b1a3070263 100644
--- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,28 @@ public:
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+    return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
+#include "clang/AST/OperationKinds.def"
+        .Default(CK_Invalid);
+  }
+
+public:
+  static bool is(const VariantValue &Value) {
+    return Value.isString() &&  
+        getCastKind(Value.getString()) != CK_Invalid;
+  }
+  static clang::CastKind get(const VariantValue &Value) {
+    return getCastKind(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
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index e43960241d7..ee271e40538 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -210,6 +210,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 34eca9977a9..0db16d692f0 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3485,6 +3485,15 @@ TEST(CastExpression, DoesNotMatchNonCasts) {
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+              castExpr(hasCastKind(CK_NullToPointer))));
+  EXPECT_TRUE(notMatches("char *p = 0;",
+              castExpr(hasCastKind(CK_DerivedToBase))));
+  EXPECT_TRUE(matches("char *p = 0;",
+              implicitCastExpr(hasCastKind(CK_NullToPointer))));
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
                       cxxReinterpretCastExpr()));
-- 
cgit v1.2.3