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