OSDN Git Service

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