Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -71,6 +71,10 @@ using namespace clang::ast_matchers; if (ND->isImplicit()) return true; + // Skip nameless declarations. + if (ND->getDeclName().isEmpty()) + return true; + // FIXME: figure out a way to handle internal linkage symbols (e.g. static // variables, function) defined in the .cc files. Also we skip the symbols // in anonymous namespace as the qualifier names of these symbols are like @@ -82,12 +86,18 @@ if (ND->isInAnonymousNamespace()) return true; - // We only want symbols in namespaces or translation unit scopes (e.g. no - // class members). - if (match(decl(allOf( - Opts.IndexMainFiles ? decl() - : decl(unless(isExpansionInMainFile())), - hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())))), + // We only want: + // * symbols in namespaces or translation unit scopes (e.g. no class + // members) + // * enum constants in unscoped enum decl (e.g. "red" in "enum {red};") + auto InTopLevelScope = + hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())); + if (match(decl(allOf(Opts.IndexMainFiles + ? decl() + : decl(unless(isExpansionInMainFile())), + anyOf(InTopLevelScope, + hasDeclContext(enumDecl(InTopLevelScope, + unless(isScoped())))))), *ND, *ASTCtx) .empty()) return true; Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -161,6 +161,43 @@ QName("foo::baz")})); } +TEST_F(SymbolCollectorTest, IncludeEnums) { + CollectorOpts.IndexMainFiles = false; + const std::string Header = R"( + enum { + Red + }; + enum Color { + Green + }; + enum class Color2 { + Yellow // ignore + }; + namespace ns { + enum { + Black + }; + } + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Red"), QName("Color"), + QName("Green"), QName("Color2"), + QName("ns"), + QName("ns::Black"))); +} + +TEST_F(SymbolCollectorTest, IgnoreNamelessSymbols) { + CollectorOpts.IndexMainFiles = false; + const std::string Header = R"( + struct { + int a; + } Foo; + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, + UnorderedElementsAre(QName("Foo"))); +} + TEST_F(SymbolCollectorTest, IgnoreSymbolsInMainFile) { CollectorOpts.IndexMainFiles = false; const std::string Header = R"(