OSDN Git Service

* cpplib.h (enum cpp_token): Added CPP_WCHAR and CPP_WSTRING.
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
1 /* Parse C expressions for CCCP.
2    Copyright (C) 1987, 92, 94, 95, 97, 98, 1999, 2000 Free Software Foundation.
3
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.
8
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.
13
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.
18
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!
22
23 Written by Per Bothner 1994.  */
24
25 /* Parse a C expression from text in a string  */
26    
27 #include "config.h"
28 #include "system.h"
29 #include "cpplib.h"
30
31 #ifdef MULTIBYTE_CHARS
32 #include <locale.h>
33 #endif
34
35 #ifndef CHAR_TYPE_SIZE
36 #define CHAR_TYPE_SIZE BITS_PER_UNIT
37 #endif
38
39 #ifndef INT_TYPE_SIZE
40 #define INT_TYPE_SIZE BITS_PER_WORD
41 #endif
42
43 #ifndef LONG_TYPE_SIZE
44 #define LONG_TYPE_SIZE BITS_PER_WORD
45 #endif
46
47 #ifndef WCHAR_TYPE_SIZE
48 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
49 #endif
50
51 #ifndef MAX_CHAR_TYPE_SIZE
52 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
53 #endif
54
55 #ifndef MAX_INT_TYPE_SIZE
56 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
57 #endif
58
59 #ifndef MAX_LONG_TYPE_SIZE
60 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
61 #endif
62
63 #ifndef MAX_WCHAR_TYPE_SIZE
64 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
65 #endif
66
67 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
68                             ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
69                             : ~ (HOST_WIDEST_INT) 0)
70
71 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
72                              ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
73                              : ~ (HOST_WIDEST_INT) 0)
74
75 /* Yield nonzero if adding two numbers with A's and B's signs can yield a
76    number with SUM's sign, where A, B, and SUM are all C integers.  */
77 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
78
79 static void integer_overflow PARAMS ((cpp_reader *));
80 static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT));
81 static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT));
82 static struct operation parse_number PARAMS ((cpp_reader *, U_CHAR *, U_CHAR *));
83 static struct operation parse_charconst PARAMS ((cpp_reader *, U_CHAR *, U_CHAR *));
84 static struct operation cpp_lex PARAMS ((cpp_reader *, int));
85 extern HOST_WIDEST_INT cpp_parse_expr PARAMS ((cpp_reader *));
86 static HOST_WIDEST_INT cpp_parse_escape PARAMS ((cpp_reader *, U_CHAR **, HOST_WIDEST_INT));
87
88 #define ERROR 299
89 #define OROR 300
90 #define ANDAND 301
91 #define EQUAL 302
92 #define NOTEQUAL 303
93 #define LEQ 304
94 #define GEQ 305
95 #define LSH 306
96 #define RSH 307
97 #define NAME 308
98 #define INT 309
99 #define CHAR 310
100
101 #define LEFT_OPERAND_REQUIRED 1
102 #define RIGHT_OPERAND_REQUIRED 2
103 #define HAVE_VALUE 4
104 /* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the
105    following operand should be short-circuited instead of evaluated.  */
106 #define SKIP_OPERAND 8
107 /*#define UNSIGNEDP 16*/
108
109 struct operation {
110     short op;
111     char rprio; /* Priority of op (relative to it right operand).  */
112     char flags;
113     char unsignedp;    /* true if value should be treated as unsigned */
114     HOST_WIDEST_INT value;        /* The value logically "right" of op.  */
115 };
116
117 /* Parse and convert an integer for #if.  Accepts decimal, hex, or octal
118    with or without size suffixes.  */
119
120 static struct operation
121 parse_number (pfile, start, end)
122      cpp_reader *pfile;
123      U_CHAR *start;
124      U_CHAR *end;
125 {
126   struct operation op;
127   U_CHAR *p = start;
128   int c;
129   unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base;
130   int base = 10;
131   int overflow = 0;
132   int digit, largest_digit = 0;
133   int spec_long = 0;
134
135   op.unsignedp = 0;
136
137   if (p[0] == '0')
138     {
139       if (end - start >= 3 && (p[1] == 'x' || p[1] == 'X'))
140         {
141           p += 2;
142           base = 16;
143         }
144       else
145         {
146           p += 1;
147           base = 8;
148         }
149     }
150
151   /* Some buggy compilers (e.g. MPW C) seem to need both casts.  */
152   MAX_over_base = (((unsigned HOST_WIDEST_INT) -1)
153                    / ((unsigned HOST_WIDEST_INT) base));
154
155   while (p < end)
156     {
157       c = *p++;
158
159       if (c >= '0' && c <= '9')
160         digit = c - '0';
161       else if (base == 16 && c >= 'a' && c <= 'f') /* FIXME: assumes ASCII */
162         digit = c - 'a' + 10;
163       else if (base == 16 && c >= 'A' && c <= 'F')
164         digit = c - 'A' + 10;
165       else if (c == '.')
166         {
167           /* It's a float since it contains a point.  */
168           cpp_error (pfile,
169                 "floating point numbers are not allowed in #if expressions");
170           goto error;
171         }
172       else
173         {
174           /* `l' means long, and `u' means unsigned.  */
175           for (;;)
176             {
177               if (c == 'l' || c == 'L')
178                   spec_long++;
179               else if (c == 'u' || c == 'U')
180                   op.unsignedp++;
181               else
182                 {
183                   /* Decrement p here so that the error for an invalid number
184                      will be generated below in the case where this is the
185                      last character in the buffer.  */
186                   p--;
187                   break;
188                 }
189               if (p == end)
190                 break;
191               c = *p++;
192             }
193           /* Don't look for any more digits after the suffixes.  */
194           break;
195         }
196       
197       if (largest_digit < digit)
198         largest_digit = digit;
199       nd = n * base + digit;
200       overflow |= MAX_over_base < n || nd < n;
201       n = nd;
202     }
203
204   if (p != end)
205     {
206       cpp_error (pfile, "invalid number in #if expression");
207       goto error;
208     }
209   else if (spec_long > (CPP_OPTIONS (pfile)->c89 ? 1 : 2))
210     {
211       cpp_error (pfile, "too many `l' suffixes in integer constant");
212       goto error;
213     }
214   else if (op.unsignedp > 1)
215     {
216       cpp_error (pfile, "too many `u' suffixes in integer constant");
217       goto error;
218     }
219   
220   if (base <= largest_digit)
221     cpp_pedwarn (pfile, "integer constant contains digits beyond the radix");
222
223   if (overflow)
224     cpp_pedwarn (pfile, "integer constant out of range");
225
226   /* If too big to be signed, consider it unsigned.  */
227   else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp)
228     {
229       if (base == 10)
230         cpp_warning (pfile,
231                      "integer constant is so large that it is unsigned");
232       op.unsignedp = 1;
233     }
234
235   op.value = n;
236   op.op = INT;
237   return op;
238
239  error:
240   op.op = ERROR;
241   return op;
242 }
243
244 /* Parse and convert a character constant for #if.  Understands backslash
245    escapes (\n, \031) and multibyte characters (if so configured).  */
246 static struct operation
247 parse_charconst (pfile, start, end)
248      cpp_reader *pfile;
249      U_CHAR *start;
250      U_CHAR *end;
251 {
252   struct operation op;
253   HOST_WIDEST_INT result = 0;
254   int num_chars = 0;
255   int num_bits;
256   unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK;
257   int max_chars;
258   U_CHAR *ptr = start;
259
260   /* FIXME: Should use reentrant multibyte functions.  */
261 #ifdef MULTIBYTE_CHARS
262   wchar_t c = (wchar_t)-1;
263   (void) mbtowc (NULL_PTR, NULL_PTR, 0);
264 #else
265   int c = -1;
266 #endif
267
268   if (*ptr == 'L')
269     {
270       ++ptr;
271       width = MAX_WCHAR_TYPE_SIZE, mask = MAX_WCHAR_TYPE_MASK;
272     }
273   max_chars = MAX_LONG_TYPE_SIZE / width;
274
275   ++ptr;  /* skip initial quote */
276
277   while (ptr < end)
278     {
279 #ifndef MULTIBYTE_CHARS
280       c = *ptr++;
281 #else
282       ptr += mbtowc (&c, ptr, end - ptr);
283 #endif
284       if (c == '\'' || c == '\0')
285         break;
286       else if (c == '\\')
287         {
288           /* Hopefully valid assumption: if mbtowc returns a backslash,
289              we are in initial shift state.  No valid escape-sequence
290              character can take us out of initial shift state or begin
291              an unshifted multibyte char, so cpp_parse_escape doesn't
292              need to know about multibyte chars.  */
293
294           c = cpp_parse_escape (pfile, &ptr, mask);
295           if (width < HOST_BITS_PER_INT
296               && (unsigned int) c >= (unsigned int)(1 << width))
297             cpp_pedwarn (pfile, "escape sequence out of range for character");
298         }
299           
300       /* Merge character into result; ignore excess chars.  */
301       if (++num_chars <= max_chars)
302         {
303           if (width < HOST_BITS_PER_INT)
304             result = (result << width) | (c & ((1 << width) - 1));
305           else
306             result = c;
307         }
308     }
309
310   if (num_chars == 0)
311     {
312       cpp_error (pfile, "empty character constant");
313       goto error;
314     }
315   else if (c != '\'')
316     {
317       /* cpp_get_token has already emitted an error if !traditional. */
318       if (! CPP_TRADITIONAL (pfile))
319         cpp_error (pfile, "malformatted character constant");
320       goto error;
321     }
322   else if (num_chars > max_chars)
323     {
324       cpp_error (pfile, "character constant too long");
325       goto error;
326     }
327   else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
328     cpp_warning (pfile, "multi-character character constant");
329
330   /* If char type is signed, sign-extend the constant.  */
331   num_bits = num_chars * width;
332       
333   if (cpp_defined (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
334                    sizeof ("__CHAR_UNSIGNED__")-1)
335       || ((result >> (num_bits - 1)) & 1) == 0)
336     op.value = result & ((unsigned HOST_WIDEST_INT) ~0
337                          >> (HOST_BITS_PER_WIDEST_INT - num_bits));
338   else
339     op.value = result | ~((unsigned HOST_WIDEST_INT) ~0
340                           >> (HOST_BITS_PER_WIDEST_INT - num_bits));
341
342   /* This is always a signed type.  */
343   op.unsignedp = 0;
344   op.op = CHAR;
345   return op;
346
347  error:
348   op.op = ERROR;
349   return op;
350 }
351
352
353 struct token {
354   const char *operator;
355   int token;
356 };
357
358 static struct token tokentab2[] = {
359   {"&&", ANDAND},
360   {"||", OROR},
361   {"<<", LSH},
362   {">>", RSH},
363   {"==", EQUAL},
364   {"!=", NOTEQUAL},
365   {"<=", LEQ},
366   {">=", GEQ},
367   {"++", ERROR},
368   {"--", ERROR},
369   {NULL, ERROR}
370 };
371
372 /* Read one token.  */
373
374 static struct operation
375 cpp_lex (pfile, skip_evaluation)
376      cpp_reader *pfile;
377      int skip_evaluation;
378 {
379   struct token *toktab;
380   enum cpp_token token;
381   struct operation op;
382   U_CHAR *tok_start, *tok_end;
383   long old_written;
384
385   old_written = CPP_WRITTEN (pfile);
386   token = get_directive_token (pfile);
387
388   tok_start = pfile->token_buffer + old_written;
389   tok_end = CPP_PWRITTEN (pfile);
390   CPP_SET_WRITTEN (pfile, old_written);
391   switch (token)
392   {
393     case CPP_EOF: /* Should not happen ...  */
394     case CPP_VSPACE:
395       op.op = 0;
396       return op;
397     case CPP_NUMBER:
398       return parse_number (pfile, tok_start, tok_end);
399     case CPP_STRING:
400     case CPP_WSTRING:
401       cpp_error (pfile, "string constants are not allowed in #if expressions");
402       op.op = ERROR;
403       return op;
404
405     case CPP_CHAR:
406     case CPP_WCHAR:
407       return parse_charconst (pfile, tok_start, tok_end);
408
409     case CPP_NAME:
410       op.op = INT;
411       op.unsignedp = 0;
412       op.value = 0;
413       if (strcmp (tok_start, "defined"))
414         {
415           if (CPP_WARN_UNDEF (pfile) && !skip_evaluation)
416             cpp_warning (pfile, "`%.*s' is not defined",
417                          (int) (tok_end - tok_start), tok_start);
418         }
419       else
420         {
421           int paren = 0, len;
422           U_CHAR *tok;
423
424           pfile->no_macro_expand++;
425           token = get_directive_token (pfile);
426           if (token == CPP_LPAREN)
427             {
428               paren++;
429               CPP_SET_WRITTEN (pfile, old_written);
430               token = get_directive_token (pfile);
431             }
432
433           if (token != CPP_NAME)
434             goto oops;
435
436           tok = pfile->token_buffer + old_written;
437           len = CPP_PWRITTEN (pfile) - tok;
438           if (cpp_defined (pfile, tok, len))
439             op.value = 1;
440
441           if (paren)
442             {
443               if (get_directive_token (pfile) != CPP_RPAREN)
444                 goto oops;
445             }
446           CPP_SET_WRITTEN (pfile, old_written);
447           pfile->no_macro_expand--;
448         }
449       return op;
450
451     oops:
452       CPP_SET_WRITTEN (pfile, old_written);
453       pfile->no_macro_expand--;
454       cpp_error (pfile, "`defined' without an identifier");
455       return op;
456
457     case CPP_OTHER:
458       /* See if it is a special token of length 2.  */
459       if (tok_start + 2 == tok_end)
460         {
461           for (toktab = tokentab2; toktab->operator != NULL; toktab++)
462             if (tok_start[0] == toktab->operator[0]
463                 && tok_start[1] == toktab->operator[1])
464                 break;
465           if (toktab->token == ERROR)
466             cpp_error (pfile, "`%s' not allowed in operand of `#if'",
467                        tok_start);
468           op.op = toktab->token; 
469           return op;
470         }
471       else if (tok_start + 1 == tok_end && *tok_start == '#')
472         {
473           CPP_FORWARD (CPP_BUFFER (pfile), -1);
474           op.op = INT;
475           op.value = cpp_read_check_assertion (pfile);
476           return op;
477         }
478       /* fall through */
479     default:
480       op.op = *tok_start;
481       return op;
482   }
483 }
484
485
486 /* Parse a C escape sequence.  STRING_PTR points to a variable
487    containing a pointer to the string to parse.  That pointer
488    is updated past the characters we use.  The value of the
489    escape sequence is returned.
490
491    A negative value means the sequence \ newline was seen,
492    which is supposed to be equivalent to nothing at all.
493
494    If \ is followed by a null character, we return a negative
495    value and leave the string pointer pointing at the null character.
496
497    If \ is followed by 000, we return 0 and leave the string pointer
498    after the zeros.  A value of 0 does not mean end of string.  */
499
500 static HOST_WIDEST_INT
501 cpp_parse_escape (pfile, string_ptr, result_mask)
502      cpp_reader *pfile;
503      U_CHAR **string_ptr;
504      HOST_WIDEST_INT result_mask;
505 {
506   register int c = *(*string_ptr)++;
507   switch (c)
508     {
509     case 'a':
510       return TARGET_BELL;
511     case 'b':
512       return TARGET_BS;
513     case 'e':
514     case 'E':
515       if (CPP_OPTIONS (pfile)->pedantic)
516         cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
517       return TARGET_ESC;
518     case 'f':
519       return TARGET_FF;
520     case 'n':
521       return TARGET_NEWLINE;
522     case 'r':
523       return TARGET_CR;
524     case 't':
525       return TARGET_TAB;
526     case 'v':
527       return TARGET_VT;
528     case '\n':
529       return -2;
530     case 0:
531       (*string_ptr)--;
532       return 0;
533       
534     case '0':
535     case '1':
536     case '2':
537     case '3':
538     case '4':
539     case '5':
540     case '6':
541     case '7':
542       {
543         register HOST_WIDEST_INT i = c - '0';
544         register int count = 0;
545         while (++count < 3)
546           {
547             c = *(*string_ptr)++;
548             if (c >= '0' && c <= '7')
549               i = (i << 3) + c - '0';
550             else
551               {
552                 (*string_ptr)--;
553                 break;
554               }
555           }
556         if (i != (i & result_mask))
557           {
558             i &= result_mask;
559             cpp_pedwarn (pfile, "octal escape sequence out of range");
560           }
561         return i;
562       }
563     case 'x':
564       {
565         register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
566         register int digits_found = 0, digit;
567         for (;;)
568           {
569             c = *(*string_ptr)++;
570             if (c >= '0' && c <= '9')
571               digit = c - '0';
572             else if (c >= 'a' && c <= 'f')
573               digit = c - 'a' + 10;
574             else if (c >= 'A' && c <= 'F')
575               digit = c - 'A' + 10;
576             else
577               {
578                 (*string_ptr)--;
579                 break;
580               }
581             overflow |= i ^ (i << 4 >> 4);
582             i = (i << 4) + digit;
583             digits_found = 1;
584           }
585         if (!digits_found)
586           cpp_error (pfile, "\\x used with no following hex digits");
587         if (overflow | (i != (i & result_mask)))
588           {
589             i &= result_mask;
590             cpp_pedwarn (pfile, "hex escape sequence out of range");
591           }
592         return i;
593       }
594     default:
595       return c;
596     }
597 }
598
599 static void
600 integer_overflow (pfile)
601      cpp_reader *pfile;
602 {
603   if (CPP_PEDANTIC (pfile))
604     cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
605 }
606
607 static HOST_WIDEST_INT
608 left_shift (pfile, a, unsignedp, b)
609      cpp_reader *pfile;
610      HOST_WIDEST_INT a;
611      int unsignedp;
612      unsigned HOST_WIDEST_INT b;
613 {
614   if (b >= HOST_BITS_PER_WIDEST_INT)
615     {
616       if (! unsignedp && a != 0)
617         integer_overflow (pfile);
618       return 0;
619     }
620   else if (unsignedp)
621     return (unsigned HOST_WIDEST_INT) a << b;
622   else
623     {
624       HOST_WIDEST_INT l = a << b;
625       if (l >> b != a)
626         integer_overflow (pfile);
627       return l;
628     }
629 }
630
631 static HOST_WIDEST_INT
632 right_shift (pfile, a, unsignedp, b)
633      cpp_reader *pfile ATTRIBUTE_UNUSED;
634      HOST_WIDEST_INT a;
635      int unsignedp;
636      unsigned HOST_WIDEST_INT b;
637 {
638   if (b >= HOST_BITS_PER_WIDEST_INT)
639     return unsignedp ? 0 : a >> (HOST_BITS_PER_WIDEST_INT - 1);
640   else if (unsignedp)
641     return (unsigned HOST_WIDEST_INT) a >> b;
642   else
643     return a >> b;
644 }
645 \f
646 /* These priorities are all even, so we can handle associatively.  */
647 #define PAREN_INNER_PRIO 0
648 #define COMMA_PRIO 4
649 #define COND_PRIO (COMMA_PRIO+2)
650 #define OROR_PRIO (COND_PRIO+2)
651 #define ANDAND_PRIO (OROR_PRIO+2)
652 #define OR_PRIO (ANDAND_PRIO+2)
653 #define XOR_PRIO (OR_PRIO+2)
654 #define AND_PRIO (XOR_PRIO+2)
655 #define EQUAL_PRIO (AND_PRIO+2)
656 #define LESS_PRIO (EQUAL_PRIO+2)
657 #define SHIFT_PRIO (LESS_PRIO+2)
658 #define PLUS_PRIO (SHIFT_PRIO+2)
659 #define MUL_PRIO (PLUS_PRIO+2)
660 #define UNARY_PRIO (MUL_PRIO+2)
661 #define PAREN_OUTER_PRIO (UNARY_PRIO+2)
662
663 #define COMPARE(OP) \
664   top->unsignedp = 0;\
665   top->value = (unsigned1 || unsigned2) \
666   ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
667
668 /* Parse and evaluate a C expression, reading from PFILE.
669    Returns the value of the expression.  */
670
671 HOST_WIDEST_INT
672 cpp_parse_expr (pfile)
673      cpp_reader *pfile;
674 {
675   /* The implementation is an operator precedence parser,
676      i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
677
678      The stack base is 'stack', and the current stack pointer is 'top'.
679      There is a stack element for each operator (only),
680      and the most recently pushed operator is 'top->op'.
681      An operand (value) is stored in the 'value' field of the stack
682      element of the operator that precedes it.
683      In that case the 'flags' field has the HAVE_VALUE flag set.  */
684
685 #define INIT_STACK_SIZE 20
686   struct operation init_stack[INIT_STACK_SIZE];
687   struct operation *stack = init_stack;
688   struct operation *limit = stack + INIT_STACK_SIZE;
689   register struct operation *top = stack;
690   int lprio, rprio = 0;
691   int skip_evaluation = 0;
692
693   top->rprio = 0;
694   top->flags = 0;
695   for (;;)
696     {
697       struct operation op;
698       char flags = 0;
699
700       /* Read a token */
701       op =  cpp_lex (pfile, skip_evaluation);
702
703       /* See if the token is an operand, in which case go to set_value.
704          If the token is an operator, figure out its left and right
705          priorities, and then goto maybe_reduce.  */
706
707       switch (op.op)
708         {
709         case NAME:
710           cpp_ice (pfile, "cpp_lex returns a NAME");
711           goto syntax_error;
712         case INT:  case CHAR:
713           goto set_value;
714         case 0:
715           lprio = 0;  goto maybe_reduce;
716         case '+':  case '-':
717           if (top->flags & HAVE_VALUE)
718             {
719               lprio = PLUS_PRIO;
720               goto binop;
721             }
722           /* else fall through */
723         case '!':  case '~':
724           flags = RIGHT_OPERAND_REQUIRED;
725           rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;
726         case '*':  case '/':  case '%':
727           lprio = MUL_PRIO;  goto binop;
728         case '<':  case '>':  case LEQ:  case GEQ:
729           lprio = LESS_PRIO;  goto binop;
730         case EQUAL:  case NOTEQUAL:
731           lprio = EQUAL_PRIO;  goto binop;
732         case LSH:  case RSH:
733           lprio = SHIFT_PRIO;  goto binop;
734         case '&':  lprio = AND_PRIO;  goto binop;
735         case '^':  lprio = XOR_PRIO;  goto binop;
736         case '|':  lprio = OR_PRIO;  goto binop;
737         case ANDAND:  lprio = ANDAND_PRIO;  goto binop;
738         case OROR:  lprio = OROR_PRIO;  goto binop;
739         case ',':
740           lprio = COMMA_PRIO;  goto binop;
741         case '(':
742           lprio = PAREN_OUTER_PRIO;  rprio = PAREN_INNER_PRIO;
743           goto maybe_reduce;
744         case ')':
745           lprio = PAREN_INNER_PRIO;  rprio = PAREN_OUTER_PRIO;
746           goto maybe_reduce;
747         case ':':
748           lprio = COND_PRIO;  rprio = COND_PRIO;
749           goto maybe_reduce;
750         case '?':
751           lprio = COND_PRIO + 1;  rprio = COND_PRIO;
752           goto maybe_reduce;
753         case ERROR:
754           goto syntax_error;
755         default:
756           cpp_error (pfile, "invalid character in #if");
757           goto syntax_error;
758         }
759
760     set_value:
761       /* Push a value onto the stack.  */
762       if (top->flags & HAVE_VALUE)
763         {
764           cpp_error (pfile, "syntax error in #if");
765           goto syntax_error;
766         }
767       top->value = op.value;
768       top->unsignedp = op.unsignedp;
769       top->flags |= HAVE_VALUE;
770       continue;
771
772     binop:
773       flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
774       rprio = lprio + 1;
775
776     maybe_reduce:
777       /* Push an operator, and check if we can reduce now.  */
778       while (top->rprio > lprio)
779         {
780           HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value;
781           int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;
782           top--;
783           if ((top[1].flags & LEFT_OPERAND_REQUIRED)
784               && ! (top[0].flags & HAVE_VALUE))
785             {
786               cpp_error (pfile, "syntax error - missing left operand");
787               goto syntax_error;
788             }
789           if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
790               && ! (top[1].flags & HAVE_VALUE))
791             {
792               cpp_error (pfile, "syntax error - missing right operand");
793               goto syntax_error;
794             }
795           /* top[0].value = (top[1].op)(v1, v2);*/
796           switch (top[1].op)
797             {
798             case '+':
799               if (!(top->flags & HAVE_VALUE))
800                 { /* Unary '+' */
801                   top->value = v2;
802                   top->unsignedp = unsigned2;
803                   top->flags |= HAVE_VALUE;
804                 }
805               else
806                 {
807                   top->value = v1 + v2;
808                   top->unsignedp = unsigned1 || unsigned2;
809                   if (! top->unsignedp && ! skip_evaluation
810                       && ! possible_sum_sign (v1, v2, top->value))
811                     integer_overflow (pfile);
812                 }
813               break;
814             case '-':
815               if (!(top->flags & HAVE_VALUE))
816                 { /* Unary '-' */
817                   top->value = - v2;
818                   if (!skip_evaluation && (top->value & v2) < 0 && !unsigned2)
819                     integer_overflow (pfile);
820                   top->unsignedp = unsigned2;
821                   top->flags |= HAVE_VALUE;
822                 }
823               else
824                 { /* Binary '-' */
825                   top->value = v1 - v2;
826                   top->unsignedp = unsigned1 || unsigned2;
827                   if (! top->unsignedp && ! skip_evaluation
828                       && ! possible_sum_sign (top->value, v2, v1))
829                     integer_overflow (pfile);
830                 }
831               break;
832             case '*':
833               top->unsignedp = unsigned1 || unsigned2;
834               if (top->unsignedp)
835                 top->value = (unsigned HOST_WIDEST_INT) v1 * v2;
836               else if (!skip_evaluation)
837                 {
838                   top->value = v1 * v2;
839                   if (v1
840                       && (top->value / v1 != v2
841                           || (top->value & v1 & v2) < 0))
842                     integer_overflow (pfile);
843                 }
844               break;
845             case '/':
846               if (skip_evaluation)
847                 break;
848               if (v2 == 0)
849                 {
850                   cpp_error (pfile, "division by zero in #if");
851                   v2 = 1;
852                 }
853               top->unsignedp = unsigned1 || unsigned2;
854               if (top->unsignedp)
855                 top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
856               else
857                 {
858                   top->value = v1 / v2;
859                   if ((top->value & v1 & v2) < 0)
860                     integer_overflow (pfile);
861                 }
862               break;
863             case '%':
864               if (skip_evaluation)
865                 break;
866               if (v2 == 0)
867                 {
868                   cpp_error (pfile, "division by zero in #if");
869                   v2 = 1;
870                 }
871               top->unsignedp = unsigned1 || unsigned2;
872               if (top->unsignedp)
873                 top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
874               else
875                 top->value = v1 % v2;
876               break;
877             case '!':
878               if (top->flags & HAVE_VALUE)
879                 {
880                   cpp_error (pfile, "syntax error");
881                   goto syntax_error;
882                 }
883               top->value = ! v2;
884               top->unsignedp = 0;
885               top->flags |= HAVE_VALUE;
886               break;
887             case '~':
888               if (top->flags & HAVE_VALUE)
889                 {
890                   cpp_error (pfile, "syntax error");
891                   goto syntax_error;
892                 }
893               top->value = ~ v2;
894               top->unsignedp = unsigned2;
895               top->flags |= HAVE_VALUE;
896               break;
897             case '<':  COMPARE(<);  break;
898             case '>':  COMPARE(>);  break;
899             case LEQ:  COMPARE(<=); break;
900             case GEQ:  COMPARE(>=); break;
901             case EQUAL:
902               top->value = (v1 == v2);
903               top->unsignedp = 0;
904               break;
905             case NOTEQUAL:
906               top->value = (v1 != v2);
907               top->unsignedp = 0;
908               break;
909             case LSH:
910               if (skip_evaluation)
911                 break;
912               top->unsignedp = unsigned1;
913               if (v2 < 0 && ! unsigned2)
914                 top->value = right_shift (pfile, v1, unsigned1, -v2);
915               else
916                 top->value = left_shift (pfile, v1, unsigned1, v2);
917               break;
918             case RSH:
919               if (skip_evaluation)
920                 break;
921               top->unsignedp = unsigned1;
922               if (v2 < 0 && ! unsigned2)
923                 top->value = left_shift (pfile, v1, unsigned1, -v2);
924               else
925                 top->value = right_shift (pfile, v1, unsigned1, v2);
926               break;
927 #define LOGICAL(OP) \
928               top->value = v1 OP v2;\
929               top->unsignedp = unsigned1 || unsigned2;
930             case '&':  LOGICAL(&); break;
931             case '^':  LOGICAL(^);  break;
932             case '|':  LOGICAL(|);  break;
933             case ANDAND:
934               top->value = v1 && v2;  top->unsignedp = 0;
935               if (!v1) skip_evaluation--;
936               break;
937             case OROR:
938               top->value = v1 || v2;  top->unsignedp = 0;
939               if (v1) skip_evaluation--;
940               break;
941             case ',':
942               if (CPP_PEDANTIC (pfile))
943                 cpp_pedwarn (pfile, "comma operator in operand of `#if'");
944               top->value = v2;
945               top->unsignedp = unsigned2;
946               break;
947             case '(':  case '?':
948               cpp_error (pfile, "syntax error in #if");
949               goto syntax_error;
950             case ':':
951               if (top[0].op != '?')
952                 {
953                   cpp_error (pfile,
954                              "syntax error ':' without preceding '?'");
955                   goto syntax_error;
956                 }
957               else if (! (top[1].flags & HAVE_VALUE)
958                        || !(top[-1].flags & HAVE_VALUE)
959                        || !(top[0].flags & HAVE_VALUE))
960                 {
961                   cpp_error (pfile, "bad syntax for ?: operator");
962                   goto syntax_error;
963                 }
964               else
965                 {
966                   top--;
967                   if (top->value) skip_evaluation--;
968                   top->value = top->value ? v1 : v2;
969                   top->unsignedp = unsigned1 || unsigned2;
970                 }
971               break;
972             case ')':
973               if ((top[1].flags & HAVE_VALUE)
974                   || ! (top[0].flags & HAVE_VALUE)
975                   || top[0].op != '('
976                   || (top[-1].flags & HAVE_VALUE))
977                 {
978                   cpp_error (pfile, "mismatched parentheses in #if");
979                   goto syntax_error;
980                 }
981               else
982                 {
983                   top--;
984                   top->value = v1;
985                   top->unsignedp = unsigned1;
986                   top->flags |= HAVE_VALUE;
987                 }
988               break;
989             default:
990               if (ISGRAPH (top[1].op))
991                 cpp_error (pfile, "unimplemented operator '%c'\n", top[1].op);
992               else
993                 cpp_error (pfile, "unimplemented operator '\\%03o'\n",
994                            top[1].op);
995             }
996         }
997       if (op.op == 0)
998         {
999           if (top != stack)
1000             cpp_ice (pfile, "unbalanced stack in #if expression");
1001           if (stack != init_stack)
1002             free (stack);
1003           return top->value;
1004         }
1005       top++;
1006       
1007       /* Check for and handle stack overflow.  */
1008       if (top == limit)
1009         {
1010           struct operation *new_stack;
1011           int old_size = (char *) limit - (char *) stack;
1012           int new_size = 2 * old_size;
1013           if (stack != init_stack)
1014             new_stack = (struct operation *) xrealloc (stack, new_size);
1015           else
1016             {
1017               new_stack = (struct operation *) xmalloc (new_size);
1018               bcopy ((char *) stack, (char *) new_stack, old_size);
1019             }
1020           stack = new_stack;
1021           top = (struct operation *) ((char *) new_stack + old_size);
1022           limit = (struct operation *) ((char *) new_stack + new_size);
1023         }
1024       
1025       top->flags = flags;
1026       top->rprio = rprio;
1027       top->op = op.op;
1028       if ((op.op == OROR && top[-1].value)
1029           || (op.op == ANDAND && !top[-1].value)
1030           || (op.op == '?' && !top[-1].value))
1031         {
1032           skip_evaluation++;
1033         }
1034       else if (op.op == ':')
1035         {
1036           if (top[-2].value) /* Was condition true? */
1037             skip_evaluation++;
1038           else
1039             skip_evaluation--;
1040         }
1041     }
1042  syntax_error:
1043   if (stack != init_stack)
1044     free (stack);
1045   return 0;
1046 }