public inbox for linux-sparse@vger.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-sparse@vger.kernel.org
Cc: chriscli@google.com, torvalds@linux-foundation.org,
	zxh@xh-zhang.com, ben.dooks@codethink.co.uk,
	dan.carpenter@linaro.org, rf@opensource.cirrus.com
Subject: [PATCH 4/6] TOKEN_DIRECTIVE: recognize directive-introducing # in tokenizer
Date: Tue, 31 Mar 2026 09:07:27 +0100	[thread overview]
Message-ID: <20260331080729.1378613-4-viro@zeniv.linux.org.uk> (raw)
In-Reply-To: <20260331080729.1378613-1-viro@zeniv.linux.org.uk>

'#' acts as start of directive it had been the first token in its line
at the beginning of phase 4.  In other words, it must have come from
the input stream rather than from macro expansion (# may be present in
the body of object-like macro) and there must've been no token between
it and beginning of the line *before* any macro expansion had been
done (i.e. in
	#define EMPTY
	EMPTY #include <stdlib.h>
the # in front of include is *not* a beginning of directive).

Currently we handle that by hijacking 'noexpand' flag to mark the instances
of # coming from macro expansion and checking if the token we'd run into
might be a directive-starting # in do_preprocess() and in collect_arg().

It's actually simpler and faster to recognize those in tokenizer.  Just
have get_one_special() check if it's about to return a TOKEN_SPECIAL[#]
and if it's the first token in its line, return a token of new type
(TOKEN_DIRECTIVE).  Checks in the preprocessor get simpler and we get
rid of 'noexpand' abuse - there's no way for TOKEN_DIRECTIVE to end up
in the body of any macro.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 pre-process.c | 22 ++++++++--------------
 token.h       |  1 +
 tokenize.c    |  2 ++
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/pre-process.c b/pre-process.c
index ea199a9a..e62d6379 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -263,12 +263,10 @@ static struct token *collect_arg(struct token *prev, bool vararg, const struct p
 	int nesting = 0;
 
 	while (!eof_token(next = scan_next(p))) {
-		if (next->pos.newline && match_op(next, '#')) {
-			if (!next->pos.noexpand) {
-				preprocessor_line(stream, p);
-				__free_token(next);	/* Free the '#' token */
-				continue;
-			}
+		if (token_type(next) == TOKEN_DIRECTIVE) {
+			preprocessor_line(stream, p);
+			__free_token(next);	/* Free the '#' token */
+			continue;
 		}
 		switch (token_type(next)) {
 		case TOKEN_STREAMEND:
@@ -1402,8 +1400,6 @@ static struct token *handle_hash(struct token **p, struct arg_state args[])
 			goto Equote;
 		__free_token(token);
 		token = *p = next;
-	} else {
-		token->pos.noexpand = 1;
 	}
 	return token;
 
@@ -2427,12 +2423,10 @@ static void do_preprocess(struct token **list)
 	while (!eof_token(next = scan_next(list))) {
 		struct stream *stream = input_streams + next->pos.stream;
 
-		if (next->pos.newline && match_op(next, '#')) {
-			if (!next->pos.noexpand) {
-				preprocessor_line(stream, list);
-				__free_token(next);	/* Free the '#' token */
-				continue;
-			}
+		if (token_type(next) == TOKEN_DIRECTIVE) {
+			preprocessor_line(stream, list);
+			__free_token(next);	/* Free the '#' token */
+			continue;
 		}
 
 		switch (token_type(next)) {
diff --git a/token.h b/token.h
index 5915d6a4..7265bae5 100644
--- a/token.h
+++ b/token.h
@@ -109,6 +109,7 @@ enum token_type {
 	TOKEN_IF,
 	TOKEN_SKIP_GROUPS,
 	TOKEN_ELSE,
+	TOKEN_DIRECTIVE,
 };
 
 /* Combination tokens */
diff --git a/tokenize.c b/tokenize.c
index e6e071ae..9f7912c4 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -790,6 +790,8 @@ static int get_one_special(int c, stream_t *stream)
 	/* Pass it on.. */
 	token = stream->token;
 	token_type(token) = TOKEN_SPECIAL;
+	if (value == '#' && token->pos.newline)
+		token_type(token) = TOKEN_DIRECTIVE;
 	token->special = value;
 	add_token(stream);
 	return next;
-- 
2.47.3


  parent reply	other threads:[~2026-03-31  8:04 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1771930766.git.dan.carpenter@linaro.org>
2026-02-24 11:07 ` [PATCH] sparse: add support for __VA_OPT__ Dan Carpenter
2026-02-24 11:16   ` Ben Dooks
2026-02-24 11:56     ` Dan Carpenter
2026-02-24 12:42       ` Richard Fitzgerald
2026-02-24 13:15         ` Ben Dooks
2026-02-25  2:39   ` Chris Li
2026-02-25  3:36     ` Al Viro
2026-02-25  5:29       ` [RFC PATCH] pre-process: add __VA_OPT__ support Eric Zhang
2026-02-25  6:40         ` Al Viro
2026-02-25  7:27           ` Al Viro
2026-02-25  8:14             ` Eric Zhang
2026-02-25 22:18               ` Al Viro
2026-02-26  7:29                 ` Al Viro
2026-03-16  6:56                   ` Al Viro
2026-03-16  7:03                     ` [PATCH 01/21] split copy() into "need to copy" and "can move in place" cases Al Viro
2026-03-16  7:03                       ` [PATCH 02/21] expand and simplify the call of dup_token() in copy() Al Viro
2026-03-16  7:03                       ` [PATCH 03/21] more dup_token() optimizations Al Viro
2026-03-16  7:03                       ` [PATCH 04/21] parsing #define: saner handling of argument count, part 1 Al Viro
2026-03-16  7:03                       ` [PATCH 05/21] simplify collect_arguments() and fix error handling there Al Viro
2026-03-16  7:04                       ` [PATCH 06/21] try_arg(): don't use arglist for argument name lookups Al Viro
2026-03-16  7:04                       ` [PATCH 07/21] make expand_has_...() responsible for expanding its argument Al Viro
2026-03-16  7:04                       ` [PATCH 08/21] preparing to change argument number encoding for TOKEN_..._ARGUMENT Al Viro
2026-03-16  7:04                       ` [PATCH 09/21] steal 2 bits from argnum for argument kind Al Viro
2026-03-16  7:04                       ` [PATCH 10/21] on-demand argument expansion Al Viro
2026-03-16  7:04                       ` [PATCH 11/21] kill create_arglist() Al Viro
2026-03-16  7:04                       ` [PATCH 12/21] stop mangling arglist, get rid of TOKEN_ARG_COUNT Al Viro
2026-03-16  7:04                       ` [PATCH 13/21] deal with ## on arguments separately Al Viro
2026-03-16  7:04                       ` [PATCH 14/21] preparations for __VA_OPT__ support: reshuffle argument slot assignments Al Viro
2026-03-16  7:04                       ` [PATCH 15/21] pre-process.c: split try_arg() Al Viro
2026-03-16  7:04                       ` [PATCH 16/21] __VA_OPT__: parsing Al Viro
2026-03-16  7:04                       ` [PATCH 17/21] expansion-time va_opt handling Al Viro
2026-03-16  7:04                       ` [PATCH 18/21] merge(): saner handling of ->noexpand Al Viro
2026-03-16  7:04                       ` [PATCH 19/21] simplify the calling conventions of collect_arguments() Al Viro
2026-03-16  7:04                       ` [PATCH 20/21] make expand_one_symbol() inline Al Viro
2026-03-16  7:04                       ` [PATCH 21/21] substitute(): convert switch() into cascade of ifs Al Viro
2026-03-16 16:42                     ` [RFC PATCH] pre-process: add __VA_OPT__ support Linus Torvalds
2026-03-19  3:53                       ` Al Viro
2026-03-19  4:07                         ` Linus Torvalds
2026-03-19  5:34                           ` Al Viro
2026-03-17  7:41                     ` Chris Li
2026-03-18  6:35                     ` Eric Zhang
2026-03-31  8:06                     ` Al Viro
2026-03-31  8:07                       ` [PATCH 1/6] nextchar(): get rid of special[] Al Viro
2026-03-31  8:07                         ` [PATCH 2/6] simplify the inlined side of nextchar() Al Viro
2026-03-31  8:07                         ` [PATCH 3/6] tokenize_stream(): don't bother with isspace() Al Viro
2026-03-31  8:07                         ` Al Viro [this message]
2026-03-31  8:07                         ` [PATCH 5/6] saner collect_arg() code generation Al Viro
2026-03-31  8:07                         ` [PATCH 6/6] try to get whitespaces right Al Viro
2026-04-01 10:39                       ` [RFC PATCH] pre-process: add __VA_OPT__ support Al Viro
2026-04-01 16:18                         ` Linus Torvalds
2026-04-01 19:52                           ` Al Viro
2026-04-01 20:22                             ` Al Viro
2026-02-25  7:05       ` [PATCH] sparse: add support for __VA_OPT__ Chris Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260331080729.1378613-4-viro@zeniv.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=ben.dooks@codethink.co.uk \
    --cc=chriscli@google.com \
    --cc=dan.carpenter@linaro.org \
    --cc=linux-sparse@vger.kernel.org \
    --cc=rf@opensource.cirrus.com \
    --cc=torvalds@linux-foundation.org \
    --cc=zxh@xh-zhang.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox