1 //===--- Marshallers.h - Generic matcher function marshallers ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Functions templates and classes to wrap matcher construct functions. 12 /// 13 /// A collection of template function and classes that provide a generic 14 /// marshalling layer on top of matcher construct functions. 15 /// These are used by the registry to export all marshaller constructors with 16 /// the same generic interface. 17 /// 18 //===----------------------------------------------------------------------===// 19 20 #ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 21 #define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 22 23 #include "clang/ASTMatchers/ASTMatchers.h" 24 #include "clang/ASTMatchers/Dynamic/Diagnostics.h" 25 #include "clang/ASTMatchers/Dynamic/VariantValue.h" 26 #include "clang/Basic/LLVM.h" 27 #include "llvm/ADT/STLExtras.h" 28 #include <string> 29 30 namespace clang { 31 namespace ast_matchers { 32 namespace dynamic { 33 namespace internal { 34 35 /// \brief Helper template class to just from argument type to the right is/get 36 /// functions in VariantValue. 37 /// Used to verify and extract the matcher arguments below. 38 template <class T> struct ArgTypeTraits; 39 template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 40 }; 41 42 template <> struct ArgTypeTraits<std::string> { 43 static bool is(const VariantValue &Value) { return Value.isString(); } 44 static const std::string &get(const VariantValue &Value) { 45 return Value.getString(); 46 } 47 static ArgKind getKind() { 48 return ArgKind(ArgKind::AK_String); 49 } 50 }; 51 52 template <> 53 struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { 54 }; 55 56 template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > { 57 static bool is(const VariantValue &Value) { 58 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); 59 } 60 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { 61 return Value.getMatcher().getTypedMatcher<T>(); 62 } 63 static ArgKind getKind() { 64 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 65 } 66 }; 67 68 template <> struct ArgTypeTraits<unsigned> { 69 static bool is(const VariantValue &Value) { return Value.isUnsigned(); } 70 static unsigned get(const VariantValue &Value) { 71 return Value.getUnsigned(); 72 } 73 static ArgKind getKind() { 74 return ArgKind(ArgKind::AK_Unsigned); 75 } 76 }; 77 78 template <> struct ArgTypeTraits<attr::Kind> { 79 private: 80 static attr::Kind getAttrKind(llvm::StringRef AttrKind) { 81 return llvm::StringSwitch<attr::Kind>(AttrKind) 82 #define ATTR(X) .Case("attr::" #X, attr:: X) 83 #include "clang/Basic/AttrList.inc" 84 .Default(attr::Kind(-1)); 85 } 86 public: 87 static bool is(const VariantValue &Value) { 88 return Value.isString() && 89 getAttrKind(Value.getString()) != attr::Kind(-1); 90 } 91 static attr::Kind get(const VariantValue &Value) { 92 return getAttrKind(Value.getString()); 93 } 94 static ArgKind getKind() { 95 return ArgKind(ArgKind::AK_String); 96 } 97 }; 98 99 template <> struct ArgTypeTraits<clang::CastKind> { 100 private: 101 static clang::CastKind getCastKind(llvm::StringRef AttrKind) { 102 return llvm::StringSwitch<clang::CastKind>(AttrKind) 103 #define CAST_OPERATION(Name) .Case( #Name, CK_##Name) 104 #include "clang/AST/OperationKinds.def" 105 .Default(CK_Invalid); 106 } 107 108 public: 109 static bool is(const VariantValue &Value) { 110 return Value.isString() && 111 getCastKind(Value.getString()) != CK_Invalid; 112 } 113 static clang::CastKind get(const VariantValue &Value) { 114 return getCastKind(Value.getString()); 115 } 116 static ArgKind getKind() { 117 return ArgKind(ArgKind::AK_String); 118 } 119 }; 120 121 /// \brief Matcher descriptor interface. 122 /// 123 /// Provides a \c create() method that constructs the matcher from the provided 124 /// arguments, and various other methods for type introspection. 125 class MatcherDescriptor { 126 public: 127 virtual ~MatcherDescriptor() {} 128 virtual VariantMatcher create(SourceRange NameRange, 129 ArrayRef<ParserValue> Args, 130 Diagnostics *Error) const = 0; 131 132 /// Returns whether the matcher is variadic. Variadic matchers can take any 133 /// number of arguments, but they must be of the same type. 134 virtual bool isVariadic() const = 0; 135 136 /// Returns the number of arguments accepted by the matcher if not variadic. 137 virtual unsigned getNumArgs() const = 0; 138 139 /// Given that the matcher is being converted to type \p ThisKind, append the 140 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds. 141 // FIXME: We should provide the ability to constrain the output of this 142 // function based on the types of other matcher arguments. 143 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 144 std::vector<ArgKind> &ArgKinds) const = 0; 145 146 /// Returns whether this matcher is convertible to the given type. If it is 147 /// so convertible, store in *Specificity a value corresponding to the 148 /// "specificity" of the converted matcher to the given context, and in 149 /// *LeastDerivedKind the least derived matcher kind which would result in the 150 /// same matcher overload. Zero specificity indicates that this conversion 151 /// would produce a trivial matcher that will either always or never match. 152 /// Such matchers are excluded from code completion results. 153 virtual bool isConvertibleTo( 154 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr, 155 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0; 156 157 /// Returns whether the matcher will, given a matcher of any type T, yield a 158 /// matcher of type T. 159 virtual bool isPolymorphic() const { return false; } 160 }; 161 162 inline bool isRetKindConvertibleTo( 163 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 164 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 165 ast_type_traits::ASTNodeKind *LeastDerivedKind) { 166 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) { 167 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) { 168 if (LeastDerivedKind) 169 *LeastDerivedKind = NodeKind; 170 return true; 171 } 172 } 173 return false; 174 } 175 176 /// \brief Simple callback implementation. Marshaller and function are provided. 177 /// 178 /// This class wraps a function of arbitrary signature and a marshaller 179 /// function into a MatcherDescriptor. 180 /// The marshaller is in charge of taking the VariantValue arguments, checking 181 /// their types, unpacking them and calling the underlying function. 182 class FixedArgCountMatcherDescriptor : public MatcherDescriptor { 183 public: 184 typedef VariantMatcher (*MarshallerType)(void (*Func)(), 185 StringRef MatcherName, 186 SourceRange NameRange, 187 ArrayRef<ParserValue> Args, 188 Diagnostics *Error); 189 190 /// \param Marshaller Function to unpack the arguments and call \c Func 191 /// \param Func Matcher construct function. This is the function that 192 /// compile-time matcher expressions would use to create the matcher. 193 /// \param RetKinds The list of matcher types to which the matcher is 194 /// convertible. 195 /// \param ArgKinds The types of the arguments this matcher takes. 196 FixedArgCountMatcherDescriptor( 197 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName, 198 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 199 ArrayRef<ArgKind> ArgKinds) 200 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName), 201 RetKinds(RetKinds.begin(), RetKinds.end()), 202 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {} 203 204 VariantMatcher create(SourceRange NameRange, 205 ArrayRef<ParserValue> Args, 206 Diagnostics *Error) const override { 207 return Marshaller(Func, MatcherName, NameRange, Args, Error); 208 } 209 210 bool isVariadic() const override { return false; } 211 unsigned getNumArgs() const override { return ArgKinds.size(); } 212 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 213 std::vector<ArgKind> &Kinds) const override { 214 Kinds.push_back(ArgKinds[ArgNo]); 215 } 216 bool isConvertibleTo( 217 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 218 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 219 return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 220 LeastDerivedKind); 221 } 222 223 private: 224 const MarshallerType Marshaller; 225 void (* const Func)(); 226 const std::string MatcherName; 227 const std::vector<ast_type_traits::ASTNodeKind> RetKinds; 228 const std::vector<ArgKind> ArgKinds; 229 }; 230 231 /// \brief Helper methods to extract and merge all possible typed matchers 232 /// out of the polymorphic object. 233 template <class PolyMatcher> 234 static void mergePolyMatchers(const PolyMatcher &Poly, 235 std::vector<DynTypedMatcher> &Out, 236 ast_matchers::internal::EmptyTypeList) {} 237 238 template <class PolyMatcher, class TypeList> 239 static void mergePolyMatchers(const PolyMatcher &Poly, 240 std::vector<DynTypedMatcher> &Out, TypeList) { 241 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); 242 mergePolyMatchers(Poly, Out, typename TypeList::tail()); 243 } 244 245 /// \brief Convert the return values of the functions into a VariantMatcher. 246 /// 247 /// There are 2 cases right now: The return value is a Matcher<T> or is a 248 /// polymorphic matcher. For the former, we just construct the VariantMatcher. 249 /// For the latter, we instantiate all the possible Matcher<T> of the poly 250 /// matcher. 251 static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 252 return VariantMatcher::SingleMatcher(Matcher); 253 } 254 255 template <typename T> 256 static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, 257 typename T::ReturnTypes * = 258 nullptr) { 259 std::vector<DynTypedMatcher> Matchers; 260 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); 261 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers)); 262 return Out; 263 } 264 265 template <typename T> 266 inline void buildReturnTypeVectorFromTypeList( 267 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 268 RetTypes.push_back( 269 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>()); 270 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes); 271 } 272 273 template <> 274 inline void 275 buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>( 276 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {} 277 278 template <typename T> 279 struct BuildReturnTypeVector { 280 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 281 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes); 282 } 283 }; 284 285 template <typename T> 286 struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > { 287 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 288 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 289 } 290 }; 291 292 template <typename T> 293 struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > { 294 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 295 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 296 } 297 }; 298 299 /// \brief Variadic marshaller function. 300 template <typename ResultT, typename ArgT, 301 ResultT (*Func)(ArrayRef<const ArgT *>)> 302 VariantMatcher 303 variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, 304 ArrayRef<ParserValue> Args, Diagnostics *Error) { 305 ArgT **InnerArgs = new ArgT *[Args.size()](); 306 307 bool HasError = false; 308 for (size_t i = 0, e = Args.size(); i != e; ++i) { 309 typedef ArgTypeTraits<ArgT> ArgTraits; 310 const ParserValue &Arg = Args[i]; 311 const VariantValue &Value = Arg.Value; 312 if (!ArgTraits::is(Value)) { 313 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 314 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); 315 HasError = true; 316 break; 317 } 318 InnerArgs[i] = new ArgT(ArgTraits::get(Value)); 319 } 320 321 VariantMatcher Out; 322 if (!HasError) { 323 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs, 324 Args.size()))); 325 } 326 327 for (size_t i = 0, e = Args.size(); i != e; ++i) { 328 delete InnerArgs[i]; 329 } 330 delete[] InnerArgs; 331 return Out; 332 } 333 334 /// \brief Matcher descriptor for variadic functions. 335 /// 336 /// This class simply wraps a VariadicFunction with the right signature to export 337 /// it as a MatcherDescriptor. 338 /// This allows us to have one implementation of the interface for as many free 339 /// functions as we want, reducing the number of symbols and size of the 340 /// object file. 341 class VariadicFuncMatcherDescriptor : public MatcherDescriptor { 342 public: 343 typedef VariantMatcher (*RunFunc)(StringRef MatcherName, 344 SourceRange NameRange, 345 ArrayRef<ParserValue> Args, 346 Diagnostics *Error); 347 348 template <typename ResultT, typename ArgT, 349 ResultT (*F)(ArrayRef<const ArgT *>)> 350 VariadicFuncMatcherDescriptor( 351 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func, 352 StringRef MatcherName) 353 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), 354 MatcherName(MatcherName.str()), 355 ArgsKind(ArgTypeTraits<ArgT>::getKind()) { 356 BuildReturnTypeVector<ResultT>::build(RetKinds); 357 } 358 359 VariantMatcher create(SourceRange NameRange, 360 ArrayRef<ParserValue> Args, 361 Diagnostics *Error) const override { 362 return Func(MatcherName, NameRange, Args, Error); 363 } 364 365 bool isVariadic() const override { return true; } 366 unsigned getNumArgs() const override { return 0; } 367 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 368 std::vector<ArgKind> &Kinds) const override { 369 Kinds.push_back(ArgsKind); 370 } 371 bool isConvertibleTo( 372 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 373 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 374 return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 375 LeastDerivedKind); 376 } 377 378 private: 379 const RunFunc Func; 380 const std::string MatcherName; 381 std::vector<ast_type_traits::ASTNodeKind> RetKinds; 382 const ArgKind ArgsKind; 383 }; 384 385 /// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers. 386 class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor { 387 public: 388 template <typename BaseT, typename DerivedT> 389 DynCastAllOfMatcherDescriptor( 390 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func, 391 StringRef MatcherName) 392 : VariadicFuncMatcherDescriptor(Func, MatcherName), 393 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) { 394 } 395 396 bool 397 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 398 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 399 // If Kind is not a base of DerivedKind, either DerivedKind is a base of 400 // Kind (in which case the match will always succeed) or Kind and 401 // DerivedKind are unrelated (in which case it will always fail), so set 402 // Specificity to 0. 403 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity, 404 LeastDerivedKind)) { 405 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) { 406 if (Specificity) 407 *Specificity = 0; 408 } 409 return true; 410 } else { 411 return false; 412 } 413 } 414 415 private: 416 const ast_type_traits::ASTNodeKind DerivedKind; 417 }; 418 419 /// \brief Helper macros to check the arguments on all marshaller functions. 420 #define CHECK_ARG_COUNT(count) \ 421 if (Args.size() != count) { \ 422 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ 423 << count << Args.size(); \ 424 return VariantMatcher(); \ 425 } 426 427 #define CHECK_ARG_TYPE(index, type) \ 428 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ 429 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ 430 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ 431 << Args[index].Value.getTypeAsString(); \ 432 return VariantMatcher(); \ 433 } 434 435 /// \brief 0-arg marshaller function. 436 template <typename ReturnType> 437 static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, 438 SourceRange NameRange, 439 ArrayRef<ParserValue> Args, 440 Diagnostics *Error) { 441 typedef ReturnType (*FuncType)(); 442 CHECK_ARG_COUNT(0); 443 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)()); 444 } 445 446 /// \brief 1-arg marshaller function. 447 template <typename ReturnType, typename ArgType1> 448 static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName, 449 SourceRange NameRange, 450 ArrayRef<ParserValue> Args, 451 Diagnostics *Error) { 452 typedef ReturnType (*FuncType)(ArgType1); 453 CHECK_ARG_COUNT(1); 454 CHECK_ARG_TYPE(0, ArgType1); 455 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 456 ArgTypeTraits<ArgType1>::get(Args[0].Value))); 457 } 458 459 /// \brief 2-arg marshaller function. 460 template <typename ReturnType, typename ArgType1, typename ArgType2> 461 static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName, 462 SourceRange NameRange, 463 ArrayRef<ParserValue> Args, 464 Diagnostics *Error) { 465 typedef ReturnType (*FuncType)(ArgType1, ArgType2); 466 CHECK_ARG_COUNT(2); 467 CHECK_ARG_TYPE(0, ArgType1); 468 CHECK_ARG_TYPE(1, ArgType2); 469 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 470 ArgTypeTraits<ArgType1>::get(Args[0].Value), 471 ArgTypeTraits<ArgType2>::get(Args[1].Value))); 472 } 473 474 #undef CHECK_ARG_COUNT 475 #undef CHECK_ARG_TYPE 476 477 /// \brief Helper class used to collect all the possible overloads of an 478 /// argument adaptative matcher function. 479 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 480 typename FromTypes, typename ToTypes> 481 class AdaptativeOverloadCollector { 482 public: 483 AdaptativeOverloadCollector(StringRef Name, 484 std::vector<MatcherDescriptor *> &Out) 485 : Name(Name), Out(Out) { 486 collect(FromTypes()); 487 } 488 489 private: 490 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc< 491 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc; 492 493 /// \brief End case for the recursion 494 static void collect(ast_matchers::internal::EmptyTypeList) {} 495 496 /// \brief Recursive case. Get the overload for the head of the list, and 497 /// recurse to the tail. 498 template <typename FromTypeList> 499 inline void collect(FromTypeList); 500 501 StringRef Name; 502 std::vector<MatcherDescriptor *> &Out; 503 }; 504 505 /// \brief MatcherDescriptor that wraps multiple "overloads" of the same 506 /// matcher. 507 /// 508 /// It will try every overload and generate appropriate errors for when none or 509 /// more than one overloads match the arguments. 510 class OverloadedMatcherDescriptor : public MatcherDescriptor { 511 public: 512 OverloadedMatcherDescriptor(ArrayRef<MatcherDescriptor *> Callbacks) 513 : Overloads(Callbacks.begin(), Callbacks.end()) {} 514 515 ~OverloadedMatcherDescriptor() override {} 516 517 VariantMatcher create(SourceRange NameRange, 518 ArrayRef<ParserValue> Args, 519 Diagnostics *Error) const override { 520 std::vector<VariantMatcher> Constructed; 521 Diagnostics::OverloadContext Ctx(Error); 522 for (const auto &O : Overloads) { 523 VariantMatcher SubMatcher = O->create(NameRange, Args, Error); 524 if (!SubMatcher.isNull()) { 525 Constructed.push_back(SubMatcher); 526 } 527 } 528 529 if (Constructed.empty()) return VariantMatcher(); // No overload matched. 530 // We ignore the errors if any matcher succeeded. 531 Ctx.revertErrors(); 532 if (Constructed.size() > 1) { 533 // More than one constructed. It is ambiguous. 534 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); 535 return VariantMatcher(); 536 } 537 return Constructed[0]; 538 } 539 540 bool isVariadic() const override { 541 bool Overload0Variadic = Overloads[0]->isVariadic(); 542 #ifndef NDEBUG 543 for (const auto &O : Overloads) { 544 assert(Overload0Variadic == O->isVariadic()); 545 } 546 #endif 547 return Overload0Variadic; 548 } 549 550 unsigned getNumArgs() const override { 551 unsigned Overload0NumArgs = Overloads[0]->getNumArgs(); 552 #ifndef NDEBUG 553 for (const auto &O : Overloads) { 554 assert(Overload0NumArgs == O->getNumArgs()); 555 } 556 #endif 557 return Overload0NumArgs; 558 } 559 560 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 561 std::vector<ArgKind> &Kinds) const override { 562 for (const auto &O : Overloads) { 563 if (O->isConvertibleTo(ThisKind)) 564 O->getArgKinds(ThisKind, ArgNo, Kinds); 565 } 566 } 567 568 bool isConvertibleTo( 569 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 570 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 571 for (const auto &O : Overloads) { 572 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind)) 573 return true; 574 } 575 return false; 576 } 577 578 private: 579 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; 580 }; 581 582 /// \brief Variadic operator marshaller function. 583 class VariadicOperatorMatcherDescriptor : public MatcherDescriptor { 584 public: 585 typedef DynTypedMatcher::VariadicOperator VarOp; 586 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, 587 VarOp Op, StringRef MatcherName) 588 : MinCount(MinCount), MaxCount(MaxCount), Op(Op), 589 MatcherName(MatcherName) {} 590 591 VariantMatcher create(SourceRange NameRange, 592 ArrayRef<ParserValue> Args, 593 Diagnostics *Error) const override { 594 if (Args.size() < MinCount || MaxCount < Args.size()) { 595 const std::string MaxStr = 596 (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str(); 597 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) 598 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size(); 599 return VariantMatcher(); 600 } 601 602 std::vector<VariantMatcher> InnerArgs; 603 for (size_t i = 0, e = Args.size(); i != e; ++i) { 604 const ParserValue &Arg = Args[i]; 605 const VariantValue &Value = Arg.Value; 606 if (!Value.isMatcher()) { 607 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 608 << (i + 1) << "Matcher<>" << Value.getTypeAsString(); 609 return VariantMatcher(); 610 } 611 InnerArgs.push_back(Value.getMatcher()); 612 } 613 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs)); 614 } 615 616 bool isVariadic() const override { return true; } 617 unsigned getNumArgs() const override { return 0; } 618 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 619 std::vector<ArgKind> &Kinds) const override { 620 Kinds.push_back(ThisKind); 621 } 622 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 623 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 624 if (Specificity) 625 *Specificity = 1; 626 if (LeastDerivedKind) 627 *LeastDerivedKind = Kind; 628 return true; 629 } 630 bool isPolymorphic() const override { return true; } 631 632 private: 633 const unsigned MinCount; 634 const unsigned MaxCount; 635 const VarOp Op; 636 const StringRef MatcherName; 637 }; 638 639 /// Helper functions to select the appropriate marshaller functions. 640 /// They detect the number of arguments, arguments types and return type. 641 642 /// \brief 0-arg overload 643 template <typename ReturnType> 644 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(), 645 StringRef MatcherName) { 646 std::vector<ast_type_traits::ASTNodeKind> RetTypes; 647 BuildReturnTypeVector<ReturnType>::build(RetTypes); 648 return new FixedArgCountMatcherDescriptor( 649 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), 650 MatcherName, RetTypes, None); 651 } 652 653 /// \brief 1-arg overload 654 template <typename ReturnType, typename ArgType1> 655 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), 656 StringRef MatcherName) { 657 std::vector<ast_type_traits::ASTNodeKind> RetTypes; 658 BuildReturnTypeVector<ReturnType>::build(RetTypes); 659 ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); 660 return new FixedArgCountMatcherDescriptor( 661 matcherMarshall1<ReturnType, ArgType1>, 662 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); 663 } 664 665 /// \brief 2-arg overload 666 template <typename ReturnType, typename ArgType1, typename ArgType2> 667 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), 668 StringRef MatcherName) { 669 std::vector<ast_type_traits::ASTNodeKind> RetTypes; 670 BuildReturnTypeVector<ReturnType>::build(RetTypes); 671 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), 672 ArgTypeTraits<ArgType2>::getKind() }; 673 return new FixedArgCountMatcherDescriptor( 674 matcherMarshall2<ReturnType, ArgType1, ArgType2>, 675 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); 676 } 677 678 /// \brief Variadic overload. 679 template <typename ResultT, typename ArgT, 680 ResultT (*Func)(ArrayRef<const ArgT *>)> 681 MatcherDescriptor *makeMatcherAutoMarshall( 682 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, 683 StringRef MatcherName) { 684 return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName); 685 } 686 687 /// \brief Overload for VariadicDynCastAllOfMatchers. 688 /// 689 /// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better 690 /// completion results for that type of matcher. 691 template <typename BaseT, typename DerivedT> 692 MatcherDescriptor * 693 makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher< 694 BaseT, DerivedT> VarFunc, 695 StringRef MatcherName) { 696 return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName); 697 } 698 699 /// \brief Argument adaptative overload. 700 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 701 typename FromTypes, typename ToTypes> 702 MatcherDescriptor * 703 makeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc< 704 ArgumentAdapterT, FromTypes, ToTypes>, 705 StringRef MatcherName) { 706 std::vector<MatcherDescriptor *> Overloads; 707 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, 708 Overloads); 709 return new OverloadedMatcherDescriptor(Overloads); 710 } 711 712 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 713 typename FromTypes, typename ToTypes> 714 template <typename FromTypeList> 715 inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, 716 ToTypes>::collect(FromTypeList) { 717 Out.push_back(makeMatcherAutoMarshall( 718 &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); 719 collect(typename FromTypeList::tail()); 720 } 721 722 /// \brief Variadic operator overload. 723 template <unsigned MinCount, unsigned MaxCount> 724 MatcherDescriptor * 725 makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc< 726 MinCount, MaxCount> Func, 727 StringRef MatcherName) { 728 return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op, 729 MatcherName); 730 } 731 732 } // namespace internal 733 } // namespace dynamic 734 } // namespace ast_matchers 735 } // namespace clang 736 737 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 738