OSDN Git Service

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