1// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
2
3typedef __strong id strong_id;
4typedef __weak id weak_id;
5
6// CHECK-LABEL: define void @_Z8test_newP11objc_object
7void test_new(id invalue) {
8  // CHECK: [[INVALUEADDR:%.*]] = alloca i8*
9  // CHECK-NEXT: store i8* null, i8** [[INVALUEADDR]]
10  // CHECK-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]])
11
12  // CHECK: call noalias i8* @_Znwm
13  // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
14  // CHECK-NEXT: store i8* null, i8**
15  new strong_id;
16  // CHECK: call noalias i8* @_Znwm
17  // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
18  // CHECK-NEXT: store i8* null, i8**
19  new weak_id;
20
21  // CHECK: call noalias i8* @_Znwm
22  // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
23  // CHECK-NEXT: store i8* null, i8**
24  new __strong id;
25  // CHECK: call noalias i8* @_Znwm
26  // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
27  // CHECK-NEXT: store i8* null, i8**
28  new __weak id;
29
30  // CHECK: call noalias i8* @_Znwm
31  // CHECK: call i8* @objc_retain
32  // CHECK: store i8*
33  new __strong id(invalue);
34
35  // CHECK: call noalias i8* @_Znwm
36  // CHECK: call i8* @objc_initWeak
37  new __weak id(invalue);
38
39  // CHECK: call void @objc_storeStrong
40  // CHECK: ret void
41}
42
43// CHECK-LABEL: define void @_Z14test_array_new
44void test_array_new() {
45  // CHECK: call noalias i8* @_Znam
46  // CHECK: store i64 17, i64*
47  // CHECK: call void @llvm.memset.p0i8.i64
48  new strong_id[17];
49
50  // CHECK: call noalias i8* @_Znam
51  // CHECK: store i64 17, i64*
52  // CHECK: call void @llvm.memset.p0i8.i64
53  new weak_id[17];
54  // CHECK: ret void
55}
56
57// CHECK-LABEL: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_
58void test_delete(__strong id *sptr, __weak id *wptr) {
59  // CHECK: br i1
60  // CHECK: load i8*, i8**
61  // CHECK-NEXT: call void @objc_release
62  // CHECK: call void @_ZdlPv
63  delete sptr;
64
65  // CHECK: call void @objc_destroyWeak
66  // CHECK: call void @_ZdlPv
67  delete wptr;
68
69  // CHECK: ret void
70}
71
72// CHECK-LABEL: define void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_
73void test_array_delete(__strong id *sptr, __weak id *wptr) {
74  // CHECK: icmp eq i8** [[BEGIN:%.*]], null
75  // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
76  // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
77  // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
78  // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
79  // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
80  // CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null)
81  // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
82  // CHECK: call void @_ZdaPv
83  delete [] sptr;
84
85  // CHECK: icmp eq i8** [[BEGIN:%.*]], null
86  // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
87  // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
88  // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
89  // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
90  // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
91  // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]])
92  // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
93  // CHECK: call void @_ZdaPv
94  delete [] wptr;
95}
96