diff options
Diffstat (limited to 'clang/unittests/ASTMatchers/ASTMatchersTest.cpp')
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index cd18df8410b..46392dcd63a 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1608,6 +1608,91 @@ TEST(Matcher, AnyArgument) { EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY)); } +TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) { + StatementMatcher ArgumentY = + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + + // IntParam does not match. + EXPECT_FALSE(matches("void f(int* i) { int* y; f(y); }", CallExpr)); + // ArgumentY does not match. + EXPECT_FALSE(matches("void f(int i) { int x; f(x); }", CallExpr)); +} + +TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) { + StatementMatcher ArgumentY = + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + EXPECT_TRUE(matchAndVerifyResultTrue( + "struct S {" + " const S& operator[](int i) { return *this; }" + "};" + "void f(S S1) {" + " int y = 1;" + " S1[y];" + "}", + CallExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1))); +} + +TEST(ForEachArgumentWithParam, MatchesCallExpr) { + StatementMatcher ArgumentY = + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + + EXPECT_TRUE( + matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, + new VerifyIdIsBoundTo<ParmVarDecl>("param"))); + EXPECT_TRUE( + matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr, + new VerifyIdIsBoundTo<DeclRefExpr>("arg"))); + + EXPECT_TRUE(matchAndVerifyResultTrue( + "void f(int i, int j) { int y; f(y, y); }", CallExpr, + new VerifyIdIsBoundTo<ParmVarDecl>("param", 2))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "void f(int i, int j) { int y; f(y, y); }", CallExpr, + new VerifyIdIsBoundTo<DeclRefExpr>("arg", 2))); +} + +TEST(ForEachArgumentWithParam, MatchesConstructExpr) { + StatementMatcher ArgumentY = + declRefExpr(to(varDecl(hasName("y")))).bind("arg"); + DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param"); + StatementMatcher ConstructExpr = + cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)); + + EXPECT_TRUE(matchAndVerifyResultTrue( + "struct C {" + " C(int i) {}" + "};" + "int y = 0;" + "C Obj(y);", + ConstructExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param"))); +} + +TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) { + EXPECT_TRUE(matchAndVerifyResultTrue( + "void g(int i, int j) {" + " int a;" + " int b;" + " int c;" + " g(a, 0);" + " g(a, b);" + " g(0, b);" + "}", + functionDecl( + forEachDescendant(varDecl().bind("v")), + forEachDescendant(callExpr(forEachArgumentWithParam( + declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))), + new VerifyIdIsBoundTo<VarDecl>("v", 4))); +} + TEST(Matcher, ArgumentCount) { StatementMatcher Call1Arg = callExpr(argumentCountIs(1)); |