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