diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1966,6 +1966,20 @@ [[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); diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -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 @@ 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) { 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 @@ -377,6 +377,21 @@ 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(); + tooling::runToolOnCode(std::make_unique(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