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