StmtPrinter: factor out arg printing code to PrintCallArgs
[clang.git] / test / CodeGenObjC / property.m
blobdd0786eb30ee0ec4d24426089fcdf7af36eb1e70
1 // RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
3 // TODO: actually test most of this instead of just emitting it
5 int printf(const char *, ...);
7 @interface Root
8 -(id) alloc;
9 -(id) init;
10 @end
12 @interface A : Root {
13   int x;
14   int y, ro, z;
15   id ob0, ob1, ob2, ob3, ob4;
17 @property int x;
18 @property int y;
19 @property int z;
20 @property(readonly) int ro;
21 @property(assign) id ob0;
22 @property(retain) id ob1;
23 @property(copy) id ob2;
24 @property(retain, nonatomic) id ob3;
25 @property(copy, nonatomic) id ob4;
26 @end
28 @implementation A
29 @dynamic x;
30 @synthesize y;
31 @synthesize z = z;
32 @synthesize ro;
33 @synthesize ob0;
34 @synthesize ob1;
35 @synthesize ob2;
36 @synthesize ob3;
37 @synthesize ob4;
38 -(int) y {
39   return x + 1;
41 -(void) setZ: (int) arg {
42   x = arg - 1;
44 @end
46 @interface A (Cat)
47 @property int dyn;
48 @end
50 @implementation A (Cat)
51 -(int) dyn {
52   return 10;
54 @end
56 // Test that compound operations only compute the base once.
57 // CHECK: define void @test2
58 A *test2_helper(void);
59 void test2() {
60   // CHECK:      [[BASE:%.*]] = call [[A:%.*]]* @test2_helper()
61   // CHECK-NEXT: [[SEL:%.*]] = load i8**
62   // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
63   // CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[BASETMP]], i8* [[SEL]])
64   // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LD]], 1
65   // CHECK-NEXT: [[SEL:%.*]] = load i8**
66   // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
67   // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* [[BASETMP]], i8* [[SEL]], i32 [[ADD]])
68   test2_helper().dyn++;
70   // CHECK:      [[BASE:%.*]] = call [[A]]* @test2_helper()
71   // CHECK-NEXT: [[SEL:%.*]] = load i8**
72   // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
73   // CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[BASETMP]], i8* [[SEL]])
74   // CHECK-NEXT: [[ADD:%.*]] = mul nsw i32 [[LD]], 10
75   // CHECK-NEXT: [[SEL:%.*]] = load i8**
76   // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
77   // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* [[BASETMP]], i8* [[SEL]], i32 [[ADD]])
78   test2_helper().dyn *= 10;
81 // Test aggregate initialization from property reads.
82 // Not crashing is good enough for the property-specific test.
83 struct test3_struct { int x,y,z; };
84 struct test3_nested { struct test3_struct t; };
85 @interface test3_object
86 @property struct test3_struct s;
87 @end
88 void test3(test3_object *p) {
89   struct test3_struct array[1] = { p.s };
90   struct test3_nested agg = { p.s };
93 // PR8742
94 @interface Test4  {}
95 @property float f;
96 @end
97 // CHECK: define void @test4
98 void test4(Test4 *t) {
99   extern int test4_printf(const char *, ...);
100   // CHECK: [[TMP:%.*]] = call float {{.*}} @objc_msgSend
101   // CHECK-NEXT: [[EXT:%.*]] = fpext float [[TMP]] to double
102   // CHECK-NEXT: call i32 (i8*, ...)* @test4_printf(i8* {{.*}}, double [[EXT]])
103   // CHECK-NEXT: ret void
104   test4_printf("%.2f", t.f);