type.h (6793B)
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 /* Defined in abi/c_abi.h (which includes this header), forward-declared here so 66 * Type can cache a computed record layout pointer without a header cycle. */ 67 struct ABIRecordLayout; 68 69 typedef enum FieldFlag { 70 FIELD_NONE = 0, 71 FIELD_BITFIELD = 1u << 0, 72 FIELD_ZERO_WIDTH = 1u << 1, 73 FIELD_ANON = 1u << 2, 74 FIELD_FLEXIBLE_ARRAY = 1u << 3, 75 } FieldFlag; 76 77 typedef struct Field { 78 Sym name; 79 const Type* type; 80 u16 bitfield_width; /* valid when FIELD_BITFIELD is set; may be 0 */ 81 u16 flags; /* FieldFlag */ 82 /* Phase 2 attribute carriers — populated by the parser when the member 83 * carries __attribute__((aligned(N))) / ((packed)). Zero means "no 84 * override"; c_abi_record_layout interprets them. */ 85 u16 align_override; 86 u16 max_align; 87 u8 packed; 88 } Field; 89 90 /* One enumerator (name = value), collected by parse_enum and carried on the 91 * enum Type so CG/debug lowering can emit DW_TAG_enumerator children. */ 92 typedef struct EnumConst { 93 Sym name; 94 i64 value; 95 } EnumConst; 96 97 struct Type { 98 u16 kind; 99 u16 qual; 100 /* Memoized VALUE-mode CG lowering of this canonical node (0 = not yet 101 * lowered). Sits in the alignment hole before the 8-aligned union, so the 102 * node stays the same size. NOT part of type identity: the structural intern 103 * set compares named fields and type_tagged_eq compares the rec/enm payload, 104 * so this mutable cache never participates in interning. See type_cg_lower. 105 */ 106 KitCgTypeId cg_id; 107 /* Memoized record layout for TY_STRUCT/TY_UNION (NULL = not yet built). Like 108 * the lowering caches this is mutable state, NOT part of type identity — the 109 * interning comparisons never read it. Only c_abi_record_layout writes it, 110 * and only for a complete record, whose layout is immutable + arena-lived for 111 * the pool's lifetime, so sharing the pointer across qualified variants is 112 * safe. */ 113 const struct ABIRecordLayout* abi_layout; 114 union { 115 struct { 116 const Type* pointee; 117 } ptr; 118 struct { 119 const Type* elem; 120 u32 count; 121 u8 incomplete; 122 } arr; 123 struct { 124 const Type* ret; 125 const Type** params; 126 u16 nparams; 127 u8 variadic; 128 } fn; 129 struct { 130 TagId tag_id; 131 Sym tag; 132 const Field* fields; 133 u16 nfields; 134 u8 incomplete; 135 /* Phase 2 attribute carriers — record-level 136 * __attribute__((packed)) / ((aligned(N))). Both zero means 137 * "natural layout". c_abi_record_layout honors them. */ 138 u8 packed; 139 u16 max_align; 140 u16 align_override; 141 } rec; /* struct / union */ 142 struct { 143 TagId tag_id; 144 Sym tag; 145 const Type* base; 146 const EnumConst* consts; /* enumerators, NULL until the body is parsed */ 147 u16 nconsts; 148 } enm; 149 }; 150 }; 151 152 const Type* type_void(Pool*); 153 const Type* type_prim(Pool*, TypeKind); 154 const Type* type_ptr(Pool*, const Type*); 155 const Type* type_array(Pool*, const Type* elem, u32 count, int incomplete); 156 const Type* type_func(Pool*, const Type* ret, const Type** params, u16 n, 157 int variadic); 158 const Type* type_qualified(Pool*, const Type*, u16 qual); 159 160 /* Aggregate construction is mutable only through TypeRecordBuilder. The 161 * committed Type is immutable and interned; field offsets, record 162 * size/alignment, and bitfield storage are target ABI facts. */ 163 typedef struct TypeRecordBuilder TypeRecordBuilder; 164 TagId type_tag_new(Pool*, TagDeclKind, Sym spelling, SrcLoc); 165 TypeRecordBuilder* type_record_begin(Pool*, TypeKind kind, TagId, 166 Sym tag); /* TY_STRUCT or TY_UNION */ 167 168 /* Phase 2 record options carried from __attribute__((packed))/aligned(N)). 169 * Zero-initialized = natural layout. Fields kept as a struct so future 170 * options (e.g. transparent_union) don't churn the call sites. */ 171 typedef struct TypeRecordOpts { 172 u8 packed; 173 u16 max_align; 174 u16 align_override; 175 } TypeRecordOpts; 176 177 /* Variant of type_record_begin that records record-level attribute 178 * options on the builder; type_record_end copies them to Type.rec. The 179 * plain type_record_begin is equivalent to passing a zeroed 180 * TypeRecordOpts. */ 181 TypeRecordBuilder* type_record_begin_ex(Pool*, TypeKind kind, TagId, Sym tag, 182 TypeRecordOpts); 183 void type_record_field(TypeRecordBuilder*, Field); 184 const Type* type_record_end(Pool*, TypeRecordBuilder*); 185 /* Forward-declared struct/union: returns a mutable, incomplete Type with the 186 * given tag identity but no fields. Pointers to it are valid; sizeof/member 187 * access are not until type_record_install is called. The same Type* identity 188 * survives completion, so any TY_PTR(forward) pointer types remain valid. */ 189 Type* type_record_forward(Pool*, TypeKind kind, TagId, Sym tag); 190 void type_record_install(Type* forward, const Field* fields, u16 nfields); 191 const Type* type_enum(Pool*, TagId, Sym tag, const Type* base); 192 193 const Type* type_unqual(Pool*, const Type*); 194 const Type* type_promoted(Pool*, const Type*); 195 int type_compatible(const Type*, const Type*); 196 const Type* type_composite(Pool*, const Type*, const Type*); 197 int type_is_arith(const Type*); 198 int type_is_int(const Type*); 199 int type_is_ptr(const Type*); 200 int type_is_signed_integer(const Type*); 201 202 /* Per-TypeKind scalar facts, backed by a single property table in type.c. 203 * These take a bare TypeKind so callers that already have one (and the 204 * Type* wrappers above) share the same source of truth. */ 205 int type_kind_is_int(TypeKind); 206 int type_kind_is_fp(TypeKind); 207 int type_kind_is_signed_integer(TypeKind); 208 u32 type_kind_int_rank(TypeKind); 209 TypeKind type_kind_unsigned_variant(TypeKind); 210 211 KitCgTypeId type_cg_id_in_pool(KitCompiler*, Pool*, const Type*); 212 KitCgDebugType type_cg_debug_in_pool(KitCg*, KitCompiler*, Pool*, const Type*); 213 214 #endif