From: Benjamin Kramer Date: Sun, 22 Mar 2015 21:57:53 +0000 (+0000) Subject: [ASTMatchers] Factor wrapping matcher classes into a common base class. X-Git-Tag: llvmorg-3.7.0-rc1~8626 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70f19df90d0f8b69f0516290f75e90ef94d6d57d;p=platform%2Fupstream%2Fllvm.git [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. llvm-svn: 232924 --- diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index c4093898..20f1efa 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -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 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 +class WrapperMatcherInterface : public MatcherInterface { +protected: + explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher) + : InnerMatcher(std::move(InnerMatcher)) {} + + const DynTypedMatcher InnerMatcher; +}; + /// \brief Wrapper of a MatcherInterface *that allows copying. /// /// A Matcher can be used anywhere a Matcher is @@ -456,19 +469,18 @@ public: /// does only matches in the absence of qualifiers, or not, i.e. simply /// ignores any qualifiers. template - class TypeToQualType : public MatcherInterface { - public: + class TypeToQualType : public WrapperMatcherInterface { + public: TypeToQualType(const Matcher &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 InnerMatcher; }; private: @@ -632,13 +644,13 @@ class HasNameMatcher : public SingleNodeMatcherInterface { /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but /// not actually used. template -class HasDeclarationMatcher : public MatcherInterface { +class HasDeclarationMatcher : public WrapperMatcherInterface { static_assert(std::is_same>::value, "instantiated with wrong types"); public: explicit HasDeclarationMatcher(const Matcher &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 InnerMatcher; }; /// \brief IsBaseType::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 -class HasMatcher : public MatcherInterface { +class HasMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "has only accepts base type matcher"); public: explicit HasMatcher(const Matcher &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 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 -class ForEachMatcher : public MatcherInterface { +class ForEachMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "for each only accepts base type matcher"); public: - explicit ForEachMatcher(const Matcher &ChildMatcher) - : ChildMatcher(ChildMatcher) {} + explicit ForEachMatcher(const Matcher &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 ChildMatcher; }; /// \brief VariadicOperatorMatcher related types. @@ -1182,11 +1187,9 @@ BindableMatcher makeAllOfComposite( return BindableMatcher(*InnerMatchers[0]); } - std::vector DynMatchers; - DynMatchers.reserve(InnerMatchers.size()); - for (const auto *InnerMatcher : InnerMatchers) { - DynMatchers.push_back(*InnerMatcher); - } + typedef llvm::pointee_iterator *const *> PI; + std::vector DynMatchers(PI(InnerMatchers.begin()), + PI(InnerMatchers.end())); return BindableMatcher( DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, std::move(DynMatchers)) @@ -1211,22 +1214,19 @@ BindableMatcher makeDynCastAllOfComposite( /// /// DescendantT must be an AST base type. template -class HasDescendantMatcher : public MatcherInterface { +class HasDescendantMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "has descendant only accepts base type matcher"); public: explicit HasDescendantMatcher(const Matcher &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 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 -class HasParentMatcher : public MatcherInterface { +class HasParentMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "has parent only accepts base type matcher"); public: explicit HasParentMatcher(const Matcher &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 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 -class HasAncestorMatcher : public MatcherInterface { +class HasAncestorMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "has ancestor only accepts base type matcher"); public: explicit HasAncestorMatcher(const Matcher &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 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 -class ForEachDescendantMatcher : public MatcherInterface { +class ForEachDescendantMatcher : public WrapperMatcherInterface { static_assert(IsBaseType::value, "for each descendant only accepts base type matcher"); - public: +public: explicit ForEachDescendantMatcher( - const Matcher& DescendantMatcher) - : DescendantMatcher(DescendantMatcher) {} + const Matcher &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 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 matches. template -class LocMatcher : public MatcherInterface { +class LocMatcher : public WrapperMatcherInterface { public: explicit LocMatcher(const Matcher &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 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 { +class TypeLocTypeMatcher : public WrapperMatcherInterface { public: explicit TypeLocTypeMatcher(const Matcher &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 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 -class TypeTraverseMatcher : public MatcherInterface { +class TypeTraverseMatcher : public WrapperMatcherInterface { public: explicit TypeTraverseMatcher(const Matcher &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 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 -class TypeLocTraverseMatcher : public MatcherInterface { +class TypeLocTraverseMatcher : public WrapperMatcherInterface { public: explicit TypeLocTraverseMatcher(const Matcher &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 InnerMatcher; TypeLoc (T::*TraverseFunction)() const; };