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 9struct 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; 21void x(id y) {} 22void y(int a) {} 23 24extern id opaque_id(); 25 26void 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 71void (^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): 94void 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 133void CFRelease(id); 134void 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 152void test_empty_block() { 153// 01 00 154// CHECK: block variable layout for block: 0x01, 0x30, 0x00 155 void (^wrapperBlock)() = ^() { 156 }; 157 wrapperBlock(); 158} 159