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