diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2015-03-22 21:57:53 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2015-03-22 21:57:53 +0000 |
commit | 70f19df90d0f8b69f0516290f75e90ef94d6d57d (patch) | |
tree | b9a8e651d29fb5374188a7a099c2190f53a90456 | |
parent | abd9f5bfb661f2338a8ebcd70586248a31e598ed (diff) | |
download | bcm5719-llvm-70f19df90d0f8b69f0516290f75e90ef94d6d57d.tar.gz bcm5719-llvm-70f19df90d0f8b69f0516290f75e90ef94d6d57d.zip |
[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
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchersInternal.h | 162 |
1 files changed, 76 insertions, 86 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index c4093898b68..20f1efa5e3b 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<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 SingleNodeMatcherInterface<NamedDecl> { /// 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> makeDynCastAllOfComposite( /// /// 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; }; |