scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }