scc

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

symbol.c (1595B)


      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 
     14 static Symbol *symtab[NR_SYMHASH], *curlocal;
     15 static int infunction;
     16 
     17 
     18 void
     19 freesym(Symbol *sym)
     20 {
     21 	free(sym->name);
     22 	free(sym);
     23 }
     24 
     25 void
     26 pushctx(void)
     27 {
     28 	infunction = 1;
     29 }
     30 
     31 void
     32 popctx(void)
     33 {
     34 	Symbol *sym, *next;
     35 
     36 	infunction = 0;
     37 	for (sym = locals; sym; sym = next) {
     38 		next = sym->next;
     39 		/*
     40 		 * Symbols are inserted in the hash in the inverted
     41 		 * order they are found in locals and it is impossible
     42 		 * to have a global over a local, because a local is
     43 		 * any symbol defined in the body of a function,
     44 		 * even if it has extern linkage.
     45 		 * For this reason when we reach a symbol in the
     46 		 * locals list we know that it is the head of it
     47 		 * collision list and we can remove it assigning
     48 		 * it h_next to the hash table position
     49 		 */
     50 		if (sym->id != TMPSYM)
     51 			symtab[sym->id & NR_SYMHASH-1] = sym->h_next;
     52 		freesym(sym);
     53 	}
     54 	curlocal = locals = NULL;
     55 }
     56 
     57 Symbol *
     58 getsym(unsigned id)
     59 {
     60 	Symbol **htab, *sym;
     61 	static unsigned short num;
     62 
     63 	if (id >= USHRT_MAX)
     64 		error(EBADID);
     65 
     66 	if (id != TMPSYM) {
     67 		htab = &symtab[id & NR_SYMHASH-1];
     68 		for (sym = *htab; sym; sym = sym->h_next) {
     69 			if (sym->id == id)
     70 				return sym;
     71 		}
     72 	}
     73 
     74 	sym = xcalloc(1, sizeof(*sym));
     75 	sym->id = id;
     76 	if (infunction) {
     77 		if (!locals)
     78 			locals = sym;
     79 		if (curlocal)
     80 			curlocal->next = sym;
     81 		curlocal = sym;
     82 	}
     83 	if (id != TMPSYM) {
     84 		sym->h_next = *htab;
     85 		*htab = sym;
     86 	}
     87 	if ((sym->numid = ++num) == 0)
     88 		error(EIDOVER);
     89 
     90 	return sym;
     91 }