From 5cdc2cda28ac86ba4ec3771341545355452fdc86 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 12 Dec 2018 21:50:55 +0000 Subject: [AST] Store "UsesADL" information in CallExpr. Summary: Currently the Clang AST doesn't store information about how the callee of a CallExpr was found. Specifically if it was found using ADL. However, this information is invaluable to tooling. Consider a tool which renames usages of a function. If the originally CallExpr was formed using ADL, then the tooling may need to additionally qualify the replacement. Without information about how the callee was found, the tooling is left scratching it's head. Additionally, we want to be able to match ADL calls as quickly as possible, which means avoiding computing the answer on the fly. This patch changes `CallExpr` to store whether it's callee was found using ADL. It does not change the size of any AST nodes. Reviewers: fowles, rsmith, klimek, shafik Reviewed By: rsmith Subscribers: aaron.ballman, riccibruno, calabrese, titus, cfe-commits Differential Revision: https://reviews.llvm.org/D55534 llvm-svn: 348977 --- .../unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp') diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index 9278987cb0b..1bd4e09e776 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -199,6 +199,40 @@ TEST(Matcher, UnresolvedLookupExpr) { "-fno-delayed-template-parsing")); } +TEST(Matcher, ADLCall) { + StatementMatcher ADLMatch = callExpr(usesADL()); + StatementMatcher ADLMatchOper = cxxOperatorCallExpr(usesADL()); + auto NS_Str = R"cpp( + namespace NS { + struct X {}; + void f(X); + void operator+(X, X); + } + struct MyX {}; + void f(...); + void operator+(MyX, MyX); +)cpp"; + + auto MkStr = [&](std::string Body) -> std::string { + std::string S = NS_Str; + S += "void test_fn() { " + Body + " }"; + return S; + }; + + EXPECT_TRUE(matches(MkStr("NS::X x; f(x);"), ADLMatch)); + EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::f(x);"), ADLMatch)); + EXPECT_TRUE(notMatches(MkStr("MyX x; f(x);"), ADLMatch)); + EXPECT_TRUE(notMatches(MkStr("NS::X x; using NS::f; f(x);"), ADLMatch)); + + // Operator call expressions + EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatch)); + EXPECT_TRUE(matches(MkStr("NS::X x; x + x;"), ADLMatchOper)); + EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatch)); + EXPECT_TRUE(notMatches(MkStr("MyX x; x + x;"), ADLMatchOper)); + EXPECT_TRUE(matches(MkStr("NS::X x; operator+(x, x);"), ADLMatch)); + EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::operator+(x, x);"), ADLMatch)); +} + TEST(Matcher, Call) { // FIXME: Do we want to overload Call() to directly take // Matcher, too? -- cgit v1.2.3