diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp --- a/clang/lib/Index/IndexTypeSourceInfo.cpp +++ b/clang/lib/Index/IndexTypeSourceInfo.cpp @@ -160,6 +160,25 @@ return true; } + bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { + if (!WalkUpFromTemplateSpecializationTypeLoc(TL)) + return false; + if (!TraverseTemplateName(TL.getTypePtr()->getTemplateName())) + return false; + + // The relations we have to `Parent` do not apply to our template arguments, + // so clear them while visiting the args. + SmallVector SavedRelations = Relations; + // Relations.clear(); + for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { + if (!TraverseTemplateArgumentLoc(TL.getArgLoc(I))) + return false; + } + Relations = SavedRelations; + + return true; + } + bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) { auto *T = TL.getTypePtr(); if (!T) diff --git a/clang/unittests/Index/IndexTests.cpp b/clang/unittests/Index/IndexTests.cpp --- a/clang/unittests/Index/IndexTests.cpp +++ b/clang/unittests/Index/IndexTests.cpp @@ -334,6 +334,20 @@ WrittenAt(Position(3, 20))))); } +TEST(IndexTest, RelationBaseOf) { + std::string Code = R"cpp( + class A {}; + template class B {}; + class C : B {}; + )cpp"; + auto Index = std::make_shared(); + tooling::runToolOnCode(std::make_unique(Index), Code); + // A should not be the base of anything. + EXPECT_THAT(Index->Symbols, + Contains(AllOf(QName("A"), HasRole(SymbolRole::Reference), + Not(HasRole(SymbolRole::RelationBaseOf))))); +} + } // namespace } // namespace index } // namespace clang