aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-04-12 16:09:14 +0800
committerTeddy <ted.sybil@gmail.com>2014-04-12 16:09:14 +0800
commit85d862310c2e00361f68c317c6256b29f18eae36 (patch)
treee7c0581472045c1b9327c033a6f3874be25ae79f
parent63e795cad88cb52ecdf46f90584867ae22939058 (diff)
memory leaknew_scope_design
-rw-r--r--semantics.c73
-rw-r--r--semantics.h5
2 files changed, 45 insertions, 33 deletions
diff --git a/semantics.c b/semantics.c
index 92d7f0b..ea64905 100644
--- a/semantics.c
+++ b/semantics.c
@@ -73,20 +73,6 @@ const char *csymbol_getname(CSymbol_t sym) {
sym->rec.var->name : sym->rec.type->name;
}
-CSymbol_t type2sym(CType_t type) {
- CSymbol_t p = NEW(CSymbol);
- p->kind = CTYPE;
- p->rec.type = type;
- return p;
-}
-
-CSymbol_t var2sym(CVar_t var) {
- CSymbol_t p = NEW(CSymbol);
- p->kind = CVAR;
- p->rec.var = var;
- return p;
-}
-
#ifdef CIBIC_DEBUG
CTable_t ctable_create(Hashfunc_t hfunc, Printfunc_t pfunc) {
CTable_t ct = NEW(CTable);
@@ -169,7 +155,7 @@ CScope_t cscope_create() {
return p;
}
-int cscope_push(CScope_t cs, CSymbol_t sym, int nspace) {
+static int cscope_push(CScope_t cs, CSymbol_t sym, int nspace) {
CTable_t ct = nspace == NS_ID ? cs->ids: cs->tags;
#ifdef CIBIC_DEBUG
assert(cs->top);
@@ -185,6 +171,30 @@ int cscope_push(CScope_t cs, CSymbol_t sym, int nspace) {
else return 0; /* naming conflict */
}
+int cscope_push_var(CScope_t cs, CVar_t var, int nspace) {
+ CSymbol_t p = NEW(CSymbol);
+ p->kind = CVAR;
+ p->rec.var = var;
+ if (!cscope_push(cs, p, nspace))
+ {
+ free(p);
+ return 0;
+ }
+ return 1;
+}
+
+int cscope_push_type(CScope_t cs, CType_t type, int nspace) {
+ CSymbol_t p = NEW(CSymbol);
+ p->kind = CTYPE;
+ p->rec.type = type;
+ if (!cscope_push(cs, p, nspace))
+ {
+ free(p);
+ return 0;
+ }
+ return 1;
+}
+
void cscope_enter(CScope_t cs) {
CSNode *np = NEW(CSNode);
np->next = cs->top;
@@ -195,14 +205,17 @@ void cscope_enter(CScope_t cs) {
void cscope_exit(CScope_t cs) {
CSNode *top_o = cs->top;
- CSElem *p;
+ CSElem *p, *np;
cs->lvl--;
cs->top = top_o->next;
- for (p = top_o->symlist; p; p = p->next)
+ for (p = top_o->symlist; p; p = np)
{
const char *name = csymbol_getname(p->sym);
ctable_clip(cs->ids, name, cs->lvl);
ctable_clip(cs->tags, name, cs->lvl);
+ np = p->next;
+ free(p->sym); /* free CSymbol */
+ free(p); /* free CSElem */
}
free(top_o);
}
@@ -375,7 +388,7 @@ static CType_t struct_type_merge(CType_t new, CScope_t scope) {
CType_t old;
if (!lu) /* create it if it does not exist */
{
- cscope_push(scope, type2sym(new), NS_TAG);
+ cscope_push_type(scope, new, NS_TAG);
return new;
} /* otherwise we have it */
old = lu->rec.type;
@@ -385,7 +398,7 @@ static CType_t struct_type_merge(CType_t new, CScope_t scope) {
if (!new->rec.fields) /* use the old definition */
return old;
/* otherwise there's a completion definition */
- if (cscope_push(scope, type2sym(new), NS_TAG)) /* try to push the defintion */
+ if (cscope_push_type(scope, new, NS_TAG)) /* try to push the defintion */
return new;
/* conflict appears */
if (old->rec.fields) /* if the old one is complete */
@@ -455,7 +468,7 @@ int is_same_type(CType_t typea, CType_t typeb) {
static CVar_t var_merge(CVar_t new, CScope_t scope) {
CVar_t old;
- if (cscope_push(scope, var2sym(new), NS_ID))
+ if (cscope_push_var(scope, new, NS_ID))
return new;
else
old = cscope_lookup(scope, new->name, NS_ID)->rec.var;
@@ -720,7 +733,7 @@ CVar_t semantics_decl(CNode *p, CScope_t scope) {
if ((type->type == CSTRUCT || type->type == CUNION) &&
(*type->name) != '\0')
{
- cscope_push(scope, type2sym(type), NS_TAG);
+ cscope_push_type(scope, type, NS_TAG);
useful = 1;
}
if (declr->chd->type != NOP)
@@ -734,7 +747,7 @@ CVar_t semantics_decl(CNode *p, CScope_t scope) {
{
CType_t func = var->type;
func->name = var->name;
- if (!cscope_push(scope, type2sym(func), NS_ID))
+ if (!cscope_push_type(scope, func, NS_ID))
{
CSymbol_t lu = cscope_lookup(scope, func->name, NS_ID);
if (lu->kind != CTYPE)
@@ -1462,7 +1475,7 @@ CType_t semantics_func(CNode *p, CScope_t scope) {
scope->top = ntop->next;
scope->lvl--;
- if (!cscope_push(scope, type2sym(func), NS_ID))
+ if (!cscope_push_type(scope, func, NS_ID))
{
CSymbol_t lu = cscope_lookup(scope, func->name, NS_ID);
if (lu->kind != CTYPE)
@@ -1483,7 +1496,7 @@ CType_t semantics_func(CNode *p, CScope_t scope) {
for (var = func->rec.func.params; var; var = var->next)
{
- cscope_push(scope, var2sym(var), NS_ID);
+ cscope_push_var(scope, var, NS_ID);
if (!type_is_complete(var->type))
ERROR((var->ast, "parameter '%s' has incomplete type", var->name));
}
@@ -1516,12 +1529,12 @@ void semantics_check(CNode *p) {
builtin_malloc = make_builtin_func("malloc", vstar);
}
/* add top-level basic types */
- cscope_push(scope, type2sym(basic_type_int), NS_TAG);
- cscope_push(scope, type2sym(basic_type_char), NS_TAG);
- cscope_push(scope, type2sym(basic_type_void), NS_TAG);
- cscope_push(scope, type2sym(builtin_printf), NS_ID);
- cscope_push(scope, type2sym(builtin_scanf), NS_ID);
- cscope_push(scope, type2sym(builtin_malloc), NS_ID);
+ cscope_push_type(scope, basic_type_int, NS_TAG);
+ cscope_push_type(scope, basic_type_char, NS_TAG);
+ cscope_push_type(scope, basic_type_void, NS_TAG);
+ cscope_push_type(scope, builtin_printf, NS_ID);
+ cscope_push_type(scope, builtin_scanf, NS_ID);
+ cscope_push_type(scope, builtin_malloc, NS_ID);
/* check all definitions and declarations */
for (p = p->chd; p; p = p->next)
{
diff --git a/semantics.h b/semantics.h
index 00c8525..bcd8ca8 100644
--- a/semantics.h
+++ b/semantics.h
@@ -129,13 +129,12 @@ struct CSymbol {
} rec;
};
const char *csymbol_print(void *csym);
-CSymbol_t type2sym(CType_t type);
-CSymbol_t var2sym(CVar_t var);
const char *csym_getname(CSymbol_t csym);
CScope_t cscope_create();
CSymbol_t cscope_lookup(CScope_t cs, const char *name, int nspace);
-int cscope_push(CScope_t cs, CSymbol_t sym, int nspace);
+int cscope_push_var(CScope_t cs, CVar_t var, int nspace);
+int cscope_push_type(CScope_t cs, CType_t type, int nspace);
void cscope_enter(CScope_t cs);
void cscope_exit(CScope_t cs);
void cscope_debug_print(CScope_t cs);