ioeric updated this revision to Diff 149465. ioeric added a comment. - Clarify.
Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D47623 Files: clangd/index/SymbolCollector.cpp unittests/clangd/SymbolCollectorTests.cpp Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -812,6 +812,31 @@ QName("nx::Kind"), QName("nx::Kind_Fine"))); } +TEST_F(SymbolCollectorTest, DoNotIndexSymbolsInFriendDecl) { + Annotations Header(R"( + namespace nx { + class $z[[Z]] {}; + class X { + friend class Y; + friend class Z; + friend void foo(); + friend void $bar[[bar]]() {} + }; + class $y[[Y]] {}; + void $foo[[foo]](); + } + )"); + runSymbolCollector(Header.code(), /*Main=*/""); + + EXPECT_THAT(Symbols, + UnorderedElementsAre( + QName("nx"), QName("nx::X"), + AllOf(QName("nx::Y"), DeclRange(Header.range("y"))), + AllOf(QName("nx::Z"), DeclRange(Header.range("z"))), + AllOf(QName("nx::foo"), DeclRange(Header.range("foo"))), + AllOf(QName("nx::bar"), DeclRange(Header.range("bar"))))); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -290,6 +290,18 @@ index::IndexDataConsumer::ASTNodeInfo ASTNode) { assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set."); assert(CompletionAllocator && CompletionTUInfo); + assert(ASTNode.OrigD); + // If OrigD is an declaration associated with a friend declaration and it's + // not a definition, skip it. Note that OrigD is the occurrence that the + // collector is currently visiting. + if ((ASTNode.OrigD->getFriendObjectKind() != + Decl::FriendObjectKind::FOK_None) && + !(Roles & static_cast<unsigned>(index::SymbolRole::Definition))) + return true; + // A declaration created for a friend declaration should not be used as the + // canonical declaration in the index. + if (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) + D = ASTNode.OrigD; const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(D); if (!ND) return true;
Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -812,6 +812,31 @@ QName("nx::Kind"), QName("nx::Kind_Fine"))); } +TEST_F(SymbolCollectorTest, DoNotIndexSymbolsInFriendDecl) { + Annotations Header(R"( + namespace nx { + class $z[[Z]] {}; + class X { + friend class Y; + friend class Z; + friend void foo(); + friend void $bar[[bar]]() {} + }; + class $y[[Y]] {}; + void $foo[[foo]](); + } + )"); + runSymbolCollector(Header.code(), /*Main=*/""); + + EXPECT_THAT(Symbols, + UnorderedElementsAre( + QName("nx"), QName("nx::X"), + AllOf(QName("nx::Y"), DeclRange(Header.range("y"))), + AllOf(QName("nx::Z"), DeclRange(Header.range("z"))), + AllOf(QName("nx::foo"), DeclRange(Header.range("foo"))), + AllOf(QName("nx::bar"), DeclRange(Header.range("bar"))))); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -290,6 +290,18 @@ index::IndexDataConsumer::ASTNodeInfo ASTNode) { assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set."); assert(CompletionAllocator && CompletionTUInfo); + assert(ASTNode.OrigD); + // If OrigD is an declaration associated with a friend declaration and it's + // not a definition, skip it. Note that OrigD is the occurrence that the + // collector is currently visiting. + if ((ASTNode.OrigD->getFriendObjectKind() != + Decl::FriendObjectKind::FOK_None) && + !(Roles & static_cast<unsigned>(index::SymbolRole::Definition))) + return true; + // A declaration created for a friend declaration should not be used as the + // canonical declaration in the index. + if (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) + D = ASTNode.OrigD; const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(D); if (!ND) return true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits