c.c (5341B)
1 #include "c.h" 2 3 #include "decl/decl.h" 4 #include "lex/lex.h" 5 #include "parse/parse.h" 6 #include "pp/pp.h" 7 8 static SrcLoc c_no_loc(void) { 9 SrcLoc loc; 10 loc.file_id = 0; 11 loc.line = 0; 12 loc.col = 0; 13 return loc; 14 } 15 16 static _Noreturn void c_bad_options(Compiler* c, const char* msg) { 17 compiler_panic(c, c_no_loc(), "bad C frontend options: %.*s", 18 KIT_SLICE_ARG(kit_slice_cstr(msg))); 19 } 20 21 static void c_apply_pp_options(Pp* pp, const KitPreprocessOptions* opts) { 22 u32 i; 23 24 for (i = 0; i < opts->ninclude_dirs; ++i) { 25 pp_add_include_dir(pp, opts->include_dirs[i], 0); 26 } 27 for (i = 0; i < opts->nsystem_include_dirs; ++i) { 28 pp_add_include_dir(pp, opts->system_include_dirs[i], 1); 29 } 30 for (i = 0; i < opts->ndefines; ++i) { 31 const char* body = 32 opts->defines[i].body.len ? opts->defines[i].body.s : "1"; 33 pp_define(pp, opts->defines[i].name.s, body); 34 } 35 for (i = 0; i < opts->nundefines; ++i) { 36 pp_undef(pp, opts->undefines[i].s); 37 } 38 } 39 40 typedef struct CFrontend { 41 KitCompiler* c; 42 } CFrontend; 43 44 static KitFrontendState* c_frontend_new(KitCompiler* c) { 45 KitHeap* h; 46 CFrontend* fe; 47 if (!c) return NULL; 48 h = kit_compiler_context(c)->heap; 49 fe = (CFrontend*)h->alloc(h, sizeof(*fe), _Alignof(CFrontend)); 50 if (!fe) return NULL; 51 fe->c = c; 52 return (KitFrontendState*)fe; 53 } 54 55 static KitStatus c_frontend_compile_cg(KitFrontendState* frontend, 56 const KitFrontendCompileOptions* fe_opts, 57 const KitSourceInput* input, KitCg* cg) { 58 CFrontend* fe = (CFrontend*)frontend; 59 KitCompiler* c; 60 /* Code, diagnostics, and preprocessor settings all arrive on the common 61 * KitFrontendCompileOptions; the C frontend uses no language_options. */ 62 const KitSlice* bytes; 63 Pool* pool; 64 Lexer* lex; 65 Pp* pp; 66 DeclTable* decls; 67 68 if (!fe || !fe->c) return KIT_INVALID; 69 c = fe->c; 70 if (!fe_opts || !input || !cg) c_bad_options(c, "compile args missing"); 71 bytes = &input->bytes; 72 73 kit_frontend_metrics_scope_begin(c, "compile.c.setup"); 74 kit_frontend_metrics_scope_begin(c, "compile.c.pool_new"); 75 pool = c_pool_new(c); 76 kit_frontend_metrics_scope_end(c, "compile.c.pool_new"); 77 if (!pool) compiler_panic(c, c_no_loc(), "C compiler out of memory"); 78 kit_frontend_metrics_scope_begin(c, "compile.c.lex_open"); 79 lex = lex_open_mem(c, input->name.s, bytes->s, bytes->len); 80 if (lex) lex_skip_shebang(lex); 81 kit_frontend_metrics_scope_end(c, "compile.c.lex_open"); 82 kit_frontend_metrics_scope_begin(c, "compile.c.pp_new"); 83 pp = pp_new(c); 84 kit_frontend_metrics_scope_end(c, "compile.c.pp_new"); 85 if (!lex || !pp || !cg) 86 compiler_panic(c, c_no_loc(), "C compiler out of memory"); 87 kit_frontend_metrics_scope_begin(c, "compile.c.decl_new"); 88 decls = decl_new(c, pool, cg); 89 kit_frontend_metrics_scope_end(c, "compile.c.decl_new"); 90 kit_frontend_metrics_scope_end(c, "compile.c.setup"); 91 92 kit_frontend_metrics_scope_begin(c, "compile.c.pp_options"); 93 kit_frontend_metrics_count(c, "compile.c.pp_include_dirs", 94 fe_opts->preprocess.ninclude_dirs); 95 kit_frontend_metrics_count(c, "compile.c.pp_system_include_dirs", 96 fe_opts->preprocess.nsystem_include_dirs); 97 kit_frontend_metrics_count(c, "compile.c.pp_defines", 98 fe_opts->preprocess.ndefines); 99 kit_frontend_metrics_count(c, "compile.c.pp_undefines", 100 fe_opts->preprocess.nundefines); 101 c_apply_pp_options(pp, &fe_opts->preprocess); 102 kit_frontend_metrics_scope_end(c, "compile.c.pp_options"); 103 kit_frontend_metrics_scope_begin(c, "compile.c.pp_push_input"); 104 pp_push_input(pp, lex); 105 kit_frontend_metrics_scope_end(c, "compile.c.pp_push_input"); 106 107 kit_frontend_metrics_scope_begin(c, "compile.c.parse_codegen"); 108 parse_c(c, pool, pp, decls, cg, (KitSymVis)fe_opts->code.default_visibility); 109 kit_frontend_metrics_scope_end(c, "compile.c.parse_codegen"); 110 111 kit_frontend_metrics_scope_begin(c, "compile.c.cleanup"); 112 decl_free(decls); 113 pp_free(pp); 114 c_pool_free(pool); 115 kit_frontend_metrics_scope_end(c, "compile.c.cleanup"); 116 return KIT_OK; 117 } 118 119 static void c_frontend_free(KitFrontendState* frontend) { 120 CFrontend* fe = (CFrontend*)frontend; 121 KitHeap* h; 122 if (!fe) return; 123 h = kit_compiler_context(fe->c)->heap; 124 h->free(h, fe, sizeof(*fe)); 125 } 126 127 /* C is just another frontend: it claims its source/header extensions so the 128 * language-for-path lookup resolves them by the same registry walk as every 129 * other language, with no special fallback. */ 130 static const KitSlice c_extensions[] = {KIT_SLICE_LIT("c"), KIT_SLICE_LIT("h")}; 131 /* Canonical `-x` name; mirrors the driver's "c" spelling. */ 132 static const KitSlice c_names[] = {KIT_SLICE_LIT("c")}; 133 134 const KitFrontendVTable kit_c_frontend_vtable = { 135 c_frontend_new, 136 c_frontend_compile_cg, 137 NULL, /* compile_obj: semantic frontends are wrapped by compile session */ 138 c_frontend_free, 139 c_extensions, 140 (uint32_t)(sizeof c_extensions / sizeof c_extensions[0]), 141 c_names, 142 (uint32_t)(sizeof c_names / sizeof c_names[0]), 143 /* commit/abort: C has no durable cross-compile state yet */ 144 NULL, 145 NULL, 146 {true, KIT_FRONTEND_LTO_CG, false}, 147 NULL, /* parse_options: C has no frontend-specific flags */ 148 NULL, /* free_options */ 149 };