summaryrefslogtreecommitdiff
path: root/include/clang/ASTMatchers/ASTMatchersInternal.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/ASTMatchers/ASTMatchersInternal.h')
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h470
1 files changed, 248 insertions, 222 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 69cee2eb5dfd..94435fd274eb 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -44,7 +44,6 @@
#include "clang/AST/Type.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/VariadicFunction.h"
-#include "llvm/Support/type_traits.h"
#include <map>
#include <string>
#include <vector>
@@ -52,11 +51,6 @@
namespace clang {
namespace ast_matchers {
-/// FIXME: Move into the llvm support library.
-template <bool> struct CompileAssert {};
-#define TOOLING_COMPILE_ASSERT(Expr, Msg) \
- typedef CompileAssert<(bool(Expr))> Msg[bool(Expr) ? 1 : -1]
-
class BoundNodes;
namespace internal {
@@ -80,7 +74,7 @@ public:
const T *getNodeAs(StringRef ID) const {
IDToNodeMap::const_iterator It = NodeMap.find(ID);
if (It == NodeMap.end()) {
- return NULL;
+ return nullptr;
}
return It->second.get<T>();
}
@@ -198,9 +192,9 @@ public:
private:
/// Implements MatcherInterface::Matches.
- virtual bool matches(const T &Node,
- ASTMatchFinder * /* Finder */,
- BoundNodesTreeBuilder * /* Builder */) const {
+ bool matches(const T &Node,
+ ASTMatchFinder * /* Finder */,
+ BoundNodesTreeBuilder * /* Builder */) const override {
return matchesNode(Node);
}
};
@@ -225,9 +219,8 @@ public:
/// Requires \c T to be derived from \c From.
template <typename From>
Matcher(const Matcher<From> &Other,
- typename llvm::enable_if_c<
- llvm::is_base_of<From, T>::value &&
- !llvm::is_same<From, T>::value >::type* = 0)
+ typename std::enable_if<std::is_base_of<From, T>::value &&
+ !std::is_same<From, T>::value>::type * = 0)
: Implementation(new ImplicitCastMatcher<From>(Other)) {}
/// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
@@ -235,9 +228,9 @@ public:
/// The resulting matcher is not strict, i.e. ignores qualifiers.
template <typename TypeT>
Matcher(const Matcher<TypeT> &Other,
- typename llvm::enable_if_c<
- llvm::is_same<T, QualType>::value &&
- llvm::is_same<TypeT, Type>::value >::type* = 0)
+ typename std::enable_if<
+ std::is_same<T, QualType>::value &&
+ std::is_same<TypeT, Type>::value>::type* = 0)
: Implementation(new TypeToQualType<TypeT>(Other)) {}
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
@@ -257,7 +250,7 @@ public:
uint64_t getID() const {
/// FIXME: Document the requirements this imposes on matcher
/// implementations (no new() implementation_ during a Matches()).
- return reinterpret_cast<uint64_t>(Implementation.getPtr());
+ return reinterpret_cast<uint64_t>(Implementation.get());
}
/// \brief Allows the conversion of a \c Matcher<Type> to a \c
@@ -272,9 +265,8 @@ public:
TypeToQualType(const Matcher<TypeT> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const QualType &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const QualType &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (Node.isNull())
return false;
return InnerMatcher.matches(*Node, Finder, Builder);
@@ -292,9 +284,8 @@ private:
explicit ImplicitCastMatcher(const Matcher<Base> &From)
: From(From) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return From.matches(Node, Finder, Builder);
}
@@ -379,9 +370,7 @@ public:
/// matcher can handle a value of T.
///
/// If it is not compatible, then this matcher will never match anything.
- template <typename T> Matcher<T> unconditionalConvertTo() const {
- return Matcher<T>(new WrappedMatcher<T>(*this));
- }
+ template <typename T> Matcher<T> unconditionalConvertTo() const;
private:
class MatcherStorage : public RefCountedBaseVPTR {
@@ -410,9 +399,6 @@ private:
/// \brief Typed implementation of \c MatcherStorage.
template <typename T> class TypedMatcherStorage;
- /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
- template <typename T> class WrappedMatcher;
-
IntrusiveRefCntPtr<const MatcherStorage> Storage;
};
@@ -425,15 +411,15 @@ public:
InnerMatcher(Other), AllowBind(AllowBind) {}
bool matches(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const
- LLVM_OVERRIDE {
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (const T *Node = DynNode.get<T>()) {
return InnerMatcher.matches(*Node, Finder, Builder);
}
return false;
}
- llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE {
+ llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override {
if (!AllowBind)
return llvm::Optional<DynTypedMatcher>();
return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
@@ -452,22 +438,6 @@ template <typename T>
inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
: Storage(new TypedMatcherStorage<T>(M, true)) {}
-template <typename T>
-class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> {
-public:
- explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {}
- virtual ~WrappedMatcher() {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder,
- Builder);
- }
-
-private:
- const DynTypedMatcher Inner;
-};
-
/// \brief Specialization of the conversion functions for QualType.
///
/// These specializations provide the Matcher<Type>->Matcher<QualType>
@@ -537,7 +507,7 @@ template <typename T> struct has_getDecl {
static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
template<typename C> static char (&f(...))[2];
- static bool const value = sizeof(f<Derived>(0)) == 2;
+ static bool const value = sizeof(f<Derived>(nullptr)) == 2;
};
/// \brief Matches overloaded operators with a specific name.
@@ -546,16 +516,17 @@ template <typename T> struct has_getDecl {
/// PolymorphicMatcherWithParam1 and should be StringRef.
template <typename T, typename ArgT>
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_same<T, CXXOperatorCallExpr>::value ||
- llvm::is_same<T, CXXMethodDecl>::value),
- unsupported_class_for_matcher);
- TOOLING_COMPILE_ASSERT((llvm::is_same<ArgT, StringRef>::value),
- argument_type_must_be_StringRef);
+ static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
+ std::is_base_of<FunctionDecl, T>::value,
+ "unsupported class for matcher");
+ static_assert(std::is_same<ArgT, StringRef>::value,
+ "argument type must be StringRef");
+
public:
explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
: SingleNodeMatcherInterface<T>(), Name(Name) {}
- virtual bool matchesNode(const T &Node) const LLVM_OVERRIDE {
+ bool matchesNode(const T &Node) const override {
return matchesSpecialized(Node);
}
@@ -570,7 +541,7 @@ private:
/// \brief Returns true only if CXXMethodDecl represents an overloaded
/// operator and has the given operator name.
- bool matchesSpecialized(const CXXMethodDecl &Node) const {
+ bool matchesSpecialized(const FunctionDecl &Node) const {
return Node.isOverloadedOperator() &&
getOperatorSpelling(Node.getOverloadedOperator()) == Name;
}
@@ -584,16 +555,15 @@ private:
/// not actually used.
template <typename T, typename DeclMatcherT>
class HasDeclarationMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_same< DeclMatcherT,
- Matcher<Decl> >::value),
- instantiated_with_wrong_types);
+ static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
+ "instantiated with wrong types");
+
public:
explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return matchesSpecialized(Node, Finder, Builder);
}
@@ -603,7 +573,7 @@ private:
template <typename U>
bool matchesSpecialized(
const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
- typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+ typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
return matchesDecl(Node.getDecl(), Finder, Builder);
}
@@ -656,7 +626,7 @@ private:
bool matchesDecl(const Decl *Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder);
+ return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder);
}
const Matcher<Decl> InnerMatcher;
@@ -667,14 +637,14 @@ private:
template <typename T>
struct IsBaseType {
static const bool value =
- (llvm::is_same<T, Decl>::value ||
- llvm::is_same<T, Stmt>::value ||
- llvm::is_same<T, QualType>::value ||
- llvm::is_same<T, Type>::value ||
- llvm::is_same<T, TypeLoc>::value ||
- llvm::is_same<T, NestedNameSpecifier>::value ||
- llvm::is_same<T, NestedNameSpecifierLoc>::value ||
- llvm::is_same<T, CXXCtorInitializer>::value);
+ std::is_same<T, Decl>::value ||
+ std::is_same<T, Stmt>::value ||
+ std::is_same<T, QualType>::value ||
+ std::is_same<T, Type>::value ||
+ std::is_same<T, TypeLoc>::value ||
+ std::is_same<T, NestedNameSpecifier>::value ||
+ std::is_same<T, NestedNameSpecifierLoc>::value ||
+ std::is_same<T, CXXCtorInitializer>::value;
};
template <typename T>
const bool IsBaseType<T>::value;
@@ -740,14 +710,13 @@ public:
BoundNodesTreeBuilder *Builder,
TraversalKind Traverse,
BindKind Bind) {
- TOOLING_COMPILE_ASSERT(
- (llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value ||
- llvm::is_base_of<NestedNameSpecifier, T>::value ||
- llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
- llvm::is_base_of<TypeLoc, T>::value ||
- llvm::is_base_of<QualType, T>::value),
- unsupported_type_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value ||
+ std::is_base_of<NestedNameSpecifier, T>::value ||
+ std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ std::is_base_of<TypeLoc, T>::value ||
+ std::is_base_of<QualType, T>::value,
+ "unsupported type for recursive matching");
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Traverse, Bind);
}
@@ -757,14 +726,13 @@ public:
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) {
- TOOLING_COMPILE_ASSERT(
- (llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value ||
- llvm::is_base_of<NestedNameSpecifier, T>::value ||
- llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
- llvm::is_base_of<TypeLoc, T>::value ||
- llvm::is_base_of<QualType, T>::value),
- unsupported_type_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value ||
+ std::is_base_of<NestedNameSpecifier, T>::value ||
+ std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ std::is_base_of<TypeLoc, T>::value ||
+ std::is_base_of<QualType, T>::value,
+ "unsupported type for recursive matching");
return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Bind);
}
@@ -775,9 +743,9 @@ public:
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
- TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value),
- only_Decl_or_Stmt_allowed_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value,
+ "only Decl or Stmt allowed for recursive matching");
return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, MatchMode);
}
@@ -820,7 +788,7 @@ struct TypeList {
/// \brief The first type on the list.
typedef T1 head;
- /// \brief A sub list with the tail. ie everything but the head.
+ /// \brief A sublist with the tail. ie everything but the head.
///
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
/// end of the list.
@@ -852,7 +820,7 @@ typedef TypeList<> EmptyTypeList;
template <typename AnyTypeList, typename T>
struct TypeListContainsSuperOf {
static const bool value =
- llvm::is_base_of<typename AnyTypeList::head, T>::value ||
+ std::is_base_of<typename AnyTypeList::head, T>::value ||
TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
};
template <typename T>
@@ -952,8 +920,8 @@ public:
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T>());
}
};
@@ -970,8 +938,8 @@ public:
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1>(Param1));
}
@@ -991,8 +959,8 @@ public:
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
}
@@ -1018,7 +986,7 @@ private:
template <typename T>
class TrueMatcher : public SingleNodeMatcherInterface<T> {
public:
- virtual bool matchesNode(const T &Node) const {
+ bool matchesNode(const T &Node) const override {
return true;
}
};
@@ -1033,9 +1001,8 @@ public:
IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher)
: ID(ID), InnerMatcher(InnerMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
bool Result = InnerMatcher.matches(Node, Finder, Builder);
if (Result) {
Builder->setBinding(ID, &Node);
@@ -1074,15 +1041,15 @@ public:
/// ChildT must be an AST base type.
template <typename T, typename ChildT>
class HasMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
- has_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ChildT>::value,
+ "has only accepts base type matcher");
+
public:
explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
: ChildMatcher(ChildMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesChildOf(
Node, ChildMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1100,15 +1067,15 @@ public:
/// for each child that matches.
template <typename T, typename ChildT>
class ForEachMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
- for_each_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ChildT>::value,
+ "for each only accepts base type matcher");
+
public:
explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
: ChildMatcher(ChildMatcher) {}
- virtual bool matches(const T& Node,
- ASTMatchFinder* Finder,
- BoundNodesTreeBuilder* Builder) const {
+ bool matches(const T& Node, ASTMatchFinder* Finder,
+ BoundNodesTreeBuilder* Builder) const override {
return Finder->matchesChildOf(
Node, ChildMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1119,38 +1086,6 @@ private:
const Matcher<ChildT> ChildMatcher;
};
-/// \brief Matches nodes of type T if the given Matcher<T> does not match.
-///
-/// Type argument MatcherT is required by PolymorphicMatcherWithParam1
-/// but not actually used. It will always be instantiated with a type
-/// convertible to Matcher<T>.
-template <typename T, typename MatcherT>
-class NotMatcher : public MatcherInterface<T> {
-public:
- explicit NotMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- // The 'unless' matcher will always discard the result:
- // If the inner matcher doesn't match, unless returns true,
- // but the inner matcher cannot have bound anything.
- // If the inner matcher matches, the result is false, and
- // any possible binding will be discarded.
- // We still need to hand in all the bound nodes up to this
- // point so the inner matcher can depend on bound nodes,
- // and we need to actively discard the bound nodes, otherwise
- // the inner matcher will reset the bound nodes if it doesn't
- // match, but this would be inversed by 'unless'.
- BoundNodesTreeBuilder Discard(*Builder);
- return !InnerMatcher.matches(Node, Finder, &Discard);
- }
-
-private:
- const Matcher<T> InnerMatcher;
-};
-
/// \brief VariadicOperatorMatcher related types.
/// @{
@@ -1165,22 +1100,18 @@ template <typename T>
class VariadicOperatorMatcherInterface : public MatcherInterface<T> {
public:
VariadicOperatorMatcherInterface(VariadicOperatorFunction Func,
- ArrayRef<const Matcher<T> *> InputMatchers)
- : Func(Func) {
- for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {
- InnerMatchers.push_back(*InputMatchers[i]);
- }
- }
+ std::vector<DynTypedMatcher> InnerMatchers)
+ : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
- virtual bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
InnerMatchers);
}
private:
const VariadicOperatorFunction Func;
- std::vector<DynTypedMatcher> InnerMatchers;
+ const std::vector<DynTypedMatcher> InnerMatchers;
};
/// \brief "No argument" placeholder to use as template paratemers.
@@ -1192,46 +1123,55 @@ struct VariadicOperatorNoArg {};
/// Input matchers can have any type (including other polymorphic matcher
/// types), and the actual Matcher<T> is generated on demand with an implicit
/// coversion operator.
-template <typename P1, typename P2,
+template <typename P1, typename P2 = VariadicOperatorNoArg,
typename P3 = VariadicOperatorNoArg,
typename P4 = VariadicOperatorNoArg,
- typename P5 = VariadicOperatorNoArg>
+ typename P5 = VariadicOperatorNoArg,
+ typename P6 = VariadicOperatorNoArg,
+ typename P7 = VariadicOperatorNoArg,
+ typename P8 = VariadicOperatorNoArg,
+ typename P9 = VariadicOperatorNoArg>
class VariadicOperatorMatcher {
public:
VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
- const P2 &Param2,
+ const P2 &Param2 = VariadicOperatorNoArg(),
const P3 &Param3 = VariadicOperatorNoArg(),
const P4 &Param4 = VariadicOperatorNoArg(),
- const P5 &Param5 = VariadicOperatorNoArg())
+ const P5 &Param5 = VariadicOperatorNoArg(),
+ const P6 &Param6 = VariadicOperatorNoArg(),
+ const P7 &Param7 = VariadicOperatorNoArg(),
+ const P8 &Param8 = VariadicOperatorNoArg(),
+ const P9 &Param9 = VariadicOperatorNoArg())
: Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
- Param4(Param4), Param5(Param5) {}
+ Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
+ Param8(Param8), Param9(Param9) {}
template <typename T> operator Matcher<T>() const {
- Matcher<T> *Array[5];
- size_t Size = 0;
-
- addMatcher<T>(Param1, Array, Size);
- addMatcher<T>(Param2, Array, Size);
- addMatcher<T>(Param3, Array, Size);
- addMatcher<T>(Param4, Array, Size);
- addMatcher<T>(Param5, Array, Size);
- Matcher<T> Result(new VariadicOperatorMatcherInterface<T>(
- Func, ArrayRef<const Matcher<T> *>(Array, Size)));
- for (size_t i = 0, e = Size; i != e; ++i) delete Array[i];
- return Result;
+ std::vector<DynTypedMatcher> Matchers;
+ addMatcher<T>(Param1, Matchers);
+ addMatcher<T>(Param2, Matchers);
+ addMatcher<T>(Param3, Matchers);
+ addMatcher<T>(Param4, Matchers);
+ addMatcher<T>(Param5, Matchers);
+ addMatcher<T>(Param6, Matchers);
+ addMatcher<T>(Param7, Matchers);
+ addMatcher<T>(Param8, Matchers);
+ addMatcher<T>(Param9, Matchers);
+ return Matcher<T>(
+ new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
}
private:
template <typename T>
- static void addMatcher(const Matcher<T> &M, Matcher<T> **Array,
- size_t &Size) {
- Array[Size++] = new Matcher<T>(M);
+ static void addMatcher(const Matcher<T> &M,
+ std::vector<DynTypedMatcher> &Matchers) {
+ Matchers.push_back(M);
}
/// \brief Overload to ignore \c VariadicOperatorNoArg arguments.
template <typename T>
- static void addMatcher(VariadicOperatorNoArg, Matcher<T> **Array,
- size_t &Size) {}
+ static void addMatcher(VariadicOperatorNoArg,
+ std::vector<DynTypedMatcher> &Matchers) {}
const VariadicOperatorFunction Func;
const P1 Param1;
@@ -1239,40 +1179,100 @@ private:
const P3 Param3;
const P4 Param4;
const P5 Param5;
+ const P6 Param6;
+ const P7 Param7;
+ const P8 Param8;
+ const P9 Param9;
};
/// \brief Overloaded function object to generate VariadicOperatorMatcher
/// objects from arbitrary matchers.
///
-/// It supports 2-5 argument overloaded operator(). More can be added if needed.
+/// It supports 1-9 argument overloaded operator(). More can be added if needed.
+template <unsigned MinCount, unsigned MaxCount>
struct VariadicOperatorMatcherFunc {
VariadicOperatorFunction Func;
+ template <unsigned Count, typename T>
+ struct EnableIfValidArity
+ : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {};
+
+ template <typename M1>
+ typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
+ operator()(const M1 &P1) const {
+ return VariadicOperatorMatcher<M1>(Func, P1);
+ }
template <typename M1, typename M2>
- VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const {
+ typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
+ operator()(const M1 &P1, const M2 &P2) const {
return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
}
template <typename M1, typename M2, typename M3>
- VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2,
- const M3 &P3) const {
+ typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
}
template <typename M1, typename M2, typename M3, typename M4>
- VariadicOperatorMatcher<M1, M2, M3, M4>
+ typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5>
- VariadicOperatorMatcher<M1, M2, M3, M4, M5>
+ typename EnableIfValidArity<
+ 5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
P5);
}
+ template <typename M1, typename M2, typename M3, typename M4, typename M5,
+ typename M6>
+ typename EnableIfValidArity<
+ 6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+ const M5 &P5, const M6 &P6) const {
+ return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
+ Func, P1, P2, P3, P4, P5, P6);
+ }
+ template <typename M1, typename M2, typename M3, typename M4, typename M5,
+ typename M6, typename M7>
+ typename EnableIfValidArity<
+ 7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+ const M5 &P5, const M6 &P6, const M7 &P7) const {
+ return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
+ Func, P1, P2, P3, P4, P5, P6, P7);
+ }
+ template <typename M1, typename M2, typename M3, typename M4, typename M5,
+ typename M6, typename M7, typename M8>
+ typename EnableIfValidArity<
+ 8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+ const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
+ return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
+ Func, P1, P2, P3, P4, P5, P6, P7, P8);
+ }
+ template <typename M1, typename M2, typename M3, typename M4, typename M5,
+ typename M6, typename M7, typename M8, typename M9>
+ typename EnableIfValidArity<
+ 9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+ const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
+ const M9 &P9) const {
+ return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
+ Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+ }
};
/// @}
+/// \brief Matches nodes that do not match the provided matcher.
+///
+/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<DynTypedMatcher> InnerMatchers);
+
/// \brief Matches nodes for which all provided matchers match.
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
ASTMatchFinder *Finder,
@@ -1293,12 +1293,22 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
+template <typename T>
+inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
+ return Matcher<T>(new VariadicOperatorMatcherInterface<T>(
+ AllOfVariadicOperator, llvm::makeArrayRef(*this)));
+}
+
/// \brief Creates a Matcher<T> that matches if all inner matchers match.
template<typename T>
BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
+ DynMatchers.push_back(*InnerMatchers[i]);
+ }
return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>(
- AllOfVariadicOperator, InnerMatchers));
+ AllOfVariadicOperator, std::move(DynMatchers)));
}
/// \brief Creates a Matcher<T> that matches if
@@ -1320,15 +1330,15 @@ BindableMatcher<T> makeDynCastAllOfComposite(
/// DescendantT must be an AST base type.
template <typename T, typename DescendantT>
class HasDescendantMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
- has_descendant_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<DescendantT>::value,
+ "has descendant only accepts base type matcher");
+
public:
explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
: DescendantMatcher(DescendantMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesDescendantOf(
Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First);
}
@@ -1343,15 +1353,15 @@ public:
/// \c ParentT must be an AST base type.
template <typename T, typename ParentT>
class HasParentMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value,
- has_parent_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ParentT>::value,
+ "has parent only accepts base type matcher");
+
public:
explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
: ParentMatcher(ParentMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesAncestorOf(
Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
}
@@ -1366,15 +1376,15 @@ public:
/// \c AncestorT must be an AST base type.
template <typename T, typename AncestorT>
class HasAncestorMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value,
- has_ancestor_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<AncestorT>::value,
+ "has ancestor only accepts base type matcher");
+
public:
explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
: AncestorMatcher(AncestorMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesAncestorOf(
Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
}
@@ -1391,16 +1401,16 @@ public:
/// for each descendant node that matches instead of only for the first.
template <typename T, typename DescendantT>
class ForEachDescendantMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
- for_each_descendant_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<DescendantT>::value,
+ "for each descendant only accepts base type matcher");
+
public:
explicit ForEachDescendantMatcher(
const Matcher<DescendantT>& DescendantMatcher)
: DescendantMatcher(DescendantMatcher) {}
- virtual bool matches(const T& Node,
- ASTMatchFinder* Finder,
- BoundNodesTreeBuilder* Builder) const {
+ bool matches(const T& Node, ASTMatchFinder* Finder,
+ BoundNodesTreeBuilder* Builder) const override {
return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder,
ASTMatchFinder::BK_All);
}
@@ -1413,17 +1423,17 @@ private:
/// the value the ValueEqualsMatcher was constructed with.
template <typename T, typename ValueT>
class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_base_of<CharacterLiteral, T>::value ||
- llvm::is_base_of<CXXBoolLiteralExpr,
- T>::value ||
- llvm::is_base_of<FloatingLiteral, T>::value ||
- llvm::is_base_of<IntegerLiteral, T>::value),
- the_node_must_have_a_getValue_method);
+ static_assert(std::is_base_of<CharacterLiteral, T>::value ||
+ std::is_base_of<CXXBoolLiteralExpr, T>::value ||
+ std::is_base_of<FloatingLiteral, T>::value ||
+ std::is_base_of<IntegerLiteral, T>::value,
+ "the node must have a getValue method");
+
public:
explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
: ExpectedValue(ExpectedValue) {}
- virtual bool matchesNode(const T &Node) const {
+ bool matchesNode(const T &Node) const override {
return Node.getValue() == ExpectedValue;
}
@@ -1478,9 +1488,8 @@ public:
explicit LocMatcher(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const TLoc &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const TLoc &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (!Node)
return false;
return InnerMatcher.matches(*extract(Node), Finder, Builder);
@@ -1503,9 +1512,8 @@ public:
explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const TypeLoc &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (!Node)
return false;
return InnerMatcher.matches(Node.getType(), Finder, Builder);
@@ -1525,9 +1533,8 @@ public:
QualType (T::*TraverseFunction)() const)
: InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
QualType NextNode = (Node.*TraverseFunction)();
if (NextNode.isNull())
return false;
@@ -1549,9 +1556,8 @@ public:
TypeLoc (T::*TraverseFunction)() const)
: InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
TypeLoc NextNode = (Node.*TraverseFunction)();
if (!NextNode)
return false;
@@ -1612,6 +1618,26 @@ TypeTraversePolymorphicMatcher<
return Self(InnerMatchers);
}
+// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
+// APIs for accessing the template argument list.
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
+ return D.getTemplateArgs().asArray();
+}
+
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
+ return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+}
+
+struct NotEqualsBoundNodePredicate {
+ bool operator()(const internal::BoundNodesMap &Nodes) const {
+ return Nodes.getNode(ID) != Node;
+ }
+ std::string ID;
+ ast_type_traits::DynTypedNode Node;
+};
+
} // end namespace internal
} // end namespace ast_matchers
} // end namespace clang