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:
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