brintos

brintos / llvm-project-archived public Read only

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