From e61d0257ede2bf597440f516ecd9ff1146bf7b06 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 17 Jul 2019 15:26:49 +0000 Subject: [PATCH] [clangd] Type hierarchy: don't resolve parents if the client only asked for children Summary: Also reorganize the code for computing supertypes to make it more symmetric to subtypes. Reviewers: kadircet Reviewed By: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64613 llvm-svn: 366338 --- clang-tools-extra/clangd/XRefs.cpp | 33 +++++++++++----------- .../clangd/unittests/TypeHierarchyTests.cpp | 3 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 59f07ee..6339f86 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -1132,15 +1132,9 @@ static void fillSubTypes(const SymbolID &ID, using RecursionProtectionSet = llvm::SmallSet; -static Optional -getTypeAncestors(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx, - RecursionProtectionSet &RPSet) { - Optional Result = declToTypeHierarchyItem(ASTCtx, CXXRD); - if (!Result) - return Result; - - Result->parents.emplace(); - +static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx, + std::vector &SuperTypes, + RecursionProtectionSet &RPSet) { // typeParents() will replace dependent template specializations // with their class template, so to avoid infinite recursion for // certain types of hierarchies, keep the templates encountered @@ -1149,22 +1143,22 @@ getTypeAncestors(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx, auto *Pattern = CXXRD.getDescribedTemplate() ? &CXXRD : nullptr; if (Pattern) { if (!RPSet.insert(Pattern).second) { - return Result; + return; } } for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) { if (Optional ParentSym = - getTypeAncestors(*ParentDecl, ASTCtx, RPSet)) { - Result->parents->emplace_back(std::move(*ParentSym)); + declToTypeHierarchyItem(ASTCtx, *ParentDecl)) { + ParentSym->parents.emplace(); + fillSuperTypes(*ParentDecl, ASTCtx, *ParentSym->parents, RPSet); + SuperTypes.emplace_back(std::move(*ParentSym)); } } if (Pattern) { RPSet.erase(Pattern); } - - return Result; } const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) { @@ -1231,12 +1225,19 @@ getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels, if (!CXXRD) return llvm::None; - RecursionProtectionSet RPSet; Optional Result = - getTypeAncestors(*CXXRD, AST.getASTContext(), RPSet); + declToTypeHierarchyItem(AST.getASTContext(), *CXXRD); if (!Result) return Result; + if (Direction == TypeHierarchyDirection::Parents || + Direction == TypeHierarchyDirection::Both) { + Result->parents.emplace(); + + RecursionProtectionSet RPSet; + fillSuperTypes(*CXXRD, AST.getASTContext(), *Result->parents, RPSet); + } + if ((Direction == TypeHierarchyDirection::Children || Direction == TypeHierarchyDirection::Both) && ResolveLevels > 0) { diff --git a/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp b/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp index 633a25f..cebfa8d 100644 --- a/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp +++ b/clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp @@ -630,7 +630,8 @@ struct Child2b : Child1 {}; ASSERT_TRUE(bool(Result)); EXPECT_THAT( *Result, - AllOf(WithName("Parent"), WithKind(SymbolKind::Struct), Parents(), + AllOf(WithName("Parent"), WithKind(SymbolKind::Struct), + ParentsNotResolved(), Children(AllOf(WithName("Child1"), WithKind(SymbolKind::Struct), ParentsNotResolved(), ChildrenNotResolved())))); -- 2.7.4