summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-07-19 11:50:54 +0000
committerManuel Klimek <klimek@google.com>2013-07-19 11:50:54 +0000
commitba46fc01a866fb8b6f14d3104227a7bbe5b98d01 (patch)
tree77e4fa0bc639a6f3089c510768ed6bd920533293 /clang
parent6c321c131b7f6698eaa9499b5a37f5ecf36cee44 (diff)
downloadbcm5719-llvm-ba46fc01a866fb8b6f14d3104227a7bbe5b98d01.tar.gz
bcm5719-llvm-ba46fc01a866fb8b6f14d3104227a7bbe5b98d01.zip
Adds ctorInitializer and forEachConstructorInitializer matchers.
llvm-svn: 186668
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h36
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTest.cpp11
2 files changed, 47 insertions, 0 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 18bfe15486d..1414c4ef2f9 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -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.
///
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 8df0274504e..b6d21e69975 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -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) {
OpenPOWER on IntegriCloud