[clang] Visit enum base specifiers in libIndex
authorKadir Cetinkaya <kadircet@google.com>
Wed, 6 Oct 2021 19:59:04 +0000 (21:59 +0200)
committerKadir Cetinkaya <kadircet@google.com>
Mon, 25 Oct 2021 11:16:14 +0000 (13:16 +0200)
Fixes https://github.com/clangd/clangd/issues/878.

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

clang-tools-extra/clangd/unittests/XRefsTests.cpp
clang/lib/Index/IndexDecl.cpp
clang/unittests/Index/IndexTests.cpp

index 99a6b6e..8023676 100644 (file)
@@ -1966,6 +1966,20 @@ TEST(FindReferences, WithinAST) {
           [[f^oo]](s);
         }
       )cpp",
+
+      // Enum base
+      R"cpp(
+        typedef int $def[[MyTypeD^ef]];
+        enum MyEnum : [[MyTy^peDef]] { };
+      )cpp",
+      R"cpp(
+        typedef int $def[[MyType^Def]];
+        enum MyEnum : [[MyTypeD^ef]];
+      )cpp",
+      R"cpp(
+        using $def[[MyTypeD^ef]] = int;
+        enum MyEnum : [[MyTy^peDef]] { };
+      )cpp",
   };
   for (const char *Test : Tests)
     checkFindRefs(Test);
index 00adb36..3139aed 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "IndexingContext.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/Index/IndexDataConsumer.h"
 
@@ -372,6 +373,15 @@ public:
     return true;
   }
 
+  bool VisitEnumDecl(const EnumDecl *ED) {
+    TRY_TO(VisitTagDecl(ED));
+    // Indexing for enumdecl itself is handled inside TagDecl, we just want to
+    // visit integer-base here, which is different than other TagDecl bases.
+    if (auto *TSI = ED->getIntegerTypeSourceInfo())
+      IndexCtx.indexTypeSourceInfo(TSI, ED, ED, /*isBase=*/true);
+    return true;
+  }
+
   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
                                  const ObjCContainerDecl *ContD,
                                  SourceLocation SuperLoc) {
index 24230c6..88ad63b 100644 (file)
@@ -377,6 +377,21 @@ TEST(IndexTest, RelationBaseOf) {
                              Not(HasRole(SymbolRole::RelationBaseOf)))));
 }
 
+TEST(IndexTest, EnumBase) {
+  std::string Code = R"cpp(
+    typedef int MyTypedef;
+    enum Foo : MyTypedef;
+    enum Foo : MyTypedef {};
+  )cpp";
+  auto Index = std::make_shared<Indexer>();
+  tooling::runToolOnCode(std::make_unique<IndexAction>(Index), Code);
+  EXPECT_THAT(
+      Index->Symbols,
+      AllOf(Contains(AllOf(QName("MyTypedef"), HasRole(SymbolRole::Reference),
+                           WrittenAt(Position(3, 16)))),
+            Contains(AllOf(QName("MyTypedef"), HasRole(SymbolRole::Reference),
+                           WrittenAt(Position(4, 16))))));
+}
 } // namespace
 } // namespace index
 } // namespace clang