|
|
@@ -57,10 +57,10 @@ void type_dump(struct type *t, FILE *fp)
|
|
57
|
57
|
fputs("struct ", fp);
|
|
58
|
58
|
fputs(t->sou.name, fp);
|
|
59
|
59
|
break;
|
|
60
|
|
- case T_UNION:
|
|
61
|
|
- fputs("union ", fp);
|
|
62
|
|
- fputs(t->sou.name, fp);
|
|
63
|
|
- break;
|
|
|
60
|
+ /* case T_UNION: */
|
|
|
61
|
+ /* fputs("union ", fp); */
|
|
|
62
|
+ /* fputs(t->sou.name, fp); */
|
|
|
63
|
+ /* break; */
|
|
64
|
64
|
case T_FUNC:
|
|
65
|
65
|
type_dump_func(t, fp);
|
|
66
|
66
|
break;
|
|
|
@@ -97,7 +97,7 @@ void type_dump_cdecl(struct type *t, FILE *fp)
|
|
97
|
97
|
break;
|
|
98
|
98
|
|
|
99
|
99
|
case T_STRUCT:
|
|
100
|
|
- case T_UNION:
|
|
|
100
|
+ /* case T_UNION: */
|
|
101
|
101
|
type_dump_cdecl_sou(t, fp);
|
|
102
|
102
|
break;
|
|
103
|
103
|
|
|
|
@@ -124,45 +124,6 @@ void type_dump_cdecl(struct type *t, FILE *fp)
|
|
124
|
124
|
/* } */
|
|
125
|
125
|
/* } */
|
|
126
|
126
|
|
|
127
|
|
-/* struct type *type_map_of(struct type *ktype, struct type *vtype) */
|
|
128
|
|
-/* { */
|
|
129
|
|
-/* struct type *t; */
|
|
130
|
|
-/* size_t i; */
|
|
131
|
|
-
|
|
132
|
|
-/* for (i = 0; i < types.len; i++) { */
|
|
133
|
|
-/* t = types.type[i]; */
|
|
134
|
|
-/* if ((t->ttype == T_MAP) */
|
|
135
|
|
-/* && (t->map.ktype == ktype) */
|
|
136
|
|
-/* && (t->map.vtype == vtype)) */
|
|
137
|
|
-/* return t; */
|
|
138
|
|
-/* } */
|
|
139
|
|
-
|
|
140
|
|
-/* t = calloc(1, sizeof(*t)); */
|
|
141
|
|
-/* t->ttype = T_MAP; */
|
|
142
|
|
-/* t->map.vtype = vtype; */
|
|
143
|
|
-/* t->map.ktype = ktype; */
|
|
144
|
|
-/* type_add(t); */
|
|
145
|
|
-/* return t; */
|
|
146
|
|
-/* } */
|
|
147
|
|
-
|
|
148
|
|
-/* struct type *type_ptr_of(struct type *type) */
|
|
149
|
|
-/* { */
|
|
150
|
|
-/* struct type *t; */
|
|
151
|
|
-/* size_t i; */
|
|
152
|
|
-
|
|
153
|
|
-/* for (i = 0; i < types.len; i++) { */
|
|
154
|
|
-/* t = types.type[i]; */
|
|
155
|
|
-/* if ((t->ttype == T_POINTER) */
|
|
156
|
|
-/* && (t->pointer.type == type)) */
|
|
157
|
|
-/* return t; */
|
|
158
|
|
-/* } */
|
|
159
|
|
-
|
|
160
|
|
-/* t = calloc(1, sizeof(*t)); */
|
|
161
|
|
-/* t->ttype = T_POINTER; */
|
|
162
|
|
-/* t->pointer.type = type; */
|
|
163
|
|
-/* type_add(t); */
|
|
164
|
|
-/* return t; */
|
|
165
|
|
-/* } */
|
|
166
|
127
|
|
|
167
|
128
|
|
|
168
|
129
|
struct type *type_normalize(struct type *t)
|
|
|
@@ -199,7 +160,7 @@ int type_compatible(struct type *a, struct type *b)
|
|
199
|
160
|
|
|
200
|
161
|
return type_compatible(a->array.type, b->array.type);
|
|
201
|
162
|
case T_STRUCT:
|
|
202
|
|
- case T_UNION:
|
|
|
163
|
+ /* case T_UNION: */
|
|
203
|
164
|
return !strcmp(a->sou.name, b->sou.name);
|
|
204
|
165
|
case T_FUNC:
|
|
205
|
166
|
return type_compatible(a->func.type, b->func.type);
|
|
|
@@ -214,85 +175,22 @@ int type_compatible(struct type *a, struct type *b)
|
|
214
|
175
|
return 0;
|
|
215
|
176
|
}
|
|
216
|
177
|
|
|
217
|
|
-/* void type_size_set_sou(struct type *t) */
|
|
218
|
|
-/* { */
|
|
219
|
|
-/* struct tfield *f; */
|
|
220
|
|
-/* size_t size = 0; */
|
|
221
|
|
-
|
|
222
|
|
-/* if (!t->sou.fields) */
|
|
223
|
|
-/* return; */
|
|
224
|
|
-
|
|
225
|
|
-/* for (f = t->sou.fields; f->name; f++) { */
|
|
226
|
|
-/* /\* size of all members is now known yet, abort *\/ */
|
|
227
|
|
-/* if (!f->type->size) */
|
|
228
|
|
-/* return; */
|
|
229
|
|
-
|
|
230
|
|
-/* if (!t->sou.packed) */
|
|
231
|
|
-/* size += size % f->type->size; */
|
|
232
|
|
-
|
|
233
|
|
-/* size += f->type->size; */
|
|
234
|
|
-/* f->offset = size; */
|
|
235
|
|
-/* } */
|
|
236
|
|
-
|
|
237
|
|
-/* if (!t->sou.packed && size) { */
|
|
238
|
|
-/* /\* align complete struct to requirements of first */
|
|
239
|
|
-/* * member, if struct keep going downwards *\/ */
|
|
240
|
|
-/* f = t->sou.fields; */
|
|
241
|
|
-/* while (f->type->ttype == T_STRUCT) */
|
|
242
|
|
-/* f = f->type->sou.fields; */
|
|
243
|
|
-
|
|
244
|
|
-/* size += size % f->type->size; */
|
|
245
|
|
-/* } */
|
|
246
|
|
-
|
|
247
|
|
-/* t->size = size; */
|
|
248
|
|
-/* } */
|
|
249
|
|
-
|
|
250
|
|
-/* void type_size_set(struct type *t) */
|
|
251
|
|
-/* { */
|
|
252
|
|
-/* switch (t->ttype) { */
|
|
253
|
|
-/* case T_TYPEDEF: */
|
|
254
|
|
-/* t->size = t->tdef.type->size; */
|
|
255
|
|
-/* break; */
|
|
256
|
|
-/* case T_STRUCT: */
|
|
257
|
|
-/* case T_UNION: */
|
|
258
|
|
-/* type_size_set_sou(t); */
|
|
259
|
|
-/* break; */
|
|
260
|
|
-/* case T_FUNC: */
|
|
261
|
|
-/* t->size = t->func.type->size; */
|
|
262
|
|
-/* assert(t->func.generate_ir); */
|
|
263
|
|
-/* break; */
|
|
264
|
|
-/* case T_SCALAR: */
|
|
265
|
|
-/* break; */
|
|
266
|
|
-/* case T_POINTER: */
|
|
267
|
|
-/* t->size = sizeof(void *); */
|
|
268
|
|
-/* break; */
|
|
269
|
|
-/* case T_ARRAY: */
|
|
270
|
|
-/* t->size = t->array.len * t->array.type->size; */
|
|
271
|
|
-/* break; */
|
|
272
|
|
-/* case T_MAP: */
|
|
273
|
|
-/* /\* map fds are s64:s *\/ */
|
|
274
|
|
-/* t->size = 8; */
|
|
275
|
|
-/* break; */
|
|
276
|
|
-/* } */
|
|
277
|
|
-/* } */
|
|
278
|
|
-
|
|
279
|
|
-static ssize_t type_alignof_union(struct type *t)
|
|
|
178
|
+static ssize_t type_alignof_struct(struct type *t)
|
|
280
|
179
|
{
|
|
281
|
|
- ssize_t amax = -EINVAL;
|
|
282
|
180
|
struct tfield *f;
|
|
|
181
|
+ ssize_t falign, align = -EINVAL;
|
|
283
|
182
|
|
|
284
|
|
- for (f = t->sou.fields; f->type != T_VOID; f++) {
|
|
285
|
|
- ssize_t a;
|
|
|
183
|
+ tfields_foreach(f, t->sou.fields) {
|
|
|
184
|
+ falign = type_alignof(f->type);
|
|
286
|
185
|
|
|
287
|
|
- a = type_alignof(f->type);
|
|
288
|
|
- if (a < 0)
|
|
289
|
|
- return a;
|
|
|
186
|
+ if (falign < 0)
|
|
|
187
|
+ return falign;
|
|
290
|
188
|
|
|
291
|
|
- if (a > amax)
|
|
292
|
|
- amax = a;
|
|
|
189
|
+ if (falign > align)
|
|
|
190
|
+ align = falign;
|
|
293
|
191
|
}
|
|
294
|
192
|
|
|
295
|
|
- return amax;
|
|
|
193
|
+ return align;
|
|
296
|
194
|
}
|
|
297
|
195
|
|
|
298
|
196
|
ssize_t type_alignof(struct type *t)
|
|
|
@@ -309,67 +207,59 @@ ssize_t type_alignof(struct type *t)
|
|
309
|
207
|
case T_ARRAY:
|
|
310
|
208
|
return type_alignof(t->array.type);
|
|
311
|
209
|
case T_STRUCT:
|
|
312
|
|
- if (!t->sou.fields)
|
|
313
|
|
- return type_alignof(&t_void);
|
|
314
|
|
- return type_alignof(t->sou.fields->type);
|
|
315
|
|
- case T_UNION:
|
|
316
|
|
- if (!t->sou.fields)
|
|
317
|
|
- return type_alignof(&t_void);
|
|
318
|
|
- return type_alignof_union(t);
|
|
|
210
|
+ return type_alignof_struct(t);
|
|
319
|
211
|
}
|
|
320
|
212
|
|
|
321
|
213
|
return -EINVAL;
|
|
322
|
214
|
}
|
|
323
|
215
|
|
|
324
|
|
-static ssize_t type_sizeof_struct(struct type *t)
|
|
|
216
|
+ssize_t type_offset_size_of(struct type *t, const char *field)
|
|
325
|
217
|
{
|
|
326
|
218
|
struct tfield *f;
|
|
327
|
|
- size_t size = 0;
|
|
328
|
|
- ssize_t fsize;
|
|
|
219
|
+ size_t offset = 0;
|
|
|
220
|
+ ssize_t fsize, falign;
|
|
|
221
|
+
|
|
|
222
|
+ assert(t->ttype == T_STRUCT);
|
|
329
|
223
|
|
|
330
|
224
|
if (!t->sou.fields)
|
|
331
|
|
- return 0;
|
|
|
225
|
+ return -ENOENT;
|
|
332
|
226
|
|
|
333
|
|
- for (f = t->sou.fields; f->name; f++) {
|
|
334
|
|
- /* size of all members is now known yet, abort */
|
|
|
227
|
+ tfields_foreach(f, t->sou.fields) {
|
|
335
|
228
|
fsize = type_sizeof(f->type);
|
|
336
|
229
|
if (fsize < 0)
|
|
337
|
230
|
return fsize;
|
|
338
|
231
|
|
|
339
|
|
- size += fsize;
|
|
|
232
|
+ falign = type_alignof(f->type);
|
|
|
233
|
+ if (falign < 0)
|
|
|
234
|
+ return falign;
|
|
340
|
235
|
|
|
341
|
|
- if (!t->sou.packed)
|
|
342
|
|
- size += size % type_alignof(f->type);
|
|
343
|
|
- }
|
|
|
236
|
+ if (!t->sou.packed && (falign > 1))
|
|
|
237
|
+ offset += falign - (offset % falign);
|
|
344
|
238
|
|
|
345
|
|
- if (!t->sou.packed && size)
|
|
346
|
|
- size += size % type_alignof(t);
|
|
|
239
|
+ if (field && !strcmp(f->name, field))
|
|
|
240
|
+ return offset;
|
|
347
|
241
|
|
|
348
|
|
- return size;
|
|
349
|
|
-}
|
|
|
242
|
+ offset += fsize;
|
|
|
243
|
+ }
|
|
350
|
244
|
|
|
351
|
|
-static ssize_t type_sizeof_union(struct type *t)
|
|
352
|
|
-{
|
|
353
|
|
- struct tfield *f;
|
|
354
|
|
- ssize_t size = 0;
|
|
|
245
|
+ if (field)
|
|
|
246
|
+ return -ENOENT;
|
|
355
|
247
|
|
|
356
|
|
- if (!t->sou.fields)
|
|
357
|
|
- return 0;
|
|
|
248
|
+ if (!t->sou.packed && offset && (falign > 1))
|
|
|
249
|
+ offset += falign - (offset % falign);
|
|
358
|
250
|
|
|
359
|
|
- for (f = t->sou.fields; f->name; f++) {
|
|
360
|
|
- ssize_t z, a;
|
|
361
|
|
-
|
|
362
|
|
- z = type_sizeof(f->type);
|
|
363
|
|
- a = t->sou.packed ? type_alignof(f->type) : 0;
|
|
364
|
|
- if ((z < 0) || (a < 0))
|
|
365
|
|
- return -EINVAL;
|
|
|
251
|
+ return offset;
|
|
|
252
|
+
|
|
|
253
|
+}
|
|
366
|
254
|
|
|
367
|
|
- z += z % a;
|
|
368
|
|
- if (z > size)
|
|
369
|
|
- size = z;
|
|
370
|
|
- }
|
|
|
255
|
+ssize_t type_offsetof(struct type *t, const char *field)
|
|
|
256
|
+{
|
|
|
257
|
+ return type_offset_size_of(t, field);
|
|
|
258
|
+}
|
|
371
|
259
|
|
|
372
|
|
- return size;
|
|
|
260
|
+ssize_t type_sizeof_struct(struct type *t)
|
|
|
261
|
+{
|
|
|
262
|
+ return type_offset_size_of(t, NULL);
|
|
373
|
263
|
}
|
|
374
|
264
|
|
|
375
|
265
|
ssize_t type_sizeof(struct type *t)
|
|
|
@@ -388,8 +278,6 @@ ssize_t type_sizeof(struct type *t)
|
|
388
|
278
|
return t->array.len * type_sizeof(t->array.type);
|
|
389
|
279
|
case T_STRUCT:
|
|
390
|
280
|
return type_sizeof_struct(t);
|
|
391
|
|
- case T_UNION:
|
|
392
|
|
- return type_sizeof_union(t);
|
|
393
|
281
|
case T_MAP:
|
|
394
|
282
|
return sizeof(int);
|
|
395
|
283
|
}
|
|
|
@@ -397,66 +285,6 @@ ssize_t type_sizeof(struct type *t)
|
|
397
|
285
|
return -EINVAL;
|
|
398
|
286
|
}
|
|
399
|
287
|
|
|
400
|
|
-/* int type_walk_fields(struct tfield *f, twalk_fn pre, twalk_fn post, void *ctx) */
|
|
401
|
|
-/* { */
|
|
402
|
|
-/* if (!f) */
|
|
403
|
|
-/* return 0; */
|
|
404
|
|
-
|
|
405
|
|
-/* while (f->type != T_VOID) { */
|
|
406
|
|
-/* if (pre && (err = pre(f->type, ctx))) */
|
|
407
|
|
-/* return err; */
|
|
408
|
|
-
|
|
409
|
|
-/* err = type_walk(f->type, pre, post, ctx); */
|
|
410
|
|
-/* if (err) */
|
|
411
|
|
-/* return err; */
|
|
412
|
|
-
|
|
413
|
|
-/* if (post && (err = post(f->type, ctx))) */
|
|
414
|
|
-/* return err; */
|
|
415
|
|
-/* } */
|
|
416
|
|
-/* } */
|
|
417
|
|
-
|
|
418
|
|
-/* int type_walk(struct type *t, twalk_fn pre, twalk_fn post, void *ctx) */
|
|
419
|
|
-/* { */
|
|
420
|
|
-/* int err; */
|
|
421
|
|
-
|
|
422
|
|
-/* if (pre && (err = pre(t, ctx))) */
|
|
423
|
|
-/* return err; */
|
|
424
|
|
-
|
|
425
|
|
-/* switch (t->ttype){ */
|
|
426
|
|
-/* case T_VOID: */
|
|
427
|
|
-/* case T_SCALAR: */
|
|
428
|
|
-/* break; */
|
|
429
|
|
-/* case T_TYPEDEF: */
|
|
430
|
|
-/* err = type_walk(t->tdef.type, pre, post, ctx); */
|
|
431
|
|
-/* break; */
|
|
432
|
|
-/* case T_POINTER: */
|
|
433
|
|
-/* err = type_walk(t->ptr.type, pre, post, ctx); */
|
|
434
|
|
-/* break; */
|
|
435
|
|
-/* case T_ARRAY: */
|
|
436
|
|
-/* err = type_walk(t->array.type, pre, post, ctx); */
|
|
437
|
|
-/* break; */
|
|
438
|
|
-/* case T_STRUCT: */
|
|
439
|
|
-/* case T_UNION: */
|
|
440
|
|
-/* err = type_walk_fields(t->sou.fields, pre, post, ctx); */
|
|
441
|
|
-/* break; */
|
|
442
|
|
-/* case T_FUNC: */
|
|
443
|
|
-/* err = type_walk_fields(t->func.args, pre, post, ctx); */
|
|
444
|
|
-/* break; */
|
|
445
|
|
-/* case T_MAP: */
|
|
446
|
|
-/* err = type_walk(t->map.ktype, pre, post, ctx); */
|
|
447
|
|
-/* if (err) */
|
|
448
|
|
-/* break; */
|
|
449
|
|
-
|
|
450
|
|
-/* err = type_walk(t->map.vtype, pre, post, ctx); */
|
|
451
|
|
-/* break; */
|
|
452
|
|
-/* } */
|
|
453
|
|
-
|
|
454
|
|
-/* if (err) */
|
|
455
|
|
-/* return err; */
|
|
456
|
|
-
|
|
457
|
|
-/* if (post && (err = post(t, ctx))) */
|
|
458
|
|
-/* return err; */
|
|
459
|
|
-/* } */
|
|
460
|
288
|
|
|
461
|
289
|
|
|
462
|
290
|
int all_types_cmp(const void *_a, const void *_b)
|
|
|
@@ -472,6 +300,9 @@ struct type_list {
|
|
472
|
300
|
size_t len;
|
|
473
|
301
|
} all_types;
|
|
474
|
302
|
|
|
|
303
|
+#define types_foreach(_t) \
|
|
|
304
|
+ for ((_t) = all_types.types[0]; (_t) <= all_types.types[all_types.len]; (_t)++)
|
|
|
305
|
+
|
|
475
|
306
|
int type_add(struct type *t)
|
|
476
|
307
|
{
|
|
477
|
308
|
if (bsearch(t, all_types.types, all_types.len,
|
|
|
@@ -501,6 +332,61 @@ int type_add_list(struct type **ts)
|
|
501
|
332
|
return 0;
|
|
502
|
333
|
}
|
|
503
|
334
|
|
|
|
335
|
+struct type *type_array_of(struct type *type, size_t len)
|
|
|
336
|
+{
|
|
|
337
|
+ struct type *t;
|
|
|
338
|
+
|
|
|
339
|
+ types_foreach(t) {
|
|
|
340
|
+ if ((t->ttype == T_ARRAY)
|
|
|
341
|
+ && (t->array.type == type)
|
|
|
342
|
+ && (t->array.len == len))
|
|
|
343
|
+ return t;
|
|
|
344
|
+ }
|
|
|
345
|
+
|
|
|
346
|
+ t = calloc(1, sizeof(*t));
|
|
|
347
|
+ t->ttype = T_ARRAY;
|
|
|
348
|
+ t->array.type = type;
|
|
|
349
|
+ t->array.len = len;
|
|
|
350
|
+ type_add(t);
|
|
|
351
|
+ return t;
|
|
|
352
|
+}
|
|
|
353
|
+
|
|
|
354
|
+struct type *type_map_of(struct type *ktype, struct type *vtype)
|
|
|
355
|
+{
|
|
|
356
|
+ struct type *t;
|
|
|
357
|
+
|
|
|
358
|
+ types_foreach(t) {
|
|
|
359
|
+ if ((t->ttype == T_MAP)
|
|
|
360
|
+ && (t->map.ktype == ktype)
|
|
|
361
|
+ && (t->map.vtype == vtype))
|
|
|
362
|
+ return t;
|
|
|
363
|
+ }
|
|
|
364
|
+
|
|
|
365
|
+ t = calloc(1, sizeof(*t));
|
|
|
366
|
+ t->ttype = T_MAP;
|
|
|
367
|
+ t->map.vtype = vtype;
|
|
|
368
|
+ t->map.ktype = ktype;
|
|
|
369
|
+ type_add(t);
|
|
|
370
|
+ return t;
|
|
|
371
|
+}
|
|
|
372
|
+
|
|
|
373
|
+struct type *type_ptr_of(struct type *type)
|
|
|
374
|
+{
|
|
|
375
|
+ struct type *t;
|
|
|
376
|
+
|
|
|
377
|
+ types_foreach(t) {
|
|
|
378
|
+ if ((t->ttype == T_POINTER)
|
|
|
379
|
+ && (t->ptr.type == type))
|
|
|
380
|
+ return t;
|
|
|
381
|
+ }
|
|
|
382
|
+
|
|
|
383
|
+ t = calloc(1, sizeof(*t));
|
|
|
384
|
+ t->ttype = T_POINTER;
|
|
|
385
|
+ t->ptr.type = type;
|
|
|
386
|
+ type_add(t);
|
|
|
387
|
+ return t;
|
|
|
388
|
+}
|
|
|
389
|
+
|
|
504
|
390
|
#define is_signed(_t) (((_t)(-1)) < 0)
|
|
505
|
391
|
|
|
506
|
392
|
#define builtin_scalar(_t) { \
|