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