1 module it.c.compile.struct_;
2 
3 
4 import it;
5 
6 
7 @("onefield.int")
8 @C(
9     q{
10         struct Foo { int i; };
11     }
12 )
13 @safe unittest {
14     mixin(
15         shouldCompile(
16             D(
17                 q{
18                     auto f = Foo(5);
19                     static assert(f.sizeof == 4, "Wrong sizeof for foo");
20                 }
21             )
22         )
23     );
24 }
25 
26 @("onefield.double")
27 @safe unittest {
28     shouldCompile(
29         C(
30             q{
31                 struct Bar { double d; };
32             }
33         ),
34 
35         D(
36             q{
37                 auto b = Bar(33.3);
38                 static assert(b.sizeof == 8, "Wrong sizeof for Bar");
39             }
40         )
41     );
42 }
43 
44 
45 @("threefields")
46 @safe unittest {
47     shouldCompile(
48         C(
49             q{
50                 struct Baz {
51                     int i;
52                     int j;
53                     double d;
54                 };
55             }
56         ),
57 
58         D(
59             q{
60                 import std.conv: text;
61                 auto b = Baz(42, 7, 33.3);
62                 static assert(is(typeof(b.i) == int));
63                 static assert(is(typeof(b.j) == int));
64                 static assert(is(typeof(b.d) == double));
65                 static assert(b.sizeof == 16, text("Wrong sizeof for Baz: ", b.sizeof));
66             }
67         )
68     );
69 }
70 
71 
72 @("nested")
73 @C(
74     q{
75         struct Outer {
76             int integer;
77             struct Inner {
78                 int x;
79             } inner;
80         };
81     }
82 )
83 @safe unittest {
84     mixin(
85         shouldCompile(
86             D(
87                 q{
88                     auto o = Outer(77, Outer.Inner(42));
89                     static assert(o.sizeof == 8, "Wrong sizeof for Outer");
90                 }
91             )
92         )
93     );
94 }
95 
96 
97 @("typedef.name")
98 @C(
99     q{
100         typedef struct TypeDefd_ {
101             int i;
102             double d;
103         } TypeDefd;
104     }
105 )
106 @safe unittest {
107     mixin(
108         shouldCompile(
109             D(
110                 q{
111                     {
112                         auto t = TypeDefd_(42, 33.3);
113                         static assert(t.sizeof == 16, "Wrong sizeof for TypeDefd_");
114                     }
115                     {
116                         auto t = TypeDefd(42, 33.3);
117                         static assert(t.sizeof == 16, "Wrong sizeof for TypeDefd");
118                     }
119                 }
120             )
121         )
122     );
123 }
124 
125 
126 @C(
127     q{
128         typedef struct {
129             int x, y, z;
130         } Nameless1;
131 
132         typedef struct {
133             double d;
134         } Nameless2;
135     }
136 )
137 @("typedef.anon")
138 @safe unittest {
139     mixin(
140         shouldCompile(
141             D(
142                 q{
143                     auto n1 = Nameless1(2, 3, 4);
144                     static assert(n1.sizeof == 12, "Wrong sizeof for Nameless1");
145                     static assert(is(typeof(Nameless1.x) == int));
146                     static assert(is(typeof(Nameless1.y) == int));
147                     static assert(is(typeof(Nameless1.z) == int));
148 
149                     auto n2 = Nameless2(33.3);
150                     static assert(n2.sizeof == 8, "Wrong sizeof for Nameless2");
151                     static assert(is(typeof(Nameless2.d) == double));
152                 }
153             )
154         )
155     );
156 }
157 
158 
159 @C(
160     q{
161         typedef struct A B;
162         struct A { int a; };
163     }
164 )
165 @("typedef.before")
166 @safe unittest {
167     mixin(
168         shouldCompile(
169             D(
170                 q{
171                     auto a = A(42);
172                     auto b = B(77);
173                     static assert(is(A == B));
174                 }
175             )
176         )
177     );
178 }
179 
180 
181 @WIP2
182 @("fsid_t")
183 @safe unittest {
184     shouldCompile(
185         C(
186             `
187                 #define __FSID_T_TYPE struct { int __val[2]; }
188                 typedef  __FSID_T_TYPE __fsid_t;
189                 typedef __fsid_t fsid_t;
190             `
191         ),
192         D(
193             q{
194                 fsid_t foo;
195                 foo.__val[0] = 2;
196                 foo.__val[1] = 3;
197             }
198         )
199     );
200 }
201 
202 
203 @WIP2
204 @("fd_set")
205 @safe unittest {
206 
207     with(immutable IncludeSandbox()) {
208 
209         writeFile("system.h",
210                   `
211                       #define __FD_SETSIZE 1024
212                       typedef long int __fd_mask;
213                       #define __NFDBITS (8 * (int) sizeof (__fd_mask))
214 
215                       typedef struct
216                       {
217                        #ifdef __USE_XOPEN
218                           __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
219                        # define __FDS_BITS(set) ((set)->fds_bits)
220                        #else
221                           __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
222                        # define __FDS_BITS(set) ((set)->__fds_bits)
223                        #endif
224                       } fd_set;
225                   `);
226 
227 
228         writeFile("header.h",
229                   `
230                       #include "system.h"
231                   `);
232 
233         const dppFileName = "foo.dpp";
234         writeFile("foo.dpp",
235                   `
236                       #include "header.h"
237                       void func() {
238                           fd_set foo;
239                           foo.__fds_bits[0] = 5;
240                       }
241                   `);
242 
243 
244         runPreprocessOnly("foo.dpp");
245         shouldCompile("foo.d");
246     }
247 }
248 
249 
250 @("multiple declarations")
251 @safe unittest {
252     shouldCompile(
253         C(
254             q{
255                 struct Struct;
256                 struct Struct;
257                 struct OtherStruct;
258                 struct Struct { int x, y, z; };
259             }
260         ),
261         D(
262             q{
263                 Struct s;
264                 s.x = 42;
265                 s.y = 33;
266                 s.z = 77;
267                 static assert(!__traits(compiles, OtherStruct()));
268             }
269         )
270     );
271 }
272 
273 
274 @WIP2
275 @("var.anonymous")
276 @safe unittest {
277     shouldCompile(
278         C(`struct { int i; } var;`),
279         D(
280             q{
281                 var.i = 42;
282             }
283         )
284     );
285 }
286 
287 
288 @WIP2
289 @("var.anonymous.typedef")
290 @safe unittest {
291     shouldCompile(
292         C(`
293               typedef struct { int i; } mystruct;
294               mystruct var;
295           `),
296         D(
297             q{
298                 var.i = 42;
299             }
300         )
301     );
302 }
303 
304 @("const anonymous struct as field")
305 @safe unittest {
306     shouldCompile(
307         C(
308             q{
309                 struct A {
310                     const struct {
311                         int version;
312                         int other;
313                     } version;
314                 };
315             }
316         ),
317         D(
318             q{
319                 A a = { version_ : { version_ : 13, other : 7 } };
320             }
321         )
322     );
323 }
324 
325 @("Pointer to pointer to undeclared struct should result in a struct declaration")
326 @safe unittest {
327     shouldCompile(
328         C(
329             q{
330                 struct A {
331                     const struct B** p;
332                 };
333 
334                 void f(struct C***);
335             }
336         ),
337         D(
338             q{
339                 B *ptrB;
340                 C *ptrC;
341             }
342         )
343     );
344 }