xref: /llvm-project/clang/test/CodeGenCXX/cxx20-decomposition.cpp (revision 94473f4db6a6f5f12d7c4081455b5b596094eac5)
1 // RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
2 
3 struct S {
4   int i;
5   int j;
6 };
7 
8 int f() {
9   auto [i, j] = S{1, 42};
10   return [&i, j] {
11     return i + j;
12   }();
13 }
14 
15 // Ensures the representation of the lambda, the order of the
16 // 1st 2nd don't matter except for ABI-esque things, but make sure
17 // that the ref-capture is a ptr, and 'j' is captured by value.
18 // CHECK: %[[LAMBDA_TY:.+]] = type <{ ptr, i32, [4 x i8] }>
19 
20 // Check the captures themselves.
21 // CHECK: define{{.*}} i32 @_Z1fv()
22 // CHECK: %[[BINDING:.+]] = alloca %struct.S
23 // CHECK: %[[LAMBDA:.+]] = alloca %[[LAMBDA_TY]]
24 
25 // Copy a pointer to the binding, for reference capture.
26 // CHECK: %[[LAMBDA_CAP_PTR:.+]] = getelementptr inbounds nuw %[[LAMBDA_TY]], ptr %[[LAMBDA]], i32 0, i32 0
27 // CHECK: %[[BINDING_PTR:.+]] = getelementptr inbounds nuw %struct.S, ptr %[[BINDING]], i32 0, i32 0
28 // CHECK: store ptr %[[BINDING_PTR]], ptr %[[LAMBDA_CAP_PTR]]
29 
30 // Copy the integer from the binding, for copy capture.
31 // CHECK: %[[LAMBDA_CAP_INT:.+]] = getelementptr inbounds nuw %[[LAMBDA_TY]], ptr %[[LAMBDA]], i32 0, i32 1
32 // CHECK: %[[PTR_TO_J:.+]] = getelementptr inbounds nuw %struct.S, ptr %[[BINDING]], i32 0, i32 1
33 // CHECK: %[[J_COPY:.+]] = load i32, ptr %[[PTR_TO_J]]
34 // CHECK: store i32 %[[J_COPY]], ptr %[[LAMBDA_CAP_INT]]
35 
36 // Ensure the captures are properly extracted in operator().
37 // CHECK: define{{.*}} i32 @"_ZZ1fvENK3$_0clEv"
38 // CHECK: %[[THIS_ADDR:.+]] = alloca ptr
39 // CHECK: %[[THIS_PTR:.+]] = load ptr, ptr %[[THIS_ADDR]]
40 
41 // Load 'i', passed by reference.
42 // CHECK: %[[LAMBDA_GEP_TO_PTR:.+]] = getelementptr inbounds nuw %[[LAMBDA_TY]], ptr %[[THIS_PTR]], i32 0, i32 0
43 // CHECK: %[[I_PTR:.+]] = load ptr, ptr %[[LAMBDA_GEP_TO_PTR]]
44 // CHECK: %[[I_VALUE:.+]] = load i32, ptr %[[I_PTR]]
45 
46 // Load the 'j', passed by value.
47 // CHECK: %[[LAMBDA_GEP_TO_INT:.+]] = getelementptr inbounds nuw %[[LAMBDA_TY]], ptr %[[THIS_PTR]], i32 0, i32 1
48 // CHECK: %[[J_VALUE:.+]] = load i32, ptr %[[LAMBDA_GEP_TO_INT]]
49