]> granicus.if.org Git - clang/commitdiff
Make isNoThrow and hasDynamicExceptionSpec polymorphic so they can be used with both...
authorAaron Ballman <aaron@aaronballman.com>
Tue, 7 Jun 2016 17:34:45 +0000 (17:34 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Tue, 7 Jun 2016 17:34:45 +0000 (17:34 +0000)
Patch by Don Hinton.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272028 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
include/clang/ASTMatchers/ASTMatchersInternal.h
unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

index b944fc6b7e9280fc4fecfd14a6f74d6cd1f7fc9f..3606367d2fde457f6e9bf9e0e96100741ad2331b 100644 (file)
@@ -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.
index 1f704098261e95de497921453467e54a5a6fee04..c7e7bc5df01a32b65ca4c0101cccc3c39f2c7e3a 100644 (file)
@@ -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.
index 86c8e6cfec7e5c75775e56a95552acad8f314518..c2c01fbd78ea3128371521aad14de338aef77b72 100644 (file)
@@ -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:
index dc266076d3cbab1be175529ca1de127b7dbd56b3..e304d0629cb3abffc79fd2e2a519a72a0ff804e7 100644 (file)
@@ -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) {