[ASTMatchers][NFC] Use move semantics when passing matchers around.

Changing matchers to use non-const members and adding r-value overloads of matcher conversions enables move optimisations.
I don't have performance figures but I can say this knocked 120k from the clang-tidy binary(86k was from the .text section) on a Release with assertions build(x86_64-unknown-linux-gnu).

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D98792
This commit is contained in:
Nathan James 2021-03-17 22:03:07 +00:00
parent 35e0567d58
commit 48ab9674b2
No known key found for this signature in database
GPG Key ID: CC007AFCDA90AA5F
2 changed files with 90 additions and 39 deletions

View File

@ -541,12 +541,18 @@ public:
/// 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,
@ -563,7 +569,13 @@ public:
///
/// 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>.
@ -870,7 +882,7 @@ private:
Names, getOperatorSpelling(Node.getOverloadedOperator()));
}
const std::vector<std::string> Names;
std::vector<std::string> Names;
};
/// Matches named declarations with a specific name.
@ -904,8 +916,8 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
/// 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
@ -926,7 +938,7 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
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)
@ -1315,20 +1327,36 @@ public:
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;
};
@ -1417,12 +1445,18 @@ public:
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
@ -1464,7 +1498,7 @@ struct ArgumentAdaptingMatcherFunc {
};
template <typename T> class TraversalMatcher : public MatcherInterface<T> {
const DynTypedMatcher InnerMatcher;
DynTypedMatcher InnerMatcher;
clang::TraversalKind Traversal;
public:
@ -1490,13 +1524,22 @@ 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;
@ -1522,15 +1565,23 @@ public:
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
@ -1539,7 +1590,7 @@ private:
/// 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)
@ -1562,7 +1613,7 @@ class ForEachMatcher : public MatcherInterface<T> {
static_assert(IsBaseType<ChildT>::value,
"for each only accepts base type matcher");
const DynTypedMatcher InnerMatcher;
DynTypedMatcher InnerMatcher;
public:
explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
@ -1592,7 +1643,7 @@ class HasDescendantMatcher : public MatcherInterface<T> {
static_assert(IsBaseType<DescendantT>::value,
"has descendant only accepts base type matcher");
const DynTypedMatcher DescendantMatcher;
DynTypedMatcher DescendantMatcher;
public:
explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
@ -1614,7 +1665,7 @@ class HasParentMatcher : public MatcherInterface<T> {
static_assert(IsBaseType<ParentT>::value,
"has parent only accepts base type matcher");
const DynTypedMatcher ParentMatcher;
DynTypedMatcher ParentMatcher;
public:
explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
@ -1636,7 +1687,7 @@ class HasAncestorMatcher : public MatcherInterface<T> {
static_assert(IsBaseType<AncestorT>::value,
"has ancestor only accepts base type matcher");
const DynTypedMatcher AncestorMatcher;
DynTypedMatcher AncestorMatcher;
public:
explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
@ -1660,7 +1711,7 @@ class ForEachDescendantMatcher : public MatcherInterface<T> {
static_assert(IsBaseType<DescendantT>::value,
"for each descendant only accepts base type matcher");
const DynTypedMatcher DescendantMatcher;
DynTypedMatcher DescendantMatcher;
public:
explicit ForEachDescendantMatcher(
@ -1693,7 +1744,7 @@ public:
}
private:
const ValueT ExpectedValue;
ValueT ExpectedValue;
};
/// Template specializations to easily write matchers for floating point
@ -1726,7 +1777,7 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
/// \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)
@ -1750,7 +1801,7 @@ private:
///
/// Used to implement the \c loc() matcher.
class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
const DynTypedMatcher InnerMatcher;
DynTypedMatcher InnerMatcher;
public:
explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
@ -1769,7 +1820,7 @@ public:
/// 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,
@ -1794,7 +1845,7 @@ private:
/// given traverse function.
template <typename T>
class TypeLocTraverseMatcher : public MatcherInterface<T> {
const DynTypedMatcher InnerMatcher;
DynTypedMatcher InnerMatcher;
public:
explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
@ -1849,7 +1900,7 @@ public:
};
private:
const Matcher<InnerTBase> InnerMatcher;
Matcher<InnerTBase> InnerMatcher;
};
/// A simple memoizer of T(*)() functions.
@ -2193,7 +2244,7 @@ private:
return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
}
const std::vector<std::string> Names;
std::vector<std::string> Names;
};
using HasOpNameMatcher =

View File

@ -143,7 +143,7 @@
*Builder) const override; \
\
private: \
ParamType const Param; \
ParamType Param; \
}; \
} \
inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
@ -151,7 +151,7 @@
return ::clang::ast_matchers::internal::makeMatcher( \
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
} \
typedef ::clang::ast_matchers::internal::Matcher<Type>( \
typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
&DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, \
@ -192,8 +192,8 @@
*Builder) const override; \
\
private: \
ParamType1 const Param1; \
ParamType2 const Param2; \
ParamType1 Param1; \
ParamType2 Param2; \
}; \
} \
inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
@ -202,7 +202,7 @@
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
Param2)); \
} \
typedef ::clang::ast_matchers::internal::Matcher<Type>( \
typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
&DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \
ParamType2 const &Param2); \
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
@ -281,7 +281,7 @@
*Builder) const override; \
\
private: \
ParamType const Param; \
ParamType Param; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
@ -333,8 +333,8 @@
*Builder) const override; \
\
private: \
ParamType1 const Param1; \
ParamType2 const Param2; \
ParamType1 Param1; \
ParamType2 Param2; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
@ -469,7 +469,7 @@
*Builder) const override; \
\
private: \
std::shared_ptr<llvm::Regex> const Param; \
std::shared_ptr<llvm::Regex> Param; \
}; \
} \
inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
@ -521,7 +521,7 @@
*Builder) const override; \
\
private: \
std::shared_ptr<llvm::Regex> const Param; \
std::shared_ptr<llvm::Regex> Param; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \