PiotrZSL updated this revision to Diff 534363. PiotrZSL added a comment. Rebase + Added change to Registry.cpp
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153716/new/ https://reviews.llvm.org/D153716 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1640,6 +1640,95 @@ cxxConversionDecl(isExplicit()))); } +TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr) { + StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2)); + + EXPECT_TRUE(notMatches("void x(void) { x(); }", Call2PlusArgs)); + EXPECT_TRUE(notMatches("void x(int) { x(0); }", Call2PlusArgs)); + EXPECT_TRUE(matches("void x(int, int) { x(0, 0); }", Call2PlusArgs)); + EXPECT_TRUE(matches("void x(int, int, int) { x(0, 0, 0); }", Call2PlusArgs)); + + if (!GetParam().isCXX()) { + return; + } + + EXPECT_TRUE( + notMatches("void x(int = 1) { x(); }", traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int = 1) { x(0); }", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int = 1, int = 1) { x(0); }", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }", + traverse(TK_AsIs, Call2PlusArgs))); + + EXPECT_TRUE( + notMatches("void x(int = 1) { x(); }", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE( + notMatches("void x(int, int = 1) { x(0); }", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE( + notMatches("void x(int, int = 1, int = 1) { x(0); }", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int, int = 1) { x(0, 0); }", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE(matches("void x(int, int, int, int = 1) { x(0, 0, 0); }", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); +} + +TEST_P(ASTMatchersTest, ArgumentCountAtLeast_CallExpr_CXX) { + if (!GetParam().isCXX()) { + return; + } + + StatementMatcher Call2PlusArgs = callExpr(argumentCountAtLeast(2)); + EXPECT_TRUE(notMatches("class X { void x() { x(); } };", Call2PlusArgs)); + EXPECT_TRUE(notMatches("class X { void x(int) { x(0); } };", Call2PlusArgs)); + EXPECT_TRUE( + matches("class X { void x(int, int) { x(0, 0); } };", Call2PlusArgs)); + EXPECT_TRUE(matches("class X { void x(int, int, int) { x(0, 0, 0); } };", + Call2PlusArgs)); + + EXPECT_TRUE(notMatches("class X { void x(int = 1) { x(0); } };", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("class X { void x(int, int = 1) { x(0); } };", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("class X { void x(int, int = 1, int = 1) { x(0); } };", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };", + traverse(TK_AsIs, Call2PlusArgs))); + EXPECT_TRUE( + matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };", + traverse(TK_AsIs, Call2PlusArgs))); + + EXPECT_TRUE( + notMatches("class X { void x(int = 1) { x(0); } };", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE( + notMatches("class X { void x(int, int = 1) { x(0); } };", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE( + notMatches("class X { void x(int, int = 1, int = 1) { x(0); } };", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE(matches("class X { void x(int, int, int = 1) { x(0, 0); } };", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + EXPECT_TRUE( + matches("class X { void x(int, int, int, int = 1) { x(0, 0, 0); } };", + traverse(TK_IgnoreUnlessSpelledInSource, Call2PlusArgs))); + + EXPECT_TRUE( + notMatches("class X { static void x() { x(); } };", Call2PlusArgs)); + EXPECT_TRUE( + notMatches("class X { static void x(int) { x(0); } };", Call2PlusArgs)); + EXPECT_TRUE(matches("class X { static void x(int, int) { x(0, 0); } };", + Call2PlusArgs)); + EXPECT_TRUE( + matches("class X { static void x(int, int, int) { x(0, 0, 0); } };", + Call2PlusArgs)); +} + TEST_P(ASTMatchersTest, ArgumentCountIs_CallExpr) { StatementMatcher Call1Arg = callExpr(argumentCountIs(1)); Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -135,6 +135,7 @@ REGISTER_MATCHER(anyOf); REGISTER_MATCHER(anything); REGISTER_MATCHER(argumentCountIs); + REGISTER_MATCHER(argumentCountAtLeast); REGISTER_MATCHER(arraySubscriptExpr); REGISTER_MATCHER(arrayType); REGISTER_MATCHER(asString); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4431,6 +4431,33 @@ return NumArgs == N; } +/// Checks that a call expression or a constructor call expression has at least +/// the specified number of arguments (including absent default arguments). +/// +/// Example matches f(0, 0) and g(0, 0, 0) +/// (matcher = callExpr(argumentCountAtLeast(2))) +/// \code +/// void f(int x, int y); +/// void g(int x, int y, int z); +/// f(0, 0); +/// g(0, 0, 0); +/// \endcode +AST_POLYMORPHIC_MATCHER_P(argumentCountAtLeast, + AST_POLYMORPHIC_SUPPORTED_TYPES( + CallExpr, CXXConstructExpr, + CXXUnresolvedConstructExpr, ObjCMessageExpr), + unsigned, N) { + unsigned NumArgs = Node.getNumArgs(); + if (!Finder->isTraversalIgnoringImplicitNodes()) + return NumArgs >= N; + while (NumArgs) { + if (!isa<CXXDefaultArgExpr>(Node.getArg(NumArgs - 1))) + break; + --NumArgs; + } + return NumArgs >= N; +} + /// Matches the n'th argument of a call expression or a constructor /// call expression. /// Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -3036,6 +3036,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('argumentCountAtLeast1')"><a name="argumentCountAtLeast1Anchor">argumentCountAtLeast</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountAtLeast1"><pre>Checks that a call expression or a constructor call expression has +at least the specified number of arguments (including absent default arguments). + +Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2))) + void f(int x, int y); + void g(int x, int y, int z); + f(0, 0); + g(0, 0, 0); +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('argumentCountIs1')"><a name="argumentCountIs1Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="argumentCountIs1"><pre>Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). @@ -3693,6 +3705,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>></td><td class="name" onclick="toggle('argumentCountAtLeast2')"><a name="argumentCountAtLeast2Anchor">argumentCountAtLeast</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountAtLeast2"><pre>Checks that a call expression or a constructor call expression has +at least the specified number of arguments (including absent default arguments). + +Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2))) + void f(int x, int y); + void g(int x, int y, int z); + f(0, 0); + g(0, 0, 0); +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>></td><td class="name" onclick="toggle('argumentCountIs2')"><a name="argumentCountIs2Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="argumentCountIs2"><pre>Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). @@ -3703,6 +3727,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('argumentCountAtLeast0')"><a name="argumentCountAtLeast0Anchor">argumentCountAtLeast</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountAtLeast0"><pre>Checks that a call expression or a constructor call expression has +at least the specified number of arguments (including absent default arguments). + +Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2))) + void f(int x, int y); + void g(int x, int y, int z); + f(0, 0); + g(0, 0, 0); +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('argumentCountIs0')"><a name="argumentCountIs0Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="argumentCountIs0"><pre>Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). @@ -4860,6 +4896,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('argumentCountAtLeast3')"><a name="argumentCountAtLeast3Anchor">argumentCountAtLeast</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountAtLeast3"><pre>Checks that a call expression or a constructor call expression has +at least the specified number of arguments (including absent default arguments). + +Example matches f(0, 0) and g(0, 0, 0) (matcher = callExpr(argumentCountAtLeast(2))) + void f(int x, int y); + void g(int x, int y, int z); + f(0, 0); + g(0, 0, 0); +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('argumentCountIs3')"><a name="argumentCountIs3Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="argumentCountIs3"><pre>Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments).
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits