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 4// See commentary in test/CodeGenObjC/block-var-layout.m, from which 5// this is largely cloned. 6 7struct 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; 19void x(id y) {} 20void y(int a) {} 21 22extern id opaque_id(); 23 24void 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: block variable layout for block: 0x01, 0x35, 0x10, 0x00 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: 0x01, 0x36, 0x10, 0x00 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// CHECK: block variable layout for block: 0x01, 0x35, 0x30, 0x00 69void (^d)() = ^{ 70 byref_int = sh + ch+ch1+ch2 ; 71 x(bar); 72 x(baz); 73 x(wid); 74 bl_var1 = 0; 75 y(i + dob); 76 x(byref_bab); 77 }; 78 d(); 79 80// Test4 81// struct S (int, id, int, id, int, id) 82// 01 41 11 11 00 83// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00 84 struct S s2; 85 void (^e)() = ^{ 86 x(s2.o1); 87 }; 88 e(); 89} 90 91// Test 5 (unions/structs and their nesting): 92void Test5() { 93 struct S5 { 94 int i1; 95 id o1; 96 struct V { 97 int i2; 98 id o2; 99 } v1; 100 int i3; 101 union UI { 102 void * i1; 103 id o1; 104 int i3; 105 id o3; 106 }ui; 107 }; 108 109 union U { 110 void * i1; 111 id o1; 112 int i3; 113 id o3; 114 }ui; 115 116 struct S5 s2; 117 union U u2; 118 119// struct s2 (int, id, int, id, int, id?), union u2 (id?) 120// 01 41 11 12 00 121// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00 122 void (^c)() = ^{ 123 x(s2.ui.o1); 124 x(u2.o1); 125 }; 126 c(); 127 128} 129 130void CFRelease(id); 131void notifyBlock(id dependentBlock) { 132 id singleObservationToken; 133 id token; 134 void (^b)(); 135 136// id, id, void(^)() 137// 01 33 00 138// CHECK: block variable layout for block: 0x01, 0x33, 0x00 139 void (^wrapperBlock)() = ^() { 140 CFRelease(singleObservationToken); 141 CFRelease(singleObservationToken); 142 CFRelease(token); 143 CFRelease(singleObservationToken); 144 b(); 145 }; 146 wrapperBlock(); 147} 148 149void test_empty_block() { 150// 01 00 151// CHECK: block variable layout for block: 0x01, 0x30, 0x00 152 void (^wrapperBlock)() = ^() { 153 }; 154 wrapperBlock(); 155} 156