1*67e74705SXin Li// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li// TODO: actually test most of this instead of just emitting it 4*67e74705SXin Li 5*67e74705SXin Liint printf(const char *, ...); 6*67e74705SXin Li 7*67e74705SXin Li@interface Root 8*67e74705SXin Li-(id) alloc; 9*67e74705SXin Li-(id) init; 10*67e74705SXin Li@end 11*67e74705SXin Li 12*67e74705SXin Li@interface A : Root { 13*67e74705SXin Li int x; 14*67e74705SXin Li int y, ro, z; 15*67e74705SXin Li id ob0, ob1, ob2, ob3, ob4; 16*67e74705SXin Li} 17*67e74705SXin Li@property int x; 18*67e74705SXin Li@property int y; 19*67e74705SXin Li@property int z; 20*67e74705SXin Li@property(readonly) int ro; 21*67e74705SXin Li@property(assign) id ob0; 22*67e74705SXin Li@property(retain) id ob1; 23*67e74705SXin Li@property(copy) id ob2; 24*67e74705SXin Li@property(retain, nonatomic) id ob3; 25*67e74705SXin Li@property(copy, nonatomic) id ob4; 26*67e74705SXin Li@end 27*67e74705SXin Li 28*67e74705SXin Li@implementation A 29*67e74705SXin Li@dynamic x; 30*67e74705SXin Li@synthesize y; 31*67e74705SXin Li@synthesize z = z; 32*67e74705SXin Li@synthesize ro; 33*67e74705SXin Li@synthesize ob0; 34*67e74705SXin Li@synthesize ob1; 35*67e74705SXin Li@synthesize ob2; 36*67e74705SXin Li@synthesize ob3; 37*67e74705SXin Li@synthesize ob4; 38*67e74705SXin Li-(int) y { 39*67e74705SXin Li return x + 1; 40*67e74705SXin Li} 41*67e74705SXin Li-(void) setZ: (int) arg { 42*67e74705SXin Li x = arg - 1; 43*67e74705SXin Li} 44*67e74705SXin Li@end 45*67e74705SXin Li 46*67e74705SXin Li@interface A (Cat) 47*67e74705SXin Li@property int dyn; 48*67e74705SXin Li@end 49*67e74705SXin Li 50*67e74705SXin Li@implementation A (Cat) 51*67e74705SXin Li-(int) dyn { 52*67e74705SXin Li return 10; 53*67e74705SXin Li} 54*67e74705SXin Li@end 55*67e74705SXin Li 56*67e74705SXin Li// Test that compound operations only compute the base once. 57*67e74705SXin Li// CHECK-LABEL: define void @test2 58*67e74705SXin LiA *test2_helper(void); 59*67e74705SXin Livoid test2() { 60*67e74705SXin Li // CHECK: [[BASE:%.*]] = call [[A:%.*]]* @test2_helper() 61*67e74705SXin Li // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** 62*67e74705SXin Li // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8* 63*67e74705SXin Li // CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[BASETMP]], i8* [[SEL]]) 64*67e74705SXin Li // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LD]], 1 65*67e74705SXin Li // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** 66*67e74705SXin Li // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8* 67*67e74705SXin Li // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* [[BASETMP]], i8* [[SEL]], i32 [[ADD]]) 68*67e74705SXin Li test2_helper().dyn++; 69*67e74705SXin Li 70*67e74705SXin Li // CHECK: [[BASE:%.*]] = call [[A]]* @test2_helper() 71*67e74705SXin Li // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** 72*67e74705SXin Li // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8* 73*67e74705SXin Li // CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* [[BASETMP]], i8* [[SEL]]) 74*67e74705SXin Li // CHECK-NEXT: [[ADD:%.*]] = mul nsw i32 [[LD]], 10 75*67e74705SXin Li // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** 76*67e74705SXin Li // CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8* 77*67e74705SXin Li // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* [[BASETMP]], i8* [[SEL]], i32 [[ADD]]) 78*67e74705SXin Li test2_helper().dyn *= 10; 79*67e74705SXin Li} 80*67e74705SXin Li 81*67e74705SXin Li// Test aggregate initialization from property reads. 82*67e74705SXin Li// Not crashing is good enough for the property-specific test. 83*67e74705SXin Listruct test3_struct { int x,y,z; }; 84*67e74705SXin Listruct test3_nested { struct test3_struct t; }; 85*67e74705SXin Li@interface test3_object 86*67e74705SXin Li@property struct test3_struct s; 87*67e74705SXin Li@end 88*67e74705SXin Livoid test3(test3_object *p) { 89*67e74705SXin Li struct test3_struct array[1] = { p.s }; 90*67e74705SXin Li struct test3_nested agg = { p.s }; 91*67e74705SXin Li} 92*67e74705SXin Li 93*67e74705SXin Li// PR8742 94*67e74705SXin Li@interface Test4 {} 95*67e74705SXin Li@property float f; 96*67e74705SXin Li@end 97*67e74705SXin Li// CHECK-LABEL: define void @test4 98*67e74705SXin Livoid test4(Test4 *t) { 99*67e74705SXin Li extern int test4_printf(const char *, ...); 100*67e74705SXin Li // CHECK: [[TMP:%.*]] = call float {{.*}} @objc_msgSend 101*67e74705SXin Li // CHECK-NEXT: [[EXT:%.*]] = fpext float [[TMP]] to double 102*67e74705SXin Li // CHECK-NEXT: call i32 (i8*, ...) @test4_printf(i8* {{.*}}, double [[EXT]]) 103*67e74705SXin Li // CHECK-NEXT: ret void 104*67e74705SXin Li test4_printf("%.2f", t.f); 105*67e74705SXin Li} 106*67e74705SXin Li 107*67e74705SXin Li@interface Test5 { 108*67e74705SXin Li unsigned _x : 5; 109*67e74705SXin Li} 110*67e74705SXin Li@property unsigned x; 111*67e74705SXin Li@end 112*67e74705SXin Li@implementation Test5 113*67e74705SXin Li@synthesize x = _x; 114*67e74705SXin Li@end 115*67e74705SXin Li 116*67e74705SXin Li// rdar://problem/10410531 117*67e74705SXin Li@interface Test6 118*67e74705SXin Li@property void (*prop)(void); 119*67e74705SXin Li@end 120*67e74705SXin Li 121*67e74705SXin Livoid test6_func(void); 122*67e74705SXin Livoid test6(Test6 *a) { 123*67e74705SXin Li a.prop = test6_func; 124*67e74705SXin Li} 125*67e74705SXin Li 126*67e74705SXin Li// rdar://problem/10507455 127*67e74705SXin Li@interface Test7 128*67e74705SXin Li@property unsigned char x; 129*67e74705SXin Li@end 130*67e74705SXin Livoid test7(Test7 *t) { 131*67e74705SXin Li t.x &= 2; 132*67e74705SXin Li t.x |= 5; 133*67e74705SXin Li t.x ^= 8; 134*67e74705SXin Li} 135*67e74705SXin Li// CHECK: define void @test7([[TEST7:%.*]]* 136*67e74705SXin Li// CHECK: [[T:%.*]] = alloca [[TEST7]]*, 137*67e74705SXin Li// CHECK-NEXT: store 138*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align 139*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 140*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 141*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast 142*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 143*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2 144*67e74705SXin Li// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 145*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 146*67e74705SXin Li// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 147*67e74705SXin Li// CHECK-NEXT: call void bitcast 148*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align 149*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 150*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 151*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast 152*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 153*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5 154*67e74705SXin Li// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 155*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 156*67e74705SXin Li// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 157*67e74705SXin Li// CHECK-NEXT: call void bitcast 158*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align 159*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 160*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 161*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast 162*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 163*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8 164*67e74705SXin Li// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 165*67e74705SXin Li// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES 166*67e74705SXin Li// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* 167*67e74705SXin Li// CHECK-NEXT: call void bitcast 168*67e74705SXin Li// CHECK-NEXT: ret void 169