Replace variadic operator function pointer with an enum value.
authorSamuel Benzaquen <sbenza@google.com>
Thu, 20 Nov 2014 15:45:53 +0000 (15:45 +0000)
committerSamuel Benzaquen <sbenza@google.com>
Thu, 20 Nov 2014 15:45:53 +0000 (15:45 +0000)
Summary:
Replace variadic operator function pointer with an enum value.
Hiding the implementation of the variadic matcher will allow to specialize them for the operation performed.
In particular, it will allow for a more efficient allOf() matcher.

Reviewers: klimek

Subscribers: klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D6293

llvm-svn: 222432

clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Marshallers.h
clang/lib/ASTMatchers/Dynamic/VariantValue.cpp

index 4537c47..37c7b16 100644 (file)
@@ -1512,21 +1512,21 @@ const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
 ///
 /// Usable as: Any Matcher
 const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
-  internal::EachOfVariadicOperator
+  internal::DynTypedMatcher::VO_EachOf
 };
 
 /// \brief Matches if any of the given matchers matches.
 ///
 /// Usable as: Any Matcher
 const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
-  internal::AnyOfVariadicOperator
+  internal::DynTypedMatcher::VO_AnyOf
 };
 
 /// \brief Matches if all given matchers match.
 ///
 /// Usable as: Any Matcher
 const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
-  internal::AllOfVariadicOperator
+  internal::DynTypedMatcher::VO_AllOf
 };
 
 /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
@@ -1858,7 +1858,7 @@ const internal::ArgumentAdaptingMatcherFunc<
 ///
 /// Usable as: Any Matcher
 const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
-  internal::NotUnaryOperator
+  internal::DynTypedMatcher::VO_UnaryNot
 };
 
 /// \brief Matches a node if the declaration associated with that node
index ba571f0..1b8040c 100644 (file)
@@ -263,11 +263,23 @@ public:
         RestrictKind(SupportedKind), Implementation(Implementation) {}
 
   /// \brief Construct from a variadic function.
-  typedef bool (*VariadicOperatorFunction)(
-      const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
-      BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
+  enum VariadicOperator {
+    /// \brief Matches nodes for which all provided matchers match.
+    VO_AllOf,
+    /// \brief Matches nodes for which at least one of the provided matchers
+    /// matches.
+    VO_AnyOf,
+    /// \brief Matches nodes for which at least one of the provided matchers
+    /// matches, but doesn't stop at the first match.
+    VO_EachOf,
+    /// \brief Matches nodes that do not match the provided matcher.
+    ///
+    /// Uses the variadic matcher interface, but fails if
+    /// InnerMatchers.size() != 1.
+    VO_UnaryNot
+  };
   static DynTypedMatcher
-  constructVariadic(VariadicOperatorFunction Func,
+  constructVariadic(VariadicOperator Op,
                     std::vector<DynTypedMatcher> InnerMatchers);
 
   /// \brief Get a "true" matcher for \p NodeKind.
@@ -1125,7 +1137,7 @@ private:
 struct VariadicOperatorNoArg {};
 
 /// \brief Polymorphic matcher object that uses a \c
-/// DynTypedMatcher::VariadicOperatorFunction operator.
+/// DynTypedMatcher::VariadicOperator operator.
 ///
 /// Input matchers can have any type (including other polymorphic matcher
 /// types), and the actual Matcher<T> is generated on demand with an implicit
@@ -1140,7 +1152,7 @@ template <typename P1, typename P2 = VariadicOperatorNoArg,
           typename P9 = VariadicOperatorNoArg>
 class VariadicOperatorMatcher {
 public:
-  VariadicOperatorMatcher(DynTypedMatcher::VariadicOperatorFunction Func,
+  VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
                           const P1 &Param1,
                           const P2 &Param2 = VariadicOperatorNoArg(),
                           const P3 &Param3 = VariadicOperatorNoArg(),
@@ -1150,7 +1162,7 @@ public:
                           const P7 &Param7 = VariadicOperatorNoArg(),
                           const P8 &Param8 = VariadicOperatorNoArg(),
                           const P9 &Param9 = VariadicOperatorNoArg())
-      : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
+      : Op(Op), Param1(Param1), Param2(Param2), Param3(Param3),
         Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
         Param8(Param8), Param9(Param9) {}
 
@@ -1165,7 +1177,7 @@ public:
     addMatcher<T>(Param7, Matchers);
     addMatcher<T>(Param8, Matchers);
     addMatcher<T>(Param9, Matchers);
-    return DynTypedMatcher::constructVariadic(Func, std::move(Matchers))
+    return DynTypedMatcher::constructVariadic(Op, std::move(Matchers))
         .template unconditionalConvertTo<T>();
   }
 
@@ -1181,7 +1193,7 @@ private:
   static void addMatcher(VariadicOperatorNoArg,
                          std::vector<DynTypedMatcher> &Matchers) {}
 
-  const DynTypedMatcher::VariadicOperatorFunction Func;
+  const DynTypedMatcher::VariadicOperator Op;
   const P1 Param1;
   const P2 Param2;
   const P3 Param3;
@@ -1199,7 +1211,7 @@ private:
 /// It supports 1-9 argument overloaded operator(). More can be added if needed.
 template <unsigned MinCount, unsigned MaxCount>
 struct VariadicOperatorMatcherFunc {
-  DynTypedMatcher::VariadicOperatorFunction Func;
+  DynTypedMatcher::VariadicOperator Op;
 
   template <unsigned Count, typename T>
   struct EnableIfValidArity
@@ -1208,30 +1220,29 @@ struct VariadicOperatorMatcherFunc {
   template <typename M1>
   typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
   operator()(const M1 &P1) const {
-    return VariadicOperatorMatcher<M1>(Func, P1);
+    return VariadicOperatorMatcher<M1>(Op, P1);
   }
   template <typename M1, typename M2>
   typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
   operator()(const M1 &P1, const M2 &P2) const {
-    return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
+    return VariadicOperatorMatcher<M1, M2>(Op, P1, P2);
   }
   template <typename M1, typename M2, typename M3>
   typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
   operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
-    return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
+    return VariadicOperatorMatcher<M1, M2, M3>(Op, P1, P2, P3);
   }
   template <typename M1, typename M2, typename M3, typename M4>
   typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
-    return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
+    return VariadicOperatorMatcher<M1, M2, M3, M4>(Op, P1, P2, P3, P4);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5>
   typename EnableIfValidArity<
       5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
              const M5 &P5) const {
-    return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
-                                                       P5);
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Op, P1, P2, P3, P4, P5);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5,
             typename M6>
@@ -1240,7 +1251,7 @@ struct VariadicOperatorMatcherFunc {
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
              const M5 &P5, const M6 &P6) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
-        Func, P1, P2, P3, P4, P5, P6);
+        Op, P1, P2, P3, P4, P5, P6);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5,
             typename M6, typename M7>
@@ -1249,7 +1260,7 @@ struct VariadicOperatorMatcherFunc {
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
              const M5 &P5, const M6 &P6, const M7 &P7) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
-        Func, P1, P2, P3, P4, P5, P6, P7);
+        Op, P1, P2, P3, P4, P5, P6, P7);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5,
             typename M6, typename M7, typename M8>
@@ -1258,7 +1269,7 @@ struct VariadicOperatorMatcherFunc {
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
              const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
-        Func, P1, P2, P3, P4, P5, P6, P7, P8);
+        Op, P1, P2, P3, P4, P5, P6, P7, P8);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5,
             typename M6, typename M7, typename M8, typename M9>
@@ -1268,39 +1279,12 @@ struct VariadicOperatorMatcherFunc {
              const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
              const M9 &P9) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
-        Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+        Op, P1, P2, P3, P4, P5, P6, P7, P8, P9);
   }
 };
 
 /// @}
 
-/// \brief Matches nodes that do not match the provided matcher.
-///
-/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
-                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
-                      ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which all provided matchers match.
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                           ASTMatchFinder *Finder,
-                           BoundNodesTreeBuilder *Builder,
-                           ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which at least one of the provided matchers
-/// matches, but doesn't stop at the first match.
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                            ASTMatchFinder *Finder,
-                            BoundNodesTreeBuilder *Builder,
-                            ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which at least one of the provided matchers
-/// matches.
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
-                           ASTMatchFinder *Finder,
-                           BoundNodesTreeBuilder *Builder,
-                           ArrayRef<DynTypedMatcher> InnerMatchers);
-
 template <typename T>
 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
   return Matcher<T>(*this);
@@ -1325,9 +1309,10 @@ BindableMatcher<T> makeAllOfComposite(
   for (const auto *InnerMatcher : InnerMatchers) {
     DynMatchers.push_back(*InnerMatcher);
   }
-  return BindableMatcher<T>(DynTypedMatcher::constructVariadic(
-                                AllOfVariadicOperator, std::move(DynMatchers))
-                                .template unconditionalConvertTo<T>());
+  return BindableMatcher<T>(
+      DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
+                                         std::move(DynMatchers))
+          .template unconditionalConvertTo<T>());
 }
 
 /// \brief Creates a Matcher<T> that matches if
index e4b5519..a9bd3d5 100644 (file)
@@ -107,7 +107,7 @@ class VariantMatcher {
     /// Will try to convert each inner matcher to the destination type and
     /// return llvm::None if it fails to do so.
     llvm::Optional<DynTypedMatcher>
-    constructVariadicOperator(DynTypedMatcher::VariadicOperatorFunction Func,
+    constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
                               ArrayRef<VariantMatcher> InnerMatchers) const;
 
   protected:
@@ -148,7 +148,7 @@ public:
   ///
   /// It will bind to the appropriate type on getTypedMatcher<T>().
   static VariantMatcher
-  VariadicOperatorMatcher(DynTypedMatcher::VariadicOperatorFunction Func,
+  VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
                           std::vector<VariantMatcher> Args);
 
   /// \brief Makes the matcher the "null" matcher.
index af6f0ab..c7d98b8 100644 (file)
@@ -20,6 +20,26 @@ namespace clang {
 namespace ast_matchers {
 namespace internal {
 
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+                      ArrayRef<DynTypedMatcher> InnerMatchers);
+
+bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
+
+bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                            ASTMatchFinder *Finder,
+                            BoundNodesTreeBuilder *Builder,
+                            ArrayRef<DynTypedMatcher> InnerMatchers);
+
+bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
+
+
 void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
   if (Bindings.empty())
     Bindings.push_back(BoundNodesMap());
@@ -31,8 +51,12 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
 namespace {
 
 class VariadicMatcher : public DynMatcherInterface {
- public:
-  VariadicMatcher(DynTypedMatcher::VariadicOperatorFunction Func,
+public:
+  typedef bool (*VariadicOperatorFunction)(
+      const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
+      BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
+
+  VariadicMatcher(VariadicOperatorFunction Func,
                   std::vector<DynTypedMatcher> InnerMatchers)
       : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
 
@@ -42,8 +66,8 @@ class VariadicMatcher : public DynMatcherInterface {
     return Func(DynNode, Finder, Builder, InnerMatchers);
   }
 
- private:
-  DynTypedMatcher::VariadicOperatorFunction Func;
+private:
+  VariadicOperatorFunction Func;
   std::vector<DynTypedMatcher> InnerMatchers;
 };
 
@@ -86,7 +110,7 @@ static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
 }  // namespace
 
 DynTypedMatcher DynTypedMatcher::constructVariadic(
-    DynTypedMatcher::VariadicOperatorFunction Func,
+    DynTypedMatcher::VariadicOperator Op,
     std::vector<DynTypedMatcher> InnerMatchers) {
   assert(InnerMatchers.size() > 0 && "Array must not be empty.");
   assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
@@ -100,6 +124,22 @@ DynTypedMatcher DynTypedMatcher::constructVariadic(
   // Make it the same as SupportedKind, since that is the broadest type we are
   // allowed to accept.
   auto SupportedKind = InnerMatchers[0].SupportedKind;
+  VariadicMatcher::VariadicOperatorFunction Func;
+  switch (Op) {
+  case VO_AllOf:
+    Func = AllOfVariadicOperator;
+    break;
+  case VO_AnyOf:
+    Func = AnyOfVariadicOperator;
+    break;
+  case VO_EachOf:
+    Func = EachOfVariadicOperator;
+    break;
+  case VO_UnaryNot:
+    Func = NotUnaryOperator;
+    break;
+  }
+
   return DynTypedMatcher(SupportedKind, SupportedKind,
                          new VariadicMatcher(Func, std::move(InnerMatchers)));
 }
index 42c880e..b78bc03 100644 (file)
@@ -556,10 +556,10 @@ private:
 /// \brief Variadic operator marshaller function.
 class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
 public:
-  typedef DynTypedMatcher::VariadicOperatorFunction VarFunc;
+  typedef DynTypedMatcher::VariadicOperator VarOp;
   VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
-                                    VarFunc Func, StringRef MatcherName)
-      : MinCount(MinCount), MaxCount(MaxCount), Func(Func),
+                                    VarOp Op, StringRef MatcherName)
+      : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
         MatcherName(MatcherName) {}
 
   virtual VariantMatcher create(const SourceRange &NameRange,
@@ -584,7 +584,7 @@ public:
       }
       InnerArgs.push_back(Value.getMatcher());
     }
-    return VariantMatcher::VariadicOperatorMatcher(Func, std::move(InnerArgs));
+    return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
   }
 
   bool isVariadic() const override { return true; }
@@ -606,7 +606,7 @@ public:
 private:
   const unsigned MinCount;
   const unsigned MaxCount;
-  const VarFunc Func;
+  const VarOp Op;
   const StringRef MatcherName;
 };
 
@@ -699,7 +699,7 @@ MatcherDescriptor *
 makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
                             MinCount, MaxCount> Func,
                         StringRef MatcherName) {
-  return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Func,
+  return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op,
                                                MatcherName);
 }
 
index 08b3b1d..a88b707 100644 (file)
@@ -58,7 +58,7 @@ VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
 
 llvm::Optional<DynTypedMatcher>
 VariantMatcher::MatcherOps::constructVariadicOperator(
-    DynTypedMatcher::VariadicOperatorFunction Func,
+    DynTypedMatcher::VariadicOperator Op,
     ArrayRef<VariantMatcher> InnerMatchers) const {
   std::vector<DynTypedMatcher> DynMatchers;
   for (const auto &InnerMatcher : InnerMatchers) {
@@ -72,7 +72,7 @@ VariantMatcher::MatcherOps::constructVariadicOperator(
       return llvm::None;
     DynMatchers.push_back(*Inner);
   }
-  return DynTypedMatcher::constructVariadic(Func, DynMatchers);
+  return DynTypedMatcher::constructVariadic(Op, DynMatchers);
 }
 
 VariantMatcher::Payload::~Payload() {}
@@ -176,9 +176,9 @@ public:
 
 class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
 public:
-  VariadicOpPayload(DynTypedMatcher::VariadicOperatorFunction Func,
+  VariadicOpPayload(DynTypedMatcher::VariadicOperator Op,
                     std::vector<VariantMatcher> Args)
-      : Func(Func), Args(std::move(Args)) {}
+      : Op(Op), Args(std::move(Args)) {}
 
   llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
     return llvm::Optional<DynTypedMatcher>();
@@ -196,7 +196,7 @@ public:
 
   llvm::Optional<DynTypedMatcher>
   getTypedMatcher(const MatcherOps &Ops) const override {
-    return Ops.constructVariadicOperator(Func, Args);
+    return Ops.constructVariadicOperator(Op, Args);
   }
 
   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -209,7 +209,7 @@ public:
   }
 
 private:
-  const DynTypedMatcher::VariadicOperatorFunction Func;
+  const DynTypedMatcher::VariadicOperator Op;
   const std::vector<VariantMatcher> Args;
 };
 
@@ -225,9 +225,9 @@ VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
 }
 
 VariantMatcher VariantMatcher::VariadicOperatorMatcher(
-    DynTypedMatcher::VariadicOperatorFunction Func,
+    DynTypedMatcher::VariadicOperator Op,
     std::vector<VariantMatcher> Args) {
-  return VariantMatcher(new VariadicOpPayload(Func, std::move(Args)));
+  return VariantMatcher(new VariadicOpPayload(Op, std::move(Args)));
 }
 
 llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {