diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -643,7 +643,7 @@ return V.Refs; } -llvm::SmallVector refInExpr(const Expr *E) { +llvm::SmallVector refInStmt(const Stmt *S) { struct Visitor : ConstStmtVisitor { // FIXME: handle more complicated cases: more ObjC, designated initializers. llvm::SmallVector Refs; @@ -722,10 +722,25 @@ /*IsDecl=*/false, std::move(Targets)}); } } + + void VisitGotoStmt(const GotoStmt *GS) { + llvm::SmallVector Targets; + if (const auto *L = GS->getLabel()) + Targets.push_back(L); + Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), GS->getLabelLoc(), + /*IsDecl=*/false, std::move(Targets)}); + } + + void VisitLabelStmt(const LabelStmt *LS) { + Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), + LS->getIdentLoc(), + /*IsDecl=*/true, + {LS->getDecl()}}); + } }; Visitor V; - V.Visit(E); + V.Visit(S); return V.Refs; } @@ -837,8 +852,8 @@ return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L); } - bool VisitExpr(Expr *E) { - visitNode(DynTypedNode::create(*E)); + bool VisitStmt(Stmt *S) { + visitNode(DynTypedNode::create(*S)); return true; } @@ -926,8 +941,8 @@ llvm::SmallVector explicitReference(DynTypedNode N) { if (auto *D = N.get()) return refInDecl(D); - if (auto *E = N.get()) - return refInExpr(E); + if (auto *S = N.get()) + return refInStmt(S); if (auto *NNSL = N.get()) { // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases. return {ReferenceLoc{ diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -786,6 +786,14 @@ "6: targets = {a::b::S}\n" "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n" "8: targets = {y}, decl\n"}, + {R"cpp( + void foo() { + $0^ten: // PRINT "HELLO WORLD!" + goto $1^ten; + } + )cpp", + "0: targets = {ten}, decl\n" + "1: targets = {ten}\n"}, // Simple templates. {R"cpp( template struct vector { using value_type = T; };