summaryrefslogtreecommitdiffstats
path: root/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp')
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 6911d7600a71..f198dc71eb83 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -985,6 +985,38 @@ TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
std::make_unique<VerifyIdIsBoundTo<VarDecl>>("v", 4)));
}
+TEST_P(ASTMatchersTest,
+ ForEachArgumentWithParamMatchesExplicitObjectParamOnOperatorCalls) {
+ if (!GetParam().isCXX23OrLater()) {
+ return;
+ }
+
+ auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
+ auto SelfParam = parmVarDecl().bind("param");
+ StatementMatcher CallExpr =
+ callExpr(forEachArgumentWithParam(DeclRef, SelfParam));
+
+ StringRef S = R"cpp(
+ struct A {
+ int operator()(this const A &self);
+ };
+ A obj;
+ int global = obj();
+ )cpp";
+
+ auto Args = GetParam().getCommandLineArgs();
+ auto Filename = getFilenameForTesting(GetParam().Language);
+
+ EXPECT_TRUE(matchAndVerifyResultTrue(
+ S, CallExpr,
+ std::make_unique<VerifyIdIsBoundTo<ParmVarDecl>>("param", "self"), Args,
+ Filename));
+ EXPECT_TRUE(matchAndVerifyResultTrue(
+ S, CallExpr,
+ std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
+ Filename));
+}
+
TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) {
StatementMatcher ArgumentY =
declRefExpr(to(varDecl(hasName("y")))).bind("arg");
@@ -1168,6 +1200,37 @@ TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) {
S, CallExpr, std::make_unique<VerifyIdIsBoundTo<DeclRefExpr>>("arg")));
}
+TEST_P(ASTMatchersTest,
+ ForEachArgumentWithParamTypeMatchesExplicitObjectParamOnOperatorCalls) {
+ if (!GetParam().isCXX23OrLater()) {
+ return;
+ }
+
+ auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg");
+ auto SelfTy = qualType(asString("const A &")).bind("selfType");
+ StatementMatcher CallExpr =
+ callExpr(forEachArgumentWithParamType(DeclRef, SelfTy));
+
+ StringRef S = R"cpp(
+ struct A {
+ int operator()(this const A &self);
+ };
+ A obj;
+ int global = obj();
+ )cpp";
+
+ auto Args = GetParam().getCommandLineArgs();
+ auto Filename = getFilenameForTesting(GetParam().Language);
+
+ EXPECT_TRUE(matchAndVerifyResultTrue(
+ S, CallExpr, std::make_unique<VerifyIdIsBoundTo<QualType>>("selfType"),
+ Args, Filename));
+ EXPECT_TRUE(matchAndVerifyResultTrue(
+ S, CallExpr,
+ std::make_unique<VerifyIdIsBoundTo<VarDecl>>("declOfArg", "obj"), Args,
+ Filename));
+}
+
TEST(QualType, hasCanonicalType) {
EXPECT_TRUE(notMatches("typedef int &int_ref;"
"int a;"