Index: clang-tools-extra/clangd/index/SymbolCollector.cpp =================================================================== --- clang-tools-extra/clangd/index/SymbolCollector.cpp +++ clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -373,13 +373,21 @@ const auto &SM = PP->getSourceManager(); auto DefLoc = MI->getDefinitionLoc(); - if (SM.isInMainFile(SM.getExpansionLoc(DefLoc))) - return true; + // Header guards are not interesting in index. Builtin macros don't have // useful locations and are not needed for code completions. if (MI->isUsedForHeaderGuard() || MI->isBuiltinMacro()) return true; + // Skip main-file symbols if we are not collecting them. + bool IsMainFileSymbol = SM.isInMainFile(SM.getExpansionLoc(DefLoc)); + if (IsMainFileSymbol && !Opts.CollectMainFileSymbols) + return false; + + // Also avoid storing predefined macros like __DBL_MIN__. + if (SM.isWrittenInBuiltinFile(DefLoc)) + return true; + // Mark the macro as referenced if this is a reference coming from the main // file. The macro may not be an interesting symbol, but it's cheaper to check // at the end. @@ -404,7 +412,10 @@ Symbol S; S.ID = std::move(*ID); S.Name = Name->getName(); - S.Flags |= Symbol::IndexedForCodeCompletion; + if (!IsMainFileSymbol) { + S.Flags |= Symbol::IndexedForCodeCompletion; + S.Flags |= Symbol::VisibleOutsideFile; + } S.SymInfo = index::getSymbolInfoForMacro(*MI); std::string FileURI; // FIXME: use the result to filter out symbols. Index: clang-tools-extra/unittests/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/unittests/clangd/CMakeLists.txt +++ clang-tools-extra/unittests/clangd/CMakeLists.txt @@ -59,6 +59,7 @@ clangLex clangSema clangSerialization + clangTidy clangTooling clangToolingCore clangToolingInclusions Index: clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp =================================================================== --- clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp +++ clang-tools-extra/unittests/clangd/FindSymbolsTests.cpp @@ -87,13 +87,16 @@ } // namespace -TEST_F(WorkspaceSymbolsTest, NoMacro) { +TEST_F(WorkspaceSymbolsTest, Macros) { addFile("foo.cpp", R"cpp( #define MACRO X )cpp"); - // Macros are not in the index. - EXPECT_THAT(getSymbols("macro"), IsEmpty()); + // LSP's SymbolKind doesn't have a "Macro" kind, and + // indexSymbolKindToSymbolKind() currently maps macros + // to SymbolKind::String. + EXPECT_THAT(getSymbols("macro"), + ElementsAre(AllOf(QName("MACRO"), WithKind(SymbolKind::String)))); } TEST_F(WorkspaceSymbolsTest, NoLocals) { Index: clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp +++ clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp @@ -1052,21 +1052,26 @@ MAC(p); )"); - const std::string Main = R"( - #define MAIN 1 // not indexed + Annotations Main(R"( + #define $main[[MAIN]] 1 USED(t); - )"; + )"); CollectorOpts.CountReferences = true; CollectorOpts.CollectMacro = true; - runSymbolCollector(Header.code(), Main); + runSymbolCollector(Header.code(), Main.code()); EXPECT_THAT(Symbols, UnorderedElementsAre(QName("p"), QName("t"), AllOf(QName("X"), DeclURI(TestHeaderURI), IncludeHeader(TestHeaderURI)), AllOf(Labeled("MAC(x)"), RefCount(0), - DeclRange(Header.range("mac"))), + DeclRange(Header.range("mac")), + VisibleOutsideFile()), AllOf(Labeled("USED(y)"), RefCount(1), - DeclRange(Header.range("used"))))); + DeclRange(Header.range("used")), + VisibleOutsideFile()), + AllOf(Labeled("MAIN"), RefCount(0), + DeclRange(Main.range("main")), + Not(VisibleOutsideFile())))); } TEST_F(SymbolCollectorTest, DeprecatedSymbols) {