From: Etienne Bergeron Date: Mon, 30 May 2016 15:25:25 +0000 (+0000) Subject: [ASTMatchers] Add support of hasCondition for SwitchStmt. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c33ca9eb5710ee67a91bfde52cf2deaa1e5b512e;p=clang [ASTMatchers] Add support of hasCondition for SwitchStmt. Summary: The switch statement could be added to the hasCondition matcher. Example: ``` clang-query> match switchStmt(hasCondition(ignoringImpCasts(declRefExpr()))) ``` Output: ``` Match #1: Binding for "root": SwitchStmt 0x2f9b528 |-<<>> |-ImplicitCastExpr 0x2f9b510 'int' | `-ImplicitCastExpr 0x2f9b4f8 'enum Color' | `-DeclRefExpr 0x2f9b4d0 'enum Color' lvalue Var 0x2f9a118 'C' 'enum Color' `-CompoundStmt 0x2f9b610 |-CaseStmt 0x2f9b578 | |-ImplicitCastExpr 0x2f9b638 'int' | | `-DeclRefExpr 0x2f9b550 'enum Size' EnumConstant 0x2f99e40 'Small' 'enum Size' | |-<<>> | `-ReturnStmt 0x2f9b5d0 | `-IntegerLiteral 0x2f9b5b0 'int' 1 `-DefaultStmt 0x2f9b5f0 `-BreakStmt 0x2f9b5e8 1 match. ``` Reviewers: aaron.ballman, sbenza, klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D20767 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@271208 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 27e934ccac..433ba7843f 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -3536,9 +3536,9 @@ Usable as: Any Matcher -Matcher<AbstractConditionalOperator>hasConditionMatcher<Expr> InnerMatcher -
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+Matcher<AbstractConditionalOperator>hasConditionMatcher<Expr> InnerMatcher
+
Matches the condition expression of an if statement, for loop,
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
@@ -4293,7 +4293,7 @@ with compoundStmt()
 
 Matcher<DoStmt>hasConditionMatcher<Expr> InnerMatcher
 
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
@@ -4476,7 +4476,7 @@ with compoundStmt()
 
 Matcher<ForStmt>hasConditionMatcher<Expr> InnerMatcher
 
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
@@ -4554,7 +4554,7 @@ cxxMethodDecl(returns(asString("int")))
 
 Matcher<IfStmt>hasConditionMatcher<Expr> InnerMatcher
 
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
@@ -5052,6 +5052,15 @@ switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
 
+Matcher<SwitchStmt>hasConditionMatcher<Expr> InnerMatcher +
Matches the condition expression of an if statement, for loop,
+switch statement or conditional operator.
+
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+  if (true) {}
+
+ + Matcher<TagType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -5385,7 +5394,7 @@ with compoundStmt()
 
 Matcher<WhileStmt>hasConditionMatcher<Expr> InnerMatcher
 
Matches the condition expression of an if statement, for loop,
-or conditional operator.
+switch statement or conditional operator.
 
 Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
   if (true) {}
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 7b1a7e77d5..c445152c7c 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -3299,7 +3299,7 @@ AST_POLYMORPHIC_MATCHER(isConstexpr,
 }
 
 /// \brief Matches the condition expression of an if statement, for loop,
-/// or conditional operator.
+/// switch statement or conditional operator.
 ///
 /// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
 /// \code
@@ -3308,7 +3308,7 @@ AST_POLYMORPHIC_MATCHER(isConstexpr,
 AST_POLYMORPHIC_MATCHER_P(
     hasCondition,
     AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt,
-                                    AbstractConditionalOperator),
+                                    SwitchStmt, AbstractConditionalOperator),
     internal::Matcher, InnerMatcher) {
   const Expr *const Condition = Node.getCond();
   return (Condition != nullptr &&
diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index a2e1dee261..481b7e3041 100644
--- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -958,6 +958,28 @@ TEST(Matcher, VisitsTemplateInstantiations) {
       callee(cxxMethodDecl(hasName("x"))))))));
 }
 
+TEST(Matcher, HasCondition) {
+  StatementMatcher IfStmt =
+    ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
+  EXPECT_TRUE(matches("void x() { if (true) {} }", IfStmt));
+  EXPECT_TRUE(notMatches("void x() { if (false) {} }", IfStmt));
+
+  StatementMatcher ForStmt =
+    forStmt(hasCondition(cxxBoolLiteral(equals(true))));
+  EXPECT_TRUE(matches("void x() { for (;true;) {} }", ForStmt));
+  EXPECT_TRUE(notMatches("void x() { for (;false;) {} }", ForStmt));
+
+  StatementMatcher WhileStmt =
+    whileStmt(hasCondition(cxxBoolLiteral(equals(true))));
+  EXPECT_TRUE(matches("void x() { while (true) {} }", WhileStmt));
+  EXPECT_TRUE(notMatches("void x() { while (false) {} }", WhileStmt));
+
+  StatementMatcher SwitchStmt =
+    switchStmt(hasCondition(integerLiteral(equals(42))));
+  EXPECT_TRUE(matches("void x() { switch (42) {case 42:;} }", SwitchStmt));
+  EXPECT_TRUE(notMatches("void x() { switch (43) {case 43:;} }", SwitchStmt));
+}
+
 TEST(For, ForLoopInternals) {
   EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
                       forStmt(hasCondition(anything()))));