diff options
-rw-r--r-- | clang/docs/LibASTMatchersReference.html | 14 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 28 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 9 |
4 files changed, 52 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 454f60d44f2..df21be72611 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2236,6 +2236,20 @@ namespaceDecl(isInline()) will match n::m. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isNoThrow0')"><a name="isNoThrow0Anchor">isNoThrow</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isNoThrow0"><pre>Matches functions that have a non-throwing exception specification. + +Given: + void f(); + void g() noexcept; + void h() throw(); + void i() throw(int); + void j() noexcept(false); +functionDecl(isNoThrow()) + matches the declarations of g, and h, but not f, i or j. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isTemplateInstantiation0')"><a name="isTemplateInstantiation0Anchor">isTemplateInstantiation</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isTemplateInstantiation0"><pre>Matches template instantiations of function, class, or static member variable template instantiations. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 18a1bf040b9..6a5f5ee57c5 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2942,6 +2942,34 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } +/// \brief Matches functions that have a non-throwing exception specification. +/// +/// Given: +/// \code +/// void f(); +/// void g() noexcept; +/// void h() throw(); +/// void i() throw(int); +/// void j() noexcept(false); +/// \endcode +/// functionDecl(isNoThrow()) +/// matches the declarations of g, and h, but not f, i or j. +AST_MATCHER(FunctionDecl, isNoThrow) { + const auto *FnTy = Node.getType()->getAs<FunctionProtoType>(); + + // If the function does not have a prototype, then it is assumed to be a + // throwing function (as it would if the function did not have any exception + // specification). + if (!FnTy) + return false; + + // Assume the best for any unresolved exception specification. + if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) + return true; + + return FnTy->isNothrow(Node.getASTContext()); +} + /// \brief Matches constexpr variable and function declarations. /// /// Given: diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 8b0f033260e..762be25e914 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -288,6 +288,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isListInitialization); REGISTER_MATCHER(isMemberInitializer); REGISTER_MATCHER(isMoveConstructor); + REGISTER_MATCHER(isNoThrow); REGISTER_MATCHER(isOverride); REGISTER_MATCHER(isPrivate); REGISTER_MATCHER(isProtected); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 51233e91303..9aefb078091 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1716,6 +1716,15 @@ TEST(IsDeleted, MatchesDeletedFunctionDeclarations) { functionDecl(hasName("Func"), isDeleted()))); } +TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) { + EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow()))); + EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow()))); + EXPECT_TRUE( + notMatches("void f() noexcept(false);", functionDecl(isNoThrow()))); + EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow()))); + EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow()))); +} + TEST(isConstexpr, MatchesConstexprDeclarations) { EXPECT_TRUE(matches("constexpr int foo = 42;", varDecl(hasName("foo"), isConstexpr()))); |