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