diff --git a/clang-tools-extra/clangd/index/FileIndex.h b/clang-tools-extra/clangd/index/FileIndex.h --- a/clang-tools-extra/clangd/index/FileIndex.h +++ b/clang-tools-extra/clangd/index/FileIndex.h @@ -140,7 +140,7 @@ /// Exposed to assist in unit tests. SlabTuple indexMainDecls(ParsedAST &AST); -/// Idex declarations from \p AST and macros from \p PP that are declared in +/// Index declarations from \p AST and macros from \p PP that are declared in /// included headers. SlabTuple indexHeaderSymbols(ASTContext &AST, std::shared_ptr PP, const CanonicalIncludes &Includes); diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp --- a/clang-tools-extra/clangd/index/FileIndex.cpp +++ b/clang-tools-extra/clangd/index/FileIndex.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "FileIndex.h" +#include "CollectMacros.h" #include "Logger.h" #include "ParsedAST.h" #include "SymbolCollector.h" @@ -32,6 +33,7 @@ static SlabTuple indexSymbols(ASTContext &AST, std::shared_ptr PP, llvm::ArrayRef DeclsToIndex, + const MainFileMacros *MacroRefsToIndex, const CanonicalIncludes &Includes, bool IsIndexMainAST) { SymbolCollector::Options CollectorOpts; @@ -59,6 +61,8 @@ SymbolCollector Collector(std::move(CollectorOpts)); Collector.setPreprocessor(PP); + if (MacroRefsToIndex) + Collector.handleMacroOccurence(*MacroRefsToIndex); index::indexTopLevelDecls(AST, *PP, DeclsToIndex, Collector, IndexOpts); const auto &SM = AST.getSourceManager(); @@ -68,6 +72,7 @@ auto Syms = Collector.takeSymbols(); auto Refs = Collector.takeRefs(); auto Relations = Collector.takeRelations(); + vlog("index AST for {0} (main={1}): \n" " symbol slab: {2} symbols, {3} bytes\n" " ref slab: {4} symbols, {5} refs, {6} bytes\n" @@ -80,7 +85,8 @@ SlabTuple indexMainDecls(ParsedAST &AST) { return indexSymbols(AST.getASTContext(), AST.getPreprocessorPtr(), - AST.getLocalTopLevelDecls(), AST.getCanonicalIncludes(), + AST.getLocalTopLevelDecls(), &AST.getMacros(), + AST.getCanonicalIncludes(), /*IsIndexMainAST=*/true); } @@ -89,7 +95,8 @@ std::vector DeclsToIndex( AST.getTranslationUnitDecl()->decls().begin(), AST.getTranslationUnitDecl()->decls().end()); - return indexSymbols(AST, std::move(PP), DeclsToIndex, Includes, + return indexSymbols(AST, std::move(PP), DeclsToIndex, + /*MainFileMacros=*/nullptr, Includes, /*IsIndexMainAST=*/false); } diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h --- a/clang-tools-extra/clangd/index/SymbolCollector.h +++ b/clang-tools-extra/clangd/index/SymbolCollector.h @@ -9,6 +9,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_COLLECTOR_H #include "CanonicalIncludes.h" +#include "CollectMacros.h" #include "Index.h" #include "SymbolOrigin.h" #include "clang/AST/ASTContext.h" @@ -104,6 +105,8 @@ SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override; + void handleMacroOccurence(const MainFileMacros &MacroRefsToIndex); + bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *MI, index::SymbolRoleSet Roles, SourceLocation Loc) override; diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -342,6 +342,31 @@ return true; } +void SymbolCollector::handleMacroOccurence( + const MainFileMacros &MacroRefsToIndex) { + assert(PP.get()); + const auto &SM = PP->getSourceManager(); + const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID()); + if (!MainFileEntry) + return; + + const auto MainFileURI = toURI(SM, MainFileEntry->getName(), Opts); + // Add macro references. + for (const auto &IDToRefs : MacroRefsToIndex.MacroRefs) { + for (const auto &Range : IDToRefs.second) { + Ref R; + R.Location.Start.setLine(Range.start.line); + R.Location.Start.setColumn(Range.start.character); + R.Location.End.setLine(Range.end.line); + R.Location.End.setColumn(Range.end.character); + R.Location.FileURI = MainFileURI.c_str(); + // FIXME: Add correct RefKind information to MainFileMacros. + R.Kind = RefKind::Reference; + Refs.insert(IDToRefs.first, R); + } + } +} + bool SymbolCollector::handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *MI, index::SymbolRoleSet Roles, diff --git a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp --- a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp @@ -345,6 +345,41 @@ FileURI("unittest:///test2.cc"))})); } +TEST(FileIndexTest, MacroRefs) { + Annotations HeaderCode(R"cpp( + #define $macro[[MACRO]](X) (X+1) + )cpp"); + Annotations MainCode(R"cpp( + void f() { + int a = $macro[[MACRO]](1); + } + )cpp"); + + auto Macro = findSymbol( + TestTU::withHeaderCode(HeaderCode.code()).headerSymbols(), "MACRO"); + FileIndex Index; + // Add test.cc + TestTU Test; + Test.HeaderCode = HeaderCode.code(); + Test.Code = MainCode.code(); + Test.Filename = "test.cc"; + auto AST = Test.build(); + Index.updateMain(Test.Filename, AST); + // Add test2.cc + TestTU Test2; + Test2.HeaderCode = HeaderCode.code(); + Test2.Code = MainCode.code(); + Test2.Filename = "test2.cc"; + AST = Test2.build(); + Index.updateMain(Test2.Filename, AST); + + EXPECT_THAT(getRefs(Index, Macro.ID), + RefsAre({AllOf(RefRange(MainCode.range("macro")), + FileURI("unittest:///test.cc")), + AllOf(RefRange(MainCode.range("macro")), + FileURI("unittest:///test2.cc"))})); +} + TEST(FileIndexTest, CollectMacros) { FileIndex M; update(M, "f", "#define CLANGD 1");