forked from OSchip/llvm-project
[clang] Do not consider the template arguments of bases to be bases themselves
Fixes https://github.com/clangd/clangd/issues/504 Differential Revision: https://reviews.llvm.org/D86424
This commit is contained in:
parent
94948f3c92
commit
7cd6b0c3b5
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "IndexingContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace index;
|
||||
|
@ -160,6 +161,26 @@ public:
|
|||
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<SymbolRelation, 3> SavedRelations = Relations;
|
||||
Relations.clear();
|
||||
auto ResetSavedRelations =
|
||||
llvm::make_scope_exit([&] { this->Relations = SavedRelations; });
|
||||
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
|
||||
if (!TraverseTemplateArgumentLoc(TL.getArgLoc(I)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) {
|
||||
auto *T = TL.getTypePtr();
|
||||
if (!T)
|
||||
|
|
|
@ -560,3 +560,11 @@ class SubclassOffsetof : public Struct {
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
namespace clangd_issue_504 {
|
||||
class A {};
|
||||
template <typename> class B {};
|
||||
class C : B<A> {};
|
||||
// CHECK: [[@LINE-1]]:13 | class/C++ | A | c:@N@clangd_issue_504@S@A | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | C | c:@N@clangd_issue_504@S@C
|
||||
} // namespace clangd_issue_504
|
||||
|
|
|
@ -334,6 +334,20 @@ TEST(IndexTest, VisitDefaultArgs) {
|
|||
WrittenAt(Position(3, 20)))));
|
||||
}
|
||||
|
||||
TEST(IndexTest, RelationBaseOf) {
|
||||
std::string Code = R"cpp(
|
||||
class A {};
|
||||
template <typename> class B {};
|
||||
class C : B<A> {};
|
||||
)cpp";
|
||||
auto Index = std::make_shared<Indexer>();
|
||||
tooling::runToolOnCode(std::make_unique<IndexAction>(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
|
||||
|
|
Loading…
Reference in New Issue