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 }