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(MatcherKind: 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(Prefix: "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(Prefix: "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(Prefix: "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(Matchers: 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(Range: Arg.Range, Error: 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(Range: Arg.Range, Error: Error->ET_RegistryUnknownEnumWithReplace) |
514 | << i + 1 << Value.getString() << *BestGuess; |
515 | } else if (Value.isString()) { |
516 | Error->addError(Range: Arg.Range, Error: 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(Range: Arg.Range, Error: 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(Other: DerivedKind) || !Kind.isBaseOf(Other: 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(Range: NameRange, Error: 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(Range: NameRange, Error: Diagnostics::ET_RegistryWrongArgCount) |
826 | << "1 or 2" << Args.size(); |
827 | return VariantMatcher(); |
828 | } |
829 | if (!ArgTypeTraits<StringRef>::hasCorrectType(Value: Args[0].Value)) { |
830 | Error->addError(Range: Args[0].Range, Error: 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(Value: Args[0].Value))); |
838 | } |
839 | if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType( |
840 | Value: Args[1].Value)) { |
841 | Error->addError(Range: Args[1].Range, Error: 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 | Value: Args[1].Value)) { |
848 | if (std::optional<std::string> BestGuess = |
849 | ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess( |
850 | Value: Args[1].Value)) { |
851 | Error->addError(Range: Args[1].Range, Error: Error->ET_RegistryUnknownEnumWithReplace) |
852 | << 2 << Args[1].Value.getString() << *BestGuess; |
853 | } else { |
854 | Error->addError(Range: Args[1].Range, Error: Error->ET_RegistryValueNotFound) |
855 | << Args[1].Value.getString(); |
856 | } |
857 | return VariantMatcher(); |
858 | } |
859 | return outvalueToVariantMatcher( |
860 | WithFlags(ArgTypeTraits<StringRef>::get(Value: Args[0].Value), |
861 | ArgTypeTraits<llvm::Regex::RegexFlags>::get(Value: 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(Range: NameRange, Error: 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(Range: Arg.Range, Error: 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, Args: 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(MatcherKind: 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 | Op: ast_matchers::internal::DynTypedMatcher::VO_AnyOf, SupportedKind: CladeNodeKind, |
974 | InnerMatchers: NodeArgs); |
975 | Result.setAllowBind(true); |
976 | return VariantMatcher::SingleMatcher(Matcher: 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(MatcherKind: 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(MatcherKind: 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 | |