summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LibASTMatchersReference.html40
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h23
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h11
-rw-r--r--unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp21
4 files changed, 82 insertions, 13 deletions
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index b944fc6b7e..3606367d2f 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -2414,8 +2414,9 @@ Given:
void j() throw();
void k() throw(int);
void l() throw(...);
-functionDecl(hasDynamicExceptionSpec())
- matches the declarations of j, k, and l, but not f, g, h, or i.
+functionDecl(hasDynamicExceptionSpec()) and
+ functionProtoType(hasDynamicExceptionSpec())
+ match the declarations of j, k, and l, but not f, g, h, or i.
</pre></td></tr>
@@ -2540,8 +2541,8 @@ Given:
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.
+functionDecl(isNoThrow()) and functionProtoType(isNoThrow())
+ match the declarations of g, and h, but not f, i or j.
</pre></td></tr>
@@ -2597,6 +2598,37 @@ functionProtoType(parameterCountIs(3))
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>&gt;</td><td class="name" onclick="toggle('hasDynamicExceptionSpec1')"><a name="hasDynamicExceptionSpec1Anchor">hasDynamicExceptionSpec</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasDynamicExceptionSpec1"><pre>Matches functions that have a dynamic exception specification.
+
+Given:
+ void f();
+ void g() noexcept;
+ void h() noexcept(true);
+ void i() noexcept(false);
+ void j() throw();
+ void k() throw(int);
+ void l() throw(...);
+functionDecl(hasDynamicExceptionSpec()) and
+ functionProtoType(hasDynamicExceptionSpec())
+ match the declarations of j, k, and l, but not f, g, h, or i.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>&gt;</td><td class="name" onclick="toggle('isNoThrow1')"><a name="isNoThrow1Anchor">isNoThrow</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isNoThrow1"><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()) and functionProtoType(isNoThrow())
+ match the declarations of g, and h, but not f, i or j.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>&gt;</td><td class="name" onclick="toggle('parameterCountIs1')"><a name="parameterCountIs1Anchor">parameterCountIs</a></td><td>unsigned N</td></tr>
<tr><td colspan="4" class="doc" id="parameterCountIs1"><pre>Matches FunctionDecls and FunctionProtoTypes that have a
specific parameter count.
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 1f70409826..c7e7bc5df0 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -3265,10 +3265,13 @@ AST_MATCHER(FunctionDecl, isDefaulted) {
/// void k() throw(int);
/// void l() throw(...);
/// \endcode
-/// functionDecl(hasDynamicExceptionSpec())
-/// matches the declarations of j, k, and l, but not f, g, h, or i.
-AST_MATCHER(FunctionDecl, hasDynamicExceptionSpec) {
- if (const auto *FnTy = Node.getType()->getAs<FunctionProtoType>())
+/// functionDecl(hasDynamicExceptionSpec()) and
+/// functionProtoType(hasDynamicExceptionSpec())
+/// match the declarations of j, k, and l, but not f, g, h, or i.
+AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ FunctionProtoType)) {
+ if (const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node))
return FnTy->hasDynamicExceptionSpec();
return false;
}
@@ -3283,10 +3286,12 @@ AST_MATCHER(FunctionDecl, hasDynamicExceptionSpec) {
/// 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>();
+/// functionDecl(isNoThrow()) and functionProtoType(isNoThrow())
+/// match the declarations of g, and h, but not f, i or j.
+AST_POLYMORPHIC_MATCHER(isNoThrow,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ FunctionProtoType)) {
+ const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node);
// 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
@@ -3298,7 +3303,7 @@ AST_MATCHER(FunctionDecl, isNoThrow) {
if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
return true;
- return FnTy->isNothrow(Node.getASTContext());
+ return FnTy->isNothrow(Finder->getASTContext());
}
/// \brief Matches constexpr variable and function declarations.
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 86c8e6cfec..c2c01fbd78 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -106,6 +106,17 @@ inline QualType getUnderlyingType(const TypedefNameDecl &Node) {
return Node.getUnderlyingType();
}
+/// \brief Unifies obtaining the FunctionProtoType pointer from both
+/// FunctionProtoType and FunctionDecl nodes..
+inline const FunctionProtoType *
+getFunctionProtoType(const FunctionProtoType &Node) {
+ return &Node;
+}
+
+inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) {
+ return Node.getType()->getAs<FunctionProtoType>();
+}
+
/// \brief Internal version of BoundNodes. Holds all the bound nodes.
class BoundNodesMap {
public:
diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index dc266076d3..e304d0629c 100644
--- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -845,6 +845,13 @@ TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
+
+ EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow())));
+ EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow())));
+ EXPECT_TRUE(
+ notMatches("void f() noexcept(false);", functionProtoType(isNoThrow())));
+ EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow())));
+ EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow())));
}
TEST(isConstexpr, MatchesConstexprDeclarations) {
@@ -1396,6 +1403,20 @@ TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) {
matches("void k() throw(int);", functionDecl(hasDynamicExceptionSpec())));
EXPECT_TRUE(
matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec())));
+
+ EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(notMatches("void g() noexcept;",
+ functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(notMatches("void h() noexcept(true);",
+ functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(notMatches("void i() noexcept(false);",
+ functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(
+ matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(
+ matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec())));
+ EXPECT_TRUE(
+ matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec())));
}
TEST(HasObjectExpression, DoesNotMatchMember) {