usaxena95 created this revision.
usaxena95 added a reviewer: kadircet.
Herald added subscribers: cfe-commits, arphaman, jkorous, MaskRay,
ilya-biryukov.
Herald added a project: clang.
With this patch the `findReferences` API will return Xref for macros.
If the symbol under the cursor is a macro then we collect the references to it
from:
1. Main file by looking at the ParsedAST. (These were added to the ParsedAST in
https://reviews.llvm.org/D70008)
2. Files other than the mainfile by looking at the:
- static index (Added in https://reviews.llvm.org/D70489)
- file index (Added in https://reviews.llvm.org/D71406)
This patch collects all the xref from the above places and outputs it in
`findReferences` API.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D72395
Files:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -937,6 +937,13 @@
[[CAT]](Fo, o) foo4;
}
)cpp",
+
+ R"cpp(// Macros
+ #define [[MA^CRO]](X) (X+1)
+ void test() {
+ int x = [[MACRO]]([[MACRO]](1));
+ }
+ )cpp",
};
for (const char *Test : Tests) {
Annotations T(Test);
@@ -1012,8 +1019,16 @@
}
TEST(FindReferences, NeedsIndex) {
- const char *Header = "int foo();";
- Annotations Main("int main() { [[f^oo]](); }");
+ const char *Header = (R"cpp(
+ int foo();
+ #define MACRO(X) (X+1)
+ )cpp");
+ Annotations Main(R"cpp(
+ int main() {
+ $foo[[f$foo^oo]]();
+ int a = $macro[[MA$macro^CRO]](1);
+ }
+ )cpp");
TestTU TU;
TU.Code = Main.code();
TU.HeaderCode = Header;
@@ -1021,10 +1036,17 @@
// References in main file are returned without index.
EXPECT_THAT(
- findReferences(AST, Main.point(), 0, /*Index=*/nullptr).References,
- ElementsAre(RangeIs(Main.range())));
+ findReferences(AST, Main.point("foo"), 0, /*Index=*/nullptr).References,
+ ElementsAre(RangeIs(Main.range("foo"))));
+ EXPECT_THAT(
+ findReferences(AST, Main.point("macro"), 0, /*Index=*/nullptr).References,
+ ElementsAre(RangeIs(Main.range("macro"))));
+
Annotations IndexedMain(R"cpp(
- int main() { [[f^oo]](); }
+ int indexed_main() {
+ $foo[[foo]]();
+ int a = $macro[[MACRO]](1);
+ }
)cpp");
// References from indexed files are included.
@@ -1033,18 +1055,21 @@
IndexedTU.Filename = "Indexed.cpp";
IndexedTU.HeaderCode = Header;
EXPECT_THAT(
- findReferences(AST, Main.point(), 0, IndexedTU.index().get()).References,
- ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
+ findReferences(AST, Main.point("foo"), 0, IndexedTU.index().get()).References,
+ ElementsAre(RangeIs(Main.range("foo")), RangeIs(IndexedMain.range("foo"))));
+ EXPECT_THAT(
+ findReferences(AST, Main.point("macro"), 0, IndexedTU.index().get()).References,
+ ElementsAre(RangeIs(Main.range("macro")), RangeIs(IndexedMain.range("macro"))));
auto LimitRefs =
- findReferences(AST, Main.point(), /*Limit*/ 1, IndexedTU.index().get());
+ findReferences(AST, Main.point("foo"), /*Limit*/ 1, IndexedTU.index().get());
EXPECT_EQ(1u, LimitRefs.References.size());
EXPECT_TRUE(LimitRefs.HasMore);
// If the main file is in the index, we don't return duplicates.
// (even if the references are in a different location)
TU.Code = ("\n\n" + Main.code()).str();
- EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()).References,
- ElementsAre(RangeIs(Main.range())));
+ EXPECT_THAT(findReferences(AST, Main.point("foo"), 0, TU.index().get()).References,
+ ElementsAre(RangeIs(Main.range("foo"))));
}
TEST(FindReferences, NoQueryForLocalSymbols) {
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -432,9 +432,48 @@
elog("Failed to get a path for the main file, so no references");
return Results;
}
+ auto URIMainFile = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
auto Loc = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
- // TODO: should we handle macros, too?
+ auto AddRefFromIndex = [&](const Ref &R) {
+ // No need to continue process if we reach the limit.
+ if (Results.References.size() > Limit)
+ return;
+ auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
+ // Avoid indexed results for the main file - the AST is authoritative.
+ if (!LSPLoc || LSPLoc->uri.file() == *MainFilePath)
+ return;
+
+ Results.References.push_back(std::move(*LSPLoc));
+ };
+ // Handle references to macro.
+ if (auto Macro = locateMacroAt(Loc, AST.getPreprocessor())) {
+ if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) {
+ // Collect macro references from main file.
+ const auto &IDToRefs = AST.getMacros().MacroRefs;
+ auto Refs = IDToRefs.find(*MacroSID);
+ if (Refs != IDToRefs.end()) {
+ for (const auto Ref : Refs->second) {
+ Location Loc;
+ Loc.uri = URIMainFile;
+ Loc.range = Ref;
+ Results.References.push_back(Loc);
+ }
+ }
+ // Query the index for references from other files.
+ if (Index && Results.References.size() < Limit) {
+ RefsRequest Req;
+ Req.Limit = Limit;
+ Req.IDs.insert(*MacroSID);
+ Results.HasMore |= Index->refs(Req, AddRefFromIndex);
+ }
+ }
+ if (Results.References.size() > Limit) {
+ Results.HasMore = true;
+ Results.References.resize(Limit);
+ }
+ return Results;
+ }
// We also show references to the targets of using-decls, so we include
// DeclRelation::Underlying.
DeclRelationSet Relations = DeclRelation::TemplatePattern |
@@ -456,7 +495,7 @@
if (auto Range = getTokenRange(SM, AST.getLangOpts(), Ref.Loc)) {
Location Result;
Result.range = *Range;
- Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
+ Result.uri = URIMainFile;
Results.References.push_back(std::move(Result));
}
}
@@ -476,17 +515,7 @@
}
if (Req.IDs.empty())
return Results;
- Results.HasMore |= Index->refs(Req, [&](const Ref &R) {
- // no need to continue process if we reach the limit.
- if (Results.References.size() > Limit)
- return;
- auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
- // Avoid indexed results for the main file - the AST is authoritative.
- if (!LSPLoc || LSPLoc->uri.file() == *MainFilePath)
- return;
-
- Results.References.push_back(std::move(*LSPLoc));
- });
+ Results.HasMore |= Index->refs(Req, AddRefFromIndex);
}
if (Results.References.size() > Limit) {
Results.HasMore = true;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits