scc

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

types.c (9275B)


      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 	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 			type = (*sp)->type;
    210 			a = type->align;
    211 			if (a > align)
    212 				align = a;
    213 			if (tp->op == STRUCT) {
    214 				if (--a != 0)
    215 					offset = (offset + a) & ~a;
    216 				(*sp)->u.i = offset;
    217 				size = offset + type->size;
    218 				offset = size;
    219 			} else {
    220 				(*sp)->u.i = 0;
    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 	} else if (tp->op == ARY) {
    270 		/* We need alignment for flexible array members */
    271 		tp->align = tp->type->align;
    272 	}
    273 
    274 	if (curfun) {
    275 		/* it is a type defined in the body of a function */
    276 		tp->next = localtypes;
    277 		localtypes = tp;
    278 	}
    279 	if (tp->prop & TDEFINED)
    280 		deftype(tp);
    281 	return tp;
    282 }
    283 
    284 Type *
    285 mktype(Type *tp, int op, TINT nelem, Type *pars[])
    286 {
    287 	Type **tbl, type;
    288 	Type *bp;
    289 
    290 	if (op == PTR && tp == voidtype)
    291 		return pvoidtype;
    292 
    293 	type = (Type) {
    294 		.type = tp,
    295 		.op = op,
    296 		.p.pars = pars,
    297 		.n.elem = nelem,
    298 	};
    299 
    300 	switch (op) {
    301 	case ARY:
    302 		if (tp == voidtype) {
    303 			errorp("declaration of array of voids type");
    304 			tp = inttype;
    305 		}
    306 		type.letter = L_ARRAY;
    307 		if (nelem != 0)
    308 			type.prop |= TDEFINED;
    309 		break;
    310 	case KRFTN:
    311 		type.prop |= TDEFINED | TK_R;
    312 		type.op = FTN;
    313 		type.letter = L_FUNCTION;
    314 		break;
    315 	case FTN:
    316 		if (nelem > 0 && pars[nelem-1] == ellipsistype)
    317 			type.prop |= TELLIPSIS;
    318 		type.letter = L_FUNCTION;
    319 		type.prop |= TDEFINED;
    320 		break;
    321 	case PTR:
    322 	        type.letter = L_POINTER;
    323 		type.prop |= TDEFINED;
    324 		break;
    325 	case ENUM:
    326 		type.letter = inttype->letter;
    327 		type.prop |= TINTEGER | TARITH;
    328 		type.n.rank = inttype->n.rank;
    329 		goto create_type;
    330 	case STRUCT:
    331 		type.letter = L_STRUCT;
    332 		type.prop |= TAGGREG;
    333 		goto create_type;
    334 	case UNION:
    335 		type.letter = L_UNION;
    336 		type.prop |= TAGGREG;
    337 	create_type:
    338 		return newtype(&type);
    339 	default:
    340 		abort();
    341 	}
    342 
    343 	tbl = &typetab[HASH(&type)];
    344 	for (bp = *tbl; bp; bp = bp->h_next) {
    345 		if (eqtype(bp, &type, EQUAL))
    346 			return bp;
    347 	}
    348 
    349 	bp = newtype(&type);
    350 	bp->h_next = *tbl;
    351 	*tbl = bp;
    352 
    353 	return bp;
    354 }
    355 
    356 /*
    357  * If one type has a parameter type list and the other type is specified by
    358  * a function declarator that is not part of a function definition and that
    359  * contains an empty identifier list, the parameter list shall not have an
    360  * ellipsis terminator and the type of each parameter shall be compatible
    361  * with the type that results from the application of the default argument
    362  * promotions.
    363  */
    364 static int
    365 eqfuns(Type *tp1, Type *tp2, int equiv)
    366 {
    367 	TINT n;
    368 	int f1kr, f2kr;
    369 	Type *krf, *ansi, **pp, *p;
    370 
    371 	f1kr = (tp1->prop&TK_R) != 0;
    372 	f2kr = (tp2->prop&TK_R) != 0;
    373 
    374 	/* 1: 2 ansi functions */
    375 	if (!f1kr && !f2kr) {
    376 		Type **p1, **p2;
    377 		if (tp1->n.elem != tp2->n.elem)
    378 			return 0;
    379 		p1 = tp1->p.pars, p2 = tp2->p.pars;
    380 		for (n = tp1->n.elem; n > 0; --n) {
    381 			if (!eqtype(*p1++, *p2++, equiv))
    382 				return 0;
    383 		}
    384 		goto check_base;
    385 	}
    386 
    387 	/* 2: 2 k&r functions */
    388 	if (f1kr && f2kr)
    389 		goto check_base;
    390 
    391 	/* 3: 1 k&r function + 1 ansi function */
    392 	if (!equiv)
    393 		return 0;
    394 
    395 	if (f1kr) {
    396 		krf = tp1;
    397 		ansi = tp2;
    398 	} else {
    399 		ansi = tp1;
    400 		krf = tp2;
    401 	}
    402 
    403 	for (pp = ansi->p.pars; p = *pp; ++pp) {
    404 		switch (p->op) {
    405 		case ELLIPSIS:
    406 			return 0;
    407 		case INT:
    408 		case ENUM:
    409 			if (p->n.rank < inttype->n.rank)
    410 				return 0;
    411 			break;
    412 		case FLOAT:
    413 			if (p == floattype)
    414 				return 0;
    415 			break;
    416 		}
    417 	}
    418 
    419 check_base:
    420 	return eqtype(tp1->type, tp2->type, equiv);
    421 }
    422 
    423 int
    424 eqtype(Type *tp1, Type *tp2, int equiv)
    425 {
    426 	TINT n;
    427 	Symbol **s1, **s2;
    428 
    429 	if (tp1 == tp2)
    430 		return 1;
    431 	if (!tp1 || !tp2)
    432 		return 0;
    433 	if (tp1->op != tp2->op)
    434 		return 0;
    435 
    436 	switch (tp1->op) {
    437 	case UNION:
    438 	case STRUCT:
    439 		if (tp1->letter != tp2->letter)
    440 			return 0;
    441 		if (tp1->tag->name || tp2->tag->name)
    442 			return tp1->tag == tp2->tag;
    443 		if (tp1->n.elem != tp2->n.elem)
    444 			return 0;
    445 		s1 = tp1->p.fields, s2 = tp2->p.fields;
    446 		for (n = tp1->n.elem; n > 0; --n, ++s1, ++s2) {
    447 			if (strcmp((*s1)->name, (*s2)->name))
    448 				return 0;
    449 			if (!eqtype((*s1)->type, (*s2)->type, equiv))
    450 				return 0;
    451 		}
    452 		return 1;
    453 	case FTN:
    454 		return eqfuns(tp1, tp2, equiv);
    455 	case ARY:
    456 		if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0))
    457 			goto check_base;
    458 		if (tp1->n.elem != tp2->n.elem)
    459 			return 0;
    460 	case PTR:
    461 	check_base:
    462 		return eqtype(tp1->type, tp2->type, equiv);
    463 	case VOID:
    464 	case ENUM:
    465 		return 0;
    466 	case INT:
    467 	case FLOAT:
    468 		return tp1->letter == tp2->letter;
    469 	default:
    470 		abort();
    471 	}
    472 }
    473 
    474 void
    475 flushtypes(void)
    476 {
    477 	Type *tp, *next, **h;
    478 
    479 	for (tp = localtypes; tp; tp = next) {
    480 		next = tp->next;
    481 		switch (tp->op) {
    482 		default:
    483 			/*
    484 			 * All the local types are linked after
    485 			 * global types, and since we are
    486 			 * unlinking them in the inverse order
    487 			 * we do know that tp is always the head
    488 			 * of the collision list
    489 			 */
    490 			h = &typetab[HASH(tp)];
    491 			assert(*h == tp);
    492 			*h = tp->h_next;
    493 		case STRUCT:
    494 		case UNION:
    495 		case ENUM:
    496 			free(tp);
    497 			break;
    498 		}
    499 	}
    500 	localtypes = NULL;
    501 }