10b57cec5SDimitry Andric //===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Functions templates and classes to wrap matcher construct functions. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric /// A collection of template function and classes that provide a generic 130b57cec5SDimitry Andric /// marshalling layer on top of matcher construct functions. 140b57cec5SDimitry Andric /// These are used by the registry to export all marshaller constructors with 150b57cec5SDimitry Andric /// the same generic interface. 160b57cec5SDimitry Andric // 170b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 200b57cec5SDimitry Andric #define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric #include "clang/AST/ASTTypeTraits.h" 230b57cec5SDimitry Andric #include "clang/AST/OperationKinds.h" 240b57cec5SDimitry Andric #include "clang/ASTMatchers/ASTMatchersInternal.h" 250b57cec5SDimitry Andric #include "clang/ASTMatchers/Dynamic/Diagnostics.h" 260b57cec5SDimitry Andric #include "clang/ASTMatchers/Dynamic/VariantValue.h" 270b57cec5SDimitry Andric #include "clang/Basic/AttrKinds.h" 280b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 290b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h" 305ffd83dbSDimitry Andric #include "clang/Basic/TypeTraits.h" 310b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 320b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 330b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 340b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 350b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 365ffd83dbSDimitry Andric #include "llvm/Support/Regex.h" 370b57cec5SDimitry Andric #include <cassert> 380b57cec5SDimitry Andric #include <cstddef> 390b57cec5SDimitry Andric #include <iterator> 400b57cec5SDimitry Andric #include <limits> 410b57cec5SDimitry Andric #include <memory> 42bdd1243dSDimitry Andric #include <optional> 430b57cec5SDimitry Andric #include <string> 440b57cec5SDimitry Andric #include <utility> 450b57cec5SDimitry Andric #include <vector> 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric namespace clang { 480b57cec5SDimitry Andric namespace ast_matchers { 490b57cec5SDimitry Andric namespace dynamic { 500b57cec5SDimitry Andric namespace internal { 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric /// Helper template class to just from argument type to the right is/get 530b57cec5SDimitry Andric /// functions in VariantValue. 540b57cec5SDimitry Andric /// Used to verify and extract the matcher arguments below. 550b57cec5SDimitry Andric template <class T> struct ArgTypeTraits; 560b57cec5SDimitry Andric template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 570b57cec5SDimitry Andric }; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric template <> struct ArgTypeTraits<std::string> { 60e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 61e8d8bef9SDimitry Andric return Value.isString(); 62e8d8bef9SDimitry Andric } 63e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue &Value) { return true; } 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric static const std::string &get(const VariantValue &Value) { 660b57cec5SDimitry Andric return Value.getString(); 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric static ArgKind getKind() { 700b57cec5SDimitry Andric return ArgKind(ArgKind::AK_String); 710b57cec5SDimitry Andric } 725ffd83dbSDimitry Andric 73bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &) { 74bdd1243dSDimitry Andric return std::nullopt; 755ffd83dbSDimitry Andric } 760b57cec5SDimitry Andric }; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric template <> 790b57cec5SDimitry Andric struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { 800b57cec5SDimitry Andric }; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> { 83e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue& Value) { 84e8d8bef9SDimitry Andric return Value.isMatcher(); 85e8d8bef9SDimitry Andric } 86e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue &Value) { 87e8d8bef9SDimitry Andric return Value.getMatcher().hasTypedMatcher<T>(); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { 910b57cec5SDimitry Andric return Value.getMatcher().getTypedMatcher<T>(); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static ArgKind getKind() { 95fe6060f1SDimitry Andric return ArgKind::MakeMatcherArg(ASTNodeKind::getFromNodeKind<T>()); 965ffd83dbSDimitry Andric } 975ffd83dbSDimitry Andric 98bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &) { 99bdd1243dSDimitry Andric return std::nullopt; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric }; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric template <> struct ArgTypeTraits<bool> { 104e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 105e8d8bef9SDimitry Andric return Value.isBoolean(); 106e8d8bef9SDimitry Andric } 107e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue &Value) { return true; } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric static bool get(const VariantValue &Value) { 1100b57cec5SDimitry Andric return Value.getBoolean(); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric static ArgKind getKind() { 1140b57cec5SDimitry Andric return ArgKind(ArgKind::AK_Boolean); 1150b57cec5SDimitry Andric } 1165ffd83dbSDimitry Andric 117bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &) { 118bdd1243dSDimitry Andric return std::nullopt; 1195ffd83dbSDimitry Andric } 1200b57cec5SDimitry Andric }; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric template <> struct ArgTypeTraits<double> { 123e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 124e8d8bef9SDimitry Andric return Value.isDouble(); 125e8d8bef9SDimitry Andric } 126e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue &Value) { return true; } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric static double get(const VariantValue &Value) { 1290b57cec5SDimitry Andric return Value.getDouble(); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric static ArgKind getKind() { 1330b57cec5SDimitry Andric return ArgKind(ArgKind::AK_Double); 1340b57cec5SDimitry Andric } 1355ffd83dbSDimitry Andric 136bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &) { 137bdd1243dSDimitry Andric return std::nullopt; 1385ffd83dbSDimitry Andric } 1390b57cec5SDimitry Andric }; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric template <> struct ArgTypeTraits<unsigned> { 142e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 143e8d8bef9SDimitry Andric return Value.isUnsigned(); 144e8d8bef9SDimitry Andric } 145e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue &Value) { return true; } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric static unsigned get(const VariantValue &Value) { 1480b57cec5SDimitry Andric return Value.getUnsigned(); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric static ArgKind getKind() { 1520b57cec5SDimitry Andric return ArgKind(ArgKind::AK_Unsigned); 1530b57cec5SDimitry Andric } 1545ffd83dbSDimitry Andric 155bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &) { 156bdd1243dSDimitry Andric return std::nullopt; 1575ffd83dbSDimitry Andric } 1580b57cec5SDimitry Andric }; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric template <> struct ArgTypeTraits<attr::Kind> { 1610b57cec5SDimitry Andric private: 162bdd1243dSDimitry Andric static std::optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) { 163e8d8bef9SDimitry Andric if (!AttrKind.consume_front("attr::")) 164bdd1243dSDimitry Andric return std::nullopt; 165bdd1243dSDimitry Andric return llvm::StringSwitch<std::optional<attr::Kind>>(AttrKind) 166e8d8bef9SDimitry Andric #define ATTR(X) .Case(#X, attr::X) 1670b57cec5SDimitry Andric #include "clang/Basic/AttrList.inc" 168bdd1243dSDimitry Andric .Default(std::nullopt); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric public: 172e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 173e8d8bef9SDimitry Andric return Value.isString(); 174e8d8bef9SDimitry Andric } 175e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue& Value) { 17681ad6265SDimitry Andric return getAttrKind(Value.getString()).has_value(); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric static attr::Kind get(const VariantValue &Value) { 1800b57cec5SDimitry Andric return *getAttrKind(Value.getString()); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric static ArgKind getKind() { 1840b57cec5SDimitry Andric return ArgKind(ArgKind::AK_String); 1850b57cec5SDimitry Andric } 1865ffd83dbSDimitry Andric 187bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &Value); 1880b57cec5SDimitry Andric }; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric template <> struct ArgTypeTraits<CastKind> { 1910b57cec5SDimitry Andric private: 192bdd1243dSDimitry Andric static std::optional<CastKind> getCastKind(llvm::StringRef AttrKind) { 193e8d8bef9SDimitry Andric if (!AttrKind.consume_front("CK_")) 194bdd1243dSDimitry Andric return std::nullopt; 195bdd1243dSDimitry Andric return llvm::StringSwitch<std::optional<CastKind>>(AttrKind) 196e8d8bef9SDimitry Andric #define CAST_OPERATION(Name) .Case(#Name, CK_##Name) 1970b57cec5SDimitry Andric #include "clang/AST/OperationKinds.def" 198bdd1243dSDimitry Andric .Default(std::nullopt); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric public: 202e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 203e8d8bef9SDimitry Andric return Value.isString(); 204e8d8bef9SDimitry Andric } 205e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue& Value) { 20681ad6265SDimitry Andric return getCastKind(Value.getString()).has_value(); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric static CastKind get(const VariantValue &Value) { 2100b57cec5SDimitry Andric return *getCastKind(Value.getString()); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric static ArgKind getKind() { 2140b57cec5SDimitry Andric return ArgKind(ArgKind::AK_String); 2150b57cec5SDimitry Andric } 2165ffd83dbSDimitry Andric 217bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &Value); 2185ffd83dbSDimitry Andric }; 2195ffd83dbSDimitry Andric 2205ffd83dbSDimitry Andric template <> struct ArgTypeTraits<llvm::Regex::RegexFlags> { 2215ffd83dbSDimitry Andric private: 222bdd1243dSDimitry Andric static std::optional<llvm::Regex::RegexFlags> getFlags(llvm::StringRef Flags); 2235ffd83dbSDimitry Andric 2245ffd83dbSDimitry Andric public: 225e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 226e8d8bef9SDimitry Andric return Value.isString(); 227e8d8bef9SDimitry Andric } 228e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue& Value) { 22981ad6265SDimitry Andric return getFlags(Value.getString()).has_value(); 2305ffd83dbSDimitry Andric } 2315ffd83dbSDimitry Andric 2325ffd83dbSDimitry Andric static llvm::Regex::RegexFlags get(const VariantValue &Value) { 2335ffd83dbSDimitry Andric return *getFlags(Value.getString()); 2345ffd83dbSDimitry Andric } 2355ffd83dbSDimitry Andric 2365ffd83dbSDimitry Andric static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } 2375ffd83dbSDimitry Andric 238bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &Value); 2390b57cec5SDimitry Andric }; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric template <> struct ArgTypeTraits<OpenMPClauseKind> { 2420b57cec5SDimitry Andric private: 243bdd1243dSDimitry Andric static std::optional<OpenMPClauseKind> 244bdd1243dSDimitry Andric getClauseKind(llvm::StringRef ClauseKind) { 245bdd1243dSDimitry Andric return llvm::StringSwitch<std::optional<OpenMPClauseKind>>(ClauseKind) 246e8d8bef9SDimitry Andric #define GEN_CLANG_CLAUSE_CLASS 247e8d8bef9SDimitry Andric #define CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) 248e8d8bef9SDimitry Andric #include "llvm/Frontend/OpenMP/OMP.inc" 249bdd1243dSDimitry Andric .Default(std::nullopt); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric public: 253e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 254e8d8bef9SDimitry Andric return Value.isString(); 255e8d8bef9SDimitry Andric } 256e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue& Value) { 25781ad6265SDimitry Andric return getClauseKind(Value.getString()).has_value(); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric static OpenMPClauseKind get(const VariantValue &Value) { 2610b57cec5SDimitry Andric return *getClauseKind(Value.getString()); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } 2655ffd83dbSDimitry Andric 266bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &Value); 2675ffd83dbSDimitry Andric }; 2685ffd83dbSDimitry Andric 2695ffd83dbSDimitry Andric template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> { 2705ffd83dbSDimitry Andric private: 271bdd1243dSDimitry Andric static std::optional<UnaryExprOrTypeTrait> 2725ffd83dbSDimitry Andric getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) { 273e8d8bef9SDimitry Andric if (!ClauseKind.consume_front("UETT_")) 274bdd1243dSDimitry Andric return std::nullopt; 275bdd1243dSDimitry Andric return llvm::StringSwitch<std::optional<UnaryExprOrTypeTrait>>(ClauseKind) 276e8d8bef9SDimitry Andric #define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name) 2775ffd83dbSDimitry Andric #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \ 278e8d8bef9SDimitry Andric .Case(#Name, UETT_##Name) 2795ffd83dbSDimitry Andric #include "clang/Basic/TokenKinds.def" 280bdd1243dSDimitry Andric .Default(std::nullopt); 2815ffd83dbSDimitry Andric } 2825ffd83dbSDimitry Andric 2835ffd83dbSDimitry Andric public: 284e8d8bef9SDimitry Andric static bool hasCorrectType(const VariantValue &Value) { 285e8d8bef9SDimitry Andric return Value.isString(); 286e8d8bef9SDimitry Andric } 287e8d8bef9SDimitry Andric static bool hasCorrectValue(const VariantValue& Value) { 28881ad6265SDimitry Andric return getUnaryOrTypeTraitKind(Value.getString()).has_value(); 2895ffd83dbSDimitry Andric } 2905ffd83dbSDimitry Andric 2915ffd83dbSDimitry Andric static UnaryExprOrTypeTrait get(const VariantValue &Value) { 2925ffd83dbSDimitry Andric return *getUnaryOrTypeTraitKind(Value.getString()); 2935ffd83dbSDimitry Andric } 2945ffd83dbSDimitry Andric 2955ffd83dbSDimitry Andric static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } 2965ffd83dbSDimitry Andric 297bdd1243dSDimitry Andric static std::optional<std::string> getBestGuess(const VariantValue &Value); 2980b57cec5SDimitry Andric }; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric /// Matcher descriptor interface. 3010b57cec5SDimitry Andric /// 3020b57cec5SDimitry Andric /// Provides a \c create() method that constructs the matcher from the provided 3030b57cec5SDimitry Andric /// arguments, and various other methods for type introspection. 3040b57cec5SDimitry Andric class MatcherDescriptor { 3050b57cec5SDimitry Andric public: 3060b57cec5SDimitry Andric virtual ~MatcherDescriptor() = default; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric virtual VariantMatcher create(SourceRange NameRange, 3090b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 3100b57cec5SDimitry Andric Diagnostics *Error) const = 0; 3110b57cec5SDimitry Andric 312fe6060f1SDimitry Andric virtual ASTNodeKind nodeMatcherType() const { return ASTNodeKind(); } 313fe6060f1SDimitry Andric 314fe6060f1SDimitry Andric virtual bool isBuilderMatcher() const { return false; } 315fe6060f1SDimitry Andric 316fe6060f1SDimitry Andric virtual std::unique_ptr<MatcherDescriptor> 317fe6060f1SDimitry Andric buildMatcherCtor(SourceRange NameRange, ArrayRef<ParserValue> Args, 318fe6060f1SDimitry Andric Diagnostics *Error) const { 319fe6060f1SDimitry Andric return {}; 320fe6060f1SDimitry Andric } 321fe6060f1SDimitry Andric 3220b57cec5SDimitry Andric /// Returns whether the matcher is variadic. Variadic matchers can take any 3230b57cec5SDimitry Andric /// number of arguments, but they must be of the same type. 3240b57cec5SDimitry Andric virtual bool isVariadic() const = 0; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric /// Returns the number of arguments accepted by the matcher if not variadic. 3270b57cec5SDimitry Andric virtual unsigned getNumArgs() const = 0; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric /// Given that the matcher is being converted to type \p ThisKind, append the 3300b57cec5SDimitry Andric /// set of argument types accepted for argument \p ArgNo to \p ArgKinds. 3310b57cec5SDimitry Andric // FIXME: We should provide the ability to constrain the output of this 3320b57cec5SDimitry Andric // function based on the types of other matcher arguments. 3335ffd83dbSDimitry Andric virtual void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 3340b57cec5SDimitry Andric std::vector<ArgKind> &ArgKinds) const = 0; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric /// Returns whether this matcher is convertible to the given type. If it is 3370b57cec5SDimitry Andric /// so convertible, store in *Specificity a value corresponding to the 3380b57cec5SDimitry Andric /// "specificity" of the converted matcher to the given context, and in 3390b57cec5SDimitry Andric /// *LeastDerivedKind the least derived matcher kind which would result in the 3400b57cec5SDimitry Andric /// same matcher overload. Zero specificity indicates that this conversion 3410b57cec5SDimitry Andric /// would produce a trivial matcher that will either always or never match. 3420b57cec5SDimitry Andric /// Such matchers are excluded from code completion results. 3435ffd83dbSDimitry Andric virtual bool 3445ffd83dbSDimitry Andric isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr, 3455ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind = nullptr) const = 0; 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric /// Returns whether the matcher will, given a matcher of any type T, yield a 3480b57cec5SDimitry Andric /// matcher of type T. 3490b57cec5SDimitry Andric virtual bool isPolymorphic() const { return false; } 3500b57cec5SDimitry Andric }; 3510b57cec5SDimitry Andric 3525ffd83dbSDimitry Andric inline bool isRetKindConvertibleTo(ArrayRef<ASTNodeKind> RetKinds, 3535ffd83dbSDimitry Andric ASTNodeKind Kind, unsigned *Specificity, 3545ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) { 3555ffd83dbSDimitry Andric for (const ASTNodeKind &NodeKind : RetKinds) { 356fe6060f1SDimitry Andric if (ArgKind::MakeMatcherArg(NodeKind).isConvertibleTo( 357fe6060f1SDimitry Andric ArgKind::MakeMatcherArg(Kind), Specificity)) { 3580b57cec5SDimitry Andric if (LeastDerivedKind) 3590b57cec5SDimitry Andric *LeastDerivedKind = NodeKind; 3600b57cec5SDimitry Andric return true; 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric return false; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric /// Simple callback implementation. Marshaller and function are provided. 3670b57cec5SDimitry Andric /// 3680b57cec5SDimitry Andric /// This class wraps a function of arbitrary signature and a marshaller 3690b57cec5SDimitry Andric /// function into a MatcherDescriptor. 3700b57cec5SDimitry Andric /// The marshaller is in charge of taking the VariantValue arguments, checking 3710b57cec5SDimitry Andric /// their types, unpacking them and calling the underlying function. 3720b57cec5SDimitry Andric class FixedArgCountMatcherDescriptor : public MatcherDescriptor { 3730b57cec5SDimitry Andric public: 3740b57cec5SDimitry Andric using MarshallerType = VariantMatcher (*)(void (*Func)(), 3750b57cec5SDimitry Andric StringRef MatcherName, 3760b57cec5SDimitry Andric SourceRange NameRange, 3770b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 3780b57cec5SDimitry Andric Diagnostics *Error); 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric /// \param Marshaller Function to unpack the arguments and call \c Func 3810b57cec5SDimitry Andric /// \param Func Matcher construct function. This is the function that 3820b57cec5SDimitry Andric /// compile-time matcher expressions would use to create the matcher. 3830b57cec5SDimitry Andric /// \param RetKinds The list of matcher types to which the matcher is 3840b57cec5SDimitry Andric /// convertible. 3850b57cec5SDimitry Andric /// \param ArgKinds The types of the arguments this matcher takes. 3865ffd83dbSDimitry Andric FixedArgCountMatcherDescriptor(MarshallerType Marshaller, void (*Func)(), 3875ffd83dbSDimitry Andric StringRef MatcherName, 3885ffd83dbSDimitry Andric ArrayRef<ASTNodeKind> RetKinds, 3890b57cec5SDimitry Andric ArrayRef<ArgKind> ArgKinds) 3900b57cec5SDimitry Andric : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName), 3910b57cec5SDimitry Andric RetKinds(RetKinds.begin(), RetKinds.end()), 3920b57cec5SDimitry Andric ArgKinds(ArgKinds.begin(), ArgKinds.end()) {} 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric VariantMatcher create(SourceRange NameRange, 3950b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 3960b57cec5SDimitry Andric Diagnostics *Error) const override { 3970b57cec5SDimitry Andric return Marshaller(Func, MatcherName, NameRange, Args, Error); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric bool isVariadic() const override { return false; } 4010b57cec5SDimitry Andric unsigned getNumArgs() const override { return ArgKinds.size(); } 4020b57cec5SDimitry Andric 4035ffd83dbSDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 4040b57cec5SDimitry Andric std::vector<ArgKind> &Kinds) const override { 4050b57cec5SDimitry Andric Kinds.push_back(ArgKinds[ArgNo]); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4085ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 4095ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 4100b57cec5SDimitry Andric return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 4110b57cec5SDimitry Andric LeastDerivedKind); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric private: 4150b57cec5SDimitry Andric const MarshallerType Marshaller; 4160b57cec5SDimitry Andric void (* const Func)(); 4170b57cec5SDimitry Andric const std::string MatcherName; 4185ffd83dbSDimitry Andric const std::vector<ASTNodeKind> RetKinds; 4190b57cec5SDimitry Andric const std::vector<ArgKind> ArgKinds; 4200b57cec5SDimitry Andric }; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric /// Helper methods to extract and merge all possible typed matchers 4230b57cec5SDimitry Andric /// out of the polymorphic object. 4240b57cec5SDimitry Andric template <class PolyMatcher> 4250b57cec5SDimitry Andric static void mergePolyMatchers(const PolyMatcher &Poly, 4260b57cec5SDimitry Andric std::vector<DynTypedMatcher> &Out, 4270b57cec5SDimitry Andric ast_matchers::internal::EmptyTypeList) {} 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric template <class PolyMatcher, class TypeList> 4300b57cec5SDimitry Andric static void mergePolyMatchers(const PolyMatcher &Poly, 4310b57cec5SDimitry Andric std::vector<DynTypedMatcher> &Out, TypeList) { 4320b57cec5SDimitry Andric Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); 4330b57cec5SDimitry Andric mergePolyMatchers(Poly, Out, typename TypeList::tail()); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric /// Convert the return values of the functions into a VariantMatcher. 4370b57cec5SDimitry Andric /// 4380b57cec5SDimitry Andric /// There are 2 cases right now: The return value is a Matcher<T> or is a 4390b57cec5SDimitry Andric /// polymorphic matcher. For the former, we just construct the VariantMatcher. 4400b57cec5SDimitry Andric /// For the latter, we instantiate all the possible Matcher<T> of the poly 4410b57cec5SDimitry Andric /// matcher. 4425ffd83dbSDimitry Andric inline VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 4430b57cec5SDimitry Andric return VariantMatcher::SingleMatcher(Matcher); 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric template <typename T> 4470b57cec5SDimitry Andric static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, 4480b57cec5SDimitry Andric typename T::ReturnTypes * = 4490b57cec5SDimitry Andric nullptr) { 4500b57cec5SDimitry Andric std::vector<DynTypedMatcher> Matchers; 4510b57cec5SDimitry Andric mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); 4520b57cec5SDimitry Andric VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers)); 4530b57cec5SDimitry Andric return Out; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric template <typename T> 4575ffd83dbSDimitry Andric inline void 4585ffd83dbSDimitry Andric buildReturnTypeVectorFromTypeList(std::vector<ASTNodeKind> &RetTypes) { 4595ffd83dbSDimitry Andric RetTypes.push_back(ASTNodeKind::getFromNodeKind<typename T::head>()); 4600b57cec5SDimitry Andric buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric template <> 4640b57cec5SDimitry Andric inline void 4650b57cec5SDimitry Andric buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>( 4665ffd83dbSDimitry Andric std::vector<ASTNodeKind> &RetTypes) {} 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric template <typename T> 4690b57cec5SDimitry Andric struct BuildReturnTypeVector { 4705ffd83dbSDimitry Andric static void build(std::vector<ASTNodeKind> &RetTypes) { 4710b57cec5SDimitry Andric buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes); 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric }; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric template <typename T> 4760b57cec5SDimitry Andric struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> { 4775ffd83dbSDimitry Andric static void build(std::vector<ASTNodeKind> &RetTypes) { 4785ffd83dbSDimitry Andric RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>()); 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric }; 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric template <typename T> 4830b57cec5SDimitry Andric struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> { 4845ffd83dbSDimitry Andric static void build(std::vector<ASTNodeKind> &RetTypes) { 4855ffd83dbSDimitry Andric RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>()); 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric }; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric /// Variadic marshaller function. 4900b57cec5SDimitry Andric template <typename ResultT, typename ArgT, 4910b57cec5SDimitry Andric ResultT (*Func)(ArrayRef<const ArgT *>)> 4920b57cec5SDimitry Andric VariantMatcher 4930b57cec5SDimitry Andric variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, 4940b57cec5SDimitry Andric ArrayRef<ParserValue> Args, Diagnostics *Error) { 495fe6060f1SDimitry Andric SmallVector<ArgT *, 8> InnerArgsPtr; 496fe6060f1SDimitry Andric InnerArgsPtr.resize_for_overwrite(Args.size()); 497fe6060f1SDimitry Andric SmallVector<ArgT, 8> InnerArgs; 498fe6060f1SDimitry Andric InnerArgs.reserve(Args.size()); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric for (size_t i = 0, e = Args.size(); i != e; ++i) { 5010b57cec5SDimitry Andric using ArgTraits = ArgTypeTraits<ArgT>; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric const ParserValue &Arg = Args[i]; 5040b57cec5SDimitry Andric const VariantValue &Value = Arg.Value; 505e8d8bef9SDimitry Andric if (!ArgTraits::hasCorrectType(Value)) { 5060b57cec5SDimitry Andric Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 5070b57cec5SDimitry Andric << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); 508fe6060f1SDimitry Andric return {}; 5090b57cec5SDimitry Andric } 510e8d8bef9SDimitry Andric if (!ArgTraits::hasCorrectValue(Value)) { 511bdd1243dSDimitry Andric if (std::optional<std::string> BestGuess = 512e8d8bef9SDimitry Andric ArgTraits::getBestGuess(Value)) { 513e8d8bef9SDimitry Andric Error->addError(Arg.Range, Error->ET_RegistryUnknownEnumWithReplace) 514e8d8bef9SDimitry Andric << i + 1 << Value.getString() << *BestGuess; 515e8d8bef9SDimitry Andric } else if (Value.isString()) { 516e8d8bef9SDimitry Andric Error->addError(Arg.Range, Error->ET_RegistryValueNotFound) 517e8d8bef9SDimitry Andric << Value.getString(); 518e8d8bef9SDimitry Andric } else { 519e8d8bef9SDimitry Andric // This isn't ideal, but it's better than reporting an empty string as 520e8d8bef9SDimitry Andric // the error in this case. 521e8d8bef9SDimitry Andric Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 522e8d8bef9SDimitry Andric << (i + 1) << ArgTraits::getKind().asString() 523e8d8bef9SDimitry Andric << Value.getTypeAsString(); 524e8d8bef9SDimitry Andric } 525fe6060f1SDimitry Andric return {}; 526e8d8bef9SDimitry Andric } 52704eeddc0SDimitry Andric assert(InnerArgs.size() < InnerArgs.capacity()); 52804eeddc0SDimitry Andric InnerArgs.emplace_back(ArgTraits::get(Value)); 52904eeddc0SDimitry Andric InnerArgsPtr[i] = &InnerArgs[i]; 5300b57cec5SDimitry Andric } 531fe6060f1SDimitry Andric return outvalueToVariantMatcher(Func(InnerArgsPtr)); 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric /// Matcher descriptor for variadic functions. 5350b57cec5SDimitry Andric /// 5360b57cec5SDimitry Andric /// This class simply wraps a VariadicFunction with the right signature to export 5370b57cec5SDimitry Andric /// it as a MatcherDescriptor. 5380b57cec5SDimitry Andric /// This allows us to have one implementation of the interface for as many free 5390b57cec5SDimitry Andric /// functions as we want, reducing the number of symbols and size of the 5400b57cec5SDimitry Andric /// object file. 5410b57cec5SDimitry Andric class VariadicFuncMatcherDescriptor : public MatcherDescriptor { 5420b57cec5SDimitry Andric public: 5430b57cec5SDimitry Andric using RunFunc = VariantMatcher (*)(StringRef MatcherName, 5440b57cec5SDimitry Andric SourceRange NameRange, 5450b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 5460b57cec5SDimitry Andric Diagnostics *Error); 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric template <typename ResultT, typename ArgT, 5490b57cec5SDimitry Andric ResultT (*F)(ArrayRef<const ArgT *>)> 5500b57cec5SDimitry Andric VariadicFuncMatcherDescriptor( 5510b57cec5SDimitry Andric ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func, 5520b57cec5SDimitry Andric StringRef MatcherName) 5530b57cec5SDimitry Andric : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), 5540b57cec5SDimitry Andric MatcherName(MatcherName.str()), 5550b57cec5SDimitry Andric ArgsKind(ArgTypeTraits<ArgT>::getKind()) { 5560b57cec5SDimitry Andric BuildReturnTypeVector<ResultT>::build(RetKinds); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric VariantMatcher create(SourceRange NameRange, 5600b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 5610b57cec5SDimitry Andric Diagnostics *Error) const override { 5620b57cec5SDimitry Andric return Func(MatcherName, NameRange, Args, Error); 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric bool isVariadic() const override { return true; } 5660b57cec5SDimitry Andric unsigned getNumArgs() const override { return 0; } 5670b57cec5SDimitry Andric 5685ffd83dbSDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 5690b57cec5SDimitry Andric std::vector<ArgKind> &Kinds) const override { 5700b57cec5SDimitry Andric Kinds.push_back(ArgsKind); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric 5735ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 5745ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 5750b57cec5SDimitry Andric return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 5760b57cec5SDimitry Andric LeastDerivedKind); 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 579fe6060f1SDimitry Andric ASTNodeKind nodeMatcherType() const override { return RetKinds[0]; } 580fe6060f1SDimitry Andric 5810b57cec5SDimitry Andric private: 5820b57cec5SDimitry Andric const RunFunc Func; 5830b57cec5SDimitry Andric const std::string MatcherName; 5845ffd83dbSDimitry Andric std::vector<ASTNodeKind> RetKinds; 5850b57cec5SDimitry Andric const ArgKind ArgsKind; 5860b57cec5SDimitry Andric }; 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric /// Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers. 5890b57cec5SDimitry Andric class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor { 5900b57cec5SDimitry Andric public: 5910b57cec5SDimitry Andric template <typename BaseT, typename DerivedT> 5920b57cec5SDimitry Andric DynCastAllOfMatcherDescriptor( 5930b57cec5SDimitry Andric ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func, 5940b57cec5SDimitry Andric StringRef MatcherName) 5950b57cec5SDimitry Andric : VariadicFuncMatcherDescriptor(Func, MatcherName), 5965ffd83dbSDimitry Andric DerivedKind(ASTNodeKind::getFromNodeKind<DerivedT>()) {} 5970b57cec5SDimitry Andric 5985ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 5995ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 6000b57cec5SDimitry Andric // If Kind is not a base of DerivedKind, either DerivedKind is a base of 6010b57cec5SDimitry Andric // Kind (in which case the match will always succeed) or Kind and 6020b57cec5SDimitry Andric // DerivedKind are unrelated (in which case it will always fail), so set 6030b57cec5SDimitry Andric // Specificity to 0. 6040b57cec5SDimitry Andric if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity, 6050b57cec5SDimitry Andric LeastDerivedKind)) { 6060b57cec5SDimitry Andric if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) { 6070b57cec5SDimitry Andric if (Specificity) 6080b57cec5SDimitry Andric *Specificity = 0; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric return true; 6110b57cec5SDimitry Andric } else { 6120b57cec5SDimitry Andric return false; 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 616fe6060f1SDimitry Andric ASTNodeKind nodeMatcherType() const override { return DerivedKind; } 617fe6060f1SDimitry Andric 6180b57cec5SDimitry Andric private: 6195ffd83dbSDimitry Andric const ASTNodeKind DerivedKind; 6200b57cec5SDimitry Andric }; 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric /// Helper macros to check the arguments on all marshaller functions. 6230b57cec5SDimitry Andric #define CHECK_ARG_COUNT(count) \ 6240b57cec5SDimitry Andric if (Args.size() != count) { \ 6250b57cec5SDimitry Andric Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ 6260b57cec5SDimitry Andric << count << Args.size(); \ 6270b57cec5SDimitry Andric return VariantMatcher(); \ 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric #define CHECK_ARG_TYPE(index, type) \ 631e8d8bef9SDimitry Andric if (!ArgTypeTraits<type>::hasCorrectType(Args[index].Value)) { \ 632e8d8bef9SDimitry Andric Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ 633e8d8bef9SDimitry Andric << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ 634e8d8bef9SDimitry Andric << Args[index].Value.getTypeAsString(); \ 635e8d8bef9SDimitry Andric return VariantMatcher(); \ 636e8d8bef9SDimitry Andric } \ 637e8d8bef9SDimitry Andric if (!ArgTypeTraits<type>::hasCorrectValue(Args[index].Value)) { \ 638bdd1243dSDimitry Andric if (std::optional<std::string> BestGuess = \ 6395ffd83dbSDimitry Andric ArgTypeTraits<type>::getBestGuess(Args[index].Value)) { \ 6405ffd83dbSDimitry Andric Error->addError(Args[index].Range, \ 6415ffd83dbSDimitry Andric Error->ET_RegistryUnknownEnumWithReplace) \ 6425ffd83dbSDimitry Andric << index + 1 << Args[index].Value.getString() << *BestGuess; \ 643e8d8bef9SDimitry Andric } else if (Args[index].Value.isString()) { \ 644e8d8bef9SDimitry Andric Error->addError(Args[index].Range, Error->ET_RegistryValueNotFound) \ 645e8d8bef9SDimitry Andric << Args[index].Value.getString(); \ 6465ffd83dbSDimitry Andric } \ 6470b57cec5SDimitry Andric return VariantMatcher(); \ 6480b57cec5SDimitry Andric } 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric /// 0-arg marshaller function. 6510b57cec5SDimitry Andric template <typename ReturnType> 6520b57cec5SDimitry Andric static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, 6530b57cec5SDimitry Andric SourceRange NameRange, 6540b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 6550b57cec5SDimitry Andric Diagnostics *Error) { 6560b57cec5SDimitry Andric using FuncType = ReturnType (*)(); 6570b57cec5SDimitry Andric CHECK_ARG_COUNT(0); 6580b57cec5SDimitry Andric return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)()); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric /// 1-arg marshaller function. 6620b57cec5SDimitry Andric template <typename ReturnType, typename ArgType1> 6630b57cec5SDimitry Andric static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName, 6640b57cec5SDimitry Andric SourceRange NameRange, 6650b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 6660b57cec5SDimitry Andric Diagnostics *Error) { 6670b57cec5SDimitry Andric using FuncType = ReturnType (*)(ArgType1); 6680b57cec5SDimitry Andric CHECK_ARG_COUNT(1); 6690b57cec5SDimitry Andric CHECK_ARG_TYPE(0, ArgType1); 6700b57cec5SDimitry Andric return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 6710b57cec5SDimitry Andric ArgTypeTraits<ArgType1>::get(Args[0].Value))); 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric /// 2-arg marshaller function. 6750b57cec5SDimitry Andric template <typename ReturnType, typename ArgType1, typename ArgType2> 6760b57cec5SDimitry Andric static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName, 6770b57cec5SDimitry Andric SourceRange NameRange, 6780b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 6790b57cec5SDimitry Andric Diagnostics *Error) { 6800b57cec5SDimitry Andric using FuncType = ReturnType (*)(ArgType1, ArgType2); 6810b57cec5SDimitry Andric CHECK_ARG_COUNT(2); 6820b57cec5SDimitry Andric CHECK_ARG_TYPE(0, ArgType1); 6830b57cec5SDimitry Andric CHECK_ARG_TYPE(1, ArgType2); 6840b57cec5SDimitry Andric return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 6850b57cec5SDimitry Andric ArgTypeTraits<ArgType1>::get(Args[0].Value), 6860b57cec5SDimitry Andric ArgTypeTraits<ArgType2>::get(Args[1].Value))); 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric #undef CHECK_ARG_COUNT 6900b57cec5SDimitry Andric #undef CHECK_ARG_TYPE 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric /// Helper class used to collect all the possible overloads of an 6930b57cec5SDimitry Andric /// argument adaptative matcher function. 6940b57cec5SDimitry Andric template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 6950b57cec5SDimitry Andric typename FromTypes, typename ToTypes> 6960b57cec5SDimitry Andric class AdaptativeOverloadCollector { 6970b57cec5SDimitry Andric public: 6980b57cec5SDimitry Andric AdaptativeOverloadCollector( 6990b57cec5SDimitry Andric StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out) 7000b57cec5SDimitry Andric : Name(Name), Out(Out) { 7010b57cec5SDimitry Andric collect(FromTypes()); 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric private: 7050b57cec5SDimitry Andric using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc< 7060b57cec5SDimitry Andric ArgumentAdapterT, FromTypes, ToTypes>; 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric /// End case for the recursion 7090b57cec5SDimitry Andric static void collect(ast_matchers::internal::EmptyTypeList) {} 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric /// Recursive case. Get the overload for the head of the list, and 7120b57cec5SDimitry Andric /// recurse to the tail. 7130b57cec5SDimitry Andric template <typename FromTypeList> 7140b57cec5SDimitry Andric inline void collect(FromTypeList); 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric StringRef Name; 7170b57cec5SDimitry Andric std::vector<std::unique_ptr<MatcherDescriptor>> &Out; 7180b57cec5SDimitry Andric }; 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric /// MatcherDescriptor that wraps multiple "overloads" of the same 7210b57cec5SDimitry Andric /// matcher. 7220b57cec5SDimitry Andric /// 7230b57cec5SDimitry Andric /// It will try every overload and generate appropriate errors for when none or 7240b57cec5SDimitry Andric /// more than one overloads match the arguments. 7250b57cec5SDimitry Andric class OverloadedMatcherDescriptor : public MatcherDescriptor { 7260b57cec5SDimitry Andric public: 7270b57cec5SDimitry Andric OverloadedMatcherDescriptor( 7280b57cec5SDimitry Andric MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks) 7290b57cec5SDimitry Andric : Overloads(std::make_move_iterator(Callbacks.begin()), 7300b57cec5SDimitry Andric std::make_move_iterator(Callbacks.end())) {} 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric ~OverloadedMatcherDescriptor() override = default; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric VariantMatcher create(SourceRange NameRange, 7350b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 7360b57cec5SDimitry Andric Diagnostics *Error) const override { 7370b57cec5SDimitry Andric std::vector<VariantMatcher> Constructed; 7380b57cec5SDimitry Andric Diagnostics::OverloadContext Ctx(Error); 7390b57cec5SDimitry Andric for (const auto &O : Overloads) { 7400b57cec5SDimitry Andric VariantMatcher SubMatcher = O->create(NameRange, Args, Error); 7410b57cec5SDimitry Andric if (!SubMatcher.isNull()) { 7420b57cec5SDimitry Andric Constructed.push_back(SubMatcher); 7430b57cec5SDimitry Andric } 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric if (Constructed.empty()) return VariantMatcher(); // No overload matched. 7470b57cec5SDimitry Andric // We ignore the errors if any matcher succeeded. 7480b57cec5SDimitry Andric Ctx.revertErrors(); 7490b57cec5SDimitry Andric if (Constructed.size() > 1) { 7500b57cec5SDimitry Andric // More than one constructed. It is ambiguous. 7510b57cec5SDimitry Andric Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); 7520b57cec5SDimitry Andric return VariantMatcher(); 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric return Constructed[0]; 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric bool isVariadic() const override { 7580b57cec5SDimitry Andric bool Overload0Variadic = Overloads[0]->isVariadic(); 7590b57cec5SDimitry Andric #ifndef NDEBUG 7600b57cec5SDimitry Andric for (const auto &O : Overloads) { 7610b57cec5SDimitry Andric assert(Overload0Variadic == O->isVariadic()); 7620b57cec5SDimitry Andric } 7630b57cec5SDimitry Andric #endif 7640b57cec5SDimitry Andric return Overload0Variadic; 7650b57cec5SDimitry Andric } 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric unsigned getNumArgs() const override { 7680b57cec5SDimitry Andric unsigned Overload0NumArgs = Overloads[0]->getNumArgs(); 7690b57cec5SDimitry Andric #ifndef NDEBUG 7700b57cec5SDimitry Andric for (const auto &O : Overloads) { 7710b57cec5SDimitry Andric assert(Overload0NumArgs == O->getNumArgs()); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric #endif 7740b57cec5SDimitry Andric return Overload0NumArgs; 7750b57cec5SDimitry Andric } 7760b57cec5SDimitry Andric 7775ffd83dbSDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 7780b57cec5SDimitry Andric std::vector<ArgKind> &Kinds) const override { 7790b57cec5SDimitry Andric for (const auto &O : Overloads) { 7800b57cec5SDimitry Andric if (O->isConvertibleTo(ThisKind)) 7810b57cec5SDimitry Andric O->getArgKinds(ThisKind, ArgNo, Kinds); 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric 7855ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 7865ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 7870b57cec5SDimitry Andric for (const auto &O : Overloads) { 7880b57cec5SDimitry Andric if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind)) 7890b57cec5SDimitry Andric return true; 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric return false; 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric private: 7950b57cec5SDimitry Andric std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; 7960b57cec5SDimitry Andric }; 7970b57cec5SDimitry Andric 7985ffd83dbSDimitry Andric template <typename ReturnType> 7995ffd83dbSDimitry Andric class RegexMatcherDescriptor : public MatcherDescriptor { 8005ffd83dbSDimitry Andric public: 8015ffd83dbSDimitry Andric RegexMatcherDescriptor(ReturnType (*WithFlags)(StringRef, 8025ffd83dbSDimitry Andric llvm::Regex::RegexFlags), 8035ffd83dbSDimitry Andric ReturnType (*NoFlags)(StringRef), 8045ffd83dbSDimitry Andric ArrayRef<ASTNodeKind> RetKinds) 8055ffd83dbSDimitry Andric : WithFlags(WithFlags), NoFlags(NoFlags), 8065ffd83dbSDimitry Andric RetKinds(RetKinds.begin(), RetKinds.end()) {} 8075ffd83dbSDimitry Andric bool isVariadic() const override { return true; } 8085ffd83dbSDimitry Andric unsigned getNumArgs() const override { return 0; } 8095ffd83dbSDimitry Andric 8105ffd83dbSDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 8115ffd83dbSDimitry Andric std::vector<ArgKind> &Kinds) const override { 8125ffd83dbSDimitry Andric assert(ArgNo < 2); 8135ffd83dbSDimitry Andric Kinds.push_back(ArgKind::AK_String); 8145ffd83dbSDimitry Andric } 8155ffd83dbSDimitry Andric 8165ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 8175ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 8185ffd83dbSDimitry Andric return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 8195ffd83dbSDimitry Andric LeastDerivedKind); 8205ffd83dbSDimitry Andric } 8215ffd83dbSDimitry Andric 8225ffd83dbSDimitry Andric VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args, 8235ffd83dbSDimitry Andric Diagnostics *Error) const override { 8245ffd83dbSDimitry Andric if (Args.size() < 1 || Args.size() > 2) { 8255ffd83dbSDimitry Andric Error->addError(NameRange, Diagnostics::ET_RegistryWrongArgCount) 8265ffd83dbSDimitry Andric << "1 or 2" << Args.size(); 8275ffd83dbSDimitry Andric return VariantMatcher(); 8285ffd83dbSDimitry Andric } 829e8d8bef9SDimitry Andric if (!ArgTypeTraits<StringRef>::hasCorrectType(Args[0].Value)) { 8305ffd83dbSDimitry Andric Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType) 8315ffd83dbSDimitry Andric << 1 << ArgTypeTraits<StringRef>::getKind().asString() 8325ffd83dbSDimitry Andric << Args[0].Value.getTypeAsString(); 8335ffd83dbSDimitry Andric return VariantMatcher(); 8345ffd83dbSDimitry Andric } 8355ffd83dbSDimitry Andric if (Args.size() == 1) { 8365ffd83dbSDimitry Andric return outvalueToVariantMatcher( 8375ffd83dbSDimitry Andric NoFlags(ArgTypeTraits<StringRef>::get(Args[0].Value))); 8385ffd83dbSDimitry Andric } 839e8d8bef9SDimitry Andric if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType( 840e8d8bef9SDimitry Andric Args[1].Value)) { 841e8d8bef9SDimitry Andric Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType) 842e8d8bef9SDimitry Andric << 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString() 843e8d8bef9SDimitry Andric << Args[1].Value.getTypeAsString(); 844e8d8bef9SDimitry Andric return VariantMatcher(); 845e8d8bef9SDimitry Andric } 846e8d8bef9SDimitry Andric if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectValue( 847e8d8bef9SDimitry Andric Args[1].Value)) { 848bdd1243dSDimitry Andric if (std::optional<std::string> BestGuess = 8495ffd83dbSDimitry Andric ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess( 8505ffd83dbSDimitry Andric Args[1].Value)) { 8515ffd83dbSDimitry Andric Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace) 8525ffd83dbSDimitry Andric << 2 << Args[1].Value.getString() << *BestGuess; 8535ffd83dbSDimitry Andric } else { 854e8d8bef9SDimitry Andric Error->addError(Args[1].Range, Error->ET_RegistryValueNotFound) 855e8d8bef9SDimitry Andric << Args[1].Value.getString(); 8565ffd83dbSDimitry Andric } 8575ffd83dbSDimitry Andric return VariantMatcher(); 8585ffd83dbSDimitry Andric } 8595ffd83dbSDimitry Andric return outvalueToVariantMatcher( 8605ffd83dbSDimitry Andric WithFlags(ArgTypeTraits<StringRef>::get(Args[0].Value), 8615ffd83dbSDimitry Andric ArgTypeTraits<llvm::Regex::RegexFlags>::get(Args[1].Value))); 8625ffd83dbSDimitry Andric } 8635ffd83dbSDimitry Andric 8645ffd83dbSDimitry Andric private: 8655ffd83dbSDimitry Andric ReturnType (*const WithFlags)(StringRef, llvm::Regex::RegexFlags); 8665ffd83dbSDimitry Andric ReturnType (*const NoFlags)(StringRef); 8675ffd83dbSDimitry Andric const std::vector<ASTNodeKind> RetKinds; 8685ffd83dbSDimitry Andric }; 8695ffd83dbSDimitry Andric 8700b57cec5SDimitry Andric /// Variadic operator marshaller function. 8710b57cec5SDimitry Andric class VariadicOperatorMatcherDescriptor : public MatcherDescriptor { 8720b57cec5SDimitry Andric public: 8730b57cec5SDimitry Andric using VarOp = DynTypedMatcher::VariadicOperator; 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, 8760b57cec5SDimitry Andric VarOp Op, StringRef MatcherName) 8770b57cec5SDimitry Andric : MinCount(MinCount), MaxCount(MaxCount), Op(Op), 8780b57cec5SDimitry Andric MatcherName(MatcherName) {} 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric VariantMatcher create(SourceRange NameRange, 8810b57cec5SDimitry Andric ArrayRef<ParserValue> Args, 8820b57cec5SDimitry Andric Diagnostics *Error) const override { 8830b57cec5SDimitry Andric if (Args.size() < MinCount || MaxCount < Args.size()) { 8840b57cec5SDimitry Andric const std::string MaxStr = 8850b57cec5SDimitry Andric (MaxCount == std::numeric_limits<unsigned>::max() ? "" 8860b57cec5SDimitry Andric : Twine(MaxCount)) 8870b57cec5SDimitry Andric .str(); 8880b57cec5SDimitry Andric Error->addError(NameRange, Error->ET_RegistryWrongArgCount) 8890b57cec5SDimitry Andric << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size(); 8900b57cec5SDimitry Andric return VariantMatcher(); 8910b57cec5SDimitry Andric } 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andric std::vector<VariantMatcher> InnerArgs; 8940b57cec5SDimitry Andric for (size_t i = 0, e = Args.size(); i != e; ++i) { 8950b57cec5SDimitry Andric const ParserValue &Arg = Args[i]; 8960b57cec5SDimitry Andric const VariantValue &Value = Arg.Value; 8970b57cec5SDimitry Andric if (!Value.isMatcher()) { 8980b57cec5SDimitry Andric Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 8990b57cec5SDimitry Andric << (i + 1) << "Matcher<>" << Value.getTypeAsString(); 9000b57cec5SDimitry Andric return VariantMatcher(); 9010b57cec5SDimitry Andric } 9020b57cec5SDimitry Andric InnerArgs.push_back(Value.getMatcher()); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs)); 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric bool isVariadic() const override { return true; } 9080b57cec5SDimitry Andric unsigned getNumArgs() const override { return 0; } 9090b57cec5SDimitry Andric 9105ffd83dbSDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, 9110b57cec5SDimitry Andric std::vector<ArgKind> &Kinds) const override { 912fe6060f1SDimitry Andric Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind)); 9130b57cec5SDimitry Andric } 9140b57cec5SDimitry Andric 9155ffd83dbSDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 9165ffd83dbSDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 9170b57cec5SDimitry Andric if (Specificity) 9180b57cec5SDimitry Andric *Specificity = 1; 9190b57cec5SDimitry Andric if (LeastDerivedKind) 9200b57cec5SDimitry Andric *LeastDerivedKind = Kind; 9210b57cec5SDimitry Andric return true; 9220b57cec5SDimitry Andric } 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric bool isPolymorphic() const override { return true; } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric private: 9270b57cec5SDimitry Andric const unsigned MinCount; 9280b57cec5SDimitry Andric const unsigned MaxCount; 9290b57cec5SDimitry Andric const VarOp Op; 9300b57cec5SDimitry Andric const StringRef MatcherName; 9310b57cec5SDimitry Andric }; 9320b57cec5SDimitry Andric 933e8d8bef9SDimitry Andric class MapAnyOfMatcherDescriptor : public MatcherDescriptor { 934e8d8bef9SDimitry Andric ASTNodeKind CladeNodeKind; 935e8d8bef9SDimitry Andric std::vector<ASTNodeKind> NodeKinds; 936e8d8bef9SDimitry Andric 937e8d8bef9SDimitry Andric public: 938e8d8bef9SDimitry Andric MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind, 939e8d8bef9SDimitry Andric std::vector<ASTNodeKind> NodeKinds) 940*0fca6ea1SDimitry Andric : CladeNodeKind(CladeNodeKind), NodeKinds(std::move(NodeKinds)) {} 941e8d8bef9SDimitry Andric 942e8d8bef9SDimitry Andric VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args, 943e8d8bef9SDimitry Andric Diagnostics *Error) const override { 944e8d8bef9SDimitry Andric 945e8d8bef9SDimitry Andric std::vector<DynTypedMatcher> NodeArgs; 946e8d8bef9SDimitry Andric 947e8d8bef9SDimitry Andric for (auto NK : NodeKinds) { 948e8d8bef9SDimitry Andric std::vector<DynTypedMatcher> InnerArgs; 949e8d8bef9SDimitry Andric 950e8d8bef9SDimitry Andric for (const auto &Arg : Args) { 951e8d8bef9SDimitry Andric if (!Arg.Value.isMatcher()) 952e8d8bef9SDimitry Andric return {}; 953e8d8bef9SDimitry Andric const VariantMatcher &VM = Arg.Value.getMatcher(); 954e8d8bef9SDimitry Andric if (VM.hasTypedMatcher(NK)) { 955e8d8bef9SDimitry Andric auto DM = VM.getTypedMatcher(NK); 956e8d8bef9SDimitry Andric InnerArgs.push_back(DM); 957e8d8bef9SDimitry Andric } 958e8d8bef9SDimitry Andric } 959e8d8bef9SDimitry Andric 960e8d8bef9SDimitry Andric if (InnerArgs.empty()) { 961e8d8bef9SDimitry Andric NodeArgs.push_back( 962e8d8bef9SDimitry Andric DynTypedMatcher::trueMatcher(NK).dynCastTo(CladeNodeKind)); 963e8d8bef9SDimitry Andric } else { 964e8d8bef9SDimitry Andric NodeArgs.push_back( 965e8d8bef9SDimitry Andric DynTypedMatcher::constructVariadic( 966e8d8bef9SDimitry Andric ast_matchers::internal::DynTypedMatcher::VO_AllOf, NK, 967e8d8bef9SDimitry Andric InnerArgs) 968e8d8bef9SDimitry Andric .dynCastTo(CladeNodeKind)); 969e8d8bef9SDimitry Andric } 970e8d8bef9SDimitry Andric } 971e8d8bef9SDimitry Andric 972e8d8bef9SDimitry Andric auto Result = DynTypedMatcher::constructVariadic( 973e8d8bef9SDimitry Andric ast_matchers::internal::DynTypedMatcher::VO_AnyOf, CladeNodeKind, 974e8d8bef9SDimitry Andric NodeArgs); 975e8d8bef9SDimitry Andric Result.setAllowBind(true); 976e8d8bef9SDimitry Andric return VariantMatcher::SingleMatcher(Result); 977e8d8bef9SDimitry Andric } 978e8d8bef9SDimitry Andric 979e8d8bef9SDimitry Andric bool isVariadic() const override { return true; } 980e8d8bef9SDimitry Andric unsigned getNumArgs() const override { return 0; } 981e8d8bef9SDimitry Andric 982e8d8bef9SDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned, 983e8d8bef9SDimitry Andric std::vector<ArgKind> &Kinds) const override { 984fe6060f1SDimitry Andric Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind)); 985e8d8bef9SDimitry Andric } 986e8d8bef9SDimitry Andric 987e8d8bef9SDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, 988e8d8bef9SDimitry Andric ASTNodeKind *LeastDerivedKind) const override { 989e8d8bef9SDimitry Andric if (Specificity) 990e8d8bef9SDimitry Andric *Specificity = 1; 991e8d8bef9SDimitry Andric if (LeastDerivedKind) 992e8d8bef9SDimitry Andric *LeastDerivedKind = CladeNodeKind; 993e8d8bef9SDimitry Andric return true; 994e8d8bef9SDimitry Andric } 995e8d8bef9SDimitry Andric }; 996e8d8bef9SDimitry Andric 997fe6060f1SDimitry Andric class MapAnyOfBuilderDescriptor : public MatcherDescriptor { 998fe6060f1SDimitry Andric public: 999fe6060f1SDimitry Andric VariantMatcher create(SourceRange, ArrayRef<ParserValue>, 1000fe6060f1SDimitry Andric Diagnostics *) const override { 1001fe6060f1SDimitry Andric return {}; 1002fe6060f1SDimitry Andric } 1003fe6060f1SDimitry Andric 1004fe6060f1SDimitry Andric bool isBuilderMatcher() const override { return true; } 1005fe6060f1SDimitry Andric 1006fe6060f1SDimitry Andric std::unique_ptr<MatcherDescriptor> 1007fe6060f1SDimitry Andric buildMatcherCtor(SourceRange, ArrayRef<ParserValue> Args, 1008fe6060f1SDimitry Andric Diagnostics *) const override { 1009fe6060f1SDimitry Andric 1010fe6060f1SDimitry Andric std::vector<ASTNodeKind> NodeKinds; 101106c3fb27SDimitry Andric for (const auto &Arg : Args) { 1012fe6060f1SDimitry Andric if (!Arg.Value.isNodeKind()) 1013fe6060f1SDimitry Andric return {}; 1014fe6060f1SDimitry Andric NodeKinds.push_back(Arg.Value.getNodeKind()); 1015fe6060f1SDimitry Andric } 1016fe6060f1SDimitry Andric 1017fe6060f1SDimitry Andric if (NodeKinds.empty()) 1018fe6060f1SDimitry Andric return {}; 1019fe6060f1SDimitry Andric 1020fe6060f1SDimitry Andric ASTNodeKind CladeNodeKind = NodeKinds.front().getCladeKind(); 1021fe6060f1SDimitry Andric 1022fe6060f1SDimitry Andric for (auto NK : NodeKinds) 1023fe6060f1SDimitry Andric { 1024fe6060f1SDimitry Andric if (!NK.getCladeKind().isSame(CladeNodeKind)) 1025fe6060f1SDimitry Andric return {}; 1026fe6060f1SDimitry Andric } 1027fe6060f1SDimitry Andric 1028fe6060f1SDimitry Andric return std::make_unique<MapAnyOfMatcherDescriptor>(CladeNodeKind, 1029*0fca6ea1SDimitry Andric std::move(NodeKinds)); 1030fe6060f1SDimitry Andric } 1031fe6060f1SDimitry Andric 1032fe6060f1SDimitry Andric bool isVariadic() const override { return true; } 1033fe6060f1SDimitry Andric 1034fe6060f1SDimitry Andric unsigned getNumArgs() const override { return 0; } 1035fe6060f1SDimitry Andric 1036fe6060f1SDimitry Andric void getArgKinds(ASTNodeKind ThisKind, unsigned, 1037fe6060f1SDimitry Andric std::vector<ArgKind> &ArgKinds) const override { 1038fe6060f1SDimitry Andric ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind)); 1039fe6060f1SDimitry Andric } 1040fe6060f1SDimitry Andric bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr, 1041fe6060f1SDimitry Andric ASTNodeKind *LeastDerivedKind = nullptr) const override { 1042fe6060f1SDimitry Andric if (Specificity) 1043fe6060f1SDimitry Andric *Specificity = 1; 1044fe6060f1SDimitry Andric if (LeastDerivedKind) 1045fe6060f1SDimitry Andric *LeastDerivedKind = Kind; 1046fe6060f1SDimitry Andric return true; 1047fe6060f1SDimitry Andric } 1048fe6060f1SDimitry Andric 1049fe6060f1SDimitry Andric bool isPolymorphic() const override { return false; } 1050fe6060f1SDimitry Andric }; 1051fe6060f1SDimitry Andric 10520b57cec5SDimitry Andric /// Helper functions to select the appropriate marshaller functions. 10530b57cec5SDimitry Andric /// They detect the number of arguments, arguments types and return type. 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric /// 0-arg overload 10560b57cec5SDimitry Andric template <typename ReturnType> 10570b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> 10580b57cec5SDimitry Andric makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) { 10595ffd83dbSDimitry Andric std::vector<ASTNodeKind> RetTypes; 10600b57cec5SDimitry Andric BuildReturnTypeVector<ReturnType>::build(RetTypes); 1061a7dea167SDimitry Andric return std::make_unique<FixedArgCountMatcherDescriptor>( 10620b57cec5SDimitry Andric matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), 1063bdd1243dSDimitry Andric MatcherName, RetTypes, std::nullopt); 10640b57cec5SDimitry Andric } 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andric /// 1-arg overload 10670b57cec5SDimitry Andric template <typename ReturnType, typename ArgType1> 10680b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> 10690b57cec5SDimitry Andric makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) { 10705ffd83dbSDimitry Andric std::vector<ASTNodeKind> RetTypes; 10710b57cec5SDimitry Andric BuildReturnTypeVector<ReturnType>::build(RetTypes); 10720b57cec5SDimitry Andric ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); 1073a7dea167SDimitry Andric return std::make_unique<FixedArgCountMatcherDescriptor>( 10740b57cec5SDimitry Andric matcherMarshall1<ReturnType, ArgType1>, 10750b57cec5SDimitry Andric reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric /// 2-arg overload 10790b57cec5SDimitry Andric template <typename ReturnType, typename ArgType1, typename ArgType2> 10800b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> 10810b57cec5SDimitry Andric makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), 10820b57cec5SDimitry Andric StringRef MatcherName) { 10835ffd83dbSDimitry Andric std::vector<ASTNodeKind> RetTypes; 10840b57cec5SDimitry Andric BuildReturnTypeVector<ReturnType>::build(RetTypes); 10850b57cec5SDimitry Andric ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), 10860b57cec5SDimitry Andric ArgTypeTraits<ArgType2>::getKind() }; 1087a7dea167SDimitry Andric return std::make_unique<FixedArgCountMatcherDescriptor>( 10880b57cec5SDimitry Andric matcherMarshall2<ReturnType, ArgType1, ArgType2>, 10890b57cec5SDimitry Andric reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); 10900b57cec5SDimitry Andric } 10910b57cec5SDimitry Andric 10925ffd83dbSDimitry Andric template <typename ReturnType> 10935ffd83dbSDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherRegexMarshall( 10945ffd83dbSDimitry Andric ReturnType (*FuncFlags)(llvm::StringRef, llvm::Regex::RegexFlags), 10955ffd83dbSDimitry Andric ReturnType (*Func)(llvm::StringRef)) { 10965ffd83dbSDimitry Andric std::vector<ASTNodeKind> RetTypes; 10975ffd83dbSDimitry Andric BuildReturnTypeVector<ReturnType>::build(RetTypes); 10985ffd83dbSDimitry Andric return std::make_unique<RegexMatcherDescriptor<ReturnType>>(FuncFlags, Func, 10995ffd83dbSDimitry Andric RetTypes); 11005ffd83dbSDimitry Andric } 11015ffd83dbSDimitry Andric 11020b57cec5SDimitry Andric /// Variadic overload. 11030b57cec5SDimitry Andric template <typename ResultT, typename ArgT, 11040b57cec5SDimitry Andric ResultT (*Func)(ArrayRef<const ArgT *>)> 11050b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( 11060b57cec5SDimitry Andric ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, 11070b57cec5SDimitry Andric StringRef MatcherName) { 1108a7dea167SDimitry Andric return std::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName); 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric /// Overload for VariadicDynCastAllOfMatchers. 11120b57cec5SDimitry Andric /// 11130b57cec5SDimitry Andric /// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better 11140b57cec5SDimitry Andric /// completion results for that type of matcher. 11150b57cec5SDimitry Andric template <typename BaseT, typename DerivedT> 11160b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( 11170b57cec5SDimitry Andric ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> 11180b57cec5SDimitry Andric VarFunc, 11190b57cec5SDimitry Andric StringRef MatcherName) { 1120a7dea167SDimitry Andric return std::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName); 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric /// Argument adaptative overload. 11240b57cec5SDimitry Andric template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 11250b57cec5SDimitry Andric typename FromTypes, typename ToTypes> 11260b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( 11270b57cec5SDimitry Andric ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT, 11280b57cec5SDimitry Andric FromTypes, ToTypes>, 11290b57cec5SDimitry Andric StringRef MatcherName) { 11300b57cec5SDimitry Andric std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; 11310b57cec5SDimitry Andric AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, 11320b57cec5SDimitry Andric Overloads); 1133a7dea167SDimitry Andric return std::make_unique<OverloadedMatcherDescriptor>(Overloads); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 11370b57cec5SDimitry Andric typename FromTypes, typename ToTypes> 11380b57cec5SDimitry Andric template <typename FromTypeList> 11390b57cec5SDimitry Andric inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, 11400b57cec5SDimitry Andric ToTypes>::collect(FromTypeList) { 11410b57cec5SDimitry Andric Out.push_back(makeMatcherAutoMarshall( 11420b57cec5SDimitry Andric &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); 11430b57cec5SDimitry Andric collect(typename FromTypeList::tail()); 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric /// Variadic operator overload. 11470b57cec5SDimitry Andric template <unsigned MinCount, unsigned MaxCount> 11480b57cec5SDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( 11490b57cec5SDimitry Andric ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount> 11500b57cec5SDimitry Andric Func, 11510b57cec5SDimitry Andric StringRef MatcherName) { 1152a7dea167SDimitry Andric return std::make_unique<VariadicOperatorMatcherDescriptor>( 11530b57cec5SDimitry Andric MinCount, MaxCount, Func.Op, MatcherName); 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric 1156e8d8bef9SDimitry Andric template <typename CladeType, typename... MatcherT> 1157e8d8bef9SDimitry Andric std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( 1158e8d8bef9SDimitry Andric ast_matchers::internal::MapAnyOfMatcherImpl<CladeType, MatcherT...>, 1159e8d8bef9SDimitry Andric StringRef MatcherName) { 1160e8d8bef9SDimitry Andric return std::make_unique<MapAnyOfMatcherDescriptor>( 1161e8d8bef9SDimitry Andric ASTNodeKind::getFromNodeKind<CladeType>(), 1162e8d8bef9SDimitry Andric std::vector<ASTNodeKind>{ASTNodeKind::getFromNodeKind<MatcherT>()...}); 1163e8d8bef9SDimitry Andric } 1164e8d8bef9SDimitry Andric 11650b57cec5SDimitry Andric } // namespace internal 11660b57cec5SDimitry Andric } // namespace dynamic 11670b57cec5SDimitry Andric } // namespace ast_matchers 11680b57cec5SDimitry Andric } // namespace clang 11690b57cec5SDimitry Andric 117004eeddc0SDimitry Andric #endif // LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 1171