(yylex): For integers, rename shorts to parts.
Let the number of them be variable. Simplify overflow testing. Don't use long long types unless ll was specified. Don't warn twice. From-SVN: r1463
This commit is contained in:
parent
a57bd38144
commit
4ca827d08d
151
gcc/c-lex.c
151
gcc/c-lex.c
@ -65,6 +65,10 @@ extern int yydebug;
|
||||
/* File used for outputting assembler code. */
|
||||
extern FILE *asm_out_file;
|
||||
|
||||
#ifndef LONG_LONG_TYPE_SIZE
|
||||
#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
|
||||
#endif
|
||||
|
||||
#ifndef WCHAR_TYPE_SIZE
|
||||
#ifdef INT_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
|
||||
@ -1151,16 +1155,18 @@ yylex ()
|
||||
int largest_digit = 0;
|
||||
int numdigits = 0;
|
||||
/* for multi-precision arithmetic,
|
||||
we store only 8 live bits in each short,
|
||||
giving us 64 bits of reliable precision */
|
||||
short shorts[8];
|
||||
we actually store only HOST_BITS_PER_CHAR bits in each part.
|
||||
The number of parts is chosen so as to be sufficient to hold
|
||||
at least as many bits as are in a target `long long' value. */
|
||||
#define TOTAL_PARTS (LONG_LONG_TYPE_SIZE / HOST_BITS_PER_CHAR) + 2
|
||||
int parts[TOTAL_PARTS];
|
||||
int overflow = 0;
|
||||
|
||||
enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
|
||||
= NOT_FLOAT;
|
||||
|
||||
for (count = 0; count < 8; count++)
|
||||
shorts[count] = 0;
|
||||
for (count = 0; count < TOTAL_PARTS; count++)
|
||||
parts[count] = 0;
|
||||
|
||||
p = token_buffer;
|
||||
*p++ = c;
|
||||
@ -1259,20 +1265,24 @@ yylex ()
|
||||
largest_digit = c;
|
||||
numdigits++;
|
||||
|
||||
for (count = 0; count < 8; count++)
|
||||
for (count = 0; count < TOTAL_PARTS; count++)
|
||||
{
|
||||
shorts[count] *= base;
|
||||
parts[count] *= base;
|
||||
if (count)
|
||||
{
|
||||
shorts[count] += (shorts[count-1] >> 8);
|
||||
shorts[count-1] &= (1<<8)-1;
|
||||
parts[count]
|
||||
+= (parts[count-1] >> HOST_BITS_PER_CHAR);
|
||||
parts[count-1]
|
||||
&= (1 << HOST_BITS_PER_CHAR) - 1;
|
||||
}
|
||||
else shorts[0] += c;
|
||||
else
|
||||
parts[0] += c;
|
||||
}
|
||||
|
||||
if (shorts[7] >= 1<<8
|
||||
|| shorts[7] < - (1 << 8))
|
||||
overflow = TRUE;
|
||||
/* If the extra highest-order part ever gets anything in it,
|
||||
the number is certainly too big. */
|
||||
if (parts[TOTAL_PARTS - 1] != 0)
|
||||
overflow = 1;
|
||||
|
||||
if (p >= token_buffer + maxtoken - 3)
|
||||
p = extend_token_buffer (p);
|
||||
@ -1477,32 +1487,12 @@ yylex ()
|
||||
else
|
||||
bytes = TYPE_PRECISION (long_integer_type_node) / 8;
|
||||
|
||||
if (bytes <= 8)
|
||||
{
|
||||
warn = overflow;
|
||||
for (i = bytes; i < 8; i++)
|
||||
if (shorts[i])
|
||||
{
|
||||
/* If LL was not used, then clear any excess precision.
|
||||
This is equivalent to the original code, but it is
|
||||
not clear why this is being done. Perhaps to prevent
|
||||
ANSI programs from creating long long constants
|
||||
by accident? */
|
||||
if (! spec_long_long)
|
||||
shorts[i] = 0;
|
||||
warn = 1;
|
||||
}
|
||||
if (warn)
|
||||
pedwarn ("integer constant out of range");
|
||||
}
|
||||
else if (overflow)
|
||||
pedwarn ("integer constant larger than compiler can handle");
|
||||
|
||||
/* If it overflowed our internal buffer, then make it unsigned.
|
||||
We can't distinguish based on the tree node because
|
||||
any integer constant fits any long long type. */
|
||||
if (overflow)
|
||||
spec_unsigned = 1;
|
||||
warn = overflow;
|
||||
for (i = bytes; i < TOTAL_PARTS; i++)
|
||||
if (parts[i])
|
||||
warn = 1;
|
||||
if (warn)
|
||||
pedwarn ("integer constant out of range");
|
||||
|
||||
/* This is simplified by the fact that our constant
|
||||
is always positive. */
|
||||
@ -1510,74 +1500,11 @@ yylex ()
|
||||
needed, but they get around bugs in some C compilers. */
|
||||
yylval.ttype
|
||||
= (build_int_2
|
||||
((((long)shorts[3]<<24) + ((long)shorts[2]<<16)
|
||||
+ ((long)shorts[1]<<8) + (long)shorts[0]),
|
||||
(((long)shorts[7]<<24) + ((long)shorts[6]<<16)
|
||||
+ ((long)shorts[5]<<8) + (long)shorts[4])));
|
||||
((((long)parts[3]<<24) + ((long)parts[2]<<16)
|
||||
+ ((long)parts[1]<<8) + (long)parts[0]),
|
||||
(((long)parts[7]<<24) + ((long)parts[6]<<16)
|
||||
+ ((long)parts[5]<<8) + (long)parts[4])));
|
||||
|
||||
#if 0
|
||||
/* Find the first allowable type that the value fits in. */
|
||||
type = 0;
|
||||
for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
|
||||
i++)
|
||||
if (!(spec_long && !type_sequence[i].long_flag)
|
||||
&& !(spec_long_long && !type_sequence[i].long_long_flag)
|
||||
&& !(spec_unsigned && !type_sequence[i].unsigned_flag)
|
||||
/* A decimal constant can't be unsigned int
|
||||
unless explicitly specified. */
|
||||
&& !(base == 10 && !spec_unsigned
|
||||
&& *type_sequence[i].node_var == unsigned_type_node))
|
||||
if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
|
||||
{
|
||||
type = *type_sequence[i].node_var;
|
||||
break;
|
||||
}
|
||||
if (flag_traditional && type == long_unsigned_type_node
|
||||
&& !spec_unsigned)
|
||||
type = long_integer_type_node;
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
type = long_long_integer_type_node;
|
||||
warning ("integer constant out of range");
|
||||
}
|
||||
|
||||
/* Warn about some cases where the type of a given constant
|
||||
changes from traditional C to ANSI C. */
|
||||
if (warn_traditional)
|
||||
{
|
||||
tree other_type = 0;
|
||||
|
||||
/* This computation is the same as the previous one
|
||||
except that flag_traditional is used backwards. */
|
||||
for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
|
||||
i++)
|
||||
if (!(spec_long && !type_sequence[i].long_flag)
|
||||
&& !(spec_long_long && !type_sequence[i].long_long_flag)
|
||||
&& !(spec_unsigned && !type_sequence[i].unsigned_flag)
|
||||
/* A decimal constant can't be unsigned int
|
||||
unless explicitly specified. */
|
||||
&& !(base == 10 && !spec_unsigned
|
||||
&& *type_sequence[i].node_var == unsigned_type_node))
|
||||
if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
|
||||
{
|
||||
other_type = *type_sequence[i].node_var;
|
||||
break;
|
||||
}
|
||||
if (!flag_traditional && type == long_unsigned_type_node
|
||||
&& !spec_unsigned)
|
||||
type = long_integer_type_node;
|
||||
|
||||
if (other_type != 0 && other_type != type)
|
||||
{
|
||||
if (flag_traditional)
|
||||
warning ("type of integer constant would be different without -traditional");
|
||||
else
|
||||
warning ("type of integer constant would be different with -traditional");
|
||||
}
|
||||
}
|
||||
|
||||
#else /* 1 */
|
||||
/* If warn_traditional, calculate both the ANSI type and the
|
||||
traditional type, then see if they disagree.
|
||||
Otherwise, calculate only the type for the dialect in use. */
|
||||
@ -1600,9 +1527,7 @@ yylex ()
|
||||
&& int_fits_type_p (yylval.ttype, integer_type_node))
|
||||
traditional_type = (spec_unsigned ? unsigned_type_node
|
||||
: integer_type_node);
|
||||
else if (! spec_long_long
|
||||
&& int_fits_type_p (yylval.ttype,
|
||||
long_unsigned_type_node))
|
||||
else if (! spec_long_long)
|
||||
traditional_type = (spec_unsigned ? long_unsigned_type_node
|
||||
: long_integer_type_node);
|
||||
else
|
||||
@ -1622,9 +1547,7 @@ yylex ()
|
||||
else if (! spec_unsigned && !spec_long_long
|
||||
&& int_fits_type_p (yylval.ttype, long_integer_type_node))
|
||||
ansi_type = long_integer_type_node;
|
||||
else if (! spec_long_long
|
||||
&& int_fits_type_p (yylval.ttype,
|
||||
long_unsigned_type_node))
|
||||
else if (! spec_long_long)
|
||||
ansi_type = long_unsigned_type_node;
|
||||
else if (! spec_unsigned
|
||||
&& int_fits_type_p (yylval.ttype,
|
||||
@ -1647,9 +1570,9 @@ yylex ()
|
||||
else
|
||||
warning ("width of integer constant may change on other systems with -traditional");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!flag_traditional && !int_fits_type_p (yylval.ttype, type))
|
||||
if (!flag_traditional && !int_fits_type_p (yylval.ttype, type)
|
||||
&& !warn)
|
||||
pedwarn ("integer constant out of range");
|
||||
|
||||
TREE_TYPE (yylval.ttype) = type;
|
||||
|
Loading…
Reference in New Issue
Block a user