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