]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/Marshallers.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / clang / lib / ASTMatchers / Dynamic / Marshallers.h
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