https://github.com/max-winkler updated 
https://github.com/llvm/llvm-project/pull/231191

>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 1/2] [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 cd57eb7d912b8b..388dfe7a0e7aac 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 f144c890f6ee65..13dd5eda84fa65 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 1cb96b556971ad..46494105ea55d2 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()));

>From 73b2b038f9fa508e64cd84268566dbcf96bf86bd Mon Sep 17 00:00:00 2001
From: Max Winkler <[email protected]>
Date: Wed, 14 Oct 2026 11:15:01 +0200
Subject: [PATCH 2/2] [clang] Add PackIndexingTypeLoc tests and FIXME for
 ellipsis

Adds RecursiveASTVisitorTests for type locations of pack indexing types
in variable declaration (T...[0] x) and alias definition (using U = T...[0]).
Tests fail without changes in SemaType.cpp and RecursiveASTVisitor.h.

Adds Lang_CXX26 entry in TestVisitor.h to run the test with -std=c++26.

Adds FIXME comment in TypeSpecLocFiller::VisitPackIndexingTypeLoc noting
an invalid EllipsisLoc which is dropped by the parser when annotating
the type.

Assisted-by: Claude
---
 clang/lib/Sema/SemaType.cpp                   |  5 ++
 clang/unittests/Tooling/CMakeLists.txt        |  1 +
 .../PackIndexingTypeLoc.cpp                   | 48 +++++++++++++++++++
 clang/unittests/Tooling/TestVisitor.h         |  4 ++
 4 files changed, 58 insertions(+)
 create mode 100644 
clang/unittests/Tooling/RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 46494105ea55d2..742fb853ce8615 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6121,6 +6121,11 @@ namespace {
     }
     void VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
       assert(DS.getTypeSpecType() == DeclSpec::TST_typename_pack_indexing);
+      // FIXME: The location of the ellipsis is not recorded here. The parser
+      // knows it when it first parses the pack indexing type, but it is 
dropped
+      // when the type is annotated (see
+      // Parser::AnnotateExistingIndexedTypeNamePack), so DS.getEllipsisLoc()
+      // is invalid when this runs.
       TL.setEllipsisLoc(DS.getEllipsisLoc());
       TL.getPatternLoc().initialize(Context, DS.getTypeSpecTypeLoc());
     }
diff --git a/clang/unittests/Tooling/CMakeLists.txt 
b/clang/unittests/Tooling/CMakeLists.txt
index 4de300fa86385f..44373a57fcf53e 100644
--- a/clang/unittests/Tooling/CMakeLists.txt
+++ b/clang/unittests/Tooling/CMakeLists.txt
@@ -43,6 +43,7 @@ add_clang_unittest(ToolingTests
   RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
   RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
   RecursiveASTVisitorTests/OffsetOfExpr.cpp
+  RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp
   RecursiveASTVisitorTests/ParenExpr.cpp
   RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
   RecursiveASTVisitorTests/TraversalScope.cpp
diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp
new file mode 100644
index 00000000000000..65072ddc3f74db
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp
@@ -0,0 +1,48 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/PackIndexingTypeLoc.cpp 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+class PackIndexingTypeLocVisitor : public ExpectedLocationVisitor {
+public:
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
+    if (!TL)
+      return true;
+    Match(TL.getDecl()->getName(), TL.getNameLoc());
+    return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, VisitTypeLocInPackIndexingType) {
+  PackIndexingTypeLocVisitor Visitor;
+  Visitor.ExpectMatch("T", 4, 8);
+  llvm::StringLiteral Code = R"cpp(
+     template <typename... T>
+     void foo() {
+       T...[0] x;
+     }
+  )cpp";
+  EXPECT_TRUE(Visitor.runOver(Code, PackIndexingTypeLocVisitor::Lang_CXX26));
+}
+
+TEST(RecursiveASTVisitor, VisitTypeLocInPackIndexingTypeAlias) {
+  PackIndexingTypeLocVisitor Visitor;
+  Visitor.ExpectMatch("T", 4, 18);
+  llvm::StringLiteral Code = R"cpp(
+     template <typename... T>
+     void foo() {
+       using U = T...[0];
+     }
+  )cpp";
+  EXPECT_TRUE(Visitor.runOver(Code, PackIndexingTypeLocVisitor::Lang_CXX26));
+}
+} // end anonymous namespace
diff --git a/clang/unittests/Tooling/TestVisitor.h 
b/clang/unittests/Tooling/TestVisitor.h
index fdf57a946a6e2d..f6fe58bc9c4411 100644
--- a/clang/unittests/Tooling/TestVisitor.h
+++ b/clang/unittests/Tooling/TestVisitor.h
@@ -36,6 +36,7 @@ class TestVisitorHelper {
     Lang_CXX14,
     Lang_CXX17,
     Lang_CXX2a,
+    Lang_CXX26,
     Lang_OBJC,
     Lang_OBJCXX11,
     Lang_CXX = Lang_CXX98
@@ -64,6 +65,9 @@ class TestVisitorHelper {
     case Lang_CXX2a:
       Args.push_back("-std=c++2a");
       break;
+    case Lang_CXX26:
+      Args.push_back("-std=c++26");
+      break;
     case Lang_OBJC:
       Args.push_back("-ObjC");
       Args.push_back("-fobjc-runtime=macosx-10.12.0");

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to