source: trunk/third/gcc/cppexp.c @ 8834

Revision 8834, 24.1 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* Parse C expressions for CCCP.
2   Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
3
4This program is free software; you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the
6Free Software Foundation; either version 2, or (at your option) any
7later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 59 Temple Place - Suite 330,
17Boston, 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
23Written 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
30extern char *xmalloc PARAMS ((unsigned));
31extern 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.  */
41struct 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
66extern 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
104static void integer_overflow ();
105static long left_shift ();
106static 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
138struct 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
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
151struct operation
152parse_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
256struct token {
257  char *operator;
258  int token;
259};
260
261static 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
277struct operation
278cpp_lex (pfile)
279cpp_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        ++ptr;
361        while (ptr < tok_end && ((c = *ptr++) != '\''))
362          {
363            if (c == '\\')
364              {
365                c = cpp_parse_escape (pfile, &ptr);
366                if (width < HOST_BITS_PER_INT
367                  && (unsigned) c >= (1 << width))
368                    cpp_pedwarn (pfile,
369                                 "escape sequence out of range for character");
370              }
371
372            num_chars++;
373
374            /* Merge character into result; ignore excess chars.  */
375            if (num_chars < max_chars + 1)
376              {
377                if (width < HOST_BITS_PER_INT)
378                  result = (result << width) | (c & ((1 << width) - 1));
379                else
380                  result = c;
381                token_buffer[num_chars - 1] = c;
382              }
383          }
384
385        token_buffer[num_chars] = 0;
386
387        if (c != '\'')
388          cpp_error (pfile, "malformatted character constant");
389        else if (num_chars == 0)
390          cpp_error (pfile, "empty character constant");
391        else if (num_chars > max_chars)
392          {
393            num_chars = max_chars;
394            cpp_error (pfile, "character constant too long");
395          }
396        else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
397          cpp_warning (pfile, "multi-character character constant");
398
399        /* If char type is signed, sign-extend the constant.  */
400        if (! wide_flag)
401          {
402            int num_bits = num_chars * width;
403
404            if (cpp_lookup (pfile, "__CHAR_UNSIGNED__",
405                            sizeof ("__CHAR_UNSIGNED__")-1, -1)
406                || ((result >> (num_bits - 1)) & 1) == 0)
407                op.value
408                    = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
409            else
410                op.value
411                    = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
412          }
413        else
414          {
415#ifdef MULTIBYTE_CHARS
416            /* Set the initial shift state and convert the next sequence.  */
417              result = 0;
418              /* In all locales L'\0' is zero and mbtowc will return zero,
419                 so don't use it.  */
420              if (num_chars > 1
421                  || (num_chars == 1 && token_buffer[0] != '\0'))
422                {
423                  wchar_t wc;
424                  (void) mbtowc (NULL_PTR, NULL_PTR, 0);
425                  if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
426                    result = wc;
427                  else
428                    cpp_warning (pfile,"Ignoring invalid multibyte character");
429                }
430#endif
431              op.value = result;
432            }
433        }
434
435      /* This is always a signed type.  */
436      op.unsignedp = 0;
437      op.op = CHAR;
438   
439      return op;
440
441    case CPP_NAME:
442      return parse_number (pfile, "0", 0);
443
444    case CPP_OTHER:
445      /* See if it is a special token of length 2.  */
446      if (tok_start + 2 == tok_end)
447        {
448          for (toktab = tokentab2; toktab->operator != NULL; toktab++)
449            if (tok_start[0] == toktab->operator[0]
450                && tok_start[1] == toktab->operator[1])
451                break;
452          if (toktab->token == ERROR)
453            {
454              char *buf = (char *) alloca (40);
455              sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start);
456              cpp_error (pfile, buf);
457            }
458          op.op = toktab->token;
459          return op;
460        }
461      /* fall through */
462    default:
463      op.op = *tok_start;
464      return op;
465  }
466}
467
468
469/* Parse a C escape sequence.  STRING_PTR points to a variable
470   containing a pointer to the string to parse.  That pointer
471   is updated past the characters we use.  The value of the
472   escape sequence is returned.
473
474   A negative value means the sequence \ newline was seen,
475   which is supposed to be equivalent to nothing at all.
476
477   If \ is followed by a null character, we return a negative
478   value and leave the string pointer pointing at the null character.
479
480   If \ is followed by 000, we return 0 and leave the string pointer
481   after the zeros.  A value of 0 does not mean end of string.  */
482
483int
484cpp_parse_escape (pfile, string_ptr)
485     cpp_reader *pfile;
486     char **string_ptr;
487{
488  register int c = *(*string_ptr)++;
489  switch (c)
490    {
491    case 'a':
492      return TARGET_BELL;
493    case 'b':
494      return TARGET_BS;
495    case 'e':
496    case 'E':
497      if (CPP_PEDANTIC (pfile))
498        cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
499      return 033;
500    case 'f':
501      return TARGET_FF;
502    case 'n':
503      return TARGET_NEWLINE;
504    case 'r':
505      return TARGET_CR;
506    case 't':
507      return TARGET_TAB;
508    case 'v':
509      return TARGET_VT;
510    case '\n':
511      return -2;
512    case 0:
513      (*string_ptr)--;
514      return 0;
515     
516    case '0':
517    case '1':
518    case '2':
519    case '3':
520    case '4':
521    case '5':
522    case '6':
523    case '7':
524      {
525        register int i = c - '0';
526        register int count = 0;
527        while (++count < 3)
528          {
529            c = *(*string_ptr)++;
530            if (c >= '0' && c <= '7')
531              i = (i << 3) + c - '0';
532            else
533              {
534                (*string_ptr)--;
535                break;
536              }
537          }
538        if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
539          {
540            i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
541            cpp_warning (pfile,
542                          "octal character constant does not fit in a byte");
543          }
544        return i;
545      }
546    case 'x':
547      {
548        register unsigned i = 0, overflow = 0, digits_found = 0, digit;
549        for (;;)
550          {
551            c = *(*string_ptr)++;
552            if (c >= '0' && c <= '9')
553              digit = c - '0';
554            else if (c >= 'a' && c <= 'f')
555              digit = c - 'a' + 10;
556            else if (c >= 'A' && c <= 'F')
557              digit = c - 'A' + 10;
558            else
559              {
560                (*string_ptr)--;
561                break;
562              }
563            overflow |= i ^ (i << 4 >> 4);
564            i = (i << 4) + digit;
565            digits_found = 1;
566          }
567        if (!digits_found)
568          cpp_error (pfile, "\\x used with no following hex digits");
569        if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
570          {
571            i &= (1 << BITS_PER_UNIT) - 1;
572            cpp_warning (pfile,
573                         "hex character constant does not fit in a byte");
574          }
575        return i;
576      }
577    default:
578      return c;
579    }
580}
581
582static void
583integer_overflow (pfile)
584     cpp_reader *pfile;
585{
586  if (CPP_PEDANTIC (pfile))
587    cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
588}
589
590static long
591left_shift (pfile, a, unsignedp, b)
592     cpp_reader *pfile;
593     long a;
594     int unsignedp;
595     unsigned long b;
596{
597  if (b >= HOST_BITS_PER_LONG)
598    {
599      if (! unsignedp && a != 0)
600        integer_overflow (pfile);
601      return 0;
602    }
603  else if (unsignedp)
604    return (unsigned long) a << b;
605  else
606    {
607      long l = a << b;
608      if (l >> b != a)
609        integer_overflow (pfile);
610      return l;
611    }
612}
613
614static long
615right_shift (pfile, a, unsignedp, b)
616     cpp_reader *pfile;
617     long a;
618     int unsignedp;
619     unsigned long b;
620{
621  if (b >= HOST_BITS_PER_LONG)
622    return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);
623  else if (unsignedp)
624    return (unsigned long) a >> b;
625  else
626    return a >> b;
627}
628
629/* These priorities are all even, so we can handle associatively. */
630#define PAREN_INNER_PRIO 0
631#define COMMA_PRIO 4
632#define COND_PRIO (COMMA_PRIO+2)
633#define OROR_PRIO (COND_PRIO+2)
634#define ANDAND_PRIO (OROR_PRIO+2)
635#define OR_PRIO (ANDAND_PRIO+2)
636#define XOR_PRIO (OR_PRIO+2)
637#define AND_PRIO (XOR_PRIO+2)
638#define EQUAL_PRIO (AND_PRIO+2)
639#define LESS_PRIO (EQUAL_PRIO+2)
640#define SHIFT_PRIO (LESS_PRIO+2)
641#define PLUS_PRIO (SHIFT_PRIO+2)
642#define MUL_PRIO (PLUS_PRIO+2)
643#define UNARY_PRIO (MUL_PRIO+2)
644#define PAREN_OUTER_PRIO (UNARY_PRIO+2)
645
646#define COMPARE(OP) \
647  top->unsignedp = 0;\
648  top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2)
649
650/* Parse and evaluate a C expression, reading from PFILE.
651   Returns the value of the expression.  */
652
653HOST_WIDE_INT
654cpp_parse_expr (pfile)
655     cpp_reader *pfile;
656{
657  /* The implementation is an operator precedence parser,
658     i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
659
660     The stack base is 'stack', and the current stack pointer is 'top'.
661     There is a stack element for each operator (only),
662     and the most recently pushed operator is 'top->op'.
663     An operand (value) is stored in the 'value' field of the stack
664     element of the operator that precedes it.
665     In that case the 'flags' field has the HAVE_VALUE flag set.  */
666
667#define INIT_STACK_SIZE 20
668  struct operation init_stack[INIT_STACK_SIZE];
669  struct operation *stack = init_stack;
670  struct operation *limit = stack + INIT_STACK_SIZE;
671  register struct operation *top = stack;
672  int lprio, rprio;
673
674  top->rprio = 0;
675  top->flags = 0;
676  for (;;)
677    {
678      struct operation op;
679      char flags = 0;
680
681      /* Read a token */
682      op =  cpp_lex (pfile);
683
684      /* See if the token is an operand, in which case go to set_value.
685         If the token is an operator, figure out its left and right
686         priorities, and then goto maybe_reduce. */
687
688      switch (op.op)
689        {
690        case NAME:
691          top->value = 0, top->unsignedp = 0;
692          goto set_value;
693        case INT:  case CHAR:
694          top->value = op.value;
695          top->unsignedp = op.unsignedp;
696          goto set_value;
697        case 0:
698          lprio = 0;  goto maybe_reduce;
699        case '+':  case '-':
700          /* Is this correct if unary ? FIXME */
701          flags = RIGHT_OPERAND_REQUIRED;
702          lprio = PLUS_PRIO;  rprio = lprio + 1;  goto maybe_reduce;
703        case '!':  case '~':
704          flags = RIGHT_OPERAND_REQUIRED;
705          rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;
706        case '*':  case '/':  case '%':
707          lprio = MUL_PRIO;  goto binop;
708        case '<':  case '>':  case LEQ:  case GEQ:
709          lprio = LESS_PRIO;  goto binop;
710        case EQUAL:  case NOTEQUAL:
711          lprio = EQUAL_PRIO;  goto binop;
712        case LSH:  case RSH:
713          lprio = SHIFT_PRIO;  goto binop;
714        case '&':  lprio = AND_PRIO;  goto binop;
715        case '^':  lprio = XOR_PRIO;  goto binop;
716        case '|':  lprio = OR_PRIO;  goto binop;
717        case ANDAND:  lprio = ANDAND_PRIO;  goto binop;
718        case OROR:  lprio = OROR_PRIO;  goto binop;
719        case ',':
720          lprio = COMMA_PRIO;  goto binop;
721        case '(':
722          lprio = PAREN_OUTER_PRIO;  rprio = PAREN_INNER_PRIO;
723          goto maybe_reduce;
724        case ')':
725          lprio = PAREN_INNER_PRIO;  rprio = PAREN_OUTER_PRIO;
726          goto maybe_reduce;
727        case ':':
728          lprio = COND_PRIO;  rprio = COND_PRIO;
729          goto maybe_reduce;
730        case '?':
731          lprio = COND_PRIO + 1;  rprio = COND_PRIO;
732          goto maybe_reduce;
733        binop:
734          flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
735          rprio = lprio + 1;
736          goto maybe_reduce;
737        default:
738          cpp_error (pfile, "invalid character in #if");
739          goto syntax_error;
740        }
741
742    set_value:
743      /* Push a value onto the stack. */
744      if (top->flags & HAVE_VALUE)
745        {
746          cpp_error (pfile, "syntax error in #if");
747          goto syntax_error;
748        }
749      top->flags |= HAVE_VALUE;
750      continue;
751
752    maybe_reduce:
753      /* Push an operator, and check if we can reduce now. */
754      while (top->rprio > lprio)
755        {
756          long v1 = top[-1].value, v2 = top[0].value;
757          int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;
758          top--;
759          if ((top[1].flags & LEFT_OPERAND_REQUIRED)
760              && ! (top[0].flags & HAVE_VALUE))
761            {
762              cpp_error (pfile, "syntax error - missing left operand");
763              goto syntax_error;
764            }
765          if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
766              && ! (top[1].flags & HAVE_VALUE))
767            {
768              cpp_error (pfile, "syntax error - missing right operand");
769              goto syntax_error;
770            }
771          /* top[0].value = (top[1].op)(v1, v2);*/
772          switch (top[1].op)
773            {
774            case '+':
775              if (!(top->flags & HAVE_VALUE))
776                { /* Unary '+' */
777                  top->value = v2;
778                  top->unsignedp = unsigned2;
779                  top->flags |= HAVE_VALUE;
780                }
781              else
782                {
783                  top->value = v1 + v2;
784                  top->unsignedp = unsigned1 || unsigned2;
785                  if (! top->unsignedp
786                      && ! possible_sum_sign (v1, v2, top->value))
787                    integer_overflow (pfile);
788                }
789              break;
790            case '-':
791              if (!(top->flags & HAVE_VALUE))
792                { /* Unary '-' */
793                  top->value = - v2;
794                  if ((top->value & v2) < 0 && ! unsigned2)
795                    integer_overflow (pfile);
796                  top->unsignedp = unsigned2;
797                  top->flags |= HAVE_VALUE;
798                }
799              else
800                { /* Binary '-' */
801                  top->value = v1 - v2;
802                  top->unsignedp = unsigned1 || unsigned2;
803                  if (! top->unsignedp
804                      && ! possible_sum_sign (top->value, v2, v1))
805                    integer_overflow (pfile);
806                }
807              break;
808            case '*':
809              top->unsignedp = unsigned1 || unsigned2;
810              if (top->unsignedp)
811                top->value = (unsigned long) v1 * v2;
812              else
813                {
814                  top->value = v1 * v2;
815                  if (v1
816                      && (top->value / v1 != v2
817                          || (top->value & v1 & v2) < 0))
818                    integer_overflow (pfile);
819                }
820              break;
821            case '/':
822              if (v2 == 0)
823                {
824                  cpp_error (pfile, "division by zero in #if");
825                  v2 = 1;
826                }
827              top->unsignedp = unsigned1 || unsigned2;
828              if (top->unsignedp)
829                top->value = (unsigned long) v1 / v2;
830              else
831                {
832                  top->value = v1 / v2;
833                  if ((top->value & v1 & v2) < 0)
834                    integer_overflow (pfile);
835                }
836              break;
837            case '%':
838              if (v2 == 0)
839                {
840                  cpp_error (pfile, "division by zero in #if");
841                  v2 = 1;
842                }
843              top->unsignedp = unsigned1 || unsigned2;
844              if (top->unsignedp)
845                top->value = (unsigned long) v1 % v2;
846              else
847                top->value = v1 % v2;
848              break;
849            case '!':
850              if (top->flags & HAVE_VALUE)
851                {
852                  cpp_error (pfile, "syntax error");
853                  goto syntax_error;
854                }
855              top->value = ! v2;
856              top->unsignedp = 0;
857              top->flags |= HAVE_VALUE;
858              break;
859            case '~':
860              if (top->flags & HAVE_VALUE)
861                {
862                  cpp_error (pfile, "syntax error");
863                  goto syntax_error;
864                }
865              top->value = ~ v2;
866              top->unsignedp = unsigned2;
867              top->flags |= HAVE_VALUE;
868              break;
869            case '<':  COMPARE(<);  break;
870            case '>':  COMPARE(>);  break;
871            case LEQ:  COMPARE(<=); break;
872            case GEQ:  COMPARE(>=); break;
873            case EQUAL:
874              top->value = (v1 == v2);
875              top->unsignedp = 0;
876              break;
877            case NOTEQUAL:
878              top->value = (v1 != v2);
879              top->unsignedp = 0;
880              break;
881            case LSH:
882              top->unsignedp = unsigned1;
883              if (v2 < 0 && ! unsigned2)
884                top->value = right_shift (pfile, v1, unsigned1, -v2);
885              else
886                top->value = left_shift (pfile, v1, unsigned1, v2);
887              break;
888            case RSH:
889              top->unsignedp = unsigned1;
890              if (v2 < 0 && ! unsigned2)
891                top->value = left_shift (pfile, v1, unsigned1, -v2);
892              else
893                top->value = right_shift (pfile, v1, unsigned1, v2);
894              break;
895#define LOGICAL(OP) \
896              top->value = v1 OP v2;\
897              top->unsignedp = unsigned1 || unsigned2;
898            case '&':  LOGICAL(&); break;
899            case '^':  LOGICAL(^);  break;
900            case '|':  LOGICAL(|);  break;
901            case ANDAND:
902              top->value = v1 && v2;  top->unsignedp = 0;  break;
903            case OROR:
904              top->value = v1 || v2;  top->unsignedp = 0;  break;
905            case ',':
906              if (CPP_PEDANTIC (pfile))
907                cpp_pedwarn (pfile, "comma operator in operand of `#if'");
908              top->value = v2;
909              top->unsignedp = unsigned2;
910              break;
911            case '(':  case '?':
912              cpp_error (pfile, "syntax error in #if");
913              goto syntax_error;
914            case ':':
915              if (top[0].op != '?')
916                {
917                  cpp_error (pfile,
918                             "syntax error ':' without preceding '?'");
919                  goto syntax_error;
920                }
921              else if (! (top[1].flags & HAVE_VALUE)
922                       || !(top[-1].flags & HAVE_VALUE)
923                       || !(top[0].flags & HAVE_VALUE))
924                {
925                  cpp_error (pfile, "bad syntax for ?: operator");
926                  goto syntax_error;
927                }
928              else
929                {
930                  top--;
931                  top->value = top->value ? v1 : v2;
932                  top->unsignedp = unsigned1 || unsigned2;
933                }
934              break;
935            case ')':
936              if ((top[1].flags & HAVE_VALUE)
937                  || ! (top[0].flags & HAVE_VALUE)
938                  || top[0].op != '('
939                  || (top[-1].flags & HAVE_VALUE))
940                {
941                  cpp_error (pfile, "mismatched parentheses in #if");
942                  goto syntax_error;
943                }
944              else
945                {
946                  top--;
947                  top->value = v1;
948                  top->unsignedp = unsigned1;
949                  top->flags |= HAVE_VALUE;
950                }
951              break;
952            default:
953              fprintf (stderr,
954                       top[1].op >= ' ' && top[1].op <= '~'
955                       ? "unimplemented operator '%c'\n"
956                       : "unimplemented operator '\\%03o'\n",
957                       top[1].op);
958            }
959        }
960      if (op.op == 0)
961        {
962          if (top != stack)
963            cpp_error (pfile, "internal error in #if expression");
964          if (stack != init_stack)
965            free (stack);
966          return top->value;
967        }
968      top++;
969     
970      /* Check for and handle stack overflow. */
971      if (top == limit)
972        {
973          struct operation *new_stack;
974          int old_size = (char*)limit - (char*)stack;
975          int new_size = 2 * old_size;
976          if (stack != init_stack)
977            new_stack = (struct operation*) xrealloc (stack, new_size);
978          else
979            {
980              new_stack = (struct operation*) xmalloc (new_size);
981              bcopy ((char *) stack, (char *) new_stack, old_size);
982            }
983          stack = new_stack;
984          top = (struct operation*)((char*) new_stack + old_size);
985          limit = (struct operation*)((char*) new_stack + new_size);
986        }
987     
988      top->flags = flags;
989      top->rprio = rprio;
990      top->op = op.op;
991    }
992 syntax_error:
993  if (stack != init_stack)
994    free (stack);
995  skip_rest_of_line (pfile);
996  return 0;
997}
Note: See TracBrowser for help on using the repository browser.