403 lines · plain
1// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout2// RUN: FileCheck --input-file=%t-32.layout %s3 4void x(id y) {}5void y(int a) {}6 7extern id opaque_id(void);8 9void f(void) {10 __weak id wid;11 __block int byref_int = 0;12 char ch = 'a';13 char ch1 = 'b';14 char ch2 = 'c';15 short sh = 2;16 const id bar = (id) opaque_id();17 id baz = 0;18 __strong id strong_void_sta;19 __block id byref_bab = (id)0;20 __block id bl_var1;21 int i; double dob;22 23// The patterns here are a sequence of bytes, each saying first how24// many sizeof(void*) chunks to skip (high nibble) and then how many25// to scan (low nibble). A zero byte says that we've reached the end26// of the pattern.27//28// All of these patterns start with 01 3x because the block header on29// LP64 consists of an isa pointer (which we're supposed to scan for30// some reason) followed by three words (2 ints, a function pointer,31// and a descriptor pointer).32 33// Test 134// CHECK: Inline block variable layout: 0x0320, BL_STRONG:3, BL_BYREF:2, BL_OPERATOR:035 void (^b)(void) = ^{36 byref_int = sh + ch+ch1+ch2 ;37 x(bar);38 x(baz);39 x((id)strong_void_sta);40 x(byref_bab);41 }; 42 b();43 44// Test 245// CHECK: Inline block variable layout: 0x0331, BL_STRONG:3, BL_BYREF:3, BL_WEAK:1, BL_OPERATOR:046 void (^c)(void) = ^{47 byref_int = sh + ch+ch1+ch2 ;48 x(bar);49 x(baz);50 x((id)strong_void_sta);51 x(wid);52 bl_var1 = 0;53 x(byref_bab);54 }; 55}56 57@class NSString, NSNumber;58void g(void) {59 NSString *foo;60 NSNumber *bar;61 unsigned int bletch;62 __weak id weak_delegate;63 unsigned int i;64 NSString *y;65 NSString *z;66// CHECK: Inline block variable layout: 0x0401, BL_STRONG:4, BL_WEAK:1, BL_OPERATOR:067 void (^c)(void) = ^{68 int j = i + bletch;69 x(foo);70 x(bar);71 x(weak_delegate);72 x(y);73 x(z); 74 };75 c();76}77 78// Test 5 (unions/structs and their nesting):79void h(void) {80 struct S5 {81 int i1;82 __unsafe_unretained id o1;83 struct V {84 int i2;85 __unsafe_unretained id o2;86 } v1;87 int i3;88 union UI {89 void * i1;90 __unsafe_unretained id o1;91 int i3;92 __unsafe_unretained id o3;93 }ui;94 };95 96 union U {97 void * i1;98 __unsafe_unretained id o1;99 int i3;100 __unsafe_unretained id o3;101 }ui;102 103 struct S5 s2;104 union U u2;105 __block id block_id;106 107/**108block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1, 109 BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0110*/111// CHECK: Block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0112 void (^c)(void) = ^{113 x(s2.ui.o1);114 x(u2.o1);115 block_id = 0;116 };117 c();118}119 120// Test for array of stuff.121void arr1(void) {122 struct S {123 __unsafe_unretained id unsafe_unretained_var[4];124 } imported_s;125 126// CHECK: Block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0127 void (^c)(void) = ^{128 x(imported_s.unsafe_unretained_var[2]);129 }; 130 131 c();132}133 134// Test2 for array of stuff.135void arr2(void) {136 struct S {137 int a;138 __unsafe_unretained id unsafe_unretained_var[4];139 } imported_s;140 141// CHECK: Block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0142 void (^c)(void) = ^{143 x(imported_s.unsafe_unretained_var[2]);144 }; 145 146 c();147}148 149// Test3 for array of stuff.150void arr3(void) {151 struct S {152 int a;153 __unsafe_unretained id unsafe_unretained_var[0];154 } imported_s;155 156// CHECK: Block variable layout: BL_OPERATOR:0157 void (^c)(void) = ^{158 int i = imported_s.a;159 }; 160 161 c();162}163 164 165// Test4 for array of stuff.166@class B;167void arr4(void) {168 struct S {169 struct s0 {170 __unsafe_unretained id s_f0;171 __unsafe_unretained id s_f1;172 } f0;173 174 __unsafe_unretained id f1;175 176 struct s1 {177 int *f0;178 __unsafe_unretained B *f1;179 } f4[2][2];180 } captured_s;181 182// CHECK: Block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0183 void (^c)(void) = ^{184 id i = captured_s.f0.s_f1;185 };186 187 c();188}189 190// Test1 bitfield in cpatured aggregate.191void bf1(void) {192 struct S {193 int flag : 25;194 int flag1: 7;195 int flag2 :1;196 int flag3: 7;197 int flag4: 24;198 } s;199 200// CHECK: Block variable layout: BL_OPERATOR:0201 int (^c)(void) = ^{202 return s.flag;203 };204 c();205}206 207// Test2 bitfield in cpatured aggregate.208void bf2(void) {209 struct S {210 int flag : 1;211 } s;212 213// CHECK: Block variable layout: BL_OPERATOR:0214 int (^c)(void) = ^{215 return s.flag;216 };217 c();218}219 220// Test3 bitfield in cpatured aggregate.221void bf3(void) {222 223 struct {224 unsigned short _reserved : 16;225 226 unsigned char _draggedNodesAreDeletable: 1;227 unsigned char _draggedOutsideOutlineView : 1;228 unsigned char _adapterRespondsTo_addRootPaths : 1;229 unsigned char _adapterRespondsTo_moveDataNodes : 1;230 unsigned char _adapterRespondsTo_removeRootDataNode : 1;231 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;232 unsigned char _adapterRespondsTo_selectDataNode : 1;233 unsigned char _adapterRespondsTo_textDidEndEditing : 1;234 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;235 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;236 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;237 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;238 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;239 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;240 241 unsigned int _filler : 32;242 } _flags;243 244// CHECK: Block variable layout: BL_OPERATOR:0245 unsigned char (^c)(void) = ^{246 return _flags._draggedNodesAreDeletable;247 };248 249 c();250}251 252// Test4 unnamed bitfield253void bf4(void) {254 255 struct {256 unsigned short _reserved : 16;257 258 unsigned char _draggedNodesAreDeletable: 1;259 unsigned char _draggedOutsideOutlineView : 1;260 unsigned char _adapterRespondsTo_addRootPaths : 1;261 unsigned char _adapterRespondsTo_moveDataNodes : 1;262 unsigned char _adapterRespondsTo_removeRootDataNode : 1;263 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;264 unsigned char _adapterRespondsTo_selectDataNode : 1;265 unsigned char _adapterRespondsTo_textDidEndEditing : 1;266 267 unsigned long long : 64;268 269 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;270 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;271 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;272 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;273 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;274 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;275 276 unsigned int _filler : 32;277 } _flags;278 279// CHECK: Block variable layout: BL_OPERATOR:0280 unsigned char (^c)(void) = ^{281 return _flags._draggedNodesAreDeletable;282 };283 284 c();285}286 287 288 289// Test5 unnamed bitfield.290void bf5(void) {291 struct {292 unsigned char flag : 1;293 unsigned int : 32;294 unsigned char flag1 : 1;295 } _flags;296 297// CHECK: Block variable layout: BL_OPERATOR:0298 unsigned char (^c)(void) = ^{299 return _flags.flag;300 };301 302 c();303}304 305 306// Test6 0 length bitfield.307void bf6(void) {308 struct {309 unsigned char flag : 1;310 unsigned int : 0;311 unsigned char flag1 : 1;312 } _flags;313 314// CHECK: Block variable layout: BL_OPERATOR:0315 unsigned char (^c)(void) = ^{316 return _flags.flag;317 };318 319 c();320}321 322// Test7 large number of captured variables.323void Test7(void) {324 __weak id wid;325 __weak id wid1, wid2, wid3, wid4;326 __weak id wid5, wid6, wid7, wid8;327 __weak id wid9, wid10, wid11, wid12;328 __weak id wid13, wid14, wid15, wid16;329 const id bar = (id) opaque_id();330// CHECK: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0331 void (^b)(void) = ^{332 x(bar);333 x(wid1);334 x(wid2);335 x(wid3);336 x(wid4);337 x(wid5);338 x(wid6);339 x(wid7);340 x(wid8);341 x(wid9);342 x(wid10);343 x(wid11);344 x(wid12);345 x(wid13);346 x(wid14);347 x(wid15);348 x(wid16);349 }; 350}351 352 353// Test 8 very large number of captured variables.354void Test8(void) {355__weak id wid;356 __weak id wid1, wid2, wid3, wid4;357 __weak id wid5, wid6, wid7, wid8;358 __weak id wid9, wid10, wid11, wid12;359 __weak id wid13, wid14, wid15, wid16;360 __weak id w1, w2, w3, w4;361 __weak id w5, w6, w7, w8;362 __weak id w9, w10, w11, w12;363 __weak id w13, w14, w15, w16;364 const id bar = (id) opaque_id();365// CHECK: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0366 void (^b)(void) = ^{367 x(bar);368 x(wid1);369 x(wid2);370 x(wid3);371 x(wid4);372 x(wid5);373 x(wid6);374 x(wid7);375 x(wid8);376 x(wid9);377 x(wid10);378 x(wid11);379 x(wid12);380 x(wid13);381 x(wid14);382 x(wid15);383 x(wid16);384 x(w1);385 x(w2);386 x(w3);387 x(w4);388 x(w5);389 x(w6);390 x(w7);391 x(w8);392 x(w9);393 x(w10);394 x(w11);395 x(w12);396 x(w13);397 x(w14);398 x(w15);399 x(w16);400 x(wid);401 }; 402}403