Commit 78ae7d80 by Paul Eggert

(HOST_WIDE_INT_MASK): Renamed from LONG_MASK; use HOST_WIDE_INT.

(HOST_WIDE_INT, HOST_BITS_PER_WIDE_INT): New (actually resuscitated) macros.
(parse_c_expression, expression_value, parse_escape, left_shift, right_shift,
struct constant, exp, parse_number, yylex): Replace `long' with
`HOST_WIDE_INT'.

From-SVN: r11061
parent 047380ca
...@@ -82,12 +82,30 @@ struct arglist { ...@@ -82,12 +82,30 @@ struct arglist {
#endif #endif
#endif #endif
#define LONG_MASK(bits) ((bits) < HOST_BITS_PER_LONG ? ~(~0L << (bits)) : ~0L)
#ifndef NULL_PTR #ifndef NULL_PTR
#define NULL_PTR ((GENERIC_PTR)0) #define NULL_PTR ((GENERIC_PTR)0)
#endif #endif
/* Find the largest host integer type and set its size and type.
Don't blindly use `long'; on some crazy hosts it is shorter than `int'. */
#ifndef HOST_BITS_PER_WIDE_INT
#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
#define HOST_WIDE_INT long
#else
#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
#define HOST_WIDE_INT int
#endif
#endif
#define HOST_WIDE_INT_MASK(bits) \
((bits) < HOST_BITS_PER_WIDE_INT \
? ~ (~ (HOST_WIDE_INT) 0 << (bits)) \
: ~ (HOST_WIDE_INT) 0)
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
# define __attribute__(x) # define __attribute__(x)
#endif #endif
...@@ -124,11 +142,11 @@ struct arglist { ...@@ -124,11 +142,11 @@ struct arglist {
#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2) #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
long parse_c_expression PROTO((char *)); HOST_WIDE_INT parse_c_expression PROTO((char *));
static int yylex PROTO((void)); static int yylex PROTO((void));
static void yyerror PROTO((char *)) __attribute__ ((noreturn)); static void yyerror PROTO((char *)) __attribute__ ((noreturn));
static long expression_value; static HOST_WIDE_INT expression_value;
static jmp_buf parse_return_error; static jmp_buf parse_return_error;
...@@ -193,7 +211,7 @@ extern int traditional; ...@@ -193,7 +211,7 @@ extern int traditional;
struct constant; struct constant;
GENERIC_PTR xmalloc PROTO((size_t)); GENERIC_PTR xmalloc PROTO((size_t));
long parse_escape PROTO((char **, long)); HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
int check_assertion PROTO((U_CHAR *, int, int, struct arglist *)); int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
struct hashnode *lookup PROTO((U_CHAR *, int, int)); struct hashnode *lookup PROTO((U_CHAR *, int, int));
void error PRINTF_PROTO_1((char *, ...)); void error PRINTF_PROTO_1((char *, ...));
...@@ -201,8 +219,8 @@ void pedwarn PRINTF_PROTO_1((char *, ...)); ...@@ -201,8 +219,8 @@ void pedwarn PRINTF_PROTO_1((char *, ...));
void warning PRINTF_PROTO_1((char *, ...)); void warning PRINTF_PROTO_1((char *, ...));
static int parse_number PROTO((int)); static int parse_number PROTO((int));
static long left_shift PROTO((struct constant *, unsigned long)); static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
static long right_shift PROTO((struct constant *, unsigned long)); static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
static void integer_overflow PROTO((void)); static void integer_overflow PROTO((void));
/* `signedp' values */ /* `signedp' values */
...@@ -211,7 +229,7 @@ static void integer_overflow PROTO((void)); ...@@ -211,7 +229,7 @@ static void integer_overflow PROTO((void));
%} %}
%union { %union {
struct constant {long value; int signedp;} integer; struct constant {HOST_WIDE_INT value; int signedp;} integer;
struct name {U_CHAR *address; int length;} name; struct name {U_CHAR *address; int length;} name;
struct arglist *keywords; struct arglist *keywords;
} }
...@@ -293,7 +311,8 @@ exp : exp '*' exp ...@@ -293,7 +311,8 @@ exp : exp '*' exp
integer_overflow (); integer_overflow ();
} }
else else
$$.value = (unsigned long) $1.value * $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
* $3.value); }
| exp '/' exp | exp '/' exp
{ if ($3.value == 0) { if ($3.value == 0)
{ {
...@@ -309,7 +328,8 @@ exp : exp '*' exp ...@@ -309,7 +328,8 @@ exp : exp '*' exp
integer_overflow (); integer_overflow ();
} }
else else
$$.value = (unsigned long) $1.value / $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
/ $3.value); }
| exp '%' exp | exp '%' exp
{ if ($3.value == 0) { if ($3.value == 0)
{ {
...@@ -321,7 +341,8 @@ exp : exp '*' exp ...@@ -321,7 +341,8 @@ exp : exp '*' exp
if ($$.signedp) if ($$.signedp)
$$.value = $1.value % $3.value; $$.value = $1.value % $3.value;
else else
$$.value = (unsigned long) $1.value % $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
% $3.value); }
| exp '+' exp | exp '+' exp
{ $$.value = $1.value + $3.value; { $$.value = $1.value + $3.value;
$$.signedp = $1.signedp & $3.signedp; $$.signedp = $1.signedp & $3.signedp;
...@@ -357,25 +378,29 @@ exp : exp '*' exp ...@@ -357,25 +378,29 @@ exp : exp '*' exp
if ($1.signedp & $3.signedp) if ($1.signedp & $3.signedp)
$$.value = $1.value <= $3.value; $$.value = $1.value <= $3.value;
else else
$$.value = (unsigned long) $1.value <= $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
<= $3.value); }
| exp GEQ exp | exp GEQ exp
{ $$.signedp = SIGNED; { $$.signedp = SIGNED;
if ($1.signedp & $3.signedp) if ($1.signedp & $3.signedp)
$$.value = $1.value >= $3.value; $$.value = $1.value >= $3.value;
else else
$$.value = (unsigned long) $1.value >= $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
>= $3.value); }
| exp '<' exp | exp '<' exp
{ $$.signedp = SIGNED; { $$.signedp = SIGNED;
if ($1.signedp & $3.signedp) if ($1.signedp & $3.signedp)
$$.value = $1.value < $3.value; $$.value = $1.value < $3.value;
else else
$$.value = (unsigned long) $1.value < $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
< $3.value); }
| exp '>' exp | exp '>' exp
{ $$.signedp = SIGNED; { $$.signedp = SIGNED;
if ($1.signedp & $3.signedp) if ($1.signedp & $3.signedp)
$$.value = $1.value > $3.value; $$.value = $1.value > $3.value;
else else
$$.value = (unsigned long) $1.value > $3.value; } $$.value = ((unsigned HOST_WIDE_INT) $1.value
> $3.value); }
| exp '&' exp | exp '&' exp
{ $$.value = $1.value & $3.value; { $$.value = $1.value & $3.value;
$$.signedp = $1.signedp & $3.signedp; } $$.signedp = $1.signedp & $3.signedp; }
...@@ -454,7 +479,7 @@ parse_number (olen) ...@@ -454,7 +479,7 @@ parse_number (olen)
{ {
register char *p = lexptr; register char *p = lexptr;
register int c; register int c;
register unsigned long n = 0, nd, ULONG_MAX_over_base; register unsigned HOST_WIDE_INT n = 0, nd, max_over_base;
register int base = 10; register int base = 10;
register int len = olen; register int len = olen;
register int overflow = 0; register int overflow = 0;
...@@ -472,7 +497,7 @@ parse_number (olen) ...@@ -472,7 +497,7 @@ parse_number (olen)
} }
} }
ULONG_MAX_over_base = (unsigned long) -1 / base; max_over_base = (unsigned HOST_WIDE_INT) -1 / base;
for (; len > 0; len--) { for (; len > 0; len--) {
c = *p++; c = *p++;
...@@ -519,7 +544,7 @@ parse_number (olen) ...@@ -519,7 +544,7 @@ parse_number (olen)
if (largest_digit < digit) if (largest_digit < digit)
largest_digit = digit; largest_digit = digit;
nd = n * base + digit; nd = n * base + digit;
overflow |= (ULONG_MAX_over_base < n) | (nd < n); overflow |= (max_over_base < n) | (nd < n);
n = nd; n = nd;
} }
...@@ -530,7 +555,7 @@ parse_number (olen) ...@@ -530,7 +555,7 @@ parse_number (olen)
warning ("integer constant out of range"); warning ("integer constant out of range");
/* If too big to be signed, consider it unsigned. */ /* If too big to be signed, consider it unsigned. */
if (((long) n & yylval.integer.signedp) < 0) if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
{ {
if (base == 10) if (base == 10)
warning ("integer constant is so large that it is unsigned"); warning ("integer constant is so large that it is unsigned");
...@@ -571,7 +596,7 @@ yylex () ...@@ -571,7 +596,7 @@ yylex ()
register unsigned char *tokstart; register unsigned char *tokstart;
register struct token *toktab; register struct token *toktab;
int wide_flag; int wide_flag;
long mask; HOST_WIDE_INT mask;
retry: retry:
...@@ -607,21 +632,21 @@ yylex () ...@@ -607,21 +632,21 @@ yylex ()
{ {
lexptr++; lexptr++;
wide_flag = 1; wide_flag = 1;
mask = LONG_MASK (MAX_WCHAR_TYPE_SIZE); mask = HOST_WIDE_INT_MASK (MAX_WCHAR_TYPE_SIZE);
goto char_constant; goto char_constant;
} }
if (lexptr[1] == '"') if (lexptr[1] == '"')
{ {
lexptr++; lexptr++;
wide_flag = 1; wide_flag = 1;
mask = LONG_MASK (MAX_WCHAR_TYPE_SIZE); mask = HOST_WIDE_INT_MASK (MAX_WCHAR_TYPE_SIZE);
goto string_constant; goto string_constant;
} }
break; break;
case '\'': case '\'':
wide_flag = 0; wide_flag = 0;
mask = LONG_MASK (MAX_CHAR_TYPE_SIZE); mask = HOST_WIDE_INT_MASK (MAX_CHAR_TYPE_SIZE);
char_constant: char_constant:
lexptr++; lexptr++;
if (keyword_parsing) { if (keyword_parsing) {
...@@ -642,7 +667,7 @@ yylex () ...@@ -642,7 +667,7 @@ yylex ()
handles multicharacter constants and wide characters. handles multicharacter constants and wide characters.
It is mostly copied from c-lex.c. */ It is mostly copied from c-lex.c. */
{ {
register long result = 0; register HOST_WIDE_INT result = 0;
register num_chars = 0; register num_chars = 0;
unsigned width = MAX_CHAR_TYPE_SIZE; unsigned width = MAX_CHAR_TYPE_SIZE;
int max_chars; int max_chars;
...@@ -679,7 +704,7 @@ yylex () ...@@ -679,7 +704,7 @@ yylex ()
/* Merge character into result; ignore excess chars. */ /* Merge character into result; ignore excess chars. */
if (num_chars <= max_chars) if (num_chars <= max_chars)
{ {
if (width < HOST_BITS_PER_LONG) if (width < HOST_BITS_PER_WIDE_INT)
result = (result << width) | c; result = (result << width) | c;
else else
result = c; result = c;
...@@ -709,10 +734,12 @@ yylex () ...@@ -709,10 +734,12 @@ yylex ()
if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1) if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
|| ((result >> (num_bits - 1)) & 1) == 0) || ((result >> (num_bits - 1)) & 1) == 0)
yylval.integer.value yylval.integer.value
= result & (~ (unsigned long) 0 >> (HOST_BITS_PER_LONG - num_bits)); = result & (~ (unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits));
else else
yylval.integer.value yylval.integer.value
= result | ~(~ (unsigned long) 0 >> (HOST_BITS_PER_LONG - num_bits)); = result | ~(~ (unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits));
} }
else else
{ {
...@@ -774,7 +801,7 @@ yylex () ...@@ -774,7 +801,7 @@ yylex ()
return c; return c;
case '"': case '"':
mask = LONG_MASK (MAX_CHAR_TYPE_SIZE); mask = HOST_WIDE_INT_MASK (MAX_CHAR_TYPE_SIZE);
string_constant: string_constant:
if (keyword_parsing) { if (keyword_parsing) {
char *start_ptr = lexptr; char *start_ptr = lexptr;
...@@ -852,10 +879,10 @@ yylex () ...@@ -852,10 +879,10 @@ yylex ()
If \ is followed by 000, we return 0 and leave the string pointer If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */ after the zeros. A value of 0 does not mean end of string. */
long HOST_WIDE_INT
parse_escape (string_ptr, result_mask) parse_escape (string_ptr, result_mask)
char **string_ptr; char **string_ptr;
long result_mask; HOST_WIDE_INT result_mask;
{ {
register int c = *(*string_ptr)++; register int c = *(*string_ptr)++;
switch (c) switch (c)
...@@ -894,7 +921,7 @@ parse_escape (string_ptr, result_mask) ...@@ -894,7 +921,7 @@ parse_escape (string_ptr, result_mask)
case '6': case '6':
case '7': case '7':
{ {
register long i = c - '0'; register HOST_WIDE_INT i = c - '0';
register int count = 0; register int count = 0;
while (++count < 3) while (++count < 3)
{ {
...@@ -916,7 +943,7 @@ parse_escape (string_ptr, result_mask) ...@@ -916,7 +943,7 @@ parse_escape (string_ptr, result_mask)
} }
case 'x': case 'x':
{ {
register unsigned long i = 0, overflow = 0; register unsigned HOST_WIDE_INT i = 0, overflow = 0;
register int digits_found = 0, digit; register int digits_found = 0, digit;
for (;;) for (;;)
{ {
...@@ -966,31 +993,31 @@ integer_overflow () ...@@ -966,31 +993,31 @@ integer_overflow ()
pedwarn ("integer overflow in preprocessor expression"); pedwarn ("integer overflow in preprocessor expression");
} }
static long static HOST_WIDE_INT
left_shift (a, b) left_shift (a, b)
struct constant *a; struct constant *a;
unsigned long b; unsigned HOST_WIDE_INT b;
{ {
/* It's unclear from the C standard whether shifts can overflow. /* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */ interpretation ruling is needed. */
if (b >= HOST_BITS_PER_LONG) if (b >= HOST_BITS_PER_WIDE_INT)
return 0; return 0;
else else
return (unsigned long) a->value << b; return (unsigned HOST_WIDE_INT) a->value << b;
} }
static long static HOST_WIDE_INT
right_shift (a, b) right_shift (a, b)
struct constant *a; struct constant *a;
unsigned long b; unsigned HOST_WIDE_INT b;
{ {
if (b >= HOST_BITS_PER_LONG) if (b >= HOST_BITS_PER_WIDE_INT)
return a->signedp ? a->value >> (HOST_BITS_PER_LONG - 1) : 0; return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
else if (a->signedp) else if (a->signedp)
return a->value >> b; return a->value >> b;
else else
return (unsigned long) a->value >> b; return (unsigned HOST_WIDE_INT) a->value >> b;
} }
/* This page contains the entry point to this file. */ /* This page contains the entry point to this file. */
...@@ -1002,7 +1029,7 @@ right_shift (a, b) ...@@ -1002,7 +1029,7 @@ right_shift (a, b)
/* We do not support C comments. They should be removed before /* We do not support C comments. They should be removed before
this function is called. */ this function is called. */
long HOST_WIDE_INT
parse_c_expression (string) parse_c_expression (string)
char *string; char *string;
{ {
...@@ -1063,7 +1090,7 @@ main (argc, argv) ...@@ -1063,7 +1090,7 @@ main (argc, argv)
n++; n++;
if (c == EOF) if (c == EOF)
break; break;
printf ("parser returned %ld\n", parse_c_expression (buf)); printf ("parser returned %ld\n", (long) parse_c_expression (buf));
} }
return 0; return 0;
......
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