1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
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 "llvm/ADT/ArrayRef.h" |
31 | #include "llvm/ADT/None.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 <cassert> |
37 | #include <cstddef> |
38 | #include <iterator> |
39 | #include <limits> |
40 | #include <memory> |
41 | #include <string> |
42 | #include <utility> |
43 | #include <vector> |
44 | |
45 | namespace clang { |
46 | namespace ast_matchers { |
47 | namespace dynamic { |
48 | namespace internal { |
49 | |
50 | |
51 | |
52 | |
53 | template <class T> struct ArgTypeTraits; |
54 | template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { |
55 | }; |
56 | |
57 | template <> struct ArgTypeTraits<std::string> { |
58 | static bool is(const VariantValue &Value) { return Value.isString(); } |
59 | |
60 | static const std::string &get(const VariantValue &Value) { |
61 | return Value.getString(); |
62 | } |
63 | |
64 | static ArgKind getKind() { |
65 | return ArgKind(ArgKind::AK_String); |
66 | } |
67 | }; |
68 | |
69 | template <> |
70 | struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { |
71 | }; |
72 | |
73 | template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> { |
74 | static bool is(const VariantValue &Value) { |
75 | return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); |
76 | } |
77 | |
78 | static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { |
79 | return Value.getMatcher().getTypedMatcher<T>(); |
80 | } |
81 | |
82 | static ArgKind getKind() { |
83 | return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); |
84 | } |
85 | }; |
86 | |
87 | template <> struct ArgTypeTraits<bool> { |
88 | static bool is(const VariantValue &Value) { return Value.isBoolean(); } |
89 | |
90 | static bool get(const VariantValue &Value) { |
91 | return Value.getBoolean(); |
92 | } |
93 | |
94 | static ArgKind getKind() { |
95 | return ArgKind(ArgKind::AK_Boolean); |
96 | } |
97 | }; |
98 | |
99 | template <> struct ArgTypeTraits<double> { |
100 | static bool is(const VariantValue &Value) { return Value.isDouble(); } |
101 | |
102 | static double get(const VariantValue &Value) { |
103 | return Value.getDouble(); |
104 | } |
105 | |
106 | static ArgKind getKind() { |
107 | return ArgKind(ArgKind::AK_Double); |
108 | } |
109 | }; |
110 | |
111 | template <> struct ArgTypeTraits<unsigned> { |
112 | static bool is(const VariantValue &Value) { return Value.isUnsigned(); } |
113 | |
114 | static unsigned get(const VariantValue &Value) { |
115 | return Value.getUnsigned(); |
116 | } |
117 | |
118 | static ArgKind getKind() { |
119 | return ArgKind(ArgKind::AK_Unsigned); |
120 | } |
121 | }; |
122 | |
123 | template <> struct ArgTypeTraits<attr::Kind> { |
124 | private: |
125 | static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) { |
126 | return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind) |
127 | #define ATTR(X) .Case("attr::" #X, attr:: X) |
128 | #include "clang/Basic/AttrList.inc" |
129 | .Default(llvm::None); |
130 | } |
131 | |
132 | public: |
133 | static bool is(const VariantValue &Value) { |
134 | return Value.isString() && getAttrKind(Value.getString()); |
135 | } |
136 | |
137 | static attr::Kind get(const VariantValue &Value) { |
138 | return *getAttrKind(Value.getString()); |
139 | } |
140 | |
141 | static ArgKind getKind() { |
142 | return ArgKind(ArgKind::AK_String); |
143 | } |
144 | }; |
145 | |
146 | template <> struct ArgTypeTraits<CastKind> { |
147 | private: |
148 | static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) { |
149 | return llvm::StringSwitch<Optional<CastKind>>(AttrKind) |
150 | #define CAST_OPERATION(Name) .Case( #Name, CK_##Name) |
151 | #include "clang/AST/OperationKinds.def" |
152 | .Default(llvm::None); |
153 | } |
154 | |
155 | public: |
156 | static bool is(const VariantValue &Value) { |
157 | return Value.isString() && getCastKind(Value.getString()); |
158 | } |
159 | |
160 | static CastKind get(const VariantValue &Value) { |
161 | return *getCastKind(Value.getString()); |
162 | } |
163 | |
164 | static ArgKind getKind() { |
165 | return ArgKind(ArgKind::AK_String); |
166 | } |
167 | }; |
168 | |
169 | template <> struct ArgTypeTraits<OpenMPClauseKind> { |
170 | private: |
171 | static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) { |
172 | return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind) |
173 | #define OPENMP_CLAUSE(TextualSpelling, Class) \ |
174 | .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) |
175 | #include "clang/Basic/OpenMPKinds.def" |
176 | .Default(llvm::None); |
177 | } |
178 | |
179 | public: |
180 | static bool is(const VariantValue &Value) { |
181 | return Value.isString() && getClauseKind(Value.getString()); |
182 | } |
183 | |
184 | static OpenMPClauseKind get(const VariantValue &Value) { |
185 | return *getClauseKind(Value.getString()); |
186 | } |
187 | |
188 | static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } |
189 | }; |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | class MatcherDescriptor { |
196 | public: |
197 | virtual ~MatcherDescriptor() = default; |
198 | |
199 | virtual VariantMatcher create(SourceRange NameRange, |
200 | ArrayRef<ParserValue> Args, |
201 | Diagnostics *Error) const = 0; |
202 | |
203 | |
204 | |
205 | virtual bool isVariadic() const = 0; |
206 | |
207 | |
208 | virtual unsigned getNumArgs() const = 0; |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, |
215 | std::vector<ArgKind> &ArgKinds) const = 0; |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | virtual bool isConvertibleTo( |
225 | ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr, |
226 | ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0; |
227 | |
228 | |
229 | |
230 | virtual bool isPolymorphic() const { return false; } |
231 | }; |
232 | |
233 | inline bool isRetKindConvertibleTo( |
234 | ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, |
235 | ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
236 | ast_type_traits::ASTNodeKind *LeastDerivedKind) { |
237 | for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) { |
238 | if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) { |
239 | if (LeastDerivedKind) |
240 | *LeastDerivedKind = NodeKind; |
241 | return true; |
242 | } |
243 | } |
244 | return false; |
245 | } |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | class FixedArgCountMatcherDescriptor : public MatcherDescriptor { |
254 | public: |
255 | using MarshallerType = VariantMatcher (*)(void (*Func)(), |
256 | StringRef MatcherName, |
257 | SourceRange NameRange, |
258 | ArrayRef<ParserValue> Args, |
259 | Diagnostics *Error); |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | FixedArgCountMatcherDescriptor( |
268 | MarshallerType Marshaller, void (*Func)(), StringRef MatcherName, |
269 | ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, |
270 | ArrayRef<ArgKind> ArgKinds) |
271 | : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName), |
272 | RetKinds(RetKinds.begin(), RetKinds.end()), |
273 | ArgKinds(ArgKinds.begin(), ArgKinds.end()) {} |
274 | |
275 | VariantMatcher create(SourceRange NameRange, |
276 | ArrayRef<ParserValue> Args, |
277 | Diagnostics *Error) const override { |
278 | return Marshaller(Func, MatcherName, NameRange, Args, Error); |
279 | } |
280 | |
281 | bool isVariadic() const override { return false; } |
282 | unsigned getNumArgs() const override { return ArgKinds.size(); } |
283 | |
284 | void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, |
285 | std::vector<ArgKind> &Kinds) const override { |
286 | Kinds.push_back(ArgKinds[ArgNo]); |
287 | } |
288 | |
289 | bool isConvertibleTo( |
290 | ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
291 | ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { |
292 | return isRetKindConvertibleTo(RetKinds, Kind, Specificity, |
293 | LeastDerivedKind); |
294 | } |
295 | |
296 | private: |
297 | const MarshallerType Marshaller; |
298 | void (* const Func)(); |
299 | const std::string MatcherName; |
300 | const std::vector<ast_type_traits::ASTNodeKind> RetKinds; |
301 | const std::vector<ArgKind> ArgKinds; |
302 | }; |
303 | |
304 | |
305 | |
306 | template <class PolyMatcher> |
307 | static void mergePolyMatchers(const PolyMatcher &Poly, |
308 | std::vector<DynTypedMatcher> &Out, |
309 | ast_matchers::internal::EmptyTypeList) {} |
310 | |
311 | template <class PolyMatcher, class TypeList> |
312 | static void mergePolyMatchers(const PolyMatcher &Poly, |
313 | std::vector<DynTypedMatcher> &Out, TypeList) { |
314 | Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); |
315 | mergePolyMatchers(Poly, Out, typename TypeList::tail()); |
316 | } |
317 | |
318 | |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { |
325 | return VariantMatcher::SingleMatcher(Matcher); |
326 | } |
327 | |
328 | template <typename T> |
329 | static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, |
330 | typename T::ReturnTypes * = |
331 | nullptr) { |
332 | std::vector<DynTypedMatcher> Matchers; |
333 | mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); |
334 | VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers)); |
335 | return Out; |
336 | } |
337 | |
338 | template <typename T> |
339 | inline void buildReturnTypeVectorFromTypeList( |
340 | std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { |
341 | RetTypes.push_back( |
342 | ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>()); |
343 | buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes); |
344 | } |
345 | |
346 | template <> |
347 | inline void |
348 | buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>( |
349 | std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {} |
350 | |
351 | template <typename T> |
352 | struct BuildReturnTypeVector { |
353 | static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { |
354 | buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes); |
355 | } |
356 | }; |
357 | |
358 | template <typename T> |
359 | struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> { |
360 | static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { |
361 | RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); |
362 | } |
363 | }; |
364 | |
365 | template <typename T> |
366 | struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> { |
367 | static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { |
368 | RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); |
369 | } |
370 | }; |
371 | |
372 | |
373 | template <typename ResultT, typename ArgT, |
374 | ResultT (*Func)(ArrayRef<const ArgT *>)> |
375 | VariantMatcher |
376 | variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, |
377 | ArrayRef<ParserValue> Args, Diagnostics *Error) { |
378 | ArgT **InnerArgs = new ArgT *[Args.size()](); |
379 | |
380 | bool HasError = false; |
381 | for (size_t i = 0, e = Args.size(); i != e; ++i) { |
382 | using ArgTraits = ArgTypeTraits<ArgT>; |
383 | |
384 | const ParserValue &Arg = Args[i]; |
385 | const VariantValue &Value = Arg.Value; |
386 | if (!ArgTraits::is(Value)) { |
387 | Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) |
388 | << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); |
389 | HasError = true; |
390 | break; |
391 | } |
392 | InnerArgs[i] = new ArgT(ArgTraits::get(Value)); |
393 | } |
394 | |
395 | VariantMatcher Out; |
396 | if (!HasError) { |
397 | Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs, |
398 | Args.size()))); |
399 | } |
400 | |
401 | for (size_t i = 0, e = Args.size(); i != e; ++i) { |
402 | delete InnerArgs[i]; |
403 | } |
404 | delete[] InnerArgs; |
405 | return Out; |
406 | } |
407 | |
408 | |
409 | |
410 | |
411 | |
412 | |
413 | |
414 | |
415 | class VariadicFuncMatcherDescriptor : public MatcherDescriptor { |
416 | public: |
417 | using RunFunc = VariantMatcher (*)(StringRef MatcherName, |
418 | SourceRange NameRange, |
419 | ArrayRef<ParserValue> Args, |
420 | Diagnostics *Error); |
421 | |
422 | template <typename ResultT, typename ArgT, |
423 | ResultT (*F)(ArrayRef<const ArgT *>)> |
424 | VariadicFuncMatcherDescriptor( |
425 | ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func, |
426 | StringRef MatcherName) |
427 | : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), |
428 | MatcherName(MatcherName.str()), |
429 | ArgsKind(ArgTypeTraits<ArgT>::getKind()) { |
430 | BuildReturnTypeVector<ResultT>::build(RetKinds); |
431 | } |
432 | |
433 | VariantMatcher create(SourceRange NameRange, |
434 | ArrayRef<ParserValue> Args, |
435 | Diagnostics *Error) const override { |
436 | return Func(MatcherName, NameRange, Args, Error); |
437 | } |
438 | |
439 | bool isVariadic() const override { return true; } |
440 | unsigned getNumArgs() const override { return 0; } |
441 | |
442 | void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, |
443 | std::vector<ArgKind> &Kinds) const override { |
444 | Kinds.push_back(ArgsKind); |
445 | } |
446 | |
447 | bool isConvertibleTo( |
448 | ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
449 | ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { |
450 | return isRetKindConvertibleTo(RetKinds, Kind, Specificity, |
451 | LeastDerivedKind); |
452 | } |
453 | |
454 | private: |
455 | const RunFunc Func; |
456 | const std::string MatcherName; |
457 | std::vector<ast_type_traits::ASTNodeKind> RetKinds; |
458 | const ArgKind ArgsKind; |
459 | }; |
460 | |
461 | |
462 | class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor { |
463 | public: |
464 | template <typename BaseT, typename DerivedT> |
465 | DynCastAllOfMatcherDescriptor( |
466 | ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func, |
467 | StringRef MatcherName) |
468 | : VariadicFuncMatcherDescriptor(Func, MatcherName), |
469 | DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) { |
470 | } |
471 | |
472 | bool |
473 | isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
474 | ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { |
475 | |
476 | |
477 | |
478 | |
479 | if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity, |
480 | LeastDerivedKind)) { |
481 | if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) { |
482 | if (Specificity) |
483 | *Specificity = 0; |
484 | } |
485 | return true; |
486 | } else { |
487 | return false; |
488 | } |
489 | } |
490 | |
491 | private: |
492 | const ast_type_traits::ASTNodeKind DerivedKind; |
493 | }; |
494 | |
495 | |
496 | #define CHECK_ARG_COUNT(count) \ |
497 | if (Args.size() != count) { \ |
498 | Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ |
499 | << count << Args.size(); \ |
500 | return VariantMatcher(); \ |
501 | } |
502 | |
503 | #define CHECK_ARG_TYPE(index, type) \ |
504 | if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ |
505 | Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ |
506 | << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ |
507 | << Args[index].Value.getTypeAsString(); \ |
508 | return VariantMatcher(); \ |
509 | } |
510 | |
511 | |
512 | template <typename ReturnType> |
513 | static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, |
514 | SourceRange NameRange, |
515 | ArrayRef<ParserValue> Args, |
516 | Diagnostics *Error) { |
517 | using FuncType = ReturnType (*)(); |
518 | CHECK_ARG_COUNT(0); |
519 | return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)()); |
520 | } |
521 | |
522 | |
523 | template <typename ReturnType, typename ArgType1> |
524 | static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName, |
525 | SourceRange NameRange, |
526 | ArrayRef<ParserValue> Args, |
527 | Diagnostics *Error) { |
528 | using FuncType = ReturnType (*)(ArgType1); |
529 | CHECK_ARG_COUNT(1); |
530 | CHECK_ARG_TYPE(0, ArgType1); |
531 | return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( |
532 | ArgTypeTraits<ArgType1>::get(Args[0].Value))); |
533 | } |
534 | |
535 | |
536 | template <typename ReturnType, typename ArgType1, typename ArgType2> |
537 | static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName, |
538 | SourceRange NameRange, |
539 | ArrayRef<ParserValue> Args, |
540 | Diagnostics *Error) { |
541 | using FuncType = ReturnType (*)(ArgType1, ArgType2); |
542 | CHECK_ARG_COUNT(2); |
543 | CHECK_ARG_TYPE(0, ArgType1); |
544 | CHECK_ARG_TYPE(1, ArgType2); |
545 | return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( |
546 | ArgTypeTraits<ArgType1>::get(Args[0].Value), |
547 | ArgTypeTraits<ArgType2>::get(Args[1].Value))); |
548 | } |
549 | |
550 | #undef CHECK_ARG_COUNT |
551 | #undef CHECK_ARG_TYPE |
552 | |
553 | |
554 | |
555 | template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, |
556 | typename FromTypes, typename ToTypes> |
557 | class AdaptativeOverloadCollector { |
558 | public: |
559 | AdaptativeOverloadCollector( |
560 | StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out) |
561 | : Name(Name), Out(Out) { |
562 | collect(FromTypes()); |
563 | } |
564 | |
565 | private: |
566 | using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc< |
567 | ArgumentAdapterT, FromTypes, ToTypes>; |
568 | |
569 | |
570 | static void collect(ast_matchers::internal::EmptyTypeList) {} |
571 | |
572 | |
573 | |
574 | template <typename FromTypeList> |
575 | inline void collect(FromTypeList); |
576 | |
577 | StringRef Name; |
578 | std::vector<std::unique_ptr<MatcherDescriptor>> &Out; |
579 | }; |
580 | |
581 | |
582 | |
583 | |
584 | |
585 | |
586 | class OverloadedMatcherDescriptor : public MatcherDescriptor { |
587 | public: |
588 | OverloadedMatcherDescriptor( |
589 | MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks) |
590 | : Overloads(std::make_move_iterator(Callbacks.begin()), |
591 | std::make_move_iterator(Callbacks.end())) {} |
592 | |
593 | ~OverloadedMatcherDescriptor() override = default; |
594 | |
595 | VariantMatcher create(SourceRange NameRange, |
596 | ArrayRef<ParserValue> Args, |
597 | Diagnostics *Error) const override { |
598 | std::vector<VariantMatcher> Constructed; |
599 | Diagnostics::OverloadContext Ctx(Error); |
600 | for (const auto &O : Overloads) { |
601 | VariantMatcher SubMatcher = O->create(NameRange, Args, Error); |
602 | if (!SubMatcher.isNull()) { |
603 | Constructed.push_back(SubMatcher); |
604 | } |
605 | } |
606 | |
607 | if (Constructed.empty()) return VariantMatcher(); |
608 | |
609 | Ctx.revertErrors(); |
610 | if (Constructed.size() > 1) { |
611 | |
612 | Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); |
613 | return VariantMatcher(); |
614 | } |
615 | return Constructed[0]; |
616 | } |
617 | |
618 | bool isVariadic() const override { |
619 | bool Overload0Variadic = Overloads[0]->isVariadic(); |
620 | #ifndef NDEBUG |
621 | for (const auto &O : Overloads) { |
622 | isVariadic()", "/home/seafit/code_projects/clang_source/clang/lib/ASTMatchers/Dynamic/Marshallers.h", 622, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Overload0Variadic == O->isVariadic()); |
623 | } |
624 | #endif |
625 | return Overload0Variadic; |
626 | } |
627 | |
628 | unsigned getNumArgs() const override { |
629 | unsigned Overload0NumArgs = Overloads[0]->getNumArgs(); |
630 | #ifndef NDEBUG |
631 | for (const auto &O : Overloads) { |
632 | getNumArgs()", "/home/seafit/code_projects/clang_source/clang/lib/ASTMatchers/Dynamic/Marshallers.h", 632, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Overload0NumArgs == O->getNumArgs()); |
633 | } |
634 | #endif |
635 | return Overload0NumArgs; |
636 | } |
637 | |
638 | void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, |
639 | std::vector<ArgKind> &Kinds) const override { |
640 | for (const auto &O : Overloads) { |
641 | if (O->isConvertibleTo(ThisKind)) |
642 | O->getArgKinds(ThisKind, ArgNo, Kinds); |
643 | } |
644 | } |
645 | |
646 | bool isConvertibleTo( |
647 | ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
648 | ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { |
649 | for (const auto &O : Overloads) { |
650 | if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind)) |
651 | return true; |
652 | } |
653 | return false; |
654 | } |
655 | |
656 | private: |
657 | std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; |
658 | }; |
659 | |
660 | |
661 | class VariadicOperatorMatcherDescriptor : public MatcherDescriptor { |
662 | public: |
663 | using VarOp = DynTypedMatcher::VariadicOperator; |
664 | |
665 | VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, |
666 | VarOp Op, StringRef MatcherName) |
667 | : MinCount(MinCount), MaxCount(MaxCount), Op(Op), |
668 | MatcherName(MatcherName) {} |
669 | |
670 | VariantMatcher create(SourceRange NameRange, |
671 | ArrayRef<ParserValue> Args, |
672 | Diagnostics *Error) const override { |
673 | if (Args.size() < MinCount || MaxCount < Args.size()) { |
674 | const std::string MaxStr = |
675 | (MaxCount == std::numeric_limits<unsigned>::max() ? "" |
676 | : Twine(MaxCount)) |
677 | .str(); |
678 | Error->addError(NameRange, Error->ET_RegistryWrongArgCount) |
679 | << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size(); |
680 | return VariantMatcher(); |
681 | } |
682 | |
683 | std::vector<VariantMatcher> InnerArgs; |
684 | for (size_t i = 0, e = Args.size(); i != e; ++i) { |
685 | const ParserValue &Arg = Args[i]; |
686 | const VariantValue &Value = Arg.Value; |
687 | if (!Value.isMatcher()) { |
688 | Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) |
689 | << (i + 1) << "Matcher<>" << Value.getTypeAsString(); |
690 | return VariantMatcher(); |
691 | } |
692 | InnerArgs.push_back(Value.getMatcher()); |
693 | } |
694 | return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs)); |
695 | } |
696 | |
697 | bool isVariadic() const override { return true; } |
698 | unsigned getNumArgs() const override { return 0; } |
699 | |
700 | void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, |
701 | std::vector<ArgKind> &Kinds) const override { |
702 | Kinds.push_back(ThisKind); |
703 | } |
704 | |
705 | bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, |
706 | ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { |
707 | if (Specificity) |
708 | *Specificity = 1; |
709 | if (LeastDerivedKind) |
710 | *LeastDerivedKind = Kind; |
711 | return true; |
712 | } |
713 | |
714 | bool isPolymorphic() const override { return true; } |
715 | |
716 | private: |
717 | const unsigned MinCount; |
718 | const unsigned MaxCount; |
719 | const VarOp Op; |
720 | const StringRef MatcherName; |
721 | }; |
722 | |
723 | |
724 | |
725 | |
726 | |
727 | template <typename ReturnType> |
728 | std::unique_ptr<MatcherDescriptor> |
729 | makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) { |
730 | std::vector<ast_type_traits::ASTNodeKind> RetTypes; |
731 | BuildReturnTypeVector<ReturnType>::build(RetTypes); |
732 | return llvm::make_unique<FixedArgCountMatcherDescriptor>( |
733 | matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), |
734 | MatcherName, RetTypes, None); |
735 | } |
736 | |
737 | |
738 | template <typename ReturnType, typename ArgType1> |
739 | std::unique_ptr<MatcherDescriptor> |
740 | makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) { |
741 | std::vector<ast_type_traits::ASTNodeKind> RetTypes; |
742 | BuildReturnTypeVector<ReturnType>::build(RetTypes); |
743 | ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); |
744 | return llvm::make_unique<FixedArgCountMatcherDescriptor>( |
745 | matcherMarshall1<ReturnType, ArgType1>, |
746 | reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); |
747 | } |
748 | |
749 | |
750 | template <typename ReturnType, typename ArgType1, typename ArgType2> |
751 | std::unique_ptr<MatcherDescriptor> |
752 | makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), |
753 | StringRef MatcherName) { |
754 | std::vector<ast_type_traits::ASTNodeKind> RetTypes; |
755 | BuildReturnTypeVector<ReturnType>::build(RetTypes); |
756 | ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), |
757 | ArgTypeTraits<ArgType2>::getKind() }; |
758 | return llvm::make_unique<FixedArgCountMatcherDescriptor>( |
759 | matcherMarshall2<ReturnType, ArgType1, ArgType2>, |
760 | reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); |
761 | } |
762 | |
763 | |
764 | template <typename ResultT, typename ArgT, |
765 | ResultT (*Func)(ArrayRef<const ArgT *>)> |
766 | std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( |
767 | ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, |
768 | StringRef MatcherName) { |
769 | return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName); |
770 | } |
771 | |
772 | |
773 | |
774 | |
775 | |
776 | template <typename BaseT, typename DerivedT> |
777 | std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( |
778 | ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> |
779 | VarFunc, |
780 | StringRef MatcherName) { |
781 | return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName); |
782 | } |
783 | |
784 | |
785 | template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, |
786 | typename FromTypes, typename ToTypes> |
787 | std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( |
788 | ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT, |
789 | FromTypes, ToTypes>, |
790 | StringRef MatcherName) { |
791 | std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; |
792 | AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, |
793 | Overloads); |
794 | return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads); |
795 | } |
796 | |
797 | template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, |
798 | typename FromTypes, typename ToTypes> |
799 | template <typename FromTypeList> |
800 | inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, |
801 | ToTypes>::collect(FromTypeList) { |
802 | Out.push_back(makeMatcherAutoMarshall( |
803 | &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); |
804 | collect(typename FromTypeList::tail()); |
805 | } |
806 | |
807 | |
808 | template <unsigned MinCount, unsigned MaxCount> |
809 | std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( |
810 | ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount> |
811 | Func, |
812 | StringRef MatcherName) { |
813 | return llvm::make_unique<VariadicOperatorMatcherDescriptor>( |
814 | MinCount, MaxCount, Func.Op, MatcherName); |
815 | } |
816 | |
817 | } |
818 | } |
819 | } |
820 | } |
821 | |
822 | #endif |
823 | |