From a8245d8fe2d5228413d2e5ae23e4a036e0072c70 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 2 Jul 2015 12:53:22 +0000 Subject: [PATCH] Implement an AST matcher for C++ exception catch handlers that can catch any exception type (...). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241256 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 10 ++++++++++ include/clang/ASTMatchers/ASTMatchers.h | 17 +++++++++++++++++ lib/ASTMatchers/Dynamic/Registry.cpp | 1 + unittests/ASTMatchers/ASTMatchersTest.cpp | 4 ++++ 4 files changed, 32 insertions(+) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 74bbf9e473..a555bb339f 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1434,6 +1434,16 @@ Usable as: Matcher<FloatingLiteral>, Matcher<IntegerLiteral> +Matcher<CXXCatchStmt>isCatchAll +
Matches a C++ catch statement that has a handler that catches any exception type.
+
+Example matches catch(...) (matcher = catchStmt(isCatchAll()))
+  try {
+    // ...
+  } catch(...) {
+  }
+
+ Matcher<CXXConstructExpr>argumentCountIsunsigned N
Checks that a call expression or a constructor call expression has
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 94c77f7f73..e7a97a7ff7 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -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
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 59c204d370..72713dda03 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -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);
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index ae363e974b..1fc7979bd0 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -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) {
-- 
2.50.1