[clang-tools-extra] r349033 - [clangd] Refine the way of checking a declaration is referenced by the written code.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 13 05:17:04 PST 2018
Author: hokein
Date: Thu Dec 13 05:17:04 2018
New Revision: 349033
URL: http://llvm.org/viewvc/llvm-project?rev=349033&view=rev
Log:
[clangd] Refine the way of checking a declaration is referenced by the written code.
Summary:
The previous solution (checking the AST) is not a reliable way to
determine whether a declaration is explicitly referenced by the source
code, we are still missing a few cases.
Reviewers: ilya-biryukov
Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D55191
Modified:
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=349033&r1=349032&r2=349033&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Thu Dec 13 05:17:04 2018
@@ -139,21 +139,19 @@ public:
SourceLocation Loc,
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
if (Loc == SearchedLocation) {
- // Check whether the E has an implicit AST node (e.g. ImplicitCastExpr).
- auto hasImplicitExpr = [](const Expr *E) {
- if (!E || E->child_begin() == E->child_end())
+ auto isImplicitExpr = [](const Expr *E) {
+ if (!E)
return false;
- // Use the first child is good enough for most cases -- normally the
- // expression returned by handleDeclOccurence contains exactly one
- // child expression.
- const auto *FirstChild = *E->child_begin();
- return isa<ExprWithCleanups>(FirstChild) ||
- isa<MaterializeTemporaryExpr>(FirstChild) ||
- isa<CXXBindTemporaryExpr>(FirstChild) ||
- isa<ImplicitCastExpr>(FirstChild);
+ // We assume that a constructor expression is implict (was inserted by
+ // clang) if it has an invalid paren/brace location, since such
+ // experssion is impossible to write down.
+ if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E))
+ return CtorExpr->getNumArgs() > 0 &&
+ CtorExpr->getParenOrBraceRange().isInvalid();
+ return isa<ImplicitCastExpr>(E);
};
- bool IsExplicit = !hasImplicitExpr(ASTNode.OrigE);
+ bool IsExplicit = !isImplicitExpr(ASTNode.OrigE);
// Find and add definition declarations (for GoToDefinition).
// We don't use parameter `D`, as Parameter `D` is the canonical
// declaration, which is the first declaration of a redeclarable
Modified: clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp?rev=349033&r1=349032&r2=349033&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp Thu Dec 13 05:17:04 2018
@@ -1225,6 +1225,53 @@ TEST(FindReferences, WithinAST) {
}
}
+TEST(FindReferences, ExplicitSymbols) {
+ const char *Tests[] = {
+ R"cpp(
+ struct Foo { Foo* [self]() const; };
+ void f() {
+ if (Foo* T = foo.[^self]()) {} // Foo member call expr.
+ }
+ )cpp",
+
+ R"cpp(
+ struct Foo { Foo(int); };
+ Foo f() {
+ int [b];
+ return [^b]; // Foo constructor expr.
+ }
+ )cpp",
+
+ R"cpp(
+ struct Foo {};
+ void g(Foo);
+ Foo [f]();
+ void call() {
+ g([^f]()); // Foo constructor expr.
+ }
+ )cpp",
+
+ R"cpp(
+ void [foo](int);
+ void [foo](double);
+
+ namespace ns {
+ using ::[fo^o];
+ }
+ )cpp",
+ };
+ for (const char *Test : Tests) {
+ Annotations T(Test);
+ auto AST = TestTU::withCode(T.code()).build();
+ std::vector<Matcher<Location>> ExpectedLocations;
+ for (const auto &R : T.ranges())
+ ExpectedLocations.push_back(RangeIs(R));
+ EXPECT_THAT(findReferences(AST, T.point()),
+ ElementsAreArray(ExpectedLocations))
+ << Test;
+ }
+}
+
TEST(FindReferences, NeedsIndex) {
const char *Header = "int foo();";
Annotations Main("int main() { [[f^oo]](); }");
More information about the cfe-commits
mailing list