scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

types.c (7969B)


      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) ? ushortype  : shortype;
    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 	error("invalid type specification");
    175 }
    176 
    177 void
    178 typesize(Type *tp)
    179 {
    180 	Symbol **sp;
    181 	Type *type;
    182 	unsigned long size, offset;
    183 	int align, a;
    184 	TINT n;
    185 
    186 	switch (tp->op) {
    187 	case ARY:
    188 		/* FIXME: Control overflow */
    189 		tp->size = tp->n.elem * tp->type->size;
    190 		tp->align = tp->type->align;
    191 		return;
    192 	case PTR:
    193 		tp->size = pvoidtype->size;
    194 		tp->align = pvoidtype->align;
    195 		return;
    196 	case STRUCT:
    197 	case UNION:
    198 		/* FIXME: Control overflow */
    199 		/*
    200 		 * The alignment of the struct/union is
    201 		 * he alignment of the largest included type.
    202 		 * The size of an union is the size of the largest
    203 		 * field, and the size of a struct is the sum
    204 		 * of the size of every field plus padding bits.
    205 		 */
    206 		offset = align = size = 0;
    207 		n = tp->n.elem;
    208 		for (sp = tp->p.fields; n--; ++sp) {
    209 			(*sp)->u.i = offset;
    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 					size = (size + a) & ~a;
    217 				size += type->size;
    218 				offset = size;
    219 			} else {
    220 				if (type->size > size)
    221 					size = type->size;
    222 			}
    223 		}
    224 
    225 		tp->align = align;
    226 		/*
    227 		 * We have to add the padding bits to
    228 		 * ensure next struct in an array is well
    229 		 * alignment.
    230 		 */
    231 		if (tp->op == STRUCT && align-- > 1)
    232 			size += size+align & ~align;
    233 		tp->size = size;
    234 		return;
    235 	case ENUM:
    236 		tp->size = inttype->size;
    237 		tp->align = inttype->align;
    238 		return;
    239 	case FTN:
    240 		return;
    241 	default:
    242 		abort();
    243 	}
    244 }
    245 
    246 Type *
    247 deftype(Type *tp)
    248 {
    249 	tp->prop |= TDEFINED;
    250 	typesize(tp);
    251 	emit(OTYP, tp);
    252 	return tp;
    253 }
    254 
    255 static Type *
    256 newtype(Type *base)
    257 {
    258 	Type *tp;
    259 	size_t siz;
    260 
    261 	tp = xmalloc(sizeof(*tp));
    262 	*tp = *base;
    263 	tp->id = newid();
    264 
    265 	if (tp->op == FTN) {
    266 		siz = tp->n.elem * sizeof(Type *);
    267 		tp->p.pars = memcpy(xmalloc(siz), tp->p.pars, siz);
    268 	}
    269 
    270 	if (curfun) {
    271 		/* it is a type defined in the body of a function */
    272 		tp->next = localtypes;
    273 		localtypes = tp;
    274 	}
    275 	if (tp->prop & TDEFINED)
    276 		deftype(tp);
    277 	return tp;
    278 }
    279 
    280 Type *
    281 mktype(Type *tp, int op, TINT nelem, Type *pars[])
    282 {
    283 	Type **tbl, type;
    284 	Type *bp;
    285 
    286 	if (op == PTR && tp == voidtype)
    287 		return pvoidtype;
    288 
    289 	memset(&type, 0, sizeof(type));
    290 	type.type = tp;
    291 	type.op = op;
    292 	type.p.pars = pars;
    293 	type.n.elem = nelem;
    294 
    295 	switch (op) {
    296 	case ARY:
    297 		if (tp == voidtype) {
    298 			errorp("declaration of array of voids type");
    299 			tp = inttype;
    300 		}
    301 		type.letter = L_ARRAY;
    302 		if (nelem != 0)
    303 			type.prop |= TDEFINED;
    304 		break;
    305 	case KRFTN:
    306 		type.prop |= TDEFINED | TK_R;
    307 		type.op = FTN;
    308 		type.letter = L_FUNCTION;
    309 		break;
    310 	case FTN:
    311 		if (nelem > 0 && pars[nelem-1] == ellipsistype)
    312 			type.prop |= TELLIPSIS;
    313 		type.letter = L_FUNCTION;
    314 		type.prop |= TDEFINED;
    315 		break;
    316 	case PTR:
    317 	        type.letter = L_POINTER;
    318 		type.prop |= TDEFINED;
    319 		break;
    320 	case ENUM:
    321 		type.letter = inttype->letter;
    322 		type.prop |= TINTEGER | TARITH;
    323 		type.n.rank = inttype->n.rank;
    324 		goto create_type;
    325 	case STRUCT:
    326 		type.letter = L_STRUCT;
    327 		type.prop |= TAGGREG;
    328 		goto create_type;
    329 	case UNION:
    330 		type.letter = L_UNION;
    331 		type.prop |= TAGGREG;
    332 	create_type:
    333 		return newtype(&type);
    334 	default:
    335 		abort();
    336 	}
    337 
    338 	tbl = &typetab[HASH(&type)];
    339 	for (bp = *tbl; bp; bp = bp->h_next) {
    340 		if (eqtype(bp, &type, 0))
    341 			return bp;
    342 	}
    343 
    344 	bp = newtype(&type);
    345 	bp->h_next = *tbl;
    346 	*tbl = bp;
    347 
    348 	return bp;
    349 }
    350 
    351 int
    352 eqtype(Type *tp1, Type *tp2, int equiv)
    353 {
    354 	TINT n;
    355 	Type **p1, **p2;
    356 	Symbol **s1, **s2;
    357 
    358 	if (tp1 == tp2)
    359 		return 1;
    360 	if (!tp1 || !tp2)
    361 		return 0;
    362 	if (tp1->op != tp2->op)
    363 		return 0;
    364 
    365 	switch (tp1->op) {
    366 	case UNION:
    367 	case STRUCT:
    368 		if (tp1->letter != tp2->letter)
    369 			return 0;
    370 		if (tp1->tag->name || tp2->tag->name)
    371 			return tp1->tag == tp2->tag;
    372 		if (tp1->n.elem != tp2->n.elem)
    373 			return 0;
    374 		s1 = tp1->p.fields, s2 = tp2->p.fields;
    375 		for (n = tp1->n.elem; n > 0; --n, ++s1, ++s2) {
    376 			if (strcmp((*s1)->name, (*s2)->name))
    377 				return 0;
    378 			if (!eqtype((*s1)->type, (*s2)->type, equiv))
    379 				return 0;
    380 		}
    381 		return 1;
    382 	case FTN:
    383 		if (tp1->n.elem != tp2->n.elem)
    384 			return 0;
    385 		p1 = tp1->p.pars, p2 = tp2->p.pars;
    386 		for (n = tp1->n.elem; n > 0; --n) {
    387 			if (!eqtype(*p1++, *p2++, equiv))
    388 				return 0;
    389 		}
    390 		goto check_base;
    391 	case ARY:
    392 		if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0))
    393 			goto check_base;
    394 		if (tp1->n.elem != tp2->n.elem)
    395 			return 0;
    396 	case PTR:
    397 	check_base:
    398 		return eqtype(tp1->type, tp2->type, equiv);
    399 	case VOID:
    400 	case ENUM:
    401 		return 0;
    402 	case INT:
    403 	case FLOAT:
    404 		return tp1->letter == tp2->letter;
    405 	default:
    406 		abort();
    407 	}
    408 }
    409 
    410 void
    411 flushtypes(void)
    412 {
    413 	Type *tp, *next, **h;
    414 
    415 	for (tp = localtypes; tp; tp = next) {
    416 		next = tp->next;
    417 		switch (tp->op) {
    418 		default:
    419 			/*
    420 			 * All the local types are linked after
    421 			 * global types, and since we are
    422 			 * unlinking them in the inverse order
    423 			 * we do know that tp is always the head
    424 			 * of the collision list
    425 			 */
    426 			h = &typetab[HASH(tp)];
    427 			assert(*h == tp);
    428 			*h = tp->h_next;
    429 		case STRUCT:
    430 		case UNION:
    431 		case ENUM:
    432 			free(tp);
    433 			break;
    434 		}
    435 	}
    436 	localtypes = NULL;
    437 }