aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplex.c
diff options
context:
space:
mode:
authorNeil Booth <neilb@earthling.net>2000-11-08 23:08:07 +0000
committerNeil Booth <neil@gcc.gnu.org>2000-11-08 23:08:07 +0000
commitadb84b4254d23c4ff58f53c4f48971b6cd8395d1 (patch)
tree2829d58899280886dce9cbba61c7c88422fd36e6 /gcc/cpplex.c
parent09ff8283a84ea06073df34b17baad67126f5b68e (diff)
downloadgcc-adb84b4254d23c4ff58f53c4f48971b6cd8395d1.zip
gcc-adb84b4254d23c4ff58f53c4f48971b6cd8395d1.tar.gz
gcc-adb84b4254d23c4ff58f53c4f48971b6cd8395d1.tar.bz2
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. From-SVN: r37329
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r--gcc/cpplex.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index eab49ff..fb5eec5 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -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,20 +1162,51 @@ _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;