cpp_support.h (3601B)
1 #ifndef KIT_LANG_CPP_SUPPORT_H 2 #define KIT_LANG_CPP_SUPPORT_H 3 4 /* Shared substrate for the lexer and preprocessor: width-typed integer 5 * aliases, the Compiler/Heap/Writer/Sym/SrcLoc typedefs, the Pool 6 * abstraction over a per-frontend arena, arena allocation macros, and 7 * the panic helpers. Used by lang/cpp/ directly and re-exported by 8 * lang/c/c_support.h for the C frontend. */ 9 10 #include <kit/frontend.h> 11 #include <kit/support/hashmap.h> 12 #include <stdarg.h> 13 #include <stddef.h> 14 #include <stdint.h> 15 16 typedef int8_t i8; 17 typedef int16_t i16; 18 typedef int32_t i32; 19 typedef int64_t i64; 20 typedef uint8_t u8; 21 typedef uint16_t u16; 22 typedef uint32_t u32; 23 typedef uint64_t u64; 24 25 typedef KitCompiler Compiler; 26 typedef KitHeap Heap; 27 typedef KitWriter Writer; 28 typedef KitSym Sym; 29 typedef KitSrcLoc SrcLoc; 30 typedef u32 BytesId; 31 32 typedef struct Pool { 33 Compiler* c; 34 KitArena* arena; 35 void* type_cache; /* opaque slot owned by the C frontend; unused by cpp */ 36 } Pool; 37 38 /* C data model for frontend-visible scalar spelling. kit currently uses LP64 39 * for 64-bit non-Windows targets, LLP64 for 64-bit Windows targets, and ILP32 40 * for 32-bit targets. The distinction is exactly sizeof(long): 8 for LP64, 41 * 4 for LLP64/ILP32 — a resolved data-model fact carried on the spec, so we 42 * read it instead of re-deriving from ptr_size + OS identity. */ 43 static inline int kit_target_uses_lp64(KitTargetSpec t) { 44 return t.long_size == 8; 45 } 46 47 static inline Pool* c_pool_new(Compiler* c) { 48 Heap* h = kit_compiler_context(c)->heap; 49 Pool* p = h ? (Pool*)h->alloc(h, sizeof(*p), _Alignof(Pool)) : NULL; 50 if (!p) return NULL; 51 p->c = c; 52 p->arena = NULL; 53 p->type_cache = NULL; 54 if (kit_arena_new(h, 0, &p->arena) != KIT_OK || !p->arena) { 55 h->free(h, p, sizeof(*p)); 56 return NULL; 57 } 58 return p; 59 } 60 61 static inline void c_pool_free(Pool* p) { 62 Heap* h; 63 if (!p) return; 64 h = kit_compiler_context(p->c)->heap; 65 kit_arena_free(p->arena); 66 if (h) h->free(h, p, sizeof(*p)); 67 } 68 69 #define arena_alloc(a, size, align) kit_arena_alloc((a), (size), (align)) 70 #define arena_zalloc(a, size, align) kit_arena_zalloc((a), (size), (align)) 71 #define arena_strdup(a, s, len) kit_arena_strdup((a), (s), (len)) 72 #define arena_new(a, T) kit_arena_new_obj((a), T) 73 #define arena_znew(a, T) kit_arena_znew_obj((a), T) 74 #define arena_array(a, T, n) kit_arena_array((a), T, n) 75 #define arena_zarray(a, T, n) kit_arena_zarray((a), T, n) 76 77 _Noreturn static inline void compiler_panic(Compiler* c, SrcLoc loc, 78 const char* fmt, ...) { 79 va_list ap; 80 va_start(ap, fmt); 81 kit_frontend_vfatal(c, loc, fmt, ap); 82 } 83 84 _Noreturn static inline void compiler_panicv(Compiler* c, SrcLoc loc, 85 const char* fmt, va_list ap) { 86 kit_frontend_vfatal(c, loc, fmt, ap); 87 } 88 89 /* True when the C `long double` type is IEEE-754 binary128 (quad) on this 90 * target rather than an alias of `double`. RISC-V (LP64/LP64D) and 91 * non-Apple/non-Windows aarch64 follow the quad psABI; wasm32 matches 92 * clang/LLVM's wasm convention. x86 (80-bit x87, not modeled), Apple, and 93 * Windows alias long double to double. This is a resolved ABI fact 94 * (long_double_format) computed once in kit_target_new, so we read the 95 * spec field instead of re-deriving an arch/os ladder here. Centralized so 96 * the preprocessor's __LDBL_* / __SIZEOF_LONG_DOUBLE__ macros and the C type 97 * system's long-double -> CG-builtin mapping cannot drift apart. */ 98 static inline int kit_target_long_double_is_binary128(KitTargetSpec t) { 99 return t.long_double_format == KIT_LDBL_BINARY128; 100 } 101 102 #endif