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