Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -emit-llvm %s -o %t-64.ll
      2 // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
      3 
      4 // See commentary in test/CodeGenObjC/block-var-layout.m, from which
      5 // this is largely cloned.
      6 
      7 struct S {
      8     int i1;
      9     id o1;
     10     struct V {
     11      int i2;
     12      id o2;
     13     } v1;
     14     int i3;
     15     id o3;
     16 };
     17 
     18 __weak id wid;
     19 void x(id y) {}
     20 void y(int a) {}
     21 
     22 extern id opaque_id();
     23 
     24 void f() {
     25     __block int byref_int = 0;
     26     char ch = 'a';
     27     char ch1 = 'b';
     28     char ch2 = 'c';
     29     short sh = 2;
     30     const id bar = (id) opaque_id();
     31     id baz = 0;
     32     __strong void *strong_void_sta;
     33     __block id byref_bab = (id)0;
     34     __block void *bl_var1;
     35     int i; double dob;
     36 
     37 // Test 1
     38 // byref int, short, char, char, char, id, id, strong void*, byref id
     39 // 01 35 10 00
     40 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
     41     void (^b)() = ^{
     42         byref_int = sh + ch+ch1+ch2 ;
     43         x(bar);
     44         x(baz);
     45         x((id)strong_void_sta);
     46         x(byref_bab);
     47     };    
     48     b();
     49 
     50 // Test 2
     51 // byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
     52 // 01 36 10 00
     53 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
     54     void (^c)() = ^{
     55         byref_int = sh + ch+ch1+ch2 ;
     56         x(bar);
     57         x(baz);
     58         x((id)strong_void_sta);
     59         x(wid);
     60         bl_var1 = 0;
     61         x(byref_bab);
     62     };    
     63     c();
     64 
     65 // Test 3
     66 // byref int, short, char, char, char, id, id, byref void*, int, double, byref id
     67 // 01 34 11 30 00
     68 // FIXME: we'd get a better format here if we sorted by scannability, not just alignment
     69 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
     70 void (^d)() = ^{
     71         byref_int = sh + ch+ch1+ch2 ;
     72         x(bar);
     73         x(baz);
     74         x(wid);
     75         bl_var1 = 0; 
     76         y(i + dob);
     77         x(byref_bab);
     78     };    
     79     d();
     80 
     81 // Test4
     82 // struct S (int, id, int, id, int, id)
     83 // 01 41 11 11
     84 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
     85     struct S s2;
     86     void (^e)() = ^{
     87         x(s2.o1);
     88     };    
     89     e();
     90 }
     91 
     92 // Test 5 (unions/structs and their nesting):
     93 void Test5() {
     94   struct S5 {
     95     int i1;
     96     id o1;
     97     struct V {
     98      int i2;
     99      id o2;
    100     } v1;
    101     int i3;
    102     union UI {
    103         void * i1;
    104         id o1;
    105         int i3;
    106         id o3;
    107     }ui;
    108   };
    109 
    110   union U {
    111         void * i1;
    112         id o1;
    113         int i3;
    114         id o3;
    115   }ui;
    116 
    117   struct S5 s2;
    118   union U u2;
    119 
    120 // struct s2 (int, id, int, id, int, id?), union u2 (id?)
    121 // 01 41 11 12 70 00
    122 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [6 x i8] c"\01A\11\12p\00"
    123   void (^c)() = ^{
    124     x(s2.ui.o1);
    125     x(u2.o1);
    126   };
    127   c();
    128 
    129 }
    130 
    131 // rdar: //8417746
    132 void CFRelease(id);
    133 void notifyBlock(id dependentBlock) {
    134  id singleObservationToken;
    135  id token;
    136  void (^b)();
    137 
    138 // id, id, void(^)()
    139 // 01 33 00
    140 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
    141  void (^wrapperBlock)() = ^() {
    142      CFRelease(singleObservationToken);
    143      CFRelease(singleObservationToken);
    144      CFRelease(token);
    145      CFRelease(singleObservationToken);
    146      b();
    147     };
    148  wrapperBlock();
    149 }
    150 
    151 void test_empty_block() {
    152 // 01 00
    153 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
    154  void (^wrapperBlock)() = ^() {
    155     };
    156  wrapperBlock();
    157 }
    158