OSDN Git Service

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