etienneb updated this revision to Diff 56022.
etienneb added a comment.
add dynamic parsing
http://reviews.llvm.org/D19871
Files:
docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Marshallers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
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))));
+}
+
TEST(ReinterpretCast, MatchesSimpleCase) {
EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -209,6 +209,7 @@
REGISTER_MATCHER(hasBody);
REGISTER_MATCHER(hasCanonicalType);
REGISTER_MATCHER(hasCaseConstant);
+ REGISTER_MATCHER(hasCastKind);
REGISTER_MATCHER(hasCondition);
REGISTER_MATCHER(hasConditionVariableStatement);
REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===================================================================
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -95,6 +95,85 @@
return ArgKind(ArgKind::AK_String);
}
};
+///////////////////////////////////////////////////
+template <> struct ArgTypeTraits<clang::CastKind> {
+private:
+ static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+ return llvm::StringSwitch<clang::CastKind>(AttrKind)
+ .Case("CK_Dependent", CK_Dependent)
+ .Case("CK_BitCast", CK_BitCast)
+ .Case("CK_LValueBitCast", CK_LValueBitCast)
+ .Case("CK_LValueToRValue", CK_LValueToRValue)
+ .Case("CK_NoOp", CK_NoOp)
+ .Case("CK_BaseToDerived", CK_BaseToDerived)
+ .Case("CK_DerivedToBase", CK_DerivedToBase)
+ .Case("CK_UncheckedDerivedToBase", CK_UncheckedDerivedToBase)
+ .Case("CK_Dynamic", CK_Dynamic)
+ .Case("CK_ToUnion", CK_ToUnion)
+ .Case("CK_ArrayToPointerDecay", CK_ArrayToPointerDecay)
+ .Case("CK_FunctionToPointerDecay", CK_FunctionToPointerDecay)
+ .Case("CK_NullToMemberPointer", CK_NullToMemberPointer)
+ .Case("CK_NullToPointer", CK_NullToPointer)
+ .Case("CK_BaseToDerivedMemberPointer", CK_BaseToDerivedMemberPointer)
+ .Case("CK_DerivedToBaseMemberPointer", CK_DerivedToBaseMemberPointer)
+ .Case("CK_ReinterpretMemberPointer", CK_ReinterpretMemberPointer)
+ .Case("CK_UserDefinedConversion", CK_UserDefinedConversion)
+ .Case("CK_ConstructorConversion", CK_ConstructorConversion)
+ .Case("CK_IntegralToPointer", CK_IntegralToPointer)
+ .Case("CK_PointerToIntegral", CK_PointerToIntegral)
+ .Case("CK_PointerToBoolean", CK_PointerToBoolean)
+ .Case("CK_ToVoid", CK_ToVoid)
+ .Case("CK_VectorSplat", CK_VectorSplat)
+ .Case("CK_IntegralCast", CK_IntegralCast)
+ .Case("CK_BooleanToSignedIntegral", CK_BooleanToSignedIntegral)
+ .Case("CK_IntegralToBoolean", CK_IntegralToBoolean)
+ .Case("CK_IntegralToFloating", CK_IntegralToFloating)
+ .Case("CK_FloatingToIntegral", CK_FloatingToIntegral)
+ .Case("CK_FloatingCast", CK_FloatingCast)
+ .Case("CK_FloatingToBoolean", CK_FloatingToBoolean)
+ .Case("CK_MemberPointerToBoolean", CK_MemberPointerToBoolean)
+ .Case("CK_CPointerToObjCPointerCast", CK_CPointerToObjCPointerCast)
+ .Case("CK_BlockPointerToObjCPointerCast",
+ CK_BlockPointerToObjCPointerCast)
+ .Case("CK_AnyPointerToBlockPointerCast", CK_AnyPointerToBlockPointerCast)
+ .Case("CK_ObjCObjectLValueCast", CK_ObjCObjectLValueCast)
+ .Case("CK_FloatingRealToComplex", CK_FloatingRealToComplex)
+ .Case("CK_FloatingComplexToReal", CK_FloatingComplexToReal)
+ .Case("CK_FloatingComplexToBoolean", CK_FloatingComplexToBoolean)
+ .Case("CK_FloatingComplexCast", CK_FloatingComplexCast)
+ .Case("CK_FloatingComplexToIntegralComplex",
+ CK_FloatingComplexToIntegralComplex)
+ .Case("CK_IntegralRealToComplex", CK_IntegralRealToComplex)
+ .Case("CK_IntegralComplexToReal", CK_IntegralComplexToReal)
+ .Case("CK_IntegralComplexToBoolean", CK_IntegralComplexToBoolean)
+ .Case("CK_IntegralComplexCast", CK_IntegralComplexCast)
+ .Case("CK_IntegralComplexToFloatingComplex",
+ CK_IntegralComplexToFloatingComplex)
+ .Case("CK_ARCConsumeObject", CK_ARCConsumeObject)
+ .Case("CK_ARCProduceObject", CK_ARCProduceObject)
+ .Case("CK_ARCReclaimReturnedObject", CK_ARCReclaimReturnedObject)
+ .Case("CK_ARCExtendBlockObject", CK_ARCExtendBlockObject)
+ .Case("CK_AtomicToNonAtomic", CK_AtomicToNonAtomic)
+ .Case("CK_NonAtomicToAtomic", CK_NonAtomicToAtomic)
+ .Case("CK_CopyAndAutoreleaseBlockObject",
+ CK_CopyAndAutoreleaseBlockObject)
+ .Case("CK_BuiltinFnToFnPtr", CK_BuiltinFnToFnPtr)
+ .Case("CK_ZeroToOCLEvent", CK_ZeroToOCLEvent)
+ .Case("CK_AddressSpaceConversion", CK_AddressSpaceConversion)
+ .Default(clang::CastKind(-1));
+ }
+public:
+ static bool is(const VariantValue &Value) {
+ return Value.isString() &&
+ getCastKind(Value.getString()) != clang::CastKind(-1);
+ }
+ static clang::CastKind get(const VariantValue &Value) {
+ return getCastKind(Value.getString());
+ }
+ static ArgKind getKind() {
+ return ArgKind(ArgKind::AK_String);
+ }
+};
/// \brief Matcher descriptor interface.
///
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
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: docs/LibASTMatchersReference.html
===================================================================
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -410,7 +410,7 @@
Given
typedef int X;
- using Y = int;
+ using Y = int;
typeAliasDecl()
matches "using Y = int", but not "typedef int X"
</pre></td></tr>
@@ -421,7 +421,7 @@
Given
typedef int X;
- using Y = int;
+ using Y = int;
typedefDecl()
matches "typedef int X", but not "using Y = int"
</pre></td></tr>
@@ -432,7 +432,7 @@
Given
typedef int X;
- using Y = int;
+ using Y = int;
typedefNameDecl()
matches "typedef int X" and "using Y = int"
</pre></td></tr>
@@ -2156,6 +2156,15 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits