Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

types.c File Reference

#include "c.h"
#include <float.h>

Include dependency graph for types.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  entry

Defines

#define xx(ty)   if (size == (ty)->size) return ty;
#define xx(t)   if (ty->size == t->size) return t
#define xx(name, type)
#define xx(v, t)   if (v==NULL && t->size==voidptype->size && t->align==voidptype->align) v=t
#define xx(v, name, op, metrics)   v=xxinit(op,name,IR->metrics)
#define xx(name)

Functions

Type array (Type ty, int n, int a)
Type atop (Type ty)
Type btot (int op, int size)
Type compose (Type ty1, Type ty2)
Type deref (Type ty)
int eqtype (Type ty1, Type ty2, int ret)
Field fieldlist (Type ty)
Field fieldref (const char *name, Type ty)
Type freturn (Type ty)
Type ftype (Type rty, Type ty)
Type func (Type ty, Type *proto, int style)
int hasproto (Type ty)
Field isfield (const char *, Field)
Field newfield (char *name, Type ty, Type fty)
Type newstruct (int op, char *tag)
void outtype (Type ty, FILE *f)
void printdecl (Symbol p, Type ty)
void printproto (Symbol p, Symbol callee[])
void printtype (Type ty, int fd)
Type promote (Type ty)
void prtype (Type ty, FILE *f, int indent, unsigned mark)
Type ptr (Type ty)
Type qual (int op, Type ty)
void rmtypes (int lev)
Type signedint (Type ty)
int ttob (Type ty)
Type type (int, Type, int, int, void *)
void type_init (int argc, char *argv[])
char * typestring (Type ty, char *str)
int variadic (Type ty)
Type xxinit (int op, char *name, Metrics m)

Variables

Type charptype
Type chartype
Type doubletype
Type floattype
Type funcptype
Type inttype
Type longdouble
Type longlong
Type longtype
int maxlevel
Symbol pointersym
Type shorttype
Type signedchar
Type signedptr
entrytypetable [128]
Type unsignedchar
Type unsignedlong
Type unsignedlonglong
Type unsignedptr
Type unsignedshort
Type unsignedtype
Type voidptype
Type voidtype
Type widechar


Define Documentation

#define xx ty   )     if (size == (ty)->size) return ty;
 

#define xx t   )     if (ty->size == t->size) return t
 

#define xx name,
type   ) 
 

Value:

if (strcmp(argv[i], "-wchar_t=" #name) == 0) \
            widechar = type;

#define xx v,
t   )     if (v==NULL && t->size==voidptype->size && t->align==voidptype->align) v=t
 

#define xx v,
name,
op,
metrics   )     v=xxinit(op,name,IR->metrics)
 

#define xx name   ) 
 

Value:

else if (sscanf(argv[i], "-" #name "=%d,%d,%d", &size, &align, &outofline) == 3) { \
            IR->name.size = size; IR->name.align = align; \
            IR->name.outofline = outofline; }


Function Documentation

Type array Type  ty,
int  n,
int  a
 

Definition at line 202 of file types.c.

References a, Aflag, type::align, ARRAY, array(), assert, error(), INT_MAX, inttype, isarray, isfunc, n, NULL, type::size, type(), Type, unqual, and warning().

00202                                   {
00203     assert(ty);
00204     if (isfunc(ty)) {
00205         error("illegal type `array of %t'\n", ty);
00206         return array(inttype, n, 0);
00207     }
00208     if (isarray(ty) && ty->size == 0)
00209         error("missing array size\n");
00210     if (ty->size == 0) {
00211         if (unqual(ty) == voidtype)
00212             error("illegal type `array of %t'\n", ty);
00213         else if (Aflag >= 2)
00214             warning("declaring type array of %t' is undefined\n", ty);
00215 
00216     } else if (n > INT_MAX/ty->size) {
00217         error("size of `array of %t' exceeds %d bytes\n",
00218             ty, INT_MAX);
00219         n = 1;
00220     }
00221     return type(ARRAY, ty, n*ty->size,
00222         a ? a : ty->align, NULL);
00223 }

Here is the call graph for this function:

Type atop Type  ty  ) 
 

Definition at line 224 of file types.c.

References error(), isarray, ptr(), type::type, and Type.

Referenced by cvtconst(), and dclparam().

00224                    {
00225     if (isarray(ty))
00226         return ptr(ty->type);
00227     error("type error: %s\n", "array expected");
00228     return ptr(ty);
00229 }

Here is the call graph for this function:

Type btot int  op,
int  size
 

Definition at line 447 of file types.c.

References assert, chartype, doubletype, F, floattype, funcptype, I, inttype, longdouble, longlong, longtype, type::op, op, optype, P, shorttype, signedchar, Type, U, unsignedchar, unsignedlong, unsignedlonglong, unsignedshort, unsignedtype, voidptype, and xx.

Referenced by newtemp(), uid2type(), and visit().

00447                             {
00448 #define xx(ty) if (size == (ty)->size) return ty;
00449     switch (optype(op)) {
00450     case F:
00451         xx(floattype);
00452         xx(doubletype);
00453         xx(longdouble);
00454         assert(0); return 0;
00455     case I:
00456         if (chartype->op == INT)
00457             xx(chartype);
00458         xx(signedchar);
00459         xx(shorttype);
00460         xx(inttype);
00461         xx(longtype);
00462         xx(longlong);
00463         assert(0); return 0;
00464     case U:
00465         if (chartype->op == UNSIGNED)
00466             xx(chartype);
00467         xx(unsignedchar);
00468         xx(unsignedshort);
00469         xx(unsignedtype);
00470         xx(unsignedlong);
00471         xx(unsignedlonglong);
00472         assert(0); return 0;
00473     case P:
00474         xx(voidptype);
00475         xx(funcptype);
00476         assert(0); return 0;
00477     }
00478 #undef xx
00479     assert(0); return 0;
00480 }

Type compose Type  ty1,
Type  ty2
 

Definition at line 390 of file types.c.

References type::align, append(), array(), ARRAY, assert, compose(), CONST, type::f, func(), FUNCTION, isconst, isvolatile, List, ltov(), NULL, type::oldstyle, type::op, p2, PERM, POINTER, type::proto, ptr(), qual(), type::size, type::type, Type, type::u, unqual, and VOLATILE.

Referenced by compile(), compose(), dclglobal(), dcllocal(), and filename().

00390                                  {
00391     if (ty1 == ty2)
00392         return ty1;
00393     assert(ty1->op == ty2->op);
00394     switch (ty1->op) {
00395     case POINTER:
00396         return ptr(compose(ty1->type, ty2->type));
00397     case CONST+VOLATILE:
00398         return qual(CONST, qual(VOLATILE,
00399             compose(ty1->type, ty2->type)));
00400     case CONST: case VOLATILE:
00401         return qual(ty1->op, compose(ty1->type, ty2->type));
00402     case ARRAY:    { Type ty = compose(ty1->type, ty2->type);
00403              if (ty1->size && (ty1->type->size && ty2->size == 0 || ty1->size == ty2->size))
00404                 return array(ty, ty1->size/ty1->type->size, ty1->align);
00405              if (ty2->size && ty2->type->size && ty1->size == 0)
00406                 return array(ty, ty2->size/ty2->type->size, ty2->align);
00407              return array(ty, 0, 0);    }
00408     case FUNCTION: { Type *p1  = ty1->u.f.proto, *p2 = ty2->u.f.proto;
00409              Type ty   = compose(ty1->type, ty2->type);
00410              List tlist = NULL;
00411              if (p1 == NULL && p2 == NULL)
00412                 return func(ty, NULL, 1);
00413              if (p1 && p2 == NULL)
00414                 return func(ty, p1, ty1->u.f.oldstyle);
00415              if (p2 && p1 == NULL)
00416                 return func(ty, p2, ty2->u.f.oldstyle);
00417              for ( ; *p1 && *p2; p1++, p2++) {
00418                 Type ty = compose(unqual(*p1), unqual(*p2));
00419                 if (isconst(*p1)    || isconst(*p2))
00420                     ty = qual(CONST, ty);
00421                 if (isvolatile(*p1) || isvolatile(*p2))
00422                     ty = qual(VOLATILE, ty);
00423                 tlist = append(ty, tlist);
00424              }
00425              assert(*p1 == NULL && *p2 == NULL);
00426              return func(ty, ltov(&tlist, PERM), 0); }
00427     }
00428     assert(0); return NULL;
00429 }

Here is the call graph for this function:

Type deref Type  ty  ) 
 

Definition at line 195 of file types.c.

References error(), isenum, isptr, type::type, Type, and unqual.

00195                     {
00196     if (isptr(ty))
00197         ty = ty->type;
00198     else
00199         error("type error: %s\n", "pointer expected");
00200     return isenum(ty) ? unqual(ty)->type : ty;
00201 }

Here is the call graph for this function:

int eqtype Type  ty1,
Type  ty2,
int  ret
 

Definition at line 312 of file types.c.

References ARRAY, assert, CONST, ENUM, type::f, FLOAT, FUNCTION, INT, isenum, NULL, type::op, p2, POINTER, promote(), type::proto, type::size, STRUCT, type::type, Type, type::u, UNION, unqual, UNSIGNED, variadic(), and VOLATILE.

Referenced by constant(), dclglobal(), dcllocal(), and funcdefn().

00312                                         {
00313     if (ty1 == ty2)
00314         return 1;
00315     if (ty1->op != ty2->op)
00316         return 0;
00317     switch (ty1->op) {
00318     case ENUM: case UNION: case STRUCT:
00319     case UNSIGNED: case INT: case FLOAT:
00320         return 0;
00321     case POINTER:  return eqtype(ty1->type, ty2->type, 1);
00322     case VOLATILE: case CONST+VOLATILE:
00323     case CONST:    return eqtype(ty1->type, ty2->type, 1);
00324     case ARRAY:    if (eqtype(ty1->type, ty2->type, 1)) {
00325                 if (ty1->size == ty2->size)
00326                     return 1;
00327                 if (ty1->size == 0 || ty2->size == 0)
00328                     return ret;
00329                }
00330                return 0;
00331     case FUNCTION: if (eqtype(ty1->type, ty2->type, 1)) {
00332                 Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto;
00333                 if (p1 == p2)
00334                     return 1;
00335                 if (p1 && p2) {
00336                     for ( ; *p1 && *p2; p1++, p2++)
00337                     if (eqtype(unqual(*p1), unqual(*p2), 1) == 0)
00338                         return 0;
00339                 if (*p1 == NULL && *p2 == NULL)
00340                     return 1;
00341                 } else {
00342                     if (variadic(p1 ? ty1 : ty2))
00343                     return 0;
00344                 if (p1 == NULL)
00345                     p1 = p2;
00346                 for ( ; *p1; p1++) {
00347                     Type ty = unqual(*p1);
00348                     if (promote(ty) != (isenum(ty) ? ty->type : ty))
00349                         return 0;
00350                 }
00351                 return 1;
00352                 }
00353                }
00354                return 0;
00355     }
00356     assert(0); return 0;
00357 }

Here is the call graph for this function:

Field fieldlist Type  ty  ) 
 

Definition at line 497 of file types.c.

References Field, symbol::flist, symbol::s, type::sym, Type, symbol::u, and type::u.

Referenced by asgncode(), emittype(), and typeuid().

00497                          {
00498     return ty->u.sym->u.s.flist;
00499 }

Field fieldref const char *  name,
Type  ty
 

Definition at line 502 of file types.c.

References assert, Field, isfield(), lookup(), name, p, q, src, Symbol, Type, unqual, and use().

00502                                           {
00503     Field p = isfield(name, unqual(ty)->u.sym->u.s.flist);
00504 
00505     if (p && xref) {
00506         Symbol q;
00507         assert(unqual(ty)->u.sym->u.s.ftab);
00508         q = lookup(name, unqual(ty)->u.sym->u.s.ftab);
00509         assert(q);
00510         use(q, src);
00511     }
00512     return p;
00513 }

Here is the call graph for this function:

Type freturn Type  ty  ) 
 

Definition at line 256 of file types.c.

References error(), isfunc, type::type, and Type.

Referenced by compound(), funcdefn(), printproto(), retcode(), stabsym(), statement(), tracefinis(), and tracereturn().

00256                       {
00257     if (isfunc(ty))
00258         return ty->type;
00259     error("type error: %s\n", "function expected");
00260     return inttype;
00261 }

Here is the call graph for this function:

Type ftype Type  rty,
Type  ty
 

Definition at line 516 of file types.c.

References append(), func(), List, ltov(), NULL, PERM, Type, and voidtype.

Referenced by bbentry(), bbexit(), and trace_init().

00516                               {
00517     List list = append(ty, NULL);
00518 
00519     list = append(voidtype, list);
00520     return func(rty, ltov(&list, PERM), 0);
00521 }

Here is the call graph for this function:

Type func Type  ty,
Type proto,
int  style
 

Definition at line 248 of file types.c.

References error(), type::f, FUNCTION, isarray, isfunc, NULL, type::oldstyle, type::proto, type(), Type, and type::u.

Referenced by AddThread(), compose(), CPUID(), dclr(), ftype(), funcdefn(), logAlphaFunc(), logDepthFunc(), logStencilFunc(), main_init(), printproto(), qglAlphaFunc(), qglDepthFunc(), qglStencilFunc(), RunThreadsOn(), TableForFunc(), type_init(), and uid2type().

00248                                            {
00249     if (ty && (isarray(ty) || isfunc(ty)))
00250         error("illegal return type `%t'\n", ty);
00251     ty = type(FUNCTION, ty, 0, 0, NULL);
00252     ty->u.f.proto = proto;
00253     ty->u.f.oldstyle = style;
00254     return ty;
00255 }

Here is the call graph for this function:

int hasproto Type  ty  ) 
 

Definition at line 481 of file types.c.

References ARRAY, assert, CONST, ENUM, type::f, FLOAT, FUNCTION, INT, type::op, POINTER, type::proto, STRUCT, type::type, Type, type::u, UNION, UNSIGNED, VOID, and VOLATILE.

Referenced by decl(), parameters(), and typename().

00481                       {
00482     if (ty == 0)
00483         return 1;
00484     switch (ty->op) {
00485     case CONST: case VOLATILE: case CONST+VOLATILE: case POINTER:
00486     case ARRAY:
00487         return hasproto(ty->type);
00488     case FUNCTION:
00489         return hasproto(ty->type) && ty->u.f.proto;
00490     case STRUCT: case UNION:
00491     case VOID:   case FLOAT: case ENUM:  case INT: case UNSIGNED:
00492         return 1;
00493     }
00494     assert(0); return 0;
00495 }

Field isfield const char *  ,
Field 
[static]
 

Definition at line 524 of file types.c.

References Field, field::link, and field::name.

Referenced by fieldref().

00524                                                     {
00525     for ( ; flist; flist = flist->link)
00526         if (flist->name == name)
00527             break;
00528     return flist;
00529 }

Field newfield char *  name,
Type  ty,
Type  fty
 

Definition at line 292 of file types.c.

References error(), Field, symbol::flist, symbol::ftab, genlabel(), install(), level, field::link, field::name, name, NEW0, NULL, p, PERM, q, symbol::s, symbol::src, stringd(), type::sym, table(), field::type, Type, symbol::u, and type::u.

00292                                               {
00293     Field p, *q = &ty->u.sym->u.s.flist;
00294 
00295     if (name == NULL)
00296         name = stringd(genlabel(1));
00297     for (p = *q; p; q = &p->link, p = *q)
00298         if (p->name == name)
00299             error("duplicate field name `%s' in `%t'\n",
00300                 name, ty);
00301     NEW0(p, PERM);
00302     *q = p;
00303     p->name = name;
00304     p->type = fty;
00305     if (xref) {                         /* omit */
00306         if (ty->u.sym->u.s.ftab == NULL)            /* omit */
00307             ty->u.sym->u.s.ftab = table(NULL, level);   /* omit */
00308         install(name, &ty->u.sym->u.s.ftab, 0, PERM)->src = src;/* omit */
00309     }                               /* omit */
00310     return p;
00311 }

Here is the call graph for this function:

Type newstruct int  op,
char *  tag
 

Definition at line 271 of file types.c.

References assert, symbol::defined, error(), genlabel(), install(), level, lookup(), maxlevel, symbol::name, NULL, op, type::op, p, PARAM, PERM, symbol::scope, symbol::src, stringd(), Symbol, type(), symbol::type, Type, and types.

Referenced by enumdcl(), structdcl(), and uid2type().

00271                                   {
00272     Symbol p;
00273 
00274     assert(tag);
00275     if (*tag == 0)
00276         tag = stringd(genlabel(1));
00277     else
00278         if ((p = lookup(tag, types)) != NULL && (p->scope == level
00279         || p->scope == PARAM && level == PARAM+1)) {
00280             if (p->type->op == op && !p->defined)
00281                 return p->type;
00282             error("redefinition of `%s' previously defined at %w\n",
00283                 p->name, &p->src);
00284         }
00285     p = install(tag, &types, level, PERM);
00286     p->type = type(op, NULL, 0, 0, p);
00287     if (p->scope > maxlevel)
00288         maxlevel = p->scope;
00289     p->src = src;
00290     return p->type;
00291 }

Here is the call graph for this function:

void outtype Type  ty,
FILE f
 

Definition at line 532 of file types.c.

References ARRAY, assert, CONST, ENUM, type::f, f, findtype(), FLOAT, fprint(), FUNCTION, i, INT, isarray, symbol::name, type::op, p, POINTER, type::proto, type::size, symbol::src, STRUCT, type::sym, Symbol, type::type, Type, type::u, UNION, UNSIGNED, VOID, and VOLATILE.

Referenced by vfprint().

00532                                {
00533     switch (ty->op) {
00534     case CONST+VOLATILE: case CONST: case VOLATILE:
00535         fprint(f, "%k %t", ty->op, ty->type);
00536         break;
00537     case STRUCT: case UNION: case ENUM:
00538         assert(ty->u.sym);
00539         if (ty->size == 0)
00540             fprint(f, "incomplete ");
00541         assert(ty->u.sym->name);
00542         if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') {
00543             Symbol p = findtype(ty);
00544             if (p == 0)
00545                 fprint(f, "%k defined at %w", ty->op, &ty->u.sym->src);
00546             else
00547                 fprint(f, p->name);
00548         } else {
00549             fprint(f, "%k %s", ty->op, ty->u.sym->name);
00550             if (ty->size == 0)
00551                 fprint(f, " defined at %w", &ty->u.sym->src);
00552         }
00553         break;
00554     case VOID: case FLOAT: case INT: case UNSIGNED:
00555         fprint(f, ty->u.sym->name);
00556         break;
00557     case POINTER:
00558         fprint(f, "pointer to %t", ty->type);
00559         break;
00560     case FUNCTION:
00561         fprint(f, "%t function", ty->type);
00562         if (ty->u.f.proto && ty->u.f.proto[0]) {
00563             int i;
00564             fprint(f, "(%t", ty->u.f.proto[0]);
00565             for (i = 1; ty->u.f.proto[i]; i++)
00566                 if (ty->u.f.proto[i] == voidtype)
00567                     fprint(f, ",...");
00568                 else
00569                     fprint(f, ",%t", ty->u.f.proto[i]);
00570             fprint(f, ")");
00571         } else if (ty->u.f.proto && ty->u.f.proto[0] == 0)
00572             fprint(f, "(void)");
00573 
00574         break;
00575     case ARRAY:
00576         if (ty->size > 0 && ty->type && ty->type->size > 0) {
00577             fprint(f, "array %d", ty->size/ty->type->size);
00578             while (ty->type && isarray(ty->type) && ty->type->type->size > 0) {
00579                 ty = ty->type;
00580                 fprint(f, ",%d", ty->size/ty->type->size);
00581             }
00582         } else
00583             fprint(f, "incomplete array");
00584         if (ty->type)
00585             fprint(f, " of %t", ty->type);
00586         break;
00587     default: assert(0);
00588     }
00589 }

Here is the call graph for this function:

void printdecl Symbol  p,
Type  ty
 

Definition at line 592 of file types.c.

References assert, ENUM, EXTERN, fprint(), symbol::name, p, symbol::sclass, stderr, Symbol, Type, and typestring().

Referenced by doglobal(), and printproto().

00592                                   {
00593     switch (p->sclass) {
00594     case AUTO:
00595         fprint(stderr, "%s;\n", typestring(ty, p->name));
00596         break;
00597     case STATIC: case EXTERN:
00598         fprint(stderr, "%k %s;\n", p->sclass, typestring(ty, p->name));
00599         break;
00600     case TYPEDEF: case ENUM:
00601         break;
00602     default: assert(0);
00603     }
00604 }

Here is the call graph for this function:

void printproto Symbol  p,
Symbol  callee[]
 

Definition at line 607 of file types.c.

References append(), type::f, freturn(), func(), i, List, ltov(), p, PERM, printdecl(), type::proto, Symbol, symbol::type, type::u, and voidtype.

Referenced by funcdefn().

00607                                            {
00608     if (p->type->u.f.proto)
00609         printdecl(p, p->type);
00610     else {
00611         int i;
00612         List list = 0;
00613         if (callee[0] == 0)
00614             list = append(voidtype, list);
00615         else
00616             for (i = 0; callee[i]; i++)
00617                 list = append(callee[i]->type, list);
00618         printdecl(p, func(freturn(p->type), ltov(&list, PERM), 0));
00619     }
00620 }

Here is the call graph for this function:

void printtype Type  ty,
int  fd
 

Definition at line 684 of file types.c.

References fprint(), prtype(), stderr, stdout, and Type.