@@ -59,7 +59,6 @@ IDENT_RESERVED(__label__);
* sparse. */
IDENT(defined);
IDENT(once);
-__IDENT(pragma_ident, "__pragma__", 0);
__IDENT(__VA_ARGS___ident, "__VA_ARGS__", 0);
__IDENT(__LINE___ident, "__LINE__", 0);
__IDENT(__FILE___ident, "__FILE__", 0);
@@ -211,7 +211,7 @@ static void expand_list(struct token **list)
}
}
-static void preprocessor_line(struct stream *stream, struct token **line);
+static int preprocessor_line(struct stream *stream, struct token **line);
static struct token *collect_arg(struct token *prev, int vararg, struct position *pos, int count)
{
@@ -225,9 +225,10 @@ static struct token *collect_arg(struct token *prev, int vararg, struct position
if (!next->pos.noexpand) {
sparse_error(next->pos,
"directive in argument list");
- preprocessor_line(stream, p);
- __free_token(next); /* Free the '#' token */
- continue;
+ if(preprocessor_line(stream, p)) {
+ __free_token(next); /* Free the '#' token */
+ continue;
+ }
}
}
switch (token_type(next)) {
@@ -1808,31 +1809,25 @@ static int handle_split_include(struct stream *stream, struct token **line, stru
}
/*
- * We replace "#pragma xxx" with "__pragma__" in the token
- * stream. Just as an example.
- *
- * We'll just #define that away for now, but the theory here
- * is that we can use this to insert arbitrary token sequences
- * to turn the pragmas into internal front-end sequences for
- * when we actually start caring about them.
- *
- * So eventually this will turn into some kind of extended
- * __attribute__() like thing, except called __pragma__(xxx).
+ * pragma, unlike all other directives starting with '#' is not
+ * meant for the preprocessor to consume, but it should be
+ * echoed back exactly as in the source code.
+ * the only exception is pragma once, which is targetting the
+ * cpp. preprocessor_line() assumes that any line starting with '#'
+ * can be dropped and manipulates the list to point to the token after
+ * the next newline. however, we need to undo this here if what we get
+ * is not "pragma once. thus we pass the start token pointing to '#'
+ * unlike all other handler function, so we can safely restore the list.
*/
-static int handle_pragma(struct stream *stream, struct token **line, struct token *token)
+static int handle_pragma(struct stream *stream, struct token **line, struct token *start)
{
- struct token *next = *line;
-
+ struct token *token = start->next;
if (match_ident(token->next, &once_ident) && eof_token(token->next->next)) {
stream->once = 1;
return 1;
}
- token->ident = &pragma_ident;
- token->pos.newline = 1;
- token->pos.whitespace = 1;
- token->pos.pos = 1;
- *line = token;
- token->next = next;
+
+ *line = start;
return 0;
}
@@ -1904,14 +1899,15 @@ static void init_preprocessor(void)
counter_macro = 0;
}
-static void handle_preprocessor_line(struct stream *stream, struct token **line, struct token *start)
+/* return 1 if the entire preprocessor line was consumed, 0 if it needs to be preserved */
+static int handle_preprocessor_line(struct stream *stream, struct token **line, struct token *start)
{
int (*handler)(struct stream *, struct token **, struct token *);
struct token *token = start->next;
- int is_normal = 1;
+ int is_normal = 1, ret;
if (eof_token(token))
- return;
+ return 1;
if (token_type(token) == TOKEN_IDENT) {
struct symbol *sym = lookup_symbol(token->ident, NS_PREPROCESSOR);
@@ -1932,14 +1928,24 @@ static void handle_preprocessor_line(struct stream *stream, struct token **line,
if (false_nesting)
goto out;
}
+
+ ret = 1; /* was the entire line consumed ? */
+
+ /* pragma handler is special */
+ if(handler == handle_pragma) {
+ token = start;
+ ret = 0;
+ }
+
if (!handler(stream, line, token)) /* all set */
- return;
+ return ret;
out:
free_preprocessor_line(token);
+ return 1;
}
-static void preprocessor_line(struct stream *stream, struct token **line)
+static int preprocessor_line(struct stream *stream, struct token **line)
{
struct token *start = *line, *next;
struct token **tp = &start->next;
@@ -1952,7 +1958,7 @@ static void preprocessor_line(struct stream *stream, struct token **line)
}
*line = next;
*tp = &eof_token_entry;
- handle_preprocessor_line(stream, line, start);
+ return handle_preprocessor_line(stream, line, start);
}
static void do_preprocess(struct token **list)
@@ -1964,9 +1970,10 @@ static void do_preprocess(struct token **list)
if (next->pos.newline && match_op(next, '#')) {
if (!next->pos.noexpand) {
- preprocessor_line(stream, list);
- __free_token(next); /* Free the '#' token */
- continue;
+ if(preprocessor_line(stream, list)) {
+ __free_token(next); /* Free the '#' token */
+ continue;
+ }
}
}