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