scc

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

commit d59f0b5d2d11178047efaa052eb6659e48bb827e
parent cd2e378821e5e5f86215643e87a6b806a8b54492
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Tue, 16 Jun 2026 22:07:09 +0200

cc1: Add hideset by input

Having a hideset by input allows to follow the Prosser algorithm [1],
because hideset changes happens only when expansions happen, so we
can continue using the push up input streams to implemenet the algorithm
while we maintain the hideset for every new input push up.

[1] https://www.spinellis.gr/blog/20060626/cpp.algo.pdf

Diffstat:
Msrc/cmd/scc-cc/cc1/cc1.h | 4+++-
Msrc/cmd/scc-cc/cc1/cpp.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/cmd/scc-cc/cc1/error.c | 2++
Msrc/cmd/scc-cc/cc1/lex.c | 23+++++++++++++++++++++--
4 files changed, 82 insertions(+), 23 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -428,7 +428,7 @@ struct macro { }; #endif -#ifdef stdin +#if defined(stdin) && defined(NR_MACROARG) struct input { char flags; unsigned lineno; @@ -436,6 +436,7 @@ struct input { FILE *fp; Macro *macro; char *line, *begin, *p; + Symbol *hideset[NR_MACROARG]; struct input *next; }; #endif @@ -530,6 +531,7 @@ void defdefine(char *, char *, char *); void undefmacro(char *); void ppragmaln(void); void delmacro(Macro *); +void sethideset(Input *), unsethideset(Input *); Macro *newmacro(Symbol *); Node *defined(void); diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c @@ -361,6 +361,7 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz) buf += siz; } } else { + disexpand++; addinput(IPARAM, arg, FAIL); for (siz = 0; ; siz += yylen) { yyspace = '\0'; @@ -383,6 +384,7 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz) } delinput(); + disexpand--; } *buf = '\0'; @@ -472,13 +474,19 @@ expansion_too_long: error("macro expansion of \"%s\" too long", mp->sym->name); } +/* + * Functions to deal with macro hidesets. Yes, this sucks, a lot, + * but before blaming me read + * https://www.spinellis.gr/blog/20060626/cpp.algo.pdf + * It is not my fault. + */ static void -addhideset(Input *ip, Symbol *sym) +addhideset(Symbol *sym) { - Symbol **set; - Symbol **p; + char *iname; + Symbol **set, **p; - set = ip->macro->hideset; + set = input->hideset; for (p = set; p < &set[NR_MACROARG] && *p; ++p) { if (*p == sym) return; @@ -489,7 +497,7 @@ addhideset(Input *ip, Symbol *sym) *p = sym; DBG("MACRO Adding %s to hideset of %s", - sym->name, ip->macro->sym->name); + sym->name, input->macro->sym->name); } static void @@ -507,6 +515,26 @@ unhide(Symbol *sym) } void +unsethideset(Input *ip) +{ + Symbol **set, **p; + + set = ip->hideset; + for (p = set; p < &set[NR_MACROARG] && *p; ++p) + unhide(*p); +} + +void +sethideset(Input *ip) +{ + Symbol **set, **p; + + set = ip->hideset; + for (p = set; p < &set[NR_MACROARG] && *p; ++p) + hide(*p); +} + +void delmacro(Macro *mp) { int i; @@ -520,9 +548,6 @@ delmacro(Macro *mp) free(mp->arglist[i]); } - for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p) - unhide(*p); - free(mp->arglist); free(mp); } @@ -532,8 +557,7 @@ newmacro(Symbol *sym) { Macro *mp; - mp = xmalloc(sizeof(*mp)); - *mp = (Macro) {0}; + mp = memset(xmalloc(sizeof(*mp)), 0, sizeof(*mp)); mp->sym = sym; mp->def = sym->u.s + 3; if (sym->u.s) @@ -542,13 +566,27 @@ newmacro(Symbol *sym) return mp; } +static void +intersect(Symbol **dst, Symbol **set) +{ + Symbol *sym, **cur, **p; + + for (cur = dst; sym = *cur; ++cur) { + for (p = set; *p && *p != sym; ++p) + ; + if (*p) + *dst++ = sym; + } + + while (dst != cur) + *dst++ = NULL; +} + int expand(Symbol *sym) { int siz; Macro *mp; - Input *ip; - Symbol **p; DBG("MACRO '%s' detected disexpand=%d hide=%d", sym->name, disexpand, sym->hide); @@ -558,27 +596,25 @@ expand(Symbol *sym) mp = newmacro(sym); mp->fname = filenam; + memcpy(mp->hideset, input->hideset, sizeof(mp->hideset)); if (!parsepars(mp)) { delmacro(mp); return 0; } + if (mp->npars != -1) + intersect(mp->hideset, input->hideset); addinput(IMACRO, mp, FAIL); + addhideset(sym); + hide(sym); + mp->buffer = input->line; mp->bufsiz = INPUTSIZ-1; 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); return 1; diff --git a/src/cmd/scc-cc/cc1/error.c b/src/cmd/scc-cc/cc1/error.c @@ -2,7 +2,9 @@ #include <stdio.h> #include <stdlib.h> +#include <scc/cstd.h> #include <scc/scc.h> + #include "cc1.h" #define MAXERRNUM 10 diff --git a/src/cmd/scc-cc/cc1/lex.c b/src/cmd/scc-cc/cc1/lex.c @@ -60,7 +60,7 @@ addinput(int type, void *arg, int fail) char *extp, *fname, *buffer, *infile; int infileln; Macro *mp; - Symbol *sym; + Symbol *sym, **hs; Input *newip, *curip = input; if (curip) @@ -122,6 +122,9 @@ addinput(int type, void *arg, int fail) buffer = xstrdup(buffer); } + if (input) + unsethideset(input); + newip = xmalloc(sizeof(*newip)); newip->next = curip; newip->macro = mp; @@ -130,8 +133,21 @@ addinput(int type, void *arg, int fail) newip->lineno = 0; newip->fp = fp; newip->flags = type; + memset(newip->hideset, 0, sizeof(newip->hideset)); input = newip; + hs = NULL; + if (curip) + hs = curip->hideset; + if (type == IMACRO) + hs = mp->hideset; + if (type == IPARAM && curip) + hs = curip->macro->hideset; + if (hs) { + memcpy(input->hideset, hs, sizeof(input->hideset)); + sethideset(input); + } + setloc(fname, lineno); return 1; } @@ -160,13 +176,16 @@ delinput(void) default: abort(); } + unsethideset(input); input = ip->next; free(ip->filenam); free(ip->line); free(ip); - if (input) + if (input) { + sethideset(input); setloc(input->filenam, input->lineno); + } } static void