scc

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

types.c (8014B)


      1 static char sccsid[] = "@(#) ./cc1/types.c";
      2 #include <assert.h>
      3 #include <inttypes.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include <scc/cstd.h>
      8 #include <scc/scc.h>
      9 #include "cc1.h"
     10 
     11 #define NR_TYPE_HASH 16
     12 #define HASH(t) (((t)->op ^ (uintptr_t) (t)->type>>3) & NR_TYPE_HASH-1)
     13 
     14 static Type *typetab[NR_TYPE_HASH], *localtypes;
     15 
     16 /* FIXME:
     17  * Compiler can generate warnings here if the ranges of TINT,
     18  * TUINT and TFLOAT are smaller than any of the constants in this
     19  * array. Ignore them if you know that the target types are correct
     20  */
     21 static struct limits limits[][4] = {
     22 	{
     23 		{	/* 0 = unsigned 1 byte */
     24 			.min.i = 0,
     25 			.max.i = 0xff
     26 		},
     27 		{	/* 1 = unsigned 2 bytes */
     28 			.min.i = 0,
     29 			.max.i = 0xffff
     30 		},
     31 		{	/* 2 = unsigned 4 bytes */
     32 			.min.i = 0,
     33 			.max.i = 0xffffffff
     34 		},
     35 		{	/* 3 = unsigned 8 bytes */
     36 			.min.i = 0,
     37 			.max.i = 0xffffffffffffffff
     38 		}
     39 	},
     40 	{
     41 		{	/* 0 = signed 1 byte */
     42 			.min.i = -0x7f-1,
     43 			.max.i = 0x7f
     44 		},
     45 		{	/* 1 = signed 2 byte */
     46 			.min.i = -0x7fff-1,
     47 			.max.i = 0x7fff
     48 		},
     49 		{	/* 2 = signed 4 byte */
     50 			.min.i = -0x7fffffff-1,
     51 			.max.i = 0x7fffffff
     52 		},
     53 		{	/* 3 = signed 8 byte */
     54 			.min.i = -0x7fffffffffffffff-1,
     55 			.max.i = 0x7fffffffffffffff,
     56 		}
     57 	},
     58 	{
     59 		{
     60 			/* 0 = float 4 bytes */
     61 			.min.f = -1,
     62 			.max.f = 2
     63 		},
     64 		{
     65 			/* 1 = float 8 bytes */
     66 			.min.f = -1,
     67 			.max.f = 2,
     68 		},
     69 		{
     70 			/* 2 = float 16 bytes */
     71 			.min.f = -1,
     72 			.max.f = 2,
     73 		}
     74 	}
     75 };
     76 
     77 struct limits *
     78 getlimits(Type *tp)
     79 {
     80 	int ntable, ntype;
     81 
     82 	switch (tp->op) {
     83 	case ENUM:
     84 	case INT:
     85 		ntable = ((tp->prop & TSIGNED) != 0);
     86 		switch (tp->size) {
     87 		case 1: ntype = 0; break;
     88 		case 2: ntype = 1; break;
     89 		case 4: ntype = 2; break;
     90 		case 8: ntype = 3; break;
     91 		}
     92 		break;
     93 	case FLOAT:
     94 		ntable = 2;
     95 		switch (tp->size) {
     96 		case 4:  ntype = 0; break;
     97 		case 8:  ntype = 1; break;
     98 		case 16: ntype = 2; break;
     99 		}
    100 		break;
    101 	default:
    102 		abort();
    103 	}
    104 
    105 	return &limits[ntable][ntype];
    106 }
    107 
    108 Type *
    109 ctype(int type, int sign, int size)
    110 {
    111 	switch (type) {
    112 	case CHAR:
    113 		if (size)
    114 			goto invalid_type;
    115 		switch (sign) {
    116 		case 0:
    117 			return chartype;
    118 		case SIGNED:
    119 			return schartype;
    120 		case UNSIGNED:
    121 			return uchartype;
    122 		}
    123 		break;
    124 	case VA_LIST:
    125 		if (size || sign)
    126 			goto invalid_type;
    127 		return va_list_type;
    128 	case VOID:
    129 		if (size || sign)
    130 			goto invalid_type;
    131 		return voidtype;
    132 	case BOOL:
    133 		if (size || sign)
    134 			goto invalid_type;
    135 		return booltype;
    136 	case 0:
    137 	case INT:
    138 		switch (size) {
    139 		case 0:
    140 			return (sign == UNSIGNED) ? uinttype   : inttype;
    141 		case SHORT:
    142 			return (sign == UNSIGNED) ? ushortype  : shortype;
    143 		case LONG:
    144 			return (sign == UNSIGNED) ? ulongtype  : longtype;
    145 		case LLONG:
    146 			return (sign == UNSIGNED) ? ullongtype : llongtype;
    147 		}
    148 		break;
    149 	case DOUBLE:
    150 		if (size == LLONG)
    151 			goto invalid_type;
    152 		if (size == LONG)
    153 			size = LLONG;
    154 		else
    155 			size = LONG;
    156 		goto floating;
    157 	case FLOAT:
    158 		if (size == LLONG)
    159 			goto invalid_type;
    160 	floating:
    161 		if (sign)
    162 			goto invalid_type;
    163 		switch (size) {
    164 		case 0:
    165 			return floattype;
    166 		case LONG:
    167 			return doubletype;
    168 		case LLONG:
    169 			return ldoubletype;
    170 		}
    171 		break;
    172 	}
    173 
    174 invalid_type:
    175 	error("invalid type specification");
    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 			(*sp)->u.i = offset;
    211 			type = (*sp)->type;
    212 			a = type->align;
    213 			if (a > align)
    214 				align = a;
    215 			if (tp->op == STRUCT) {
    216 				if (--a != 0)
    217 					size = (size + a) & ~a;
    218 				size += type->size;
    219 				offset = size;
    220 			} else {
    221 				if (type->size > size)
    222 					size = type->size;
    223 			}
    224 		}
    225 
    226 		tp->align = align;
    227 		/*
    228 		 * We have to add the padding bits to
    229 		 * ensure next struct in an array is well
    230 		 * alignment.
    231 		 */
    232 		if (tp->op == STRUCT && align-- > 1)
    233 			size += size+align & ~align;
    234 		tp->size = size;
    235 		return;
    236 	case ENUM:
    237 		tp->size = inttype->size;
    238 		tp->align = inttype->align;
    239 		return;
    240 	case FTN:
    241 		return;
    242 	default:
    243 		abort();
    244 	}
    245 }
    246 
    247 Type *
    248 deftype(Type *tp)
    249 {
    250 	tp->prop |= TDEFINED;
    251 	typesize(tp);
    252 	emit(OTYP, tp);
    253 	return tp;
    254 }
    255 
    256 static Type *
    257 newtype(Type *base)
    258 {
    259 	Type *tp;
    260 	size_t siz;
    261 
    262 	tp = xmalloc(sizeof(*tp));
    263 	*tp = *base;
    264 	tp->id = newid();
    265 
    266 	if (tp->op == FTN) {
    267 		siz = tp->n.elem * sizeof(Type *);
    268 		tp->p.pars = memcpy(xmalloc(siz), tp->p.pars, siz);
    269 	}
    270 
    271 	if (curfun) {
    272 		/* it is a type defined in the body of a function */
    273 		tp->next = localtypes;
    274 		localtypes = tp;
    275 	}
    276 	if (tp->prop & TDEFINED)
    277 		deftype(tp);
    278 	return tp;
    279 }
    280 
    281 Type *
    282 mktype(Type *tp, int op, TINT nelem, Type *pars[])
    283 {
    284 	Type **tbl, type;
    285 	Type *bp;
    286 
    287 	if (op == PTR && tp == voidtype)
    288 		return pvoidtype;
    289 
    290 	memset(&type, 0, sizeof(type));
    291 	type.type = tp;
    292 	type.op = op;
    293 	type.p.pars = pars;
    294 	type.n.elem = nelem;
    295 
    296 	switch (op) {
    297 	case ARY:
    298 		if (tp == voidtype) {
    299 			errorp("declaration of array of voids type");
    300 			tp = inttype;
    301 		}
    302 		type.letter = L_ARRAY;
    303 		if (nelem != 0)
    304 			type.prop |= TDEFINED;
    305 		break;
    306 	case KRFTN:
    307 		type.prop |= TDEFINED | TK_R;
    308 		type.op = FTN;
    309 		type.letter = L_FUNCTION;
    310 		break;
    311 	case FTN:
    312 		if (nelem > 0 && pars[nelem-1] == ellipsistype)
    313 			type.prop |= TELLIPSIS;
    314 		type.letter = L_FUNCTION;
    315 		type.prop |= TDEFINED;
    316 		break;
    317 	case PTR:
    318 	        type.letter = L_POINTER;
    319 		type.prop |= TDEFINED;
    320 		break;
    321 	case ENUM:
    322 		type.letter = inttype->letter;
    323 		type.prop |= TINTEGER | TARITH;
    324 		type.n.rank = inttype->n.rank;
    325 		goto create_type;
    326 	case STRUCT:
    327 		type.letter = L_STRUCT;
    328 		type.prop |= TAGGREG;
    329 		goto create_type;
    330 	case UNION:
    331 		type.letter = L_UNION;
    332 		type.prop |= TAGGREG;
    333 	create_type:
    334 		return newtype(&type);
    335 	default:
    336 		abort();
    337 	}
    338 
    339 	tbl = &typetab[HASH(&type)];
    340 	for (bp = *tbl; bp; bp = bp->h_next) {
    341 		if (eqtype(bp, &type, 0))
    342 			return bp;
    343 	}
    344 
    345 	bp = newtype(&type);
    346 	bp->h_next = *tbl;
    347 	*tbl = bp;
    348 
    349 	return bp;
    350 }
    351 
    352 int
    353 eqtype(Type *tp1, Type *tp2, int equiv)
    354 {
    355 	TINT n;
    356 	Type **p1, **p2;
    357 	Symbol **s1, **s2;
    358 
    359 	if (tp1 == tp2)
    360 		return 1;
    361 	if (!tp1 || !tp2)
    362 		return 0;
    363 	if (tp1->op != tp2->op)
    364 		return 0;
    365 
    366 	switch (tp1->op) {
    367 	case UNION:
    368 	case STRUCT:
    369 		if (tp1->letter != tp2->letter)
    370 			return 0;
    371 		if (tp1->tag->name || tp2->tag->name)
    372 			return tp1->tag == tp2->tag;
    373 		if (tp1->n.elem != tp2->n.elem)
    374 			return 0;
    375 		s1 = tp1->p.fields, s2 = tp2->p.fields;
    376 		for (n = tp1->n.elem; n > 0; --n, ++s1, ++s2) {
    377 			if (strcmp((*s1)->name, (*s2)->name))
    378 				return 0;
    379 			if (!eqtype((*s1)->type, (*s2)->type, equiv))
    380 				return 0;
    381 		}
    382 		return 1;
    383 	case FTN:
    384 		if (tp1->n.elem != tp2->n.elem)
    385 			return 0;
    386 		p1 = tp1->p.pars, p2 = tp2->p.pars;
    387 		for (n = tp1->n.elem; n > 0; --n) {
    388 			if (!eqtype(*p1++, *p2++, equiv))
    389 				return 0;
    390 		}
    391 		goto check_base;
    392 	case ARY:
    393 		if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0))
    394 			goto check_base;
    395 		if (tp1->n.elem != tp2->n.elem)
    396 			return 0;
    397 	case PTR:
    398 	check_base:
    399 		return eqtype(tp1->type, tp2->type, equiv);
    400 	case VOID:
    401 	case ENUM:
    402 		return 0;
    403 	case INT:
    404 	case FLOAT:
    405 		return tp1->letter == tp2->letter;
    406 	default:
    407 		abort();
    408 	}
    409 }
    410 
    411 void
    412 flushtypes(void)
    413 {
    414 	Type *tp, *next, **h;
    415 
    416 	for (tp = localtypes; tp; tp = next) {
    417 		next = tp->next;
    418 		switch (tp->op) {
    419 		default:
    420 			/*
    421 			 * All the local types are linked after
    422 			 * global types, and since we are
    423 			 * unlinking them in the inverse order
    424 			 * we do know that tp is always the head
    425 			 * of the collision list
    426 			 */
    427 			h = &typetab[HASH(tp)];
    428 			assert(*h == tp);
    429 			*h = tp->h_next;
    430 		case STRUCT:
    431 		case UNION:
    432 		case ENUM:
    433 			free(tp);
    434 			break;
    435 		}
    436 	}
    437 	localtypes = NULL;
    438 }