kit

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

source.c (5597B)


      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 static KitStatus file_register(SourceManager* sm, Slice name,
     95                                SourceFileKind kind, int system_header,
     96                                u32* id_out) {
     97   Sym sym;
     98   u32 id;
     99   if (files_grow(sm, sm->nfiles + 1)) return KIT_NOMEM;
    100   sym = pool_intern_slice(sm->c->global, name);
    101   id = sm->nfiles++;
    102   memset(&sm->files[id], 0, sizeof(sm->files[id]));
    103   sm->files[id].info.id = id;
    104   sm->files[id].info.name = sym;
    105   sm->files[id].info.path = (kind == SRC_FILE_REAL) ? sym : 0;
    106   sm->files[id].info.kind = (u8)kind;
    107   sm->files[id].info.system_header = (u8)(system_header ? 1 : 0);
    108   *id_out = id;
    109   return KIT_OK;
    110 }
    111 
    112 KitStatus source_add_file(SourceManager* sm, const char* path,
    113                           int system_header, u32* id_out) {
    114   return file_register(sm, slice_from_cstr(path ? path : ""), SRC_FILE_REAL,
    115                        system_header, id_out);
    116 }
    117 
    118 KitStatus source_add_memory(SourceManager* sm, KitSlice name, u32* id_out) {
    119   return file_register(sm, name, SRC_FILE_MEMORY, 0, id_out);
    120 }
    121 
    122 KitStatus source_add_builtin(SourceManager* sm, KitSlice name, u32* id_out) {
    123   return file_register(sm, name, SRC_FILE_BUILTIN, 0, id_out);
    124 }
    125 
    126 KitStatus source_add_include(SourceManager* sm, u32 includer_file_id,
    127                              u32 included_file_id, SrcLoc include_loc,
    128                              int system) {
    129   if (includes_grow(sm)) return KIT_NOMEM;
    130   sm->includes[sm->nincludes].info.includer_file_id = includer_file_id;
    131   sm->includes[sm->nincludes].info.included_file_id = included_file_id;
    132   sm->includes[sm->nincludes].info.include_loc = include_loc;
    133   sm->includes[sm->nincludes].info.system = (u8)(system ? 1 : 0);
    134   sm->nincludes++;
    135   return KIT_OK;
    136 }
    137 
    138 KitStatus source_add_macro_expansion(SourceManager* sm, Sym macro_name,
    139                                      SrcLoc spelling_loc, SrcLoc expansion_loc,
    140                                      u32* id_out) {
    141   (void)spelling_loc;
    142   (void)expansion_loc;
    143   if (files_grow(sm, sm->nfiles + 1)) return KIT_NOMEM;
    144   {
    145     u32 id = sm->nfiles++;
    146     memset(&sm->files[id], 0, sizeof(sm->files[id]));
    147     sm->files[id].info.id = id;
    148     sm->files[id].info.name = macro_name;
    149     sm->files[id].info.kind = SRC_FILE_MACRO;
    150     *id_out = id;
    151   }
    152   return KIT_OK;
    153 }
    154 
    155 const SourceFile* source_file(SourceManager* sm, u32 file_id) {
    156   if (file_id == 0 || file_id >= sm->nfiles) return NULL;
    157   return &sm->files[file_id].info;
    158 }
    159 
    160 const SourceExpansion* source_expansion(SourceManager* sm,
    161                                         u32 expansion_file_id) {
    162   (void)sm;
    163   (void)expansion_file_id;
    164   return NULL;
    165 }
    166 
    167 SrcLoc source_spelling_loc(SourceManager* sm, SrcLoc loc) {
    168   (void)sm;
    169   return loc;
    170 }
    171 SrcLoc source_expansion_loc(SourceManager* sm, SrcLoc loc) {
    172   (void)sm;
    173   return loc;
    174 }
    175 
    176 SourceDepIter* source_depiter_new(SourceManager* sm) {
    177   SourceDepIter* it = (SourceDepIter*)sm->heap->alloc(sm->heap, sizeof(*it),
    178                                                       _Alignof(SourceDepIter));
    179   if (!it) return NULL;
    180   it->sm = sm;
    181   it->idx = 0;
    182   return it;
    183 }
    184 
    185 const SourceInclude* source_depiter_next(SourceDepIter* it) {
    186   if (!it || it->idx >= it->sm->nincludes) return NULL;
    187   return &it->sm->includes[it->idx++].info;
    188 }
    189 
    190 void source_depiter_free(SourceDepIter* it) {
    191   if (!it) return;
    192   it->sm->heap->free(it->sm->heap, it, sizeof(*it));
    193 }