kadircet created this revision. kadircet added reviewers: nridge, hokein. Herald added subscribers: usaxena95, arphaman. kadircet requested review of this revision. Herald added projects: clang, clang-tools-extra. Herald added a subscriber: cfe-commits.
Visit enum integer-base specifiers explicitly written in the code. This is achieved by: - traversing the typeloc for integer-base on enum decls when they are spelled in the code (similar to base-specifiers for CXXRecordDecls). - Visiting the typesourceinfo for integer-base in libindex, similar to base-specifiers. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D111224 Files: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp clang/include/clang/AST/RecursiveASTVisitor.h clang/lib/Index/IndexTypeSourceInfo.cpp clang/unittests/Index/IndexTests.cpp
Index: clang/unittests/Index/IndexTests.cpp =================================================================== --- clang/unittests/Index/IndexTests.cpp +++ clang/unittests/Index/IndexTests.cpp @@ -377,6 +377,18 @@ Not(HasRole(SymbolRole::RelationBaseOf))))); } +TEST(IndexTest, EnumBase) { + std::string Code = R"cpp( + typedef int MyTypedef; + enum Foo : MyTypedef {}; + )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("MyTypedef"), HasRole(SymbolRole::Reference), + WrittenAt(Position(3, 16))))); +} } // namespace } // namespace index } // namespace clang Index: clang/lib/Index/IndexTypeSourceInfo.cpp =================================================================== --- clang/lib/Index/IndexTypeSourceInfo.cpp +++ clang/lib/Index/IndexTypeSourceInfo.cpp @@ -7,8 +7,10 @@ //===----------------------------------------------------------------------===// #include "IndexingContext.h" +#include "clang/AST/Decl.h" #include "clang/AST/RecursiveASTVisitor.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/Support/Casting.h" using namespace clang; using namespace index; @@ -305,6 +307,9 @@ for (const auto &I : CXXRD->bases()) { indexTypeSourceInfo(I.getTypeSourceInfo(), CXXRD, CXXRD, /*isBase=*/true); } + } else if (auto *ED = dyn_cast<EnumDecl>(D)) { + if (auto *TSI = ED->getIntegerTypeSourceInfo()) + indexTypeSourceInfo(TSI, ED, ED, /*isBase=*/true); } indexDeclContext(D); } Index: clang/include/clang/AST/RecursiveASTVisitor.h =================================================================== --- clang/include/clang/AST/RecursiveASTVisitor.h +++ clang/include/clang/AST/RecursiveASTVisitor.h @@ -1863,6 +1863,9 @@ DEF_TRAVERSE_DECL(EnumDecl, { TRY_TO(TraverseDeclTemplateParameterLists(D)); + if (auto *TSI = D->getIntegerTypeSourceInfo()) + TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + if (D->getTypeForDecl()) TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -880,6 +880,15 @@ }; )cpp", + R"cpp(// Enum base + typedef int $def[[MyTypeDef]]; + enum Foo : My^TypeDef; + )cpp", + R"cpp(// Enum base + using $def[[MyTypeDef]] = int; + enum Foo : My^TypeDef {}; + )cpp", + R"objc( @protocol Dog; @protocol $decl[[Dog]] @@ -1951,6 +1960,16 @@ [[f^oo]](s); } )cpp", + + // Enum base + R"cpp( + typedef int $def[[MyTypeDef]]; + enum MyEnum : [[MyTy^peDef]] { }; + )cpp", + R"cpp( + using $def[[MyTypeDef]] = int; + enum MyEnum : [[MyTy^peDef]] { }; + )cpp", }; for (const char *Test : Tests) checkFindRefs(Test); Index: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -780,6 +780,16 @@ $LocalVariable_decl[[d]]($LocalVariable[[b]]) ]() {}(); } )cpp", + // Enum base specifier + R"cpp( + using $Primitive_decl[[MyTypedef]] = int; + enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {}; + )cpp", + // Enum base specifier + R"cpp( + typedef int $Primitive_decl[[MyTypedef]]; + enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {}; + )cpp", }; for (const auto &TestCase : TestCases) // Mask off scope modifiers to keep the tests manageable.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits