]> granicus.if.org Git - clang/commitdiff
Implement an AST matcher for C++ exception catch handlers that can catch any exceptio...
authorAaron Ballman <aaron@aaronballman.com>
Thu, 2 Jul 2015 12:53:22 +0000 (12:53 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Thu, 2 Jul 2015 12:53:22 +0000 (12:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241256 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp

index 74bbf9e47334cacb073733616f79b811b6f1ad1c..a555bb339fc176e67b80969dc287372b75889c64 100644 (file)
@@ -1434,6 +1434,16 @@ Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Charac
            Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;
 </pre></td></tr>
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>&gt;</td><td class="name" onclick="toggle('isCatchAll1')"><a name="isCatchAll1Anchor">isCatchAll</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isCatchAll1"><pre>Matches a C++ catch statement that has a handler that catches any exception type.
+
+Example matches catch(...) (matcher = catchStmt(isCatchAll()))
+  try {
+    // ...
+  } catch(...) {
+  }
+</pre></td></tr>
+
 
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;</td><td class="name" onclick="toggle('argumentCountIs1')"><a name="argumentCountIs1Anchor">argumentCountIs</a></td><td>unsigned N</td></tr>
 <tr><td colspan="4" class="doc" id="argumentCountIs1"><pre>Checks that a call expression or a constructor call expression has
index 94c77f7f73ba8b85f36a5fae9b0450b92df102f0..e7a97a7ff7458f5910c15138e32325e262883451 100644 (file)
@@ -2528,6 +2528,23 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
   return InnerMatcher.matches(**Iterator, Finder, Builder);
 }
 
+/// \brief Matches a C++ catch statement that has a catch-all handler.
+///
+/// Given
+/// \code
+///   try {
+///     // ...
+///   } catch (int) {
+///     // ...
+///   } catch (...) {
+///     // ...
+///   }
+/// /endcode
+/// catchStmt(isCatchAll()) matches catch(...) but not catch(int).
+AST_MATCHER(CXXCatchStmt, isCatchAll) {
+  return Node.getExceptionDecl() == nullptr;
+}
+
 /// \brief Matches a constructor initializer.
 ///
 /// Given
index 59c204d370a642b93c09d8ead78e72e491209ec7..72713dda03c77666a625e94093eefa065952518e 100644 (file)
@@ -240,6 +240,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(innerType);
   REGISTER_MATCHER(integerLiteral);
   REGISTER_MATCHER(isArrow);
+  REGISTER_MATCHER(isCatchAll);
   REGISTER_MATCHER(isConst);
   REGISTER_MATCHER(isConstQualified);
   REGISTER_MATCHER(isDefinition);
index ae363e974b5d4c1284cbf64927a44c34e0b6510f..1fc7979bd073269e4aa51ac6a8be93b881764945 100644 (file)
@@ -3321,6 +3321,10 @@ TEST(ExceptionHandling, SimpleCases) {
                       throwExpr()));
   EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
                       throwExpr()));
+  EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
+                      catchStmt(isCatchAll())));
+  EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
+                         catchStmt(isCatchAll())));
 }
 
 TEST(HasConditionVariableStatement, DoesNotMatchCondition) {