Home
       symbol.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       symbol.c (1627B)
       ---
            1 #include <limits.h>
            2 #include <stdio.h>
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include <scc/scc.h>
            7 
            8 #include "cc2.h"
            9 
           10 #define NR_SYMHASH  64
           11 
           12 Symbol *locals;
           13 static Symbol *tail;
           14 
           15 static Symbol *symtab[NR_SYMHASH];
           16 static int infunction;
           17 
           18 
           19 void
           20 freesym(Symbol *sym)
           21 {
           22         free(sym->name);
           23         free(sym);
           24 }
           25 
           26 void
           27 pushctx(void)
           28 {
           29         infunction = 1;
           30 }
           31 
           32 void
           33 popctx(void)
           34 {
           35         Symbol *sym, *prev;
           36 
           37         infunction = 0;
           38         for (sym = tail; sym; sym = prev) {
           39                 prev = sym->prev;
           40                 /*
           41                  * Symbols are inserted in the hash in the inverted
           42                  * order they are found in locals and it is impossible
           43                  * to have a global over a local, because a local is
           44                  * any symbol defined in the body of a function,
           45                  * even if it has extern linkage.
           46                  * For this reason when we reach a symbol in the
           47                  * locals list we know that it is the head of it
           48                  * collision list and we can remove it assigning
           49                  * it h_next to the hash table position
           50                  */
           51                 if (sym->id != TMPSYM)
           52                         symtab[sym->id & NR_SYMHASH-1] = sym->h_next;
           53                 freesym(sym);
           54         }
           55         locals = tail = NULL;
           56 }
           57 
           58 Symbol *
           59 getsym(unsigned id)
           60 {
           61         Symbol **htab, *sym;
           62         static unsigned short num;
           63 
           64         if (id >= USHRT_MAX)
           65                 error(EBADID);
           66 
           67         if (id != TMPSYM) {
           68                 htab = &symtab[id & NR_SYMHASH-1];
           69                 for (sym = *htab; sym; sym = sym->h_next) {
           70                         if (sym->id == id)
           71                                 return sym;
           72                 }
           73         }
           74 
           75         sym = xcalloc(1, sizeof(*sym));
           76         sym->id = id;
           77         if (infunction) {
           78                 sym->next = NULL;
           79                 sym->prev = tail;
           80                 if (tail)
           81                         tail->next = sym;
           82                 tail = sym;
           83                 if (!locals)
           84                         locals = sym;
           85         }
           86         if (id != TMPSYM) {
           87                 sym->h_next = *htab;
           88                 *htab = sym;
           89         }
           90         if ((sym->numid = ++num) == 0)
           91                 error(EIDOVER);
           92 
           93         return sym;
           94 }