1// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s 2 3struct my_complex_struct { 4 int a, b; 5}; 6 7struct my_aggregate_struct { 8 int a, b; 9 char buf[128]; 10}; 11 12__attribute__((objc_root_class)) 13@interface Root 14@end 15 16@implementation Root 17// CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"( 18- (int)getInt __attribute__((objc_direct)) { 19 // loading parameters 20 // CHECK-LABEL: entry: 21 // CHECK-NEXT: [[RETVAL:%.*]] = alloca 22 // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*, 23 // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*, 24 // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]], 25 // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]], 26 27 // self nil-check 28 // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]], 29 // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null 30 // CHECK-NEXT: br i1 [[NILCHECK]], 31 32 // setting return value to nil 33 // CHECK-LABEL: objc_direct_method.self_is_nil: 34 // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]] 35 // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0, 36 // CHECK-NEXT: br label 37 38 // set value 39 // CHECK-LABEL: objc_direct_method.cont: 40 // CHECK: store{{.*}}[[RETVAL]], 41 // CHECK-NEXT: br label 42 43 // return 44 // CHECK-LABEL: return: 45 // CHECK: {{%.*}} = load{{.*}}[[RETVAL]], 46 // CHECK-NEXT: ret 47 return 42; 48} 49 50// CHECK-LABEL: define hidden i32 @"\01+[Root classGetInt]"( 51+ (int)classGetInt __attribute__((objc_direct)) { 52 // loading parameters 53 // CHECK-LABEL: entry: 54 // CHECK-NEXT: [[SELFADDR:%.*]] = alloca i8*, 55 // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*, 56 // CHECK-NEXT: store i8* %{{.*}}, i8** [[SELFADDR]], 57 // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]], 58 59 // [self self] 60 // CHECK-NEXT: [[SELF:%.*]] = load i8*, i8** [[SELFADDR]], 61 // CHECK-NEXT: [[SELFSEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ 62 // CHECK-NEXT: [[SELF0:%.*]] = call {{.*}} @objc_msgSend 63 // CHECK-NEXT: store i8* [[SELF0]], i8** [[SELFADDR]], 64 65 // return 66 // CHECK-NEXT: ret 67 return 42; 68} 69 70// CHECK-LABEL: define hidden i64 @"\01-[Root getComplex]"( 71- (struct my_complex_struct)getComplex __attribute__((objc_direct)) { 72 // loading parameters 73 // CHECK-LABEL: entry: 74 // CHECK-NEXT: [[RETVAL:%.*]] = alloca 75 // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*, 76 // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*, 77 // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]], 78 // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]], 79 80 // self nil-check 81 // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]], 82 // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null 83 // CHECK-NEXT: br i1 [[NILCHECK]], 84 85 // setting return value to nil 86 // CHECK-LABEL: objc_direct_method.self_is_nil: 87 // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]] 88 // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0, 89 // CHECK-NEXT: br label 90 91 // set value 92 // CHECK-LABEL: objc_direct_method.cont: 93 // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]] 94 // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RET1]], 95 // CHECK-NEXT: br label 96 97 // return 98 // CHECK-LABEL: return: 99 // CHECK: [[RET2:%.*]] = bitcast{{.*}}[[RETVAL]] 100 // CHECK-NEXT: {{%.*}} = load{{.*}}[[RET2]], 101 // CHECK-NEXT: ret 102 struct my_complex_struct st = {.a = 42}; 103 return st; 104} 105 106// CHECK-LABEL: define hidden i64 @"\01+[Root classGetComplex]"( 107+ (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) { 108 struct my_complex_struct st = {.a = 42}; 109 return st; 110 // CHECK: ret i64 111} 112 113// CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"( 114- (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) { 115 // CHECK: %struct.my_aggregate_struct* noalias sret [[RETVAL:%[^,]*]], 116 117 // loading parameters 118 // CHECK-LABEL: entry: 119 // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*, 120 // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*, 121 // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]], 122 // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]], 123 124 // self nil-check 125 // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]], 126 // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null 127 // CHECK-NEXT: br i1 [[NILCHECK]], 128 129 // setting return value to nil 130 // CHECK-LABEL: objc_direct_method.self_is_nil: 131 // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]] 132 // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0, 133 // CHECK-NEXT: br label 134 135 // set value 136 // CHECK-LABEL: objc_direct_method.cont: 137 // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]] 138 // CHECK: br label 139 140 // return 141 // CHECK-LABEL: return: 142 // CHECK: ret void 143 struct my_aggregate_struct st = {.a = 42}; 144 return st; 145} 146 147// CHECK-LABEL: define hidden void @"\01+[Root classGetAggregate]"( 148+ (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) { 149 struct my_aggregate_struct st = {.a = 42}; 150 return st; 151 // CHECK: ret void 152} 153 154@end 155 156@interface Foo : Root { 157 id __strong _cause_cxx_destruct; 158} 159@property(nonatomic, readonly, direct) int getDirect_setDynamic; 160@property(nonatomic, readonly) int getDynamic_setDirect; 161@end 162 163@interface Foo () 164@property(nonatomic, readwrite) int getDirect_setDynamic; 165@property(nonatomic, readwrite, direct) int getDynamic_setDirect; 166@end 167 168__attribute__((objc_direct_members)) 169@implementation Foo 170// CHECK-LABEL: define hidden i32 @"\01-[Foo getDirect_setDynamic]"( 171// CHECK-LABEL: define internal void @"\01-[Foo setGetDirect_setDynamic:]"( 172// CHECK-LABEL: define internal i32 @"\01-[Foo getDynamic_setDirect]"( 173// CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"( 174// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"( 175@end 176