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