1//===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief Functions templates and classes to wrap matcher construct functions. 12/// 13/// A collection of template function and classes that provide a generic 14/// marshalling layer on top of matcher construct functions. 15/// These are used by the registry to export all marshaller constructors with 16/// the same generic interface. 17/// 18//===----------------------------------------------------------------------===// 19 20#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 21#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 22 23#include <string> 24 25#include "clang/ASTMatchers/ASTMatchers.h" 26#include "clang/ASTMatchers/Dynamic/Diagnostics.h" 27#include "clang/ASTMatchers/Dynamic/VariantValue.h" 28#include "clang/Basic/LLVM.h" 29#include "llvm/ADT/STLExtras.h" 30#include "llvm/Support/type_traits.h" 31 32namespace clang { 33namespace ast_matchers { 34namespace dynamic { 35 36namespace internal { 37 38/// \brief Helper template class to just from argument type to the right is/get 39/// functions in VariantValue. 40/// Used to verify and extract the matcher arguments below. 41template <class T> struct ArgTypeTraits; 42template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 43}; 44 45template <> struct ArgTypeTraits<std::string> { 46 static StringRef asString() { return "String"; } 47 static bool is(const VariantValue &Value) { return Value.isString(); } 48 static const std::string &get(const VariantValue &Value) { 49 return Value.getString(); 50 } 51}; 52 53template <> 54struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { 55}; 56 57template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > { 58 static std::string asString() { 59 return (Twine("Matcher<") + 60 ast_type_traits::ASTNodeKind::getFromNodeKind<T>().asStringRef() + 61 ">").str(); 62 } 63 static bool is(const VariantValue &Value) { 64 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); 65 } 66 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { 67 return Value.getMatcher().getTypedMatcher<T>(); 68 } 69}; 70 71template <> struct ArgTypeTraits<unsigned> { 72 static std::string asString() { return "Unsigned"; } 73 static bool is(const VariantValue &Value) { return Value.isUnsigned(); } 74 static unsigned get(const VariantValue &Value) { 75 return Value.getUnsigned(); 76 } 77}; 78 79/// \brief Generic MatcherCreate interface. 80/// 81/// Provides a \c run() method that constructs the matcher from the provided 82/// arguments. 83class MatcherCreateCallback { 84public: 85 virtual ~MatcherCreateCallback() {} 86 virtual VariantMatcher run(const SourceRange &NameRange, 87 ArrayRef<ParserValue> Args, 88 Diagnostics *Error) const = 0; 89}; 90 91/// \brief Simple callback implementation. Marshaller and function are provided. 92/// 93/// This class wraps a function of arbitrary signature and a marshaller 94/// function into a MatcherCreateCallback. 95/// The marshaller is in charge of taking the VariantValue arguments, checking 96/// their types, unpacking them and calling the underlying function. 97class FixedArgCountMatcherCreateCallback : public MatcherCreateCallback { 98public: 99 typedef VariantMatcher (*MarshallerType)(void (*Func)(), 100 StringRef MatcherName, 101 const SourceRange &NameRange, 102 ArrayRef<ParserValue> Args, 103 Diagnostics *Error); 104 105 /// \param Marshaller Function to unpack the arguments and call \c Func 106 /// \param Func Matcher construct function. This is the function that 107 /// compile-time matcher expressions would use to create the matcher. 108 FixedArgCountMatcherCreateCallback(MarshallerType Marshaller, void (*Func)(), 109 StringRef MatcherName) 110 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName) {} 111 112 VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args, 113 Diagnostics *Error) const { 114 return Marshaller(Func, MatcherName, NameRange, Args, Error); 115 } 116 117private: 118 const MarshallerType Marshaller; 119 void (* const Func)(); 120 const std::string MatcherName; 121}; 122 123/// \brief Simple callback implementation. Free function is wrapped. 124/// 125/// This class simply wraps a free function with the right signature to export 126/// it as a MatcherCreateCallback. 127/// This allows us to have one implementation of the interface for as many free 128/// functions as we want, reducing the number of symbols and size of the 129/// object file. 130class FreeFuncMatcherCreateCallback : public MatcherCreateCallback { 131public: 132 typedef VariantMatcher (*RunFunc)(StringRef MatcherName, 133 const SourceRange &NameRange, 134 ArrayRef<ParserValue> Args, 135 Diagnostics *Error); 136 137 FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName) 138 : Func(Func), MatcherName(MatcherName.str()) {} 139 140 VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args, 141 Diagnostics *Error) const { 142 return Func(MatcherName, NameRange, Args, Error); 143 } 144 145private: 146 const RunFunc Func; 147 const std::string MatcherName; 148}; 149 150/// \brief Helper macros to check the arguments on all marshaller functions. 151#define CHECK_ARG_COUNT(count) \ 152 if (Args.size() != count) { \ 153 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ 154 << count << Args.size(); \ 155 return VariantMatcher(); \ 156 } 157 158#define CHECK_ARG_TYPE(index, type) \ 159 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ 160 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ 161 << (index + 1) << ArgTypeTraits<type>::asString() \ 162 << Args[index].Value.getTypeAsString(); \ 163 return VariantMatcher(); \ 164 } 165 166/// \brief Helper methods to extract and merge all possible typed matchers 167/// out of the polymorphic object. 168template <class PolyMatcher> 169static void mergePolyMatchers(const PolyMatcher &Poly, 170 std::vector<DynTypedMatcher> &Out, 171 ast_matchers::internal::EmptyTypeList) {} 172 173template <class PolyMatcher, class TypeList> 174static void mergePolyMatchers(const PolyMatcher &Poly, 175 std::vector<DynTypedMatcher> &Out, TypeList) { 176 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); 177 mergePolyMatchers(Poly, Out, typename TypeList::tail()); 178} 179 180/// \brief Convert the return values of the functions into a VariantMatcher. 181/// 182/// There are 2 cases right now: The return value is a Matcher<T> or is a 183/// polymorphic matcher. For the former, we just construct the VariantMatcher. 184/// For the latter, we instantiate all the possible Matcher<T> of the poly 185/// matcher. 186static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 187 return VariantMatcher::SingleMatcher(Matcher); 188} 189 190template <typename T> 191static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, 192 typename T::ReturnTypes * = 193 NULL) { 194 std::vector<DynTypedMatcher> Matchers; 195 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); 196 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers); 197 return Out; 198} 199 200/// \brief 0-arg marshaller function. 201template <typename ReturnType> 202static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, 203 const SourceRange &NameRange, 204 ArrayRef<ParserValue> Args, 205 Diagnostics *Error) { 206 typedef ReturnType (*FuncType)(); 207 CHECK_ARG_COUNT(0); 208 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)()); 209} 210 211/// \brief 1-arg marshaller function. 212template <typename ReturnType, typename ArgType1> 213static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName, 214 const SourceRange &NameRange, 215 ArrayRef<ParserValue> Args, 216 Diagnostics *Error) { 217 typedef ReturnType (*FuncType)(ArgType1); 218 CHECK_ARG_COUNT(1); 219 CHECK_ARG_TYPE(0, ArgType1); 220 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 221 ArgTypeTraits<ArgType1>::get(Args[0].Value))); 222} 223 224/// \brief 2-arg marshaller function. 225template <typename ReturnType, typename ArgType1, typename ArgType2> 226static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName, 227 const SourceRange &NameRange, 228 ArrayRef<ParserValue> Args, 229 Diagnostics *Error) { 230 typedef ReturnType (*FuncType)(ArgType1, ArgType2); 231 CHECK_ARG_COUNT(2); 232 CHECK_ARG_TYPE(0, ArgType1); 233 CHECK_ARG_TYPE(1, ArgType2); 234 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 235 ArgTypeTraits<ArgType1>::get(Args[0].Value), 236 ArgTypeTraits<ArgType2>::get(Args[1].Value))); 237} 238 239#undef CHECK_ARG_COUNT 240#undef CHECK_ARG_TYPE 241 242/// \brief Variadic marshaller function. 243template <typename ResultT, typename ArgT, 244 ResultT (*Func)(ArrayRef<const ArgT *>)> 245VariantMatcher 246variadicMatcherCreateCallback(StringRef MatcherName, 247 const SourceRange &NameRange, 248 ArrayRef<ParserValue> Args, Diagnostics *Error) { 249 ArgT **InnerArgs = new ArgT *[Args.size()](); 250 251 bool HasError = false; 252 for (size_t i = 0, e = Args.size(); i != e; ++i) { 253 typedef ArgTypeTraits<ArgT> ArgTraits; 254 const ParserValue &Arg = Args[i]; 255 const VariantValue &Value = Arg.Value; 256 if (!ArgTraits::is(Value)) { 257 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 258 << (i + 1) << ArgTraits::asString() << Value.getTypeAsString(); 259 HasError = true; 260 break; 261 } 262 InnerArgs[i] = new ArgT(ArgTraits::get(Value)); 263 } 264 265 VariantMatcher Out; 266 if (!HasError) { 267 Out = outvalueToVariantMatcher( 268 Func(ArrayRef<const ArgT *>(InnerArgs, Args.size()))); 269 } 270 271 for (size_t i = 0, e = Args.size(); i != e; ++i) { 272 delete InnerArgs[i]; 273 } 274 delete[] InnerArgs; 275 return Out; 276} 277 278/// \brief Helper class used to collect all the possible overloads of an 279/// argument adaptative matcher function. 280template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 281 typename FromTypes, typename ToTypes> 282class AdaptativeOverloadCollector { 283public: 284 AdaptativeOverloadCollector(StringRef Name, 285 std::vector<MatcherCreateCallback *> &Out) 286 : Name(Name), Out(Out) { 287 collect(FromTypes()); 288 } 289 290private: 291 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc< 292 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc; 293 294 /// \brief End case for the recursion 295 static void collect(ast_matchers::internal::EmptyTypeList) {} 296 297 /// \brief Recursive case. Get the overload for the head of the list, and 298 /// recurse to the tail. 299 template <typename FromTypeList> inline void collect(FromTypeList); 300 301 const StringRef Name; 302 std::vector<MatcherCreateCallback *> &Out; 303}; 304 305/// \brief MatcherCreateCallback that wraps multiple "overloads" of the same 306/// matcher. 307/// 308/// It will try every overload and generate appropriate errors for when none or 309/// more than one overloads match the arguments. 310class OverloadedMatcherCreateCallback : public MatcherCreateCallback { 311public: 312 OverloadedMatcherCreateCallback(ArrayRef<MatcherCreateCallback *> Callbacks) 313 : Overloads(Callbacks) {} 314 315 virtual ~OverloadedMatcherCreateCallback() { 316 llvm::DeleteContainerPointers(Overloads); 317 } 318 319 virtual VariantMatcher run(const SourceRange &NameRange, 320 ArrayRef<ParserValue> Args, 321 Diagnostics *Error) const { 322 std::vector<VariantMatcher> Constructed; 323 Diagnostics::OverloadContext Ctx(Error); 324 for (size_t i = 0, e = Overloads.size(); i != e; ++i) { 325 VariantMatcher SubMatcher = Overloads[i]->run(NameRange, Args, Error); 326 if (!SubMatcher.isNull()) { 327 Constructed.push_back(SubMatcher); 328 } 329 } 330 331 if (Constructed.empty()) return VariantMatcher(); // No overload matched. 332 // We ignore the errors if any matcher succeeded. 333 Ctx.revertErrors(); 334 if (Constructed.size() > 1) { 335 // More than one constructed. It is ambiguous. 336 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); 337 return VariantMatcher(); 338 } 339 return Constructed[0]; 340 } 341 342private: 343 std::vector<MatcherCreateCallback *> Overloads; 344}; 345 346/// \brief Variadic operator marshaller function. 347class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback { 348public: 349 typedef ast_matchers::internal::VariadicOperatorFunction VarFunc; 350 VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName) 351 : Func(Func), MatcherName(MatcherName) {} 352 353 virtual VariantMatcher run(const SourceRange &NameRange, 354 ArrayRef<ParserValue> Args, 355 Diagnostics *Error) const { 356 std::vector<VariantMatcher> InnerArgs; 357 for (size_t i = 0, e = Args.size(); i != e; ++i) { 358 const ParserValue &Arg = Args[i]; 359 const VariantValue &Value = Arg.Value; 360 if (!Value.isMatcher()) { 361 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 362 << (i + 1) << "Matcher<>" << Value.getTypeAsString(); 363 return VariantMatcher(); 364 } 365 InnerArgs.push_back(Value.getMatcher()); 366 } 367 return VariantMatcher::VariadicOperatorMatcher(Func, InnerArgs); 368 } 369 370private: 371 const VarFunc Func; 372 const StringRef MatcherName; 373}; 374 375 376/// Helper functions to select the appropriate marshaller functions. 377/// They detect the number of arguments, arguments types and return type. 378 379/// \brief 0-arg overload 380template <typename ReturnType> 381MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(), 382 StringRef MatcherName) { 383 return new FixedArgCountMatcherCreateCallback( 384 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), 385 MatcherName); 386} 387 388/// \brief 1-arg overload 389template <typename ReturnType, typename ArgType1> 390MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), 391 StringRef MatcherName) { 392 return new FixedArgCountMatcherCreateCallback( 393 matcherMarshall1<ReturnType, ArgType1>, 394 reinterpret_cast<void (*)()>(Func), MatcherName); 395} 396 397/// \brief 2-arg overload 398template <typename ReturnType, typename ArgType1, typename ArgType2> 399MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, 400 ArgType2), 401 StringRef MatcherName) { 402 return new FixedArgCountMatcherCreateCallback( 403 matcherMarshall2<ReturnType, ArgType1, ArgType2>, 404 reinterpret_cast<void (*)()>(Func), MatcherName); 405} 406 407/// \brief Variadic overload. 408template <typename ResultT, typename ArgT, 409 ResultT (*Func)(ArrayRef<const ArgT *>)> 410MatcherCreateCallback * 411makeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc, 412 StringRef MatcherName) { 413 return new FreeFuncMatcherCreateCallback( 414 &variadicMatcherCreateCallback<ResultT, ArgT, Func>, MatcherName); 415} 416 417/// \brief Argument adaptative overload. 418template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 419 typename FromTypes, typename ToTypes> 420MatcherCreateCallback * 421makeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc< 422 ArgumentAdapterT, FromTypes, ToTypes>, 423 StringRef MatcherName) { 424 std::vector<MatcherCreateCallback *> Overloads; 425 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, 426 Overloads); 427 return new OverloadedMatcherCreateCallback(Overloads); 428} 429 430template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 431 typename FromTypes, typename ToTypes> 432template <typename FromTypeList> 433inline void 434AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>::collect( 435 FromTypeList) { 436 Out.push_back(makeMatcherAutoMarshall( 437 &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); 438 collect(typename FromTypeList::tail()); 439} 440 441/// \brief Variadic operator overload. 442MatcherCreateCallback *makeMatcherAutoMarshall( 443 ast_matchers::internal::VariadicOperatorMatcherFunc Func, 444 StringRef MatcherName) { 445 return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName); 446} 447 448} // namespace internal 449} // namespace dynamic 450} // namespace ast_matchers 451} // namespace clang 452 453#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 454