This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: Move directive handling to the lexer.
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: cpplib: Move directive handling to the lexer.
- From: Neil Booth <NeilB at earthling dot net>
- Date: Thu, 9 Nov 2000 00:39:30 +0100 (CET)
This a minor performance enhancement, as well as a logical tidy up.
Now we've moved to token at a time, it's simpler to catch a
directive's '#' (at the beginning of a line) in the lexer itself.
This saves testing for it in the get_token loop that every token
passes through; since we can only get a directive's '#' from the lexer
and not from a macro.
Bootstrapped x86 linux and passed CPP testsuite. Running main
testsuite, but with no obvious problems so far.
Neil.
Move directive handling into the lexer itself.
* cpplex.c (_cpp_lex_token): Handle directives directly.
In the case of a directive interrupting a function-like
macro invocation, use extra_char since read_ahead is
used to store the '#'. Return a CPP_EOF in this case.
* cppmacro.c (parse_arg): No need to handle CPP_DHASH any more.
(cpp_get_token): Don't handle directives here.
* cpplib.h: Remove CPP_DHASH token type.
Index: gcc/cpplex.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplex.c,v
retrieving revision 1.113
diff -u -p -r1.113 cpplex.c
--- cpplex.c 2000/11/06 18:47:21 1.113
+++ cpplex.c 2000/11/08 22:53:34
@@ -844,11 +844,13 @@ _cpp_lex_token (pfile, result)
cpp_token *result;
{
cppchar_t c;
- cpp_buffer *buffer = pfile->buffer;
+ cpp_buffer *buffer;
const unsigned char *comment_start;
unsigned char was_skip_newlines = pfile->state.skip_newlines;
unsigned char newline_in_args = 0;
+ done_directive:
+ buffer = pfile->buffer;
pfile->state.skip_newlines = 0;
result->flags = 0;
next_char:
@@ -1160,19 +1162,50 @@ _cpp_lex_token (pfile, result)
break;
case '#':
- if (get_effective_char (buffer) == '#')
+ c = buffer->extra_char; /* Can be set by error condition below. */
+ if (c != EOF)
+ {
+ buffer->read_ahead = c;
+ buffer->extra_char = EOF;
+ }
+ else
+ c = get_effective_char (buffer);
+
+ if (c == '#')
ACCEPT_CHAR (CPP_PASTE);
else
{
result->type = CPP_HASH;
do_hash:
- /* CPP_DHASH is the hash introducing a directive. */
- if (was_skip_newlines || newline_in_args)
+ if (newline_in_args)
{
- result->type = CPP_DHASH;
+ /* 6.10.3 paragraph 11: If there are sequences of
+ preprocessing tokens within the list of arguments that
+ would otherwise act as preprocessing directives, the
+ behavior is undefined.
+
+ This implementation will report a hard error, terminate
+ the macro invocation, and proceed to process the
+ directive. */
+ cpp_error (pfile,
+ "directives may not be used inside a macro argument");
+
+ /* Put a '#' in lookahead, return CPP_EOF for parse_arg. */
+ buffer->extra_char = buffer->read_ahead;
+ buffer->read_ahead = '#';
+ pfile->state.skip_newlines = 1;
+ result->type = CPP_EOF;
+
/* Get whitespace right - newline_in_args sets it. */
if (pfile->lexer_pos.col == 1)
result->flags &= ~PREV_WHITE;
+ }
+ else if (was_skip_newlines)
+ {
+ /* This is the hash introducing a directive. */
+ if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
+ goto done_directive; /* was_skip_newlines still 1. */
+ /* This is in fact an assembler #. */
}
}
break;
Index: gcc/cpplib.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplib.h,v
retrieving revision 1.131
diff -u -p -r1.131 cpplib.h
--- cpplib.h 2000/11/06 18:43:31 1.131
+++ cpplib.h 2000/11/08 22:53:39
@@ -139,7 +139,6 @@ struct htab;
TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \
\
TK(CPP_COMMENT, SPELL_STRING) /* Only if output comments. */ \
- TK(CPP_DHASH, SPELL_NONE) /* The # of a directive. */ \
TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
TK(CPP_PLACEMARKER, SPELL_NONE) /* Placemarker token. */ \
OP(CPP_EOF, "EOL") /* End of line or file. */
Index: gcc/cppmacro.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cppmacro.c,v
retrieving revision 1.19
diff -u -p -r1.19 cppmacro.c
--- cppmacro.c 2000/11/06 18:43:31 1.19
+++ cppmacro.c 2000/11/08 22:53:53
@@ -534,21 +534,6 @@ parse_arg (pfile, arg, var_args)
break;
else if (result == CPP_EOF)
break; /* Error reported by caller. */
- else if (result == CPP_DHASH)
- {
- /* 6.10.3 paragraph 11: If there are sequences of
- preprocessing tokens within the list of arguments that
- would otherwise act as preprocessing directives, the
- behavior is undefined.
-
- This implementation will report a hard error, terminate
- the macro invocation, and proceed to process the
- directive. */
- cpp_error (pfile, "directives may not be used inside a macro argument");
- _cpp_push_token (pfile, token, &pfile->lexer_pos);
- result = CPP_EOF;
- break;
- }
}
/* Empty arguments become a single placemarker token. */
@@ -1018,16 +1003,6 @@ cpp_get_token (pfile, token)
|| pfile->state.in_directive || pfile->state.parsing_args)
break;
continue;
- }
- else if (token->type == CPP_DHASH)
- {
- /* Handle directives. */
- if (_cpp_handle_directive (pfile, token->flags & PREV_WHITE))
- continue;
- /* This is in fact an assembler #. */
- if (pfile->skipping)
- continue;
- token->type = CPP_HASH;
}
/* We are not merging the PREV_WHITE of CPP_PLACEMARKERS. I
don't think it really matters. */