scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

symbol.c (1641B)


      1 static char sccsid[] = "@(#) ./cc2/symbol.c";
      2 #include <limits.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include <scc/scc.h>
      8 
      9 #include "cc2.h"
     10 
     11 #define NR_SYMHASH  64
     12 
     13 Symbol *locals;
     14 
     15 static Symbol *symtab[NR_SYMHASH], *curlocal;
     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, *next;
     36 
     37 	infunction = 0;
     38 	for (sym = locals; sym; sym = next) {
     39 		next = sym->next;
     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 	curlocal = locals = 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 		if (!locals)
     79 			locals = sym;
     80 		if (curlocal)
     81 			curlocal->next = sym;
     82 		curlocal = sym;
     83 	}
     84 	if (id != TMPSYM) {
     85 		sym->h_next = *htab;
     86 		*htab = sym;
     87 	}
     88 	if ((sym->numid = ++num) == 0)
     89 		error(EIDOVER);
     90 
     91 	return sym;
     92 }