1*67e74705SXin Li// RUN: %clang_cc1 -fobjc-arc -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Listruct ObjCMember { 4*67e74705SXin Li id member; 5*67e74705SXin Li}; 6*67e74705SXin Li 7*67e74705SXin Listruct ObjCArrayMember { 8*67e74705SXin Li id member[2][3]; 9*67e74705SXin Li}; 10*67e74705SXin Li 11*67e74705SXin Listruct ObjCBlockMember { 12*67e74705SXin Li int (^bp)(int); 13*67e74705SXin Li}; 14*67e74705SXin Li 15*67e74705SXin Li// CHECK-LABEL: define void @_Z42test_ObjCMember_default_construct_destructv( 16*67e74705SXin Livoid test_ObjCMember_default_construct_destruct() { 17*67e74705SXin Li // CHECK: call void @_ZN10ObjCMemberC1Ev 18*67e74705SXin Li // CHECK: call void @_ZN10ObjCMemberD1Ev 19*67e74705SXin Li ObjCMember m1; 20*67e74705SXin Li} 21*67e74705SXin Li 22*67e74705SXin Li// CHECK-LABEL: define void @_Z39test_ObjCMember_copy_construct_destruct10ObjCMember 23*67e74705SXin Livoid test_ObjCMember_copy_construct_destruct(ObjCMember m1) { 24*67e74705SXin Li // CHECK: call void @_ZN10ObjCMemberC1ERKS_ 25*67e74705SXin Li // CHECK: call void @_ZN10ObjCMemberD1Ev 26*67e74705SXin Li ObjCMember m2 = m1; 27*67e74705SXin Li // CHECK: ret void 28*67e74705SXin Li} 29*67e74705SXin Li 30*67e74705SXin Li// CHECK-LABEL: define void @_Z27test_ObjCMember_copy_assign10ObjCMemberS_ 31*67e74705SXin Livoid test_ObjCMember_copy_assign(ObjCMember m1, ObjCMember m2) { 32*67e74705SXin Li // CHECK: {{call.*_ZN10ObjCMemberaSERKS_}} 33*67e74705SXin Li m1 = m2; 34*67e74705SXin Li // CHECK-NEXT: ret void 35*67e74705SXin Li} 36*67e74705SXin Li 37*67e74705SXin Li// Implicitly-generated copy assignment operator for ObjCMember 38*67e74705SXin Li// CHECK: {{define linkonce_odr.*@_ZN10ObjCMemberaSERKS_}} 39*67e74705SXin Li// CHECK: call void @objc_storeStrong 40*67e74705SXin Li// CHECK: ret 41*67e74705SXin Li 42*67e74705SXin Li// CHECK-LABEL: define void @_Z47test_ObjCArrayMember_default_construct_destructv 43*67e74705SXin Livoid test_ObjCArrayMember_default_construct_destruct() { 44*67e74705SXin Li // CHECK: call void @_ZN15ObjCArrayMemberC1Ev 45*67e74705SXin Li ObjCArrayMember m1; 46*67e74705SXin Li // CHECK: call void @_ZN15ObjCArrayMemberD1Ev 47*67e74705SXin Li // CHECK: ret void 48*67e74705SXin Li} 49*67e74705SXin Li 50*67e74705SXin Li// CHECK-LABEL: define void @_Z44test_ObjCArrayMember_copy_construct_destruct15ObjCArrayMember 51*67e74705SXin Livoid test_ObjCArrayMember_copy_construct_destruct(ObjCArrayMember m1) { 52*67e74705SXin Li // CHECK: call void @_ZN15ObjCArrayMemberC1ERKS_ 53*67e74705SXin Li ObjCArrayMember m2 = m1; 54*67e74705SXin Li // CHECK: call void @_ZN15ObjCArrayMemberD1Ev 55*67e74705SXin Li // CHECK: ret void 56*67e74705SXin Li} 57*67e74705SXin Li 58*67e74705SXin Livoid test_ObjCArrayMember_copy_assign(ObjCArrayMember m1, ObjCArrayMember m2) { 59*67e74705SXin Li // CHECK: {{call.*@_ZN15ObjCArrayMemberaSERKS_}} 60*67e74705SXin Li m1 = m2; 61*67e74705SXin Li // CHECK-NEXT: ret void 62*67e74705SXin Li} 63*67e74705SXin Li 64*67e74705SXin Li// Implicitly-generated copy assignment operator for ObjCArrayMember 65*67e74705SXin Li// CHECK: {{define linkonce_odr.*@_ZN15ObjCArrayMemberaSERKS_}} 66*67e74705SXin Li// CHECK: call void @objc_storeStrong 67*67e74705SXin Li// CHECK-NEXT: br label 68*67e74705SXin Li// CHECK: ret 69*67e74705SXin Li 70*67e74705SXin Li// CHECK-LABEL: define void @_Z47test_ObjCBlockMember_default_construct_destructv 71*67e74705SXin Livoid test_ObjCBlockMember_default_construct_destruct() { 72*67e74705SXin Li // CHECK: call void @_ZN15ObjCBlockMemberC1Ev 73*67e74705SXin Li ObjCBlockMember m; 74*67e74705SXin Li // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev 75*67e74705SXin Li // CHECK-NEXT: ret void 76*67e74705SXin Li} 77*67e74705SXin Li 78*67e74705SXin Li// CHECK-LABEL: define void @_Z44test_ObjCBlockMember_copy_construct_destruct15ObjCBlockMember 79*67e74705SXin Livoid test_ObjCBlockMember_copy_construct_destruct(ObjCBlockMember m1) { 80*67e74705SXin Li // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_ 81*67e74705SXin Li ObjCBlockMember m2 = m1; 82*67e74705SXin Li // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev 83*67e74705SXin Li // CHECK-NEXT: ret void 84*67e74705SXin Li} 85*67e74705SXin Li 86*67e74705SXin Li// CHECK-LABEL: define void @_Z32test_ObjCBlockMember_copy_assign15ObjCBlockMemberS_ 87*67e74705SXin Livoid test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) { 88*67e74705SXin Li // CHECK: {{call.*_ZN15ObjCBlockMemberaSERKS_}} 89*67e74705SXin Li m1 = m2; 90*67e74705SXin Li // CHECK-NEXT: ret void 91*67e74705SXin Li} 92*67e74705SXin Li 93*67e74705SXin Li// Implicitly-generated copy assignment operator for ObjCBlockMember 94*67e74705SXin Li// CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_( 95*67e74705SXin Li// CHECK: [[T0:%.*]] = getelementptr inbounds [[T:%.*]], [[T:%.*]]* {{%.*}}, i32 0, i32 0 96*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = load i32 (i32)*, i32 (i32)** [[T0]], align 8 97*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast i32 (i32)* [[T1]] to i8* 98*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainBlock(i8* [[T2]]) 99*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32 (i32)* 100*67e74705SXin Li// CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[T]], [[T]]* {{%.*}}, i32 0, i32 0 101*67e74705SXin Li// CHECK-NEXT: [[T6:%.*]] = load i32 (i32)*, i32 (i32)** [[T5]], align 8 102*67e74705SXin Li// CHECK-NEXT: store i32 (i32)* [[T4]], i32 (i32)** [[T5]] 103*67e74705SXin Li// CHECK-NEXT: [[T7:%.*]] = bitcast i32 (i32)* [[T6]] to i8* 104*67e74705SXin Li// CHECK-NEXT: call void @objc_release(i8* [[T7]]) 105*67e74705SXin Li// CHECK-NEXT: ret 106*67e74705SXin Li 107*67e74705SXin Li// Implicitly-generated default constructor for ObjCMember 108*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2Ev 109*67e74705SXin Li// CHECK-NOT: objc_release 110*67e74705SXin Li// CHECK: store i8* null 111*67e74705SXin Li// CHECK-NEXT: ret void 112*67e74705SXin Li 113*67e74705SXin Li// Implicitly-generated destructor for ObjCMember 114*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberD2Ev 115*67e74705SXin Li// CHECK: call void @objc_storeStrong 116*67e74705SXin Li// CHECK: ret void 117*67e74705SXin Li 118*67e74705SXin Li// Implicitly-generated copy constructor for ObjCMember 119*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2ERKS_ 120*67e74705SXin Li// CHECK-NOT: objc_release 121*67e74705SXin Li// CHECK: call i8* @objc_retain 122*67e74705SXin Li// CHECK-NEXT: store i8* 123*67e74705SXin Li// CHECK-NEXT: ret void 124*67e74705SXin Li 125*67e74705SXin Li// Implicitly-generated default constructor for ObjCArrayMember 126*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2Ev 127*67e74705SXin Li// CHECK: call void @llvm.memset.p0i8.i64 128*67e74705SXin Li// CHECK: ret 129*67e74705SXin Li 130*67e74705SXin Li// Implicitly-generated destructor for ObjCArrayMember 131*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberD2Ev 132*67e74705SXin Li// CHECK: [[BEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]], [2 x [3 x i8*]]* 133*67e74705SXin Li// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 6 134*67e74705SXin Li// CHECK-NEXT: br label 135*67e74705SXin Li// CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 136*67e74705SXin Li// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 137*67e74705SXin Li// CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) 138*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] 139*67e74705SXin Li// CHECK-NEXT: br i1 [[T1]], 140*67e74705SXin Li// CHECK: ret void 141*67e74705SXin Li 142*67e74705SXin Li// Implicitly-generated copy constructor for ObjCArrayMember 143*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_ 144*67e74705SXin Li// CHECK: br i1 145*67e74705SXin Li// CHECK: call i8* @objc_retain 146*67e74705SXin Li// CHECK-NEXT: store i8* 147*67e74705SXin Li// CHECK-NEXT: br label 148*67e74705SXin Li// CHECK: ret 149*67e74705SXin Li 150*67e74705SXin Li// Implicitly-generated default constructor for ObjCBlockMember 151*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2Ev 152*67e74705SXin Li// CHECK: store {{.*}} null, 153*67e74705SXin Li// CHECK-NEXT: ret void 154*67e74705SXin Li 155*67e74705SXin Li// Implicitly-generated destructor for ObjCBlockMember 156*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev 157*67e74705SXin Li// CHECK: call void @objc_storeStrong(i8* 158*67e74705SXin Li// CHECK: ret 159*67e74705SXin Li 160*67e74705SXin Li// Implicitly-generated copy constructor for ObjCBlockMember 161*67e74705SXin Li// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2ERKS_ 162*67e74705SXin Li// CHECK: call i8* @objc_retainBlock 163*67e74705SXin Li// CHECK: ret 164*67e74705SXin Li 165