[ASTMatchers][NFC] Use move semantics when passing matchers around.
authorNathan James <n.james93@hotmail.co.uk>
Wed, 17 Mar 2021 22:03:07 +0000 (22:03 +0000)
committerNathan James <n.james93@hotmail.co.uk>
Wed, 17 Mar 2021 22:03:08 +0000 (22:03 +0000)
Changing matchers to use non-const members and adding r-value overloads of matcher conversions enables move optimisations.
I don't have performance figures but I can say this knocked 120k from the clang-tidy binary(86k was from the .text section) on a Release with assertions build(x86_64-unknown-linux-gnu).

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D98792

clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/include/clang/ASTMatchers/ASTMatchersMacros.h

index 53b37b3..e8f427b 100644 (file)
@@ -541,12 +541,18 @@ public:
   /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
   /// argument.
   /// \c To must be a base class of \c T.
-  template <typename To>
-  Matcher<To> dynCastTo() const {
+  template <typename To> Matcher<To> dynCastTo() const LLVM_LVALUE_FUNCTION {
     static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
     return Matcher<To>(Implementation);
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename To> Matcher<To> dynCastTo() && {
+    static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
+    return Matcher<To>(std::move(Implementation));
+  }
+#endif
+
   /// Forwards the call to the underlying MatcherInterface<T> pointer.
   bool matches(const T &Node,
                ASTMatchFinder *Finder,
@@ -563,7 +569,13 @@ public:
   ///
   /// The returned matcher keeps the same restrictions as \c this and remembers
   /// that it is meant to support nodes of type \c T.
-  operator DynTypedMatcher() const { return Implementation; }
+  operator DynTypedMatcher() const LLVM_LVALUE_FUNCTION {
+    return Implementation;
+  }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  operator DynTypedMatcher() && { return std::move(Implementation); }
+#endif
 
   /// Allows the conversion of a \c Matcher<Type> to a \c
   /// Matcher<QualType>.
@@ -870,7 +882,7 @@ private:
                Names, getOperatorSpelling(Node.getOverloadedOperator()));
   }
 
-  const std::vector<std::string> Names;
+  std::vector<std::string> Names;
 };
 
 /// Matches named declarations with a specific name.
@@ -904,8 +916,8 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
   /// It is slower but simple and works on all cases.
   bool matchesNodeFullSlow(const NamedDecl &Node) const;
 
-  const bool UseUnqualifiedMatch;
-  const std::vector<std::string> Names;
+  bool UseUnqualifiedMatch;
+  std::vector<std::string> Names;
 };
 
 /// Trampoline function to use VariadicFunction<> to construct a
@@ -926,7 +938,7 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
   static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
                 "instantiated with wrong types");
 
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
@@ -1315,20 +1327,36 @@ public:
   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
       : Op(Op), Params(std::forward<Ps>(Params)...) {}
 
-  template <typename T> operator Matcher<T>() const {
+  template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
     return DynTypedMatcher::constructVariadic(
                Op, ASTNodeKind::getFromNodeKind<T>(),
                getMatchers<T>(std::index_sequence_for<Ps...>()))
         .template unconditionalConvertTo<T>();
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename T> operator Matcher<T>() && {
+    return DynTypedMatcher::constructVariadic(
+               Op, ASTNodeKind::getFromNodeKind<T>(),
+               getMatchers<T>(std::index_sequence_for<Ps...>()))
+        .template unconditionalConvertTo<T>();
+  }
+#endif
 private:
   // Helper method to unpack the tuple into a vector.
   template <typename T, std::size_t... Is>
-  std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const {
+  std::vector<DynTypedMatcher>
+  getMatchers(std::index_sequence<Is...>) const LLVM_LVALUE_FUNCTION {
     return {Matcher<T>(std::get<Is>(Params))...};
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename T, std::size_t... Is>
+  std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
+    return {Matcher<T>(std::get<Is>(std::move(Params)))...};
+  }
+#endif
+
   const DynTypedMatcher::VariadicOperator Op;
   std::tuple<Ps...> Params;
 };
@@ -1417,12 +1445,18 @@ public:
 
   using ReturnTypes = ToTypes;
 
-  template <typename To> operator Matcher<To>() const {
+  template <typename To> operator Matcher<To>() const LLVM_LVALUE_FUNCTION {
     return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename To> operator Matcher<To>() && {
+    return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
+  }
+#endif
+
 private:
-  const Matcher<T> InnerMatcher;
+  Matcher<T> InnerMatcher;
 };
 
 /// Converts a \c Matcher<T> to a matcher of desired type \c To by
@@ -1464,7 +1498,7 @@ struct ArgumentAdaptingMatcherFunc {
 };
 
 template <typename T> class TraversalMatcher : public MatcherInterface<T> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
   clang::TraversalKind Traversal;
 
 public:
@@ -1490,13 +1524,22 @@ public:
   TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
       : TK(TK), InnerMatcher(InnerMatcher) {}
 
-  template <typename T> operator Matcher<T>() const {
+  template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
     return internal::DynTypedMatcher::constructRestrictedWrapper(
                new internal::TraversalMatcher<T>(TK, InnerMatcher),
                ASTNodeKind::getFromNodeKind<T>())
         .template unconditionalConvertTo<T>();
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename T> operator Matcher<T>() && {
+    return internal::DynTypedMatcher::constructRestrictedWrapper(
+               new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
+               ASTNodeKind::getFromNodeKind<T>())
+        .template unconditionalConvertTo<T>();
+  }
+#endif
+
 private:
   TraversalKind TK;
   MatcherType InnerMatcher;
@@ -1522,15 +1565,23 @@ public:
 
   using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
 
-  template <typename T>
-  operator Matcher<T>() const {
+  template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
     static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
                   "right polymorphic conversion");
     return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  template <typename T> operator Matcher<T>() && {
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
+    return Matcher<T>(
+        new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
+  }
+#endif
+
 private:
-  const std::tuple<ParamTypes...> Params;
+  std::tuple<ParamTypes...> Params;
 };
 
 /// Matches nodes of type T that have child nodes of type ChildT for
@@ -1539,7 +1590,7 @@ private:
 /// ChildT must be an AST base type.
 template <typename T, typename ChildT>
 class HasMatcher : public MatcherInterface<T> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
@@ -1562,7 +1613,7 @@ class ForEachMatcher : public MatcherInterface<T> {
   static_assert(IsBaseType<ChildT>::value,
                 "for each only accepts base type matcher");
 
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
@@ -1592,7 +1643,7 @@ class HasDescendantMatcher : public MatcherInterface<T> {
   static_assert(IsBaseType<DescendantT>::value,
                 "has descendant only accepts base type matcher");
 
-  const DynTypedMatcher DescendantMatcher;
+  DynTypedMatcher DescendantMatcher;
 
 public:
   explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
@@ -1614,7 +1665,7 @@ class HasParentMatcher : public MatcherInterface<T> {
   static_assert(IsBaseType<ParentT>::value,
                 "has parent only accepts base type matcher");
 
-  const DynTypedMatcher ParentMatcher;
+  DynTypedMatcher ParentMatcher;
 
 public:
   explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
@@ -1636,7 +1687,7 @@ class HasAncestorMatcher : public MatcherInterface<T> {
   static_assert(IsBaseType<AncestorT>::value,
                 "has ancestor only accepts base type matcher");
 
-  const DynTypedMatcher AncestorMatcher;
+  DynTypedMatcher AncestorMatcher;
 
 public:
   explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
@@ -1660,7 +1711,7 @@ class ForEachDescendantMatcher : public MatcherInterface<T> {
   static_assert(IsBaseType<DescendantT>::value,
                 "for each descendant only accepts base type matcher");
 
-  const DynTypedMatcher DescendantMatcher;
+  DynTypedMatcher DescendantMatcher;
 
 public:
   explicit ForEachDescendantMatcher(
@@ -1693,7 +1744,7 @@ public:
   }
 
 private:
-  const ValueT ExpectedValue;
+  ValueT ExpectedValue;
 };
 
 /// Template specializations to easily write matchers for floating point
@@ -1726,7 +1777,7 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
 /// \c Matcher<T> matches.
 template <typename TLoc, typename T>
 class LocMatcher : public MatcherInterface<TLoc> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit LocMatcher(const Matcher<T> &InnerMatcher)
@@ -1750,7 +1801,7 @@ private:
 ///
 /// Used to implement the \c loc() matcher.
 class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
@@ -1769,7 +1820,7 @@ public:
 /// another node of type \c T that can be reached using a given traverse
 /// function.
 template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
@@ -1794,7 +1845,7 @@ private:
 /// given traverse function.
 template <typename T>
 class TypeLocTraverseMatcher : public MatcherInterface<T> {
-  const DynTypedMatcher InnerMatcher;
+  DynTypedMatcher InnerMatcher;
 
 public:
   explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
@@ -1849,7 +1900,7 @@ public:
   };
 
 private:
-  const Matcher<InnerTBase> InnerMatcher;
+  Matcher<InnerTBase> InnerMatcher;
 };
 
 /// A simple memoizer of T(*)() functions.
@@ -2193,7 +2244,7 @@ private:
     return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
   }
 
-  const std::vector<std::string> Names;
+  std::vector<std::string> Names;
 };
 
 using HasOpNameMatcher =
index b7fe907..592a389 100644 (file)
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    ParamType const Param;                                                     \
+    ParamType Param;                                                           \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
     return ::clang::ast_matchers::internal::makeMatcher(                       \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
   }                                                                            \
-  typedef ::clang::ast_matchers::internal::Matcher<Type>                     \
+  typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
       &DefineMatcher##_Type##OverloadId)(ParamType const &Param);              \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
       const Type &Node,                                                        \
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    ParamType1 const Param1;                                                   \
-    ParamType2 const Param2;                                                   \
+    ParamType1 Param1;                                                         \
+    ParamType2 Param2;                                                         \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
                                                                    Param2));   \
   }                                                                            \
-  typedef ::clang::ast_matchers::internal::Matcher<Type>                     \
+  typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
       &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1,             \
                                          ParamType2 const &Param2);            \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    ParamType const Param;                                                     \
+    ParamType Param;                                                           \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    ParamType1 const Param1;                                                   \
-    ParamType2 const Param2;                                                   \
+    ParamType1 Param1;                                                         \
+    ParamType2 Param2;                                                         \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    std::shared_ptr<llvm::Regex> const Param;                                  \
+    std::shared_ptr<llvm::Regex> Param;                                        \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
                      *Builder) const override;                                 \
                                                                                \
   private:                                                                     \
-    std::shared_ptr<llvm::Regex> const Param;                                  \
+    std::shared_ptr<llvm::Regex> Param;                                        \
   };                                                                           \
   }                                                                            \
   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \