Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -90,6 +90,28 @@ return llvm::None; } +bool isPrivateProtoSymbol(const NamedDecl *ND, const SourceManager &SM) { + auto FileName = SM.getFilename(findNameLoc(ND)); + if (FileName.endswith(".proto.h") || FileName.endswith(".pb.h")) { + auto Name = ND->getName(); + // Nested proto entities (e.g. Message::Nested) have top-level decls + // that shouldn't be used (Message_Nested). Ignore them completely. + // The nested entities are dangling type aliases, we may want to reconsider + // including them in the future + if (Name.contains('_')) { + if (ND->getKind() == Decl::EnumConstant) { + // SOME_ENUM_CONSTANT is not private and should be indexed. + // Outer_INNER is private. + // This heuristic relies on naming style, it will include OUTER_INNER + // and exclude some_enum_constant. + return std::any_of(Name.begin(), Name.end(), islower); + } + return true; + } + } + return false; +} + bool shouldFilterDecl(const NamedDecl *ND, ASTContext *ASTCtx, const SymbolCollector::Options &Opts) { using namespace clang::ast_matchers; @@ -130,6 +152,9 @@ .empty()) return true; + if (isPrivateProtoSymbol(ND, ASTCtx->getSourceManager())) + return true; + return false; } Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -697,6 +697,23 @@ AllOf(QName("pörk"), DeclRange(Header.range())))); } +TEST_F(SymbolCollectorTest, FilterPrivateProtoSymbols) { + TestHeaderName = testPath("x.proto.h"); + const std::string Header = R"( + namespace nx { + class Top_Level {}; + class TopLevel {}; + enum Kind { + KIND_OK, + Kind_Not_Ok, + }; + } + )"; + runSymbolCollector(Header, /*Main=*/""); + EXPECT_THAT(Symbols, UnorderedElementsAre(QName("nx"), QName("nx::TopLevel"), + QName("nx::Kind"), + QName("nx::KIND_OK"))); +} } // namespace } // namespace clangd