hintonda updated this revision to Diff 59726. hintonda added a comment. Update narrowing matchers, isNoThrow and hasDynamicExceptionSpec, to work with both functionDecl and functionProtoType matchers. Update tests and regenerate documentation.
Since FunctionDecl and FunctionProtoType are not polymorphically related, an overloaded helper function, getFunctionProtoType(), was added that takes either a FunctionDecl node or FunctionProtoType node and returns a FunctionProtoType pointer. This is based on the getUnderlyingType() implementation. http://reviews.llvm.org/D20687 Files: docs/LibASTMatchersReference.html include/clang/ASTMatchers/ASTMatchers.h include/clang/ASTMatchers/ASTMatchersInternal.h unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Index: unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -845,6 +845,13 @@ 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 @@ 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) { Index: include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- include/clang/ASTMatchers/ASTMatchersInternal.h +++ include/clang/ASTMatchers/ASTMatchersInternal.h @@ -106,6 +106,17 @@ 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: Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -3245,10 +3245,13 @@ /// 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 auto *FnTy = internal::getFunctionProtoType(Node)) return FnTy->hasDynamicExceptionSpec(); return false; } @@ -3263,10 +3266,12 @@ /// 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 auto *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 @@ -3278,7 +3283,7 @@ if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) return true; - return FnTy->isNothrow(Node.getASTContext()); + return FnTy->isNothrow(Finder->getASTContext()); } /// \brief Matches constexpr variable and function declarations. Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -2414,8 +2414,9 @@ 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 @@ 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 @@ </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>></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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits