Skip to content

Commit 243cd0a

Browse files
committed
[ASTMatchers] Make Param functors variadic
Differential Revision: https://reviews.llvm.org/D97156
1 parent 1a4990a commit 243cd0a

File tree

4 files changed

+115
-141
lines changed

4 files changed

+115
-141
lines changed

clang/docs/tools/dump_ast_matchers.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,17 @@ def act_on_decl(declaration, comment, allowed_types):
351351

352352
m = re.match(
353353
r"""^.*internal::VariadicFunction\s*<\s*
354-
internal::PolymorphicMatcherWithParam1<[\S\s]+
355-
AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)>,\s*([^,]+),
356-
\s*[^>]+>\s*([a-zA-Z]*);$""",
354+
internal::PolymorphicMatcher<[\S\s]+
355+
AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\),\s*(.*);$""",
357356
declaration, flags=re.X)
358357

359358
if m:
360-
results, arg, name = m.groups()[:3]
359+
results, trailing = m.groups()
360+
trailing, name = trailing.rsplit(">", 1)
361+
name = name.strip()
362+
trailing, _ = trailing.rsplit(",", 1)
363+
_, arg = trailing.rsplit(",", 1)
364+
arg = arg.strip()
361365

362366
result_types = [r.strip() for r in results.split(',')]
363367
for result_type in result_types:

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -835,26 +835,16 @@ traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor<
835835
ToTypes>>(TK, InnerMatcher);
836836
}
837837

838-
template <template <typename T, typename P1> class MatcherT, typename P1,
838+
template <template <typename T, typename... P> class MatcherT, typename... P,
839839
typename ReturnTypesF>
840840
internal::TraversalWrapper<
841-
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>
842-
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam1<
843-
MatcherT, P1, ReturnTypesF> &InnerMatcher) {
844-
return internal::TraversalWrapper<
845-
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>(
846-
TK, InnerMatcher);
847-
}
848-
849-
template <template <typename T, typename P1, typename P2> class MatcherT,
850-
typename P1, typename P2, typename ReturnTypesF>
851-
internal::TraversalWrapper<
852-
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>
853-
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam2<
854-
MatcherT, P1, P2, ReturnTypesF> &InnerMatcher) {
841+
internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>
842+
traverse(TraversalKind TK,
843+
const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>
844+
&InnerMatcher) {
855845
return internal::TraversalWrapper<
856-
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>(
857-
TK, InnerMatcher);
846+
internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>(TK,
847+
InnerMatcher);
858848
}
859849

860850
template <typename... T>
@@ -2996,14 +2986,15 @@ AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) {
29962986
/// matches the declaration of \c A.
29972987
///
29982988
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
2999-
inline internal::PolymorphicMatcherWithParam1<
3000-
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
3001-
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
2989+
inline internal::PolymorphicMatcher<
2990+
internal::HasOverloadedOperatorNameMatcher,
2991+
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
2992+
std::vector<std::string>>
30022993
hasOverloadedOperatorName(StringRef Name) {
3003-
return internal::PolymorphicMatcherWithParam1<
3004-
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
3005-
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(
3006-
{std::string(Name)});
2994+
return internal::PolymorphicMatcher<
2995+
internal::HasOverloadedOperatorNameMatcher,
2996+
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
2997+
std::vector<std::string>>({std::string(Name)});
30072998
}
30082999

30093000
/// Matches overloaded operator names.
@@ -3015,9 +3006,10 @@ hasOverloadedOperatorName(StringRef Name) {
30153006
/// Is equivalent to
30163007
/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
30173008
extern const internal::VariadicFunction<
3018-
internal::PolymorphicMatcherWithParam1<
3019-
internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
3020-
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>,
3009+
internal::PolymorphicMatcher<internal::HasOverloadedOperatorNameMatcher,
3010+
AST_POLYMORPHIC_SUPPORTED_TYPES(
3011+
CXXOperatorCallExpr, FunctionDecl),
3012+
std::vector<std::string>>,
30213013
StringRef, internal::hasAnyOverloadedOperatorNameFunc>
30223014
hasAnyOverloadedOperatorName;
30233015

@@ -3506,13 +3498,14 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
35063498
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
35073499
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
35083500
/// Matcher<UnresolvedUsingType>
3509-
inline internal::PolymorphicMatcherWithParam1<
3510-
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
3511-
void(internal::HasDeclarationSupportedTypes)>
3501+
inline internal::PolymorphicMatcher<
3502+
internal::HasDeclarationMatcher,
3503+
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
35123504
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
3513-
return internal::PolymorphicMatcherWithParam1<
3514-
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
3515-
void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
3505+
return internal::PolymorphicMatcher<
3506+
internal::HasDeclarationMatcher,
3507+
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>(
3508+
InnerMatcher);
35163509
}
35173510

35183511
/// Matches a \c NamedDecl whose underlying declaration matches the given
@@ -5299,11 +5292,12 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
52995292
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
53005293
/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
53015294
template <typename ValueT>
5302-
internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
5295+
internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
5296+
void(internal::AllNodeBaseTypes), ValueT>
53035297
equals(const ValueT &Value) {
5304-
return internal::PolymorphicMatcherWithParam1<
5305-
internal::ValueEqualsMatcher,
5306-
ValueT>(Value);
5298+
return internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
5299+
void(internal::AllNodeBaseTypes), ValueT>(
5300+
Value);
53075301
}
53085302

53095303
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
@@ -5358,11 +5352,11 @@ AST_POLYMORPHIC_MATCHER_P(
53585352
/// Is equivalent to
53595353
/// anyOf(hasOperatorName("+"), hasOperatorName("-"))
53605354
extern const internal::VariadicFunction<
5361-
internal::PolymorphicMatcherWithParam1<
5362-
internal::HasAnyOperatorNameMatcher, std::vector<std::string>,
5363-
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
5364-
CXXRewrittenBinaryOperator,
5365-
UnaryOperator)>,
5355+
internal::PolymorphicMatcher<internal::HasAnyOperatorNameMatcher,
5356+
AST_POLYMORPHIC_SUPPORTED_TYPES(
5357+
BinaryOperator, CXXOperatorCallExpr,
5358+
CXXRewrittenBinaryOperator, UnaryOperator),
5359+
std::vector<std::string>>,
53665360
StringRef, internal::hasAnyOperatorNameFunc>
53675361
hasAnyOperatorName;
53685362

clang/include/clang/ASTMatchers/ASTMatchersInternal.h

Lines changed: 35 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ class has_getDecl {
836836
/// Matches overloaded operators with a specific name.
837837
///
838838
/// The type argument ArgT is not used by this matcher but is used by
839-
/// PolymorphicMatcherWithParam1 and should be StringRef.
839+
/// PolymorphicMatcher and should be StringRef.
840840
template <typename T, typename ArgT>
841841
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
842842
static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
@@ -919,7 +919,7 @@ Matcher<ObjCMessageExpr> hasAnySelectorFunc(
919919

920920
/// Matches declarations for QualType and CallExpr.
921921
///
922-
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
922+
/// Type argument DeclMatcherT is required by PolymorphicMatcher but
923923
/// not actually used.
924924
template <typename T, typename DeclMatcherT>
925925
class HasDeclarationMatcher : public MatcherInterface<T> {
@@ -1157,6 +1157,18 @@ template <class T> struct ExtractFunctionArgMeta<void(T)> {
11571157
using type = T;
11581158
};
11591159

1160+
template <class T, class Tuple, std::size_t... I>
1161+
constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
1162+
return new T(std::get<I>(std::forward<Tuple>(t))...);
1163+
}
1164+
1165+
template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
1166+
return new_from_tuple_impl<T>(
1167+
std::forward<Tuple>(t),
1168+
std::make_index_sequence<
1169+
std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
1170+
}
1171+
11601172
/// Default type lists for ArgumentAdaptingMatcher matchers.
11611173
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
11621174
using AdaptativeDefaultToTypes =
@@ -1426,7 +1438,7 @@ class ArgumentAdaptingMatcherFuncAdaptor {
14261438
/// \c HasMatcher<To, T>(InnerMatcher).
14271439
///
14281440
/// If a matcher does not need knowledge about the inner type, prefer to use
1429-
/// PolymorphicMatcherWithParam1.
1441+
/// PolymorphicMatcher.
14301442
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
14311443
typename FromTypes = AdaptativeDefaultFromTypes,
14321444
typename ToTypes = AdaptativeDefaultToTypes>
@@ -1491,73 +1503,35 @@ template <typename MatcherType> class TraversalWrapper {
14911503
MatcherType InnerMatcher;
14921504
};
14931505

1494-
/// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
1506+
/// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
14951507
/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
14961508
/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
14971509
/// can be constructed.
14981510
///
14991511
/// For example:
1500-
/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>()
1512+
/// - PolymorphicMatcher<IsDefinitionMatcher>()
15011513
/// creates an object that can be used as a Matcher<T> for any type T
15021514
/// where an IsDefinitionMatcher<T>() can be constructed.
1503-
/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42)
1515+
/// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
15041516
/// creates an object that can be used as a Matcher<T> for any type T
15051517
/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
1506-
template <template <typename T> class MatcherT,
1507-
typename ReturnTypesF = void(AllNodeBaseTypes)>
1508-
class PolymorphicMatcherWithParam0 {
1509-
public:
1510-
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1511-
1512-
template <typename T>
1513-
operator Matcher<T>() const {
1514-
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1515-
"right polymorphic conversion");
1516-
return Matcher<T>(new MatcherT<T>());
1517-
}
1518-
};
1519-
1520-
template <template <typename T, typename P1> class MatcherT,
1521-
typename P1,
1522-
typename ReturnTypesF = void(AllNodeBaseTypes)>
1523-
class PolymorphicMatcherWithParam1 {
1524-
public:
1525-
explicit PolymorphicMatcherWithParam1(const P1 &Param1)
1526-
: Param1(Param1) {}
1527-
1528-
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1529-
1530-
template <typename T>
1531-
operator Matcher<T>() const {
1532-
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1533-
"right polymorphic conversion");
1534-
return Matcher<T>(new MatcherT<T, P1>(Param1));
1535-
}
1536-
1537-
private:
1538-
const P1 Param1;
1539-
};
1540-
1541-
template <template <typename T, typename P1, typename P2> class MatcherT,
1542-
typename P1, typename P2,
1543-
typename ReturnTypesF = void(AllNodeBaseTypes)>
1544-
class PolymorphicMatcherWithParam2 {
1518+
template <template <typename T, typename... Params> class MatcherT,
1519+
typename ReturnTypesF, typename... ParamTypes>
1520+
class PolymorphicMatcher {
15451521
public:
1546-
PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
1547-
: Param1(Param1), Param2(Param2) {}
1522+
PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
15481523

15491524
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
15501525

15511526
template <typename T>
15521527
operator Matcher<T>() const {
15531528
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
15541529
"right polymorphic conversion");
1555-
return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
1530+
return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
15561531
}
15571532

15581533
private:
1559-
const P1 Param1;
1560-
const P2 Param2;
1534+
const std::tuple<ParamTypes...> Params;
15611535
};
15621536

15631537
/// Matches nodes of type T that have child nodes of type ChildT for
@@ -2174,7 +2148,7 @@ inline Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
21742148
/// Matches overloaded operators with a specific name.
21752149
///
21762150
/// The type argument ArgT is not used by this matcher but is used by
2177-
/// PolymorphicMatcherWithParam1 and should be std::vector<std::string>>.
2151+
/// PolymorphicMatcher and should be std::vector<std::string>>.
21782152
template <typename T, typename ArgT = std::vector<std::string>>
21792153
class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
21802154
static_assert(std::is_same<T, BinaryOperator>::value ||
@@ -2223,16 +2197,19 @@ class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
22232197
const std::vector<std::string> Names;
22242198
};
22252199

2226-
using HasOpNameMatcher = PolymorphicMatcherWithParam1<
2227-
HasAnyOperatorNameMatcher, std::vector<std::string>,
2228-
void(TypeList<BinaryOperator, CXXOperatorCallExpr,
2229-
CXXRewrittenBinaryOperator, UnaryOperator>)>;
2200+
using HasOpNameMatcher =
2201+
PolymorphicMatcher<HasAnyOperatorNameMatcher,
2202+
void(
2203+
TypeList<BinaryOperator, CXXOperatorCallExpr,
2204+
CXXRewrittenBinaryOperator, UnaryOperator>),
2205+
std::vector<std::string>>;
22302206

22312207
HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
22322208

2233-
using HasOverloadOpNameMatcher = PolymorphicMatcherWithParam1<
2234-
HasOverloadedOperatorNameMatcher, std::vector<std::string>,
2235-
void(TypeList<CXXOperatorCallExpr, FunctionDecl>)>;
2209+
using HasOverloadOpNameMatcher =
2210+
PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
2211+
void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
2212+
std::vector<std::string>>;
22362213

22372214
HasOverloadOpNameMatcher
22382215
hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);

0 commit comments

Comments
 (0)