Skip to content

Conversation

@Michael137
Copy link
Member

We didn't have coverage for this yet. And I'm planning on making some chnges in this area. These tests will be useful for that.

We didn't have coverage for this yet. And I'm planning on making some
chnges in this area. These tests will be useful for that.
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Sep 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-clang

Author: Michael Buch (Michael137)

Changes

We didn't have coverage for this yet. And I'm planning on making some chnges in this area. These tests will be useful for that.


Full diff: https://github.com/llvm/llvm-project/pull/160705.diff

1 Files Affected:

  • (added) clang/test/DebugInfo/CXX/lambda-capture-packs.cpp (+165)
diff --git a/clang/test/DebugInfo/CXX/lambda-capture-packs.cpp b/clang/test/DebugInfo/CXX/lambda-capture-packs.cpp
new file mode 100644
index 0000000000000..d5fd442ff2936
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/lambda-capture-packs.cpp
@@ -0,0 +1,165 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \
+// RUN:   -debug-info-kind=standalone -std=c++26 %s -o - | FileCheck %s
+
+
+// CHECK: ![[PACK1:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int>"
+// CHECK: ![[PACK2:[0-9]+]] = distinct !DISubprogram(name: "capture_pack<int, int>"
+// CHECK: ![[PACK3:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int>"
+// CHECK: ![[PACK4:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_locals<int, int>"
+// CHECK: ![[PACK5:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int>"
+// CHECK: ![[PACK6:[0-9]+]] = distinct !DISubprogram(name: "capture_pack_and_this<int, int>"
+
+template<typename... Args>
+auto capture_pack(Args... args) {
+  return [args..., ...params = args] {
+    return 0;
+  }();
+}
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK1]]
+// CHECK-SAME:                           elements: ![[PACK1_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK1_ELEMS]] = !{![[PACK1_ARGS:[0-9]+]], ![[PACK1_PARAMS:[0-9]+]]}
+// CHECK-NEXT: ![[PACK1_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK1_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK2]]
+// CHECK-SAME:                           elements: ![[PACK2_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK2_ELEMS]] = !{![[PACK2_ARGS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK2_ARGS]]
+// CHECK-SAME:                      ![[PACK2_PARAMS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK2_PARAMS]]}
+// CHECK-NEXT: ![[PACK2_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK2_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+template<typename... Args>
+auto capture_pack_and_locals(int x, Args... args) {
+  int w = 0;
+  return [=, &args..., &x, ...params = args] {
+    return w;
+  }();
+}
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK3]]
+// CHECK-SAME:                           elements: ![[PACK3_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK3_ELEMS]] = !{![[PACK3_ARGS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK3_X:[0-9]+]]
+// CHECK-SAME:                      ![[PACK3_PARAMS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK3_W:[0-9]+]]}
+// CHECK-NEXT: ![[PACK3_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: !DIDerivedType(tag: DW_TAG_reference_type
+// CHECK-NEXT: ![[PACK3_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-NEXT: ![[PACK3_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NEXT: ![[PACK3_W]] = !DIDerivedType(tag: DW_TAG_member, name: "w"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK4]]
+// CHECK-SAME:                           elements: ![[PACK4_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK4_ELEMS]] = !{![[PACK4_ARGS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK4_ARGS]]
+// CHECK-SAME:                      ![[PACK4_X:[0-9]+]]
+// CHECK-SAME:                      ![[PACK4_PARAMS:[0-9]+]]
+// CHECK-SAME:                      ![[PACK4_PARAMS]]
+// CHECK-SAME:                      ![[PACK4_W:[0-9]+]]}
+// CHECK-NEXT: ![[PACK4_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK4_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-NEXT: ![[PACK4_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NEXT: ![[PACK4_W]] = !DIDerivedType(tag: DW_TAG_member, name: "w"
+// CHECK-NOT:  DW_TAG_member
+
+struct Foo {
+  template<typename... Args>
+  auto capture_pack_and_this(Args... args) {
+    auto val1 = [this, args..., ...params = args] {
+      return w;
+    }();
+
+    auto val2 = [args..., this, ...params = args] {
+      return w;
+    }();
+
+    auto val3 = [args..., ...params = args, this] {
+      return w;
+    }();
+
+    return val1 + val2 + val3;
+  }
+
+  int w = 10;
+} f;
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK5]]
+// CHECK-SAME:                           elements: ![[PACK5a_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK5a_ELEMS]] = !{![[PACK5a_THIS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5a_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5a_PARAMS:[0-9]+]]}
+// CHECK-NEXT: ![[PACK5a_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NEXT: ![[PACK5a_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK5a_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK5]]
+// CHECK-SAME:                           elements: ![[PACK5b_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK5b_ELEMS]] = !{![[PACK5b_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5b_THIS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5b_PARAMS:[0-9]+]]}
+// CHECK-NEXT: ![[PACK5b_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK5b_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NEXT: ![[PACK5b_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK5]]
+// CHECK-SAME:                           elements: ![[PACK5c_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK5c_ELEMS]] = !{![[PACK5c_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5c_PARAMS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK5c_THIS:[0-9]+]]}
+// CHECK-NEXT: ![[PACK5c_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK5c_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NEXT: ![[PACK5c_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK6]]
+// CHECK-SAME:                           elements: ![[PACK6a_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK6a_ELEMS]] = !{![[PACK6a_THIS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6a_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6a_ARGS]]
+// CHECK-SAME:                       ![[PACK6a_PARAMS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6a_PARAMS]]
+// CHECK-NEXT: ![[PACK6a_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NEXT: ![[PACK6a_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK6a_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK6]]
+// CHECK-SAME:                           elements: ![[PACK6b_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK6b_ELEMS]] = !{![[PACK6b_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6b_ARGS]]
+// CHECK-SAME:                       ![[PACK6b_THIS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6b_PARAMS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6b_PARAMS]]}
+// CHECK-NEXT: ![[PACK6b_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK6b_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NEXT: ![[PACK6b_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NOT:  DW_TAG_member
+
+// CHECK:      distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK6]]
+// CHECK-SAME:                           elements: ![[PACK6c_ELEMS:[0-9]+]]
+// CHECK-NEXT: ![[PACK6c_ELEMS]] = !{![[PACK6c_ARGS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6c_ARGS]]
+// CHECK-SAME:                       ![[PACK6c_PARAMS:[0-9]+]]
+// CHECK-SAME:                       ![[PACK6c_PARAMS]]
+// CHECK-SAME:                       ![[PACK6c_THIS:[0-9]+]]}
+// CHECK-NEXT: ![[PACK6c_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
+// CHECK-NEXT: ![[PACK6c_PARAMS]] = !DIDerivedType(tag: DW_TAG_member, name: "params"
+// CHECK-NEXT: ![[PACK6c_THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this"
+// CHECK-NOT:  DW_TAG_member
+
+int main() {
+  return capture_pack(1)
+         + capture_pack(1, 2)
+         + capture_pack_and_locals(1, 2)
+         + capture_pack_and_locals(1, 2, 3)
+         + f.capture_pack_and_this(1)
+         + f.capture_pack_and_this(1, 2);
+}

@zwuis
Copy link
Contributor

zwuis commented Sep 25, 2025

I think this test case is needed: (by-reference, with initializer, and is a pack)

return [&...params = args] {
  return /* ... */;
}();

Copy link
Collaborator

@adrian-prantl adrian-prantl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor modifications (relaxing the test)


// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK3]]
// CHECK-SAME: elements: ![[PACK3_ELEMS:[0-9]+]]
// CHECK-NEXT: ![[PACK3_ELEMS]] = !{![[PACK3_ARGS:[0-9]+]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's really no reason to expect this to be on the next line. I would just do a CHECK here.


// CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, scope: ![[PACK4]]
// CHECK-SAME: elements: ![[PACK4_ELEMS:[0-9]+]]
// CHECK-NEXT: ![[PACK4_ELEMS]] = !{![[PACK4_ARGS:[0-9]+]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

// CHECK-SAME: ![[PACK7_PARAMS]]
// CHECK-SAME: ![[PACK7_ES:[0-9]+]]
// CHECK-SAME: ![[PACK7_E:[0-9]+]]}
// CHECK-NEXT: ![[PACK7_ARGS]] = !DIDerivedType(tag: DW_TAG_member, name: "args"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here — the order doesn't matter and might change.

@Michael137
Copy link
Member Author

I think this test case is needed: (by-reference, with initializer, and is a pack)

return [&...params = args] {
  return /* ... */;
}();

The pack initialization isn't really important for debug-info (i don't think). The reason i have them in the tests is so we have multiple packs in the same capture lists. I do have a by-ref test for one of the packs

@Michael137 Michael137 enabled auto-merge (squash) September 26, 2025 06:48
@Michael137 Michael137 merged commit 77a3d43 into llvm:main Sep 26, 2025
9 checks passed
@Michael137 Michael137 deleted the clang/lambda-pack-capture-names-3 branch September 26, 2025 08:41
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
)

We didn't have coverage for this yet. And I'm planning on making some
chnges in this area. These tests will be useful for that.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants