OSDN Git Service

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