scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }