OSDN Git Service

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