From 909b5c94c072516d980013073be9ca2cd8993f67 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 27 May 2014 10:04:12 +0000 Subject: [PATCH] Adds child traversal matchers for IfStmt's then and else branches. llvm-svn: 209649 --- clang/docs/LibASTMatchersReference.html | 18 ++++++++++++++++++ clang/include/clang/ASTMatchers/ASTMatchers.h | 24 ++++++++++++++++++++++++ clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 11 +++++++++++ 3 files changed, 53 insertions(+) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 3b862cd..90351e0 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -3100,6 +3100,24 @@ hasConditionVariableStatement(...) +Matcher<IfStmt>hasElseMatcher<Stmt> InnerMatcher +
Matches the else-statement of an if statement.
+
+Examples matches the if statement
+  (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+  if (false) false; else true;
+
+ + +Matcher<IfStmt>hasThenMatcher<Stmt> InnerMatcher +
Matches the then-statement of an if statement.
+
+Examples matches the if statement
+  (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+  if (false) true; else false;
+
+ + Matcher<ImplicitCastExpr>hasImplicitDestinationTypeMatcher<QualType> InnerMatcher
Matches implicit casts whose destination type matches a given
 matcher.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 30f0264..3636def 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2334,6 +2334,30 @@ AST_POLYMORPHIC_MATCHER_P(
           InnerMatcher.matches(*Condition, Finder, Builder));
 }
 
+/// \brief Matches the then-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+/// \code
+///   if (false) true; else false;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasThen, internal::Matcher, InnerMatcher) {
+  const Stmt *const Then = Node.getThen();
+  return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
+}
+
+/// \brief Matches the else-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+/// \code
+///   if (false) false; else true;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasElse, internal::Matcher, InnerMatcher) {
+  const Stmt *const Else = Node.getElse();
+  return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
+}
+
 /// \brief Matches if a node equals a previously bound node.
 ///
 /// Matches a node if it equals the node previously bound to \p ID.
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 4ce56fd..9d9b2a1 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1966,6 +1966,17 @@ TEST(Matcher, Conditions) {
   EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
 }
 
+TEST(IfStmt, ChildTraversalMatchers) {
+  EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
+                      ifStmt(hasThen(boolLiteral(equals(true))))));
+  EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
+                         ifStmt(hasThen(boolLiteral(equals(true))))));
+  EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
+                      ifStmt(hasElse(boolLiteral(equals(true))))));
+  EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
+                         ifStmt(hasElse(boolLiteral(equals(true))))));
+}
+
 TEST(MatchBinaryOperator, HasOperatorName) {
   StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
 
-- 
2.7.4