[PATCH] D28260: Add an argumentsAre matcher

Matt Kulukundis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 3 15:36:34 PST 2017


fowles created this revision.
fowles added a reviewer: klimek.
fowles added a subscriber: cfe-commits.

Add an argumentsAre matcher


https://reviews.llvm.org/D28260

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersTraversalTest.cpp


Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -375,6 +375,14 @@
   EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
 }
 
+TEST(Matcher, ArgumentsAre) {
+  StatementMatcher Call = callExpr(argumentsAre(declRefExpr(), declRefExpr()));
+
+  EXPECT_TRUE(notMatches("void f(int x) { f(x); }", Call));
+  EXPECT_TRUE(matches("void f(int x, int y) { f(x, y); }", Call));
+  EXPECT_TRUE(notMatches("void f(int x, int y, int z) { f(x, y, z); }", Call));
+}
+
 TEST(Matcher, AnyArgument) {
   StatementMatcher CallArgumentY = callExpr(
     hasAnyArgument(
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3055,6 +3055,34 @@
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
 }
 
+namespace internal {
+inline auto argumentsAreImpl(int n) -> decltype(argumentCountIs(n)) {
+  return argumentCountIs(n);
+}
+
+template <typename First, typename... Rest>
+auto argumentsAreImpl(int n, First &&first, Rest &&... rest)
+    -> decltype(allOf(hasArgument(n, std::forward<First>(first)),
+                      argumentsAreImpl(n + 1, std::forward<Rest>(rest)...))) {
+  return allOf(hasArgument(n, std::forward<First>(first)),
+               argumentsAreImpl(n + 1, std::forward<Rest>(rest)...));
+}
+} // end namespace internal
+
+/// \brief Matches all the arguments of a call expression or a constructor
+/// call expression.
+///
+/// Example matches the call to f2, but not f1 or f3.
+///     (matcher = callExpr(argumentsAre(declRefExpr(), declRefExpr())))
+/// \code
+///   void x(int a, int b, int c) { f1(a); f2(a, b); f3(a, b, c); }
+/// \endcode
+template <typename... T>
+auto argumentsAre(T &&... t)
+    -> decltype(internal::argumentsAreImpl(0, std::forward<T>(t)...)) {
+  return internal::argumentsAreImpl(0, std::forward<T>(t)...);
+}
+
 /// \brief Matches declaration statements that contain a specific number of
 /// declarations.
 ///


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28260.82964.patch
Type: text/x-patch
Size: 2237 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170103/89341513/attachment-0001.bin>


More information about the cfe-commits mailing list