]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cppexp.c
t-aix43 (AR_FLAGS_FOR_TARGET): Adjust for new definition.
[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 }
f13eb63a
ZW
207 else if (spec_long > (CPP_OPTIONS (pfile)->c89 ? 1 : 2))
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
88ae23e7 446 if (CPP_OPTIONS (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':
f1a86df6 508 if (CPP_OPTIONS (pfile)->pedantic)
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 */
b0699dad 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;
7f2935c7 713 case INT: case CHAR:
7f2935c7
PB
714 goto set_value;
715 case 0:
716 lprio = 0; goto maybe_reduce;
717 case '+': case '-':
cf4ed945
ZW
718 if (top->flags & HAVE_VALUE)
719 {
720 lprio = PLUS_PRIO;
721 goto binop;
722 }
eba30526
NB
723 if (top->flags & SIGN_QUALIFIED)
724 {
725 cpp_error (pfile, "more than one sign operator given");
726 goto syntax_error;
727 }
728 flags = SIGN_QUALIFIED;
cf4ed945 729 /* else fall through */
7f2935c7 730 case '!': case '~':
eba30526 731 flags |= RIGHT_OPERAND_REQUIRED;
7f2935c7
PB
732 rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
733 case '*': case '/': case '%':
734 lprio = MUL_PRIO; goto binop;
735 case '<': case '>': case LEQ: case GEQ:
736 lprio = LESS_PRIO; goto binop;
737 case EQUAL: case NOTEQUAL:
738 lprio = EQUAL_PRIO; goto binop;
739 case LSH: case RSH:
740 lprio = SHIFT_PRIO; goto binop;
741 case '&': lprio = AND_PRIO; goto binop;
742 case '^': lprio = XOR_PRIO; goto binop;
743 case '|': lprio = OR_PRIO; goto binop;
744 case ANDAND: lprio = ANDAND_PRIO; goto binop;
745 case OROR: lprio = OROR_PRIO; goto binop;
746 case ',':
747 lprio = COMMA_PRIO; goto binop;
748 case '(':
749 lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO;
750 goto maybe_reduce;
751 case ')':
752 lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
eba30526 753 flags = HAVE_VALUE; /* At least, we will have after reduction. */
7f2935c7
PB
754 goto maybe_reduce;
755 case ':':
eba30526 756 lprio = COND_PRIO; rprio = COND_PRIO + 1;
7f2935c7
PB
757 goto maybe_reduce;
758 case '?':
eba30526 759 lprio = COND_PRIO; rprio = COND_PRIO;
7f2935c7 760 goto maybe_reduce;
f13eb63a
ZW
761 case ERROR:
762 goto syntax_error;
7f2935c7
PB
763 default:
764 cpp_error (pfile, "invalid character in #if");
765 goto syntax_error;
766 }
767
768 set_value:
0f41302f 769 /* Push a value onto the stack. */
7f2935c7
PB
770 if (top->flags & HAVE_VALUE)
771 {
772 cpp_error (pfile, "syntax error in #if");
773 goto syntax_error;
774 }
cf4ed945
ZW
775 top->value = op.value;
776 top->unsignedp = op.unsignedp;
7f2935c7
PB
777 top->flags |= HAVE_VALUE;
778 continue;
779
cf4ed945
ZW
780 binop:
781 flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
782 rprio = lprio + 1;
783
7f2935c7 784 maybe_reduce:
0f41302f 785 /* Push an operator, and check if we can reduce now. */
7f2935c7
PB
786 while (top->rprio > lprio)
787 {
ca261cb4 788 HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value;
e23c0ba3
ZW
789 unsigned int unsigned1 = top[-1].unsignedp;
790 unsigned int unsigned2 = top[0].unsignedp;
7f2935c7
PB
791 top--;
792 if ((top[1].flags & LEFT_OPERAND_REQUIRED)
793 && ! (top[0].flags & HAVE_VALUE))
794 {
795 cpp_error (pfile, "syntax error - missing left operand");
796 goto syntax_error;
797 }
798 if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
799 && ! (top[1].flags & HAVE_VALUE))
800 {
801 cpp_error (pfile, "syntax error - missing right operand");
802 goto syntax_error;
803 }
804 /* top[0].value = (top[1].op)(v1, v2);*/
805 switch (top[1].op)
806 {
807 case '+':
808 if (!(top->flags & HAVE_VALUE))
809 { /* Unary '+' */
810 top->value = v2;
811 top->unsignedp = unsigned2;
812 top->flags |= HAVE_VALUE;
813 }
814 else
815 {
816 top->value = v1 + v2;
817 top->unsignedp = unsigned1 || unsigned2;
a4a315ef 818 if (! top->unsignedp && ! skip_evaluation
7f2935c7
PB
819 && ! possible_sum_sign (v1, v2, top->value))
820 integer_overflow (pfile);
821 }
822 break;
823 case '-':
52529158 824 if (!(top->flags & HAVE_VALUE))
7f2935c7
PB
825 { /* Unary '-' */
826 top->value = - v2;
52529158 827 if (!skip_evaluation && (top->value & v2) < 0 && !unsigned2)
7f2935c7
PB
828 integer_overflow (pfile);
829 top->unsignedp = unsigned2;
830 top->flags |= HAVE_VALUE;
831 }
832 else
833 { /* Binary '-' */
834 top->value = v1 - v2;
835 top->unsignedp = unsigned1 || unsigned2;
52529158 836 if (! top->unsignedp && ! skip_evaluation
7f2935c7
PB
837 && ! possible_sum_sign (top->value, v2, v1))
838 integer_overflow (pfile);
839 }
840 break;
841 case '*':
842 top->unsignedp = unsigned1 || unsigned2;
843 if (top->unsignedp)
ca261cb4 844 top->value = (unsigned HOST_WIDEST_INT) v1 * v2;
a4a315ef 845 else if (!skip_evaluation)
7f2935c7
PB
846 {
847 top->value = v1 * v2;
848 if (v1
849 && (top->value / v1 != v2
850 || (top->value & v1 & v2) < 0))
851 integer_overflow (pfile);
852 }
853 break;
854 case '/':
a4a315ef
PB
855 if (skip_evaluation)
856 break;
7f2935c7
PB
857 if (v2 == 0)
858 {
859 cpp_error (pfile, "division by zero in #if");
860 v2 = 1;
861 }
862 top->unsignedp = unsigned1 || unsigned2;
863 if (top->unsignedp)
ca261cb4 864 top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
7f2935c7
PB
865 else
866 {
867 top->value = v1 / v2;
868 if ((top->value & v1 & v2) < 0)
869 integer_overflow (pfile);
870 }
871 break;
872 case '%':
a4a315ef
PB
873 if (skip_evaluation)
874 break;
7f2935c7
PB
875 if (v2 == 0)
876 {
877 cpp_error (pfile, "division by zero in #if");
878 v2 = 1;
879 }
880 top->unsignedp = unsigned1 || unsigned2;
881 if (top->unsignedp)
ca261cb4 882 top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
7f2935c7
PB
883 else
884 top->value = v1 % v2;
885 break;
886 case '!':
887 if (top->flags & HAVE_VALUE)
888 {
889 cpp_error (pfile, "syntax error");
890 goto syntax_error;
891 }
892 top->value = ! v2;
893 top->unsignedp = 0;
894 top->flags |= HAVE_VALUE;
895 break;
896 case '~':
897 if (top->flags & HAVE_VALUE)
898 {
899 cpp_error (pfile, "syntax error");
900 goto syntax_error;
901 }
902 top->value = ~ v2;
903 top->unsignedp = unsigned2;
904 top->flags |= HAVE_VALUE;
905 break;
906 case '<': COMPARE(<); break;
907 case '>': COMPARE(>); break;
908 case LEQ: COMPARE(<=); break;
909 case GEQ: COMPARE(>=); break;
910 case EQUAL:
911 top->value = (v1 == v2);
912 top->unsignedp = 0;
913 break;
914 case NOTEQUAL:
915 top->value = (v1 != v2);
916 top->unsignedp = 0;
917 break;
918 case LSH:
a4a315ef
PB
919 if (skip_evaluation)
920 break;
7f2935c7
PB
921 top->unsignedp = unsigned1;
922 if (v2 < 0 && ! unsigned2)
923 top->value = right_shift (pfile, v1, unsigned1, -v2);
924 else
925 top->value = left_shift (pfile, v1, unsigned1, v2);
926 break;
927 case RSH:
a4a315ef
PB
928 if (skip_evaluation)
929 break;
7f2935c7
PB
930 top->unsignedp = unsigned1;
931 if (v2 < 0 && ! unsigned2)
932 top->value = left_shift (pfile, v1, unsigned1, -v2);
933 else
934 top->value = right_shift (pfile, v1, unsigned1, v2);
935 break;
936#define LOGICAL(OP) \
937 top->value = v1 OP v2;\
938 top->unsignedp = unsigned1 || unsigned2;
939 case '&': LOGICAL(&); break;
940 case '^': LOGICAL(^); break;
941 case '|': LOGICAL(|); break;
942 case ANDAND:
a4a315ef
PB
943 top->value = v1 && v2; top->unsignedp = 0;
944 if (!v1) skip_evaluation--;
945 break;
7f2935c7 946 case OROR:
a4a315ef
PB
947 top->value = v1 || v2; top->unsignedp = 0;
948 if (v1) skip_evaluation--;
949 break;
7f2935c7
PB
950 case ',':
951 if (CPP_PEDANTIC (pfile))
952 cpp_pedwarn (pfile, "comma operator in operand of `#if'");
953 top->value = v2;
954 top->unsignedp = unsigned2;
955 break;
956 case '(': case '?':
957 cpp_error (pfile, "syntax error in #if");
958 goto syntax_error;
959 case ':':
960 if (top[0].op != '?')
961 {
962 cpp_error (pfile,
963 "syntax error ':' without preceding '?'");
964 goto syntax_error;
965 }
966 else if (! (top[1].flags & HAVE_VALUE)
967 || !(top[-1].flags & HAVE_VALUE)
968 || !(top[0].flags & HAVE_VALUE))
969 {
970 cpp_error (pfile, "bad syntax for ?: operator");
971 goto syntax_error;
972 }
973 else
974 {
975 top--;
a4a315ef 976 if (top->value) skip_evaluation--;
7f2935c7
PB
977 top->value = top->value ? v1 : v2;
978 top->unsignedp = unsigned1 || unsigned2;
979 }
980 break;
981 case ')':
eba30526 982 if (! (top[0].flags & HAVE_VALUE)
7f2935c7
PB
983 || top[0].op != '('
984 || (top[-1].flags & HAVE_VALUE))
985 {
986 cpp_error (pfile, "mismatched parentheses in #if");
987 goto syntax_error;
988 }
989 else
990 {
991 top--;
992 top->value = v1;
993 top->unsignedp = unsigned1;
994 top->flags |= HAVE_VALUE;
995 }
996 break;
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 }
1005 if (op.op == 0)
1006 {
1007 if (top != stack)
c1212d2f 1008 cpp_ice (pfile, "unbalanced stack in #if expression");
eba30526
NB
1009 if (!(top->flags & HAVE_VALUE))
1010 cpp_error (pfile, "#if with no expression");
45b966db
ZW
1011 result = (top->value != 0);
1012 goto done;
7f2935c7
PB
1013 }
1014 top++;
1015
0f41302f 1016 /* Check for and handle stack overflow. */
7f2935c7
PB
1017 if (top == limit)
1018 {
1019 struct operation *new_stack;
0f41302f 1020 int old_size = (char *) limit - (char *) stack;
7f2935c7
PB
1021 int new_size = 2 * old_size;
1022 if (stack != init_stack)
0f41302f 1023 new_stack = (struct operation *) xrealloc (stack, new_size);
7f2935c7
PB
1024 else
1025 {
0f41302f 1026 new_stack = (struct operation *) xmalloc (new_size);
b0699dad 1027 memcpy (new_stack, stack, old_size);
7f2935c7
PB
1028 }
1029 stack = new_stack;
0f41302f
MS
1030 top = (struct operation *) ((char *) new_stack + old_size);
1031 limit = (struct operation *) ((char *) new_stack + new_size);
7f2935c7
PB
1032 }
1033
1034 top->flags = flags;
1035 top->rprio = rprio;
1036 top->op = op.op;
a4a315ef
PB
1037 if ((op.op == OROR && top[-1].value)
1038 || (op.op == ANDAND && !top[-1].value)
1039 || (op.op == '?' && !top[-1].value))
1040 {
1041 skip_evaluation++;
1042 }
1043 else if (op.op == ':')
1044 {
1045 if (top[-2].value) /* Was condition true? */
1046 skip_evaluation++;
1047 else
1048 skip_evaluation--;
1049 }
7f2935c7
PB
1050 }
1051 syntax_error:
45b966db
ZW
1052 _cpp_skip_rest_of_line (pfile);
1053 result = 0;
1054 done:
1055 pfile->parsing_if_directive--;
1056 CPP_SET_WRITTEN (pfile, old_written);
7f2935c7
PB
1057 if (stack != init_stack)
1058 free (stack);
45b966db 1059 return result;
7f2935c7 1060}