brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · c8215f2 Raw
245 lines · plain
1// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s2 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 Root14- (int)getInt __attribute__((objc_direct));15@property(direct, readonly) int intProperty;16@property(direct, readonly) int intProperty2;17@property(direct, readonly) id objectProperty;18@end19 20@implementation Root21// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty2]"22- (int)intProperty2 {23  return 42;24}25 26// CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"(27- (int)getInt __attribute__((objc_direct)) {28  // loading parameters29  // CHECK-LABEL: entry:30  // CHECK-NEXT: [[RETVAL:%.*]] = alloca31  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,32  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],33 34  // self nil-check35  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],36  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null37  // CHECK-NEXT: br i1 [[NILCHECK]],38 39  // setting return value to nil40  // CHECK-LABEL: objc_direct_method.self_is_nil:41  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,42  // CHECK-NEXT: br label43 44  // set value45  // CHECK-LABEL: objc_direct_method.cont:46  // CHECK: store{{.*}}[[RETVAL]],47  // CHECK-NEXT: br label48 49  // return50  // CHECK-LABEL: return:51  // CHECK: {{%.*}} = load{{.*}}[[RETVAL]],52  // CHECK-NEXT: ret53  return 42;54}55 56// CHECK-LABEL: define hidden i32 @"\01+[Root classGetInt]"(57+ (int)classGetInt __attribute__((objc_direct)) {58  // loading parameters59  // CHECK-LABEL: entry:60  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,61  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],62 63  // [self self]64  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],65  // CHECK-NEXT: [[SELFSEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_66  // CHECK-NEXT: [[SELF0:%.*]] = call {{.*}} @objc_msgSend67  // CHECK-NEXT: store ptr [[SELF0]], ptr [[SELFADDR]],68 69  // return70  // CHECK-NEXT: ret71  return 42;72}73 74// CHECK-LABEL: define hidden i64 @"\01-[Root getComplex]"(75- (struct my_complex_struct)getComplex __attribute__((objc_direct)) {76  // loading parameters77  // CHECK-LABEL: entry:78  // CHECK-NEXT: [[RETVAL:%.*]] = alloca79  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,80  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],81 82  // self nil-check83  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],84  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null85  // CHECK-NEXT: br i1 [[NILCHECK]],86 87  // setting return value to nil88  // CHECK-LABEL: objc_direct_method.self_is_nil:89  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,90  // CHECK-NEXT: br label91 92  // set value93  // CHECK-LABEL: objc_direct_method.cont:94  // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RETVAL]],95  // CHECK-NEXT: br label96 97  // return98  // CHECK-LABEL: return:99  // CHECK-NEXT: {{%.*}} = load{{.*}}[[RETVAL]],100  // CHECK-NEXT: ret101  struct my_complex_struct st = {.a = 42};102  return st;103}104 105// CHECK-LABEL: define hidden i64 @"\01+[Root classGetComplex]"(106+ (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) {107  struct my_complex_struct st = {.a = 42};108  return st;109  // CHECK: ret i64110}111 112// CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"(113- (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) {114  // CHECK: ptr dead_on_unwind noalias writable sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]],115 116  // loading parameters117  // CHECK-LABEL: entry:118  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,119  // CHECK-NEXT: store ptr %{{.*}}, ptr [[SELFADDR]],120 121  // self nil-check122  // CHECK-NEXT: [[SELF:%.*]] = load ptr, ptr [[SELFADDR]],123  // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq ptr [[SELF]], null124  // CHECK-NEXT: br i1 [[NILCHECK]],125 126  // setting return value to nil127  // CHECK-LABEL: objc_direct_method.self_is_nil:128  // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RETVAL]], i8 0,129  // CHECK-NEXT: br label130 131  // set value132  // CHECK-LABEL: objc_direct_method.cont:133  // CHECK: br label134 135  // return136  // CHECK-LABEL: return:137  // CHECK: ret void138  struct my_aggregate_struct st = {.a = 42};139  return st;140}141 142// CHECK-LABEL: define hidden void @"\01+[Root classGetAggregate]"(143+ (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {144  struct my_aggregate_struct st = {.a = 42};145  return st;146  // CHECK: ret void147}148 149// CHECK-LABEL: define hidden void @"\01-[Root accessCmd]"(150- (void)accessCmd __attribute__((objc_direct)) {151  // CHECK-LABEL: entry:152  // CHECK-NEXT: [[SELFADDR:%.*]] = alloca ptr,153  // CHECK-NEXT: [[CMDVAL:%_cmd]] = alloca ptr,154 155  // loading the _cmd selector156  // CHECK-LABEL: objc_direct_method.cont:157  // CHECK-NEXT: [[CMD1:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_158  // CHECK-NEXT: store ptr [[CMD1]], ptr [[CMDVAL]],159  SEL sel = _cmd;160}161 162@end163// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]"164 165// Check the synthesized objectProperty calls objc_getProperty(); this also166// checks that the synthesized method passes undef for the `cmd` argument.167// CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(168// CHECK-LABEL: objc_direct_method.cont:169// CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,170// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef 8, {{.*}})171 172@interface Foo : Root {173  id __strong _cause_cxx_destruct;174}175@property(nonatomic, readonly, direct) int getDirect_setDynamic;176@property(nonatomic, readonly) int getDynamic_setDirect;177@end178 179@interface Foo ()180@property(nonatomic, readwrite) int getDirect_setDynamic;181@property(nonatomic, readwrite, direct) int getDynamic_setDirect;182- (int)directMethodInExtension __attribute__((objc_direct));183@end184 185@interface Foo (Cat)186- (int)directMethodInCategory __attribute__((objc_direct));187@end188 189__attribute__((objc_direct_members))190@implementation Foo191// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInExtension]"(192- (int)directMethodInExtension {193  return 42;194}195// CHECK-LABEL: define hidden i32 @"\01-[Foo getDirect_setDynamic]"(196// CHECK-LABEL: define internal void @"\01-[Foo setGetDirect_setDynamic:]"(197// CHECK-LABEL: define internal i32 @"\01-[Foo getDynamic_setDirect]"(198// CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"(199// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"(200@end201 202@implementation Foo (Cat)203// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategory]"(204- (int)directMethodInCategory {205  return 42;206}207// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategoryNoDecl]"(208- (int)directMethodInCategoryNoDecl __attribute__((objc_direct)) {209  return 42;210}211@end212 213int useRoot(Root *r) {214  // CHECK-LABEL: define{{.*}} i32 @useRoot215  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root getInt]"216  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty]"217  // CHECK: %{{[^ ]*}} = call i32  @"\01-[Root intProperty2]"218  return [r getInt] + [r intProperty] + [r intProperty2];219}220 221int useFoo(Foo *f) {222  // CHECK-LABEL: define{{.*}} i32 @useFoo223  // CHECK: call void @"\01-[Foo setGetDynamic_setDirect:]"224  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo getDirect_setDynamic]"225  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInExtension]"226  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategory]"227  // CHECK: %{{[^ ]*}} = call i32 @"\01-[Foo directMethodInCategoryNoDecl]"228  [f setGetDynamic_setDirect:1];229  return [f getDirect_setDynamic] +230         [f directMethodInExtension] +231         [f directMethodInCategory] +232         [f directMethodInCategoryNoDecl];233}234 235__attribute__((objc_root_class))236@interface RootDeclOnly237@property(direct, readonly) int intProperty;238@end239 240int useRootDeclOnly(RootDeclOnly *r) {241  // CHECK-LABEL: define{{.*}} i32 @useRootDeclOnly242  // CHECK: %{{[^ ]*}} = call i32 @"\01-[RootDeclOnly intProperty]"243  return [r intProperty];244}245