diff options
Diffstat (limited to 'contrib/gcc/cexp.y')
-rw-r--r-- | contrib/gcc/cexp.y | 376 |
1 files changed, 187 insertions, 189 deletions
diff --git a/contrib/gcc/cexp.y b/contrib/gcc/cexp.y index 6280aed..9364ac3 100644 --- a/contrib/gcc/cexp.y +++ b/contrib/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 @@ -26,25 +26,16 @@ Boston, MA 02111-1307, USA. %{ #include "config.h" -#ifdef __STDC__ -# include <stdarg.h> -#else -# include <varargs.h> -#endif - -#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 */ #ifdef MULTIBYTE_CHARS +#include "mbchar.h" #include <locale.h> -#endif - -#include "gansidecl.h" +#endif /* MULTIBYTE_CHARS */ typedef unsigned char U_CHAR; @@ -56,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 @@ -154,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. @@ -174,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 */ @@ -193,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; } @@ -280,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) @@ -297,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) @@ -310,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; @@ -347,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; @@ -451,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; @@ -469,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++; @@ -498,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) @@ -527,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"); @@ -540,7 +496,7 @@ parse_number (olen) } struct token { - char *operator; + const char *operator; int token; }; @@ -568,7 +524,7 @@ yylex () register unsigned char *tokstart; register struct token *toktab; int wide_flag; - HOST_WIDE_INT mask; + HOST_WIDEST_INT mask; retry: @@ -580,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; } @@ -639,25 +591,20 @@ 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; int max_chars; - char *token_buffer; - - if (wide_flag) - { - width = MAX_WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; + int longest_char = local_mb_cur_max (); + char *token_buffer = (char *) alloca (longest_char); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); #endif - } - else - max_chars = MAX_LONG_TYPE_SIZE / width; - token_buffer = (char *) alloca (max_chars + 1); + max_chars = MAX_LONG_TYPE_SIZE / width; + if (wide_flag) + width = MAX_WCHAR_TYPE_SIZE; while (1) { @@ -666,72 +613,108 @@ yylex () if (c == '\'' || c == EOF) break; + ++chars_seen; if (c == '\\') { c = parse_escape (&lexptr, mask); } + else + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 1; i <= longest_char; ++i) + { + token_buffer[i - 1] = c; + char_len = local_mbtowc (& wc, token_buffer, i); + if (char_len != -1) + break; + c = *lexptr++; + } + if (char_len > 1) + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len < i) + lexptr--; + if (! wide_flag) + { + /* Merge character into result; ignore excess chars. */ + for (i = 1; i <= char_len; ++i) + { + if (i > max_chars) + break; + if (width < HOST_BITS_PER_INT) + result = (result << width) + | (token_buffer[i - 1] + & ((1 << width) - 1)); + else + result = token_buffer[i - 1]; + } + num_chars += char_len; + continue; + } + } + else + { + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + } + if (wide_flag) + c = wc; +#endif /* ! MULTIBYTE_CHARS */ + } - num_chars++; + if (wide_flag) + { + if (chars_seen == 1) /* only keep the first one */ + result = c; + continue; + } /* Merge character into result; ignore excess chars. */ + num_chars++; if (num_chars <= max_chars) { - if (width < HOST_BITS_PER_WIDE_INT) - result = (result << width) | c; + if (width < HOST_BITS_PER_INT) + result = (result << width) | (c & ((1 << width) - 1)); else result = c; - token_buffer[num_chars - 1] = c; } } - token_buffer[num_chars] = 0; - if (c != '\'') error ("malformatted character constant"); - else if (num_chars == 0) + else if (chars_seen == 0) error ("empty character constant"); else if (num_chars > max_chars) { num_chars = max_chars; error ("character constant too long"); } - else if (num_chars != 1 && ! traditional) + else if (chars_seen != 1 && ! traditional) warning ("multi-character character constant"); /* If char type is signed, sign-extend the constant. */ if (! wide_flag) { int num_bits = num_chars * width; - - if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__", + if (num_bits == 0) + /* We already got an error; avoid invalid shift. */ + yylval.integer.value = 0; + else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__", 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 { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[0] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer, num_chars) == num_chars) - result = wc; - else - pedwarn ("Ignoring invalid multibyte character"); - } -#endif yylval.integer.value = result; } } @@ -854,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) @@ -896,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) { @@ -918,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 (;;) { @@ -953,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. */ @@ -1005,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; @@ -1027,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 @@ -1036,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 @@ -1049,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 (); @@ -1067,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 ("-"); @@ -1075,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"); @@ -1085,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)); } } @@ -1137,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; @@ -1215,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 |