[PATCH] Add partial support for the hasDeclaration() matcher in the dynamic layer.

Samuel Benzaquen sbenza at google.com
Thu Nov 14 08:08:39 PST 2013


  Changed the bool to an enum to make the call site more obvious to what it is selecting.

Hi klimek,

http://llvm-reviews.chandlerc.com/D1889

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1889?vs=4813&id=5548#toc

BRANCH
  has_decl

ARCANIST PROJECT
  clang

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/ASTMatchers/ASTMatchersMacros.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/Dynamic/RegistryTest.cpp

Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1695,12 +1695,19 @@
 /// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
 ///   Matcher<MemberExpr>, Matcher<TypedefType>,
 ///   Matcher<TemplateSpecializationType>
-inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
-                                     internal::Matcher<Decl> >
-    hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
+inline internal::PolymorphicMatcherWithParam1<
+    internal::HasDeclarationMatcher, internal::Matcher<Decl>,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_6(QualType, CallExpr, CXXConstructExpr,
+                                      MemberExpr, TypedefType,
+                                      TemplateSpecializationType),
+    internal::CTC_Disabled>
+hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
   return internal::PolymorphicMatcherWithParam1<
-    internal::HasDeclarationMatcher,
-    internal::Matcher<Decl> >(InnerMatcher);
+      internal::HasDeclarationMatcher, internal::Matcher<Decl>,
+      AST_POLYMORPHIC_SUPPORTED_TYPES_6(QualType, CallExpr, CXXConstructExpr,
+                                        MemberExpr, TypedefType,
+                                        TemplateSpecializationType),
+      internal::CTC_Disabled>(InnerMatcher);
 }
 
 /// \brief Matches on the implicit object argument of a member call expression.
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -902,6 +902,13 @@
   }
 };
 
+/// \brief Used to control whether we enable compile time checks in the
+///   polymorphic matchers below.
+enum CompileTimeChecks {
+  CTC_Enabled,
+  CTC_Disabled
+};
+
 /// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
 /// created from N parameters p1, ..., pN (of type P1, ..., PN) and
 /// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
@@ -915,21 +922,24 @@
 ///   creates an object that can be used as a Matcher<T> for any type T
 ///   where a ValueEqualsMatcher<T, int>(42) can be constructed.
 template <template <typename T> class MatcherT,
-          typename ReturnTypesF = void(AllNodeBaseTypes)>
+          typename ReturnTypesF = void(AllNodeBaseTypes),
+          CompileTimeChecks Checks = CTC_Enabled>
 class PolymorphicMatcherWithParam0 {
 public:
   typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT(ReturnTypes::template ContainsSuperOf<T>::value,
+    TOOLING_COMPILE_ASSERT(Checks == CTC_Disabled ||
+                               ReturnTypes::template ContainsSuperOf<T>::value,
                            right_polymorphic_conversion);
     return Matcher<T>(new MatcherT<T>());
   }
 };
 
 template <template <typename T, typename P1> class MatcherT,
           typename P1,
-          typename ReturnTypesF = void(AllNodeBaseTypes)>
+          typename ReturnTypesF = void(AllNodeBaseTypes),
+          CompileTimeChecks Checks = CTC_Enabled>
 class PolymorphicMatcherWithParam1 {
 public:
   explicit PolymorphicMatcherWithParam1(const P1 &Param1)
@@ -939,7 +949,8 @@
 
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT(ReturnTypes::template ContainsSuperOf<T>::value,
+    TOOLING_COMPILE_ASSERT(Checks == CTC_Disabled ||
+                               ReturnTypes::template ContainsSuperOf<T>::value,
                            right_polymorphic_conversion);
     return Matcher<T>(new MatcherT<T, P1>(Param1));
   }
@@ -950,7 +961,8 @@
 
 template <template <typename T, typename P1, typename P2> class MatcherT,
           typename P1, typename P2,
-          typename ReturnTypesF = void(AllNodeBaseTypes)>
+          typename ReturnTypesF = void(AllNodeBaseTypes),
+          CompileTimeChecks Checks = CTC_Enabled>
 class PolymorphicMatcherWithParam2 {
 public:
   PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
@@ -960,7 +972,8 @@
 
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT(ReturnTypes::template ContainsSuperOf<T>::value,
+    TOOLING_COMPILE_ASSERT(Checks == CTC_Disabled ||
+                               ReturnTypes::template ContainsSuperOf<T>::value,
                            right_polymorphic_conversion);
     return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
   }
Index: include/clang/ASTMatchers/ASTMatchersMacros.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersMacros.h
+++ include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -172,6 +172,8 @@
   void(internal::TypeList<t1, t2, t3, t4>)
 #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
   void(internal::TypeList<t1, t2, t3, t4, t5>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_6(t1, t2, t3, t4, t5, t6)              \
+  void(internal::TypeList<t1, t2, t3, t4, t5, t6>)
 
 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
 /// defines a single-parameter function named DefineMatcher() that is
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -83,7 +83,6 @@
   // loc
   // equals
   // equalsNode
-  // hasDeclaration
 
   REGISTER_OVERLOADED_2(callee);
   REGISTER_OVERLOADED_2(hasPrefix);
@@ -174,6 +173,7 @@
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDeclContext);
+  REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeducedType);
   REGISTER_MATCHER(hasDescendant);
   REGISTER_MATCHER(hasDestinationType);
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -179,6 +179,19 @@
   EXPECT_FALSE(matches("int Foo;", RecordDecl));
   EXPECT_TRUE(matches("class Foo {};", RecordDecl));
   EXPECT_FALSE(matches("void Foo(){};", RecordDecl));
+
+  Matcher<Stmt> ConstructExpr = constructMatcher(
+      "constructExpr",
+      constructMatcher(
+          "hasDeclaration",
+          constructMatcher(
+              "methodDecl",
+              constructMatcher(
+                  "ofClass", constructMatcher("hasName", std::string("Foo"))))))
+                                    .getTypedMatcher<Stmt>();
+  EXPECT_FALSE(matches("class Foo { public: Foo(); };", ConstructExpr));
+  EXPECT_TRUE(
+      matches("class Foo { public: Foo(); }; Foo foo = Foo();", ConstructExpr));
 }
 
 TEST_F(RegistryTest, TemplateArgument) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1889.2.patch
Type: text/x-patch
Size: 7029 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131114/7b68deba/attachment.bin>


More information about the cfe-commits mailing list