402 lines · plain
1// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout2// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.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// Inline instruction for block variable layout: 0x0320 (3 strong 2 byref)35// CHECK-LP64: Inline block variable layout: 0x0320, BL_STRONG:3, BL_BYREF:2, BL_OPERATOR:036 void (^b)(void) = ^{37 byref_int = sh + ch+ch1+ch2 ;38 x(bar);39 x(baz);40 x((id)strong_void_sta);41 x(byref_bab);42 }; 43 b();44 45// Test 246// Inline instruction for block variable layout: 0x0331 (3 strong 3 byref 1 weak)47// CHECK-LP64: Inline block variable layout: 0x0331, BL_STRONG:3, BL_BYREF:3, BL_WEAK:1, BL_OPERATOR:048 void (^c)(void) = ^{49 byref_int = sh + ch+ch1+ch2 ;50 x(bar);51 x(baz);52 x((id)strong_void_sta);53 x(wid);54 bl_var1 = 0;55 x(byref_bab);56 }; 57}58 59@class NSString, NSNumber;60void g(void) {61 NSString *foo;62 NSNumber *bar;63 unsigned int bletch;64 __weak id weak_delegate;65 unsigned int i;66 NSString *y;67 NSString *z;68// Inline instruction for block variable layout: 0x0401 (4 strong 0 byref 1 weak)69// CHECK-LP64: Inline block variable layout: 0x0401, BL_STRONG:4, BL_WEAK:1, BL_OPERATOR:070 void (^c)(void) = ^{71 int j = i + bletch;72 x(foo);73 x(bar);74 x(weak_delegate);75 x(y);76 x(z); 77 };78 c();79}80 81// Test 5 (unions/structs and their nesting):82void h(void) {83 struct S5 {84 int i1;85 __unsafe_unretained id o1;86 struct V {87 int i2;88 __unsafe_unretained id o2;89 } v1;90 int i3;91 union UI {92 void * i1;93 __unsafe_unretained id o1;94 int i3;95 __unsafe_unretained id o3;96 }ui;97 };98 99 union U {100 void * i1;101 __unsafe_unretained id o1;102 int i3;103 __unsafe_unretained id o3;104 }ui;105 106 struct S5 s2;107 union U u2;108 __block id block_id;109 110// CHECK-LP64: Block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0111 void (^c)(void) = ^{112 x(s2.ui.o1);113 x(u2.o1);114 block_id = 0;115 };116 c();117}118 119// Test for array of stuff.120void arr1(void) {121 struct S {122 __unsafe_unretained id unsafe_unretained_var[4];123 } imported_s;124 125// CHECK-LP64: Block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0126 void (^c)(void) = ^{127 x(imported_s.unsafe_unretained_var[2]);128 }; 129 130 c();131}132 133// Test2 for array of stuff.134void arr2(void) {135 struct S {136 int a;137 __unsafe_unretained id unsafe_unretained_var[4];138 } imported_s;139 140// CHECK-LP64: Block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0141 void (^c)(void) = ^{142 x(imported_s.unsafe_unretained_var[2]);143 }; 144 145 c();146}147 148// Test3 for array of stuff.149void arr3(void) {150 struct S {151 int a;152 __unsafe_unretained id unsafe_unretained_var[0];153 } imported_s;154 155// CHECK-LP64: Block variable layout: BL_OPERATOR:0156 void (^c)(void) = ^{157 int i = imported_s.a;158 }; 159 160 c();161}162 163 164// Test4 for array of stuff.165@class B;166void arr4(void) {167 struct S {168 struct s0 {169 __unsafe_unretained id s_f0;170 __unsafe_unretained id s_f1;171 } f0;172 173 __unsafe_unretained id f1;174 175 struct s1 {176 int *f0;177 __unsafe_unretained B *f1;178 } f4[2][2];179 } captured_s;180 181// CHECK-LP64: 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:0182 void (^c)(void) = ^{183 id i = captured_s.f0.s_f1;184 };185 186 c();187}188 189// Test1 bitfield in cpatured aggregate.190void bf1(void) {191 struct S {192 int flag : 25;193 int flag1: 7;194 int flag2 :1;195 int flag3: 7;196 int flag4: 24;197 } s;198 199// CHECK-LP64: Block variable layout: BL_OPERATOR:0200 int (^c)(void) = ^{201 return s.flag;202 };203 c();204}205 206// Test2 bitfield in cpatured aggregate.207void bf2(void) {208 struct S {209 int flag : 1;210 } s;211 212// CHECK-LP64: Block variable layout: BL_OPERATOR:0213 int (^c)(void) = ^{214 return s.flag;215 };216 c();217}218 219// Test3 bitfield in cpatured aggregate.220void bf3(void) {221 222 struct {223 unsigned short _reserved : 16;224 225 unsigned char _draggedNodesAreDeletable: 1;226 unsigned char _draggedOutsideOutlineView : 1;227 unsigned char _adapterRespondsTo_addRootPaths : 1;228 unsigned char _adapterRespondsTo_moveDataNodes : 1;229 unsigned char _adapterRespondsTo_removeRootDataNode : 1;230 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;231 unsigned char _adapterRespondsTo_selectDataNode : 1;232 unsigned char _adapterRespondsTo_textDidEndEditing : 1;233 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;234 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;235 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;236 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;237 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;238 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;239 240 unsigned int _filler : 32;241 } _flags;242 243// CHECK-LP64: Block variable layout: BL_OPERATOR:0244 unsigned char (^c)(void) = ^{245 return _flags._draggedNodesAreDeletable;246 };247 248 c();249}250 251// Test4 unnamed bitfield252void bf4(void) {253 254 struct {255 unsigned short _reserved : 16;256 257 unsigned char _draggedNodesAreDeletable: 1;258 unsigned char _draggedOutsideOutlineView : 1;259 unsigned char _adapterRespondsTo_addRootPaths : 1;260 unsigned char _adapterRespondsTo_moveDataNodes : 1;261 unsigned char _adapterRespondsTo_removeRootDataNode : 1;262 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;263 unsigned char _adapterRespondsTo_selectDataNode : 1;264 unsigned char _adapterRespondsTo_textDidEndEditing : 1;265 266 unsigned long long : 64;267 268 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;269 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;270 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;271 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;272 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;273 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;274 275 unsigned int _filler : 32;276 } _flags;277 278// CHECK-LP64: Block variable layout: BL_OPERATOR:0279 unsigned char (^c)(void) = ^{280 return _flags._draggedNodesAreDeletable;281 };282 283 c();284}285 286 287 288// Test5 unnamed bitfield.289void bf5(void) {290 struct {291 unsigned char flag : 1;292 unsigned int : 32;293 unsigned char flag1 : 1;294 } _flags;295 296// CHECK-LP64: Block variable layout: BL_OPERATOR:0297 unsigned char (^c)(void) = ^{298 return _flags.flag;299 };300 301 c();302}303 304 305// Test6 0 length bitfield.306void bf6(void) {307 struct {308 unsigned char flag : 1;309 unsigned int : 0;310 unsigned char flag1 : 1;311 } _flags;312 313// CHECK-LP64: Block variable layout: BL_OPERATOR:0314 unsigned char (^c)(void) = ^{315 return _flags.flag;316 };317 318 c();319}320 321// Test7 large number of captured variables.322void Test7(void) {323 __weak id wid;324 __weak id wid1, wid2, wid3, wid4;325 __weak id wid5, wid6, wid7, wid8;326 __weak id wid9, wid10, wid11, wid12;327 __weak id wid13, wid14, wid15, wid16;328 const id bar = (id) opaque_id();329// CHECK-LP64: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0330 void (^b)(void) = ^{331 x(bar);332 x(wid1);333 x(wid2);334 x(wid3);335 x(wid4);336 x(wid5);337 x(wid6);338 x(wid7);339 x(wid8);340 x(wid9);341 x(wid10);342 x(wid11);343 x(wid12);344 x(wid13);345 x(wid14);346 x(wid15);347 x(wid16);348 }; 349}350 351 352// Test 8 very large number of captured variables.353void Test8(void) {354__weak id wid;355 __weak id wid1, wid2, wid3, wid4;356 __weak id wid5, wid6, wid7, wid8;357 __weak id wid9, wid10, wid11, wid12;358 __weak id wid13, wid14, wid15, wid16;359 __weak id w1, w2, w3, w4;360 __weak id w5, w6, w7, w8;361 __weak id w9, w10, w11, w12;362 __weak id w13, w14, w15, w16;363 const id bar = (id) opaque_id();364// CHECK-LP64: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0365 void (^b)(void) = ^{366 x(bar);367 x(wid1);368 x(wid2);369 x(wid3);370 x(wid4);371 x(wid5);372 x(wid6);373 x(wid7);374 x(wid8);375 x(wid9);376 x(wid10);377 x(wid11);378 x(wid12);379 x(wid13);380 x(wid14);381 x(wid15);382 x(wid16);383 x(w1);384 x(w2);385 x(w3);386 x(w4);387 x(w5);388 x(w6);389 x(w7);390 x(w8);391 x(w9);392 x(w10);393 x(w11);394 x(w12);395 x(w13);396 x(w14);397 x(w15);398 x(w16);399 x(wid);400 }; 401}402