forked from OSchip/llvm-project
[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
This commit is contained in:
parent
abd9f5bfb6
commit
70f19df90d
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue