* pa/pa.c (compute_movstrsi_length): Handle residuals correctly.
[official-gcc.git] / gcc / cexp.y
blob2d2d34f8b2893af0edf5398c6a171a8654e45f77
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995, 1996, 1997 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding!
23 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
25 /* Parse a C expression from text in a string */
28 #include "config.h"
29 #include <setjmp.h>
30 /* #define YYDEBUG 1 */
32 /* The following symbols should be autoconfigured:
33 HAVE_STDLIB_H
34 STDC_HEADERS
35 In the mean time, we'll get by with approximations based
36 on existing GCC configuration symbols. */
38 #ifdef POSIX
39 # ifndef HAVE_STDLIB_H
40 # define HAVE_STDLIB_H 1
41 # endif
42 # ifndef STDC_HEADERS
43 # define STDC_HEADERS 1
44 # endif
45 #endif /* defined (POSIX) */
47 #if STDC_HEADERS
48 # include <string.h>
49 #endif
51 #if HAVE_STDLIB_H || defined (MULTIBYTE_CHARS)
52 # include <stdlib.h>
53 #endif
55 #ifdef MULTIBYTE_CHARS
56 #include <locale.h>
57 #endif
59 #include <stdio.h>
61 typedef unsigned char U_CHAR;
63 /* This is used for communicating lists of keywords with cccp.c. */
64 struct arglist {
65 struct arglist *next;
66 U_CHAR *name;
67 int length;
68 int argno;
71 /* Define a generic NULL if one hasn't already been defined. */
73 #ifndef NULL
74 #define NULL 0
75 #endif
77 #ifndef GENERIC_PTR
78 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
79 #define GENERIC_PTR void *
80 #else
81 #define GENERIC_PTR char *
82 #endif
83 #endif
85 #ifndef NULL_PTR
86 #define NULL_PTR ((GENERIC_PTR) 0)
87 #endif
89 /* Find the largest host integer type and set its size and type.
90 Don't blindly use `long'; on some crazy hosts it is shorter than `int'. */
92 #ifndef HOST_BITS_PER_WIDE_INT
94 #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
95 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
96 #define HOST_WIDE_INT long
97 #else
98 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
99 #define HOST_WIDE_INT int
100 #endif
102 #endif
104 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
105 # define __attribute__(x)
106 #endif
108 #ifndef PROTO
109 # if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
110 # define PROTO(ARGS) ARGS
111 # else
112 # define PROTO(ARGS) ()
113 # endif
114 #endif
116 #if defined (__STDC__) && defined (HAVE_VPRINTF)
117 # include <stdarg.h>
118 # define VA_START(va_list, var) va_start (va_list, var)
119 # define PRINTF_ALIST(msg) char *msg, ...
120 # define PRINTF_DCL(msg)
121 # define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (__printf__, m, n)))
122 #else
123 # include <varargs.h>
124 # define VA_START(va_list, var) va_start (va_list)
125 # define PRINTF_ALIST(msg) msg, va_alist
126 # define PRINTF_DCL(msg) char *msg; va_dcl
127 # define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (__printf__, m, n)))
128 # define vfprintf(file, msg, args) \
130 char *a0 = va_arg(args, char *); \
131 char *a1 = va_arg(args, char *); \
132 char *a2 = va_arg(args, char *); \
133 char *a3 = va_arg(args, char *); \
134 fprintf (file, msg, a0, a1, a2, a3); \
136 #endif
138 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
140 HOST_WIDE_INT parse_c_expression PROTO((char *));
142 static int yylex PROTO((void));
143 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
144 static HOST_WIDE_INT expression_value;
146 static jmp_buf parse_return_error;
148 /* Nonzero means count most punctuation as part of a name. */
149 static int keyword_parsing = 0;
151 /* Nonzero means do not evaluate this expression.
152 This is a count, since unevaluated expressions can nest. */
153 static int skip_evaluation;
155 /* some external tables of character types */
156 extern unsigned char is_idstart[], is_idchar[], is_space[];
158 /* Flag for -pedantic. */
159 extern int pedantic;
161 /* Flag for -traditional. */
162 extern int traditional;
164 /* Flag for -lang-c89. */
165 extern int c89;
167 #ifndef CHAR_TYPE_SIZE
168 #define CHAR_TYPE_SIZE BITS_PER_UNIT
169 #endif
171 #ifndef INT_TYPE_SIZE
172 #define INT_TYPE_SIZE BITS_PER_WORD
173 #endif
175 #ifndef LONG_TYPE_SIZE
176 #define LONG_TYPE_SIZE BITS_PER_WORD
177 #endif
179 #ifndef WCHAR_TYPE_SIZE
180 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
181 #endif
183 #ifndef MAX_CHAR_TYPE_SIZE
184 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
185 #endif
187 #ifndef MAX_INT_TYPE_SIZE
188 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
189 #endif
191 #ifndef MAX_LONG_TYPE_SIZE
192 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
193 #endif
195 #ifndef MAX_WCHAR_TYPE_SIZE
196 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
197 #endif
199 #if MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
200 #define MAX_CHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE))
201 #else
202 #define MAX_CHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
203 #endif
205 #if MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
206 #define MAX_WCHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE))
207 #else
208 #define MAX_WCHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
209 #endif
211 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
212 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
213 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
214 Then this yields nonzero if overflow occurred during the addition.
215 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
216 and SIGNEDP is negative.
217 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
218 #define overflow_sum_sign(a, b, sum, signedp) \
219 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
221 struct constant;
223 GENERIC_PTR xmalloc PROTO((size_t));
224 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
225 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
226 struct hashnode *lookup PROTO((U_CHAR *, int, int));
227 void error PRINTF_PROTO_1((char *, ...));
228 void pedwarn PRINTF_PROTO_1((char *, ...));
229 void warning PRINTF_PROTO_1((char *, ...));
231 static int parse_number PROTO((int));
232 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
233 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
234 static void integer_overflow PROTO((void));
236 /* `signedp' values */
237 #define SIGNED (~0)
238 #define UNSIGNED 0
241 %union {
242 struct constant {HOST_WIDE_INT value; int signedp;} integer;
243 struct name {U_CHAR *address; int length;} name;
244 struct arglist *keywords;
247 %type <integer> exp exp1 start
248 %type <keywords> keywords
249 %token <integer> INT CHAR
250 %token <name> NAME
251 %token <integer> ERROR
253 %right '?' ':'
254 %left ','
255 %left OR
256 %left AND
257 %left '|'
258 %left '^'
259 %left '&'
260 %left EQUAL NOTEQUAL
261 %left '<' '>' LEQ GEQ
262 %left LSH RSH
263 %left '+' '-'
264 %left '*' '/' '%'
265 %right UNARY
267 /* %expect 40 */
271 start : exp1
272 { expression_value = $1.value; }
275 /* Expressions, including the comma operator. */
276 exp1 : exp
277 | exp1 ',' exp
278 { if (pedantic)
279 pedwarn ("comma operator in operand of `#if'");
280 $$ = $3; }
283 /* Expressions, not including the comma operator. */
284 exp : '-' exp %prec UNARY
285 { $$.value = - $2.value;
286 $$.signedp = $2.signedp;
287 if (($$.value & $2.value & $$.signedp) < 0)
288 integer_overflow (); }
289 | '!' exp %prec UNARY
290 { $$.value = ! $2.value;
291 $$.signedp = SIGNED; }
292 | '+' exp %prec UNARY
293 { $$ = $2; }
294 | '~' exp %prec UNARY
295 { $$.value = ~ $2.value;
296 $$.signedp = $2.signedp; }
297 | '#' NAME
298 { $$.value = check_assertion ($2.address, $2.length,
299 0, NULL_PTR);
300 $$.signedp = SIGNED; }
301 | '#' NAME
302 { keyword_parsing = 1; }
303 '(' keywords ')'
304 { $$.value = check_assertion ($2.address, $2.length,
305 1, $5);
306 keyword_parsing = 0;
307 $$.signedp = SIGNED; }
308 | '(' exp1 ')'
309 { $$ = $2; }
312 /* Binary operators in order of decreasing precedence. */
313 exp : exp '*' exp
314 { $$.signedp = $1.signedp & $3.signedp;
315 if ($$.signedp)
317 $$.value = $1.value * $3.value;
318 if ($1.value
319 && ($$.value / $1.value != $3.value
320 || ($$.value & $1.value & $3.value) < 0))
321 integer_overflow ();
323 else
324 $$.value = ((unsigned HOST_WIDE_INT) $1.value
325 * $3.value); }
326 | exp '/' exp
327 { if ($3.value == 0)
329 if (!skip_evaluation)
330 error ("division by zero in #if");
331 $3.value = 1;
333 $$.signedp = $1.signedp & $3.signedp;
334 if ($$.signedp)
336 $$.value = $1.value / $3.value;
337 if (($$.value & $1.value & $3.value) < 0)
338 integer_overflow ();
340 else
341 $$.value = ((unsigned HOST_WIDE_INT) $1.value
342 / $3.value); }
343 | exp '%' exp
344 { if ($3.value == 0)
346 if (!skip_evaluation)
347 error ("division by zero in #if");
348 $3.value = 1;
350 $$.signedp = $1.signedp & $3.signedp;
351 if ($$.signedp)
352 $$.value = $1.value % $3.value;
353 else
354 $$.value = ((unsigned HOST_WIDE_INT) $1.value
355 % $3.value); }
356 | exp '+' exp
357 { $$.value = $1.value + $3.value;
358 $$.signedp = $1.signedp & $3.signedp;
359 if (overflow_sum_sign ($1.value, $3.value,
360 $$.value, $$.signedp))
361 integer_overflow (); }
362 | exp '-' exp
363 { $$.value = $1.value - $3.value;
364 $$.signedp = $1.signedp & $3.signedp;
365 if (overflow_sum_sign ($$.value, $3.value,
366 $1.value, $$.signedp))
367 integer_overflow (); }
368 | exp LSH exp
369 { $$.signedp = $1.signedp;
370 if (($3.value & $3.signedp) < 0)
371 $$.value = right_shift (&$1, -$3.value);
372 else
373 $$.value = left_shift (&$1, $3.value); }
374 | exp RSH exp
375 { $$.signedp = $1.signedp;
376 if (($3.value & $3.signedp) < 0)
377 $$.value = left_shift (&$1, -$3.value);
378 else
379 $$.value = right_shift (&$1, $3.value); }
380 | exp EQUAL exp
381 { $$.value = ($1.value == $3.value);
382 $$.signedp = SIGNED; }
383 | exp NOTEQUAL exp
384 { $$.value = ($1.value != $3.value);
385 $$.signedp = SIGNED; }
386 | exp LEQ exp
387 { $$.signedp = SIGNED;
388 if ($1.signedp & $3.signedp)
389 $$.value = $1.value <= $3.value;
390 else
391 $$.value = ((unsigned HOST_WIDE_INT) $1.value
392 <= $3.value); }
393 | exp GEQ exp
394 { $$.signedp = SIGNED;
395 if ($1.signedp & $3.signedp)
396 $$.value = $1.value >= $3.value;
397 else
398 $$.value = ((unsigned HOST_WIDE_INT) $1.value
399 >= $3.value); }
400 | exp '<' exp
401 { $$.signedp = SIGNED;
402 if ($1.signedp & $3.signedp)
403 $$.value = $1.value < $3.value;
404 else
405 $$.value = ((unsigned HOST_WIDE_INT) $1.value
406 < $3.value); }
407 | exp '>' exp
408 { $$.signedp = SIGNED;
409 if ($1.signedp & $3.signedp)
410 $$.value = $1.value > $3.value;
411 else
412 $$.value = ((unsigned HOST_WIDE_INT) $1.value
413 > $3.value); }
414 | exp '&' exp
415 { $$.value = $1.value & $3.value;
416 $$.signedp = $1.signedp & $3.signedp; }
417 | exp '^' exp
418 { $$.value = $1.value ^ $3.value;
419 $$.signedp = $1.signedp & $3.signedp; }
420 | exp '|' exp
421 { $$.value = $1.value | $3.value;
422 $$.signedp = $1.signedp & $3.signedp; }
423 | exp AND
424 { skip_evaluation += !$1.value; }
426 { skip_evaluation -= !$1.value;
427 $$.value = ($1.value && $4.value);
428 $$.signedp = SIGNED; }
429 | exp OR
430 { skip_evaluation += !!$1.value; }
432 { skip_evaluation -= !!$1.value;
433 $$.value = ($1.value || $4.value);
434 $$.signedp = SIGNED; }
435 | exp '?'
436 { skip_evaluation += !$1.value; }
437 exp ':'
438 { skip_evaluation += !!$1.value - !$1.value; }
440 { skip_evaluation -= !!$1.value;
441 $$.value = $1.value ? $4.value : $7.value;
442 $$.signedp = $4.signedp & $7.signedp; }
443 | INT
444 { $$ = yylval.integer; }
445 | CHAR
446 { $$ = yylval.integer; }
447 | NAME
448 { $$.value = 0;
449 $$.signedp = SIGNED; }
452 keywords :
453 { $$ = 0; }
454 | '(' keywords ')' keywords
455 { struct arglist *temp;
456 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
457 $$->next = $2;
458 $$->name = (U_CHAR *) "(";
459 $$->length = 1;
460 temp = $$;
461 while (temp != 0 && temp->next != 0)
462 temp = temp->next;
463 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
464 temp->next->next = $4;
465 temp->next->name = (U_CHAR *) ")";
466 temp->next->length = 1; }
467 | NAME keywords
468 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
469 $$->name = $1.address;
470 $$->length = $1.length;
471 $$->next = $2; }
475 /* During parsing of a C expression, the pointer to the next character
476 is in this variable. */
478 static char *lexptr;
480 /* Take care of parsing a number (anything that starts with a digit).
481 Set yylval and return the token type; update lexptr.
482 LEN is the number of characters in it. */
484 /* maybe needs to actually deal with floating point numbers */
486 static int
487 parse_number (olen)
488 int olen;
490 register char *p = lexptr;
491 register int c;
492 register unsigned HOST_WIDE_INT n = 0, nd, max_over_base;
493 register int base = 10;
494 register int len = olen;
495 register int overflow = 0;
496 register int digit, largest_digit = 0;
497 int spec_long = 0;
499 yylval.integer.signedp = SIGNED;
501 if (*p == '0') {
502 base = 8;
503 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
504 p += 2;
505 base = 16;
506 len -= 2;
510 max_over_base = (unsigned HOST_WIDE_INT) -1 / base;
512 for (; len > 0; len--) {
513 c = *p++;
515 if (c >= '0' && c <= '9')
516 digit = c - '0';
517 else if (base == 16 && c >= 'a' && c <= 'f')
518 digit = c - 'a' + 10;
519 else if (base == 16 && c >= 'A' && c <= 'F')
520 digit = c - 'A' + 10;
521 else {
522 /* `l' means long, and `u' means unsigned. */
523 while (1) {
524 if (c == 'l' || c == 'L')
526 if (!pedantic < spec_long)
527 yyerror ("too many `l's in integer constant");
528 spec_long++;
530 else if (c == 'u' || c == 'U')
532 if (! yylval.integer.signedp)
533 yyerror ("two `u's in integer constant");
534 yylval.integer.signedp = UNSIGNED;
536 else {
537 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
538 yyerror ("Floating point numbers not allowed in #if expressions");
539 else {
540 char *buf = (char *) alloca (p - lexptr + 40);
541 sprintf (buf, "missing white space after number `%.*s'",
542 (int) (p - lexptr - 1), lexptr);
543 yyerror (buf);
547 if (--len == 0)
548 break;
549 c = *p++;
551 /* Don't look for any more digits after the suffixes. */
552 break;
554 if (largest_digit < digit)
555 largest_digit = digit;
556 nd = n * base + digit;
557 overflow |= (max_over_base < n) | (nd < n);
558 n = nd;
561 if (base <= largest_digit)
562 pedwarn ("integer constant contains digits beyond the radix");
564 if (overflow)
565 pedwarn ("integer constant out of range");
567 /* If too big to be signed, consider it unsigned. */
568 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
570 if (base == 10)
571 warning ("integer constant is so large that it is unsigned");
572 yylval.integer.signedp = UNSIGNED;
575 lexptr = p;
576 yylval.integer.value = n;
577 return INT;
580 struct token {
581 char *operator;
582 int token;
585 static struct token tokentab2[] = {
586 {"&&", AND},
587 {"||", OR},
588 {"<<", LSH},
589 {">>", RSH},
590 {"==", EQUAL},
591 {"!=", NOTEQUAL},
592 {"<=", LEQ},
593 {">=", GEQ},
594 {"++", ERROR},
595 {"--", ERROR},
596 {NULL, ERROR}
599 /* Read one token, getting characters through lexptr. */
601 static int
602 yylex ()
604 register int c;
605 register int namelen;
606 register unsigned char *tokstart;
607 register struct token *toktab;
608 int wide_flag;
609 HOST_WIDE_INT mask;
611 retry:
613 tokstart = (unsigned char *) lexptr;
614 c = *tokstart;
615 /* See if it is a special token of length 2. */
616 if (! keyword_parsing)
617 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
618 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
619 lexptr += 2;
620 if (toktab->token == ERROR)
622 char *buf = (char *) alloca (40);
623 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
624 yyerror (buf);
626 return toktab->token;
629 switch (c) {
630 case '\n':
631 return 0;
633 case ' ':
634 case '\t':
635 case '\r':
636 lexptr++;
637 goto retry;
639 case 'L':
640 /* Capital L may start a wide-string or wide-character constant. */
641 if (lexptr[1] == '\'')
643 lexptr++;
644 wide_flag = 1;
645 mask = MAX_WCHAR_TYPE_MASK;
646 goto char_constant;
648 if (lexptr[1] == '"')
650 lexptr++;
651 wide_flag = 1;
652 mask = MAX_WCHAR_TYPE_MASK;
653 goto string_constant;
655 break;
657 case '\'':
658 wide_flag = 0;
659 mask = MAX_CHAR_TYPE_MASK;
660 char_constant:
661 lexptr++;
662 if (keyword_parsing) {
663 char *start_ptr = lexptr - 1;
664 while (1) {
665 c = *lexptr++;
666 if (c == '\\')
667 c = parse_escape (&lexptr, mask);
668 else if (c == '\'')
669 break;
671 yylval.name.address = tokstart;
672 yylval.name.length = lexptr - start_ptr;
673 return NAME;
676 /* This code for reading a character constant
677 handles multicharacter constants and wide characters.
678 It is mostly copied from c-lex.c. */
680 register HOST_WIDE_INT result = 0;
681 register num_chars = 0;
682 unsigned width = MAX_CHAR_TYPE_SIZE;
683 int max_chars;
684 char *token_buffer;
686 if (wide_flag)
688 width = MAX_WCHAR_TYPE_SIZE;
689 #ifdef MULTIBYTE_CHARS
690 max_chars = MB_CUR_MAX;
691 #else
692 max_chars = 1;
693 #endif
695 else
696 max_chars = MAX_LONG_TYPE_SIZE / width;
698 token_buffer = (char *) alloca (max_chars + 1);
700 while (1)
702 c = *lexptr++;
704 if (c == '\'' || c == EOF)
705 break;
707 if (c == '\\')
709 c = parse_escape (&lexptr, mask);
712 num_chars++;
714 /* Merge character into result; ignore excess chars. */
715 if (num_chars <= max_chars)
717 if (width < HOST_BITS_PER_WIDE_INT)
718 result = (result << width) | c;
719 else
720 result = c;
721 token_buffer[num_chars - 1] = c;
725 token_buffer[num_chars] = 0;
727 if (c != '\'')
728 error ("malformatted character constant");
729 else if (num_chars == 0)
730 error ("empty character constant");
731 else if (num_chars > max_chars)
733 num_chars = max_chars;
734 error ("character constant too long");
736 else if (num_chars != 1 && ! traditional)
737 warning ("multi-character character constant");
739 /* If char type is signed, sign-extend the constant. */
740 if (! wide_flag)
742 int num_bits = num_chars * width;
744 if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
745 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
746 || ((result >> (num_bits - 1)) & 1) == 0)
747 yylval.integer.value
748 = result & (~ (unsigned HOST_WIDE_INT) 0
749 >> (HOST_BITS_PER_WIDE_INT - num_bits));
750 else
751 yylval.integer.value
752 = result | ~(~ (unsigned HOST_WIDE_INT) 0
753 >> (HOST_BITS_PER_WIDE_INT - num_bits));
755 else
757 #ifdef MULTIBYTE_CHARS
758 /* Set the initial shift state and convert the next sequence. */
759 result = 0;
760 /* In all locales L'\0' is zero and mbtowc will return zero,
761 so don't use it. */
762 if (num_chars > 1
763 || (num_chars == 1 && token_buffer[0] != '\0'))
765 wchar_t wc;
766 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
767 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
768 result = wc;
769 else
770 pedwarn ("Ignoring invalid multibyte character");
772 #endif
773 yylval.integer.value = result;
777 /* This is always a signed type. */
778 yylval.integer.signedp = SIGNED;
780 return CHAR;
782 /* some of these chars are invalid in constant expressions;
783 maybe do something about them later */
784 case '/':
785 case '+':
786 case '-':
787 case '*':
788 case '%':
789 case '|':
790 case '&':
791 case '^':
792 case '~':
793 case '!':
794 case '@':
795 case '<':
796 case '>':
797 case '[':
798 case ']':
799 case '.':
800 case '?':
801 case ':':
802 case '=':
803 case '{':
804 case '}':
805 case ',':
806 case '#':
807 if (keyword_parsing)
808 break;
809 case '(':
810 case ')':
811 lexptr++;
812 return c;
814 case '"':
815 mask = MAX_CHAR_TYPE_MASK;
816 string_constant:
817 if (keyword_parsing) {
818 char *start_ptr = lexptr;
819 lexptr++;
820 while (1) {
821 c = *lexptr++;
822 if (c == '\\')
823 c = parse_escape (&lexptr, mask);
824 else if (c == '"')
825 break;
827 yylval.name.address = tokstart;
828 yylval.name.length = lexptr - start_ptr;
829 return NAME;
831 yyerror ("string constants not allowed in #if expressions");
832 return ERROR;
835 if (c >= '0' && c <= '9' && !keyword_parsing) {
836 /* It's a number */
837 for (namelen = 1; ; namelen++) {
838 int d = tokstart[namelen];
839 if (! ((is_idchar[d] || d == '.')
840 || ((d == '-' || d == '+')
841 && (c == 'e' || c == 'E'
842 || ((c == 'p' || c == 'P') && ! c89))
843 && ! traditional)))
844 break;
845 c = d;
847 return parse_number (namelen);
850 /* It is a name. See how long it is. */
852 if (keyword_parsing) {
853 for (namelen = 0;; namelen++) {
854 if (is_space[tokstart[namelen]])
855 break;
856 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
857 break;
858 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
859 break;
861 } else {
862 if (!is_idstart[c]) {
863 yyerror ("Invalid token in expression");
864 return ERROR;
867 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
871 lexptr += namelen;
872 yylval.name.address = tokstart;
873 yylval.name.length = namelen;
874 return NAME;
878 /* Parse a C escape sequence. STRING_PTR points to a variable
879 containing a pointer to the string to parse. That pointer
880 is updated past the characters we use. The value of the
881 escape sequence is returned.
883 RESULT_MASK is used to mask out the result;
884 an error is reported if bits are lost thereby.
886 A negative value means the sequence \ newline was seen,
887 which is supposed to be equivalent to nothing at all.
889 If \ is followed by a null character, we return a negative
890 value and leave the string pointer pointing at the null character.
892 If \ is followed by 000, we return 0 and leave the string pointer
893 after the zeros. A value of 0 does not mean end of string. */
895 HOST_WIDE_INT
896 parse_escape (string_ptr, result_mask)
897 char **string_ptr;
898 HOST_WIDE_INT result_mask;
900 register int c = *(*string_ptr)++;
901 switch (c)
903 case 'a':
904 return TARGET_BELL;
905 case 'b':
906 return TARGET_BS;
907 case 'e':
908 case 'E':
909 if (pedantic)
910 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
911 return 033;
912 case 'f':
913 return TARGET_FF;
914 case 'n':
915 return TARGET_NEWLINE;
916 case 'r':
917 return TARGET_CR;
918 case 't':
919 return TARGET_TAB;
920 case 'v':
921 return TARGET_VT;
922 case '\n':
923 return -2;
924 case 0:
925 (*string_ptr)--;
926 return 0;
928 case '0':
929 case '1':
930 case '2':
931 case '3':
932 case '4':
933 case '5':
934 case '6':
935 case '7':
937 register HOST_WIDE_INT i = c - '0';
938 register int count = 0;
939 while (++count < 3)
941 c = *(*string_ptr)++;
942 if (c >= '0' && c <= '7')
943 i = (i << 3) + c - '0';
944 else
946 (*string_ptr)--;
947 break;
950 if (i != (i & result_mask))
952 i &= result_mask;
953 pedwarn ("octal escape sequence out of range");
955 return i;
957 case 'x':
959 register unsigned HOST_WIDE_INT i = 0, overflow = 0;
960 register int digits_found = 0, digit;
961 for (;;)
963 c = *(*string_ptr)++;
964 if (c >= '0' && c <= '9')
965 digit = c - '0';
966 else if (c >= 'a' && c <= 'f')
967 digit = c - 'a' + 10;
968 else if (c >= 'A' && c <= 'F')
969 digit = c - 'A' + 10;
970 else
972 (*string_ptr)--;
973 break;
975 overflow |= i ^ (i << 4 >> 4);
976 i = (i << 4) + digit;
977 digits_found = 1;
979 if (!digits_found)
980 yyerror ("\\x used with no following hex digits");
981 if (overflow | (i != (i & result_mask)))
983 i &= result_mask;
984 pedwarn ("hex escape sequence out of range");
986 return i;
988 default:
989 return c;
993 static void
994 yyerror (s)
995 char *s;
997 error ("%s", s);
998 skip_evaluation = 0;
999 longjmp (parse_return_error, 1);
1002 static void
1003 integer_overflow ()
1005 if (!skip_evaluation && pedantic)
1006 pedwarn ("integer overflow in preprocessor expression");
1009 static HOST_WIDE_INT
1010 left_shift (a, b)
1011 struct constant *a;
1012 unsigned HOST_WIDE_INT b;
1014 /* It's unclear from the C standard whether shifts can overflow.
1015 The following code ignores overflow; perhaps a C standard
1016 interpretation ruling is needed. */
1017 if (b >= HOST_BITS_PER_WIDE_INT)
1018 return 0;
1019 else
1020 return (unsigned HOST_WIDE_INT) a->value << b;
1023 static HOST_WIDE_INT
1024 right_shift (a, b)
1025 struct constant *a;
1026 unsigned HOST_WIDE_INT b;
1028 if (b >= HOST_BITS_PER_WIDE_INT)
1029 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1030 else if (a->signedp)
1031 return a->value >> b;
1032 else
1033 return (unsigned HOST_WIDE_INT) a->value >> b;
1036 /* This page contains the entry point to this file. */
1038 /* Parse STRING as an expression, and complain if this fails
1039 to use up all of the contents of STRING. */
1040 /* STRING may contain '\0' bytes; it is terminated by the first '\n'
1041 outside a string constant, so that we can diagnose '\0' properly. */
1042 /* We do not support C comments. They should be removed before
1043 this function is called. */
1045 HOST_WIDE_INT
1046 parse_c_expression (string)
1047 char *string;
1049 lexptr = string;
1051 /* if there is some sort of scanning error, just return 0 and assume
1052 the parsing routine has printed an error message somewhere.
1053 there is surely a better thing to do than this. */
1054 if (setjmp (parse_return_error))
1055 return 0;
1057 if (yyparse () != 0)
1058 abort ();
1060 if (*lexptr != '\n')
1061 error ("Junk after end of expression.");
1063 return expression_value; /* set by yyparse () */
1066 #ifdef TEST_EXP_READER
1068 #if YYDEBUG
1069 extern int yydebug;
1070 #endif
1072 int pedantic;
1073 int traditional;
1075 int main PROTO((int, char **));
1076 static void initialize_random_junk PROTO((void));
1078 /* Main program for testing purposes. */
1080 main (argc, argv)
1081 int argc;
1082 char **argv;
1084 int n, c;
1085 char buf[1024];
1087 pedantic = 1 < argc;
1088 traditional = 2 < argc;
1089 #if YYDEBUG
1090 yydebug = 3 < argc;
1091 #endif
1092 initialize_random_junk ();
1094 for (;;) {
1095 printf ("enter expression: ");
1096 n = 0;
1097 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1098 n++;
1099 if (c == EOF)
1100 break;
1101 printf ("parser returned %ld\n", (long) parse_c_expression (buf));
1104 return 0;
1107 /* table to tell if char can be part of a C identifier. */
1108 unsigned char is_idchar[256];
1109 /* table to tell if char can be first char of a c identifier. */
1110 unsigned char is_idstart[256];
1111 /* table to tell if c is horizontal or vertical space. */
1112 unsigned char is_space[256];
1115 * initialize random junk in the hash table and maybe other places
1117 static void
1118 initialize_random_junk ()
1120 register int i;
1123 * Set up is_idchar and is_idstart tables. These should be
1124 * faster than saying (is_alpha (c) || c == '_'), etc.
1125 * Must do set up these things before calling any routines tthat
1126 * refer to them.
1128 for (i = 'a'; i <= 'z'; i++) {
1129 ++is_idchar[i - 'a' + 'A'];
1130 ++is_idchar[i];
1131 ++is_idstart[i - 'a' + 'A'];
1132 ++is_idstart[i];
1134 for (i = '0'; i <= '9'; i++)
1135 ++is_idchar[i];
1136 ++is_idchar['_'];
1137 ++is_idstart['_'];
1138 ++is_idchar['$'];
1139 ++is_idstart['$'];
1141 ++is_space[' '];
1142 ++is_space['\t'];
1143 ++is_space['\v'];
1144 ++is_space['\f'];
1145 ++is_space['\n'];
1146 ++is_space['\r'];
1149 void
1150 error (PRINTF_ALIST (msg))
1151 PRINTF_DCL (msg)
1153 va_list args;
1155 VA_START (args, msg);
1156 fprintf (stderr, "error: ");
1157 vfprintf (stderr, msg, args);
1158 fprintf (stderr, "\n");
1159 va_end (args);
1162 void
1163 pedwarn (PRINTF_ALIST (msg))
1164 PRINTF_DCL (msg)
1166 va_list args;
1168 VA_START (args, msg);
1169 fprintf (stderr, "pedwarn: ");
1170 vfprintf (stderr, msg, args);
1171 fprintf (stderr, "\n");
1172 va_end (args);
1175 void
1176 warning (PRINTF_ALIST (msg))
1177 PRINTF_DCL (msg)
1179 va_list args;
1181 VA_START (args, msg);
1182 fprintf (stderr, "warning: ");
1183 vfprintf (stderr, msg, args);
1184 fprintf (stderr, "\n");
1185 va_end (args);
1189 check_assertion (name, sym_length, tokens_specified, tokens)
1190 U_CHAR *name;
1191 int sym_length;
1192 int tokens_specified;
1193 struct arglist *tokens;
1195 return 0;
1198 struct hashnode *
1199 lookup (name, len, hash)
1200 U_CHAR *name;
1201 int len;
1202 int hash;
1204 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1207 GENERIC_PTR
1208 xmalloc (size)
1209 size_t size;
1211 return (GENERIC_PTR) malloc (size);
1213 #endif