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 @@ -373,16 +373,12 @@ index::SymbolRoleSet Roles, SourceLocation Loc) { assert(PP.get()); - - const auto &SM = PP->getSourceManager(); - auto DefLoc = MI->getDefinitionLoc(); - auto SpellingLoc = SM.getSpellingLoc(Loc); - bool IsMainFileSymbol = SM.isInMainFile(SM.getExpansionLoc(DefLoc)); - // Builtin macros don't have useful locations and aren't needed in completion. if (MI->isBuiltinMacro()) return true; + const auto &SM = PP->getSourceManager(); + auto DefLoc = MI->getDefinitionLoc(); // Also avoid storing predefined macros like __DBL_MIN__. if (SM.isWrittenInBuiltinFile(DefLoc)) return true; @@ -391,8 +387,13 @@ if (!ID) return true; + auto SpellingLoc = SM.getSpellingLoc(Loc); + bool IsMainFileOnly = + SM.isInMainFile(SM.getExpansionLoc(DefLoc)) && + !isHeaderFile(SM.getFileEntryForID(SM.getMainFileID())->getName(), + ASTCtx->getLangOpts()); // Do not store references to main-file macros. - if ((static_cast(Opts.RefFilter) & Roles) && !IsMainFileSymbol && + if ((static_cast(Opts.RefFilter) & Roles) && !IsMainFileOnly && (Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID())) MacroRefs[*ID].push_back({Loc, Roles}); @@ -401,7 +402,7 @@ return true; // Skip main-file macros if we are not collecting them. - if (IsMainFileSymbol && !Opts.CollectMainFileSymbols) + if (IsMainFileOnly && !Opts.CollectMainFileSymbols) return false; // Mark the macro as referenced if this is a reference coming from the main @@ -425,11 +426,12 @@ Symbol S; S.ID = std::move(*ID); S.Name = Name->getName(); - if (!IsMainFileSymbol) { + if (!IsMainFileOnly) { S.Flags |= Symbol::IndexedForCodeCompletion; S.Flags |= Symbol::VisibleOutsideFile; } S.SymInfo = index::getSymbolInfoForMacro(*MI); + S.Origin = Opts.Origin; std::string FileURI; // FIXME: use the result to filter out symbols. shouldIndexFile(SM.getFileID(Loc)); diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -1402,6 +1402,9 @@ runSymbolCollector("class Foo {};", /*Main=*/""); EXPECT_THAT(Symbols, UnorderedElementsAre( Field(&Symbol::Origin, SymbolOrigin::Static))); + runSymbolCollector("#define FOO", /*Main=*/""); + EXPECT_THAT(Symbols, UnorderedElementsAre( + Field(&Symbol::Origin, SymbolOrigin::Static))); } TEST_F(SymbolCollectorTest, CollectMacros) { @@ -1504,6 +1507,13 @@ EXPECT_THAT(Refs, Contains(Pair(findSymbol(Symbols, "PUNCT").ID, _))); } +TEST_F(SymbolCollectorTest, MacrosInHeaders) { + CollectorOpts.CollectMacro = true; + TestFileName = testPath("test.h"); + runSymbolCollector("", "#define X"); + EXPECT_THAT(Symbols, + UnorderedElementsAre(AllOf(QName("X"), ForCodeCompletion(true)))); +} } // namespace } // namespace clangd } // namespace clang