|  | // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir | 
|  | // RUN: FileCheck --input-file=%t.cir %s | 
|  |  | 
|  | struct Struk { | 
|  | int a; | 
|  | Struk() {} | 
|  | }; | 
|  |  | 
|  | void baz() { | 
|  | Struk s; | 
|  | } | 
|  |  | 
|  | // CHECK: !rec_Struk = !cir.record<struct "Struk" {!s32i}> | 
|  |  | 
|  | // Note: In the absence of the '-mconstructor-aliases' option, we emit two | 
|  | //       constructors here. The handling of constructor aliases is currently | 
|  | //       NYI, but when it is added this test should be updated to add a RUN | 
|  | //       line that passes '-mconstructor-aliases' to clang_cc1. | 
|  | // CHECK:   cir.func @_ZN5StrukC2Ev(%arg0: !cir.ptr<!rec_Struk> | 
|  | // CHECK-NEXT:     %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>>, ["this", init] {alignment = 8 : i64} | 
|  | // CHECK-NEXT:     cir.store %arg0, %[[THIS_ADDR]] : !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>> | 
|  | // CHECK-NEXT:     %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_Struk>>, !cir.ptr<!rec_Struk> | 
|  | // CHECK-NEXT:     cir.return | 
|  |  | 
|  | // CHECK:   cir.func @_ZN5StrukC1Ev(%arg0: !cir.ptr<!rec_Struk> | 
|  | // CHECK-NEXT:     %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>>, ["this", init] {alignment = 8 : i64} | 
|  | // CHECK-NEXT:     cir.store %arg0, %[[THIS_ADDR]] : !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>> | 
|  | // CHECK-NEXT:     %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_Struk>>, !cir.ptr<!rec_Struk> | 
|  | // CHECK-NEXT:     cir.call @_ZN5StrukC2Ev(%[[THIS]]) : (!cir.ptr<!rec_Struk>) -> () | 
|  | // CHECK-NEXT:     cir.return | 
|  |  | 
|  | // CHECK:   cir.func @_Z3bazv() | 
|  | // CHECK-NEXT:     %[[S_ADDR:.*]] = cir.alloca !rec_Struk, !cir.ptr<!rec_Struk>, ["s", init] {alignment = 4 : i64} | 
|  | // CHECK-NEXT:     cir.call @_ZN5StrukC1Ev(%[[S_ADDR]]) : (!cir.ptr<!rec_Struk>) -> () | 
|  | // CHECK-NEXT:     cir.return | 
|  |  | 
|  | struct VariadicStruk { | 
|  | int a; | 
|  | VariadicStruk(int n, ...) { a = n;} | 
|  | }; | 
|  |  | 
|  | void bar() { | 
|  | VariadicStruk s(1, 2, 3); | 
|  | } | 
|  |  | 
|  | // When a variadic constructor is present, we call the C2 constructor directly. | 
|  |  | 
|  | // CHECK-NOT: cir.func @_ZN13VariadicStrukC2Eiz | 
|  |  | 
|  | // CHECK:      cir.func @_ZN13VariadicStrukC1Eiz(%arg0: !cir.ptr<!rec_VariadicStruk> | 
|  | // CHECK-SAME:                                   %arg1: !s32i | 
|  | // CHECK-SAME:                                   ...) { | 
|  | // CHECK-NEXT:   %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init] | 
|  | // CHECK-NEXT:   %[[N_ADDR:.*]] = cir.alloca {{.*}} ["n", init] | 
|  | // CHECK-NEXT:   cir.store %arg0, %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   cir.store %arg1, %[[N_ADDR]] | 
|  | // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   %[[N:.*]] = cir.load{{.*}} %[[N_ADDR]] | 
|  | // CHECK-NEXT:   %[[A_ADDR:.*]] = cir.get_member %[[THIS]][0] {name = "a"} | 
|  | // CHECK-NEXT:   cir.store{{.*}} %[[N]], %[[A_ADDR]] | 
|  | // CHECK-NEXT:   cir.return | 
|  |  | 
|  | // CHECK:  cir.func @_Z3barv | 
|  | // CHECK-NEXT:    %[[S_ADDR:.*]] = cir.alloca !rec_VariadicStruk, !cir.ptr<!rec_VariadicStruk>, ["s", init] | 
|  | // CHECK-NEXT:    %[[ONE:.*]] = cir.const #cir.int<1> : !s32i | 
|  | // CHECK-NEXT:    %[[TWO:.*]] = cir.const #cir.int<2> : !s32i | 
|  | // CHECK-NEXT:    %[[THREE:.*]] = cir.const #cir.int<3> : !s32i | 
|  | // CHECK-NEXT:    cir.call @_ZN13VariadicStrukC1Eiz(%[[S_ADDR]], %[[ONE]], %[[TWO]], %[[THREE]]) | 
|  | // CHECK-NEXT:    cir.return | 
|  |  | 
|  | struct DelegatingStruk { | 
|  | int a; | 
|  | DelegatingStruk(int n) { a = n; } | 
|  | DelegatingStruk() : DelegatingStruk(0) {} | 
|  | }; | 
|  |  | 
|  | void bam() { | 
|  | DelegatingStruk s; | 
|  | } | 
|  |  | 
|  | // CHECK:       cir.func @_ZN15DelegatingStrukC2Ei(%arg0: !cir.ptr<!rec_DelegatingStruk> | 
|  | // CHECK-SAME:                                     %arg1: !s32i | 
|  | // CHECK-NEXT:   %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init] | 
|  | // CHECK-NEXT:   %[[N_ADDR:.*]] = cir.alloca {{.*}} ["n", init] | 
|  | // CHECK-NEXT:   cir.store %arg0, %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   cir.store %arg1, %[[N_ADDR]] | 
|  | // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   %[[N:.*]] = cir.load{{.*}} %[[N_ADDR]] | 
|  | // CHECK-NEXT:   %[[A_ADDR:.*]] = cir.get_member %[[THIS]][0] {name = "a"} | 
|  | // CHECK-NEXT:   cir.store{{.*}} %[[N]], %[[A_ADDR]] | 
|  | // CHECK-NEXT:   cir.return | 
|  |  | 
|  | // CHECK:       cir.func @_ZN15DelegatingStrukC1Ei(%arg0: !cir.ptr<!rec_DelegatingStruk> | 
|  | // CHECK-SAME:                                     %arg1: !s32i | 
|  | // CHECK-NEXT:   %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init] | 
|  | // CHECK-NEXT:   %[[N_ADDR:.*]] = cir.alloca {{.*}} ["n", init] | 
|  | // CHECK-NEXT:   cir.store %arg0, %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   cir.store %arg1, %[[N_ADDR]] | 
|  | // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   %[[N:.*]] = cir.load{{.*}} %[[N_ADDR]] | 
|  | // CHECK-NEXT:   cir.call @_ZN15DelegatingStrukC2Ei(%[[THIS]], %[[N]]) | 
|  | // CHECK-NEXT:   cir.return | 
|  |  | 
|  | // CHECK: cir.func @_ZN15DelegatingStrukC1Ev(%arg0: !cir.ptr<!rec_DelegatingStruk> | 
|  | // CHECK-NEXT:   %[[THIS_ADDR:.*]] = cir.alloca {{.*}} ["this", init] | 
|  | // CHECK-NEXT:   cir.store %arg0, %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   %[[THIS:.*]] = cir.load{{.*}} %[[THIS_ADDR]] | 
|  | // CHECK-NEXT:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i | 
|  | // CHECK-NEXT:   cir.call @_ZN15DelegatingStrukC1Ei(%[[THIS]], %[[ZERO]]) | 
|  | // CHECK-NEXT:   cir.return | 
|  |  | 
|  | // CHECK: cir.func @_Z3bamv | 
|  | // CHECK-NEXT:    %[[S_ADDR:.*]] = cir.alloca {{.*}} ["s", init] | 
|  | // CHECK-NEXT:    cir.call @_ZN15DelegatingStrukC1Ev(%[[S_ADDR]]) | 
|  | // CHECK-NEXT:    cir.return |