]> granicus.if.org Git - clang/commitdiff
Add an AST matcher for CastExpr kind
authorEtienne Bergeron <etienneb@google.com>
Fri, 13 May 2016 19:36:55 +0000 (19:36 +0000)
committerEtienne Bergeron <etienneb@google.com>
Fri, 13 May 2016 19:36:55 +0000 (19:36 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269460 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Marshallers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp

index 2d4b8c199970c2e8cedbbf42a936bdd7267c8e34..c0b1253ba9ef23121b321f132cd66bc30589de87 100644 (file)
@@ -2159,6 +2159,15 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>&gt;</td><td class="name" onclick="toggle('hasCastKind0')"><a name="hasCastKind0Anchor">hasCastKind</a></td><td>CastKind Kind</td></tr>
+<tr><td colspan="4" class="doc" id="hasCastKind0"><pre>Matches casts that has a given cast kind.
+
+Example: matches the implicit cast around 0
+(matcher = castExpr(hasCastKind(CK_NullToPointer)))
+  int *p = 0;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;</td><td class="name" onclick="toggle('equals3')"><a name="equals3Anchor">equals</a></td><td>ValueT  Value</td></tr>
 <tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value.
 
index 74206b9a5c535b014377cb748010236e655aff9c..26ac4fd9e75108d9a3ea553afa6a6f08154e5524 100644 (file)
@@ -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
index f28abb06f90f3be6f20105791b3d6cb6733e986a..7b1a307026334187f5bfa7fe0c47ef65d5cf6ca4 100644 (file)
@@ -96,6 +96,28 @@ public:
   }
 };
 
+template <> struct ArgTypeTraits<clang::CastKind> {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+    return llvm::StringSwitch<clang::CastKind>(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
index e43960241d7883919a79eefe3f0ab35ccfc5bac2..ee271e40538f8def8eb165ddaf3659e444100dfa 100644 (file)
@@ -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);
index 34eca9977a945c42ef0560c2948a81542803d864..0db16d692f0453f4e6d42c62c78b5882baa327a0 100644 (file)
@@ -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<char*>(&p);",
                       cxxReinterpretCastExpr()));