r232924 - [ASTMatchers] Factor wrapping matcher classes into a common base class.

Benjamin Kramer benny.kra at googlemail.com
Sun Mar 22 14:57:54 PDT 2015


Author: d0k
Date: Sun Mar 22 16:57:53 2015
New Revision: 232924

URL: http://llvm.org/viewvc/llvm-project?rev=232924&view=rev
Log:
[ASTMatchers] Factor wrapping matcher classes into a common base class.

The deduplication here is negligible, but it allows the compiler to
skip emission of many templated base class destructors. Shrinks
clang-query by 53k. No functionality change intended.

Modified:
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=232924&r1=232923&r2=232924&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Sun Mar 22 16:57:53 2015
@@ -142,7 +142,7 @@ public:
   void setBinding(const std::string &Id,
                   const ast_type_traits::DynTypedNode &DynNode) {
     if (Bindings.empty())
-      Bindings.push_back(BoundNodesMap());
+      Bindings.emplace_back();
     for (BoundNodesMap &Binding : Bindings)
       Binding.addNode(Id, DynNode);
   }
@@ -384,6 +384,19 @@ private:
   IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
 };
 
+/// \brief Wrapper base class for a wrapping matcher.
+///
+/// This is just a container for a DynTypedMatcher that can be used as a base
+/// class for another matcher.
+template <typename T>
+class WrapperMatcherInterface : public MatcherInterface<T> {
+protected:
+  explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
+      : InnerMatcher(std::move(InnerMatcher)) {}
+
+  const DynTypedMatcher InnerMatcher;
+};
+
 /// \brief Wrapper of a MatcherInterface<T> *that allows copying.
 ///
 /// A Matcher<Base> can be used anywhere a Matcher<Derived> is
@@ -456,19 +469,18 @@ public:
   /// does only matches in the absence of qualifiers, or not, i.e. simply
   /// ignores any qualifiers.
   template <typename TypeT>
-  class TypeToQualType : public MatcherInterface<QualType> {
-   public:
+  class TypeToQualType : public WrapperMatcherInterface<QualType> {
+  public:
     TypeToQualType(const Matcher<TypeT> &InnerMatcher)
-        : InnerMatcher(InnerMatcher) {}
+        : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
 
     bool matches(const QualType &Node, ASTMatchFinder *Finder,
                  BoundNodesTreeBuilder *Builder) const override {
       if (Node.isNull())
         return false;
-      return InnerMatcher.matches(*Node, Finder, Builder);
+      return this->InnerMatcher.matches(
+          ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
     }
-   private:
-    const Matcher<TypeT> InnerMatcher;
   };
 
 private:
@@ -632,13 +644,13 @@ class HasNameMatcher : public SingleNode
 /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
 /// not actually used.
 template <typename T, typename DeclMatcherT>
-class HasDeclarationMatcher : public MatcherInterface<T> {
+class HasDeclarationMatcher : public WrapperMatcherInterface<T> {
   static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
                 "instantiated with wrong types");
 
 public:
   explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
-      : InnerMatcher(InnerMatcher) {}
+      : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
@@ -701,13 +713,12 @@ private:
 
   /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
   /// is \c NULL.
-  bool matchesDecl(const Decl *Node,
-                   ASTMatchFinder *Finder,
+  bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
                    BoundNodesTreeBuilder *Builder) const {
-    return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder);
+    return Node != nullptr &&
+           this->InnerMatcher.matches(
+               ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
   }
-
-  const Matcher<Decl> InnerMatcher;
 };
 
 /// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
@@ -1070,24 +1081,21 @@ public:
 ///
 /// ChildT must be an AST base type.
 template <typename T, typename ChildT>
-class HasMatcher : public MatcherInterface<T> {
+class HasMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<ChildT>::value,
                 "has only accepts base type matcher");
 
 public:
   explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
-      : ChildMatcher(ChildMatcher) {}
+      : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     return Finder->matchesChildOf(
-        Node, ChildMatcher, Builder,
+        Node, this->InnerMatcher, Builder,
         ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
         ASTMatchFinder::BK_First);
   }
-
- private:
-  const Matcher<ChildT> ChildMatcher;
 };
 
 /// \brief Matches nodes of type T that have child nodes of type ChildT for
@@ -1096,24 +1104,21 @@ public:
 /// As opposed to the HasMatcher, the ForEachMatcher will produce a match
 /// for each child that matches.
 template <typename T, typename ChildT>
-class ForEachMatcher : public MatcherInterface<T> {
+class ForEachMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<ChildT>::value,
                 "for each only accepts base type matcher");
 
  public:
-  explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
-      : ChildMatcher(ChildMatcher) {}
+   explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
+       : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
 
   bool matches(const T& Node, ASTMatchFinder* Finder,
                BoundNodesTreeBuilder* Builder) const override {
     return Finder->matchesChildOf(
-      Node, ChildMatcher, Builder,
-      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
-      ASTMatchFinder::BK_All);
+        Node, this->InnerMatcher, Builder,
+        ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
+        ASTMatchFinder::BK_All);
   }
-
-private:
-  const Matcher<ChildT> ChildMatcher;
 };
 
 /// \brief VariadicOperatorMatcher related types.
@@ -1182,11 +1187,9 @@ BindableMatcher<T> makeAllOfComposite(
     return BindableMatcher<T>(*InnerMatchers[0]);
   }
 
-  std::vector<DynTypedMatcher> DynMatchers;
-  DynMatchers.reserve(InnerMatchers.size());
-  for (const auto *InnerMatcher : InnerMatchers) {
-    DynMatchers.push_back(*InnerMatcher);
-  }
+  typedef llvm::pointee_iterator<const Matcher<T> *const *> PI;
+  std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
+                                           PI(InnerMatchers.end()));
   return BindableMatcher<T>(
       DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
                                          std::move(DynMatchers))
@@ -1211,22 +1214,19 @@ BindableMatcher<T> makeDynCastAllOfCompo
 ///
 /// DescendantT must be an AST base type.
 template <typename T, typename DescendantT>
-class HasDescendantMatcher : public MatcherInterface<T> {
+class HasDescendantMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<DescendantT>::value,
                 "has descendant only accepts base type matcher");
 
 public:
   explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
-      : DescendantMatcher(DescendantMatcher) {}
+      : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
-    return Finder->matchesDescendantOf(
-        Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First);
+    return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
+                                       ASTMatchFinder::BK_First);
   }
-
- private:
-  const Matcher<DescendantT> DescendantMatcher;
 };
 
 /// \brief Matches nodes of type \c T that have a parent node of type \c ParentT
@@ -1234,22 +1234,19 @@ public:
 ///
 /// \c ParentT must be an AST base type.
 template <typename T, typename ParentT>
-class HasParentMatcher : public MatcherInterface<T> {
+class HasParentMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<ParentT>::value,
                 "has parent only accepts base type matcher");
 
 public:
   explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
-      : ParentMatcher(ParentMatcher) {}
+      : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
-    return Finder->matchesAncestorOf(
-        Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
+    return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
+                                     ASTMatchFinder::AMM_ParentOnly);
   }
-
- private:
-  const Matcher<ParentT> ParentMatcher;
 };
 
 /// \brief Matches nodes of type \c T that have at least one ancestor node of
@@ -1257,22 +1254,19 @@ public:
 ///
 /// \c AncestorT must be an AST base type.
 template <typename T, typename AncestorT>
-class HasAncestorMatcher : public MatcherInterface<T> {
+class HasAncestorMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<AncestorT>::value,
                 "has ancestor only accepts base type matcher");
 
 public:
   explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
-      : AncestorMatcher(AncestorMatcher) {}
+      : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
-    return Finder->matchesAncestorOf(
-        Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
+    return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
+                                     ASTMatchFinder::AMM_All);
   }
-
- private:
-  const Matcher<AncestorT> AncestorMatcher;
 };
 
 /// \brief Matches nodes of type T that have at least one descendant node of
@@ -1282,23 +1276,20 @@ public:
 /// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
 /// for each descendant node that matches instead of only for the first.
 template <typename T, typename DescendantT>
-class ForEachDescendantMatcher : public MatcherInterface<T> {
+class ForEachDescendantMatcher : public WrapperMatcherInterface<T> {
   static_assert(IsBaseType<DescendantT>::value,
                 "for each descendant only accepts base type matcher");
 
- public:
+public:
   explicit ForEachDescendantMatcher(
-      const Matcher<DescendantT>& DescendantMatcher)
-      : DescendantMatcher(DescendantMatcher) {}
+      const Matcher<DescendantT> &DescendantMatcher)
+      : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
 
-  bool matches(const T& Node, ASTMatchFinder* Finder,
-               BoundNodesTreeBuilder* Builder) const override {
-    return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder,
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
                                        ASTMatchFinder::BK_All);
   }
-
-private:
-  const Matcher<DescendantT> DescendantMatcher;
 };
 
 /// \brief Matches on nodes that have a getValue() method if getValue() equals
@@ -1391,66 +1382,64 @@ public:
 /// \brief Matches nodes of type \c TLoc for which the inner
 /// \c Matcher<T> matches.
 template <typename TLoc, typename T>
-class LocMatcher : public MatcherInterface<TLoc> {
+class LocMatcher : public WrapperMatcherInterface<TLoc> {
 public:
   explicit LocMatcher(const Matcher<T> &InnerMatcher)
-    : InnerMatcher(InnerMatcher) {}
+      : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
 
   bool matches(const TLoc &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     if (!Node)
       return false;
-    return InnerMatcher.matches(*extract(Node), Finder, Builder);
+    return this->InnerMatcher.matches(extract(Node), Finder, Builder);
   }
 
 private:
-  const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const {
-    return Loc.getNestedNameSpecifier();
+  static ast_type_traits::DynTypedNode
+  extract(const NestedNameSpecifierLoc &Loc) {
+    return ast_type_traits::DynTypedNode::create(*Loc.getNestedNameSpecifier());
   }
-
-  const Matcher<T> InnerMatcher;
 };
 
 /// \brief Matches \c TypeLocs based on an inner matcher matching a certain
 /// \c QualType.
 ///
 /// Used to implement the \c loc() matcher.
-class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
+class TypeLocTypeMatcher : public WrapperMatcherInterface<TypeLoc> {
 public:
   explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
-      : InnerMatcher(InnerMatcher) {}
+      : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
 
   bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     if (!Node)
       return false;
-    return InnerMatcher.matches(Node.getType(), Finder, Builder);
+    return this->InnerMatcher.matches(
+        ast_type_traits::DynTypedNode::create(Node.getType()), Finder, Builder);
   }
-
-private:
-  const Matcher<QualType> InnerMatcher;
 };
 
 /// \brief Matches nodes of type \c T for which the inner matcher matches on a
 /// another node of type \c T that can be reached using a given traverse
 /// function.
 template <typename T>
-class TypeTraverseMatcher : public MatcherInterface<T> {
+class TypeTraverseMatcher : public WrapperMatcherInterface<T> {
 public:
   explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
                                QualType (T::*TraverseFunction)() const)
-      : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+      : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
+        TraverseFunction(TraverseFunction) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     QualType NextNode = (Node.*TraverseFunction)();
     if (NextNode.isNull())
       return false;
-    return InnerMatcher.matches(NextNode, Finder, Builder);
+    return this->InnerMatcher.matches(
+        ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
   }
 
 private:
-  const Matcher<QualType> InnerMatcher;
   QualType (T::*TraverseFunction)() const;
 };
 
@@ -1458,22 +1447,23 @@ private:
 /// matcher matches on a another node of type \c T that can be reached using a
 /// given traverse function.
 template <typename T>
-class TypeLocTraverseMatcher : public MatcherInterface<T> {
+class TypeLocTraverseMatcher : public WrapperMatcherInterface<T> {
 public:
   explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
                                   TypeLoc (T::*TraverseFunction)() const)
-      : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+      : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
+        TraverseFunction(TraverseFunction) {}
 
   bool matches(const T &Node, ASTMatchFinder *Finder,
                BoundNodesTreeBuilder *Builder) const override {
     TypeLoc NextNode = (Node.*TraverseFunction)();
     if (!NextNode)
       return false;
-    return InnerMatcher.matches(NextNode, Finder, Builder);
+    return this->InnerMatcher.matches(
+        ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
   }
 
 private:
-  const Matcher<TypeLoc> InnerMatcher;
   TypeLoc (T::*TraverseFunction)() const;
 };
 





More information about the cfe-commits mailing list