Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenObjC / block-var-layout.m
blobc7cd3bf1282426b22f8348ad8ad49aa52a189ac8
1 // RUN: %clang_cc1 -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 -check-prefix CHECK-LP64 --input-file=%t-64.layout %s
4 struct S {
5     int i1;
6     id o1;
7     struct V {
8      int i2;
9      id o2;
10     } v1;
11     int i3;
12     id o3;
15 __weak id wid;
16 void x(id y) {}
17 void y(int a) {}
19 extern id opaque_id(void);
21 void f(void) {
22     __block int byref_int = 0;
23     char ch = 'a';
24     char ch1 = 'b';
25     char ch2 = 'c';
26     short sh = 2;
27     const id bar = (id) opaque_id();
28     id baz = 0;
29     __strong void *strong_void_sta;
30     __block id byref_bab = (id)0;
31     __block void *bl_var1;
32     int i; double dob;
34 // The patterns here are a sequence of bytes, each saying first how
35 // many sizeof(void*) chunks to skip (high nibble) and then how many
36 // to scan (low nibble).  A zero byte says that we've reached the end
37 // of the pattern.
39 // All of these patterns start with 01 3x because the block header on
40 // LP64 consists of an isa pointer (which we're supposed to scan for
41 // some reason) followed by three words (2 ints, a function pointer,
42 // and a descriptor pointer).
44 // FIXME: do these really have to be named L_OBJC_CLASS_NAME_xxx?
45 // FIXME: sequences should never end in x0 00 instead of just 00
47 // Test 1
48 // byref int, short, char, char, char, id, id, strong void*, byref id
49 // CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
50     void (^b)(void) = ^{
51         byref_int = sh + ch+ch1+ch2 ;
52         x(bar);
53         x(baz);
54         x((id)strong_void_sta);
55         x(byref_bab);
56     };    
57     b();
59 // Test 2
60 // byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
61 // 01 36 10 00
62 // CHECK-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
63     void (^c)(void) = ^{
64         byref_int = sh + ch+ch1+ch2 ;
65         x(bar);
66         x(baz);
67         x((id)strong_void_sta);
68         x(wid);
69         bl_var1 = 0;
70         x(byref_bab);
71     };    
72     c();
74 // Test 3
75 // byref int, short, char, char, char, id, id, byref void*, int, double, byref id
76 // 01 34 11 30 00
77 // FIXME: we'd get a better format here if we sorted by scannability, not just alignment
78 // CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
79     void (^d)(void) = ^{
80         byref_int = sh + ch+ch1+ch2 ;
81         x(bar);
82         x(baz);
83         x(wid);
84         bl_var1 = 0; 
85         y(i + dob);
86         x(byref_bab);
87     };    
88     d();
90 // Test 4
91 // struct S (int, id, int, id, int, id)
92 // 01 41 11 11 00
93 // CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
94     struct S s2;
95     void (^e)(void) = ^{
96         x(s2.o1);
97     };    
98     e();
101 // Test 5 (unions/structs and their nesting):
102 void Test5(void) {
103   struct S5 {
104     int i1;
105     id o1;
106     struct V {
107      int i2;
108      id o2;
109     } v1;
110     int i3;
111     union UI {
112         void * i1;
113         id o1;
114         int i3;
115         id o3;
116     }ui;
117   };
119   union U {
120         void * i1;
121         id o1;
122         int i3;
123         id o3;
124   }ui;
126   struct S5 s2;
127   union U u2;
129 // struct s2 (int, id, int, id, int, id?), union u2 (id?)
130 // 01 41 11 12 00
131 // CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
132   void (^c)(void) = ^{
133     x(s2.ui.o1);
134     x(u2.o1);
135   };
136   c();
139 void CFRelease(id);
140 void notifyBlock(id dependentBlock) {
141  id singleObservationToken;
142  id token;
143  void (^b)(void);
145 // id, id, void(^)(void)
146 // 01 33 00
147 // CHECK-LP64: block variable layout for block: 0x01, 0x33, 0x00
148  void (^wrapperBlock)(void) = ^(void) {
149      CFRelease(singleObservationToken);
150      CFRelease(singleObservationToken);
151      CFRelease(token);
152      CFRelease(singleObservationToken);
153      b();
154     };
155  wrapperBlock();
158 void test_empty_block(void) {
159 // 01 00
160 // CHECK-LP64: block variable layout for block: 0x01, 0x30, 0x00
161   void (^wrapperBlock)(void) = ^(void) {
162   };
163  wrapperBlock();
166 typedef union { char ch[8];  } SS;
167 typedef struct { SS s[4]; } CS;
168 void test_union_in_layout(void) {
169   CS cs;
170   ^{ cs; };