[ASTMatchers] Make Param functors variadic

Differential Revision: https://reviews.llvm.org/D97156
This commit is contained in:
Stephen Kelly 2021-01-13 03:07:03 +00:00
parent 1a4990a4f7
commit 243cd0afad
4 changed files with 115 additions and 141 deletions

View file

@ -351,13 +351,17 @@ Flags can be combined with '|' example \"IgnoreCase | BasicRegex\"
m = re.match(
r"""^.*internal::VariadicFunction\s*<\s*
internal::PolymorphicMatcherWithParam1<[\S\s]+
AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)>,\s*([^,]+),
\s*[^>]+>\s*([a-zA-Z]*);$""",
internal::PolymorphicMatcher<[\S\s]+
AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\),\s*(.*);$""",
declaration, flags=re.X)
if m:
results, arg, name = m.groups()[:3]
results, trailing = m.groups()
trailing, name = trailing.rsplit(">", 1)
name = name.strip()
trailing, _ = trailing.rsplit(",", 1)
_, arg = trailing.rsplit(",", 1)
arg = arg.strip()
result_types = [r.strip() for r in results.split(',')]
for result_type in result_types:

View file

@ -835,26 +835,16 @@ traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor<
ToTypes>>(TK, InnerMatcher);
}
template <template <typename T, typename P1> class MatcherT, typename P1,
template <template <typename T, typename... P> class MatcherT, typename... P,
typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam1<
MatcherT, P1, ReturnTypesF> &InnerMatcher) {
internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>
traverse(TraversalKind TK,
const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>
&InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>(
TK, InnerMatcher);
}
template <template <typename T, typename P1, typename P2> class MatcherT,
typename P1, typename P2, typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam2<
MatcherT, P1, P2, ReturnTypesF> &InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>(
TK, InnerMatcher);
internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>(TK,
InnerMatcher);
}
template <typename... T>
@ -2996,14 +2986,15 @@ AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) {
/// matches the declaration of \c A.
///
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
inline internal::PolymorphicMatcher<
internal::HasOverloadedOperatorNameMatcher,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
std::vector<std::string>>
hasOverloadedOperatorName(StringRef Name) {
return internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(
{std::string(Name)});
return internal::PolymorphicMatcher<
internal::HasOverloadedOperatorNameMatcher,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
std::vector<std::string>>({std::string(Name)});
}
/// Matches overloaded operator names.
@ -3015,9 +3006,10 @@ hasOverloadedOperatorName(StringRef Name) {
/// Is equivalent to
/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
extern const internal::VariadicFunction<
internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>,
internal::PolymorphicMatcher<internal::HasOverloadedOperatorNameMatcher,
AST_POLYMORPHIC_SUPPORTED_TYPES(
CXXOperatorCallExpr, FunctionDecl),
std::vector<std::string>>,
StringRef, internal::hasAnyOverloadedOperatorNameFunc>
hasAnyOverloadedOperatorName;
@ -3506,13 +3498,14 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
/// Matcher<UnresolvedUsingType>
inline internal::PolymorphicMatcherWithParam1<
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
void(internal::HasDeclarationSupportedTypes)>
inline internal::PolymorphicMatcher<
internal::HasDeclarationMatcher,
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
return internal::PolymorphicMatcherWithParam1<
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
return internal::PolymorphicMatcher<
internal::HasDeclarationMatcher,
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>(
InnerMatcher);
}
/// Matches a \c NamedDecl whose underlying declaration matches the given
@ -5299,11 +5292,12 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
template <typename ValueT>
internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
void(internal::AllNodeBaseTypes), ValueT>
equals(const ValueT &Value) {
return internal::PolymorphicMatcherWithParam1<
internal::ValueEqualsMatcher,
ValueT>(Value);
return internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
void(internal::AllNodeBaseTypes), ValueT>(
Value);
}
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
@ -5358,11 +5352,11 @@ AST_POLYMORPHIC_MATCHER_P(
/// Is equivalent to
/// anyOf(hasOperatorName("+"), hasOperatorName("-"))
extern const internal::VariadicFunction<
internal::PolymorphicMatcherWithParam1<
internal::HasAnyOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator,
UnaryOperator)>,
internal::PolymorphicMatcher<internal::HasAnyOperatorNameMatcher,
AST_POLYMORPHIC_SUPPORTED_TYPES(
BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, UnaryOperator),
std::vector<std::string>>,
StringRef, internal::hasAnyOperatorNameFunc>
hasAnyOperatorName;

View file

@ -836,7 +836,7 @@ public:
/// Matches overloaded operators with a specific name.
///
/// The type argument ArgT is not used by this matcher but is used by
/// PolymorphicMatcherWithParam1 and should be StringRef.
/// PolymorphicMatcher and should be StringRef.
template <typename T, typename ArgT>
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
@ -919,7 +919,7 @@ Matcher<ObjCMessageExpr> hasAnySelectorFunc(
/// Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
/// Type argument DeclMatcherT is required by PolymorphicMatcher but
/// not actually used.
template <typename T, typename DeclMatcherT>
class HasDeclarationMatcher : public MatcherInterface<T> {
@ -1157,6 +1157,18 @@ template <class T> struct ExtractFunctionArgMeta<void(T)> {
using type = T;
};
template <class T, class Tuple, std::size_t... I>
constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
return new T(std::get<I>(std::forward<Tuple>(t))...);
}
template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
return new_from_tuple_impl<T>(
std::forward<Tuple>(t),
std::make_index_sequence<
std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}
/// Default type lists for ArgumentAdaptingMatcher matchers.
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
using AdaptativeDefaultToTypes =
@ -1426,7 +1438,7 @@ private:
/// \c HasMatcher<To, T>(InnerMatcher).
///
/// If a matcher does not need knowledge about the inner type, prefer to use
/// PolymorphicMatcherWithParam1.
/// PolymorphicMatcher.
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename FromTypes = AdaptativeDefaultFromTypes,
typename ToTypes = AdaptativeDefaultToTypes>
@ -1491,39 +1503,23 @@ private:
MatcherType InnerMatcher;
};
/// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
/// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
/// can be constructed.
///
/// For example:
/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>()
/// - PolymorphicMatcher<IsDefinitionMatcher>()
/// creates an object that can be used as a Matcher<T> for any type T
/// where an IsDefinitionMatcher<T>() can be constructed.
/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42)
/// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
/// creates an object that can be used as a Matcher<T> for any type T
/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
template <template <typename T> class MatcherT,
typename ReturnTypesF = void(AllNodeBaseTypes)>
class PolymorphicMatcherWithParam0 {
template <template <typename T, typename... Params> class MatcherT,
typename ReturnTypesF, typename... ParamTypes>
class PolymorphicMatcher {
public:
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T>
operator Matcher<T>() const {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(new MatcherT<T>());
}
};
template <template <typename T, typename P1> class MatcherT,
typename P1,
typename ReturnTypesF = void(AllNodeBaseTypes)>
class PolymorphicMatcherWithParam1 {
public:
explicit PolymorphicMatcherWithParam1(const P1 &Param1)
: Param1(Param1) {}
PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
@ -1531,33 +1527,11 @@ public:
operator Matcher<T>() const {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1>(Param1));
return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
}
private:
const P1 Param1;
};
template <template <typename T, typename P1, typename P2> class MatcherT,
typename P1, typename P2,
typename ReturnTypesF = void(AllNodeBaseTypes)>
class PolymorphicMatcherWithParam2 {
public:
PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
: Param1(Param1), Param2(Param2) {}
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T>
operator Matcher<T>() const {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
}
private:
const P1 Param1;
const P2 Param2;
const std::tuple<ParamTypes...> Params;
};
/// Matches nodes of type T that have child nodes of type ChildT for
@ -2174,7 +2148,7 @@ inline Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
/// Matches overloaded operators with a specific name.
///
/// The type argument ArgT is not used by this matcher but is used by
/// PolymorphicMatcherWithParam1 and should be std::vector<std::string>>.
/// PolymorphicMatcher and should be std::vector<std::string>>.
template <typename T, typename ArgT = std::vector<std::string>>
class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
static_assert(std::is_same<T, BinaryOperator>::value ||
@ -2223,16 +2197,19 @@ private:
const std::vector<std::string> Names;
};
using HasOpNameMatcher = PolymorphicMatcherWithParam1<
HasAnyOperatorNameMatcher, std::vector<std::string>,
void(TypeList<BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, UnaryOperator>)>;
using HasOpNameMatcher =
PolymorphicMatcher<HasAnyOperatorNameMatcher,
void(
TypeList<BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, UnaryOperator>),
std::vector<std::string>>;
HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
using HasOverloadOpNameMatcher = PolymorphicMatcherWithParam1<
HasOverloadedOperatorNameMatcher, std::vector<std::string>,
void(TypeList<CXXOperatorCallExpr, FunctionDecl>)>;
using HasOverloadOpNameMatcher =
PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
std::vector<std::string>>;
HasOverloadOpNameMatcher
hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);

View file

@ -239,10 +239,10 @@
*Builder) const override; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
DefineMatcher() { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
return ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
} \
template <typename NodeType> \
@ -284,18 +284,17 @@
ParamType const Param; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF> \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType> \
DefineMatcher(ParamType const &Param) { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF>(Param); \
return ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType>(Param); \
} \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
ParamType const &Param); \
typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
template <typename NodeType, typename ParamT> \
bool internal:: \
matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
@ -338,17 +337,17 @@
ParamType2 const Param2; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF> \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType1, ParamType2> \
DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF>(Param1, Param2); \
return ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType1, ParamType2>(Param1, Param2); \
} \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)( \
ParamType1 const &Param1, ParamType2 const &Param2); \
template <typename NodeType, typename ParamT1, typename ParamT2> \
bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
@ -525,31 +524,31 @@
std::shared_ptr<llvm::Regex> const Param; \
}; \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, \
std::shared_ptr<llvm::Regex>, ReturnTypesF> \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
std::shared_ptr<llvm::Regex>> \
DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, \
std::shared_ptr<llvm::Regex>, ReturnTypesF>( \
return ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
std::shared_ptr<llvm::Regex>>( \
::clang::ast_matchers::internal::createAndVerifyRegex( \
Param, RegexFlags, #DefineMatcher)); \
} \
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, \
std::shared_ptr<llvm::Regex>, ReturnTypesF> \
inline ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
std::shared_ptr<llvm::Regex>> \
DefineMatcher(llvm::StringRef Param) { \
return DefineMatcher(Param, llvm::Regex::NoFlags); \
} \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, \
std::shared_ptr<llvm::Regex>, ReturnTypesF> ( \
typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
std::shared_ptr<llvm::Regex>> ( \
&DefineMatcher##_Type##OverloadId##Flags)( \
llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags); \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, \
std::shared_ptr<llvm::Regex>, ReturnTypesF> ( \
&DefineMatcher##_Type##OverloadId)(llvm::StringRef Param); \
typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \
std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)( \
llvm::StringRef Param); \
template <typename NodeType, typename ParamT> \
bool internal:: \
matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \