Path: blob/main/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h
35291 views
//===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file9/// Functions templates and classes to wrap matcher construct functions.10///11/// A collection of template function and classes that provide a generic12/// marshalling layer on top of matcher construct functions.13/// These are used by the registry to export all marshaller constructors with14/// the same generic interface.15//16//===----------------------------------------------------------------------===//1718#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H19#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H2021#include "clang/AST/ASTTypeTraits.h"22#include "clang/AST/OperationKinds.h"23#include "clang/ASTMatchers/ASTMatchersInternal.h"24#include "clang/ASTMatchers/Dynamic/Diagnostics.h"25#include "clang/ASTMatchers/Dynamic/VariantValue.h"26#include "clang/Basic/AttrKinds.h"27#include "clang/Basic/LLVM.h"28#include "clang/Basic/OpenMPKinds.h"29#include "clang/Basic/TypeTraits.h"30#include "llvm/ADT/ArrayRef.h"31#include "llvm/ADT/STLExtras.h"32#include "llvm/ADT/StringRef.h"33#include "llvm/ADT/StringSwitch.h"34#include "llvm/ADT/Twine.h"35#include "llvm/Support/Regex.h"36#include <cassert>37#include <cstddef>38#include <iterator>39#include <limits>40#include <memory>41#include <optional>42#include <string>43#include <utility>44#include <vector>4546namespace clang {47namespace ast_matchers {48namespace dynamic {49namespace internal {5051/// Helper template class to just from argument type to the right is/get52/// functions in VariantValue.53/// Used to verify and extract the matcher arguments below.54template <class T> struct ArgTypeTraits;55template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {56};5758template <> struct ArgTypeTraits<std::string> {59static bool hasCorrectType(const VariantValue &Value) {60return Value.isString();61}62static bool hasCorrectValue(const VariantValue &Value) { return true; }6364static const std::string &get(const VariantValue &Value) {65return Value.getString();66}6768static ArgKind getKind() {69return ArgKind(ArgKind::AK_String);70}7172static std::optional<std::string> getBestGuess(const VariantValue &) {73return std::nullopt;74}75};7677template <>78struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {79};8081template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {82static bool hasCorrectType(const VariantValue& Value) {83return Value.isMatcher();84}85static bool hasCorrectValue(const VariantValue &Value) {86return Value.getMatcher().hasTypedMatcher<T>();87}8889static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {90return Value.getMatcher().getTypedMatcher<T>();91}9293static ArgKind getKind() {94return ArgKind::MakeMatcherArg(ASTNodeKind::getFromNodeKind<T>());95}9697static std::optional<std::string> getBestGuess(const VariantValue &) {98return std::nullopt;99}100};101102template <> struct ArgTypeTraits<bool> {103static bool hasCorrectType(const VariantValue &Value) {104return Value.isBoolean();105}106static bool hasCorrectValue(const VariantValue &Value) { return true; }107108static bool get(const VariantValue &Value) {109return Value.getBoolean();110}111112static ArgKind getKind() {113return ArgKind(ArgKind::AK_Boolean);114}115116static std::optional<std::string> getBestGuess(const VariantValue &) {117return std::nullopt;118}119};120121template <> struct ArgTypeTraits<double> {122static bool hasCorrectType(const VariantValue &Value) {123return Value.isDouble();124}125static bool hasCorrectValue(const VariantValue &Value) { return true; }126127static double get(const VariantValue &Value) {128return Value.getDouble();129}130131static ArgKind getKind() {132return ArgKind(ArgKind::AK_Double);133}134135static std::optional<std::string> getBestGuess(const VariantValue &) {136return std::nullopt;137}138};139140template <> struct ArgTypeTraits<unsigned> {141static bool hasCorrectType(const VariantValue &Value) {142return Value.isUnsigned();143}144static bool hasCorrectValue(const VariantValue &Value) { return true; }145146static unsigned get(const VariantValue &Value) {147return Value.getUnsigned();148}149150static ArgKind getKind() {151return ArgKind(ArgKind::AK_Unsigned);152}153154static std::optional<std::string> getBestGuess(const VariantValue &) {155return std::nullopt;156}157};158159template <> struct ArgTypeTraits<attr::Kind> {160private:161static std::optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {162if (!AttrKind.consume_front("attr::"))163return std::nullopt;164return llvm::StringSwitch<std::optional<attr::Kind>>(AttrKind)165#define ATTR(X) .Case(#X, attr::X)166#include "clang/Basic/AttrList.inc"167.Default(std::nullopt);168}169170public:171static bool hasCorrectType(const VariantValue &Value) {172return Value.isString();173}174static bool hasCorrectValue(const VariantValue& Value) {175return getAttrKind(Value.getString()).has_value();176}177178static attr::Kind get(const VariantValue &Value) {179return *getAttrKind(Value.getString());180}181182static ArgKind getKind() {183return ArgKind(ArgKind::AK_String);184}185186static std::optional<std::string> getBestGuess(const VariantValue &Value);187};188189template <> struct ArgTypeTraits<CastKind> {190private:191static std::optional<CastKind> getCastKind(llvm::StringRef AttrKind) {192if (!AttrKind.consume_front("CK_"))193return std::nullopt;194return llvm::StringSwitch<std::optional<CastKind>>(AttrKind)195#define CAST_OPERATION(Name) .Case(#Name, CK_##Name)196#include "clang/AST/OperationKinds.def"197.Default(std::nullopt);198}199200public:201static bool hasCorrectType(const VariantValue &Value) {202return Value.isString();203}204static bool hasCorrectValue(const VariantValue& Value) {205return getCastKind(Value.getString()).has_value();206}207208static CastKind get(const VariantValue &Value) {209return *getCastKind(Value.getString());210}211212static ArgKind getKind() {213return ArgKind(ArgKind::AK_String);214}215216static std::optional<std::string> getBestGuess(const VariantValue &Value);217};218219template <> struct ArgTypeTraits<llvm::Regex::RegexFlags> {220private:221static std::optional<llvm::Regex::RegexFlags> getFlags(llvm::StringRef Flags);222223public:224static bool hasCorrectType(const VariantValue &Value) {225return Value.isString();226}227static bool hasCorrectValue(const VariantValue& Value) {228return getFlags(Value.getString()).has_value();229}230231static llvm::Regex::RegexFlags get(const VariantValue &Value) {232return *getFlags(Value.getString());233}234235static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }236237static std::optional<std::string> getBestGuess(const VariantValue &Value);238};239240template <> struct ArgTypeTraits<OpenMPClauseKind> {241private:242static std::optional<OpenMPClauseKind>243getClauseKind(llvm::StringRef ClauseKind) {244return llvm::StringSwitch<std::optional<OpenMPClauseKind>>(ClauseKind)245#define GEN_CLANG_CLAUSE_CLASS246#define CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum)247#include "llvm/Frontend/OpenMP/OMP.inc"248.Default(std::nullopt);249}250251public:252static bool hasCorrectType(const VariantValue &Value) {253return Value.isString();254}255static bool hasCorrectValue(const VariantValue& Value) {256return getClauseKind(Value.getString()).has_value();257}258259static OpenMPClauseKind get(const VariantValue &Value) {260return *getClauseKind(Value.getString());261}262263static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }264265static std::optional<std::string> getBestGuess(const VariantValue &Value);266};267268template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> {269private:270static std::optional<UnaryExprOrTypeTrait>271getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) {272if (!ClauseKind.consume_front("UETT_"))273return std::nullopt;274return llvm::StringSwitch<std::optional<UnaryExprOrTypeTrait>>(ClauseKind)275#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name)276#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \277.Case(#Name, UETT_##Name)278#include "clang/Basic/TokenKinds.def"279.Default(std::nullopt);280}281282public:283static bool hasCorrectType(const VariantValue &Value) {284return Value.isString();285}286static bool hasCorrectValue(const VariantValue& Value) {287return getUnaryOrTypeTraitKind(Value.getString()).has_value();288}289290static UnaryExprOrTypeTrait get(const VariantValue &Value) {291return *getUnaryOrTypeTraitKind(Value.getString());292}293294static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }295296static std::optional<std::string> getBestGuess(const VariantValue &Value);297};298299/// Matcher descriptor interface.300///301/// Provides a \c create() method that constructs the matcher from the provided302/// arguments, and various other methods for type introspection.303class MatcherDescriptor {304public:305virtual ~MatcherDescriptor() = default;306307virtual VariantMatcher create(SourceRange NameRange,308ArrayRef<ParserValue> Args,309Diagnostics *Error) const = 0;310311virtual ASTNodeKind nodeMatcherType() const { return ASTNodeKind(); }312313virtual bool isBuilderMatcher() const { return false; }314315virtual std::unique_ptr<MatcherDescriptor>316buildMatcherCtor(SourceRange NameRange, ArrayRef<ParserValue> Args,317Diagnostics *Error) const {318return {};319}320321/// Returns whether the matcher is variadic. Variadic matchers can take any322/// number of arguments, but they must be of the same type.323virtual bool isVariadic() const = 0;324325/// Returns the number of arguments accepted by the matcher if not variadic.326virtual unsigned getNumArgs() const = 0;327328/// Given that the matcher is being converted to type \p ThisKind, append the329/// set of argument types accepted for argument \p ArgNo to \p ArgKinds.330// FIXME: We should provide the ability to constrain the output of this331// function based on the types of other matcher arguments.332virtual void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,333std::vector<ArgKind> &ArgKinds) const = 0;334335/// Returns whether this matcher is convertible to the given type. If it is336/// so convertible, store in *Specificity a value corresponding to the337/// "specificity" of the converted matcher to the given context, and in338/// *LeastDerivedKind the least derived matcher kind which would result in the339/// same matcher overload. Zero specificity indicates that this conversion340/// would produce a trivial matcher that will either always or never match.341/// Such matchers are excluded from code completion results.342virtual bool343isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,344ASTNodeKind *LeastDerivedKind = nullptr) const = 0;345346/// Returns whether the matcher will, given a matcher of any type T, yield a347/// matcher of type T.348virtual bool isPolymorphic() const { return false; }349};350351inline bool isRetKindConvertibleTo(ArrayRef<ASTNodeKind> RetKinds,352ASTNodeKind Kind, unsigned *Specificity,353ASTNodeKind *LeastDerivedKind) {354for (const ASTNodeKind &NodeKind : RetKinds) {355if (ArgKind::MakeMatcherArg(NodeKind).isConvertibleTo(356ArgKind::MakeMatcherArg(Kind), Specificity)) {357if (LeastDerivedKind)358*LeastDerivedKind = NodeKind;359return true;360}361}362return false;363}364365/// Simple callback implementation. Marshaller and function are provided.366///367/// This class wraps a function of arbitrary signature and a marshaller368/// function into a MatcherDescriptor.369/// The marshaller is in charge of taking the VariantValue arguments, checking370/// their types, unpacking them and calling the underlying function.371class FixedArgCountMatcherDescriptor : public MatcherDescriptor {372public:373using MarshallerType = VariantMatcher (*)(void (*Func)(),374StringRef MatcherName,375SourceRange NameRange,376ArrayRef<ParserValue> Args,377Diagnostics *Error);378379/// \param Marshaller Function to unpack the arguments and call \c Func380/// \param Func Matcher construct function. This is the function that381/// compile-time matcher expressions would use to create the matcher.382/// \param RetKinds The list of matcher types to which the matcher is383/// convertible.384/// \param ArgKinds The types of the arguments this matcher takes.385FixedArgCountMatcherDescriptor(MarshallerType Marshaller, void (*Func)(),386StringRef MatcherName,387ArrayRef<ASTNodeKind> RetKinds,388ArrayRef<ArgKind> ArgKinds)389: Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),390RetKinds(RetKinds.begin(), RetKinds.end()),391ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}392393VariantMatcher create(SourceRange NameRange,394ArrayRef<ParserValue> Args,395Diagnostics *Error) const override {396return Marshaller(Func, MatcherName, NameRange, Args, Error);397}398399bool isVariadic() const override { return false; }400unsigned getNumArgs() const override { return ArgKinds.size(); }401402void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,403std::vector<ArgKind> &Kinds) const override {404Kinds.push_back(ArgKinds[ArgNo]);405}406407bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,408ASTNodeKind *LeastDerivedKind) const override {409return isRetKindConvertibleTo(RetKinds, Kind, Specificity,410LeastDerivedKind);411}412413private:414const MarshallerType Marshaller;415void (* const Func)();416const std::string MatcherName;417const std::vector<ASTNodeKind> RetKinds;418const std::vector<ArgKind> ArgKinds;419};420421/// Helper methods to extract and merge all possible typed matchers422/// out of the polymorphic object.423template <class PolyMatcher>424static void mergePolyMatchers(const PolyMatcher &Poly,425std::vector<DynTypedMatcher> &Out,426ast_matchers::internal::EmptyTypeList) {}427428template <class PolyMatcher, class TypeList>429static void mergePolyMatchers(const PolyMatcher &Poly,430std::vector<DynTypedMatcher> &Out, TypeList) {431Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));432mergePolyMatchers(Poly, Out, typename TypeList::tail());433}434435/// Convert the return values of the functions into a VariantMatcher.436///437/// There are 2 cases right now: The return value is a Matcher<T> or is a438/// polymorphic matcher. For the former, we just construct the VariantMatcher.439/// For the latter, we instantiate all the possible Matcher<T> of the poly440/// matcher.441inline VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {442return VariantMatcher::SingleMatcher(Matcher);443}444445template <typename T>446static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,447typename T::ReturnTypes * =448nullptr) {449std::vector<DynTypedMatcher> Matchers;450mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());451VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));452return Out;453}454455template <typename T>456inline void457buildReturnTypeVectorFromTypeList(std::vector<ASTNodeKind> &RetTypes) {458RetTypes.push_back(ASTNodeKind::getFromNodeKind<typename T::head>());459buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);460}461462template <>463inline void464buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(465std::vector<ASTNodeKind> &RetTypes) {}466467template <typename T>468struct BuildReturnTypeVector {469static void build(std::vector<ASTNodeKind> &RetTypes) {470buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);471}472};473474template <typename T>475struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {476static void build(std::vector<ASTNodeKind> &RetTypes) {477RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());478}479};480481template <typename T>482struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {483static void build(std::vector<ASTNodeKind> &RetTypes) {484RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());485}486};487488/// Variadic marshaller function.489template <typename ResultT, typename ArgT,490ResultT (*Func)(ArrayRef<const ArgT *>)>491VariantMatcher492variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,493ArrayRef<ParserValue> Args, Diagnostics *Error) {494SmallVector<ArgT *, 8> InnerArgsPtr;495InnerArgsPtr.resize_for_overwrite(Args.size());496SmallVector<ArgT, 8> InnerArgs;497InnerArgs.reserve(Args.size());498499for (size_t i = 0, e = Args.size(); i != e; ++i) {500using ArgTraits = ArgTypeTraits<ArgT>;501502const ParserValue &Arg = Args[i];503const VariantValue &Value = Arg.Value;504if (!ArgTraits::hasCorrectType(Value)) {505Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)506<< (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();507return {};508}509if (!ArgTraits::hasCorrectValue(Value)) {510if (std::optional<std::string> BestGuess =511ArgTraits::getBestGuess(Value)) {512Error->addError(Arg.Range, Error->ET_RegistryUnknownEnumWithReplace)513<< i + 1 << Value.getString() << *BestGuess;514} else if (Value.isString()) {515Error->addError(Arg.Range, Error->ET_RegistryValueNotFound)516<< Value.getString();517} else {518// This isn't ideal, but it's better than reporting an empty string as519// the error in this case.520Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)521<< (i + 1) << ArgTraits::getKind().asString()522<< Value.getTypeAsString();523}524return {};525}526assert(InnerArgs.size() < InnerArgs.capacity());527InnerArgs.emplace_back(ArgTraits::get(Value));528InnerArgsPtr[i] = &InnerArgs[i];529}530return outvalueToVariantMatcher(Func(InnerArgsPtr));531}532533/// Matcher descriptor for variadic functions.534///535/// This class simply wraps a VariadicFunction with the right signature to export536/// it as a MatcherDescriptor.537/// This allows us to have one implementation of the interface for as many free538/// functions as we want, reducing the number of symbols and size of the539/// object file.540class VariadicFuncMatcherDescriptor : public MatcherDescriptor {541public:542using RunFunc = VariantMatcher (*)(StringRef MatcherName,543SourceRange NameRange,544ArrayRef<ParserValue> Args,545Diagnostics *Error);546547template <typename ResultT, typename ArgT,548ResultT (*F)(ArrayRef<const ArgT *>)>549VariadicFuncMatcherDescriptor(550ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,551StringRef MatcherName)552: Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),553MatcherName(MatcherName.str()),554ArgsKind(ArgTypeTraits<ArgT>::getKind()) {555BuildReturnTypeVector<ResultT>::build(RetKinds);556}557558VariantMatcher create(SourceRange NameRange,559ArrayRef<ParserValue> Args,560Diagnostics *Error) const override {561return Func(MatcherName, NameRange, Args, Error);562}563564bool isVariadic() const override { return true; }565unsigned getNumArgs() const override { return 0; }566567void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,568std::vector<ArgKind> &Kinds) const override {569Kinds.push_back(ArgsKind);570}571572bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,573ASTNodeKind *LeastDerivedKind) const override {574return isRetKindConvertibleTo(RetKinds, Kind, Specificity,575LeastDerivedKind);576}577578ASTNodeKind nodeMatcherType() const override { return RetKinds[0]; }579580private:581const RunFunc Func;582const std::string MatcherName;583std::vector<ASTNodeKind> RetKinds;584const ArgKind ArgsKind;585};586587/// Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.588class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {589public:590template <typename BaseT, typename DerivedT>591DynCastAllOfMatcherDescriptor(592ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,593StringRef MatcherName)594: VariadicFuncMatcherDescriptor(Func, MatcherName),595DerivedKind(ASTNodeKind::getFromNodeKind<DerivedT>()) {}596597bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,598ASTNodeKind *LeastDerivedKind) const override {599// If Kind is not a base of DerivedKind, either DerivedKind is a base of600// Kind (in which case the match will always succeed) or Kind and601// DerivedKind are unrelated (in which case it will always fail), so set602// Specificity to 0.603if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,604LeastDerivedKind)) {605if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {606if (Specificity)607*Specificity = 0;608}609return true;610} else {611return false;612}613}614615ASTNodeKind nodeMatcherType() const override { return DerivedKind; }616617private:618const ASTNodeKind DerivedKind;619};620621/// Helper macros to check the arguments on all marshaller functions.622#define CHECK_ARG_COUNT(count) \623if (Args.size() != count) { \624Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \625<< count << Args.size(); \626return VariantMatcher(); \627}628629#define CHECK_ARG_TYPE(index, type) \630if (!ArgTypeTraits<type>::hasCorrectType(Args[index].Value)) { \631Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \632<< (index + 1) << ArgTypeTraits<type>::getKind().asString() \633<< Args[index].Value.getTypeAsString(); \634return VariantMatcher(); \635} \636if (!ArgTypeTraits<type>::hasCorrectValue(Args[index].Value)) { \637if (std::optional<std::string> BestGuess = \638ArgTypeTraits<type>::getBestGuess(Args[index].Value)) { \639Error->addError(Args[index].Range, \640Error->ET_RegistryUnknownEnumWithReplace) \641<< index + 1 << Args[index].Value.getString() << *BestGuess; \642} else if (Args[index].Value.isString()) { \643Error->addError(Args[index].Range, Error->ET_RegistryValueNotFound) \644<< Args[index].Value.getString(); \645} \646return VariantMatcher(); \647}648649/// 0-arg marshaller function.650template <typename ReturnType>651static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,652SourceRange NameRange,653ArrayRef<ParserValue> Args,654Diagnostics *Error) {655using FuncType = ReturnType (*)();656CHECK_ARG_COUNT(0);657return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());658}659660/// 1-arg marshaller function.661template <typename ReturnType, typename ArgType1>662static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,663SourceRange NameRange,664ArrayRef<ParserValue> Args,665Diagnostics *Error) {666using FuncType = ReturnType (*)(ArgType1);667CHECK_ARG_COUNT(1);668CHECK_ARG_TYPE(0, ArgType1);669return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(670ArgTypeTraits<ArgType1>::get(Args[0].Value)));671}672673/// 2-arg marshaller function.674template <typename ReturnType, typename ArgType1, typename ArgType2>675static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,676SourceRange NameRange,677ArrayRef<ParserValue> Args,678Diagnostics *Error) {679using FuncType = ReturnType (*)(ArgType1, ArgType2);680CHECK_ARG_COUNT(2);681CHECK_ARG_TYPE(0, ArgType1);682CHECK_ARG_TYPE(1, ArgType2);683return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(684ArgTypeTraits<ArgType1>::get(Args[0].Value),685ArgTypeTraits<ArgType2>::get(Args[1].Value)));686}687688#undef CHECK_ARG_COUNT689#undef CHECK_ARG_TYPE690691/// Helper class used to collect all the possible overloads of an692/// argument adaptative matcher function.693template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,694typename FromTypes, typename ToTypes>695class AdaptativeOverloadCollector {696public:697AdaptativeOverloadCollector(698StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)699: Name(Name), Out(Out) {700collect(FromTypes());701}702703private:704using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<705ArgumentAdapterT, FromTypes, ToTypes>;706707/// End case for the recursion708static void collect(ast_matchers::internal::EmptyTypeList) {}709710/// Recursive case. Get the overload for the head of the list, and711/// recurse to the tail.712template <typename FromTypeList>713inline void collect(FromTypeList);714715StringRef Name;716std::vector<std::unique_ptr<MatcherDescriptor>> &Out;717};718719/// MatcherDescriptor that wraps multiple "overloads" of the same720/// matcher.721///722/// It will try every overload and generate appropriate errors for when none or723/// more than one overloads match the arguments.724class OverloadedMatcherDescriptor : public MatcherDescriptor {725public:726OverloadedMatcherDescriptor(727MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)728: Overloads(std::make_move_iterator(Callbacks.begin()),729std::make_move_iterator(Callbacks.end())) {}730731~OverloadedMatcherDescriptor() override = default;732733VariantMatcher create(SourceRange NameRange,734ArrayRef<ParserValue> Args,735Diagnostics *Error) const override {736std::vector<VariantMatcher> Constructed;737Diagnostics::OverloadContext Ctx(Error);738for (const auto &O : Overloads) {739VariantMatcher SubMatcher = O->create(NameRange, Args, Error);740if (!SubMatcher.isNull()) {741Constructed.push_back(SubMatcher);742}743}744745if (Constructed.empty()) return VariantMatcher(); // No overload matched.746// We ignore the errors if any matcher succeeded.747Ctx.revertErrors();748if (Constructed.size() > 1) {749// More than one constructed. It is ambiguous.750Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);751return VariantMatcher();752}753return Constructed[0];754}755756bool isVariadic() const override {757bool Overload0Variadic = Overloads[0]->isVariadic();758#ifndef NDEBUG759for (const auto &O : Overloads) {760assert(Overload0Variadic == O->isVariadic());761}762#endif763return Overload0Variadic;764}765766unsigned getNumArgs() const override {767unsigned Overload0NumArgs = Overloads[0]->getNumArgs();768#ifndef NDEBUG769for (const auto &O : Overloads) {770assert(Overload0NumArgs == O->getNumArgs());771}772#endif773return Overload0NumArgs;774}775776void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,777std::vector<ArgKind> &Kinds) const override {778for (const auto &O : Overloads) {779if (O->isConvertibleTo(ThisKind))780O->getArgKinds(ThisKind, ArgNo, Kinds);781}782}783784bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,785ASTNodeKind *LeastDerivedKind) const override {786for (const auto &O : Overloads) {787if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))788return true;789}790return false;791}792793private:794std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;795};796797template <typename ReturnType>798class RegexMatcherDescriptor : public MatcherDescriptor {799public:800RegexMatcherDescriptor(ReturnType (*WithFlags)(StringRef,801llvm::Regex::RegexFlags),802ReturnType (*NoFlags)(StringRef),803ArrayRef<ASTNodeKind> RetKinds)804: WithFlags(WithFlags), NoFlags(NoFlags),805RetKinds(RetKinds.begin(), RetKinds.end()) {}806bool isVariadic() const override { return true; }807unsigned getNumArgs() const override { return 0; }808809void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,810std::vector<ArgKind> &Kinds) const override {811assert(ArgNo < 2);812Kinds.push_back(ArgKind::AK_String);813}814815bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,816ASTNodeKind *LeastDerivedKind) const override {817return isRetKindConvertibleTo(RetKinds, Kind, Specificity,818LeastDerivedKind);819}820821VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args,822Diagnostics *Error) const override {823if (Args.size() < 1 || Args.size() > 2) {824Error->addError(NameRange, Diagnostics::ET_RegistryWrongArgCount)825<< "1 or 2" << Args.size();826return VariantMatcher();827}828if (!ArgTypeTraits<StringRef>::hasCorrectType(Args[0].Value)) {829Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType)830<< 1 << ArgTypeTraits<StringRef>::getKind().asString()831<< Args[0].Value.getTypeAsString();832return VariantMatcher();833}834if (Args.size() == 1) {835return outvalueToVariantMatcher(836NoFlags(ArgTypeTraits<StringRef>::get(Args[0].Value)));837}838if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectType(839Args[1].Value)) {840Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType)841<< 2 << ArgTypeTraits<llvm::Regex::RegexFlags>::getKind().asString()842<< Args[1].Value.getTypeAsString();843return VariantMatcher();844}845if (!ArgTypeTraits<llvm::Regex::RegexFlags>::hasCorrectValue(846Args[1].Value)) {847if (std::optional<std::string> BestGuess =848ArgTypeTraits<llvm::Regex::RegexFlags>::getBestGuess(849Args[1].Value)) {850Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace)851<< 2 << Args[1].Value.getString() << *BestGuess;852} else {853Error->addError(Args[1].Range, Error->ET_RegistryValueNotFound)854<< Args[1].Value.getString();855}856return VariantMatcher();857}858return outvalueToVariantMatcher(859WithFlags(ArgTypeTraits<StringRef>::get(Args[0].Value),860ArgTypeTraits<llvm::Regex::RegexFlags>::get(Args[1].Value)));861}862863private:864ReturnType (*const WithFlags)(StringRef, llvm::Regex::RegexFlags);865ReturnType (*const NoFlags)(StringRef);866const std::vector<ASTNodeKind> RetKinds;867};868869/// Variadic operator marshaller function.870class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {871public:872using VarOp = DynTypedMatcher::VariadicOperator;873874VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,875VarOp Op, StringRef MatcherName)876: MinCount(MinCount), MaxCount(MaxCount), Op(Op),877MatcherName(MatcherName) {}878879VariantMatcher create(SourceRange NameRange,880ArrayRef<ParserValue> Args,881Diagnostics *Error) const override {882if (Args.size() < MinCount || MaxCount < Args.size()) {883const std::string MaxStr =884(MaxCount == std::numeric_limits<unsigned>::max() ? ""885: Twine(MaxCount))886.str();887Error->addError(NameRange, Error->ET_RegistryWrongArgCount)888<< ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();889return VariantMatcher();890}891892std::vector<VariantMatcher> InnerArgs;893for (size_t i = 0, e = Args.size(); i != e; ++i) {894const ParserValue &Arg = Args[i];895const VariantValue &Value = Arg.Value;896if (!Value.isMatcher()) {897Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)898<< (i + 1) << "Matcher<>" << Value.getTypeAsString();899return VariantMatcher();900}901InnerArgs.push_back(Value.getMatcher());902}903return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));904}905906bool isVariadic() const override { return true; }907unsigned getNumArgs() const override { return 0; }908909void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,910std::vector<ArgKind> &Kinds) const override {911Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind));912}913914bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,915ASTNodeKind *LeastDerivedKind) const override {916if (Specificity)917*Specificity = 1;918if (LeastDerivedKind)919*LeastDerivedKind = Kind;920return true;921}922923bool isPolymorphic() const override { return true; }924925private:926const unsigned MinCount;927const unsigned MaxCount;928const VarOp Op;929const StringRef MatcherName;930};931932class MapAnyOfMatcherDescriptor : public MatcherDescriptor {933ASTNodeKind CladeNodeKind;934std::vector<ASTNodeKind> NodeKinds;935936public:937MapAnyOfMatcherDescriptor(ASTNodeKind CladeNodeKind,938std::vector<ASTNodeKind> NodeKinds)939: CladeNodeKind(CladeNodeKind), NodeKinds(std::move(NodeKinds)) {}940941VariantMatcher create(SourceRange NameRange, ArrayRef<ParserValue> Args,942Diagnostics *Error) const override {943944std::vector<DynTypedMatcher> NodeArgs;945946for (auto NK : NodeKinds) {947std::vector<DynTypedMatcher> InnerArgs;948949for (const auto &Arg : Args) {950if (!Arg.Value.isMatcher())951return {};952const VariantMatcher &VM = Arg.Value.getMatcher();953if (VM.hasTypedMatcher(NK)) {954auto DM = VM.getTypedMatcher(NK);955InnerArgs.push_back(DM);956}957}958959if (InnerArgs.empty()) {960NodeArgs.push_back(961DynTypedMatcher::trueMatcher(NK).dynCastTo(CladeNodeKind));962} else {963NodeArgs.push_back(964DynTypedMatcher::constructVariadic(965ast_matchers::internal::DynTypedMatcher::VO_AllOf, NK,966InnerArgs)967.dynCastTo(CladeNodeKind));968}969}970971auto Result = DynTypedMatcher::constructVariadic(972ast_matchers::internal::DynTypedMatcher::VO_AnyOf, CladeNodeKind,973NodeArgs);974Result.setAllowBind(true);975return VariantMatcher::SingleMatcher(Result);976}977978bool isVariadic() const override { return true; }979unsigned getNumArgs() const override { return 0; }980981void getArgKinds(ASTNodeKind ThisKind, unsigned,982std::vector<ArgKind> &Kinds) const override {983Kinds.push_back(ArgKind::MakeMatcherArg(ThisKind));984}985986bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,987ASTNodeKind *LeastDerivedKind) const override {988if (Specificity)989*Specificity = 1;990if (LeastDerivedKind)991*LeastDerivedKind = CladeNodeKind;992return true;993}994};995996class MapAnyOfBuilderDescriptor : public MatcherDescriptor {997public:998VariantMatcher create(SourceRange, ArrayRef<ParserValue>,999Diagnostics *) const override {1000return {};1001}10021003bool isBuilderMatcher() const override { return true; }10041005std::unique_ptr<MatcherDescriptor>1006buildMatcherCtor(SourceRange, ArrayRef<ParserValue> Args,1007Diagnostics *) const override {10081009std::vector<ASTNodeKind> NodeKinds;1010for (const auto &Arg : Args) {1011if (!Arg.Value.isNodeKind())1012return {};1013NodeKinds.push_back(Arg.Value.getNodeKind());1014}10151016if (NodeKinds.empty())1017return {};10181019ASTNodeKind CladeNodeKind = NodeKinds.front().getCladeKind();10201021for (auto NK : NodeKinds)1022{1023if (!NK.getCladeKind().isSame(CladeNodeKind))1024return {};1025}10261027return std::make_unique<MapAnyOfMatcherDescriptor>(CladeNodeKind,1028std::move(NodeKinds));1029}10301031bool isVariadic() const override { return true; }10321033unsigned getNumArgs() const override { return 0; }10341035void getArgKinds(ASTNodeKind ThisKind, unsigned,1036std::vector<ArgKind> &ArgKinds) const override {1037ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind));1038}1039bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,1040ASTNodeKind *LeastDerivedKind = nullptr) const override {1041if (Specificity)1042*Specificity = 1;1043if (LeastDerivedKind)1044*LeastDerivedKind = Kind;1045return true;1046}10471048bool isPolymorphic() const override { return false; }1049};10501051/// Helper functions to select the appropriate marshaller functions.1052/// They detect the number of arguments, arguments types and return type.10531054/// 0-arg overload1055template <typename ReturnType>1056std::unique_ptr<MatcherDescriptor>1057makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {1058std::vector<ASTNodeKind> RetTypes;1059BuildReturnTypeVector<ReturnType>::build(RetTypes);1060return std::make_unique<FixedArgCountMatcherDescriptor>(1061matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),1062MatcherName, RetTypes, std::nullopt);1063}10641065/// 1-arg overload1066template <typename ReturnType, typename ArgType1>1067std::unique_ptr<MatcherDescriptor>1068makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {1069std::vector<ASTNodeKind> RetTypes;1070BuildReturnTypeVector<ReturnType>::build(RetTypes);1071ArgKind AK = ArgTypeTraits<ArgType1>::getKind();1072return std::make_unique<FixedArgCountMatcherDescriptor>(1073matcherMarshall1<ReturnType, ArgType1>,1074reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);1075}10761077/// 2-arg overload1078template <typename ReturnType, typename ArgType1, typename ArgType2>1079std::unique_ptr<MatcherDescriptor>1080makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),1081StringRef MatcherName) {1082std::vector<ASTNodeKind> RetTypes;1083BuildReturnTypeVector<ReturnType>::build(RetTypes);1084ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),1085ArgTypeTraits<ArgType2>::getKind() };1086return std::make_unique<FixedArgCountMatcherDescriptor>(1087matcherMarshall2<ReturnType, ArgType1, ArgType2>,1088reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);1089}10901091template <typename ReturnType>1092std::unique_ptr<MatcherDescriptor> makeMatcherRegexMarshall(1093ReturnType (*FuncFlags)(llvm::StringRef, llvm::Regex::RegexFlags),1094ReturnType (*Func)(llvm::StringRef)) {1095std::vector<ASTNodeKind> RetTypes;1096BuildReturnTypeVector<ReturnType>::build(RetTypes);1097return std::make_unique<RegexMatcherDescriptor<ReturnType>>(FuncFlags, Func,1098RetTypes);1099}11001101/// Variadic overload.1102template <typename ResultT, typename ArgT,1103ResultT (*Func)(ArrayRef<const ArgT *>)>1104std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(1105ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,1106StringRef MatcherName) {1107return std::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);1108}11091110/// Overload for VariadicDynCastAllOfMatchers.1111///1112/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better1113/// completion results for that type of matcher.1114template <typename BaseT, typename DerivedT>1115std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(1116ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>1117VarFunc,1118StringRef MatcherName) {1119return std::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);1120}11211122/// Argument adaptative overload.1123template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,1124typename FromTypes, typename ToTypes>1125std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(1126ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,1127FromTypes, ToTypes>,1128StringRef MatcherName) {1129std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;1130AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,1131Overloads);1132return std::make_unique<OverloadedMatcherDescriptor>(Overloads);1133}11341135template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,1136typename FromTypes, typename ToTypes>1137template <typename FromTypeList>1138inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,1139ToTypes>::collect(FromTypeList) {1140Out.push_back(makeMatcherAutoMarshall(1141&AdaptativeFunc::template create<typename FromTypeList::head>, Name));1142collect(typename FromTypeList::tail());1143}11441145/// Variadic operator overload.1146template <unsigned MinCount, unsigned MaxCount>1147std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(1148ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>1149Func,1150StringRef MatcherName) {1151return std::make_unique<VariadicOperatorMatcherDescriptor>(1152MinCount, MaxCount, Func.Op, MatcherName);1153}11541155template <typename CladeType, typename... MatcherT>1156std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(1157ast_matchers::internal::MapAnyOfMatcherImpl<CladeType, MatcherT...>,1158StringRef MatcherName) {1159return std::make_unique<MapAnyOfMatcherDescriptor>(1160ASTNodeKind::getFromNodeKind<CladeType>(),1161std::vector<ASTNodeKind>{ASTNodeKind::getFromNodeKind<MatcherT>()...});1162}11631164} // namespace internal1165} // namespace dynamic1166} // namespace ast_matchers1167} // namespace clang11681169#endif // LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H117011711172