[PATCH] Remove template instantiations of std::list<Matcher<T>> and std::vector<Matcher<T>*> for each node T.

Samuel Benzaquen sbenza at google.com
Mon Jun 10 15:15:30 PDT 2013


    - Change VariadicMatcherCreateCallback to be a function template, and a single class that wraps the instantiations.
    - Remove some more unnecessary template arguments and function calls.

Hi klimek,

http://llvm-reviews.chandlerc.com/D948

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D948?vs=2336&id=2345#toc

Files:
  lib/ASTMatchers/Dynamic/Marshallers.h

Index: lib/ASTMatchers/Dynamic/Marshallers.h
===================================================================
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -20,9 +20,7 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
 
-#include <list>
 #include <string>
-#include <vector>
 
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
@@ -77,9 +75,15 @@
 };
 
 /// \brief Simple callback implementation. Marshaller and function are provided.
-template <typename MarshallerType, typename FuncType>
+template <typename FuncType>
 class FixedArgCountMatcherCreateCallback : public MatcherCreateCallback {
 public:
+
+  typedef DynTypedMatcher *(*MarshallerType)(FuncType, StringRef,
+                                             const SourceRange &,
+                                             ArrayRef<ParserValue>,
+                                             Diagnostics *);
+
   /// \param Marshaller Function to unpack the arguments and call \c Func
   /// \param Func Matcher construct function. This is the function that
   ///   compile-time matcher expressions would use to create the matcher.
@@ -98,14 +102,26 @@
   const std::string MatcherName;
 };
 
-/// \brief Helper function to do template argument deduction.
-template <typename MarshallerType, typename FuncType>
-MatcherCreateCallback *
-createMarshallerCallback(MarshallerType Marshaller, FuncType Func,
-                         StringRef MatcherName) {
-  return new FixedArgCountMatcherCreateCallback<MarshallerType, FuncType>(
-      Marshaller, Func, MatcherName);
-}
+/// \brief Simple callback implementation. Free function is wrapped.
+class FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
+public:
+  typedef DynTypedMatcher *(*RunFunc)(StringRef MatcherName,
+                                      const SourceRange &NameRange,
+                                      ArrayRef<ParserValue> Args,
+                                      Diagnostics *Error);
+
+  FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
+      : Func(Func), MatcherName(MatcherName.str()) {}
+
+  DynTypedMatcher *run(const SourceRange &NameRange,
+                       ArrayRef<ParserValue> Args, Diagnostics *Error) const {
+    return Func(MatcherName, NameRange, Args, Error);
+  }
+
+private:
+  const RunFunc Func;
+  const std::string MatcherName;
+};
 
 /// \brief Helper macros to check the arguments on all marshaller functions.
 #define CHECK_ARG_COUNT(count)                                                 \
@@ -158,79 +174,87 @@
               ArgTypeTraits<ArgType2>::get(Args[1].Value)).clone();
 }
 
+#undef CHECK_ARG_COUNT
+#undef CHECK_ARG_TYPE
+
 /// \brief Variadic marshaller function.
 template <typename BaseType, typename DerivedType>
-class VariadicMatcherCreateCallback : public MatcherCreateCallback {
-public:
-  explicit VariadicMatcherCreateCallback(StringRef MatcherName)
-      : MatcherName(MatcherName.str()) {}
-
+DynTypedMatcher *VariadicMatcherCreateCallback(StringRef MatcherName,
+                                               const SourceRange &NameRange,
+                                               ArrayRef<ParserValue> Args,
+                                               Diagnostics *Error) {
   typedef ast_matchers::internal::Matcher<DerivedType> DerivedMatcherType;
-
-  DynTypedMatcher *run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
-                       Diagnostics *Error) const {
-    std::list<DerivedMatcherType> References;
-    std::vector<const DerivedMatcherType *> InnerArgs(Args.size());
-    for (size_t i = 0, e = Args.size(); i != e; ++i) {
-      CHECK_ARG_TYPE(i, DerivedMatcherType);
-      References.push_back(
-          ArgTypeTraits<DerivedMatcherType>::get(Args[i].Value));
-      InnerArgs[i] = &References.back();
+  DerivedMatcherType **InnerArgs = new DerivedMatcherType *[Args.size()]();
+
+  bool HasError = false;
+  for (size_t I = 0, E = Args.size(); I != E; ++I) {
+    if (!Args[I].Value.isTypedMatcher<DerivedType>()) {
+      Error->pushErrorFrame(Args[I].Range, Error->ET_RegistryWrongArgType)
+          << MatcherName << (I + 1);
+      HasError = true;
+      break;
     }
-    return ast_matchers::internal::makeDynCastAllOfComposite<BaseType>(
-        ArrayRef<const DerivedMatcherType *>(InnerArgs)).clone();
+    InnerArgs[I] =
+        new DerivedMatcherType(Args[I].Value.getTypedMatcher<DerivedType>());
   }
 
-private:
-  const std::string MatcherName;
-};
+  DynTypedMatcher *Out = NULL;
+  if (!HasError) {
+    Out = ast_matchers::internal::makeDynCastAllOfComposite<BaseType>(
+        ArrayRef<const DerivedMatcherType *>(InnerArgs, Args.size())).clone();
+  }
 
-#undef CHECK_ARG_COUNT
-#undef CHECK_ARG_TYPE
+  for (size_t I = 0, E = Args.size(); I != E; ++I) {
+    delete InnerArgs[I];
+  }
+  delete[] InnerArgs;
+  return Out;
+}
 
 /// Helper functions to select the appropriate marshaller functions.
-/// They detects the number of arguments, arguments types and return type.
+/// They detect the number of arguments, arguments types and return type.
 
 /// \brief 0-arg overload
 template <typename ReturnType>
 MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(),
                                                StringRef MatcherName) {
-  return createMarshallerCallback(matcherMarshall0<ReturnType>, Func,
-                                  MatcherName);
+  return new FixedArgCountMatcherCreateCallback<ReturnType (*)()>(
+      matcherMarshall0, Func, MatcherName);
 }
 
 /// \brief 1-arg overload
 template <typename ReturnType, typename ArgType1>
 MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
                                                StringRef MatcherName) {
-  return createMarshallerCallback(matcherMarshall1<ReturnType, ArgType1>, Func,
-                                  MatcherName);
+  return new FixedArgCountMatcherCreateCallback<ReturnType (*)(ArgType1)>(
+      matcherMarshall1, Func, MatcherName);
 }
 
 /// \brief 2-arg overload
 template <typename ReturnType, typename ArgType1, typename ArgType2>
 MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
                                                                   ArgType2),
                                                StringRef MatcherName) {
-  return createMarshallerCallback(
-      matcherMarshall2<ReturnType, ArgType1, ArgType2>, Func, MatcherName);
+  return new FixedArgCountMatcherCreateCallback<
+      ReturnType (*)(ArgType1, ArgType2)>(matcherMarshall2, Func, MatcherName);
 }
 
 /// \brief Variadic overload.
 template <typename MatcherType>
 MatcherCreateCallback *makeMatcherAutoMarshall(
     ast_matchers::internal::VariadicAllOfMatcher<MatcherType> Func,
     StringRef MatcherName) {
-  return new VariadicMatcherCreateCallback<MatcherType, MatcherType>(
-      MatcherName);
+  return new FreeFuncMatcherCreateCallback(
+      &VariadicMatcherCreateCallback<MatcherType, MatcherType>, MatcherName);
 }
 
 template <typename BaseType, typename MatcherType>
 MatcherCreateCallback *
 makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher<
                             BaseType, MatcherType> Func,
                         StringRef MatcherName) {
-  return new VariadicMatcherCreateCallback<BaseType, MatcherType>(MatcherName);
+  return new FreeFuncMatcherCreateCallback(
+      &VariadicMatcherCreateCallback<BaseType, MatcherType>, MatcherName);
 }
 
 }  // namespace internal
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D948.2.patch
Type: text/x-patch
Size: 7651 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130610/d8d8e269/attachment.bin>


More information about the cfe-commits mailing list