[clang] Do not consider the template arguments of bases to be bases themselves
authorNathan Ridge <zeratul976@hotmail.com>
Mon, 24 Aug 2020 02:15:12 +0000 (22:15 -0400)
committerNathan Ridge <zeratul976@hotmail.com>
Tue, 1 Sep 2020 23:18:03 +0000 (19:18 -0400)
Fixes https://github.com/clangd/clangd/issues/504

Differential Revision: https://reviews.llvm.org/D86424

clang/lib/Index/IndexTypeSourceInfo.cpp
clang/test/Index/Core/index-source.cpp
clang/unittests/Index/IndexTests.cpp

index b9fc900..ec4ca23 100644 (file)
@@ -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)
index 371265b..781343e 100644 (file)
@@ -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
index 52744e1..0ea78f1 100644 (file)
@@ -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