Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h
35291 views
1
//===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
/// \file
10
/// Functions templates and classes to wrap matcher construct functions.
11
///
12
/// A collection of template function and classes that provide a generic
13
/// marshalling layer on top of matcher construct functions.
14
/// These are used by the registry to export all marshaller constructors with
15
/// the same generic interface.
16
//
17
//===----------------------------------------------------------------------===//
18
19
#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
20
#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
21
22
#include "clang/AST/ASTTypeTraits.h"
23
#include "clang/AST/OperationKinds.h"
24
#include "clang/ASTMatchers/ASTMatchersInternal.h"
25
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
26
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
27
#include "clang/Basic/AttrKinds.h"
28
#include "clang/Basic/LLVM.h"
29
#include "clang/Basic/OpenMPKinds.h"
30
#include "clang/Basic/TypeTraits.h"
31
#include "llvm/ADT/ArrayRef.h"
32
#include "llvm/ADT/STLExtras.h"
33
#include "llvm/ADT/StringRef.h"
34
#include "llvm/ADT/StringSwitch.h"
35
#include "llvm/ADT/Twine.h"
36
#include "llvm/Support/Regex.h"
37
#include <cassert>
38
#include <cstddef>
39
#include <iterator>
40
#include <limits>
41
#include <memory>
42
#include <optional>
43
#include <string>
44
#include <utility>
45
#include <vector>
46
47
namespace clang {
48
namespace ast_matchers {
49
namespace dynamic {
50
namespace internal {
51
52
/// Helper template class to just from argument type to the right is/get
53
/// functions in VariantValue.
54
/// Used to verify and extract the matcher arguments below.
55
template <class T> struct ArgTypeTraits;
56
template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
57
};
58
59
template <> struct ArgTypeTraits<std::string> {
60
static bool hasCorrectType(const VariantValue &Value) {
61
return Value.isString();
62
}
63
static bool hasCorrectValue(const VariantValue &Value) { return true; }
64
65
static const std::string &get(const VariantValue &Value) {
66
return Value.getString();
67
}
68
69
static ArgKind getKind() {
70
return ArgKind(ArgKind::AK_String);
71
}
72
73
static std::optional<std::string> getBestGuess(const VariantValue &) {
74
return std::nullopt;
75
}
76
};
77
78
template <>
79
struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
80
};
81
82
template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
83
static bool hasCorrectType(const VariantValue& Value) {
84
return Value.isMatcher();
85
}
86
static bool hasCorrectValue(const VariantValue &Value) {
87
return Value.getMatcher().hasTypedMatcher<T>();
88
}
89
90
static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
91
return Value.getMatcher().getTypedMatcher<T>();
92
}
93
94
static ArgKind getKind() {
95
return ArgKind::MakeMatcherArg(ASTNodeKind::getFromNodeKind<T>());
96
}
97
98
static std::optional<std::string> getBestGuess(const VariantValue &) {
99
return std::nullopt;
100
}
101
};
102
103
template <> struct ArgTypeTraits<bool> {
104
static bool hasCorrectType(const VariantValue &Value) {
105
return Value.isBoolean();
106
}
107
static bool hasCorrectValue(const VariantValue &Value) { return true; }
108
109
static bool get(const VariantValue &Value) {
110
return Value.getBoolean();
111
}
112
113
static ArgKind getKind() {
114
return ArgKind(ArgKind::AK_Boolean);
115
}
116
117
static std::optional<std::string> getBestGuess(const VariantValue &) {
118
return std::nullopt;
119
}
120
};
121
122
template <> struct ArgTypeTraits<double> {
123
static bool hasCorrectType(const VariantValue &Value) {
124
return Value.isDouble();
125
}
126
static bool hasCorrectValue(const VariantValue &Value) { return true; }
127
128
static double get(const VariantValue &Value) {
129
return Value.getDouble();
130
}
131
132
static ArgKind getKind() {
133
return ArgKind(ArgKind::AK_Double);
134
}
135
136
static std::optional<std::string> getBestGuess(const VariantValue &) {
137
return std::nullopt;
138
}
139
};
140
141
template <> struct ArgTypeTraits<unsigned> {
142
static bool hasCorrectType(const VariantValue &Value) {
143
return Value.isUnsigned();
144
}
145
static bool hasCorrectValue(const VariantValue &Value) { return true; }
146
147
static unsigned get(const VariantValue &Value) {
148
return Value.getUnsigned();
149
}
150
151
static ArgKind getKind() {
152
return ArgKind(ArgKind::AK_Unsigned);
153
}
154
155
static std::optional<std::string> getBestGuess(const VariantValue &) {
156
return std::nullopt;
157
}
158
};
159
160
template <> struct ArgTypeTraits<attr::Kind> {
161
private:
162
static std::optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {
163
if (!AttrKind.consume_front("attr::"))
164
return std::nullopt;
165
return llvm::StringSwitch<std::optional<attr::Kind>>(AttrKind)
166
#define ATTR(X) .Case(#X, attr::X)
167
#include "clang/Basic/AttrList.inc"
168
.Default(std::nullopt);
169
}
170
171
public:
172
static bool hasCorrectType(const VariantValue &Value) {
173
return Value.isString();
174
}
175
static bool hasCorrectValue(const VariantValue& Value) {
176
return getAttrKind(Value.getString()).has_value();
177
}
178
179
static attr::Kind get(const VariantValue &Value) {
180
return *getAttrKind(Value.getString());
181
}
182
183
static ArgKind getKind() {
184
return ArgKind(ArgKind::AK_String);
185
}
186
187
static std::optional<std::string> getBestGuess(const VariantValue &Value);
188
};
189
190
template <> struct ArgTypeTraits<CastKind> {
191
private:
192
static std::optional<CastKind> getCastKind(llvm::StringRef AttrKind) {
193
if (!AttrKind.consume_front("CK_"))
194
return std::nullopt;
195
return llvm::StringSwitch<std::optional<CastKind>>(AttrKind)
196
#define CAST_OPERATION(Name) .Case(#Name, CK_##Name)
197
#include "clang/AST/OperationKinds.def"
198
.Default(std::nullopt);
199
}
200
201
public:
202
static bool hasCorrectType(const VariantValue &Value) {
203
return Value.isString();
204
}
205
static bool hasCorrectValue(const VariantValue& Value) {
206
return getCastKind(Value.getString()).has_value();
207
}
208
209
static CastKind get(const VariantValue &Value) {
210
return *getCastKind(Value.getString());
211
}
212
213
static ArgKind getKind() {
214
return ArgKind(ArgKind::AK_String);
215
}
216
217
static std::optional<std::string> getBestGuess(const VariantValue &Value);
218
};
219
220
template <> struct ArgTypeTraits<llvm::Regex::RegexFlags> {
221
private:
222
static std::optional<llvm::Regex::RegexFlags> getFlags(llvm::StringRef Flags);
223
224
public:
225
static bool hasCorrectType(const VariantValue &Value) {
226
return Value.isString();
227
}
228
static bool hasCorrectValue(const VariantValue& Value) {
229
return getFlags(Value.getString()).has_value();
230
}
231
232
static llvm::Regex::RegexFlags get(const VariantValue &Value) {
233
return *getFlags(Value.getString());
234
}
235
236
static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
237
238
static std::optional<std::string> getBestGuess(const VariantValue &Value);
239
};
240
241
template <> struct ArgTypeTraits<OpenMPClauseKind> {
242
private:
243
static std::optional<OpenMPClauseKind>
244
getClauseKind(llvm::StringRef ClauseKind) {
245
return llvm::StringSwitch<std::optional<OpenMPClauseKind>>(ClauseKind)
246
#define GEN_CLANG_CLAUSE_CLASS
247
#define CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum)
248
#include "llvm/Frontend/OpenMP/OMP.inc"
249
.Default(std::nullopt);
250
}
251
252
public:
253
static bool hasCorrectType(const VariantValue &Value) {
254
return Value.isString();
255
}
256
static bool hasCorrectValue(const VariantValue& Value) {
257
return getClauseKind(Value.getString()).has_value();
258
}
259
260
static OpenMPClauseKind get(const VariantValue &Value) {
261
return *getClauseKind(Value.getString());
262
}
263
264
static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
265
266
static std::optional<std::string> getBestGuess(const VariantValue &Value);
267
};
268
269
template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> {
270
private:
271
static std::optional<UnaryExprOrTypeTrait>
272
getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) {
273
if (!ClauseKind.consume_front("UETT_"))
274
return std::nullopt;
275
return llvm::StringSwitch<std::optional<UnaryExprOrTypeTrait>>(ClauseKind)
276
#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name)
277
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \
278
.Case(#Name, UETT_##Name)
279
#include "clang/Basic/TokenKinds.def"
280
.Default(std::nullopt);
281
}
282
283
public:
284
static bool hasCorrectType(const VariantValue &Value) {
285
return Value.isString();
286
}
287
static bool hasCorrectValue(const VariantValue& Value) {
288
return getUnaryOrTypeTraitKind(Value.getString()).has_value();
289
}
290
291
static UnaryExprOrTypeTrait get(const VariantValue &Value) {
292
return *getUnaryOrTypeTraitKind(Value.getString());
293
}
294
295
static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
296
297
static std::optional<std::string> getBestGuess(const VariantValue &Value);
298
};
299
300
/// Matcher descriptor interface.
301
///
302
/// Provides a \c create() method that constructs the matcher from the provided
303
/// arguments, and various other methods for type introspection.
304
class MatcherDescriptor {
305
public:
306
virtual ~MatcherDescriptor() = default;
307
308
virtual VariantMatcher create(SourceRange NameRange,
309
ArrayRef<ParserValue> Args,
310
Diagnostics *Error) const = 0;
311
312
virtual ASTNodeKind nodeMatcherType() const { return ASTNodeKind(); }
313
314
virtual bool isBuilderMatcher() const { return false; }
315
316
virtual std::unique_ptr<MatcherDescriptor>
317
buildMatcherCtor(SourceRange NameRange, ArrayRef<ParserValue> Args,
318
Diagnostics *Error) const {
319
return {};
320
}
321
322
/// Returns whether the matcher is variadic. Variadic matchers can take any
323
/// number of arguments, but they must be of the same type.
324
virtual bool isVariadic() const = 0;
325
326
/// Returns the number of arguments accepted by the matcher if not variadic.
327
virtual unsigned getNumArgs() const = 0;
328
329
/// Given that the matcher is being converted to type \p ThisKind, append the
330
/// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
331
// FIXME: We should provide the ability to constrain the output of this
332
// function based on the types of other matcher arguments.
333
virtual void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
334
std::vector<ArgKind> &ArgKinds) const = 0;
335
336
/// Returns whether this matcher is convertible to the given type. If it is
337
/// so convertible, store in *Specificity a value corresponding to the
338
/// "specificity" of the converted matcher to the given context, and in
339
/// *LeastDerivedKind the least derived matcher kind which would result in the
340
/// same matcher overload. Zero specificity indicates that this conversion
341
/// would produce a trivial matcher that will either always or never match.
342
/// Such matchers are excluded from code completion results.
343
virtual bool
344
isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,
345
ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
346
347
/// Returns whether the matcher will, given a matcher of any type T, yield a
348
/// matcher of type T.
349
virtual bool isPolymorphic() const { return false; }
350
};
351
352
inline bool isRetKindConvertibleTo(ArrayRef<ASTNodeKind> RetKinds,
353
ASTNodeKind Kind, unsigned *Specificity,
354
ASTNodeKind *LeastDerivedKind) {
355
for (const ASTNodeKind &NodeKind : RetKinds) {
356
if (ArgKind::MakeMatcherArg(NodeKind).isConvertibleTo(
357
ArgKind::MakeMatcherArg(Kind), Specificity)) {
358
if (LeastDerivedKind)
359
*LeastDerivedKind = NodeKind;
360
return true;
361
}
362
}
363
return false;
364
}
365
366
/// Simple callback implementation. Marshaller and function are provided.
367
///
368
/// This class wraps a function of arbitrary signature and a marshaller
369
/// function into a MatcherDescriptor.
370
/// The marshaller is in charge of taking the VariantValue arguments, checking
371
/// their types, unpacking them and calling the underlying function.
372
class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
373
public:
374
using MarshallerType = VariantMatcher (*)(void (*Func)(),
375
StringRef MatcherName,
376
SourceRange NameRange,
377
ArrayRef<ParserValue> Args,
378
Diagnostics *Error);
379
380
/// \param Marshaller Function to unpack the arguments and call \c Func
381
/// \param Func Matcher construct function. This is the function that
382
/// compile-time matcher expressions would use to create the matcher.
383
/// \param RetKinds The list of matcher types to which the matcher is
384
/// convertible.
385
/// \param ArgKinds The types of the arguments this matcher takes.
386
FixedArgCountMatcherDescriptor(MarshallerType Marshaller, void (*Func)(),
387
StringRef MatcherName,
388
ArrayRef<ASTNodeKind> RetKinds,
389
ArrayRef<ArgKind> ArgKinds)
390
: Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
391
RetKinds(RetKinds.begin(), RetKinds.end()),
392
ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
393
394
VariantMatcher create(SourceRange NameRange,
395
ArrayRef<ParserValue> Args,
396
Diagnostics *Error) const override {
397
return Marshaller(Func, MatcherName, NameRange, Args, Error);
398
}
399
400
bool isVariadic() const override { return false; }
401
unsigned getNumArgs() const override { return ArgKinds.size(); }
402
403
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
404
std::vector<ArgKind> &Kinds) const override {
405
Kinds.push_back(ArgKinds[ArgNo]);
406
}
407
408
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
409
ASTNodeKind *LeastDerivedKind) const override {
410
return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
411
LeastDerivedKind);
412
}
413
414
private:
415
const MarshallerType Marshaller;
416
void (* const Func)();
417
const std::string MatcherName;
418
const std::vector<ASTNodeKind> RetKinds;
419
const std::vector<ArgKind> ArgKinds;
420
};
421
422
/// Helper methods to extract and merge all possible typed matchers
423
/// out of the polymorphic object.
424
template <class PolyMatcher>
425
static void mergePolyMatchers(const PolyMatcher &Poly,
426
std::vector<DynTypedMatcher> &Out,
427
ast_matchers::internal::EmptyTypeList) {}
428
429
template <class PolyMatcher, class TypeList>
430
static void mergePolyMatchers(const PolyMatcher &Poly,
431
std::vector<DynTypedMatcher> &Out, TypeList) {
432
Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
433
mergePolyMatchers(Poly, Out, typename TypeList::tail());
434
}
435
436
/// Convert the return values of the functions into a VariantMatcher.
437
///
438
/// There are 2 cases right now: The return value is a Matcher<T> or is a
439
/// polymorphic matcher. For the former, we just construct the VariantMatcher.
440
/// For the latter, we instantiate all the possible Matcher<T> of the poly
441
/// matcher.
442
inline VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
443
return VariantMatcher::SingleMatcher(Matcher);
444
}
445
446
template <typename T>
447
static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
448
typename T::ReturnTypes * =
449
nullptr) {
450
std::vector<DynTypedMatcher> Matchers;
451
mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
452
VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
453
return Out;
454
}
455
456
template <typename T>
457
inline void
458
buildReturnTypeVectorFromTypeList(std::vector<ASTNodeKind> &RetTypes) {
459
RetTypes.push_back(ASTNodeKind::getFromNodeKind<typename T::head>());
460
buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
461
}
462
463
template <>
464
inline void
465
buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
466
std::vector<ASTNodeKind> &RetTypes) {}
467
468
template <typename T>
469
struct BuildReturnTypeVector {
470
static void build(std::vector<ASTNodeKind> &RetTypes) {
471
buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
472
}
473
};
474
475
template <typename T>
476
struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
477
static void build(std::vector<ASTNodeKind> &RetTypes) {
478
RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());
479
}
480
};
481
482
template <typename T>
483
struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
484
static void build(std::vector<ASTNodeKind> &RetTypes) {
485
RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());
486
}
487
};
488
489
/// Variadic marshaller function.
490
template <typename ResultT, typename ArgT,
491
ResultT (*Func)(ArrayRef<const ArgT *>)>
492
VariantMatcher
493
variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
494
ArrayRef<ParserValue> Args, Diagnostics *Error) {
495
SmallVector<ArgT *, 8> InnerArgsPtr;
496
InnerArgsPtr.resize_for_overwrite(Args.size());
497
SmallVector<ArgT, 8> InnerArgs;
498
InnerArgs.reserve(Args.size());
499
500
for (size_t i = 0, e = Args.size(); i != e; ++i) {
501
using ArgTraits = ArgTypeTraits<ArgT>;
502
503
const ParserValue &Arg = Args[i];
504
const VariantValue &Value = Arg.Value;
505
if (!ArgTraits::hasCorrectType(Value)) {
506
Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
507
<< (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
508
return {};
509
}
510
if (!ArgTraits::hasCorrectValue(Value)) {
511
if (std::optional<std::string> BestGuess =
512
ArgTraits::getBestGuess(Value)) {
513
Error->addError(Arg.Range, Error->ET_RegistryUnknownEnumWithReplace)
514
<< i + 1 << Value.getString() << *BestGuess;
515
} else if (Value.isString()) {
516
Error->addError(Arg.Range, Error->ET_RegistryValueNotFound)
517
<< Value.getString();
518
} else {
519
// This isn't ideal, but it's better than reporting an empty string as
520
// the error in this case.
521
Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
522
<< (i + 1) << ArgTraits::getKind().asString()
523
<< Value.getTypeAsString();
524
}
525
return {};
526
}
527
assert(InnerArgs.size() < InnerArgs.capacity());
528
InnerArgs.emplace_back(ArgTraits::get(Value));
529
InnerArgsPtr[i] = &InnerArgs[i];
530
}
531
return outvalueToVariantMatcher(Func(InnerArgsPtr));
532
}
533
534
/// Matcher descriptor for variadic functions.
535
///
536
/// This class simply wraps a VariadicFunction with the right signature to export
537
/// it as a MatcherDescriptor.
538
/// This allows us to have one implementation of the interface for as many free
539
/// functions as we want, reducing the number of symbols and size of the
540
/// object file.
541
class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
542
public:
543
using RunFunc = VariantMatcher (*)(StringRef MatcherName,
544
SourceRange NameRange,
545
ArrayRef<ParserValue> Args,
546
Diagnostics *Error);
547
548
template <typename ResultT, typename ArgT,
549
ResultT (*F)(ArrayRef<const ArgT *>)>
550
VariadicFuncMatcherDescriptor(
551
ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
552
StringRef MatcherName)
553
: Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
554
MatcherName(MatcherName.str()),
555
ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
556
BuildReturnTypeVector<ResultT>::build(RetKinds);
557
}
558
559
VariantMatcher create(SourceRange NameRange,
560
ArrayRef<ParserValue> Args,
561
Diagnostics *Error) const override {
562
return Func(MatcherName, NameRange, Args, Error);
563
}
564
565
bool isVariadic() const override { return true; }
566
unsigned getNumArgs() const override { return 0; }
567
568
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
569
std::vector<ArgKind> &Kinds) const override {
570
Kinds.push_back(ArgsKind);
571
}
572
573
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
574
ASTNodeKind *LeastDerivedKind) const override {
575
return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
576
LeastDerivedKind);
577
}
578
579
ASTNodeKind nodeMatcherType() const override { return RetKinds[0]; }
580
581
private:
582
const RunFunc Func;
583
const std::string MatcherName;
584
std::vector<ASTNodeKind> RetKinds;
585
const ArgKind ArgsKind;
586
};
587
588
/// Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
589
class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
590
public:
591
template <typename BaseT, typename DerivedT>
592
DynCastAllOfMatcherDescriptor(
593
ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
594
StringRef MatcherName)
595
: VariadicFuncMatcherDescriptor(Func, MatcherName),
596
DerivedKind(ASTNodeKind::getFromNodeKind<DerivedT>()) {}
597
598
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
599
ASTNodeKind *LeastDerivedKind) const override {
600
// If Kind is not a base of DerivedKind, either DerivedKind is a base of
601
// Kind (in which case the match will always succeed) or Kind and
602
// DerivedKind are unrelated (in which case it will always fail), so set
603
// Specificity to 0.
604
if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
605
LeastDerivedKind)) {
606
if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
607
if (Specificity)
608
*Specificity = 0;
609
}
610
return true;
611
} else {
612
return false;
613
}
614
}
615
616
ASTNodeKind nodeMatcherType() const override { return DerivedKind; }
617
618
private:
619
const ASTNodeKind DerivedKind;
620
};
621
622
/// Helper macros to check the arguments on all marshaller functions.
623
#define CHECK_ARG_COUNT(count) \
624
if (Args.size() != count) { \
625
Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
626
<< count << Args.size(); \
627
return VariantMatcher(); \
628
}
629
630
#define CHECK_ARG_TYPE(index, type) \
631
if (!ArgTypeTraits<type>::hasCorrectType(Args[index].Value)) { \
632
Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
633
<< (index + 1) << ArgTypeTraits<type>::getKind().asString() \
634
<< Args[index].Value.getTypeAsString(); \
635
return VariantMatcher(); \
636
} \
637
if (!ArgTypeTraits<type>::hasCorrectValue(Args[index].Value)) { \
638
if (std::optional<std::string> BestGuess = \
639
ArgTypeTraits<type>::getBestGuess(Args[index].Value)) { \
640
Error->addError(Args[index].Range, \
641
Error->ET_RegistryUnknownEnumWithReplace) \
642
<< index + 1 << Args[index].Value.getString() << *BestGuess; \
643
} else if (Args[index].Value.isString()) { \
644
Error->addError(Args[index].Range, Error->ET_RegistryValueNotFound) \
645
<< Args[index].Value.getString(); \
646
} \
647
return VariantMatcher(); \
648
}
649
650
/// 0-arg marshaller function.
651
template <typename ReturnType>
652
static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
653
SourceRange NameRange,
654
ArrayRef<ParserValue> Args,
655
Diagnostics *Error) {
656
using FuncType = ReturnType (*)();
657
CHECK_ARG_COUNT(0);
658
return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
659
}
660
661
/// 1-arg marshaller function.
662
template <typename ReturnType, typename ArgType1>
663
static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
664
SourceRange NameRange,
665
ArrayRef<ParserValue> Args,
666
Diagnostics *Error) {
667
using FuncType = ReturnType (*)(ArgType1);
668
CHECK_ARG_COUNT(1);
669
CHECK_ARG_TYPE(0, ArgType1);
670
return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
671
ArgTypeTraits<ArgType1>::get(Args[0].Value)));
672
}
673
674
/// 2-arg marshaller function.
675
template <typename ReturnType, typename ArgType1, typename ArgType2>
676
static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
677
SourceRange NameRange,
678
ArrayRef<ParserValue> Args,
679
Diagnostics *Error) {
680
using FuncType = ReturnType (*)(ArgType1, ArgType2);
681
CHECK_ARG_COUNT(2);
682
CHECK_ARG_TYPE(0, ArgType1);
683
CHECK_ARG_TYPE(1, ArgType2);
684
return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
685
ArgTypeTraits<ArgType1>::get(Args[0].Value),
686
ArgTypeTraits<ArgType2>::get(Args[1].Value)));
687
}
688
689
#undef CHECK_ARG_COUNT
690
#undef CHECK_ARG_TYPE
691
692
/// Helper class used to collect all the possible overloads of an
693
/// argument adaptative matcher function.
694
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
695
typename FromTypes, typename ToTypes>
696
class AdaptativeOverloadCollector {
697
public:
698
AdaptativeOverloadCollector(
699
StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
700
: Name(Name), Out(Out) {
701
collect(FromTypes());
702
}
703
704
private:
705
using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
706
ArgumentAdapterT, FromTypes, ToTypes>;
707
708
/// End case for the recursion
709
static void collect(ast_matchers::internal::EmptyTypeList) {}
710
711
/// Recursive case. Get the overload for the head of the list, and
712
/// recurse to the tail.
713
template <typename FromTypeList>
714
inline void collect(FromTypeList);
715
716
StringRef Name;
717
std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
718
};
719
720
/// MatcherDescriptor that wraps multiple "overloads" of the same
721
/// matcher.
722
///
723
/// It will try every overload and generate appropriate errors for when none or
724
/// more than one overloads match the arguments.
725
class OverloadedMatcherDescriptor : public MatcherDescriptor {
726
public:
727
OverloadedMatcherDescriptor(
728
MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
729
: Overloads(std::make_move_iterator(Callbacks.begin()),
730
std::make_move_iterator(Callbacks.end())) {}
731
732
~OverloadedMatcherDescriptor() override = default;
733
734
VariantMatcher create(SourceRange NameRange,
735
ArrayRef<ParserValue> Args,
736
Diagnostics *Error) const override {
737
std::vector<VariantMatcher> Constructed;
738
Diagnostics::OverloadContext Ctx(Error);
739
for (const auto &O : Overloads) {
740
VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
741
if (!SubMatcher.isNull()) {
742
Constructed.push_back(SubMatcher);
743
}
744
}
745
746
if (Constructed.empty()) return VariantMatcher(); // No overload matched.
747
// We ignore the errors if any matcher succeeded.
748
Ctx.revertErrors();
749
if (Constructed.size() > 1) {
750
// More than one constructed. It is ambiguous.
751
Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
752
return VariantMatcher();
753
}
754
return Constructed[0];
755
}
756
757
bool isVariadic() const override {
758
bool Overload0Variadic = Overloads[0]->isVariadic();
759
#ifndef NDEBUG
760
for (const auto &O : Overloads) {
761
assert(Overload0Variadic == O->isVariadic());
762
}
763
#endif
764
return Overload0Variadic;
765
}
766
767
unsigned getNumArgs() const override {
768
unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
769
#ifndef NDEBUG
770
for (const auto &O : Overloads) {
771
assert(Overload0NumArgs == O->getNumArgs());
772
}
773
#endif
774
return Overload0NumArgs;
775
}
776
777
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
778
std::vector<ArgKind> &Kinds) const override {
779
for (const auto &O : Overloads) {
780
if (O->isConvertibleTo(ThisKind))
781
O->getArgKinds(ThisKind, ArgNo, Kinds);
782
}
783
}
784
785
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
786
ASTNodeKind *LeastDerivedKind) const override {
787
for (const auto &O : Overloads) {
788
if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
789
return true;
790
}
791
return false;
792
}
793
794
private:
795
std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
796
};
797
798
template <typename ReturnType>
799
class RegexMatcherDescriptor : public MatcherDescriptor {
800
public:
801
RegexMatcherDescriptor(ReturnType (*WithFlags)(StringRef,
802
llvm::Regex::RegexFlags),
803
ReturnType (*NoFlags)(StringRef),
804
ArrayRef<ASTNodeKind> RetKinds)
805
: WithFlags(WithFlags), NoFlags(NoFlags),
806
RetKinds(RetKinds.begin(), RetKinds.end()) {}
807
bool isVariadic() const override { return true; }
808
unsigned getNumArgs() const override { return 0; }
809
810
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
811
std::vector<ArgKind> &Kinds) const override {
812
assert(ArgNo < 2);
813
Kinds.push_back(ArgKind::AK_String);
814
}
815
816
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
817
ASTNodeKind *LeastDerivedKind) const override {
818
return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
819
LeastDerivedKind);
820
}
821
822
VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args,
823
Diagnostics *Error) const override {
824
if (Args.size() < 1 || Args.size() > 2) {
825
Error->addError(NameRange, Diagnostics::ET_RegistryWrongArgCount)
826
<< "1 or 2" << Args.size();
827
return VariantMatcher();
828
}
829
if (!ArgTypeTraits<StringRef>::hasCorrectType(Args[0].Value)) {
830
Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType)
831
<< 1 << ArgTypeTraits<StringRef>::getKind().asString()
832
<< Args[0].Value.getTypeAsString();
833
return VariantMatcher();
834
}
835
if (Args.size() == 1) {
836
return outvalueToVariantMatcher(
837
NoFlags(ArgTypeTraits<StringRef>::get(Args[0].Value)));
838
}
839
if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType(
840
Args[1].Value)) {
841
Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType)
842
<< 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString()
843
<< Args[1].Value.getTypeAsString();
844
return VariantMatcher();
845
}
846
if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectValue(
847
Args[1].Value)) {
848
if (std::optional<std::string> BestGuess =
849
ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess(
850
Args[1].Value)) {
851
Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace)
852
<< 2 << Args[1].Value.getString() << *BestGuess;
853
} else {
854
Error->addError(Args[1].Range, Error->ET_RegistryValueNotFound)
855
<< Args[1].Value.getString();
856
}
857
return VariantMatcher();
858
}
859
return outvalueToVariantMatcher(
860
WithFlags(ArgTypeTraits<StringRef>::get(Args[0].Value),
861
ArgTypeTraits<llvm::Regex::RegexFlags>::get(Args[1].Value)));
862
}
863
864
private:
865
ReturnType (*const WithFlags)(StringRef, llvm::Regex::RegexFlags);
866
ReturnType (*const NoFlags)(StringRef);
867
const std::vector<ASTNodeKind> RetKinds;
868
};
869
870
/// Variadic operator marshaller function.
871
class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
872
public:
873
using VarOp = DynTypedMatcher::VariadicOperator;
874
875
VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
876
VarOp Op, StringRef MatcherName)
877
: MinCount(MinCount), MaxCount(MaxCount), Op(Op),
878
MatcherName(MatcherName) {}
879
880
VariantMatcher create(SourceRange NameRange,
881
ArrayRef<ParserValue> Args,
882
Diagnostics *Error) const override {
883
if (Args.size() < MinCount || MaxCount < Args.size()) {
884
const std::string MaxStr =
885
(MaxCount == std::numeric_limits<unsigned>::max() ? ""
886
: Twine(MaxCount))
887
.str();
888
Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
889
<< ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
890
return VariantMatcher();
891
}
892
893
std::vector<VariantMatcher> InnerArgs;
894
for (size_t i = 0, e = Args.size(); i != e; ++i) {
895
const ParserValue &Arg = Args[i];
896
const VariantValue &Value = Arg.Value;
897
if (!Value.isMatcher()) {
898
Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
899
<< (i + 1) << "Matcher<>" << Value.getTypeAsString();
900
return VariantMatcher();
901
}
902
InnerArgs.push_back(Value.getMatcher());
903
}
904
return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
905
}
906
907
bool isVariadic() const override { return true; }
908
unsigned getNumArgs() const override { return 0; }
909
910
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
911
std::vector<ArgKind> &Kinds) const override {
912
Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind));
913
}
914
915
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
916
ASTNodeKind *LeastDerivedKind) const override {
917
if (Specificity)
918
*Specificity = 1;
919
if (LeastDerivedKind)
920
*LeastDerivedKind = Kind;
921
return true;
922
}
923
924
bool isPolymorphic() const override { return true; }
925
926
private:
927
const unsigned MinCount;
928
const unsigned MaxCount;
929
const VarOp Op;
930
const StringRef MatcherName;
931
};
932
933
class MapAnyOfMatcherDescriptor : public MatcherDescriptor {
934
ASTNodeKind CladeNodeKind;
935
std::vector<ASTNodeKind> NodeKinds;
936
937
public:
938
MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind,
939
std::vector<ASTNodeKind> NodeKinds)
940
: CladeNodeKind(CladeNodeKind), NodeKinds(std::move(NodeKinds)) {}
941
942
VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args,
943
Diagnostics *Error) const override {
944
945
std::vector<DynTypedMatcher> NodeArgs;
946
947
for (auto NK : NodeKinds) {
948
std::vector<DynTypedMatcher> InnerArgs;
949
950
for (const auto &Arg : Args) {
951
if (!Arg.Value.isMatcher())
952
return {};
953
const VariantMatcher &VM = Arg.Value.getMatcher();
954
if (VM.hasTypedMatcher(NK)) {
955
auto DM = VM.getTypedMatcher(NK);
956
InnerArgs.push_back(DM);
957
}
958
}
959
960
if (InnerArgs.empty()) {
961
NodeArgs.push_back(
962
DynTypedMatcher::trueMatcher(NK).dynCastTo(CladeNodeKind));
963
} else {
964
NodeArgs.push_back(
965
DynTypedMatcher::constructVariadic(
966
ast_matchers::internal::DynTypedMatcher::VO_AllOf, NK,
967
InnerArgs)
968
.dynCastTo(CladeNodeKind));
969
}
970
}
971
972
auto Result = DynTypedMatcher::constructVariadic(
973
ast_matchers::internal::DynTypedMatcher::VO_AnyOf, CladeNodeKind,
974
NodeArgs);
975
Result.setAllowBind(true);
976
return VariantMatcher::SingleMatcher(Result);
977
}
978
979
bool isVariadic() const override { return true; }
980
unsigned getNumArgs() const override { return 0; }
981
982
void getArgKinds(ASTNodeKind ThisKind, unsigned,
983
std::vector<ArgKind> &Kinds) const override {
984
Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind));
985
}
986
987
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
988
ASTNodeKind *LeastDerivedKind) const override {
989
if (Specificity)
990
*Specificity = 1;
991
if (LeastDerivedKind)
992
*LeastDerivedKind = CladeNodeKind;
993
return true;
994
}
995
};
996
997
class MapAnyOfBuilderDescriptor : public MatcherDescriptor {
998
public:
999
VariantMatcher create(SourceRange, ArrayRef<ParserValue>,
1000
Diagnostics *) const override {
1001
return {};
1002
}
1003
1004
bool isBuilderMatcher() const override { return true; }
1005
1006
std::unique_ptr<MatcherDescriptor>
1007
buildMatcherCtor(SourceRange, ArrayRef<ParserValue> Args,
1008
Diagnostics *) const override {
1009
1010
std::vector<ASTNodeKind> NodeKinds;
1011
for (const auto &Arg : Args) {
1012
if (!Arg.Value.isNodeKind())
1013
return {};
1014
NodeKinds.push_back(Arg.Value.getNodeKind());
1015
}
1016
1017
if (NodeKinds.empty())
1018
return {};
1019
1020
ASTNodeKind CladeNodeKind = NodeKinds.front().getCladeKind();
1021
1022
for (auto NK : NodeKinds)
1023
{
1024
if (!NK.getCladeKind().isSame(CladeNodeKind))
1025
return {};
1026
}
1027
1028
return std::make_unique<MapAnyOfMatcherDescriptor>(CladeNodeKind,
1029
std::move(NodeKinds));
1030
}
1031
1032
bool isVariadic() const override { return true; }
1033
1034
unsigned getNumArgs() const override { return 0; }
1035
1036
void getArgKinds(ASTNodeKind ThisKind, unsigned,
1037
std::vector<ArgKind> &ArgKinds) const override {
1038
ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind));
1039
}
1040
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,
1041
ASTNodeKind *LeastDerivedKind = nullptr) const override {
1042
if (Specificity)
1043
*Specificity = 1;
1044
if (LeastDerivedKind)
1045
*LeastDerivedKind = Kind;
1046
return true;
1047
}
1048
1049
bool isPolymorphic() const override { return false; }
1050
};
1051
1052
/// Helper functions to select the appropriate marshaller functions.
1053
/// They detect the number of arguments, arguments types and return type.
1054
1055
/// 0-arg overload
1056
template <typename ReturnType>
1057
std::unique_ptr<MatcherDescriptor>
1058
makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
1059
std::vector<ASTNodeKind> RetTypes;
1060
BuildReturnTypeVector<ReturnType>::build(RetTypes);
1061
return std::make_unique<FixedArgCountMatcherDescriptor>(
1062
matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
1063
MatcherName, RetTypes, std::nullopt);
1064
}
1065
1066
/// 1-arg overload
1067
template <typename ReturnType, typename ArgType1>
1068
std::unique_ptr<MatcherDescriptor>
1069
makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
1070
std::vector<ASTNodeKind> RetTypes;
1071
BuildReturnTypeVector<ReturnType>::build(RetTypes);
1072
ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
1073
return std::make_unique<FixedArgCountMatcherDescriptor>(
1074
matcherMarshall1<ReturnType, ArgType1>,
1075
reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
1076
}
1077
1078
/// 2-arg overload
1079
template <typename ReturnType, typename ArgType1, typename ArgType2>
1080
std::unique_ptr<MatcherDescriptor>
1081
makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
1082
StringRef MatcherName) {
1083
std::vector<ASTNodeKind> RetTypes;
1084
BuildReturnTypeVector<ReturnType>::build(RetTypes);
1085
ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
1086
ArgTypeTraits<ArgType2>::getKind() };
1087
return std::make_unique<FixedArgCountMatcherDescriptor>(
1088
matcherMarshall2<ReturnType, ArgType1, ArgType2>,
1089
reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
1090
}
1091
1092
template <typename ReturnType>
1093
std::unique_ptr<MatcherDescriptor> makeMatcherRegexMarshall(
1094
ReturnType (*FuncFlags)(llvm::StringRef, llvm::Regex::RegexFlags),
1095
ReturnType (*Func)(llvm::StringRef)) {
1096
std::vector<ASTNodeKind> RetTypes;
1097
BuildReturnTypeVector<ReturnType>::build(RetTypes);
1098
return std::make_unique<RegexMatcherDescriptor<ReturnType>>(FuncFlags, Func,
1099
RetTypes);
1100
}
1101
1102
/// Variadic overload.
1103
template <typename ResultT, typename ArgT,
1104
ResultT (*Func)(ArrayRef<const ArgT *>)>
1105
std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
1106
ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
1107
StringRef MatcherName) {
1108
return std::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
1109
}
1110
1111
/// Overload for VariadicDynCastAllOfMatchers.
1112
///
1113
/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
1114
/// completion results for that type of matcher.
1115
template <typename BaseT, typename DerivedT>
1116
std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
1117
ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
1118
VarFunc,
1119
StringRef MatcherName) {
1120
return std::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
1121
}
1122
1123
/// Argument adaptative overload.
1124
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1125
typename FromTypes, typename ToTypes>
1126
std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
1127
ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
1128
FromTypes, ToTypes>,
1129
StringRef MatcherName) {
1130
std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
1131
AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
1132
Overloads);
1133
return std::make_unique<OverloadedMatcherDescriptor>(Overloads);
1134
}
1135
1136
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1137
typename FromTypes, typename ToTypes>
1138
template <typename FromTypeList>
1139
inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
1140
ToTypes>::collect(FromTypeList) {
1141
Out.push_back(makeMatcherAutoMarshall(
1142
&AdaptativeFunc::template create<typename FromTypeList::head>, Name));
1143
collect(typename FromTypeList::tail());
1144
}
1145
1146
/// Variadic operator overload.
1147
template <unsigned MinCount, unsigned MaxCount>
1148
std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
1149
ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
1150
Func,
1151
StringRef MatcherName) {
1152
return std::make_unique<VariadicOperatorMatcherDescriptor>(
1153
MinCount, MaxCount, Func.Op, MatcherName);
1154
}
1155
1156
template <typename CladeType, typename... MatcherT>
1157
std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
1158
ast_matchers::internal::MapAnyOfMatcherImpl<CladeType, MatcherT...>,
1159
StringRef MatcherName) {
1160
return std::make_unique<MapAnyOfMatcherDescriptor>(
1161
ASTNodeKind::getFromNodeKind<CladeType>(),
1162
std::vector<ASTNodeKind>{ASTNodeKind::getFromNodeKind<MatcherT>()...});
1163
}
1164
1165
} // namespace internal
1166
} // namespace dynamic
1167
} // namespace ast_matchers
1168
} // namespace clang
1169
1170
#endif // LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
1171
1172