hokein created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69094

Files:
  clang-tools-extra/clangd/index/Relation.cpp
  clang-tools-extra/clangd/index/Relation.h
  clang-tools-extra/clangd/index/Serialization.cpp
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -676,6 +676,36 @@
               Contains(Relation{Base.ID, RelationKind::BaseOf, Derived.ID}));
 }
 
+TEST_F(SymbolCollectorTest, OverrideRelations) {
+  std::string Header = R"cpp(
+    class Base {
+    virtual void foo1();
+    };
+    class Derived1 : public Base {
+    void foo1() override;
+    virtual void foo2();
+    };
+    class Derived2 : public Derived1 {
+    void foo2() override;
+    };
+  )cpp";
+  runSymbolCollector(Header, /*Main=*/"");
+  const Symbol &Base = findSymbol(Symbols, "Base");
+  const Symbol &Derived1 = findSymbol(Symbols, "Derived1");
+  const Symbol &Derived2 = findSymbol(Symbols, "Derived2");
+  const Symbol &Foo1 = findSymbol(Symbols, "Base::foo1");
+  const Symbol &OverrideFoo1 = findSymbol(Symbols, "Derived1::foo1");
+  const Symbol &Foo2 = findSymbol(Symbols, "Derived1::foo2");
+  const Symbol &OverrideFoo2 = findSymbol(Symbols, "Derived2::foo2");
+  EXPECT_THAT(Relations,
+              UnorderedElementsAreArray({
+                  Relation{Foo1.ID, RelationKind::OverridenBy, OverrideFoo1.ID},
+                  Relation{Foo2.ID, RelationKind::OverridenBy, OverrideFoo2.ID},
+                  Relation{Base.ID, RelationKind::BaseOf, Derived1.ID},
+                  Relation{Derived1.ID, RelationKind::BaseOf, Derived2.ID},
+              }));
+}
+
 TEST_F(SymbolCollectorTest, References) {
   const std::string Header = R"(
     class W;
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "SymbolLocation.h"
 #include "URI.h"
+#include "index/Relation.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -184,7 +185,16 @@
 
 bool shouldIndexRelation(const index::SymbolRelation &R) {
   // We currently only index BaseOf relations, for type hierarchy subtypes.
-  return R.Roles & static_cast<unsigned>(index::SymbolRole::RelationBaseOf);
+  return R.Roles & static_cast<unsigned>(index::SymbolRole::RelationBaseOf) ||
+         R.Roles & static_cast<unsigned>(index::SymbolRole::RelationOverrideOf);
+}
+
+llvm::Optional<RelationKind> indexableRelation(const index::SymbolRelation &R) {
+  if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationBaseOf))
+    return RelationKind::BaseOf;
+  if (R.Roles & static_cast<unsigned>(index::SymbolRole::RelationOverrideOf))
+    return RelationKind::OverridenBy;
+  return None;
 }
 
 } // namespace
@@ -422,14 +432,12 @@
 void SymbolCollector::processRelations(
     const NamedDecl &ND, const SymbolID &ID,
     ArrayRef<index::SymbolRelation> Relations) {
-  // Store subtype relations.
-  if (!dyn_cast<TagDecl>(&ND))
-    return;
-
   for (const auto &R : Relations) {
-    if (!shouldIndexRelation(R))
+    // if (!shouldIndexRelation(R))
+    //   continue;
+    auto RKind = indexableRelation(R);
+    if (!RKind)
       continue;
-
     const Decl *Object = R.RelatedSymbol;
 
     auto ObjectID = getSymbolID(Object);
@@ -445,7 +453,10 @@
     //       in the index and find nothing, but that's a situation they
     //       probably need to handle for other reasons anyways.
     // We currently do (B) because it's simpler.
-    this->Relations.insert(Relation{ID, RelationKind::BaseOf, *ObjectID});
+    if (*RKind == RelationKind::BaseOf)
+      this->Relations.insert({ID, *RKind, *ObjectID});
+    else if (*RKind == RelationKind::OverridenBy)
+      this->Relations.insert({*ObjectID, *RKind, ID});
   }
 }
 
Index: clang-tools-extra/clangd/index/Serialization.cpp
===================================================================
--- clang-tools-extra/clangd/index/Serialization.cpp
+++ clang-tools-extra/clangd/index/Serialization.cpp
@@ -31,26 +31,6 @@
 }
 } // namespace
 
-RelationKind symbolRoleToRelationKind(index::SymbolRole Role) {
-  // SymbolRole is used to record relations in the index.
-  // Only handle the relations we actually store currently.
-  // If we start storing more relations, this list can be expanded.
-  switch (Role) {
-  case index::SymbolRole::RelationBaseOf:
-    return RelationKind::BaseOf;
-  default:
-    llvm_unreachable("Unsupported symbol role");
-  }
-}
-
-index::SymbolRole relationKindToSymbolRole(RelationKind Kind) {
-  switch (Kind) {
-  case RelationKind::BaseOf:
-    return index::SymbolRole::RelationBaseOf;
-  }
-  llvm_unreachable("Invalid relation kind");
-}
-
 namespace {
 
 // IO PRIMITIVES
Index: clang-tools-extra/clangd/index/Relation.h
===================================================================
--- clang-tools-extra/clangd/index/Relation.h
+++ clang-tools-extra/clangd/index/Relation.h
@@ -21,6 +21,7 @@
 
 enum class RelationKind : uint8_t {
   BaseOf,
+  OverridenBy,
 };
 
 /// Represents a relation between two symbols.
@@ -41,6 +42,8 @@
            std::tie(Other.Subject, Other.Predicate, Other.Object);
   }
 };
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const RelationKind R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Relation &R);
 
 class RelationSlab {
 public:
Index: clang-tools-extra/clangd/index/Relation.cpp
===================================================================
--- clang-tools-extra/clangd/index/Relation.cpp
+++ clang-tools-extra/clangd/index/Relation.cpp
@@ -13,6 +13,20 @@
 namespace clang {
 namespace clangd {
 
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const RelationKind R) {
+  switch (R) {
+  case RelationKind ::BaseOf:
+    return OS << "BaseOf";
+  case RelationKind ::OverridenBy:
+    return OS << "OverridenBy";
+  }
+  llvm_unreachable("Unhandled RelationKind enum");
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Relation &R) {
+  return OS << R.Subject << " " << R.Predicate << " " << R.Object;
+}
+
 llvm::iterator_range<RelationSlab::iterator>
 RelationSlab::lookup(const SymbolID &Subject, RelationKind Predicate) const {
   auto IterPair = std::equal_range(Relations.begin(), Relations.end(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to