1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s |
2 | // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NF |
3 | |
4 | // Most of this test is apparently just verifying that we don't crash. |
5 | |
6 | int printf(const char *, ...); |
7 | |
8 | @interface Root |
9 | @end |
10 | |
11 | typedef struct { |
12 | int x, y, z[10]; |
13 | } MyPoint; |
14 | typedef struct { |
15 | float width, height; |
16 | } MySize; |
17 | |
18 | @interface A : Root |
19 | +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3; |
20 | +(float) returnAFloat; |
21 | +(double) returnADouble; |
22 | +(MyPoint) returnAPoint; |
23 | +(void) printThisSize: (MySize) arg0; |
24 | +(MySize) returnASize; |
25 | |
26 | -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3; |
27 | -(float) returnAFloat; |
28 | -(double) returnADouble; |
29 | -(MyPoint) returnAPoint; |
30 | -(void) printThisSize: (MySize) arg0; |
31 | -(MySize) returnASize; |
32 | @end |
33 | @interface B : A |
34 | @end |
35 | |
36 | @implementation A |
37 | +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
38 | printf("(CLASS) theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n", |
39 | arg0, arg1, arg2, arg3.x, arg3.y); |
40 | } |
41 | +(float) returnAFloat { |
42 | return 15.; |
43 | } |
44 | +(double) returnADouble { |
45 | return 25.; |
46 | } |
47 | +(MyPoint) returnAPoint { |
48 | MyPoint x = { 35, 45 }; |
49 | return x; |
50 | } |
51 | +(void) printThisSize: (MySize) arg0 { |
52 | printf("(CLASS) theSize: { %f, %f }\n", |
53 | arg0.width, arg0.height); |
54 | } |
55 | +(MySize) returnASize { |
56 | MySize x = { 32, 44 }; |
57 | return x; |
58 | } |
59 | |
60 | -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
61 | printf("theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n", |
62 | arg0, arg1, arg2, arg3.x, arg3.y); |
63 | } |
64 | -(float) returnAFloat { |
65 | return 10.; |
66 | } |
67 | -(double) returnADouble { |
68 | return 20.; |
69 | } |
70 | -(MyPoint) returnAPoint { |
71 | MyPoint x = { 30, 40 }; |
72 | return x; |
73 | } |
74 | -(void) printThisSize: (MySize) arg0 { |
75 | printf("theSize: { %f, %f }\n", |
76 | arg0.width, arg0.height); |
77 | } |
78 | -(MySize) returnASize { |
79 | MySize x = { 22, 34 }; |
80 | return x; |
81 | } |
82 | @end |
83 | |
84 | @implementation B |
85 | +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
86 | arg3.x *= 2; |
87 | arg3.y *= 2; |
88 | [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ]; |
89 | } |
90 | +(void) printThisSize: (MySize) arg0 { |
91 | arg0.width *= 2; |
92 | arg0.height *= 2; |
93 | [ super printThisSize: arg0 ]; |
94 | } |
95 | +(float) returnAFloat { |
96 | return [ super returnAFloat ]*2; |
97 | } |
98 | +(double) returnADouble { |
99 | return [ super returnADouble ]*2; |
100 | } |
101 | +(MyPoint) returnAPoint { |
102 | MyPoint x = [ super returnAPoint ]; |
103 | x.x *= 2; |
104 | x.y *= 2; |
105 | return x; |
106 | } |
107 | +(MySize) returnASize { |
108 | MySize x = [ super returnASize ]; |
109 | x.width *= 2; |
110 | x.height *= 2; |
111 | return x; |
112 | } |
113 | |
114 | -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
115 | arg3.x *= 2; |
116 | arg3.y *= 2; |
117 | [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ]; |
118 | } |
119 | -(void) printThisSize: (MySize) arg0 { |
120 | arg0.width *= 2; |
121 | arg0.height *= 2; |
122 | [ super printThisSize: arg0 ]; |
123 | } |
124 | -(float) returnAFloat { |
125 | return [ super returnAFloat ]*2; |
126 | } |
127 | -(double) returnADouble { |
128 | return [ super returnADouble ]*2; |
129 | } |
130 | -(MyPoint) returnAPoint { |
131 | MyPoint x = [ super returnAPoint ]; |
132 | x.x *= 2; |
133 | x.y *= 2; |
134 | return x; |
135 | } |
136 | -(MySize) returnASize { |
137 | MySize x = [ super returnASize ]; |
138 | x.width *= 2; |
139 | x.height *= 2; |
140 | return x; |
141 | } |
142 | -(const float) returnAConstFloat { |
143 | return 5; |
144 | } |
145 | @end |
146 | |
147 | // rdar://problem/7854674 |
148 | // CHECK: define void @test0([[A:%.*]]* |
149 | // CHECK-NF: define void @test0([[A:%.*]]* |
150 | void test0(A *x) { |
151 | // CHECK: [[X:%.*]] = alloca [[A]]* |
152 | // CHECK-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], |
153 | // CHECK: [[T0:%.*]] = load [[A]]*, [[A]]** [[X]] |
154 | // CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* |
155 | // CHECK-NEXT: icmp eq i8* [[T1]], null |
156 | // CHECK-NEXT: br i1 |
157 | // CHECK: call {{.*}} @objc_msgSend_stret to |
158 | // CHECK-NEXT: br label |
159 | // CHECK: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* |
160 | // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false) |
161 | // CHECK-NEXT: br label |
162 | |
163 | // CHECK-NF: [[X:%.*]] = alloca [[A]]* |
164 | // CHECK-NF-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], |
165 | // CHECK-NF: [[T0:%.*]] = load [[A]]*, [[A]]** [[X]] |
166 | // CHECK-NF: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* |
167 | // CHECK-NF-NEXT: icmp eq i8* [[T1]], null |
168 | // CHECK-NF-NEXT: br i1 |
169 | // CHECK-NF: call {{.*}} @objc_msgSend_stret to |
170 | // CHECK-NF-NEXT: br label |
171 | // CHECK-NF: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* |
172 | // CHECK-NF-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false) |
173 | // CHECK-NF-NEXT: br label |
174 | MyPoint point = [x returnAPoint]; |
175 | } |
176 | |