From: Neil Booth Date: Fri, 22 Mar 2002 07:23:21 +0000 (+0000) Subject: cpplex.c (parse_identifier_slow): Rename parse_slow, adjust prototype, and handle... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10cf9bdee651940a7c2ce3c34095ef0f98aa2382;p=gcc.git cpplex.c (parse_identifier_slow): Rename parse_slow, adjust prototype, and handle lexing numbers and identifiers. * cpplex.c (parse_identifier_slow): Rename parse_slow, adjust prototype, and handle lexing numbers and identifiers. (parse_identifier): Update to new form of parse_slow. (parse_number): Fast path only, use parse_slow otherwise. (_cpp_lex_direct): Update calls to parse_number. From-SVN: r51161 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9753047c99..58d40e47932 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-03-22 Neil Booth + + * cpplex.c (parse_identifier_slow): Rename parse_slow, adjust + prototype, and handle lexing numbers and identifiers. + (parse_identifier): Update to new form of parse_slow. + (parse_number): Fast path only, use parse_slow otherwise. + (_cpp_lex_direct): Update calls to parse_number. + 2002-03-21 DJ Delorie * bb-reorder.c (make_reorder_chain_1): Protect against diff --git a/gcc/cpplex.c b/gcc/cpplex.c index c1dae50f208..a66c36adebf 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -77,9 +77,9 @@ static int skip_line_comment PARAMS ((cpp_reader *)); static void adjust_column PARAMS ((cpp_reader *)); static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t)); static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *)); -static cpp_hashnode *parse_identifier_slow PARAMS ((cpp_reader *, - const U_CHAR *)); -static void parse_number PARAMS ((cpp_reader *, cpp_string *, cppchar_t, int)); +static U_CHAR *parse_slow PARAMS ((cpp_reader *, const U_CHAR *, int, + unsigned int *)); +static void parse_number PARAMS ((cpp_reader *, cpp_string *, int)); static int unescaped_terminator_p PARAMS ((cpp_reader *, const U_CHAR *)); static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t)); static void unterminated PARAMS ((cpp_reader *, int)); @@ -412,13 +412,13 @@ name_p (pfile, string) seen:unseen identifiers in normal code; the distribution is Poisson-like). Second most common case is a new identifier, not split and no dollar sign. The other possibilities are rare and - have been relegated to parse_identifier_slow. */ + have been relegated to parse_slow. */ static cpp_hashnode * parse_identifier (pfile) cpp_reader *pfile; { cpp_hashnode *result; - const U_CHAR *cur; + const U_CHAR *cur, *base; /* Fast-path loop. Skim over a normal identifier. N.B. ISIDNUM does not include $. */ @@ -428,13 +428,19 @@ parse_identifier (pfile) /* Check for slow-path cases. */ if (*cur == '?' || *cur == '\\' || *cur == '$') - result = parse_identifier_slow (pfile, cur); + { + unsigned int len; + + base = parse_slow (pfile, cur, 0, &len); + result = (cpp_hashnode *) + ht_lookup (pfile->hash_table, base, len, HT_ALLOCED); + } else { - const U_CHAR *base = pfile->buffer->cur - 1; + base = pfile->buffer->cur - 1; + pfile->buffer->cur = cur; result = (cpp_hashnode *) ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC); - pfile->buffer->cur = cur; } /* Rarely, identifiers require diagnostics when lexed. @@ -458,30 +464,55 @@ parse_identifier (pfile) return result; } -/* Slow path. This handles identifiers which have been split, and - identifiers which contain dollar signs. The part of the identifier - from PFILE->buffer->cur-1 to CUR has already been scanned. */ -static cpp_hashnode * -parse_identifier_slow (pfile, cur) +/* Slow path. This handles numbers and identifiers which have been + split, or contain dollar signs. The part of the token from + PFILE->buffer->cur-1 to CUR has already been scanned. NUMBER_P is + 1 if it's a number, and 2 if it has a leading period. Returns a + pointer to the token's NUL-terminated spelling in permanent + storage, and sets PLEN to its length. */ +static U_CHAR * +parse_slow (pfile, cur, number_p, plen) cpp_reader *pfile; const U_CHAR *cur; + int number_p; + unsigned int *plen; { cpp_buffer *buffer = pfile->buffer; const U_CHAR *base = buffer->cur - 1; struct obstack *stack = &pfile->hash_table->stack; - unsigned int c, saw_dollar = 0, len; + unsigned int c, prevc, saw_dollar = 0; + + /* Place any leading period. */ + if (number_p == 2) + obstack_1grow (stack, '.'); /* Copy the part of the token which is known to be okay. */ obstack_grow (stack, base, cur - base); /* Now process the part which isn't. We are looking at one of '$', '\\', or '?' on entry to this loop. */ + prevc = cur[-1]; c = *cur++; buffer->cur = cur; - do + for (;;) { - while (is_idchar (c)) + /* Potential escaped newline? */ + buffer->backup_to = buffer->cur - 1; + if (c == '?' || c == '\\') + c = skip_escaped_newlines (pfile); + + if (!is_idchar (c)) + { + if (!number_p) + break; + if (c != '.' && !VALID_SIGN (c, prevc)) + break; + } + + /* Handle normal identifier characters in this loop. */ + do { + prevc = c; obstack_1grow (stack, c); if (c == '$') @@ -489,14 +520,8 @@ parse_identifier_slow (pfile, cur) c = *buffer->cur++; } - - /* Potential escaped newline? */ - buffer->backup_to = buffer->cur - 1; - if (c != '?' && c != '\\') - break; - c = skip_escaped_newlines (pfile); + while (is_idchar (c)); } - while (is_idchar (c)); /* Step back over the unwanted char. */ BACKUP (); @@ -505,79 +530,49 @@ parse_identifier_slow (pfile, cur) accepted as an extension. Don't warn about it in skipped conditional blocks. */ if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping) - cpp_pedwarn (pfile, "'$' character(s) in identifier"); + cpp_pedwarn (pfile, "'$' character(s) in identifier or number"); - /* Identifiers are null-terminated. */ - len = obstack_object_size (stack); + /* Identifiers and numbers are null-terminated. */ + *plen = obstack_object_size (stack); obstack_1grow (stack, '\0'); - - return (cpp_hashnode *) - ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED); + return obstack_finish (stack); } /* Parse a number, beginning with character C, skipping embedded backslash-newlines. LEADING_PERIOD is non-zero if there was a "." before C. Place the result in NUMBER. */ static void -parse_number (pfile, number, c, leading_period) +parse_number (pfile, number, leading_period) cpp_reader *pfile; cpp_string *number; - cppchar_t c; int leading_period; { - cpp_buffer *buffer = pfile->buffer; - unsigned char *dest, *limit; + const U_CHAR *cur; - dest = BUFF_FRONT (pfile->u_buff); - limit = BUFF_LIMIT (pfile->u_buff); + /* Fast-path loop. Skim over a normal number. + N.B. ISIDNUM does not include $. */ + cur = pfile->buffer->cur; + while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) + cur++; - /* Place a leading period. */ - if (leading_period) - { - if (dest == limit) - { - _cpp_extend_buff (pfile, &pfile->u_buff, 1); - dest = BUFF_FRONT (pfile->u_buff); - limit = BUFF_LIMIT (pfile->u_buff); - } - *dest++ = '.'; - } - - do + /* Check for slow-path cases. */ + if (*cur == '?' || *cur == '\\' || *cur == '$') + number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len); + else { - do - { - /* Need room for terminating null. */ - if ((size_t) (limit - dest) < 2) - { - size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); - _cpp_extend_buff (pfile, &pfile->u_buff, 2); - dest = BUFF_FRONT (pfile->u_buff) + len_so_far; - limit = BUFF_LIMIT (pfile->u_buff); - } - *dest++ = c; + const U_CHAR *base = pfile->buffer->cur - 1; + U_CHAR *dest; - c = *buffer->cur++; - } - while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1])); + number->len = cur - base + leading_period; + dest = _cpp_unaligned_alloc (pfile, number->len + 1); + dest[number->len] = '\0'; + number->text = dest; - /* Potential escaped newline? */ - buffer->backup_to = buffer->cur - 1; - if (c != '?' && c != '\\') - break; - c = skip_escaped_newlines (pfile); + if (leading_period) + *dest++ = '.'; + memcpy (dest, base, cur - base); + pfile->buffer->cur = cur; } - while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1])); - - /* Step back over the unwanted char. */ - BACKUP (); - - /* Null-terminate the number. */ - *dest = '\0'; - - number->text = BUFF_FRONT (pfile->u_buff); - number->len = dest - number->text; - BUFF_FRONT (pfile->u_buff) = dest + 1; } /* Subroutine of parse_string. Emits error for unterminated strings. */ @@ -978,7 +973,7 @@ _cpp_lex_direct (pfile) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result->type = CPP_NUMBER; - parse_number (pfile, &result->val.str, c, 0); + parse_number (pfile, &result->val.str, 0); break; case 'L': @@ -1171,7 +1166,7 @@ _cpp_lex_direct (pfile) else if (ISDIGIT (c)) { result->type = CPP_NUMBER; - parse_number (pfile, &result->val.str, c, 1); + parse_number (pfile, &result->val.str, 1); } else if (c == '*' && CPP_OPTION (pfile, cplusplus)) result->type = CPP_DOT_STAR;