133 lines · plain
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -emit-llvm %s -o - | FileCheck %s2 3@interface Test04- (void) setValue: (id) x;5@end6void test0(Test0 *t0, id value) {7 t0.value = value;8}9// CHECK-LABEL: define{{.*}} void @test0(10// CHECK: call void @llvm.objc.storeStrong11// CHECK: call void @llvm.objc.storeStrong12// CHECK: @objc_msgSend13// CHECK: call void @llvm.objc.storeStrong(14// CHECK: call void @llvm.objc.storeStrong(15 16struct S1 { Class isa; };17@interface Test118@property (nonatomic, strong) __attribute__((NSObject)) struct S1 *pointer;19@end20@implementation Test121@synthesize pointer;22@end23// The getter should be a simple load.24// CHECK: define internal ptr @"\01-[Test1 pointer]"(25// CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 026// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T1]], align 827// CHECK-NEXT: ret ptr [[T3]]28 29// The setter should be using objc_setProperty.30// CHECK: define internal void @"\01-[Test1 setPointer:]"(31// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}32// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext false)33// CHECK-NEXT: ret void34 35 36@interface Test2 {37@private38 Class _theClass;39}40@property (copy) Class theClass;41@end42 43static Class theGlobalClass;44@implementation Test245@synthesize theClass = _theClass;46- (void) test {47 _theClass = theGlobalClass;48}49@end50// CHECK: define internal void @"\01-[Test2 test]"(51// CHECK: [[T0:%.*]] = load ptr, ptr @theGlobalClass, align 852// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr53// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 054// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T3]], ptr [[T0]]) [[NUW:#[0-9]+]]55// CHECK-NEXT: ret void56 57// CHECK: define internal ptr @"\01-[Test2 theClass]"(58// CHECK: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef 0, i1 noundef zeroext true)59// CHECK-NEXT: ret ptr [[T0]]60 61// CHECK: define internal void @"\01-[Test2 setTheClass:]"(62// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}63// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)64// CHECK-NEXT: ret void65 66// CHECK: define internal void @"\01-[Test2 .cxx_destruct]"(67// CHECK: [[T0:%.*]] = load ptr, ptr68// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 069// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T2]], ptr null) [[NUW]]70// CHECK-NEXT: ret void71 72@interface Test373@property id copyMachine;74@end75 76void test3(Test3 *t) {77 id x = t.copyMachine;78 x = [t copyMachine];79}80// CHECK: define{{.*}} void @test3(ptr81// Prologue.82// CHECK: [[T:%.*]] = alloca ptr,83// CHECK-NEXT: [[X:%.*]] = alloca ptr,84// Property access.85// CHECK: [[T0:%.*]] = load ptr, ptr [[T]],86// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES87// CHECK-NEXT: [[T2:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])88// CHECK-NEXT: store ptr [[T2]], ptr [[X]],89// Message send.90// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[T]],91// CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES92// CHECK-NEXT: [[T2:%.*]] = call ptr @objc_msgSend(ptr noundef [[T0]], ptr noundef [[SEL]])93// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[X]],94// CHECK-NEXT: store ptr [[T2]], ptr [[X]],95// CHECK-NEXT: call void @llvm.objc.release(ptr [[T3]])96// Epilogue.97// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr null)98// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T]], ptr null)99// CHECK-NEXT: ret void100 101@implementation Test3102- (id) copyMachine {103 extern id test3_helper(void);104 return test3_helper();105}106// CHECK: define internal ptr @"\01-[Test3 copyMachine]"(107// CHECK: [[T0:%.*]] = call ptr @test3_helper()108// CHECK-NEXT: [[T1:%.*]] = notail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]])109// CHECK-NEXT: ret ptr [[T1]]110- (void) setCopyMachine: (id) x {}111@end112 113// When synthesizing a property that's declared in multiple protocols, ensure114// that the setter is emitted if any of these declarations is readwrite.115@protocol ABC116@property (copy, nonatomic, readonly) Test3 *someId;117@end118@protocol ABC__Mutable <ABC>119@property (copy, nonatomic, readwrite) Test3 *someId;120@end121 122@interface ABC_Class <ABC, ABC__Mutable>123@end124 125@implementation ABC_Class126@synthesize someId = _someId;127// CHECK: define internal ptr @"\01-[ABC_Class someId]"128// CHECK: define internal void @"\01-[ABC_Class setSomeId:]"(129@end130 131 132// CHECK: attributes [[NUW]] = { nounwind }133