https://github.com/max-winkler created https://github.com/llvm/llvm-project/pull/231191
Fixes [clangd/clangd#2713](https://github.com/clangd/clangd/issues/2713) **Problem:** Go-to-definition on `T` in `T...[0] x;` jumped to the variable `x` instead of the template parameter `T`. **Cause:** The `TypeLoc` of the pattern (`getPatternLoc()`) was not initialized when Sema visited a `PackIndexingTypeLoc`, so the AST had no valid source location for `T`. In addition, `RecursiveASTVisitor` traversed a `PackIndexingType`'s pattern as a `Type` instead of as a `TypeLoc`. **Change:** - Sema: initialize the pattern `TypeLoc` from the type specifier location. - `RecursiveASTVisitor`: traverse the pattern via its `TypeLoc`. - Add a clangd test (`TargetDeclTest.PackIndexing`). **Testing:** `check-clang` and `check-clangd` pass. The new test fails when either the Sema change or the `RecursiveASTVisitor` change is reverted. **Note:** For this case the ellipsis location of the `PackIndexingTypeLoc` is still invalid. It is not needed for this fix, so I left it unchanged. >From a09b9aa7c5b07677a62dd405fbe4931ac254877f Mon Sep 17 00:00:00 2001 From: Max Winkler <[email protected]> Date: Mon, 12 Oct 2026 14:15:12 +0200 Subject: [PATCH] [clang] Initialize pattern TypeLoc of PackIndexingTypeLoc For a pack indexing type like 'T...[0] x', the TypeLoc of the pattern was never initialized, so it carried no valid source location. This caused clangd's go-to-definition on 'T' to jump to the variable declaration instead of the template parameter 'T'. Initialize the pattern TypeLoc when Sema visits a PackIndexingTypeLoc, and make RecursiveASTVisitor traverse the pattern via its TypeLoc instead of its Type. A clangd test is added in TargetDeclTest.PackIndexing. Fixes clangd/clangd#2713 Assisted-by: Claude --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp | 9 +++++++++ clang/include/clang/AST/RecursiveASTVisitor.h | 2 +- clang/lib/Sema/SemaType.cpp | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index cd57eb7d912b8..388dfe7a0e7aa 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -691,6 +691,15 @@ TEST_F(TargetDeclTest, PackIndexing) { )cpp"; EXPECT_DECLS("TemplateSpecializationTypeLoc", "template <typename> class ...X"); + + Code = R"cpp( + // Indexed type template parameter pack + template <typename... X> + void foo() { + [[X]]...[0] x; + } + )cpp"; + EXPECT_DECLS("TemplateTypeParmTypeLoc", "typename ...X"); } TEST_F(TargetDeclTest, PackIndexedConcept) { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f144c890f6ee6..13dd5eda84fa6 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1469,7 +1469,7 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, { }) DEF_TRAVERSE_TYPELOC(PackIndexingType, { - TRY_TO(TraverseType(TL.getPattern())); + TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr())); }) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1cb96b556971a..46494105ea55d 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6122,6 +6122,7 @@ namespace { void VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) { assert(DS.getTypeSpecType() == DeclSpec::TST_typename_pack_indexing); TL.setEllipsisLoc(DS.getEllipsisLoc()); + TL.getPatternLoc().initialize(Context, DS.getTypeSpecTypeLoc()); } void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { assert(DS.isTransformTypeTrait(DS.getTypeSpecType())); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
