From 0fd10014150c06d46f32e57111d05e33b949e5b5 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Sat, 23 Sep 2000 21:41:41 +0000 Subject: * cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q, CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete. * cpplex.c (_cpp_expand_token_space, _cpp_init_toklist, _cpp_free_toklist): No need to worry about extra dummy token at the start of token lists any more. (trigraph_ok): Only warn outside comments. (skip_block_comment): Set and clear lexing_comment. (skip_line_comment): Take a cpp_reader not cpp_buffer. Set and clear lexing_comment. (parse_number): Handle leading '.' indicated by pfile->seen_dot. (check_long_token): Delete. (lex_percent, lex_dot): New subroutines of lex_token to handle lexing of '.' and '%' without lookback. (lex_token): Use lex_dot and lex_percent. (lex_line): Don't check for LIST_OFFSET. (_cpp_init_input_buffer): Update for new _cpp_init_toklist. * cpplib.c (_cpp_parse_assertion): Similarly. (cpp_push_buffer): Initialize extra_char. * cpplib.h (LIST_OFFSET): Delete. (struct cpp_buffer): New member extra_char. (struct lexer_state): New members lexing_comment and seen_dot. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@36582 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 24 +++++++ gcc/cpphash.h | 20 ------ gcc/cpplex.c | 227 +++++++++++++++++++++++++++++++--------------------------- gcc/cpplib.c | 4 +- gcc/cpplib.h | 14 ++-- 5 files changed, 159 insertions(+), 130 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index efe588a7ad7..6b29754e911 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +Sat 23-Sep-2000 22:39:18 BST Neil Booth + + * cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q, + CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete. + * cpplex.c (_cpp_expand_token_space, _cpp_init_toklist, + _cpp_free_toklist): No need to worry about extra dummy token + at the start of token lists any more. + (trigraph_ok): Only warn outside comments. + (skip_block_comment): Set and clear lexing_comment. + (skip_line_comment): Take a cpp_reader not cpp_buffer. + Set and clear lexing_comment. + (parse_number): Handle leading '.' indicated by pfile->seen_dot. + (check_long_token): Delete. + (lex_percent, lex_dot): New subroutines of lex_token to + handle lexing of '.' and '%' without lookback. + (lex_token): Use lex_dot and lex_percent. + (lex_line): Don't check for LIST_OFFSET. + (_cpp_init_input_buffer): Update for new _cpp_init_toklist. + * cpplib.c (_cpp_parse_assertion): Similarly. + (cpp_push_buffer): Initialize extra_char. + * cpplib.h (LIST_OFFSET): Delete. + (struct cpp_buffer): New member extra_char. + (struct lexer_state): New members lexing_comment and seen_dot. + 2000-09-23 Jason Merrill * config/rs6000/x-aix41 (CLIB): Define here. diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 08d3209d7bc..8f569e7404d 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -183,22 +183,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; /* Macros. */ -/* Make sure PFILE->token_buffer has space for at least N more characters. */ -#define CPP_RESERVE(PFILE, N) \ - (CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \ - && (_cpp_grow_token_buffer (PFILE, N), 0)) - -/* Append string STR (of length N) to PFILE's output buffer. - Assume there is enough space. */ -#define CPP_PUTS_Q(PFILE, STR, N) \ - (memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N)) -/* Append string STR (of length N) to PFILE's output buffer. Make space. */ -#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N) -/* Append character CH to PFILE's output buffer. Assume sufficient space. */ -#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH)) -/* Append character CH to PFILE's output buffer. Make space if need be. */ -#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH)) - #define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev) #define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps) #define CPP_IN_SYSTEM_HEADER(PFILE) \ @@ -213,10 +197,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; parse_name. */ #define HASHSTEP(r, c) ((r) * 67 + (c - 113)); -/* Flags for _cpp_init_toklist. */ -#define DUMMY_TOKEN 0 -#define NO_DUMMY_TOKEN 1 - /* In cpperror.c */ enum error_type { WARNING = 0, PEDWARN, ERROR, FATAL, ICE }; extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type, diff --git a/gcc/cpplex.c b/gcc/cpplex.c index c0bf875aaff..a7a6f99098c 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -103,7 +103,7 @@ static cppchar_t skip_escaped_newlines PARAMS ((cpp_buffer *, cppchar_t)); static cppchar_t get_effective_char PARAMS ((cpp_buffer *)); static int skip_block_comment PARAMS ((cpp_reader *)); -static int skip_line_comment PARAMS ((cpp_buffer *)); +static int skip_line_comment PARAMS ((cpp_reader *)); static void adjust_column PARAMS ((cpp_reader *)); static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t)); static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *, cppchar_t)); @@ -112,11 +112,9 @@ static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t)); static void unterminated PARAMS ((cpp_reader *, unsigned int, int)); static int trigraph_ok PARAMS ((cpp_reader *, cppchar_t)); static void save_comment PARAMS ((cpp_reader *, cpp_token *, const U_CHAR *)); +static void lex_percent PARAMS ((cpp_buffer *, cpp_token *)); +static void lex_dot PARAMS ((cpp_reader *, cpp_token *)); static void lex_line PARAMS ((cpp_reader *, cpp_toklist *)); -static void check_long_token PARAMS ((cpp_buffer *, - cpp_token *, - cppchar_t, - enum cpp_ttype)); static void lex_token PARAMS ((cpp_reader *, cpp_token *)); static int lex_next PARAMS ((cpp_reader *, int)); @@ -453,50 +451,35 @@ _cpp_expand_token_space (list, count) cpp_toklist *list; unsigned int count; { - unsigned int n; - list->tokens_cap += count; - n = list->tokens_cap; - if (list->flags & LIST_OFFSET) - list->tokens--, n++; list->tokens = (cpp_token *) - xrealloc (list->tokens, n * sizeof (cpp_token)); - if (list->flags & LIST_OFFSET) - list->tokens++; /* Skip the dummy. */ + xrealloc (list->tokens, list->tokens_cap * sizeof (cpp_token)); } -/* Initialize a token list. If flags is DUMMY_TOKEN, we allocate - an extra token in front of the token list, as this allows the lexer - to always peek at the previous token without worrying about - underflowing the list, and some initial space. Otherwise, no - token- or name-space is allocated, and there is no dummy token. */ +/* Initialize a token list. If EMPTY is false, some token and name + space is provided. */ void -_cpp_init_toklist (list, flags) +_cpp_init_toklist (list, empty) cpp_toklist *list; - int flags; + int empty; { - if (flags == NO_DUMMY_TOKEN) + if (empty) { list->tokens_cap = 0; list->tokens = 0; list->name_cap = 0; list->namebuf = 0; - list->flags = 0; } else { - /* Initialize token space. Put a dummy token before the start - that will fail matches. */ + /* Initialize token space. */ list->tokens_cap = 256; /* 4K's worth. */ list->tokens = (cpp_token *) xmalloc ((list->tokens_cap + 1) * sizeof (cpp_token)); - list->tokens[0].type = CPP_EOF; - list->tokens++; /* Initialize name space. */ list->name_cap = 1024; list->namebuf = (unsigned char *) xmalloc (list->name_cap); - list->flags = LIST_OFFSET; } _cpp_clear_toklist (list); @@ -512,7 +495,7 @@ _cpp_clear_toklist (list) list->directive = 0; list->paramc = 0; list->params_len = 0; - list->flags &= LIST_OFFSET; /* clear all but that one */ + list->flags = 0; } /* Free a token list. Does not free the list itself, which may be @@ -521,10 +504,7 @@ void _cpp_free_toklist (list) const cpp_toklist *list; { - if (list->flags & LIST_OFFSET) - free (list->tokens - 1); /* Backup over dummy token. */ - else - free (list->tokens); + free (list->tokens); free (list->namebuf); } @@ -633,7 +613,8 @@ trigraph_ok (pfile, from_char) { int accept = CPP_OPTION (pfile, trigraphs); - if (CPP_OPTION (pfile, warn_trigraphs)) + /* Don't warn about trigraphs in comments. */ + if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment) { cpp_buffer *buffer = pfile->buffer; if (accept) @@ -768,6 +749,7 @@ skip_block_comment (pfile) cpp_buffer *buffer = pfile->buffer; cppchar_t c = EOF, prevc; + pfile->state.lexing_comment = 1; while (buffer->cur != buffer->rlimit) { prevc = c, c = *buffer->cur++; @@ -812,6 +794,7 @@ skip_block_comment (pfile) adjust_column (pfile); } + pfile->state.lexing_comment = 0; buffer->read_ahead = EOF; return c != '/' || prevc != '*'; } @@ -820,12 +803,14 @@ skip_block_comment (pfile) non-zero if a multiline comment. The following new line, if any, is left in buffer->read_ahead. */ static int -skip_line_comment (buffer) - cpp_buffer *buffer; +skip_line_comment (pfile) + cpp_reader *pfile; { + cpp_buffer *buffer = pfile->buffer; unsigned int orig_lineno = buffer->lineno; cppchar_t c; + pfile->state.lexing_comment = 1; do { c = EOF; @@ -838,6 +823,7 @@ skip_line_comment (buffer) } while (!is_vspace (c)); + pfile->state.lexing_comment = 0; buffer->read_ahead = c; /* Leave any newline for caller. */ return orig_lineno != buffer->lineno; } @@ -966,11 +952,15 @@ parse_number (pfile, number, c) cpp_buffer *buffer = pfile->buffer; unsigned int orig_used = pfile->token_list.name_used; + /* Reserve space for a leading period. */ + if (pfile->state.seen_dot) + pfile->token_list.name_used++; + do { do { - if (pfile->token_list.name_used == pfile->token_list.name_cap) + if (pfile->token_list.name_used >= pfile->token_list.name_cap) _cpp_expand_name_space (&pfile->token_list, pfile->token_list.name_used + 256); pfile->token_list.namebuf[pfile->token_list.name_used++] = c; @@ -991,6 +981,10 @@ parse_number (pfile, number, c) } while (is_numchar (c) || c == '.' || VALID_SIGN (c, prevc)); + /* Put any leading period in place, now we have the room. */ + if (pfile->state.seen_dot) + pfile->token_list.namebuf[orig_used] = '.'; + /* Remember the next character. */ buffer->read_ahead = c; @@ -1144,27 +1138,99 @@ save_comment (pfile, token, from) memcpy (buffer, from, len - COMMENT_START_LEN); } -/* A helper routine for lex_token. With some long tokens, we need - to read ahead to see if that is the token we have, but back-track - if not. */ +/* Subroutine of lex_token to handle '%'. A little tricky, since we + want to avoid stepping back when lexing %:%X. */ static void -check_long_token (buffer, result, wanted, type) +lex_percent (buffer, result) cpp_buffer *buffer; cpp_token *result; - cppchar_t wanted; - enum cpp_ttype type; { - const unsigned char *saved_cur; - cppchar_t c = buffer->read_ahead; + cppchar_t c; + + result->type = CPP_MOD; + /* Parsing %:%X could leave an extra character. */ + if (buffer->extra_char == EOF) + c = get_effective_char (buffer); + else + { + c = buffer->read_ahead = buffer->extra_char; + buffer->extra_char = EOF; + } + + if (c == '=') + ACCEPT_CHAR (CPP_MOD_EQ); + else if (CPP_OPTION (buffer->pfile, digraphs)) + { + if (c == ':') + { + result->flags |= DIGRAPH; + ACCEPT_CHAR (CPP_HASH); + if (get_effective_char (buffer) == '%') + { + buffer->extra_char = get_effective_char (buffer); + if (buffer->extra_char == ':') + { + buffer->extra_char = EOF; + ACCEPT_CHAR (CPP_PASTE); + } + else + /* We'll catch the extra_char when we're called back. */ + buffer->read_ahead = '%'; + } + } + else if (c == '>') + { + result->flags |= DIGRAPH; + ACCEPT_CHAR (CPP_CLOSE_BRACE); + } + } +} + +/* Subroutine of lex_token to handle '.'. This is tricky, since we + want to avoid stepping back when lexing '...' or '.123'. In the + latter case we should also set a flag for parse_number. */ +static void +lex_dot (pfile, result) + cpp_reader *pfile; + cpp_token *result; +{ + cpp_buffer *buffer = pfile->buffer; + cppchar_t c; + + /* Parsing ..X could leave an extra character. */ + if (buffer->extra_char == EOF) + c = get_effective_char (buffer); + else + { + c = buffer->read_ahead = buffer->extra_char; + buffer->extra_char = EOF; + } - SAVE_STATE (); - if (get_effective_char (buffer) == wanted) - ACCEPT_CHAR (type); + /* All known character sets have 0...9 contiguous. */ + if (c >= '0' && c <= '9') + { + result->type = CPP_NUMBER; + buffer->pfile->state.seen_dot = 1; + parse_number (pfile, &result->val.str, c); + buffer->pfile->state.seen_dot = 0; + } else { - /* Restore state. */ - RESTORE_STATE (); - buffer->read_ahead = c; + result->type = CPP_DOT; + if (c == '.') + { + buffer->extra_char = get_effective_char (buffer); + if (buffer->extra_char == '.') + { + buffer->extra_char = EOF; + ACCEPT_CHAR (CPP_ELLIPSIS); + } + else + /* We'll catch the extra_char when we're called back. */ + buffer->read_ahead = '.'; + } + else if (c == '*' && CPP_OPTION (pfile, cplusplus)) + ACCEPT_CHAR (CPP_DOT_STAR); } } @@ -1245,7 +1311,6 @@ lex_token (pfile, result) } break; - make_number: case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result->type = CPP_NUMBER; @@ -1342,7 +1407,7 @@ lex_token (pfile, result) comment_start = buffer->cur; /* Skip_line_comment updates buffer->read_ahead. */ - if (skip_line_comment (buffer)) + if (skip_line_comment (pfile)) cpp_warning_with_line (pfile, result->line, result->col, "multi-line comment"); @@ -1413,57 +1478,12 @@ lex_token (pfile, result) } break; - case '.': - { - const unsigned char *saved_cur; - cppchar_t c1; - - /* Save state to avoid needing to pass 2 chars to parse_number. */ - SAVE_STATE (); - c1 = get_effective_char (buffer); - /* All known character sets have 0...9 contiguous. */ - if (c1 >= '0' && c1 <= '9') - { - RESTORE_STATE (); - goto make_number; - } - - result->type = CPP_DOT; - if (c1 == '.') - { - if (get_effective_char (buffer) == '.') - ACCEPT_CHAR (CPP_ELLIPSIS); - else - { - buffer->read_ahead = EOF; - RESTORE_STATE (); - } - } - else if (c1 == '*' && CPP_OPTION (pfile, cplusplus)) - ACCEPT_CHAR (CPP_DOT_STAR); - } + case '%': + lex_percent (buffer, result); break; - case '%': - result->type = CPP_MOD; - c = get_effective_char (buffer); - if (c == '=') - ACCEPT_CHAR (CPP_MOD_EQ); - else if (CPP_OPTION (pfile, digraphs)) - { - if (c == ':') - { - result->flags |= DIGRAPH; - ACCEPT_CHAR (CPP_HASH); - if (get_effective_char (buffer) == '%') - check_long_token (buffer, result, ':', CPP_PASTE); - } - else if (c == '>') - { - result->flags |= DIGRAPH; - ACCEPT_CHAR (CPP_CLOSE_BRACE); - } - } + case '.': + lex_dot (pfile, result); break; case '+': @@ -1610,9 +1630,6 @@ lex_line (pfile, list) cpp_token *cur_token, *first; cpp_buffer *buffer = pfile->buffer; - if (!(list->flags & LIST_OFFSET)) - (abort) (); - pfile->state.in_lex_line = 1; if (pfile->buffer->cur == pfile->buffer->buf) list->flags |= BEG_OF_FILE; @@ -3397,7 +3414,7 @@ _cpp_init_input_buffer (pfile) { cpp_context *base; - _cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN); + _cpp_init_toklist (&pfile->token_list, 0); pfile->no_expand_level = UINT_MAX; pfile->context_cap = 20; pfile->cur_context = 0; diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 31064863cac..8c61ab0c222 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -1247,7 +1247,7 @@ _cpp_parse_assertion (pfile, answerp) /* Allocate a struct answer, and copy the answer to it. */ answer = (struct answer *) xmalloc (sizeof (struct answer)); list = &answer->list; - _cpp_init_toklist (list, NO_DUMMY_TOKEN); + _cpp_init_toklist (list, 1); /* Empty. */ for (;;) { @@ -1516,7 +1516,9 @@ cpp_push_buffer (pfile, buffer, length) new->rlimit = buffer + length; new->prev = buf; new->pfile = pfile; + /* No read ahead or extra char initially. */ new->read_ahead = EOF; + new->extra_char = EOF; CPP_BUFFER (pfile) = new; return new; diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 75115375664..15c30abc67d 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -182,9 +182,8 @@ struct cpp_token }; /* cpp_toklist flags. */ -#define LIST_OFFSET (1 << 0) -#define VAR_ARGS (1 << 1) -#define BEG_OF_FILE (1 << 2) +#define VAR_ARGS (1 << 0) +#define BEG_OF_FILE (1 << 1) struct directive; /* These are deliberately incomplete. */ struct answer; @@ -225,6 +224,7 @@ struct cpp_buffer const unsigned char *rlimit; /* end of valid data */ const unsigned char *line_base; /* start of current line */ cppchar_t read_ahead; /* read ahead character */ + cppchar_t extra_char; /* extra read-ahead for long tokens. */ struct cpp_reader *pfile; /* Owns this buffer. */ struct cpp_buffer *prev; @@ -460,8 +460,14 @@ struct lexer_state /* Nonzero to get force the lexer to skip newlines. */ unsigned char skip_newlines; - /* If we're in the subroutine lex_line. */ + /* Nonzero if we're in the subroutine lex_line. */ unsigned char in_lex_line; + + /* Nonzero if we're mid-comment. */ + unsigned char lexing_comment; + + /* Tells parse_number we saw a leading period. */ + unsigned char seen_dot; }; #define IN_DIRECTIVE(pfile) (pfile->state.in_directive) #define KNOWN_DIRECTIVE(list) (list->directive != 0) -- cgit v1.2.3