/// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
/// argument.
/// \c To must be a base class of \c T.
- template <typename To>
- Matcher<To> dynCastTo() const {
+ template <typename To> Matcher<To> dynCastTo() const LLVM_LVALUE_FUNCTION {
static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
return Matcher<To>(Implementation);
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename To> Matcher<To> dynCastTo() && {
+ static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
+ return Matcher<To>(std::move(Implementation));
+ }
+#endif
+
/// Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
ASTMatchFinder *Finder,
///
/// The returned matcher keeps the same restrictions as \c this and remembers
/// that it is meant to support nodes of type \c T.
- operator DynTypedMatcher() const { return Implementation; }
+ operator DynTypedMatcher() const LLVM_LVALUE_FUNCTION {
+ return Implementation;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ operator DynTypedMatcher() && { return std::move(Implementation); }
+#endif
/// Allows the conversion of a \c Matcher<Type> to a \c
/// Matcher<QualType>.
Names, getOperatorSpelling(Node.getOverloadedOperator()));
}
- const std::vector<std::string> Names;
+ std::vector<std::string> Names;
};
/// Matches named declarations with a specific name.
/// It is slower but simple and works on all cases.
bool matchesNodeFullSlow(const NamedDecl &Node) const;
- const bool UseUnqualifiedMatch;
- const std::vector<std::string> Names;
+ bool UseUnqualifiedMatch;
+ std::vector<std::string> Names;
};
/// Trampoline function to use VariadicFunction<> to construct a
static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
"instantiated with wrong types");
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
: Op(Op), Params(std::forward<Ps>(Params)...) {}
- template <typename T> operator Matcher<T>() const {
+ template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
return DynTypedMatcher::constructVariadic(
Op, ASTNodeKind::getFromNodeKind<T>(),
getMatchers<T>(std::index_sequence_for<Ps...>()))
.template unconditionalConvertTo<T>();
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename T> operator Matcher<T>() && {
+ return DynTypedMatcher::constructVariadic(
+ Op, ASTNodeKind::getFromNodeKind<T>(),
+ getMatchers<T>(std::index_sequence_for<Ps...>()))
+ .template unconditionalConvertTo<T>();
+ }
+#endif
private:
// Helper method to unpack the tuple into a vector.
template <typename T, std::size_t... Is>
- std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const {
+ std::vector<DynTypedMatcher>
+ getMatchers(std::index_sequence<Is...>) const LLVM_LVALUE_FUNCTION {
return {Matcher<T>(std::get<Is>(Params))...};
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename T, std::size_t... Is>
+ std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
+ return {Matcher<T>(std::get<Is>(std::move(Params)))...};
+ }
+#endif
+
const DynTypedMatcher::VariadicOperator Op;
std::tuple<Ps...> Params;
};
using ReturnTypes = ToTypes;
- template <typename To> operator Matcher<To>() const {
+ template <typename To> operator Matcher<To>() const LLVM_LVALUE_FUNCTION {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename To> operator Matcher<To>() && {
+ return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
+ }
+#endif
+
private:
- const Matcher<T> InnerMatcher;
+ Matcher<T> InnerMatcher;
};
/// Converts a \c Matcher<T> to a matcher of desired type \c To by
};
template <typename T> class TraversalMatcher : public MatcherInterface<T> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
clang::TraversalKind Traversal;
public:
TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
: TK(TK), InnerMatcher(InnerMatcher) {}
- template <typename T> operator Matcher<T>() const {
+ template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename T> operator Matcher<T>() && {
+ return internal::DynTypedMatcher::constructRestrictedWrapper(
+ new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
+ ASTNodeKind::getFromNodeKind<T>())
+ .template unconditionalConvertTo<T>();
+ }
+#endif
+
private:
TraversalKind TK;
MatcherType InnerMatcher;
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
- template <typename T>
- operator Matcher<T>() const {
+ template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ template <typename T> operator Matcher<T>() && {
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
+ return Matcher<T>(
+ new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
+ }
+#endif
+
private:
- const std::tuple<ParamTypes...> Params;
+ std::tuple<ParamTypes...> Params;
};
/// Matches nodes of type T that have child nodes of type ChildT for
/// ChildT must be an AST base type.
template <typename T, typename ChildT>
class HasMatcher : public MatcherInterface<T> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
static_assert(IsBaseType<ChildT>::value,
"for each only accepts base type matcher");
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
static_assert(IsBaseType<DescendantT>::value,
"has descendant only accepts base type matcher");
- const DynTypedMatcher DescendantMatcher;
+ DynTypedMatcher DescendantMatcher;
public:
explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
static_assert(IsBaseType<ParentT>::value,
"has parent only accepts base type matcher");
- const DynTypedMatcher ParentMatcher;
+ DynTypedMatcher ParentMatcher;
public:
explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
static_assert(IsBaseType<AncestorT>::value,
"has ancestor only accepts base type matcher");
- const DynTypedMatcher AncestorMatcher;
+ DynTypedMatcher AncestorMatcher;
public:
explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
static_assert(IsBaseType<DescendantT>::value,
"for each descendant only accepts base type matcher");
- const DynTypedMatcher DescendantMatcher;
+ DynTypedMatcher DescendantMatcher;
public:
explicit ForEachDescendantMatcher(
}
private:
- const ValueT ExpectedValue;
+ ValueT ExpectedValue;
};
/// Template specializations to easily write matchers for floating point
/// \c Matcher<T> matches.
template <typename TLoc, typename T>
class LocMatcher : public MatcherInterface<TLoc> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit LocMatcher(const Matcher<T> &InnerMatcher)
///
/// Used to implement the \c loc() matcher.
class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
/// another node of type \c T that can be reached using a given traverse
/// function.
template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
/// given traverse function.
template <typename T>
class TypeLocTraverseMatcher : public MatcherInterface<T> {
- const DynTypedMatcher InnerMatcher;
+ DynTypedMatcher InnerMatcher;
public:
explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
};
private:
- const Matcher<InnerTBase> InnerMatcher;
+ Matcher<InnerTBase> InnerMatcher;
};
/// A simple memoizer of T(*)() functions.
return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
}
- const std::vector<std::string> Names;
+ std::vector<std::string> Names;
};
using HasOpNameMatcher =