1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
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
6int printf(const char *, ...);
7
8@interface Root
9@end
10
11typedef struct {
12  int x, y, z[10];
13} MyPoint;
14typedef 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:%.*]]*
150void test0(A *x) {
151  // CHECK:         [[X:%.*]] = alloca [[A]]*
152  // CHECK-NEXT:    [[POINT:%.*]] = alloca [[POINT_T:%.*]],
153  // CHECK:         [[T0:%.*]] = load [[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* [[T0]], i8 0, i64 48, i32 4, 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]]** [[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* [[T0]], i8 0, i64 48, i32 4, i1 false)
173  // CHECK-NF-NEXT: br label
174  MyPoint point = [x returnAPoint];
175}
176