1 //===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Functions templates and classes to wrap matcher construct functions.
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.
18 //===----------------------------------------------------------------------===//
20 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
21 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
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"
33 namespace ast_matchers {
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> {
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();
54 struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
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() +
63 static bool is(const VariantValue &Value) {
64 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
66 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
67 return Value.getMatcher().getTypedMatcher<T>();
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();
79 /// \brief Generic MatcherCreate interface.
81 /// Provides a \c run() method that constructs the matcher from the provided
83 class MatcherCreateCallback {
85 virtual ~MatcherCreateCallback() {}
86 virtual VariantMatcher run(const SourceRange &NameRange,
87 ArrayRef<ParserValue> Args,
88 Diagnostics *Error) const = 0;
91 /// \brief Simple callback implementation. Marshaller and function are provided.
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 {
99 typedef VariantMatcher (*MarshallerType)(void (*Func)(),
100 StringRef MatcherName,
101 const SourceRange &NameRange,
102 ArrayRef<ParserValue> Args,
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) {}
112 VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
113 Diagnostics *Error) const {
114 return Marshaller(Func, MatcherName, NameRange, Args, Error);
118 const MarshallerType Marshaller;
119 void (* const Func)();
120 const std::string MatcherName;
123 /// \brief Simple callback implementation. Free function is wrapped.
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
130 class FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
132 typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
133 const SourceRange &NameRange,
134 ArrayRef<ParserValue> Args,
137 FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
138 : Func(Func), MatcherName(MatcherName.str()) {}
140 VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
141 Diagnostics *Error) const {
142 return Func(MatcherName, NameRange, Args, Error);
147 const std::string MatcherName;
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(); \
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(); \
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) {}
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());
180 /// \brief Convert the return values of the functions into a VariantMatcher.
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
186 static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
187 return VariantMatcher::SingleMatcher(Matcher);
190 template <typename T>
191 static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
192 typename T::ReturnTypes * =
194 std::vector<DynTypedMatcher> Matchers;
195 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
196 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);
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)();
208 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
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);
219 CHECK_ARG_TYPE(0, ArgType1);
220 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
221 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
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);
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)));
239 #undef CHECK_ARG_COUNT
240 #undef CHECK_ARG_TYPE
242 /// \brief Variadic marshaller function.
243 template <typename ResultT, typename ArgT,
244 ResultT (*Func)(ArrayRef<const ArgT *>)>
246 variadicMatcherCreateCallback(StringRef MatcherName,
247 const SourceRange &NameRange,
248 ArrayRef<ParserValue> Args, Diagnostics *Error) {
249 ArgT **InnerArgs = new ArgT *[Args.size()]();
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();
262 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
267 Out = outvalueToVariantMatcher(
268 Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
271 for (size_t i = 0, e = Args.size(); i != e; ++i) {
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 {
284 AdaptativeOverloadCollector(StringRef Name,
285 std::vector<MatcherCreateCallback *> &Out)
286 : Name(Name), Out(Out) {
287 collect(FromTypes());
291 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
292 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
294 /// \brief End case for the recursion
295 static void collect(ast_matchers::internal::EmptyTypeList) {}
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);
301 const StringRef Name;
302 std::vector<MatcherCreateCallback *> &Out;
305 /// \brief MatcherCreateCallback that wraps multiple "overloads" of the same
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 {
312 OverloadedMatcherCreateCallback(ArrayRef<MatcherCreateCallback *> Callbacks)
313 : Overloads(Callbacks) {}
315 virtual ~OverloadedMatcherCreateCallback() {
316 llvm::DeleteContainerPointers(Overloads);
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);
331 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
332 // We ignore the errors if any matcher succeeded.
334 if (Constructed.size() > 1) {
335 // More than one constructed. It is ambiguous.
336 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
337 return VariantMatcher();
339 return Constructed[0];
343 std::vector<MatcherCreateCallback *> Overloads;
346 /// \brief Variadic operator marshaller function.
347 class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback {
349 typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
350 VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName)
351 : Func(Func), MatcherName(MatcherName) {}
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();
365 InnerArgs.push_back(Value.getMatcher());
367 return VariantMatcher::VariadicOperatorMatcher(Func, InnerArgs);
372 const StringRef MatcherName;
376 /// Helper functions to select the appropriate marshaller functions.
377 /// They detect the number of arguments, arguments types and return type.
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),
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);
397 /// \brief 2-arg overload
398 template <typename ReturnType, typename ArgType1, typename ArgType2>
399 MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
401 StringRef MatcherName) {
402 return new FixedArgCountMatcherCreateCallback(
403 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
404 reinterpret_cast<void (*)()>(Func), MatcherName);
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);
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,
427 return new OverloadedMatcherCreateCallback(Overloads);
430 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
431 typename FromTypes, typename ToTypes>
432 template <typename FromTypeList>
434 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>::collect(
436 Out.push_back(makeMatcherAutoMarshall(
437 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
438 collect(typename FromTypeList::tail());
441 /// \brief Variadic operator overload.
442 MatcherCreateCallback *makeMatcherAutoMarshall(
443 ast_matchers::internal::VariadicOperatorMatcherFunc Func,
444 StringRef MatcherName) {
445 return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName);
448 } // namespace internal
449 } // namespace dynamic
450 } // namespace ast_matchers
453 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H