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
This commit is contained in:
parent
fbc2782eff
commit
10cf9bdee6
2 changed files with 85 additions and 82 deletions
|
@ -1,3 +1,11 @@
|
|||
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>
|
||||
|
||||
* bb-reorder.c (make_reorder_chain_1): Protect against
|
||||
|
|
159
gcc/cpplex.c
159
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)
|
||||
/* Check for slow-path cases. */
|
||||
if (*cur == '?' || *cur == '\\' || *cur == '$')
|
||||
number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
|
||||
else
|
||||
{
|
||||
if (dest == limit)
|
||||
{
|
||||
_cpp_extend_buff (pfile, &pfile->u_buff, 1);
|
||||
dest = BUFF_FRONT (pfile->u_buff);
|
||||
limit = BUFF_LIMIT (pfile->u_buff);
|
||||
}
|
||||
*dest++ = '.';
|
||||
const U_CHAR *base = pfile->buffer->cur - 1;
|
||||
U_CHAR *dest;
|
||||
|
||||
number->len = cur - base + leading_period;
|
||||
dest = _cpp_unaligned_alloc (pfile, number->len + 1);
|
||||
dest[number->len] = '\0';
|
||||
number->text = dest;
|
||||
|
||||
if (leading_period)
|
||||
*dest++ = '.';
|
||||
memcpy (dest, base, cur - base);
|
||||
pfile->buffer->cur = cur;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
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;
|
||||
|
||||
c = *buffer->cur++;
|
||||
}
|
||||
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
|
||||
|
||||
/* Potential escaped newline? */
|
||||
buffer->backup_to = buffer->cur - 1;
|
||||
if (c != '?' && c != '\\')
|
||||
break;
|
||||
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. */
|
||||
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue