scc

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

commit 229b3952de509bb616c16159020fd22ae6d2fca3
parent a11e8815c38046241934f13a7719c724af0cb4bb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  9 Jan 2016 21:14:35 +0100

Split identifier() in two functions

This function was to long and with a complex logic which made very
difficult to understand it. This patch split the function in 2
functions, creating a specific function for the case when a
symbol is redeclarated.

Diffstat:
Mcc1/decl.c | 119++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
1 file changed, 67 insertions(+), 52 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -593,13 +593,72 @@ bad_storage(Type *tp, char *name) } static Symbol * +redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass) +{ + int flags; + char *name = sym->name; + + if (!eqtype(sym->type, tp)) { + errorp("conflicting types for '%s'", name); + return sym; + } + + if (sym->token == TYPEIDEN && sclass != TYPEDEF || + sym->token != TYPEIDEN && sclass == TYPEDEF) { + goto redeclaration; + } + if (curctx != GLOBALCTX && tp->op != FTN) { + /* is it the redeclaration of a local variable? */ + if ((sym->flags & ISEXTERN) && sclass == EXTERN) + return sym; + goto redeclaration; + } + + sym->u.pars = pars; + + flags = sym->flags; + switch (sclass) { + case REGISTER: + case AUTO: + bad_storage(tp, name); + break; + case NOSCLASS: + if ((flags & ISPRIVATE) == 0) { + flags &= ~ISEXTERN; + flags |= ISGLOBAL; + break; + } + errorp("non-static declaration of '%s' follows static declaration", + name); + break; + case TYPEDEF: + case EXTERN: + break; + case STATIC: + if ((flags & (ISGLOBAL|ISEXTERN)) == 0) { + flags |= ISPRIVATE; + break; + } + errorp("static declaration of '%s' follows non-static declaration", + name); + break; + } + sym->flags = flags; + + return sym; + +redeclaration: + errorp("redeclaration of '%s'", name); + return sym; +} + +static Symbol * identifier(struct decl *dcl) { Symbol *sym = dcl->sym; Type *tp = dcl->type; - char *name = sym->name; - short flags; int sclass = dcl->sclass; + char *name = sym->name; if (empty(sym, tp)) return sym; @@ -608,7 +667,9 @@ identifier(struct decl *dcl) if (!tp->defined && sclass != EXTERN && sclass != TYPEDEF) errorp("declared variable '%s' of incomplete type", name); - if (tp->op == FTN) { + if (tp->op != FTN) { + sym = install(NS_IDEN, sym); + } else { if (sclass == NOSCLASS) sclass = EXTERN; /* @@ -622,57 +683,15 @@ identifier(struct decl *dcl) ++curctx; if (!strcmp(name, "main") && tp->type != inttype) errorp("please contact __20h__ on irc.oftc.net (#suckless) via IRC"); - } else { - sym = install(NS_IDEN, sym); } if (sym == NULL) { - sym = dcl->sym; - if (!eqtype(sym->type, tp)) - error("conflicting types for '%s'", name); - if (sym->token == TYPEIDEN && sclass != TYPEDEF || - sym->token != TYPEIDEN && sclass == TYPEDEF) - goto redeclaration; - - if (curctx != GLOBALCTX && tp->op != FTN) { - if (!(sym->flags & ISEXTERN) || sclass != EXTERN) - goto redeclaration; - } else { - sym->u.pars = dcl->pars; - flags = sym->flags; - - switch (sclass) { - case REGISTER: - case AUTO: - bad_storage(tp, name); - break; - case NOSCLASS: - if ((flags & ISPRIVATE) == 0) { - flags &= ~ISEXTERN; - flags |= ISGLOBAL; - break; - } - errorp("non-static declaration of '%s' follows static declaration", - name); - break; - case TYPEDEF: - case EXTERN: - break; - case STATIC: - if ((flags & (ISGLOBAL|ISEXTERN)) == 0) { - flags |= ISPRIVATE; - break; - } - errorp("static declaration of '%s' follows non-static declaration", - name); - break; - } - } - sym->flags = flags; + sym = redcl(dcl->sym, tp, dcl->pars, sclass); } else { + short flags = sym->flags; + sym->type = tp; sym->u.pars = dcl->pars; - flags = sym->flags; switch (sclass) { case REGISTER: @@ -705,10 +724,6 @@ identifier(struct decl *dcl) if (accept('=')) initializer(sym, sym->type, -1); return sym; - -redeclaration: - errorp("redeclaration of '%s'", name); - return sym; } static Symbol *