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