r176019 - Support in hasDeclaration for types with getDecl()

Edwin Vane edwin.vane at intel.com
Mon Feb 25 05:59:06 PST 2013


Author: revane
Date: Mon Feb 25 07:59:06 2013
New Revision: 176019

URL: http://llvm.org/viewvc/llvm-project?rev=176019&view=rev
Log:
Support in hasDeclaration for types with getDecl()

Re-introducing r175532. The has_getDecl metafunction didn't compile with Visual
Studio. This revision approaches has_getDecl from a different angle that isn't
a problem for Visual Studio.

Added dedicated tests for the metafunction.

Reviewers: klimek

Modified:
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=176019&r1=176018&r2=176019&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Feb 25 07:59:06 2013
@@ -353,6 +353,23 @@ inline Matcher<T> makeMatcher(MatcherInt
   return Matcher<T>(Implementation);
 }
 
+/// \brief Metafunction to determine if type T has a member called getDecl.
+template <typename T> struct has_getDecl {
+  struct Default { int getDecl; };
+  struct Derived : T, Default { };
+
+  template<typename C, C> struct CheckT;
+
+  // If T::getDecl exists, an ambiguity arises and CheckT will
+  // not be instantiable. This makes f(...) the only available
+  // overload.
+  template<typename C>
+  static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
+  template<typename C> static char (&f(...))[2];
+
+  static bool const value = sizeof(f<Derived>(0)) == 2;
+};
+
 /// \brief Matches declarations for QualType and CallExpr.
 ///
 /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
@@ -376,11 +393,13 @@ private:
   /// \brief If getDecl exists as a member of U, returns whether the inner
   /// matcher matches Node.getDecl().
   template <typename U>
-  bool matchesSpecialized(const U &Node, ASTMatchFinder *Finder, 
-                          BoundNodesTreeBuilder *Builder) const {
+  bool matchesSpecialized(
+      const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+      typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
     return matchesDecl(Node.getDecl(), Finder, Builder);
   }
 
+
   /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns
   /// whether the inner matcher matches on it.
   bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
@@ -393,6 +412,15 @@ private:
     return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
   }
 
+  /// \brief Gets the TemplateDecl from a TemplateSpecializationType
+  /// and returns whether the inner matches on it.
+  bool matchesSpecialized(const TemplateSpecializationType &Node,
+                          ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
+                       Finder, Buidler);
+  }
+
   /// \brief Extracts the Decl of the callee of a CallExpr and returns whether
   /// the inner matcher matches on it.
   bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=176019&r1=176018&r2=176019&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Mon Feb 25 07:59:06 2013
@@ -818,6 +818,12 @@ TEST(HasDeclaration, HasDeclarationOfEnu
                           qualType(hasDeclaration(enumDecl(hasName("X")))))))));
 }
 
+TEST(HasDeclaration, HasGetDeclTraitTest) {
+  EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
+  EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
+  EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
+}
+
 TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
   EXPECT_TRUE(matches("typedef int X; X a;",
                       varDecl(hasName("a"),





More information about the cfe-commits mailing list