--with-gnu-ld uses different x- fiile under aix 4.1
[official-gcc.git] / gcc / cexp.y
blobd63c4d1114362ec9703eb2b716e0652115af43f4
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 94 - 97, 1998 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"
30 #define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
32 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
34 #include "system.h"
35 #include <setjmp.h>
36 /* #define YYDEBUG 1 */
38 #ifdef MULTIBYTE_CHARS
39 #include "mbchar.h"
40 #include <locale.h>
41 #endif /* MULTIBYTE_CHARS */
43 typedef unsigned char U_CHAR;
45 /* This is used for communicating lists of keywords with cccp.c. */
46 struct arglist {
47 struct arglist *next;
48 U_CHAR *name;
49 int length;
50 int argno;
53 /* Find the largest host integer type and set its size and type.
54 Watch out: on some crazy hosts `long' is shorter than `int'. */
56 #ifndef HOST_WIDE_INT
57 # if HAVE_INTTYPES_H
58 # include <inttypes.h>
59 # define HOST_WIDE_INT intmax_t
60 # define unsigned_HOST_WIDE_INT uintmax_t
61 # else
62 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
63 # define HOST_WIDE_INT int
64 # else
65 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
66 # define HOST_WIDE_INT long
67 # else
68 # define HOST_WIDE_INT long long
69 # endif
70 # endif
71 # endif
72 #endif
74 #ifndef unsigned_HOST_WIDE_INT
75 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
76 #endif
78 #ifndef CHAR_BIT
79 #define CHAR_BIT 8
80 #endif
82 #ifndef HOST_BITS_PER_WIDE_INT
83 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
84 #endif
86 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
88 static int yylex PROTO((void));
89 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
90 static HOST_WIDE_INT expression_value;
91 #ifdef TEST_EXP_READER
92 static int expression_signedp;
93 #endif
95 static jmp_buf parse_return_error;
97 /* Nonzero means count most punctuation as part of a name. */
98 static int keyword_parsing = 0;
100 /* Nonzero means do not evaluate this expression.
101 This is a count, since unevaluated expressions can nest. */
102 static int skip_evaluation;
104 /* Nonzero means warn if undefined identifiers are evaluated. */
105 static int warn_undef;
107 /* some external tables of character types */
108 extern unsigned char is_idstart[], is_idchar[], is_space[];
110 /* Flag for -pedantic. */
111 extern int pedantic;
113 /* Flag for -traditional. */
114 extern int traditional;
116 /* Flag for -lang-c89. */
117 extern int c89;
119 #ifndef CHAR_TYPE_SIZE
120 #define CHAR_TYPE_SIZE BITS_PER_UNIT
121 #endif
123 #ifndef INT_TYPE_SIZE
124 #define INT_TYPE_SIZE BITS_PER_WORD
125 #endif
127 #ifndef LONG_TYPE_SIZE
128 #define LONG_TYPE_SIZE BITS_PER_WORD
129 #endif
131 #ifndef WCHAR_TYPE_SIZE
132 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
133 #endif
135 #ifndef MAX_CHAR_TYPE_SIZE
136 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
137 #endif
139 #ifndef MAX_INT_TYPE_SIZE
140 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
141 #endif
143 #ifndef MAX_LONG_TYPE_SIZE
144 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
145 #endif
147 #ifndef MAX_WCHAR_TYPE_SIZE
148 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
149 #endif
151 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
152 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
153 : ~ (HOST_WIDE_INT) 0)
155 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
156 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
157 : ~ (HOST_WIDE_INT) 0)
159 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
160 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
161 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
162 Then this yields nonzero if overflow occurred during the addition.
163 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
164 and SIGNEDP is negative.
165 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
166 #define overflow_sum_sign(a, b, sum, signedp) \
167 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
169 struct constant;
171 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
172 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
173 struct hashnode *lookup PROTO((U_CHAR *, int, int));
174 void error PRINTF_PROTO_1((char *, ...));
175 void pedwarn PRINTF_PROTO_1((char *, ...));
176 void warning PRINTF_PROTO_1((char *, ...));
178 static int parse_number PROTO((int));
179 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
180 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
181 static void integer_overflow PROTO((void));
183 /* `signedp' values */
184 #define SIGNED (~0)
185 #define UNSIGNED 0
188 %union {
189 struct constant {HOST_WIDE_INT value; int signedp;} integer;
190 struct name {U_CHAR *address; int length;} name;
191 struct arglist *keywords;
194 %type <integer> exp exp1 start
195 %type <keywords> keywords
196 %token <integer> INT CHAR
197 %token <name> NAME
198 %token <integer> ERROR
200 %right '?' ':'
201 %left ','
202 %left OR
203 %left AND
204 %left '|'
205 %left '^'
206 %left '&'
207 %left EQUAL NOTEQUAL
208 %left '<' '>' LEQ GEQ
209 %left LSH RSH
210 %left '+' '-'
211 %left '*' '/' '%'
212 %right UNARY
214 /* %expect 40 */
218 start : exp1
220 expression_value = $1.value;
221 #ifdef TEST_EXP_READER
222 expression_signedp = $1.signedp;
223 #endif
227 /* Expressions, including the comma operator. */
228 exp1 : exp
229 | exp1 ',' exp
230 { if (pedantic)
231 pedwarn ("comma operator in operand of `#if'");
232 $$ = $3; }
235 /* Expressions, not including the comma operator. */
236 exp : '-' exp %prec UNARY
237 { $$.value = - $2.value;
238 $$.signedp = $2.signedp;
239 if (($$.value & $2.value & $$.signedp) < 0)
240 integer_overflow (); }
241 | '!' exp %prec UNARY
242 { $$.value = ! $2.value;
243 $$.signedp = SIGNED; }
244 | '+' exp %prec UNARY
245 { $$ = $2; }
246 | '~' exp %prec UNARY
247 { $$.value = ~ $2.value;
248 $$.signedp = $2.signedp; }
249 | '#' NAME
250 { $$.value = check_assertion ($2.address, $2.length,
251 0, NULL_PTR);
252 $$.signedp = SIGNED; }
253 | '#' NAME
254 { keyword_parsing = 1; }
255 '(' keywords ')'
256 { $$.value = check_assertion ($2.address, $2.length,
257 1, $5);
258 keyword_parsing = 0;
259 $$.signedp = SIGNED; }
260 | '(' exp1 ')'
261 { $$ = $2; }
264 /* Binary operators in order of decreasing precedence. */
265 exp : exp '*' exp
266 { $$.signedp = $1.signedp & $3.signedp;
267 if ($$.signedp)
269 $$.value = $1.value * $3.value;
270 if ($1.value
271 && ($$.value / $1.value != $3.value
272 || ($$.value & $1.value & $3.value) < 0))
273 integer_overflow ();
275 else
276 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
277 * $3.value); }
278 | exp '/' exp
279 { if ($3.value == 0)
281 if (!skip_evaluation)
282 error ("division by zero in #if");
283 $3.value = 1;
285 $$.signedp = $1.signedp & $3.signedp;
286 if ($$.signedp)
288 $$.value = $1.value / $3.value;
289 if (($$.value & $1.value & $3.value) < 0)
290 integer_overflow ();
292 else
293 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
294 / $3.value); }
295 | exp '%' exp
296 { if ($3.value == 0)
298 if (!skip_evaluation)
299 error ("division by zero in #if");
300 $3.value = 1;
302 $$.signedp = $1.signedp & $3.signedp;
303 if ($$.signedp)
304 $$.value = $1.value % $3.value;
305 else
306 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
307 % $3.value); }
308 | exp '+' exp
309 { $$.value = $1.value + $3.value;
310 $$.signedp = $1.signedp & $3.signedp;
311 if (overflow_sum_sign ($1.value, $3.value,
312 $$.value, $$.signedp))
313 integer_overflow (); }
314 | exp '-' exp
315 { $$.value = $1.value - $3.value;
316 $$.signedp = $1.signedp & $3.signedp;
317 if (overflow_sum_sign ($$.value, $3.value,
318 $1.value, $$.signedp))
319 integer_overflow (); }
320 | exp LSH exp
321 { $$.signedp = $1.signedp;
322 if (($3.value & $3.signedp) < 0)
323 $$.value = right_shift (&$1, -$3.value);
324 else
325 $$.value = left_shift (&$1, $3.value); }
326 | exp RSH exp
327 { $$.signedp = $1.signedp;
328 if (($3.value & $3.signedp) < 0)
329 $$.value = left_shift (&$1, -$3.value);
330 else
331 $$.value = right_shift (&$1, $3.value); }
332 | exp EQUAL exp
333 { $$.value = ($1.value == $3.value);
334 $$.signedp = SIGNED; }
335 | exp NOTEQUAL exp
336 { $$.value = ($1.value != $3.value);
337 $$.signedp = SIGNED; }
338 | exp LEQ exp
339 { $$.signedp = SIGNED;
340 if ($1.signedp & $3.signedp)
341 $$.value = $1.value <= $3.value;
342 else
343 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
344 <= $3.value); }
345 | exp GEQ exp
346 { $$.signedp = SIGNED;
347 if ($1.signedp & $3.signedp)
348 $$.value = $1.value >= $3.value;
349 else
350 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
351 >= $3.value); }
352 | exp '<' exp
353 { $$.signedp = SIGNED;
354 if ($1.signedp & $3.signedp)
355 $$.value = $1.value < $3.value;
356 else
357 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
358 < $3.value); }
359 | exp '>' exp
360 { $$.signedp = SIGNED;
361 if ($1.signedp & $3.signedp)
362 $$.value = $1.value > $3.value;
363 else
364 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
365 > $3.value); }
366 | exp '&' exp
367 { $$.value = $1.value & $3.value;
368 $$.signedp = $1.signedp & $3.signedp; }
369 | exp '^' exp
370 { $$.value = $1.value ^ $3.value;
371 $$.signedp = $1.signedp & $3.signedp; }
372 | exp '|' exp
373 { $$.value = $1.value | $3.value;
374 $$.signedp = $1.signedp & $3.signedp; }
375 | exp AND
376 { skip_evaluation += !$1.value; }
378 { skip_evaluation -= !$1.value;
379 $$.value = ($1.value && $4.value);
380 $$.signedp = SIGNED; }
381 | exp OR
382 { skip_evaluation += !!$1.value; }
384 { skip_evaluation -= !!$1.value;
385 $$.value = ($1.value || $4.value);
386 $$.signedp = SIGNED; }
387 | exp '?'
388 { skip_evaluation += !$1.value; }
389 exp ':'
390 { skip_evaluation += !!$1.value - !$1.value; }
392 { skip_evaluation -= !!$1.value;
393 $$.value = $1.value ? $4.value : $7.value;
394 $$.signedp = $4.signedp & $7.signedp; }
395 | INT
396 { $$ = yylval.integer; }
397 | CHAR
398 { $$ = yylval.integer; }
399 | NAME
400 { if (warn_undef && !skip_evaluation)
401 warning ("`%.*s' is not defined",
402 $1.length, $1.address);
403 $$.value = 0;
404 $$.signedp = SIGNED; }
407 keywords :
408 { $$ = 0; }
409 | '(' keywords ')' keywords
410 { struct arglist *temp;
411 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
412 $$->next = $2;
413 $$->name = (U_CHAR *) "(";
414 $$->length = 1;
415 temp = $$;
416 while (temp != 0 && temp->next != 0)
417 temp = temp->next;
418 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
419 temp->next->next = $4;
420 temp->next->name = (U_CHAR *) ")";
421 temp->next->length = 1; }
422 | NAME keywords
423 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
424 $$->name = $1.address;
425 $$->length = $1.length;
426 $$->next = $2; }
430 /* During parsing of a C expression, the pointer to the next character
431 is in this variable. */
433 static char *lexptr;
435 /* Take care of parsing a number (anything that starts with a digit).
436 Set yylval and return the token type; update lexptr.
437 LEN is the number of characters in it. */
439 /* maybe needs to actually deal with floating point numbers */
441 static int
442 parse_number (olen)
443 int olen;
445 register char *p = lexptr;
446 register int c;
447 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
448 register int base = 10;
449 register int len = olen;
450 register int overflow = 0;
451 register int digit, largest_digit = 0;
452 int spec_long = 0;
454 yylval.integer.signedp = SIGNED;
456 if (*p == '0') {
457 base = 8;
458 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
459 p += 2;
460 base = 16;
461 len -= 2;
465 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
467 for (; len > 0; len--) {
468 c = *p++;
470 if (c >= '0' && c <= '9')
471 digit = c - '0';
472 else if (base == 16 && c >= 'a' && c <= 'f')
473 digit = c - 'a' + 10;
474 else if (base == 16 && c >= 'A' && c <= 'F')
475 digit = c - 'A' + 10;
476 else {
477 /* `l' means long, and `u' means unsigned. */
478 while (1) {
479 if (c == 'l' || c == 'L')
481 if (!pedantic < spec_long)
482 yyerror ("too many `l's in integer constant");
483 spec_long++;
485 else if (c == 'u' || c == 'U')
487 if (! yylval.integer.signedp)
488 yyerror ("two `u's in integer constant");
489 yylval.integer.signedp = UNSIGNED;
491 else {
492 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
493 yyerror ("Floating point numbers not allowed in #if expressions");
494 else {
495 char *buf = (char *) alloca (p - lexptr + 40);
496 sprintf (buf, "missing white space after number `%.*s'",
497 (int) (p - lexptr - 1), lexptr);
498 yyerror (buf);
502 if (--len == 0)
503 break;
504 c = *p++;
506 /* Don't look for any more digits after the suffixes. */
507 break;
509 if (largest_digit < digit)
510 largest_digit = digit;
511 nd = n * base + digit;
512 overflow |= (max_over_base < n) | (nd < n);
513 n = nd;
516 if (base <= largest_digit)
517 pedwarn ("integer constant contains digits beyond the radix");
519 if (overflow)
520 pedwarn ("integer constant out of range");
522 /* If too big to be signed, consider it unsigned. */
523 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
525 if (base == 10)
526 warning ("integer constant is so large that it is unsigned");
527 yylval.integer.signedp = UNSIGNED;
530 lexptr = p;
531 yylval.integer.value = n;
532 return INT;
535 struct token {
536 char *operator;
537 int token;
540 static struct token tokentab2[] = {
541 {"&&", AND},
542 {"||", OR},
543 {"<<", LSH},
544 {">>", RSH},
545 {"==", EQUAL},
546 {"!=", NOTEQUAL},
547 {"<=", LEQ},
548 {">=", GEQ},
549 {"++", ERROR},
550 {"--", ERROR},
551 {NULL, ERROR}
554 /* Read one token, getting characters through lexptr. */
556 static int
557 yylex ()
559 register int c;
560 register int namelen;
561 register unsigned char *tokstart;
562 register struct token *toktab;
563 int wide_flag;
564 HOST_WIDE_INT mask;
566 retry:
568 tokstart = (unsigned char *) lexptr;
569 c = *tokstart;
570 /* See if it is a special token of length 2. */
571 if (! keyword_parsing)
572 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
573 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
574 lexptr += 2;
575 if (toktab->token == ERROR)
577 char *buf = (char *) alloca (40);
578 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
579 yyerror (buf);
581 return toktab->token;
584 switch (c) {
585 case '\n':
586 return 0;
588 case ' ':
589 case '\t':
590 case '\r':
591 lexptr++;
592 goto retry;
594 case 'L':
595 /* Capital L may start a wide-string or wide-character constant. */
596 if (lexptr[1] == '\'')
598 lexptr++;
599 wide_flag = 1;
600 mask = MAX_WCHAR_TYPE_MASK;
601 goto char_constant;
603 if (lexptr[1] == '"')
605 lexptr++;
606 wide_flag = 1;
607 mask = MAX_WCHAR_TYPE_MASK;
608 goto string_constant;
610 break;
612 case '\'':
613 wide_flag = 0;
614 mask = MAX_CHAR_TYPE_MASK;
615 char_constant:
616 lexptr++;
617 if (keyword_parsing) {
618 char *start_ptr = lexptr - 1;
619 while (1) {
620 c = *lexptr++;
621 if (c == '\\')
622 c = parse_escape (&lexptr, mask);
623 else if (c == '\'')
624 break;
626 yylval.name.address = tokstart;
627 yylval.name.length = lexptr - start_ptr;
628 return NAME;
631 /* This code for reading a character constant
632 handles multicharacter constants and wide characters.
633 It is mostly copied from c-lex.c. */
635 register HOST_WIDE_INT result = 0;
636 register int num_chars = 0;
637 int chars_seen = 0;
638 unsigned width = MAX_CHAR_TYPE_SIZE;
639 int max_chars;
640 #ifdef MULTIBYTE_CHARS
641 int longest_char = local_mb_cur_max ();
642 char *token_buffer = (char *) alloca (longest_char);
643 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
644 #endif
646 max_chars = MAX_LONG_TYPE_SIZE / width;
647 if (wide_flag)
648 width = MAX_WCHAR_TYPE_SIZE;
650 while (1)
652 c = *lexptr++;
654 if (c == '\'' || c == EOF)
655 break;
657 ++chars_seen;
658 if (c == '\\')
660 c = parse_escape (&lexptr, mask);
662 else
664 #ifdef MULTIBYTE_CHARS
665 wchar_t wc;
666 int i;
667 int char_len = -1;
668 for (i = 1; i <= longest_char; ++i)
670 token_buffer[i - 1] = c;
671 char_len = local_mbtowc (& wc, token_buffer, i);
672 if (char_len != -1)
673 break;
674 c = *lexptr++;
676 if (char_len > 1)
678 /* mbtowc sometimes needs an extra char before accepting */
679 if (char_len < i)
680 lexptr--;
681 if (! wide_flag)
683 /* Merge character into result; ignore excess chars. */
684 for (i = 1; i <= char_len; ++i)
686 if (i > max_chars)
687 break;
688 if (width < HOST_BITS_PER_INT)
689 result = (result << width)
690 | (token_buffer[i - 1]
691 & ((1 << width) - 1));
692 else
693 result = token_buffer[i - 1];
695 num_chars += char_len;
696 continue;
699 else
701 if (char_len == -1)
702 warning ("Ignoring invalid multibyte character");
704 if (wide_flag)
705 c = wc;
706 #endif /* ! MULTIBYTE_CHARS */
709 if (wide_flag)
711 if (chars_seen == 1) /* only keep the first one */
712 result = c;
713 continue;
716 /* Merge character into result; ignore excess chars. */
717 num_chars++;
718 if (num_chars <= max_chars)
720 if (width < HOST_BITS_PER_INT)
721 result = (result << width) | (c & ((1 << width) - 1));
722 else
723 result = c;
727 if (c != '\'')
728 error ("malformatted character constant");
729 else if (chars_seen == 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 (chars_seen != 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;
743 if (num_bits == 0)
744 /* We already got an error; avoid invalid shift. */
745 yylval.integer.value = 0;
746 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
747 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
748 || ((result >> (num_bits - 1)) & 1) == 0)
749 yylval.integer.value
750 = result & (~ (unsigned_HOST_WIDE_INT) 0
751 >> (HOST_BITS_PER_WIDE_INT - num_bits));
752 else
753 yylval.integer.value
754 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
755 >> (HOST_BITS_PER_WIDE_INT - num_bits));
757 else
759 yylval.integer.value = result;
763 /* This is always a signed type. */
764 yylval.integer.signedp = SIGNED;
766 return CHAR;
768 /* some of these chars are invalid in constant expressions;
769 maybe do something about them later */
770 case '/':
771 case '+':
772 case '-':
773 case '*':
774 case '%':
775 case '|':
776 case '&':
777 case '^':
778 case '~':
779 case '!':
780 case '@':
781 case '<':
782 case '>':
783 case '[':
784 case ']':
785 case '.':
786 case '?':
787 case ':':
788 case '=':
789 case '{':
790 case '}':
791 case ',':
792 case '#':
793 if (keyword_parsing)
794 break;
795 case '(':
796 case ')':
797 lexptr++;
798 return c;
800 case '"':
801 mask = MAX_CHAR_TYPE_MASK;
802 string_constant:
803 if (keyword_parsing) {
804 char *start_ptr = lexptr;
805 lexptr++;
806 while (1) {
807 c = *lexptr++;
808 if (c == '\\')
809 c = parse_escape (&lexptr, mask);
810 else if (c == '"')
811 break;
813 yylval.name.address = tokstart;
814 yylval.name.length = lexptr - start_ptr;
815 return NAME;
817 yyerror ("string constants not allowed in #if expressions");
818 return ERROR;
821 if (c >= '0' && c <= '9' && !keyword_parsing) {
822 /* It's a number */
823 for (namelen = 1; ; namelen++) {
824 int d = tokstart[namelen];
825 if (! ((is_idchar[d] || d == '.')
826 || ((d == '-' || d == '+')
827 && (c == 'e' || c == 'E'
828 || ((c == 'p' || c == 'P') && ! c89))
829 && ! traditional)))
830 break;
831 c = d;
833 return parse_number (namelen);
836 /* It is a name. See how long it is. */
838 if (keyword_parsing) {
839 for (namelen = 0;; namelen++) {
840 if (is_space[tokstart[namelen]])
841 break;
842 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
843 break;
844 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
845 break;
847 } else {
848 if (!is_idstart[c]) {
849 yyerror ("Invalid token in expression");
850 return ERROR;
853 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
857 lexptr += namelen;
858 yylval.name.address = tokstart;
859 yylval.name.length = namelen;
860 return NAME;
864 /* Parse a C escape sequence. STRING_PTR points to a variable
865 containing a pointer to the string to parse. That pointer
866 is updated past the characters we use. The value of the
867 escape sequence is returned.
869 RESULT_MASK is used to mask out the result;
870 an error is reported if bits are lost thereby.
872 A negative value means the sequence \ newline was seen,
873 which is supposed to be equivalent to nothing at all.
875 If \ is followed by a null character, we return a negative
876 value and leave the string pointer pointing at the null character.
878 If \ is followed by 000, we return 0 and leave the string pointer
879 after the zeros. A value of 0 does not mean end of string. */
881 HOST_WIDE_INT
882 parse_escape (string_ptr, result_mask)
883 char **string_ptr;
884 HOST_WIDE_INT result_mask;
886 register int c = *(*string_ptr)++;
887 switch (c)
889 case 'a':
890 return TARGET_BELL;
891 case 'b':
892 return TARGET_BS;
893 case 'e':
894 case 'E':
895 if (pedantic)
896 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
897 return 033;
898 case 'f':
899 return TARGET_FF;
900 case 'n':
901 return TARGET_NEWLINE;
902 case 'r':
903 return TARGET_CR;
904 case 't':
905 return TARGET_TAB;
906 case 'v':
907 return TARGET_VT;
908 case '\n':
909 return -2;
910 case 0:
911 (*string_ptr)--;
912 return 0;
914 case '0':
915 case '1':
916 case '2':
917 case '3':
918 case '4':
919 case '5':
920 case '6':
921 case '7':
923 register HOST_WIDE_INT i = c - '0';
924 register int count = 0;
925 while (++count < 3)
927 c = *(*string_ptr)++;
928 if (c >= '0' && c <= '7')
929 i = (i << 3) + c - '0';
930 else
932 (*string_ptr)--;
933 break;
936 if (i != (i & result_mask))
938 i &= result_mask;
939 pedwarn ("octal escape sequence out of range");
941 return i;
943 case 'x':
945 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
946 register int digits_found = 0, digit;
947 for (;;)
949 c = *(*string_ptr)++;
950 if (c >= '0' && c <= '9')
951 digit = c - '0';
952 else if (c >= 'a' && c <= 'f')
953 digit = c - 'a' + 10;
954 else if (c >= 'A' && c <= 'F')
955 digit = c - 'A' + 10;
956 else
958 (*string_ptr)--;
959 break;
961 overflow |= i ^ (i << 4 >> 4);
962 i = (i << 4) + digit;
963 digits_found = 1;
965 if (!digits_found)
966 yyerror ("\\x used with no following hex digits");
967 if (overflow | (i != (i & result_mask)))
969 i &= result_mask;
970 pedwarn ("hex escape sequence out of range");
972 return i;
974 default:
975 return c;
979 static void
980 yyerror (s)
981 char *s;
983 error ("%s", s);
984 skip_evaluation = 0;
985 longjmp (parse_return_error, 1);
988 static void
989 integer_overflow ()
991 if (!skip_evaluation && pedantic)
992 pedwarn ("integer overflow in preprocessor expression");
995 static HOST_WIDE_INT
996 left_shift (a, b)
997 struct constant *a;
998 unsigned_HOST_WIDE_INT b;
1000 /* It's unclear from the C standard whether shifts can overflow.
1001 The following code ignores overflow; perhaps a C standard
1002 interpretation ruling is needed. */
1003 if (b >= HOST_BITS_PER_WIDE_INT)
1004 return 0;
1005 else
1006 return (unsigned_HOST_WIDE_INT) a->value << b;
1009 static HOST_WIDE_INT
1010 right_shift (a, b)
1011 struct constant *a;
1012 unsigned_HOST_WIDE_INT b;
1014 if (b >= HOST_BITS_PER_WIDE_INT)
1015 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1016 else if (a->signedp)
1017 return a->value >> b;
1018 else
1019 return (unsigned_HOST_WIDE_INT) a->value >> b;
1022 /* This page contains the entry point to this file. */
1024 /* Parse STRING as an expression, and complain if this fails
1025 to use up all of the contents of STRING.
1026 STRING may contain '\0' bytes; it is terminated by the first '\n'
1027 outside a string constant, so that we can diagnose '\0' properly.
1028 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1029 We do not support C comments. They should be removed before
1030 this function is called. */
1032 HOST_WIDE_INT
1033 parse_c_expression (string, warn_undefined)
1034 char *string;
1035 int warn_undefined;
1037 lexptr = string;
1038 warn_undef = warn_undefined;
1040 /* if there is some sort of scanning error, just return 0 and assume
1041 the parsing routine has printed an error message somewhere.
1042 there is surely a better thing to do than this. */
1043 if (setjmp (parse_return_error))
1044 return 0;
1046 if (yyparse () != 0)
1047 abort ();
1049 if (*lexptr != '\n')
1050 error ("Junk after end of expression.");
1052 return expression_value; /* set by yyparse () */
1055 #ifdef TEST_EXP_READER
1057 #if YYDEBUG
1058 extern int yydebug;
1059 #endif
1061 int pedantic;
1062 int traditional;
1064 int main PROTO((int, char **));
1065 static void initialize_random_junk PROTO((void));
1066 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1068 /* Main program for testing purposes. */
1070 main (argc, argv)
1071 int argc;
1072 char **argv;
1074 int n, c;
1075 char buf[1024];
1076 unsigned_HOST_WIDE_INT u;
1078 pedantic = 1 < argc;
1079 traditional = 2 < argc;
1080 #if YYDEBUG
1081 yydebug = 3 < argc;
1082 #endif
1083 initialize_random_junk ();
1085 for (;;) {
1086 printf ("enter expression: ");
1087 n = 0;
1088 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1089 n++;
1090 if (c == EOF)
1091 break;
1092 parse_c_expression (buf, 1);
1093 printf ("parser returned ");
1094 u = (unsigned_HOST_WIDE_INT) expression_value;
1095 if (expression_value < 0 && expression_signedp) {
1096 u = -u;
1097 printf ("-");
1099 if (u == 0)
1100 printf ("0");
1101 else
1102 print_unsigned_host_wide_int (u);
1103 if (! expression_signedp)
1104 printf("u");
1105 printf ("\n");
1108 return 0;
1111 static void
1112 print_unsigned_host_wide_int (u)
1113 unsigned_HOST_WIDE_INT u;
1115 if (u) {
1116 print_unsigned_host_wide_int (u / 10);
1117 putchar ('0' + (int) (u % 10));
1121 /* table to tell if char can be part of a C identifier. */
1122 unsigned char is_idchar[256];
1123 /* table to tell if char can be first char of a c identifier. */
1124 unsigned char is_idstart[256];
1125 /* table to tell if c is horizontal or vertical space. */
1126 unsigned char is_space[256];
1129 * initialize random junk in the hash table and maybe other places
1131 static void
1132 initialize_random_junk ()
1134 register int i;
1137 * Set up is_idchar and is_idstart tables. These should be
1138 * faster than saying (is_alpha (c) || c == '_'), etc.
1139 * Must do set up these things before calling any routines tthat
1140 * refer to them.
1142 for (i = 'a'; i <= 'z'; i++) {
1143 ++is_idchar[i - 'a' + 'A'];
1144 ++is_idchar[i];
1145 ++is_idstart[i - 'a' + 'A'];
1146 ++is_idstart[i];
1148 for (i = '0'; i <= '9'; i++)
1149 ++is_idchar[i];
1150 ++is_idchar['_'];
1151 ++is_idstart['_'];
1152 ++is_idchar['$'];
1153 ++is_idstart['$'];
1155 ++is_space[' '];
1156 ++is_space['\t'];
1157 ++is_space['\v'];
1158 ++is_space['\f'];
1159 ++is_space['\n'];
1160 ++is_space['\r'];
1163 void
1164 error VPROTO ((char * msg, ...))
1166 #ifndef ANSI_PROTOTYPES
1167 char * msg;
1168 #endif
1169 va_list args;
1171 VA_START (args, msg);
1173 #ifndef ANSI_PROTOTYPES
1174 msg = va_arg (args, char *);
1175 #endif
1177 fprintf (stderr, "error: ");
1178 vfprintf (stderr, msg, args);
1179 fprintf (stderr, "\n");
1180 va_end (args);
1183 void
1184 pedwarn VPROTO ((char * msg, ...))
1186 #ifndef ANSI_PROTOTYPES
1187 char * msg;
1188 #endif
1189 va_list args;
1191 VA_START (args, msg);
1193 #ifndef ANSI_PROTOTYPES
1194 msg = va_arg (args, char *);
1195 #endif
1197 fprintf (stderr, "pedwarn: ");
1198 vfprintf (stderr, msg, args);
1199 fprintf (stderr, "\n");
1200 va_end (args);
1203 void
1204 warning VPROTO ((char * msg, ...))
1206 #ifndef ANSI_PROTOTYPES
1207 char * msg;
1208 #endif
1209 va_list args;
1211 VA_START (args, msg);
1213 #ifndef ANSI_PROTOTYPES
1214 msg = va_arg (args, char *);
1215 #endif
1217 fprintf (stderr, "warning: ");
1218 vfprintf (stderr, msg, args);
1219 fprintf (stderr, "\n");
1220 va_end (args);
1224 check_assertion (name, sym_length, tokens_specified, tokens)
1225 U_CHAR *name;
1226 int sym_length;
1227 int tokens_specified;
1228 struct arglist *tokens;
1230 return 0;
1233 struct hashnode *
1234 lookup (name, len, hash)
1235 U_CHAR *name;
1236 int len;
1237 int hash;
1239 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1243 xmalloc (size)
1244 size_t size;
1246 return (PTR) malloc (size);
1248 #endif