diff options
| author | 2026-03-17 13:22:00 +0100 | |
|---|---|---|
| committer | 2026-03-17 13:22:00 +0100 | |
| commit | a8d6f8bf30c07edb775e56889f568ca20240bedf (patch) | |
| tree | b5a452b2675b2400f15013617291fe6061180bbf /src/c_type.h | |
| parent | 24f14b7ad1af08d872971d72ce089a529911f657 (diff) | |
REFACTOR: move sources to src/
Diffstat (limited to 'src/c_type.h')
| -rw-r--r-- | src/c_type.h | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/c_type.h b/src/c_type.h new file mode 100644 index 0000000..ad8e1b1 --- /dev/null +++ b/src/c_type.h @@ -0,0 +1,177 @@ +#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<<TYSCHAR | 1<<TYSHORT | 1<<TYINT | 1<<TYLONG | 1<<TYVLONG, + TYUNSIGNEDSET_ = 1<<TYUCHAR | 1<<TYUSHORT | 1<<TYUINT | 1<<TYULONG | 1<<TYUVLONG, + TYSCALARSET_ = ((1u << (TYCOMPLEXL - TYENUM + 1)) - 1) << TYENUM | 1<<TYPTR +}; + +enum typeflagmask { + TFCHLDQUAL = 3, + TFCHLDPRIM = 1<<2, + TFCHLDISDAT = 1<<3, +}; + +union type { + struct { + uchar t; /* type tag */ + union { + uchar flag; + uchar backing; /* type tag for enum backing int */ + }; + union { + struct { + uchar child; /* prim type tag */ + uchar arrlen; /* small array */ + }; + ushort dat; /* index into typedata */ + }; + }; + uint bits; +}; +static_assert(sizeof(union type) == 4); + +#define isprimt(t) in_range((t), TYBOOL, TYVOID) +#define isintt(t) in_range((t), TYENUM, TYUVLONG) +#define issignedt(t) ((TYSIGNEDSET_ | targ_charsigned << TYCHAR) >> (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: */ |