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
