Commit 10cf9bde by Neil Booth Committed by Neil Booth

cpplex.c (parse_identifier_slow): Rename parse_slow, adjust prototype, and…

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
parent fbc2782e
2002-03-22 Neil Booth <neil@daikokuya.demon.co.uk>
* 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 <dj@redhat.com> 2002-03-21 DJ Delorie <dj@redhat.com>
* bb-reorder.c (make_reorder_chain_1): Protect against * bb-reorder.c (make_reorder_chain_1): Protect against
......
...@@ -77,9 +77,9 @@ static int skip_line_comment PARAMS ((cpp_reader *)); ...@@ -77,9 +77,9 @@ static int skip_line_comment PARAMS ((cpp_reader *));
static void adjust_column PARAMS ((cpp_reader *)); static void adjust_column PARAMS ((cpp_reader *));
static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t)); static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *)); static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
static cpp_hashnode *parse_identifier_slow PARAMS ((cpp_reader *, static U_CHAR *parse_slow PARAMS ((cpp_reader *, const U_CHAR *, int,
const U_CHAR *)); unsigned int *));
static void parse_number PARAMS ((cpp_reader *, cpp_string *, cppchar_t, int)); static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
static int unescaped_terminator_p PARAMS ((cpp_reader *, const U_CHAR *)); static int unescaped_terminator_p PARAMS ((cpp_reader *, const U_CHAR *));
static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t)); static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
static void unterminated PARAMS ((cpp_reader *, int)); static void unterminated PARAMS ((cpp_reader *, int));
...@@ -412,13 +412,13 @@ name_p (pfile, string) ...@@ -412,13 +412,13 @@ name_p (pfile, string)
seen:unseen identifiers in normal code; the distribution is seen:unseen identifiers in normal code; the distribution is
Poisson-like). Second most common case is a new identifier, not Poisson-like). Second most common case is a new identifier, not
split and no dollar sign. The other possibilities are rare and 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 * static cpp_hashnode *
parse_identifier (pfile) parse_identifier (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_hashnode *result; cpp_hashnode *result;
const U_CHAR *cur; const U_CHAR *cur, *base;
/* Fast-path loop. Skim over a normal identifier. /* Fast-path loop. Skim over a normal identifier.
N.B. ISIDNUM does not include $. */ N.B. ISIDNUM does not include $. */
...@@ -428,13 +428,19 @@ parse_identifier (pfile) ...@@ -428,13 +428,19 @@ parse_identifier (pfile)
/* Check for slow-path cases. */ /* Check for slow-path cases. */
if (*cur == '?' || *cur == '\\' || *cur == '$') 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 else
{ {
const U_CHAR *base = pfile->buffer->cur - 1; base = pfile->buffer->cur - 1;
pfile->buffer->cur = cur;
result = (cpp_hashnode *) result = (cpp_hashnode *)
ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC); ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
pfile->buffer->cur = cur;
} }
/* Rarely, identifiers require diagnostics when lexed. /* Rarely, identifiers require diagnostics when lexed.
...@@ -458,30 +464,55 @@ parse_identifier (pfile) ...@@ -458,30 +464,55 @@ parse_identifier (pfile)
return result; return result;
} }
/* Slow path. This handles identifiers which have been split, and /* Slow path. This handles numbers and identifiers which have been
identifiers which contain dollar signs. The part of the identifier split, or contain dollar signs. The part of the token from
from PFILE->buffer->cur-1 to CUR has already been scanned. */ PFILE->buffer->cur-1 to CUR has already been scanned. NUMBER_P is
static cpp_hashnode * 1 if it's a number, and 2 if it has a leading period. Returns a
parse_identifier_slow (pfile, cur) 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; cpp_reader *pfile;
const U_CHAR *cur; const U_CHAR *cur;
int number_p;
unsigned int *plen;
{ {
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
const U_CHAR *base = buffer->cur - 1; const U_CHAR *base = buffer->cur - 1;
struct obstack *stack = &pfile->hash_table->stack; 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. */ /* Copy the part of the token which is known to be okay. */
obstack_grow (stack, base, cur - base); obstack_grow (stack, base, cur - base);
/* Now process the part which isn't. We are looking at one of /* Now process the part which isn't. We are looking at one of
'$', '\\', or '?' on entry to this loop. */ '$', '\\', or '?' on entry to this loop. */
prevc = cur[-1];
c = *cur++; c = *cur++;
buffer->cur = 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); obstack_1grow (stack, c);
if (c == '$') if (c == '$')
...@@ -489,14 +520,8 @@ parse_identifier_slow (pfile, cur) ...@@ -489,14 +520,8 @@ parse_identifier_slow (pfile, cur)
c = *buffer->cur++; c = *buffer->cur++;
} }
while (is_idchar (c));
/* Potential escaped newline? */
buffer->backup_to = buffer->cur - 1;
if (c != '?' && c != '\\')
break;
c = skip_escaped_newlines (pfile);
} }
while (is_idchar (c));
/* Step back over the unwanted char. */ /* Step back over the unwanted char. */
BACKUP (); BACKUP ();
...@@ -505,79 +530,49 @@ parse_identifier_slow (pfile, cur) ...@@ -505,79 +530,49 @@ parse_identifier_slow (pfile, cur)
accepted as an extension. Don't warn about it in skipped accepted as an extension. Don't warn about it in skipped
conditional blocks. */ conditional blocks. */
if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping) 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. */ /* Identifiers and numbers are null-terminated. */
len = obstack_object_size (stack); *plen = obstack_object_size (stack);
obstack_1grow (stack, '\0'); obstack_1grow (stack, '\0');
return obstack_finish (stack);
return (cpp_hashnode *)
ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED);
} }
/* Parse a number, beginning with character C, skipping embedded /* Parse a number, beginning with character C, skipping embedded
backslash-newlines. LEADING_PERIOD is non-zero if there was a "." backslash-newlines. LEADING_PERIOD is non-zero if there was a "."
before C. Place the result in NUMBER. */ before C. Place the result in NUMBER. */
static void static void
parse_number (pfile, number, c, leading_period) parse_number (pfile, number, leading_period)
cpp_reader *pfile; cpp_reader *pfile;
cpp_string *number; cpp_string *number;
cppchar_t c;
int leading_period; int leading_period;
{ {
cpp_buffer *buffer = pfile->buffer; const U_CHAR *cur;
unsigned char *dest, *limit;
dest = BUFF_FRONT (pfile->u_buff); /* Fast-path loop. Skim over a normal number.
limit = BUFF_LIMIT (pfile->u_buff); N.B. ISIDNUM does not include $. */
cur = pfile->buffer->cur;
while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
cur++;
/* Place a leading period. */ /* Check for slow-path cases. */
if (leading_period) if (*cur == '?' || *cur == '\\' || *cur == '$')
{ number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
if (dest == limit) else
{
_cpp_extend_buff (pfile, &pfile->u_buff, 1);
dest = BUFF_FRONT (pfile->u_buff);
limit = BUFF_LIMIT (pfile->u_buff);
}
*dest++ = '.';
}
do
{ {
do const U_CHAR *base = pfile->buffer->cur - 1;
{ U_CHAR *dest;
/* 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;
c = *buffer->cur++; number->len = cur - base + leading_period;
} dest = _cpp_unaligned_alloc (pfile, number->len + 1);
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1])); dest[number->len] = '\0';
number->text = dest;
/* Potential escaped newline? */ if (leading_period)
buffer->backup_to = buffer->cur - 1; *dest++ = '.';
if (c != '?' && c != '\\') memcpy (dest, base, cur - base);
break; pfile->buffer->cur = cur;
c = skip_escaped_newlines (pfile);
} }
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. */ /* Subroutine of parse_string. Emits error for unterminated strings. */
...@@ -978,7 +973,7 @@ _cpp_lex_direct (pfile) ...@@ -978,7 +973,7 @@ _cpp_lex_direct (pfile)
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
result->type = CPP_NUMBER; result->type = CPP_NUMBER;
parse_number (pfile, &result->val.str, c, 0); parse_number (pfile, &result->val.str, 0);
break; break;
case 'L': case 'L':
...@@ -1171,7 +1166,7 @@ _cpp_lex_direct (pfile) ...@@ -1171,7 +1166,7 @@ _cpp_lex_direct (pfile)
else if (ISDIGIT (c)) else if (ISDIGIT (c))
{ {
result->type = CPP_NUMBER; 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)) else if (c == '*' && CPP_OPTION (pfile, cplusplus))
result->type = CPP_DOT_STAR; result->type = CPP_DOT_STAR;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment