kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

type.h (5434B)


      1 #ifndef KIT_TYPE_H
      2 #define KIT_TYPE_H
      3 
      4 #include <kit/cg.h>
      5 
      6 #include "c_support.h"
      7 
      8 typedef enum TypeKind {
      9   TY_VOID,
     10   TY_BOOL,
     11   TY_CHAR,
     12   TY_SCHAR,
     13   TY_UCHAR,
     14   TY_SHORT,
     15   TY_USHORT,
     16   TY_INT,
     17   TY_UINT,
     18   TY_LONG,
     19   TY_ULONG,
     20   TY_LLONG,
     21   TY_ULLONG,
     22   TY_INT128,
     23   TY_UINT128,
     24   TY_FLOAT,
     25   TY_DOUBLE,
     26   TY_LDOUBLE,
     27   TY_PTR,
     28   TY_ARRAY,
     29   TY_FUNC,
     30   TY_STRUCT,
     31   TY_UNION,
     32   TY_ENUM,
     33 } TypeKind;
     34 
     35 /* C tag identity is scoped declaration identity, not the spelling. `Sym tag`
     36  * remains the diagnostic/debug name; TagId prevents two scoped `struct S`
     37  * declarations from collapsing under global Type interning. */
     38 typedef u32 TagId;
     39 #define TAG_NONE 0u
     40 
     41 typedef enum TagDeclKind {
     42   TAG_STRUCT,
     43   TAG_UNION,
     44   TAG_ENUM,
     45 } TagDeclKind;
     46 
     47 typedef struct TagDecl {
     48   TagId id;
     49   Sym spelling;
     50   SrcLoc loc;
     51   u8 kind; /* TagDeclKind */
     52   u8 complete;
     53   u16 pad;
     54 } TagDecl;
     55 
     56 typedef enum TypeQual {
     57   Q_CONST = 1u << 0,
     58   Q_VOLATILE = 1u << 1,
     59   Q_RESTRICT = 1u << 2,
     60   Q_ATOMIC = 1u << 3,
     61 } TypeQual;
     62 
     63 typedef struct Type Type;
     64 
     65 typedef enum FieldFlag {
     66   FIELD_NONE = 0,
     67   FIELD_BITFIELD = 1u << 0,
     68   FIELD_ZERO_WIDTH = 1u << 1,
     69   FIELD_ANON = 1u << 2,
     70   FIELD_FLEXIBLE_ARRAY = 1u << 3,
     71 } FieldFlag;
     72 
     73 typedef struct Field {
     74   Sym name;
     75   const Type* type;
     76   u16 bitfield_width; /* valid when FIELD_BITFIELD is set; may be 0 */
     77   u16 flags;          /* FieldFlag */
     78   /* Phase 2 attribute carriers — populated by the parser when the member
     79    * carries __attribute__((aligned(N))) / ((packed)). Zero means "no
     80    * override"; c_abi_record_layout interprets them. */
     81   u16 align_override;
     82   u16 max_align;
     83   u8 packed;
     84 } Field;
     85 
     86 struct Type {
     87   u16 kind;
     88   u16 qual;
     89   union {
     90     struct {
     91       const Type* pointee;
     92     } ptr;
     93     struct {
     94       const Type* elem;
     95       u32 count;
     96       u8 incomplete;
     97     } arr;
     98     struct {
     99       const Type* ret;
    100       const Type** params;
    101       u16 nparams;
    102       u8 variadic;
    103     } fn;
    104     struct {
    105       TagId tag_id;
    106       Sym tag;
    107       const Field* fields;
    108       u16 nfields;
    109       u8 incomplete;
    110       /* Phase 2 attribute carriers — record-level
    111        * __attribute__((packed)) / ((aligned(N))). Both zero means
    112        * "natural layout". c_abi_record_layout honors them. */
    113       u8 packed;
    114       u16 max_align;
    115       u16 align_override;
    116     } rec; /* struct / union */
    117     struct {
    118       TagId tag_id;
    119       Sym tag;
    120       const Type* base;
    121     } enm;
    122   };
    123 };
    124 
    125 const Type* type_void(Pool*);
    126 const Type* type_prim(Pool*, TypeKind);
    127 const Type* type_ptr(Pool*, const Type*);
    128 const Type* type_array(Pool*, const Type* elem, u32 count, int incomplete);
    129 const Type* type_func(Pool*, const Type* ret, const Type** params, u16 n,
    130                       int variadic);
    131 const Type* type_qualified(Pool*, const Type*, u16 qual);
    132 
    133 /* Aggregate construction is mutable only through TypeRecordBuilder. The
    134  * committed Type is immutable and interned; field offsets, record
    135  * size/alignment, and bitfield storage are target ABI facts. */
    136 typedef struct TypeRecordBuilder TypeRecordBuilder;
    137 TagId type_tag_new(Pool*, TagDeclKind, Sym spelling, SrcLoc);
    138 const TagDecl* type_tag_get(Pool*, TagId);
    139 TypeRecordBuilder* type_record_begin(Pool*, TypeKind kind, TagId,
    140                                      Sym tag); /* TY_STRUCT or TY_UNION */
    141 
    142 /* Phase 2 record options carried from __attribute__((packed))/aligned(N)).
    143  * Zero-initialized = natural layout. Fields kept as a struct so future
    144  * options (e.g. transparent_union) don't churn the call sites. */
    145 typedef struct TypeRecordOpts {
    146   u8 packed;
    147   u16 max_align;
    148   u16 align_override;
    149 } TypeRecordOpts;
    150 
    151 /* Variant of type_record_begin that records record-level attribute
    152  * options on the builder; type_record_end copies them to Type.rec. The
    153  * plain type_record_begin is equivalent to passing a zeroed
    154  * TypeRecordOpts. */
    155 TypeRecordBuilder* type_record_begin_ex(Pool*, TypeKind kind, TagId, Sym tag,
    156                                         TypeRecordOpts);
    157 void type_record_field(TypeRecordBuilder*, Field);
    158 const Type* type_record_end(Pool*, TypeRecordBuilder*);
    159 /* Forward-declared struct/union: returns a mutable, incomplete Type with the
    160  * given tag identity but no fields. Pointers to it are valid; sizeof/member
    161  * access are not until type_record_install is called. The same Type* identity
    162  * survives completion, so any TY_PTR(forward) pointer types remain valid. */
    163 Type* type_record_forward(Pool*, TypeKind kind, TagId, Sym tag);
    164 void type_record_install(Type* forward, const Field* fields, u16 nfields);
    165 const Type* type_enum(Pool*, TagId, Sym tag, const Type* base);
    166 
    167 const Type* type_unqual(Pool*, const Type*);
    168 const Type* type_promoted(Pool*, const Type*);
    169 int type_compatible(const Type*, const Type*);
    170 const Type* type_composite(Pool*, const Type*, const Type*);
    171 int type_is_arith(const Type*);
    172 int type_is_int(const Type*);
    173 int type_is_ptr(const Type*);
    174 int type_is_signed_integer(const Type*);
    175 
    176 /* Per-TypeKind scalar facts, backed by a single property table in type.c.
    177  * These take a bare TypeKind so callers that already have one (and the
    178  * Type* wrappers above) share the same source of truth. */
    179 int type_kind_is_int(TypeKind);
    180 int type_kind_is_fp(TypeKind);
    181 int type_kind_is_signed_integer(TypeKind);
    182 u32 type_kind_int_rank(TypeKind);
    183 TypeKind type_kind_unsigned_variant(TypeKind);
    184 
    185 KitCgTypeId type_cg_id_in_pool(KitCompiler*, Pool*, const Type*);
    186 KitCgTypeId type_cg_id(KitCompiler*, const Type*);
    187 
    188 #endif