From a8245d8fe2d5228413d2e5ae23e4a036e0072c70 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aaron@aaronballman.com> 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 74bbf9e4733..a555bb339fc 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1434,6 +1434,16 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Charac Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>> </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></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 diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 94c77f7f73b..e7a97a7ff74 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 59c204d370a..72713dda03c 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 ae363e974b5..1fc7979bd07 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) { -- GitLab