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

Reply via email to