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