Adds ctorInitializer and forEachConstructorInitializer matchers.

llvm-svn: 186668
This commit is contained in:
Manuel Klimek 2013-07-19 11:50:54 +00:00
parent 6c321c131b
commit ba46fc01a8
2 changed files with 47 additions and 0 deletions

View File

@ -241,6 +241,17 @@ const internal::VariadicDynCastAllOfMatcher<
Decl,
AccessSpecDecl> accessSpecDecl;
/// \brief Matches constructor initializers.
///
/// Examples matches \c i(42).
/// \code
/// class C {
/// C() : i(42) {}
/// int i;
/// };
/// \endcode
const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer;
/// \brief Matches public C++ declarations.
///
/// Given
@ -3494,6 +3505,31 @@ AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
return Matched;
}
/// \brief Matches each constructor initializer in a constructor definition.
///
/// Given
/// \code
/// class A { A() : i(42), j(42) {} int i; int j; };
/// \endcode
/// constructorDecl(forEachConstructorInitializer(forField(decl().bind("x"))))
/// will trigger two matches, binding for 'i' and 'j' respectively.
AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
BoundNodesTreeBuilder Result;
bool Matched = false;
for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(),
E = Node.init_end();
I != E; ++I) {
BoundNodesTreeBuilder InitBuilder(*Builder);
if (InnerMatcher.matches(**I, Finder, &InitBuilder)) {
Matched = true;
Result.addMatch(InitBuilder);
}
}
*Builder = Result;
return Matched;
}
/// \brief If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///

View File

@ -2967,6 +2967,12 @@ TEST(SwitchCase, MatchesEachCase) {
new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
}
TEST(ForEachConstructorInitializer, MatchesInitializers) {
EXPECT_TRUE(matches(
"struct X { X() : i(42), j(42) {} int i, j; };",
constructorDecl(forEachConstructorInitializer(ctorInitializer()))));
}
TEST(ExceptionHandling, SimpleCases) {
EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", catchStmt()));
EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", tryStmt()));
@ -3157,6 +3163,11 @@ TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
"class A {};",
recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
new VerifyIdIsBoundTo<Decl>("x", 1)));
EXPECT_TRUE(matchAndVerifyResultTrue(
"class A { A() : s(), i(42) {} const char *s; int i; };",
constructorDecl(hasName("::A::A"), decl().bind("x"),
forEachConstructorInitializer(forField(hasName("i")))),
new VerifyIdIsBoundTo<Decl>("x", 1)));
}
TEST(ForEachDescendant, BindsCorrectNodes) {