scc

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

commit 6d702ec165be91c82ccd3940c94625967957ae8b
parent b24acc5c7df6b763932c59376817693ed292cd68
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Thu,  9 Apr 2026 09:27:56 +0200

cc1: Add NS_MACROARG namespace

Macros are handled in translation phases 2 and 3 which means that keywords
should not affect how they work because keywords affect after translation
phase 7. To avoid problems the best solution is to have a new namespace
NS_MACROARG where we store the macro names. Trying to use NS_CPP produces
more problems because we can create fake macros that can interference
with the desired output.

Diffstat:
Msrc/cmd/scc-cc/cc1/cc1.h | 9++++++++-
Msrc/cmd/scc-cc/cc1/cpp.c | 44+++++++++++++++-----------------------------
Msrc/cmd/scc-cc/cc1/symbol.c | 2+-
Atests/cc/execute/0261-macro.c | 15+++++++++++++++
Atests/cc/execute/0262-macro.c | 11+++++++++++
Atests/cc/execute/0263-macro.c | 13+++++++++++++
Mtests/cc/execute/scc-tests.lst | 3+++
7 files changed, 66 insertions(+), 31 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -92,7 +92,14 @@ enum namespaces { NS_CPP, NS_KEYWORD, NS_CPPCLAUSES, - NS_STRUCTS + NS_MACROPAR, + + /* + * This must be the last constant of the enum definition + * because it marks the beginning of the independent + * struct namespaces + */ + NS_STRUCTS, }; /* symbol flags */ diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c @@ -533,7 +533,7 @@ getpars(Symbol *args[NR_MACROARG]) } if (yytoken == ELLIPSIS) { - sym = newsym(NS_IDEN, "__VA_ARGS__"); + sym = newsym(NS_MACROPAR, "__VA_ARGS__"); } else if (yytoken == IDEN) { sym = yylval.sym; next(); @@ -565,8 +565,8 @@ getpars(Symbol *args[NR_MACROARG]) static int getdefs(Symbol *args[NR_MACROARG], int nargs, char *buffer, size_t bufsiz) { + Symbol **argp; char c, *bp, *s, *p; - Symbol **argp, *sym; int len, id, token, prevc, ispar; while (isspace(*input->p)) @@ -578,7 +578,6 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *buffer, size_t bufsiz) ispar = 0; s = &c; token = c; - sym = NULL; if (c == '#') { if (input->p[1] == '#') { @@ -587,40 +586,27 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *buffer, size_t bufsiz) } else { c = token = STRINGIZE; } - } else if (c == '_' || isalpha(c)) { - token = IDEN; - for (p = input->p; isalnum(*p) || *p == '_'; ++p) - ; - len = p - input->p; - if (len > INTIDENTSIZ) { - cpperror("identifier too long in macro definition"); - return 0; - } - s = memcpy(yytext, input->p, len); - yytext[len] = '\0'; - yylen = len; - input->p = p - 1; - sym = lookup(NS_IDEN, yytext, NOALLOC); - } else if (c == '"' || c == '\'') { + } else if (c == '"' || c == '\'' || c == '_' || isalpha(c)) { next(); - assert(yytoken == STRING || yytoken == CONSTANT); + assert(yytoken == STRING || + yytoken == CONSTANT || + yytoken == IDEN); token = yytoken; s = yytext; len = yylen; --input->p; } - if (sym && nargs > 0) { + if (token == IDEN && nargs > 0) { for (argp = args; argp < &args[nargs]; ++argp) { - if (*argp == sym) + if (*argp == yylval.sym) { + id = argp - args; + sprintf(yytext, + "%c%02d%c", MACROPAR, id, MACROPAR); + ispar = 1; + yylen = len = 4; break; - } - if (argp != &args[nargs]) { - id = argp - args; - sprintf(yytext, - "%c%02d%c", MACROPAR, id, MACROPAR); - ispar = 1; - yylen = len = 4; + } } } @@ -678,7 +664,7 @@ define(void) } sym = yylval.sym; - namespace = NS_IDEN; /* Avoid polution in NS_CPP */ + namespace = NS_MACROPAR; /* Avoid polution in NS_CPP */ if ((n = getpars(args)) == NR_MACROARG) goto delete; if (n > 0 && strcmp(args[n-1]->name, "__VA_ARGS__") == 0) diff --git a/src/cmd/scc-cc/cc1/symbol.c b/src/cmd/scc-cc/cc1/symbol.c @@ -297,7 +297,7 @@ lookup(int ns, char *name, int alloc) * fields of such types. * TODO: Remove this trick */ - if (sns == NS_KEYWORD || + if (sns == NS_KEYWORD && ns != NS_MACROPAR && ns != NS_CPP || (sym->flags & STYPEDEF) && ns >= NS_STRUCTS) { return sym; } diff --git a/tests/cc/execute/0261-macro.c b/tests/cc/execute/0261-macro.c @@ -0,0 +1,15 @@ +#define A(sizeof) sizeof(c) + +int +f(int a) +{ + return a + 1; +} + +int +main(void) +{ + int c = 0; + + return !(A(f) == 1); +} diff --git a/tests/cc/execute/0262-macro.c b/tests/cc/execute/0262-macro.c @@ -0,0 +1,11 @@ +#define for(...) for(__VA_ARGS__) c += 2; + +int +main(void) +{ + int i, c = 0; + + for (i = 0; i < 3; i++) + + return !(c == 6); +} diff --git a/tests/cc/execute/0263-macro.c b/tests/cc/execute/0263-macro.c @@ -0,0 +1,13 @@ +typedef int cc; + +#define cc(cc, ...) for(__VA_ARGS__) cc += 2; + +int +main(void) +{ + int i, c = 0; + + cc (c, i = 0; i < 3; i++) + + return !(c == 6); +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -251,3 +251,6 @@ 0258-variadic.c 0259-multichar.c 0260-macro.c +0261-macro.c +0262-macro.c +0263-macro.c