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