OSDN Git Service

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