scc

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

commit 994751d39485e086ef623f202fb1b84729fd5d19
parent cae3fc327c4969ad626fbbe90f00026e977671e0
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 28 May 2022 08:34:45 +0200

cc1: Fix hideset implementation

The correct macro expansion is based in the hideset concept.
When the macro is expanded and scanned for tokens all the
macros expanded in the context of the macro expansion must
be disabled and not expanded again. It means that the hide
set of every macro expansion cannot be represented only with
a symbol but with a set of symbols.

It is important to hide the symbols after they are expanded
in the context of the macro expansion until the macro
expansion finished.

Diffstat:
Msrc/cmd/cc/cc1/cc1.h | 3+++
Msrc/cmd/cc/cc1/cpp.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/cmd/cc/cc1/lex.c | 20+-------------------
3 files changed, 60 insertions(+), 31 deletions(-)

diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h @@ -396,6 +396,7 @@ struct yystype { unsigned char token; }; +#ifdef NR_MACROARG struct macro { Symbol *sym; char *fname; @@ -404,7 +405,9 @@ struct macro { char *def; int bufsiz; int npars; + Symbol *hideset[NR_MACROARG]; }; +#endif #ifdef stdin struct input { diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -28,7 +28,6 @@ defdefine(char *name, char *val, char *source) .name = name, .flags = SDECLARED, }; - Macro *mp; if (!val) val = ""; @@ -38,12 +37,9 @@ defdefine(char *name, char *val, char *source) } sprintf(buffer, fmt, name, val); - mp = newmacro(sym); - mp->buffer = buffer; - mp->fname = source; - lineno = ++ncmdlines; - addinput(IMACRO, mp, FAIL); + + addinput(IPARAM, buffer, FAIL); cpp(); delinput(); } @@ -120,6 +116,7 @@ parameter(Macro *mp) { int siz; char *s, *begin, *end; + Input *ip = input; begin = input->begin; for (;;) { @@ -301,10 +298,45 @@ expansion_too_long: error("macro expansion of \"%s\" too long", mp->sym->name); } +static void +addhideset(Input *ip, Symbol *sym) +{ + Symbol **set; + Symbol **p; + + set = ip->macro->hideset; + for (p = set; p < &set[NR_MACROARG] && *p; ++p) { + if (*p == sym) + return; + } + + if (p == &set[NR_MACROARG]) + error("too complex macro expansion"); + + *p = sym; + DBG("MACRO Adding %s to hideset of %s", + sym->name, ip->macro->sym->name); +} + +static void +hide(Symbol *sym) +{ + DBG("SYM: hidding symbol %s %d", sym->name, sym->hide); + sym->hide = 1; +} + +static void +unhide(Symbol *sym) +{ + DBG("SYM: unhidding symbol %s %d", sym->name, sym->hide); + sym->hide = 0; +} + void delmacro(Macro *mp) { int i; + Symbol **p; if (!mp) return; @@ -313,6 +345,10 @@ delmacro(Macro *mp) for (i = 0; i < mp->npars; i++) free(mp->arglist[i]); } + + for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p) + unhide(*p); + free(mp->arglist); free(mp); } @@ -323,11 +359,9 @@ newmacro(Symbol *sym) Macro *mp; mp = xmalloc(sizeof(*mp)); + *mp = (Macro) {0}; mp->sym = sym; - mp->arglist = NULL; mp->def = sym->u.s + 3; - mp->npars = 0; - mp->buffer = NULL; if (sym->u.s) mp->npars = atoi(sym->u.s); @@ -337,8 +371,10 @@ newmacro(Symbol *sym) int expand(Symbol *sym) { - int elen; + int siz; Macro *mp; + Input *ip; + Symbol **p; DBG("MACRO '%s' detected disexpand=%d hide=%d", sym->name, disexpand, sym->hide); @@ -358,8 +394,16 @@ expand(Symbol *sym) mp->buffer = input->line; mp->bufsiz = INPUTSIZ-1; - elen = copymacro(mp); - mp->buffer[elen] = '\0'; + siz = copymacro(mp); + mp->buffer[siz] = '\0'; + + for (ip = input; ip; ip = ip->next) { + if ((ip->flags & ITYPE) == IMACRO) + addhideset(ip, sym); + } + + for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p) + hide(*p); DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, mp->buffer); diff --git a/src/cmd/cc/cc1/lex.c b/src/cmd/cc/cc1/lex.c @@ -48,22 +48,6 @@ setloc(char *fname, unsigned line) lineno = input->lineno = line; } -static void -hide(Symbol *sym) -{ - assert(sym->hide == 0); - sym->hide = 1; - DBG("SYM: hidding symbol %s %d", sym->name, sym->hide); -} - -static void -unhide(Symbol *sym) -{ - assert(sym->hide == 1); - DBG("SYM: unhidding symbol %s %d", sym->name, sym->hide); - sym->hide = 0; -} - int addinput(int type, void *arg, int fail) { @@ -84,7 +68,6 @@ addinput(int type, void *arg, int fail) sym = mp->sym; fname = mp->fname; buffer = mp->buffer; - hide(sym); DBG("INPUT: expanding macro %s", sym->name); break; case IPARAM: @@ -162,7 +145,7 @@ delinput(void) break; case IMACRO: DBG("INPUT: macro %s finished", ip->macro->sym->name); - unhide(ip->macro->sym); + delmacro(ip->macro); break; case IPARAM: DBG("INPUT: macro param finished"); @@ -175,7 +158,6 @@ delinput(void) } input = ip->next; - delmacro(ip->macro); free(ip->filenam); free(ip->line); free(ip);