150
|
1 // RUN: %clang_cc1 -std=gnu++98 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
|
|
2
|
|
3 #include "literal-support.h"
|
|
4
|
|
5 struct X {
|
|
6 X();
|
|
7 ~X();
|
|
8 operator id() const;
|
|
9 };
|
|
10
|
|
11 struct Y {
|
|
12 Y();
|
|
13 ~Y();
|
|
14 operator id() const;
|
|
15 };
|
|
16
|
221
|
17 // CHECK-LABEL: define{{.*}} void @_Z10test_arrayv
|
150
|
18 void test_array() {
|
|
19 // CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*
|
|
20 // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
|
|
21 // CHECK: [[TMPX:%[a-zA-Z0-9.]+]] = alloca %
|
|
22 // CHECK: [[TMPY:%[a-zA-Z0-9.]+]] = alloca %
|
|
23
|
|
24 // Initializing first element
|
|
25 // CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
|
|
26 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
|
|
27 // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
|
|
28 // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPX]] to i8*
|
|
29 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
|
|
30 // CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]])
|
|
31 // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
|
|
32 // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
|
|
33 // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
|
|
34
|
|
35 // Initializing the second element
|
|
36 // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
|
|
37 // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPY]] to i8*
|
|
38 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
|
|
39 // CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]])
|
|
40 // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
|
|
41 // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
|
|
42 // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
|
|
43
|
|
44 // Build the array
|
|
45 // CHECK: {{invoke.*@objc_msgSend}}
|
|
46 // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
|
47 id arr = @[ X(), Y() ];
|
|
48
|
|
49 // Destroy temporaries
|
|
50 // CHECK-NOT: ret void
|
|
51 // CHECK: call void @llvm.objc.release
|
|
52 // CHECK-NOT: ret void
|
|
53 // CHECK: invoke void @_ZN1YD1Ev
|
|
54 // CHECK-NOT: ret void
|
|
55 // CHECK: call void @llvm.objc.release
|
|
56 // CHECK-NEXT: call void @_ZN1XD1Ev
|
|
57 // CHECK-NOT: ret void
|
|
58 // CHECK: call void @llvm.objc.release
|
|
59 // CHECK-NEXT: [[PTR2:%.*]] = bitcast i8** [[ARR]] to i8*
|
|
60 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]])
|
|
61 // CHECK-NEXT: ret void
|
|
62
|
|
63 // Check cleanups
|
|
64 // CHECK: call void @llvm.objc.release
|
|
65 // CHECK-NOT: call void @llvm.objc.release
|
|
66 // CHECK: invoke void @_ZN1YD1Ev
|
|
67 // CHECK: call void @llvm.objc.release
|
|
68 // CHECK-NOT: call void @llvm.objc.release
|
|
69 // CHECK: invoke void @_ZN1XD1Ev
|
|
70 // CHECK-NOT: call void @llvm.objc.release
|
|
71 // CHECK: unreachable
|
|
72 }
|
|
73
|
|
74 // CHECK-LABEL: define weak_odr void @_Z24test_array_instantiationIiEvv
|
|
75 template<typename T>
|
|
76 void test_array_instantiation() {
|
|
77 // CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*
|
|
78 // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
|
|
79
|
|
80 // Initializing first element
|
|
81 // CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
|
|
82 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
|
|
83 // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
|
|
84 // CHECK: call void @_ZN1XC1Ev
|
|
85 // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
|
|
86 // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
|
|
87 // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
|
|
88
|
|
89 // Initializing the second element
|
|
90 // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
|
|
91 // CHECK: invoke void @_ZN1YC1Ev
|
|
92 // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
|
|
93 // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
|
|
94 // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
|
|
95
|
|
96 // Build the array
|
|
97 // CHECK: {{invoke.*@objc_msgSend}}
|
|
98 // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
|
99 id arr = @[ X(), Y() ];
|
|
100
|
|
101 // Destroy temporaries
|
|
102 // CHECK-NOT: ret void
|
|
103 // CHECK: call void @llvm.objc.release
|
|
104 // CHECK-NOT: ret void
|
|
105 // CHECK: invoke void @_ZN1YD1Ev
|
|
106 // CHECK-NOT: ret void
|
|
107 // CHECK: call void @llvm.objc.release
|
|
108 // CHECK-NEXT: call void @_ZN1XD1Ev
|
|
109 // CHECK-NOT: ret void
|
|
110 // CHECK: call void @llvm.objc.release
|
|
111 // CHECK-NEXT: [[PTR2]] = bitcast i8** [[ARR]] to i8*
|
|
112 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR2]])
|
|
113 // CHECK-NEXT: ret void
|
|
114
|
|
115 // Check cleanups
|
|
116 // CHECK: call void @llvm.objc.release
|
|
117 // CHECK-NOT: call void @llvm.objc.release
|
|
118 // CHECK: invoke void @_ZN1YD1Ev
|
|
119 // CHECK: call void @llvm.objc.release
|
|
120 // CHECK-NOT: call void @llvm.objc.release
|
|
121 // CHECK: invoke void @_ZN1XD1Ev
|
|
122 // CHECK-NOT: call void @llvm.objc.release
|
|
123 // CHECK: unreachable
|
|
124 }
|
|
125
|
|
126 template void test_array_instantiation<int>();
|
|
127
|