#ifndef TYPE_H_ #define TYPE_H_ #include "common.h" enum qualifier { QCONST = 1<<0, QVOLATILE = 1<<1, }; enum typetag { /* ordering is important here! */ TYXXX, TYENUM, TYBOOL, TYCHAR, TYSCHAR, TYUCHAR, TYSHORT, TYUSHORT, TYINT, TYUINT, TYLONG, TYULONG, TYVLONG, TYUVLONG, TYFLOAT, TYDOUBLE, TYLDOUBLE, TYCOMPLEXF, TYCOMPLEX, TYCOMPLEXL, TYVOID, TYPTR, TYARRAY, TYFUNC, TYSTRUCT, TYUNION, NTYPETAG, TYSIGNEDSET_ = 1<> (t) & 1) #define isunsignedt(t) ((TYUNSIGNEDSET_ | !targ_charsigned << TYCHAR) >> (t) & 1) #define isfltt(t) in_range((t), TYFLOAT, TYLDOUBLE) #define isaritht(t) in_range((t), TYENUM, TYCOMPLEXL) #define isscalart(t) (TYSCALARSET_ >> (t) & 1) #define isptrcvtt(t) in_range((t), TYPTR, TYFUNC) #define isaggt(t) in_range((t), TYSTRUCT, TYUNION) #define isprim(ty) isprimt((ty).t) #define isint(ty) isintt((ty).t) #define issigned(ty) issignedt(scalartypet(ty)) #define isunsigned(ty) isunsignedt(scalartypet(ty)) #define isflt(ty) isfltt((ty).t) #define isarith(ty) isaritht((ty).t) #define isscalar(ty) isscalart((ty).t) #define isptrcvt(ty) isptrcvtt((ty).t) #define isagg(ty) isaggt((ty).t) #define iscomplext(t) in_range((t), TYCOMPLEXF, TYCOMPLEXL) #define iscomplex(ty) iscomplext((ty).t) #define mktype(...) ((union type) {{ __VA_ARGS__ }}) struct enumvar { internstr name; union { vlong i; uvlong u; }; }; struct fielddata { union type t; ushort off; uchar bitsiz, bitoff : 6, qual : 2; }; struct namedfield { internstr name; struct fielddata f; }; struct typedata { uchar t; ushort id; union { union type child; const union type *param; /* functions */ struct { /* aggregates */ struct namedfield *fld; }; struct { /* enum */ uchar backing; struct enumvar *var; }; }; union { uint arrlen; /* array */ struct { short nmemb; /* functions, aggregates, enums */ uchar align; union { struct { /* function */ bool kandr : 1, variadic : 1; }; struct { /* aggregate */ bool anyconst : 1, flexi : 1; }; }; }; }; union { uint siz; /* aggregate & array */ union type ret; /* function */ }; }; extern struct typedata typedata[]; extern internstr ttypenames[/*id*/]; bool isincomplete(union type); uint typesize(union type); uint typealign(union type); union type mkptrtype(union type, int qual); union type mkarrtype(union type t, int qual, uint n); union type mkfntype(union type ret, uint n, const union type *, bool kandr, bool variadic); union type mktagtype(internstr name, struct typedata *td); bool getfield(struct fielddata *res, union type, internstr); union type completetype(internstr name, int id, struct typedata *td); union type typedecay(union type); bool assigncompat(union type dst, union type src); enum typetag intpromote(enum typetag); union type cvtarith(union type a, union type b); static inline union type typechild(union type t) { if (t.t == TYENUM) return mktype(t.backing ? t.backing : typedata[t.dat].backing); if (t.flag & TFCHLDPRIM) return mktype(t.child); if (t.flag & TFCHLDISDAT) { union type chld = mktype(typedata[t.dat].t, .dat = t.dat); if (chld.t == TYENUM) chld.backing = typedata[t.dat].backing; return chld; } return typedata[t.dat].child; } static inline enum typetag scalartypet(union type t) { if (t.t == TYENUM) return t.backing ? t.backing : typedata[t.dat].backing; if (isptrcvt(t)) return TYPTR; assert(!iscomplex(t)); return t.t; } static inline uint typearrlen(union type t) { return (t.flag & TFCHLDPRIM) ? t.arrlen : typedata[t.dat].arrlen; } /**********/ /* Target */ /**********/ extern uint targ_valistsize; extern uchar targ_primsizes[]; extern uchar targ_primalign[]; extern enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype; extern bool targ_charsigned, targ_bigendian, targ_64bit; #endif /* vim:set ts=3 sw=3 expandtab: */