nridge created this revision.
nridge added a reviewer: sammccall.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous,
MaskRay, ilya-biryukov.
Herald added a project: clang.
Fixes https://github.com/clangd/clangd/issues/31
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D71533
Files:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -409,17 +409,13 @@
ASSERT_TRUE(!AST.getDiagnostics().empty());
// Make sure getTypeHierarchy() doesn't get into an infinite recursion.
- // FIXME(nridge): It would be preferable if the type hierarchy gave us type
- // names (e.g. "S<0>" for the child and "S<1>" for the parent) rather than
- // template names (e.g. "S").
+ // Here, we actually don't get any parents, because the unbounded hierarchy
+ // causes instantiation of the base specifier to fail.
llvm::Optional<TypeHierarchyItem> Result = getTypeHierarchy(
AST, Source.points()[0], 0, TypeHierarchyDirection::Parents);
ASSERT_TRUE(bool(Result));
- EXPECT_THAT(
- *Result,
- AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- SelectionRangeIs(Source.range("SDef")),
Parents()))));
+ EXPECT_THAT(*Result,
+ AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct),
Parents()));
}
TEST(TypeHierarchy, RecursiveHierarchyBounded) {
@@ -449,9 +445,12 @@
ASSERT_TRUE(bool(Result));
EXPECT_THAT(
*Result,
- AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- SelectionRangeIs(Source.range("SDef")),
Parents()))));
+ AllOf(WithName("S<2>"), WithKind(SymbolKind::Struct),
+ Parents(AllOf(
+ WithName("S<1>"), WithKind(SymbolKind::Struct),
+ SelectionRangeIs(Source.range("SDef")),
+ Parents(AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct),
+ Parents()))))));
Result = getTypeHierarchy(AST, Source.point("SRefDependent"), 0,
TypeHierarchyDirection::Parents);
ASSERT_TRUE(bool(Result));
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -674,9 +674,19 @@
const SourceManager &SM = AST.getSourceManager();
SourceLocation SourceLocationBeg = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
+ // First, try to find a template instantiation. This will give us
+ // the ClassTemplateSpecializationDecl for a non-dependent
+ // specialization, allowing us to produce a more accurate type
+ // hierarchy specific to that specialization.
DeclRelationSet Relations =
- DeclRelation::TemplatePattern | DeclRelation::Underlying;
+ DeclRelation::TemplateInstantiation | DeclRelation::Underlying;
auto Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+ if (Decls.empty()) {
+ // For a dependent specialization, there is no specialization Decl
+ // to produce, so get the template pattern instead.
+ Relations = DeclRelation::TemplatePattern | DeclRelation::Underlying;
+ Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+ }
if (Decls.empty())
return nullptr;
Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -409,17 +409,13 @@
ASSERT_TRUE(!AST.getDiagnostics().empty());
// Make sure getTypeHierarchy() doesn't get into an infinite recursion.
- // FIXME(nridge): It would be preferable if the type hierarchy gave us type
- // names (e.g. "S<0>" for the child and "S<1>" for the parent) rather than
- // template names (e.g. "S").
+ // Here, we actually don't get any parents, because the unbounded hierarchy
+ // causes instantiation of the base specifier to fail.
llvm::Optional<TypeHierarchyItem> Result = getTypeHierarchy(
AST, Source.points()[0], 0, TypeHierarchyDirection::Parents);
ASSERT_TRUE(bool(Result));
- EXPECT_THAT(
- *Result,
- AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- SelectionRangeIs(Source.range("SDef")), Parents()))));
+ EXPECT_THAT(*Result,
+ AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct), Parents()));
}
TEST(TypeHierarchy, RecursiveHierarchyBounded) {
@@ -449,9 +445,12 @@
ASSERT_TRUE(bool(Result));
EXPECT_THAT(
*Result,
- AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
- SelectionRangeIs(Source.range("SDef")), Parents()))));
+ AllOf(WithName("S<2>"), WithKind(SymbolKind::Struct),
+ Parents(AllOf(
+ WithName("S<1>"), WithKind(SymbolKind::Struct),
+ SelectionRangeIs(Source.range("SDef")),
+ Parents(AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct),
+ Parents()))))));
Result = getTypeHierarchy(AST, Source.point("SRefDependent"), 0,
TypeHierarchyDirection::Parents);
ASSERT_TRUE(bool(Result));
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -674,9 +674,19 @@
const SourceManager &SM = AST.getSourceManager();
SourceLocation SourceLocationBeg = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
+ // First, try to find a template instantiation. This will give us
+ // the ClassTemplateSpecializationDecl for a non-dependent
+ // specialization, allowing us to produce a more accurate type
+ // hierarchy specific to that specialization.
DeclRelationSet Relations =
- DeclRelation::TemplatePattern | DeclRelation::Underlying;
+ DeclRelation::TemplateInstantiation | DeclRelation::Underlying;
auto Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+ if (Decls.empty()) {
+ // For a dependent specialization, there is no specialization Decl
+ // to produce, so get the template pattern instead.
+ Relations = DeclRelation::TemplatePattern | DeclRelation::Underlying;
+ Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+ }
if (Decls.empty())
return nullptr;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits