[PATCH 12/21] stop mangling arglist, get rid of TOKEN_ARG_COUNT
Al Viro <[email protected]> Mon, 16 Mar 2026 07:04:06 +0000
| Newsgroups | org.kernel.vger.linux-sparse |
|---|---|
| Message-ID | <[email protected]> |
Now it can be done - we no longer store the counters in arglist, so there's no reason to mangle it. Just have it return the pointer to closing ) on success and let the caller split the list at that point. Simplifies both the parse_arguments() and dump_macro() and fixes a bug in the latter - pre-C99 gcc vararg macros used to lose ... in -dM output. They did work correctly, but dump_macro() output had produced #define A(X,Y) instead of correct #define A(X,Y...) Testcase added. Signed-off-by: Al Viro <[email protected]> --- pre-process.c | 47 +++++++--------------------- token.h | 9 ------ tokenize.c | 4 --- validation/preprocessor/dump-macro.c | 4 ++- 4 files changed, 15 insertions(+), 49 deletions(-) diff --git a/pre-process.c b/pre-process.c index aaf60293..a60ad687 100644 --- a/pre-process.c +++ b/pre-process.c @@ -1000,7 +1000,6 @@ static int token_different(struct token *t1, struct token *t2) case TOKEN_IDENT: different = t1->ident != t2->ident; break; - case TOKEN_ARG_COUNT: case TOKEN_UNTAINT: case TOKEN_CONCAT: case TOKEN_GNU_KLUDGE: @@ -1077,22 +1076,12 @@ Eargs: return false; } -static inline void set_arg_count(struct token *token) -{ - token_type(token) = TOKEN_ARG_COUNT; -} - static struct token *parse_arguments(struct token *list) { struct token *arg = list->next, *next = list; - set_arg_count(list); - - if (match_op(arg, ')')) { - next = arg->next; - list->next = &eof_token_entry; - return next; - } + if (match_op(arg, ')')) + return arg; while (token_type(arg) == TOKEN_IDENT) { if (arg->ident == &__VA_ARGS___ident) @@ -1102,26 +1091,18 @@ static struct token *parse_arguments(struct token *list) next = arg->next; if (match_op(next, ',')) { - set_arg_count(next); arg = next->next; continue; } - if (match_op(next, ')')) { - set_arg_count(next); - next = next->next; - arg->next->next = &eof_token_entry; + if (match_op(next, ')')) return next; - } /* normal cases are finished here */ if (match_op(next, SPECIAL_ELLIPSIS)) { if (match_op(next->next, ')')) { - set_arg_count(next); macro_vararg = macro_nargs - 1; - next = next->next; - arg->next->next = &eof_token_entry; return next->next; } @@ -1143,10 +1124,7 @@ static struct token *parse_arguments(struct token *list) goto Enotclosed; if (!macro_add_arg(arg->pos, &__VA_ARGS___ident)) return NULL; - set_arg_count(next); macro_vararg = macro_nargs - 1; - next = next->next; - arg->next->next = &eof_token_entry; return next; } @@ -1483,14 +1461,19 @@ static int do_handle_define(struct stream *stream, struct token **line, struct t expansion = left->next; if (!expansion->pos.whitespace) { if (match_op(expansion, '(')) { - arglist = expansion; - expansion = parse_arguments(expansion); - if (!expansion) { + struct token *last = parse_arguments(expansion); + if (!last) { macro_nargs = 0; macro_vararg = -1; return 1; } + // last points to ) at the end of arguments, + // expansion starts right after that, + // everything up to that point is arglist. macro_funclike = true; + arglist = expansion; + expansion = last->next; + last->next = &eof_token_entry; } else if (!eof_token(expansion)) { warning(expansion->pos, "no whitespace before object-like macro body"); @@ -2281,20 +2264,14 @@ static void dump_macro(struct symbol *sym) printf("#define %s", show_ident(sym->ident)); token = sym->arglist; if (token) { - const char *sep = ""; int narg = 0; - putchar('('); for (; !eof_token(token); token = token->next) { - if (token_type(token) == TOKEN_ARG_COUNT) - continue; - printf("%s%s", sep, show_token(token)); + printf("%s", show_token(token)); if (token_type(token) == TOKEN_IDENT) args[narg++] = token->ident; - sep = ","; } if (narg < nargs) args[narg] = &__VA_ARGS___ident; - putchar(')'); } token = sym->expansion; diff --git a/token.h b/token.h index b28ac2ca..e469e02d 100644 --- a/token.h +++ b/token.h @@ -103,7 +103,6 @@ enum token_type { TOKEN_CONCAT, TOKEN_GNU_KLUDGE, TOKEN_UNTAINT, - TOKEN_ARG_COUNT, TOKEN_IF, TOKEN_SKIP_GROUPS, TOKEN_ELSE, @@ -168,13 +167,6 @@ struct string { char data[]; }; -/* will fit into 32 bits */ -struct argcount { - unsigned normal:10; - unsigned quoted:10; - unsigned str:10; -}; - enum arg_kind { ARG_QUOTED = 0, ARG_NORMAL = 1, @@ -207,7 +199,6 @@ struct token { unsigned int special; struct string *string; int argnum; - struct argcount count; char embedded[4]; }; }; diff --git a/tokenize.c b/tokenize.c index 54ea348c..85bc3f49 100644 --- a/tokenize.c +++ b/tokenize.c @@ -241,10 +241,6 @@ const char *show_token(const struct token *token) sprintf(buffer, "<untaint>"); return buffer; - case TOKEN_ARG_COUNT: - sprintf(buffer, "<argcnt>"); - return buffer; - default: sprintf(buffer, "unhandled token type '%d' ", token_type(token)); return buffer; diff --git a/validation/preprocessor/dump-macro.c b/validation/preprocessor/dump-macro.c index 46d70b34..710c1027 100644 --- a/validation/preprocessor/dump-macro.c +++ b/validation/preprocessor/dump-macro.c @@ -1,9 +1,11 @@ #define A(X,Y,...) __VA_ARGS__,Y,X +#define B(X,Y...) Y /* * check-name: -dM handling of varargs - * check-command: sparse -E -dM $file | tail -1 + * check-command: sparse -E -dM $file | tail -2 * * check-output-start #define A(X,Y,...) __VA_ARGS__,Y,X +#define B(X,Y...) Y * check-output-end */ -- 2.47.3