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 @@ -1083,6 +1083,14 @@ } )cpp", + R"cpp(// Goto Label. + void test() { + [[la^bel]]: + return; + goto [[label]]; + } + )cpp", + R"cpp( int [[v^ar]] = 0; void foo(int s = [[var]]); diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp --- a/clang/lib/Index/IndexBody.cpp +++ b/clang/lib/Index/IndexBody.cpp @@ -140,6 +140,21 @@ Parent, ParentDC, Roles, Relations, E); } + bool VisitGotoStmt(GotoStmt *Goto) { + if (auto *LabelDecl = Goto->getLabel()) + IndexCtx.handleReference(LabelDecl, Goto->getLabelLoc(), Parent, ParentDC, + static_cast(SymbolRole::Reference)); + return true; + } + + bool VisitLabelStmt(LabelStmt *Label) { + if (auto *LabelDecl = Label->getDecl()) + IndexCtx.handleReference(LabelDecl, Label->getIdentLoc(), Parent, + ParentDC, + static_cast(SymbolRole::Reference)); + return true; + } + bool VisitMemberExpr(MemberExpr *E) { SourceLocation Loc = E->getMemberLoc(); if (Loc.isInvalid()) 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 @@ -334,6 +334,28 @@ WrittenAt(Position(3, 20))))); } +TEST(IndexTest, LabelDecl) { + std::string Code = R"cpp( + void foo() { + label: + return; + } + )cpp"; + auto Index = std::make_shared(); + IndexingOptions Opts; + Opts.IndexFunctionLocals = true; + tooling::runToolOnCode(std::make_unique(Index, Opts), Code); + EXPECT_THAT(Index->Symbols, + Contains(AllOf(QName("label"), HasRole(SymbolRole::Reference), + WrittenAt(Position(3, 5))))); + Index->Symbols.clear(); + Opts.IndexFunctionLocals = false; + tooling::runToolOnCode(std::make_unique(Index, Opts), Code); + EXPECT_THAT(Index->Symbols, + Not(Contains(AllOf(QName("label"), HasRole(SymbolRole::Reference), + WrittenAt(Position(3, 5)))))); +} + } // namespace } // namespace index } // namespace clang