diff options
author | Neil Booth <neilb@earthling.net> | 2000-11-08 23:08:07 +0000 |
---|---|---|
committer | Neil Booth <neil@gcc.gnu.org> | 2000-11-08 23:08:07 +0000 |
commit | adb84b4254d23c4ff58f53c4f48971b6cd8395d1 (patch) | |
tree | 2829d58899280886dce9cbba61c7c88422fd36e6 /gcc/cpplex.c | |
parent | 09ff8283a84ea06073df34b17baad67126f5b68e (diff) | |
download | gcc-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.c | 43 |
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; |