[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
This commit is contained in:
Nathan Ridge 2019-07-17 15:26:49 +00:00
parent f81ee439a4
commit e61d0257ed
2 changed files with 19 additions and 17 deletions

View File

@ -1132,15 +1132,9 @@ static void fillSubTypes(const SymbolID &ID,
using RecursionProtectionSet = llvm::SmallSet<const CXXRecordDecl *, 4>;
static Optional<TypeHierarchyItem>
getTypeAncestors(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
std::vector<TypeHierarchyItem> &SuperTypes,
RecursionProtectionSet &RPSet) {
Optional<TypeHierarchyItem> Result = declToTypeHierarchyItem(ASTCtx, CXXRD);
if (!Result)
return Result;
Result->parents.emplace();
// 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<TypeHierarchyItem> 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<TypeHierarchyItem> 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) {

View File

@ -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()))));