1// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s 2 3// TODO: actually test most of this instead of just emitting it 4 5int printf(const char *, ...); 6 7@interface Root 8-(id) alloc; 9-(id) init; 10@end 11 12@interface A : Root { 13 int x; 14 int y, ro, z; 15 id ob0, ob1, ob2, ob3, ob4; 16} 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 27 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; 40} 41-(void) setZ: (int) arg { 42 x = arg - 1; 43} 44@end 45 46@interface A (Cat) 47@property int dyn; 48@end 49 50@implementation A (Cat) 51-(int) dyn { 52 return 10; 53} 54@end 55 56// Test that compound operations only compute the base once. 57// CHECK: define void @test2 58A *test2_helper(void); 59void 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++; 69 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; 79} 80 81// Test aggregate initialization from property reads. 82// Not crashing is good enough for the property-specific test. 83struct test3_struct { int x,y,z; }; 84struct test3_nested { struct test3_struct t; }; 85@interface test3_object 86@property struct test3_struct s; 87@end 88void test3(test3_object *p) { 89 struct test3_struct array[1] = { p.s }; 90 struct test3_nested agg = { p.s }; 91} 92 93// PR8742 94@interface Test4 {} 95@property float f; 96@end 97// CHECK: define void @test4 98void 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); 105} 106