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 32 namespace clang { 33 namespace ast_matchers { 34 namespace dynamic { 35 36 namespace 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. 41 template <class T> struct ArgTypeTraits; 42 template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 43 }; 44 45 template <> 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 53 template <> 54 struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { 55 }; 56 57 template <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 71 template <> 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. 83 class MatcherCreateCallback { 84 public: 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. 97 class FixedArgCountMatcherCreateCallback : public MatcherCreateCallback { 98 public: 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 117 private: 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. 130 class FreeFuncMatcherCreateCallback : public MatcherCreateCallback { 131 public: 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 145 private: 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. 168 template <class PolyMatcher> 169 static void mergePolyMatchers(const PolyMatcher &Poly, 170 std::vector<DynTypedMatcher> &Out, 171 ast_matchers::internal::EmptyTypeList) {} 172 173 template <class PolyMatcher, class TypeList> 174 static 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. 186 static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 187 return VariantMatcher::SingleMatcher(Matcher); 188 } 189 190 template <typename T> 191 static 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. 201 template <typename ReturnType> 202 static 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. 212 template <typename ReturnType, typename ArgType1> 213 static 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. 225 template <typename ReturnType, typename ArgType1, typename ArgType2> 226 static 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. 243 template <typename ResultT, typename ArgT, 244 ResultT (*Func)(ArrayRef<const ArgT *>)> 245 VariantMatcher 246 variadicMatcherCreateCallback(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. 280 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 281 typename FromTypes, typename ToTypes> 282 class AdaptativeOverloadCollector { 283 public: 284 AdaptativeOverloadCollector(StringRef Name, 285 std::vector<MatcherCreateCallback *> &Out) 286 : Name(Name), Out(Out) { 287 collect(FromTypes()); 288 } 289 290 private: 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. 310 class OverloadedMatcherCreateCallback : public MatcherCreateCallback { 311 public: 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 342 private: 343 std::vector<MatcherCreateCallback *> Overloads; 344 }; 345 346 /// \brief Variadic operator marshaller function. 347 class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback { 348 public: 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 370 private: 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 380 template <typename ReturnType> 381 MatcherCreateCallback *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 389 template <typename ReturnType, typename ArgType1> 390 MatcherCreateCallback *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 398 template <typename ReturnType, typename ArgType1, typename ArgType2> 399 MatcherCreateCallback *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. 408 template <typename ResultT, typename ArgT, 409 ResultT (*Func)(ArrayRef<const ArgT *>)> 410 MatcherCreateCallback * 411 makeMatcherAutoMarshall(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. 418 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 419 typename FromTypes, typename ToTypes> 420 MatcherCreateCallback * 421 makeMatcherAutoMarshall(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 430 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 431 typename FromTypes, typename ToTypes> 432 template <typename FromTypeList> 433 inline void 434 AdaptativeOverloadCollector<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. 442 MatcherCreateCallback *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