Skip to content

Commit 6b6f539

Browse files
fix: Handle self-inheritance when emitting relationships (#401)
1 parent d33d48e commit 6b6f539

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

indexer/Indexer.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -723,18 +723,20 @@ void TuIndexer::saveTagDecl(const clang::TagDecl &tagDecl) {
723723

724724
llvm::SmallPtrSet<const clang::CXXRecordDecl *, 1> seen{};
725725
llvm::SmallVector<const clang::CXXRecordDecl *, 1> stack{};
726+
const clang::CXXRecordDecl *startDecl = nullptr;
726727
if (auto *cxxRecordDecl = llvm::dyn_cast<clang::CXXRecordDecl>(&tagDecl)) {
727-
seen.insert(cxxRecordDecl);
728+
startDecl = cxxRecordDecl;
728729
stack.push_back(cxxRecordDecl);
729730
}
730731

731732
while (!stack.empty()) {
732733
auto *cxxRecordDecl = stack.back();
733734
stack.pop_back();
734-
if (!cxxRecordDecl) {
735+
if (!cxxRecordDecl || seen.contains(cxxRecordDecl)) {
735736
continue;
736737
}
737-
if (seen.find(cxxRecordDecl) == seen.end()) {
738+
seen.insert(cxxRecordDecl);
739+
if (cxxRecordDecl != startDecl) {
738740
// FIXME(def: template-specialization-support) When we get the decl
739741
// symbol here, we need to handle different kinds of templates
740742
// differently. E.g. in the ImplicitInstantiation case, call
@@ -748,7 +750,6 @@ void TuIndexer::saveTagDecl(const clang::TagDecl &tagDecl) {
748750
rel.set_is_implementation(true);
749751
*symbolInfo.add_relationships() = std::move(rel);
750752
}
751-
seen.insert(cxxRecordDecl);
752753
}
753754
if (!cxxRecordDecl->hasDefinition()) {
754755
// FIXME(def: template-specialization-support) This case

test/index/types/inheritance.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,15 @@ template <class T>
4545
struct BaseWithOnlySpecializations<false, T> {};
4646

4747
template <class T>
48-
struct DerivedFromBasedWithOnlySpecialization: public BaseWithOnlySpecializations<false, T> {};
48+
struct DerivedFromBasedWithOnlySpecialization: public BaseWithOnlySpecializations<false, T> {};
49+
50+
template <typename T>
51+
struct DerivedFromSelf: DerivedFromSelf<T *> {};
52+
53+
template <>
54+
struct DerivedFromSelf<int *> {};
55+
56+
void useDerivedFromSelf() {
57+
DerivedFromSelf<int> x;
58+
(void)x;
59+
}

test/index/types/inheritance.snapshot.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,24 @@
107107
// relation implementation [..] BaseWithOnlySpecializations#
108108
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] BaseWithOnlySpecializations#
109109
// ^ reference local 10
110+
111+
template <typename T>
112+
// ^ definition local 11
113+
struct DerivedFromSelf: DerivedFromSelf<T *> {};
114+
// ^^^^^^^^^^^^^^^ definition [..] DerivedFromSelf#
115+
// ^^^^^^^^^^^^^^^ reference [..] DerivedFromSelf#
116+
// ^ reference local 11
117+
118+
template <>
119+
struct DerivedFromSelf<int *> {};
120+
// ^^^^^^^^^^^^^^^ reference [..] DerivedFromSelf#
121+
// ^^^^^^^^^^^^^^^ definition [..] DerivedFromSelf#
122+
123+
void useDerivedFromSelf() {
124+
// ^^^^^^^^^^^^^^^^^^ definition [..] useDerivedFromSelf(49f6e7a06ebc5aa8).
125+
DerivedFromSelf<int> x;
126+
// ^^^^^^^^^^^^^^^ reference [..] DerivedFromSelf#
127+
// ^ definition local 12
128+
(void)x;
129+
// ^ reference local 12
130+
}

0 commit comments

Comments
 (0)