types.c - scc - simple c99 compiler
HTML git clone git://git.simple-cc.org/scc
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
types.c (9380B)
---
1 #include <assert.h>
2 #include <inttypes.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <scc/cstd.h>
7 #include <scc/scc.h>
8 #include "cc1.h"
9
10 #define NR_TYPE_HASH 16
11 #define HASH(t) (((t)->op ^ (uintptr_t) (t)->type>>3) & NR_TYPE_HASH-1)
12
13 static Type *typetab[NR_TYPE_HASH], *localtypes;
14
15 /* FIXME:
16 * Compiler can generate warnings here if the ranges of TINT,
17 * TUINT and TFLOAT are smaller than any of the constants in this
18 * array. Ignore them if you know that the target types are correct
19 */
20 static struct limits limits[][4] = {
21 {
22 { /* 0 = unsigned 1 byte */
23 .min.i = 0,
24 .max.i = 0xff
25 },
26 { /* 1 = unsigned 2 bytes */
27 .min.i = 0,
28 .max.i = 0xffff
29 },
30 { /* 2 = unsigned 4 bytes */
31 .min.i = 0,
32 .max.i = 0xffffffff
33 },
34 { /* 3 = unsigned 8 bytes */
35 .min.i = 0,
36 .max.i = 0xffffffffffffffff
37 }
38 },
39 {
40 { /* 0 = signed 1 byte */
41 .min.i = -0x7f-1,
42 .max.i = 0x7f
43 },
44 { /* 1 = signed 2 byte */
45 .min.i = -0x7fff-1,
46 .max.i = 0x7fff
47 },
48 { /* 2 = signed 4 byte */
49 .min.i = -0x7fffffff-1,
50 .max.i = 0x7fffffff
51 },
52 { /* 3 = signed 8 byte */
53 .min.i = -0x7fffffffffffffff-1,
54 .max.i = 0x7fffffffffffffff,
55 }
56 },
57 {
58 {
59 /* 0 = float 4 bytes */
60 .min.f = -1,
61 .max.f = 2
62 },
63 {
64 /* 1 = float 8 bytes */
65 .min.f = -1,
66 .max.f = 2,
67 },
68 {
69 /* 2 = float 16 bytes */
70 .min.f = -1,
71 .max.f = 2,
72 }
73 }
74 };
75
76 struct limits *
77 getlimits(Type *tp)
78 {
79 int ntable, ntype;
80
81 switch (tp->op) {
82 case ENUM:
83 case INT:
84 ntable = ((tp->prop & TSIGNED) != 0);
85 switch (tp->size) {
86 case 1: ntype = 0; break;
87 case 2: ntype = 1; break;
88 case 4: ntype = 2; break;
89 case 8: ntype = 3; break;
90 }
91 break;
92 case FLOAT:
93 ntable = 2;
94 switch (tp->size) {
95 case 4: ntype = 0; break;
96 case 8: ntype = 1; break;
97 case 16: ntype = 2; break;
98 }
99 break;
100 default:
101 abort();
102 }
103
104 return &limits[ntable][ntype];
105 }
106
107 Type *
108 ctype(int type, int sign, int size)
109 {
110 switch (type) {
111 case CHAR:
112 if (size)
113 goto invalid_type;
114 switch (sign) {
115 case 0:
116 return chartype;
117 case SIGNED:
118 return schartype;
119 case UNSIGNED:
120 return uchartype;
121 }
122 break;
123 case VA_LIST:
124 if (size || sign)
125 goto invalid_type;
126 return va_list_type;
127 case VOID:
128 if (size || sign)
129 goto invalid_type;
130 return voidtype;
131 case BOOL:
132 if (size || sign)
133 goto invalid_type;
134 return booltype;
135 case 0:
136 case INT:
137 switch (size) {
138 case 0:
139 return (sign == UNSIGNED) ? uinttype : inttype;
140 case SHORT:
141 return (sign == UNSIGNED) ? ushorttype : shorttype;
142 case LONG:
143 return (sign == UNSIGNED) ? ulongtype : longtype;
144 case LLONG:
145 return (sign == UNSIGNED) ? ullongtype : llongtype;
146 }
147 break;
148 case DOUBLE:
149 if (size == LLONG)
150 goto invalid_type;
151 if (size == LONG)
152 size = LLONG;
153 else
154 size = LONG;
155 goto floating;
156 case FLOAT:
157 if (size == LLONG)
158 goto invalid_type;
159 floating:
160 if (sign)
161 goto invalid_type;
162 switch (size) {
163 case 0:
164 return floattype;
165 case LONG:
166 return doubletype;
167 case LLONG:
168 return ldoubletype;
169 }
170 break;
171 }
172
173 invalid_type:
174 errorp("invalid type specification");
175 return inttype;
176 }
177
178 void
179 typesize(Type *tp)
180 {
181 Symbol **sp;
182 Type *type;
183 unsigned long size, offset;
184 int align, a;
185 TINT n;
186
187 switch (tp->op) {
188 case ARY:
189 /* FIXME: Control overflow */
190 tp->size = tp->n.elem * tp->type->size;
191 tp->align = tp->type->align;
192 return;
193 case PTR:
194 tp->size = pvoidtype->size;
195 tp->align = pvoidtype->align;
196 return;
197 case STRUCT:
198 case UNION:
199 /* FIXME: Control overflow */
200 /*
201 * The alignment of the struct/union is
202 * he alignment of the largest included type.
203 * The size of an union is the size of the largest
204 * field, and the size of a struct is the sum
205 * of the size of every field plus padding bits.
206 */
207 offset = align = size = 0;
208 n = tp->n.elem;
209 for (sp = tp->p.fields; n--; ++sp) {
210 type = (*sp)->type;
211 a = type->align;
212 if (a > align)
213 align = a;
214 if (tp->op == STRUCT) {
215 if (--a != 0)
216 offset = (offset + a) & ~a;
217 (*sp)->u.i = offset;
218 size = offset + type->size;
219 offset = size;
220 } else {
221 (*sp)->u.i = 0;
222 if (type->size > size)
223 size = type->size;
224 }
225 }
226
227 tp->align = align;
228 /*
229 * We have to add the padding bits to
230 * ensure next struct in an array is well
231 * alignment.
232 */
233 if (tp->op == STRUCT && align-- > 1)
234 size = size+align & ~align;
235 tp->size = size;
236 return;
237 case ENUM:
238 tp->size = inttype->size;
239 tp->align = inttype->align;
240 return;
241 case FTN:
242 return;
243 default:
244 abort();
245 }
246 }
247
248 Type *
249 deftype(Type *tp)
250 {
251 tp->prop |= TDEFINED;
252 typesize(tp);
253 emit(OTYP, tp);
254 return tp;
255 }
256
257 static Type *
258 newtype(Type *base)
259 {
260 Type *tp, **pars;
261 size_t siz;
262
263 tp = xmalloc(sizeof(*tp));
264 *tp = *base;
265 tp->id = newid();
266
267 if (tp->op == FTN) {
268 siz = (tp->n.elem + 1) * sizeof(Type *);
269 pars = xmalloc(siz);
270 if (tp->n.elem > 0)
271 memcpy(pars, tp->p.pars, siz);
272 pars[tp->n.elem] = NULL;
273 tp->p.pars = pars;
274 } else if (tp->op == ARY) {
275 /* We need alignment for flexible array members */
276 tp->align = tp->type->align;
277 }
278
279 if (curfun) {
280 /* it is a type defined in the body of a function */
281 tp->next = localtypes;
282 localtypes = tp;
283 }
284 if (tp->prop & TDEFINED)
285 deftype(tp);
286 return tp;
287 }
288
289 Type *
290 mktype(Type *tp, int op, TINT nelem, Type *pars[])
291 {
292 Type **tbl, type;
293 Type *bp;
294
295 if (op == PTR && tp == voidtype)
296 return pvoidtype;
297
298 type = (Type) {
299 .type = tp,
300 .op = op,
301 .p.pars = pars,
302 .n.elem = nelem,
303 };
304
305 switch (op) {
306 case ARY:
307 if (tp == voidtype) {
308 errorp("declaration of array of voids type");
309 tp = inttype;
310 }
311 type.letter = L_ARRAY;
312 if (nelem != 0)
313 type.prop |= TDEFINED;
314 break;
315 case KRFTN:
316 type.prop |= TDEFINED | TK_R;
317 type.op = FTN;
318 type.letter = L_FUNCTION;
319 break;
320 case FTN:
321 if (nelem > 0 && pars[nelem-1] == ellipsistype)
322 type.prop |= TELLIPSIS;
323 type.letter = L_FUNCTION;
324 type.prop |= TDEFINED;
325 break;
326 case PTR:
327 type.letter = L_POINTER;
328 type.prop |= TDEFINED;
329 break;
330 case ENUM:
331 type.letter = inttype->letter;
332 type.prop |= TINTEGER | TARITH;
333 type.n.rank = inttype->n.rank;
334 goto create_type;
335 case STRUCT:
336 type.letter = L_STRUCT;
337 type.prop |= TAGGREG;
338 goto create_type;
339 case UNION:
340 type.letter = L_UNION;
341 type.prop |= TAGGREG;
342 create_type:
343 return newtype(&type);
344 default:
345 abort();
346 }
347
348 tbl = &typetab[HASH(&type)];
349 for (bp = *tbl; bp; bp = bp->h_next) {
350 if (eqtype(bp, &type, EQUAL))
351 return bp;
352 }
353
354 bp = newtype(&type);
355 bp->h_next = *tbl;
356 *tbl = bp;
357
358 return bp;
359 }
360
361 /*
362 * If one type has a parameter type list and the other type is specified by
363 * a function declarator that is not part of a function definition and that
364 * contains an empty identifier list, the parameter list shall not have an
365 * ellipsis terminator and the type of each parameter shall be compatible
366 * with the type that results from the application of the default argument
367 * promotions.
368 */
369 static int
370 eqfuns(Type *tp1, Type *tp2, int equiv)
371 {
372 TINT n;
373 int f1kr, f2kr;
374 Type *krf, *ansi, **pp, *p;
375
376 f1kr = (tp1->prop&TK_R) != 0;
377 f2kr = (tp2->prop&TK_R) != 0;
378
379 /* 1: 2 ansi functions */
380 if (!f1kr && !f2kr) {
381 Type **p1, **p2;
382 if (tp1->n.elem != tp2->n.elem)
383 return 0;
384 p1 = tp1->p.pars, p2 = tp2->p.pars;
385 for (n = tp1->n.elem; n > 0; --n) {
386 if (!eqtype(*p1++, *p2++, equiv))
387 return 0;
388 }
389 goto check_base;
390 }
391
392 /* 2: 2 k&r functions */
393 if (f1kr && f2kr)
394 goto check_base;
395
396 /* 3: 1 k&r function + 1 ansi function */
397 if (!equiv)
398 return 0;
399
400 if (f1kr) {
401 krf = tp1;
402 ansi = tp2;
403 } else {
404 ansi = tp1;
405 krf = tp2;
406 }
407
408 for (pp = ansi->p.pars; p = *pp; ++pp) {
409 switch (p->op) {
410 case ELLIPSIS:
411 return 0;
412 case INT:
413 case ENUM:
414 if (p->n.rank < inttype->n.rank)
415 return 0;
416 break;
417 case FLOAT:
418 if (p == floattype)
419 return 0;
420 break;
421 }
422 }
423
424 check_base:
425 return eqtype(tp1->type, tp2->type, equiv);
426 }
427
428 int
429 eqtype(Type *tp1, Type *tp2, int equiv)
430 {
431 TINT n;
432 Symbol **s1, **s2;
433
434 if (tp1 == tp2)
435 return 1;
436 if (!tp1 || !tp2)
437 return 0;
438 if (tp1->op != tp2->op)
439 return 0;
440
441 switch (tp1->op) {
442 case UNION:
443 case STRUCT:
444 if (tp1->letter != tp2->letter)
445 return 0;
446 if (tp1->tag->name || tp2->tag->name)
447 return tp1->tag == tp2->tag;
448 if (tp1->n.elem != tp2->n.elem)
449 return 0;
450 s1 = tp1->p.fields, s2 = tp2->p.fields;
451 for (n = tp1->n.elem; n > 0; --n, ++s1, ++s2) {
452 if (strcmp((*s1)->name, (*s2)->name))
453 return 0;
454 if (!eqtype((*s1)->type, (*s2)->type, equiv))
455 return 0;
456 }
457 return 1;
458 case FTN:
459 return eqfuns(tp1, tp2, equiv);
460 case ARY:
461 if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0))
462 goto check_base;
463 if (tp1->n.elem != tp2->n.elem)
464 return 0;
465 case PTR:
466 check_base:
467 return eqtype(tp1->type, tp2->type, equiv);
468 case VOID:
469 case ENUM:
470 return 0;
471 case INT:
472 case FLOAT:
473 return tp1->letter == tp2->letter;
474 default:
475 abort();
476 }
477 }
478
479 void
480 flushtypes(void)
481 {
482 Type *tp, *next, **h;
483
484 for (tp = localtypes; tp; tp = next) {
485 next = tp->next;
486 switch (tp->op) {
487 default:
488 /*
489 * All the local types are linked after
490 * global types, and since we are
491 * unlinking them in the inverse order
492 * we do know that tp is always the head
493 * of the collision list
494 */
495 h = &typetab[HASH(tp)];
496 assert(*h == tp);
497 *h = tp->h_next;
498 case STRUCT:
499 case UNION:
500 case ENUM:
501 free(tp);
502 break;
503 }
504 }
505 localtypes = NULL;
506 }