scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

symbol.c (1654B)


      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 "../inc/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 	htab = &symtab[id & NR_SYMHASH-1];
     68 	for (sym = *htab; sym; sym = sym->h_next) {
     69 		if (sym->id > 0 && sym->id == id)
     70 			break;
     71 	}
     72 	if (!sym) {
     73 		sym = xcalloc(1, sizeof(*sym));
     74 		sym->id = id;
     75 		if ((sym->numid = ++num) == 0)
     76 			error(EIDOVER);
     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 	}
     89 	return sym;
     90 }