1#include <assert.h>2#include <inttypes.h>3#include <stdlib.h>4#include <string.h>56#include <scc/cstd.h>7#include <scc/scc.h>8#include "cc1.h"910#define NR_TYPE_HASH 1611#define HASH(t) (((t)->op ^ (uintptr_t) (t)->type>>3) & NR_TYPE_HASH-1)1213static Type *typetab[NR_TYPE_HASH], *localtypes;1415/* FIXME:16 * Compiler can generate warnings here if the ranges of long long,17 * unsigned long long and double are smaller than any of the constants in this18 * array. Ignore them if you know that the target types are correct19 */20static struct limits limits[][4] = {21 {22 { /* 0 = unsigned 1 byte */23 .min.i = 0,24 .max.i = 0xff25 },26 { /* 1 = unsigned 2 bytes */27 .min.i = 0,28 .max.i = 0xffff29 },30 { /* 2 = unsigned 4 bytes */31 .min.i = 0,32 .max.i = 0xffffffff33 },34 { /* 3 = unsigned 8 bytes */35 .min.i = 0,36 .max.i = 0xffffffffffffffff37 }38 },39 {40 { /* 0 = signed 1 byte */41 .min.i = -0x7f-1,42 .max.i = 0x7f43 },44 { /* 1 = signed 2 byte */45 .min.i = -0x7fff-1,46 .max.i = 0x7fff47 },48 { /* 2 = signed 4 byte */49 .min.i = -0x7fffffff-1,50 .max.i = 0x7fffffff51 },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 = 262 },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};7576struct limits *77getlimits(Type *tp)78{79 int ntable, ntype;8081 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 }103104 return &limits[ntable][ntype];105}106107Type *108ctype(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 else154 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 }172173invalid_type:174 errorp("invalid type specification");175 return inttype;176}177178void179typesize(Type *tp)180{181 Symbol **sp;182 Type *type;183 unsigned long size, offset;184 int align, a;185 long long n;186187 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 is202 * the alignment of the largest included type.203 * The size of an union is the size of the largest204 * field, and the size of a struct is the sum205 * 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 }226227 tp->align = align;228 /*229 * We have to add the padding bits to230 * ensure next struct in an array is well231 * 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}247248Type *249deftype(Type *tp)250{251 tp->prop |= TDEFINED;252 typesize(tp);253 emit(OTYP, tp);254 return tp;255}256257static Type *258newtype(Type *base)259{260 Type *tp, **pars;261 size_t siz;262263 tp = xmalloc(sizeof(*tp));264 *tp = *base;265 tp->id = newid();266267 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 }278279 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}288289Type *290mktype(Type *tp, int op, long long nelem, Type *pars[])291{292 Type **tbl, type;293 Type *bp;294295 if (op == PTR && tp == voidtype)296 return pvoidtype;297298 type = (Type) {299 .type = tp,300 .op = op,301 .p.pars = pars,302 .n.elem = nelem,303 };304305 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 }347348 tbl = &typetab[HASH(&type)];349 for (bp = *tbl; bp; bp = bp->h_next) {350 if (eqtype(bp, &type, EQUAL))351 return bp;352 }353354 bp = newtype(&type);355 bp->h_next = *tbl;356 *tbl = bp;357358 return bp;359}360361/*362 * If one type has a parameter type list and the other type is specified by363 * a function declarator that is not part of a function definition and that364 * contains an empty identifier list, the parameter list shall not have an365 * ellipsis terminator and the type of each parameter shall be compatible366 * with the type that results from the application of the default argument367 * promotions.368 */369static int370eqfuns(Type *tp1, Type *tp2, int equiv)371{372 long long n;373 int f1kr, f2kr;374 Type *krf, *ansi, **pp, *p;375376 f1kr = (tp1->prop&TK_R) != 0;377 f2kr = (tp2->prop&TK_R) != 0;378379 /* 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 }391392 /* 2: 2 k&r functions */393 if (f1kr && f2kr)394 goto check_base;395396 /* 3: 1 k&r function + 1 ansi function */397 if (!equiv)398 return 0;399400 if (f1kr) {401 krf = tp1;402 ansi = tp2;403 } else {404 ansi = tp1;405 krf = tp2;406 }407408 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 }423424check_base:425 return eqtype(tp1->type, tp2->type, equiv);426}427428int429eqtype(Type *tp1, Type *tp2, int equiv)430{431 long long n;432 Symbol **s1, **s2;433434 if (tp1 == tp2)435 return 1;436 if (!tp1 || !tp2)437 return 0;438 if (tp1->op != tp2->op)439 return 0;440441 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}478479void480flushtypes(void)481{482 Type *tp, *next, **h;483484 for (tp = localtypes; tp; tp = next) {485 next = tp->next;486 switch (tp->op) {487 default:488 /*489 * All the local types are linked after490 * global types, and since we are491 * unlinking them in the inverse order492 * we do know that tp is always the head493 * of the collision list494 */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}