Removed specialized attribute matchers in favor of retaining generic one.

http://reviews.llvm.org/D4996

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp
Index: docs/LibASTMatchersReference.html
===================================================================
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -1612,33 +1612,16 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaDeviceAttr0')"><a name="hasCudaDeviceAttr0Anchor">hasCudaDeviceAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaDeviceAttr0"><pre>Matches declaration that has CUDA device attribute.
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td class="name" onclick="toggle('hasAttr0')"><a name="hasAttr0Anchor">hasAttr</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasAttr0"><pre>Matches declaration that has a given attribute.
 
 Given
   __attribute__((device)) void f() { ... }
-matches the function declaration of f.
+decl(hasAttr&lt;clang::CUDADeviceAttr&gt;()) matches the function declaration of
+f.
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaGlobalAttr0')"><a name="hasCudaGlobalAttr0Anchor">hasCudaGlobalAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaGlobalAttr0"><pre>Matches declaration that has CUDA global attribute.
-
-Given
-  __attribute__((global)) void f() { ... }
-matches the function declaration of f.
-</pre></td></tr>
-
-
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaHostAttr0')"><a name="hasCudaHostAttr0Anchor">hasCudaHostAttr</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="hasCudaHostAttr0"><pre>Matches declaration that has CUDA host attribute.
-
-Given
-  __attribute__((host)) void f() { ... }
-matches the function declaration of f.
-</pre></td></tr>
-
-
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added
 by the compiler (eg. implicit defaultcopy constructors).
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3658,48 +3658,28 @@
   return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
 }
 
-/// \brief Matches CUDA kernel call expression.
+/// \brief Matches declaration that has a given attribute.
 ///
-/// Example matches,
-/// \code
-///   kernel<<<i,j>>>();
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
-    CUDAKernelCallExpr;
-
-/// \brief Matches declaration that has CUDA device attribute.
-///
 /// Given
 /// \code
 ///   __attribute__((device)) void f() { ... }
 /// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaDeviceAttr) {
-  return Node.hasAttr<clang::CUDADeviceAttr>();
+/// decl(hasAttr<clang::CUDADeviceAttr>()) matches the function declaration of
+/// f.
+template <typename Attr>
+inline internal::Matcher<Decl> hasAttr() {
+  return internal::HasAttrMatcher<Decl, Attr>();
 }
 
-/// \brief Matches declaration that has CUDA host attribute.
+/// \brief Matches CUDA kernel call expression.
 ///
-/// Given
+/// Example matches,
 /// \code
-///   __attribute__((host)) void f() { ... }
+///   kernel<<<i,j>>>();
 /// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaHostAttr) {
-  return Node.hasAttr<clang::CUDAHostAttr>();
-}
+const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+    CUDAKernelCallExpr;
 
-/// \brief  Matches declaration that has CUDA global attribute.
-///
-/// Given
-/// \code
-///   __attribute__((global)) void f() { ... }
-/// \endcode
-/// matches the function declaration of f.
-AST_MATCHER(Decl, hasCudaGlobalAttr) {
-  return Node.hasAttr<clang::CUDAGlobalAttr>();
-}
-
 } // end namespace ast_matchers
 } // end namespace clang
 
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1658,6 +1658,28 @@
   ast_type_traits::DynTypedNode Node;
 };
 
+/// \brief Matches declarations have an attribute of type \c Attr
+template <typename T, typename Attr,
+          typename ReturnTypesF = void(internal::TypeList<Decl>)>
+class HasAttrMatcher : public SingleNodeMatcherInterface<T> {
+  static_assert(std::is_same<T, Decl>::value,
+                "unsupported class for matcher");
+public:
+  typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+  operator Matcher<T>() const {
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
+    return Matcher<T>(new HasAttrMatcher<T, Attr, ReturnTypesF>());
+  }
+  bool matchesNode(const T &Node) const override {
+    return matchesSpecialized(Node);
+  }
+private:
+  bool matchesSpecialized(const Decl &Node) const {
+    return Node.hasAttr<Attr>();
+  }
+};
+
 } // end namespace internal
 } // end namespace ast_matchers
 } // end namespace clang
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -78,6 +78,7 @@
   //
   // Polymorphic + argument overload:
   // findAll
+  // hasAttr
   //
   // Other:
   // equals
@@ -182,9 +183,6 @@
   REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
-  REGISTER_MATCHER(hasCudaDeviceAttr);
-  REGISTER_MATCHER(hasCudaGlobalAttr);
-  REGISTER_MATCHER(hasCudaHostAttr);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeducedType);
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -649,22 +649,23 @@
   EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
 }
 
+TEST(DeclarationMatcher, HasAttr) {
+  EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
+                      decl(hasAttr<WarnUnusedAttr>())));
+  EXPECT_FALSE(matches("struct X {};",
+                       decl(hasAttr<WarnUnusedAttr>())));
+}
+
 TEST(DeclarationMatcher, MatchCudaDecl) {
   EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
                               "void g() { f<<<1, 2>>>(); }",
                               CUDAKernelCallExpr()));
   EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
-                              hasCudaDeviceAttr()));
-  EXPECT_TRUE(matchesWithCuda("__attribute__((host)) void f() {}",
-                              hasCudaHostAttr()));
-  EXPECT_TRUE(matchesWithCuda("__attribute__((global)) void f() {}",
-                              hasCudaGlobalAttr()));
-  EXPECT_FALSE(matchesWithCuda("void f() {}",
-                               hasCudaGlobalAttr()));
+                              hasAttr<CUDADeviceAttr>()));
   EXPECT_TRUE(notMatchesWithCuda("void f() {}",
-                                 hasCudaGlobalAttr()));
+                                 CUDAKernelCallExpr()));
   EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
-                                  hasCudaGlobalAttr()));
+                                  hasAttr<CUDAGlobalAttr>()));
 }
 
 // Implements a run method that returns whether BoundNodes contains a
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to