OSDN Git Service

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