diff options
Diffstat (limited to 'gcc/cexp.y')
-rw-r--r-- | gcc/cexp.y | 260 |
1 files changed, 116 insertions, 144 deletions
diff --git a/gcc/cexp.y b/gcc/cexp.y index c7d25c19658..9364ac3a8a0 100644 --- a/gcc/cexp.y +++ b/gcc/cexp.y @@ -1,5 +1,5 @@ /* Parse C expressions for CCCP. - Copyright (C) 1987, 1992, 94 - 97, 1998 Free Software Foundation. + Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -27,14 +27,10 @@ Boston, MA 02111-1307, USA. %{ #include "config.h" -#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n) - -#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2) - #include "system.h" +#include "intl.h" #include <setjmp.h> /* #define YYDEBUG 1 */ -#include "gansidecl.h" #ifdef MULTIBYTE_CHARS #include "mbchar.h" @@ -51,44 +47,12 @@ struct arglist { int argno; }; -/* Find the largest host integer type and set its size and type. - Watch out: on some crazy hosts `long' is shorter than `int'. */ - -#ifndef HOST_WIDE_INT -# if HAVE_INTTYPES_H -# include <inttypes.h> -# define HOST_WIDE_INT intmax_t -# define unsigned_HOST_WIDE_INT uintmax_t -# else -# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT) -# define HOST_WIDE_INT int -# else -# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX)) -# define HOST_WIDE_INT long -# else -# define HOST_WIDE_INT long long -# endif -# endif -# endif -#endif - -#ifndef unsigned_HOST_WIDE_INT -#define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT -#endif - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef HOST_BITS_PER_WIDE_INT -#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT)) -#endif - -HOST_WIDE_INT parse_c_expression PROTO((char *, int)); +HOST_WIDEST_INT parse_c_expression PROTO((char *, int)); static int yylex PROTO((void)); -static void yyerror PROTO((char *)) __attribute__ ((noreturn)); -static HOST_WIDE_INT expression_value; +static void yyerror PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; +static HOST_WIDEST_INT expression_value; #ifdef TEST_EXP_READER static int expression_signedp; #endif @@ -149,13 +113,13 @@ extern int c89; #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE #endif -#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \ - ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ - : ~ (HOST_WIDE_INT) 0) +#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ + : ~ (HOST_WIDEST_INT) 0) -#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \ - ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ - : ~ (HOST_WIDE_INT) 0) +#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ + : ~ (HOST_WIDEST_INT) 0) /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow. Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1. @@ -169,17 +133,17 @@ extern int c89; struct constant; -GENERIC_PTR xmalloc PROTO((size_t)); -HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT)); +HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT)); int check_assertion PROTO((U_CHAR *, int, int, struct arglist *)); struct hashnode *lookup PROTO((U_CHAR *, int, int)); -void error PRINTF_PROTO_1((char *, ...)); -void pedwarn PRINTF_PROTO_1((char *, ...)); -void warning PRINTF_PROTO_1((char *, ...)); +void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void verror PROTO((const char *, va_list)); +void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; static int parse_number PROTO((int)); -static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT)); -static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT)); +static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT)); +static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT)); static void integer_overflow PROTO((void)); /* `signedp' values */ @@ -188,7 +152,7 @@ static void integer_overflow PROTO((void)); %} %union { - struct constant {HOST_WIDE_INT value; int signedp;} integer; + struct constant {HOST_WIDEST_INT value; int signedp;} integer; struct name {U_CHAR *address; int length;} name; struct arglist *keywords; } @@ -275,7 +239,7 @@ exp : exp '*' exp integer_overflow (); } else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value * $3.value); } | exp '/' exp { if ($3.value == 0) @@ -292,7 +256,7 @@ exp : exp '*' exp integer_overflow (); } else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value / $3.value); } | exp '%' exp { if ($3.value == 0) @@ -305,7 +269,7 @@ exp : exp '*' exp if ($$.signedp) $$.value = $1.value % $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value % $3.value); } | exp '+' exp { $$.value = $1.value + $3.value; @@ -342,28 +306,28 @@ exp : exp '*' exp if ($1.signedp & $3.signedp) $$.value = $1.value <= $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value <= $3.value); } | exp GEQ exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value >= $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value >= $3.value); } | exp '<' exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value < $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value < $3.value); } | exp '>' exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value > $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value > $3.value); } | exp '&' exp { $$.value = $1.value & $3.value; @@ -446,7 +410,7 @@ parse_number (olen) { register char *p = lexptr; register int c; - register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base; + register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base; register int base = 10; register int len = olen; register int overflow = 0; @@ -464,7 +428,7 @@ parse_number (olen) } } - max_over_base = (unsigned_HOST_WIDE_INT) -1 / base; + max_over_base = (unsigned HOST_WIDEST_INT) -1 / base; for (; len > 0; len--) { c = *p++; @@ -493,12 +457,9 @@ parse_number (olen) else { if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P') yyerror ("Floating point numbers not allowed in #if expressions"); - else { - char *buf = (char *) alloca (p - lexptr + 40); - sprintf (buf, "missing white space after number `%.*s'", + else + yyerror ("missing white space after number `%.*s'", (int) (p - lexptr - 1), lexptr); - yyerror (buf); - } } if (--len == 0) @@ -522,7 +483,7 @@ parse_number (olen) pedwarn ("integer constant out of range"); /* If too big to be signed, consider it unsigned. */ - if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0) + if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0) { if (base == 10) warning ("integer constant is so large that it is unsigned"); @@ -535,7 +496,7 @@ parse_number (olen) } struct token { - char *operator; + const char *operator; int token; }; @@ -563,7 +524,7 @@ yylex () register unsigned char *tokstart; register struct token *toktab; int wide_flag; - HOST_WIDE_INT mask; + HOST_WIDEST_INT mask; retry: @@ -575,11 +536,7 @@ yylex () if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) { lexptr += 2; if (toktab->token == ERROR) - { - char *buf = (char *) alloca (40); - sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator); - yyerror (buf); - } + yyerror ("`%s' not allowed in operand of `#if'", toktab->operator); return toktab->token; } @@ -634,7 +591,7 @@ yylex () handles multicharacter constants and wide characters. It is mostly copied from c-lex.c. */ { - register HOST_WIDE_INT result = 0; + register HOST_WIDEST_INT result = 0; register int num_chars = 0; int chars_seen = 0; unsigned width = MAX_CHAR_TYPE_SIZE; @@ -749,12 +706,12 @@ yylex () sizeof ("__CHAR_UNSIGNED__") - 1, -1) || ((result >> (num_bits - 1)) & 1) == 0) yylval.integer.value - = result & (~ (unsigned_HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)); + = result & (~ (unsigned HOST_WIDEST_INT) 0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); else yylval.integer.value - = result | ~(~ (unsigned_HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)); + = result | ~(~ (unsigned HOST_WIDEST_INT) 0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); } else { @@ -880,10 +837,10 @@ yylex () 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. */ -HOST_WIDE_INT +HOST_WIDEST_INT parse_escape (string_ptr, result_mask) char **string_ptr; - HOST_WIDE_INT result_mask; + HOST_WIDEST_INT result_mask; { register int c = *(*string_ptr)++; switch (c) @@ -922,7 +879,7 @@ parse_escape (string_ptr, result_mask) case '6': case '7': { - register HOST_WIDE_INT i = c - '0'; + register HOST_WIDEST_INT i = c - '0'; register int count = 0; while (++count < 3) { @@ -944,7 +901,7 @@ parse_escape (string_ptr, result_mask) } case 'x': { - register unsigned_HOST_WIDE_INT i = 0, overflow = 0; + register unsigned HOST_WIDEST_INT i = 0, overflow = 0; register int digits_found = 0, digit; for (;;) { @@ -979,46 +936,37 @@ parse_escape (string_ptr, result_mask) } static void -yyerror (s) - char *s; -{ - error ("%s", s); - skip_evaluation = 0; - longjmp (parse_return_error, 1); -} - -static void integer_overflow () { if (!skip_evaluation && pedantic) pedwarn ("integer overflow in preprocessor expression"); } -static HOST_WIDE_INT +static HOST_WIDEST_INT left_shift (a, b) struct constant *a; - unsigned_HOST_WIDE_INT b; + unsigned HOST_WIDEST_INT b; { /* It's unclear from the C standard whether shifts can overflow. The following code ignores overflow; perhaps a C standard interpretation ruling is needed. */ - if (b >= HOST_BITS_PER_WIDE_INT) + if (b >= HOST_BITS_PER_WIDEST_INT) return 0; else - return (unsigned_HOST_WIDE_INT) a->value << b; + return (unsigned HOST_WIDEST_INT) a->value << b; } -static HOST_WIDE_INT +static HOST_WIDEST_INT right_shift (a, b) struct constant *a; - unsigned_HOST_WIDE_INT b; + unsigned HOST_WIDEST_INT b; { - if (b >= HOST_BITS_PER_WIDE_INT) - return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0; + if (b >= HOST_BITS_PER_WIDEST_INT) + return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0; else if (a->signedp) return a->value >> b; else - return (unsigned_HOST_WIDE_INT) a->value >> b; + return (unsigned HOST_WIDEST_INT) a->value >> b; } /* This page contains the entry point to this file. */ @@ -1031,7 +979,7 @@ right_shift (a, b) We do not support C comments. They should be removed before this function is called. */ -HOST_WIDE_INT +HOST_WIDEST_INT parse_c_expression (string, warn_undefined) char *string; int warn_undefined; @@ -1053,6 +1001,27 @@ parse_c_expression (string, warn_undefined) return expression_value; /* set by yyparse () */ } + +static void +yyerror VPROTO ((const char * msgid, ...)) +{ +#ifndef ANSI_PROTOTYPES + const char * msgid; +#endif + va_list args; + + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); +#endif + + verror (msgid, args); + va_end (args); + skip_evaluation = 0; + longjmp (parse_return_error, 1); +} + #ifdef TEST_EXP_READER @@ -1062,10 +1031,11 @@ extern int yydebug; int pedantic; int traditional; +int c89; int main PROTO((int, char **)); static void initialize_random_junk PROTO((void)); -static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT)); +static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT)); /* Main program for testing purposes. */ int @@ -1075,12 +1045,13 @@ main (argc, argv) { int n, c; char buf[1024]; - unsigned_HOST_WIDE_INT u; + unsigned HOST_WIDEST_INT u; pedantic = 1 < argc; traditional = 2 < argc; + c89 = 3 < argc; #if YYDEBUG - yydebug = 3 < argc; + yydebug = 4 < argc; #endif initialize_random_junk (); @@ -1093,7 +1064,7 @@ main (argc, argv) break; parse_c_expression (buf, 1); printf ("parser returned "); - u = (unsigned_HOST_WIDE_INT) expression_value; + u = (unsigned HOST_WIDEST_INT) expression_value; if (expression_value < 0 && expression_signedp) { u = -u; printf ("-"); @@ -1101,7 +1072,7 @@ main (argc, argv) if (u == 0) printf ("0"); else - print_unsigned_host_wide_int (u); + print_unsigned_host_widest_int (u); if (! expression_signedp) printf("u"); printf ("\n"); @@ -1111,11 +1082,11 @@ main (argc, argv) } static void -print_unsigned_host_wide_int (u) - unsigned_HOST_WIDE_INT u; +print_unsigned_host_widest_int (u) + unsigned HOST_WIDEST_INT u; { if (u) { - print_unsigned_host_wide_int (u / 10); + print_unsigned_host_widest_int (u / 10); putchar ('0' + (int) (u % 10)); } } @@ -1163,65 +1134,66 @@ initialize_random_junk () } void -error VPROTO ((char * msg, ...)) +error VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "error: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } void -pedwarn VPROTO ((char * msg, ...)) +pedwarn VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "pedwarn: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } void -warning VPROTO ((char * msg, ...)) +warning VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "warning: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } + int check_assertion (name, sym_length, tokens_specified, tokens) U_CHAR *name; @@ -1241,10 +1213,10 @@ lookup (name, len, hash) return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1); } -GENERIC_PTR +PTR xmalloc (size) - size_t size; + size_t size; { - return (GENERIC_PTR) malloc (size); + return (PTR) malloc (size); } #endif |