@@ -9,7 +9,10 @@ void fn() {
99 a ();
1010}
1111
12+ // CHECK-DAG: !ty_A = !cir.struct<struct "A" {!s32i}>
1213// CHECK: !ty_anon2E0_ = !cir.struct<class "anon.0" {!u8i}>
14+ // CHECK-DAG: !ty_anon2E7_ = !cir.struct<class "anon.7" {!ty_A}>
15+ // CHECK-DAG: !ty_anon2E8_ = !cir.struct<class "anon.8" {!cir.ptr<!ty_A>}>
1316// CHECK-DAG: module
1417
1518// CHECK: cir.func lambda internal private @_ZZ2fnvENK3$_0clEv{{.*}}) extra
@@ -285,3 +288,92 @@ int g3() {
285288// LLVM: store i32 [[tmp2]], ptr [[ret_val]], align 4
286289// LLVM: [[tmp3:%.*]] = load i32, ptr [[ret_val]], align 4
287290// LLVM: ret i32 [[tmp3]]
291+
292+ struct A {
293+ int a = 111 ;
294+ int foo () { return [*this ] { return a; }(); }
295+ int bar () { return [this ] { return a; }(); }
296+ };
297+ // A's default ctor
298+ // CHECK: cir.func linkonce_odr @_ZN1AC1Ev(%arg0: !cir.ptr<!ty_A>
299+
300+ // lambda operator() in foo()
301+ // CHECK: cir.func lambda linkonce_odr @_ZZN1A3fooEvENKUlvE_clEv([[ARG:%.*]]: !cir.ptr<!ty_anon2E7_>
302+ // CHECK: [[ARG_ADDR:%.*]] = cir.alloca !cir.ptr<!ty_anon2E7_>, !cir.ptr<!cir.ptr<!ty_anon2E7_>>, ["this", init] {alignment = 8 : i64}
303+ // CHECK: cir.store [[ARG]], [[ARG_ADDR]] : !cir.ptr<!ty_anon2E7_>, !cir.ptr<!cir.ptr<!ty_anon2E7_>>
304+ // CHECK: [[CLS_ANNO7:%.*]] = cir.load [[ARG_ADDR]] : !cir.ptr<!cir.ptr<!ty_anon2E7_>>, !cir.ptr<!ty_anon2E7_>
305+ // CHECK: [[STRUCT_A:%.*]] = cir.get_member [[CLS_ANNO7]][0] {name = ""} : !cir.ptr<!ty_anon2E7_> -> !cir.ptr<!ty_A>
306+ // CHECK: [[a:%.*]] = cir.get_member [[STRUCT_A]][0] {name = "a"} : !cir.ptr<!ty_A> -> !cir.ptr<!s32i> loc(#loc70)
307+ // CHECK: cir.return {{%.*}} : !s32i
308+
309+ // LLVM: define {{.*}}@_ZZN1A3fooEvENKUlvE_clEv(ptr{{.*}}[[ARG:%.*]])
310+ // LLVM: [[ARG_ADDR:%.*]] = alloca ptr, i64 1, align 8
311+ // LLVM: [[RET:%.*]] = alloca i32, i64 1, align 4
312+ // LLVM: store ptr [[ARG]], ptr [[ARG_ADDR]], align 8
313+ // LLVM: [[CLS_ANNO7:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8
314+ // LLVM: [[STRUCT_A:%.*]] = getelementptr %class.anon.7, ptr [[CLS_ANNO7]], i32 0, i32 0
315+ // LLVM: [[a:%.*]] = getelementptr %struct.A, ptr [[STRUCT_A]], i32 0, i32 0
316+ // LLVM: [[TMP0:%.*]] = load i32, ptr [[a]], align 4
317+ // LLVM: store i32 [[TMP0]], ptr [[RET]], align 4
318+ // LLVM: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
319+ // LLVM: ret i32 [[TMP1]]
320+
321+ // A::foo()
322+ // CHECK: cir.func linkonce_odr @_ZN1A3fooEv(%arg0: !cir.ptr<!ty_A>{{.*}}-> !s32i
323+ // CHECK: [[THIS_ARG:%.*]] = cir.alloca !ty_anon2E7_, !cir.ptr<!ty_anon2E7_>, ["ref.tmp0"] {alignment = 4 : i64}
324+ // CHECK: cir.call @_ZZN1A3fooEvENKUlvE_clEv([[THIS_ARG]]) : (!cir.ptr<!ty_anon2E7_>) -> !s32i
325+
326+ // LLVM-LABEL: _ZN1A3fooEv
327+ // LLVM: [[this_in_foo:%.*]] = alloca %class.anon.7, i64 1, align 4
328+ // LLVM: call i32 @_ZZN1A3fooEvENKUlvE_clEv(ptr [[this_in_foo]])
329+
330+ // lambda operator() in bar()
331+ // CHECK: cir.func lambda linkonce_odr @_ZZN1A3barEvENKUlvE_clEv([[ARG2:%.*]]: !cir.ptr<!ty_anon2E8_>
332+ // CHECK: [[ARG2_ADDR:%.*]] = cir.alloca !cir.ptr<!ty_anon2E8_>, !cir.ptr<!cir.ptr<!ty_anon2E8_>>, ["this", init] {alignment = 8 : i64}
333+ // CHECK: cir.store [[ARG2]], [[ARG2_ADDR]] : !cir.ptr<!ty_anon2E8_>, !cir.ptr<!cir.ptr<!ty_anon2E8_>>
334+ // CHECK: [[CLS_ANNO8:%.*]] = cir.load [[ARG2_ADDR]] : !cir.ptr<!cir.ptr<!ty_anon2E8_>>, !cir.ptr<!ty_anon2E8_>
335+ // CHECK: [[STRUCT_A_PTR:%.*]] = cir.get_member [[CLS_ANNO8]][0] {name = ""} : !cir.ptr<!ty_anon2E8_> -> !cir.ptr<!cir.ptr<!ty_A>>
336+ // CHECK: [[STRUCT_A:%.*]] = cir.load [[STRUCT_A_PTR]] : !cir.ptr<!cir.ptr<!ty_A>>, !cir.ptr<!ty_A>
337+ // CHECK: [[a:%.*]] = cir.get_member [[STRUCT_A]][0] {name = "a"} : !cir.ptr<!ty_A> -> !cir.ptr<!s32i> loc(#loc70)
338+ // CHECK: cir.return {{%.*}} : !s32i
339+
340+ // LLVM: define {{.*}}@_ZZN1A3barEvENKUlvE_clEv(ptr{{.*}}[[ARG2:%.*]])
341+ // LLVM: [[ARG2_ADDR:%.*]] = alloca ptr, i64 1, align 8
342+ // LLVM: [[RET:%.*]] = alloca i32, i64 1, align 4
343+ // LLVM: store ptr [[ARG2]], ptr [[ARG2_ADDR]], align 8
344+ // LLVM: [[CLS_ANNO8:%.*]] = load ptr, ptr [[ARG2_ADDR]], align 8
345+ // LLVM: [[STRUCT_A_PTR:%.*]] = getelementptr %class.anon.8, ptr [[CLS_ANNO8]], i32 0, i32 0
346+ // LLVM: [[STRUCT_A:%.*]] = load ptr, ptr [[STRUCT_A_PTR]], align 8
347+ // LLVM: [[a:%.*]] = getelementptr %struct.A, ptr [[STRUCT_A]], i32
348+ // LLVM: [[TMP0:%.*]] = load i32, ptr [[a]], align 4
349+ // LLVM: store i32 [[TMP0]], ptr [[RET]], align 4
350+ // LLVM: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
351+ // LLVM: ret i32 [[TMP1]]
352+
353+ // A::bar()
354+ // CHECK: cir.func linkonce_odr @_ZN1A3barEv(%arg0: !cir.ptr<!ty_A>{{.*}}-> !s32i
355+ // CHECK: [[THIS_ARG:%.*]] = cir.alloca !ty_anon2E8_, !cir.ptr<!ty_anon2E8_>, ["ref.tmp0"] {alignment = 8 : i64}
356+ // CHECK: cir.call @_ZZN1A3barEvENKUlvE_clEv([[THIS_ARG]])
357+
358+ // LLVM-LABEL: _ZN1A3barEv
359+ // LLVM: [[this_in_bar:%.*]] = alloca %class.anon.8, i64 1, align 8
360+ // LLVM: call i32 @_ZZN1A3barEvENKUlvE_clEv(ptr [[this_in_bar]])
361+
362+ int test_lambda_this1 (){
363+ struct A clsA;
364+ int x = clsA.foo ();
365+ int y = clsA.bar ();
366+ return x+y;
367+ }
368+
369+ // CHECK-LABEL: test_lambda_this1
370+ // Construct A
371+ // CHECK: cir.call @_ZN1AC1Ev([[A_THIS:%.*]]) : (!cir.ptr<!ty_A>) -> ()
372+ // CHECK: cir.call @_ZN1A3fooEv([[A_THIS]]) : (!cir.ptr<!ty_A>) -> !s32i
373+ // CHECK: cir.call @_ZN1A3barEv([[A_THIS]]) : (!cir.ptr<!ty_A>) -> !s32i
374+
375+ // LLVM-LABEL: test_lambda_this1
376+ // LLVM: [[A_THIS:%.*]] = alloca %struct.A, i64 1, align 4
377+ // LLVM: call void @_ZN1AC1Ev(ptr [[A_THIS]])
378+ // LLVM: call i32 @_ZN1A3fooEv(ptr [[A_THIS]])
379+ // LLVM: call i32 @_ZN1A3barEv(ptr [[A_THIS]])
0 commit comments