kit

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

source.c (6379B)


      1 /* SourceManager — file-id authority for diagnostics, dependency output,
      2  * and DWARF. */
      3 
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include "core/core.h"
      8 #include "core/heap.h"
      9 #include "core/pool.h"
     10 #include "core/slice.h"
     11 
     12 typedef struct SrcMgrFile {
     13   SourceFile info;
     14 } SrcMgrFile;
     15 
     16 typedef struct SrcMgrInclude {
     17   SourceInclude info;
     18 } SrcMgrInclude;
     19 
     20 struct SourceManager {
     21   Compiler* c;
     22   Heap* heap;
     23 
     24   SrcMgrFile* files;
     25   u32 nfiles;
     26   u32 files_cap;
     27 
     28   SrcMgrInclude* includes;
     29   u32 nincludes;
     30   u32 includes_cap;
     31 };
     32 
     33 struct SourceDepIter {
     34   SourceManager* sm;
     35   u32 idx;
     36 };
     37 
     38 static int files_grow(SourceManager* sm, u32 want) {
     39   u32 new_cap;
     40   SrcMgrFile* nf;
     41   if (want <= sm->files_cap) return 0;
     42   new_cap = sm->files_cap ? sm->files_cap * 2 : 16;
     43   while (new_cap < want) new_cap *= 2;
     44   nf = (SrcMgrFile*)sm->heap->realloc(
     45       sm->heap, sm->files, sizeof(*sm->files) * sm->files_cap,
     46       sizeof(*sm->files) * new_cap, _Alignof(SrcMgrFile));
     47   if (!nf) return 1;
     48   sm->files = nf;
     49   sm->files_cap = new_cap;
     50   return 0;
     51 }
     52 
     53 static int includes_grow(SourceManager* sm) {
     54   u32 new_cap;
     55   SrcMgrInclude* ni;
     56   if (sm->nincludes < sm->includes_cap) return 0;
     57   new_cap = sm->includes_cap ? sm->includes_cap * 2 : 16;
     58   ni = (SrcMgrInclude*)sm->heap->realloc(
     59       sm->heap, sm->includes, sizeof(*sm->includes) * sm->includes_cap,
     60       sizeof(*sm->includes) * new_cap, _Alignof(SrcMgrInclude));
     61   if (!ni) return 1;
     62   sm->includes = ni;
     63   sm->includes_cap = new_cap;
     64   return 0;
     65 }
     66 
     67 SourceManager* source_new(Compiler* c) {
     68   Heap* h = c->ctx->heap;
     69   SourceManager* sm =
     70       (SourceManager*)h->alloc(h, sizeof(*sm), _Alignof(SourceManager));
     71   if (!sm) return NULL;
     72   memset(sm, 0, sizeof(*sm));
     73   sm->c = c;
     74   sm->heap = h;
     75   if (files_grow(sm, 1)) {
     76     h->free(h, sm, sizeof(*sm));
     77     return NULL;
     78   }
     79   memset(&sm->files[0], 0, sizeof(sm->files[0]));
     80   sm->nfiles = 1;
     81   return sm;
     82 }
     83 
     84 void source_free(SourceManager* sm) {
     85   if (!sm) return;
     86   if (sm->files)
     87     sm->heap->free(sm->heap, sm->files, sizeof(*sm->files) * sm->files_cap);
     88   if (sm->includes)
     89     sm->heap->free(sm->heap, sm->includes,
     90                    sizeof(*sm->includes) * sm->includes_cap);
     91   sm->heap->free(sm->heap, sm, sizeof(*sm));
     92 }
     93 
     94 /* Register a file slot from a pre-interned name Sym (skips the intern). Draws
     95  * the next sequential file_id from sm->nfiles++ exactly like file_register, so
     96  * the file_id sequence -- which is byte-observable through DWARF line tables and
     97  * diagnostics -- is unchanged. */
     98 static KitStatus file_register_sym(SourceManager* sm, Sym sym,
     99                                    SourceFileKind kind, int system_header,
    100                                    u32* id_out) {
    101   u32 id;
    102   if (files_grow(sm, sm->nfiles + 1)) return KIT_NOMEM;
    103   id = sm->nfiles++;
    104   memset(&sm->files[id], 0, sizeof(sm->files[id]));
    105   sm->files[id].info.id = id;
    106   sm->files[id].info.name = sym;
    107   sm->files[id].info.path = (kind == SRC_FILE_REAL) ? sym : 0;
    108   sm->files[id].info.kind = (u8)kind;
    109   sm->files[id].info.system_header = (u8)(system_header ? 1 : 0);
    110   *id_out = id;
    111   return KIT_OK;
    112 }
    113 
    114 static KitStatus file_register(SourceManager* sm, Slice name,
    115                                SourceFileKind kind, int system_header,
    116                                u32* id_out) {
    117   Sym sym = pool_intern_slice(sm->c->global, name);
    118   return file_register_sym(sm, sym, kind, system_header, id_out);
    119 }
    120 
    121 KitStatus source_add_file(SourceManager* sm, const char* path,
    122                           int system_header, u32* id_out) {
    123   return file_register(sm, slice_from_cstr(path ? path : ""), SRC_FILE_REAL,
    124                        system_header, id_out);
    125 }
    126 
    127 KitStatus source_add_memory(SourceManager* sm, KitSlice name, u32* id_out) {
    128   return file_register(sm, name, SRC_FILE_MEMORY, 0, id_out);
    129 }
    130 
    131 KitStatus source_add_memory_sym(SourceManager* sm, Sym name, u32* id_out) {
    132   return file_register_sym(sm, name, SRC_FILE_MEMORY, 0, id_out);
    133 }
    134 
    135 KitStatus source_add_builtin(SourceManager* sm, KitSlice name, u32* id_out) {
    136   return file_register(sm, name, SRC_FILE_BUILTIN, 0, id_out);
    137 }
    138 
    139 KitStatus source_add_include(SourceManager* sm, u32 includer_file_id,
    140                              u32 included_file_id, SrcLoc include_loc,
    141                              int system, int resolved_system) {
    142   if (includes_grow(sm)) return KIT_NOMEM;
    143   sm->includes[sm->nincludes].info.includer_file_id = includer_file_id;
    144   sm->includes[sm->nincludes].info.included_file_id = included_file_id;
    145   sm->includes[sm->nincludes].info.include_loc = include_loc;
    146   sm->includes[sm->nincludes].info.system = (u8)(system ? 1 : 0);
    147   sm->includes[sm->nincludes].info.resolved_system =
    148       (u8)(resolved_system ? 1 : 0);
    149   sm->nincludes++;
    150   return KIT_OK;
    151 }
    152 
    153 KitStatus source_add_macro_expansion(SourceManager* sm, Sym macro_name,
    154                                      SrcLoc spelling_loc, SrcLoc expansion_loc,
    155                                      u32* id_out) {
    156   (void)spelling_loc;
    157   (void)expansion_loc;
    158   if (files_grow(sm, sm->nfiles + 1)) return KIT_NOMEM;
    159   {
    160     u32 id = sm->nfiles++;
    161     memset(&sm->files[id], 0, sizeof(sm->files[id]));
    162     sm->files[id].info.id = id;
    163     sm->files[id].info.name = macro_name;
    164     sm->files[id].info.kind = SRC_FILE_MACRO;
    165     *id_out = id;
    166   }
    167   return KIT_OK;
    168 }
    169 
    170 const SourceFile* source_file(SourceManager* sm, u32 file_id) {
    171   if (file_id == 0 || file_id >= sm->nfiles) return NULL;
    172   return &sm->files[file_id].info;
    173 }
    174 
    175 const SourceExpansion* source_expansion(SourceManager* sm,
    176                                         u32 expansion_file_id) {
    177   (void)sm;
    178   (void)expansion_file_id;
    179   return NULL;
    180 }
    181 
    182 SrcLoc source_spelling_loc(SourceManager* sm, SrcLoc loc) {
    183   (void)sm;
    184   return loc;
    185 }
    186 SrcLoc source_expansion_loc(SourceManager* sm, SrcLoc loc) {
    187   (void)sm;
    188   return loc;
    189 }
    190 
    191 SourceDepIter* source_depiter_new(SourceManager* sm) {
    192   SourceDepIter* it = (SourceDepIter*)sm->heap->alloc(sm->heap, sizeof(*it),
    193                                                       _Alignof(SourceDepIter));
    194   if (!it) return NULL;
    195   it->sm = sm;
    196   it->idx = 0;
    197   return it;
    198 }
    199 
    200 const SourceInclude* source_depiter_next(SourceDepIter* it) {
    201   if (!it || it->idx >= it->sm->nincludes) return NULL;
    202   return &it->sm->includes[it->idx++].info;
    203 }
    204 
    205 void source_depiter_free(SourceDepIter* it) {
    206   if (!it) return;
    207   it->sm->heap->free(it->sm->heap, it, sizeof(*it));
    208 }