]> gcc.gnu.org Git - gcc.git/blob - gcc/cexp.y
configure.in (i*86-*-sysv5*): Use fixinc.svr4 to patch byteorder problems.
[gcc.git] / gcc / cexp.y
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 94 - 97, 1998 Free Software Foundation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
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
23 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
24
25 /* Parse a C expression from text in a string */
26
27 %{
28 #include "config.h"
29
30 #define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
31
32 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
33
34 #include "system.h"
35 #include <setjmp.h>
36 /* #define YYDEBUG 1 */
37 #include "gansidecl.h"
38
39 #ifdef MULTIBYTE_CHARS
40 #include "mbchar.h"
41 #include <locale.h>
42 #endif /* MULTIBYTE_CHARS */
43
44 typedef unsigned char U_CHAR;
45
46 /* This is used for communicating lists of keywords with cccp.c. */
47 struct arglist {
48 struct arglist *next;
49 U_CHAR *name;
50 int length;
51 int argno;
52 };
53
54 /* Find the largest host integer type and set its size and type.
55 Watch out: on some crazy hosts `long' is shorter than `int'. */
56
57 #ifndef HOST_WIDE_INT
58 # if HAVE_INTTYPES_H
59 # include <inttypes.h>
60 # define HOST_WIDE_INT intmax_t
61 # define unsigned_HOST_WIDE_INT uintmax_t
62 # else
63 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
64 # define HOST_WIDE_INT int
65 # else
66 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
67 # define HOST_WIDE_INT long
68 # else
69 # define HOST_WIDE_INT long long
70 # endif
71 # endif
72 # endif
73 #endif
74
75 #ifndef unsigned_HOST_WIDE_INT
76 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
77 #endif
78
79 #ifndef CHAR_BIT
80 #define CHAR_BIT 8
81 #endif
82
83 #ifndef HOST_BITS_PER_WIDE_INT
84 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
85 #endif
86
87 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
88
89 static int yylex PROTO((void));
90 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
91 static HOST_WIDE_INT expression_value;
92 #ifdef TEST_EXP_READER
93 static int expression_signedp;
94 #endif
95
96 static jmp_buf parse_return_error;
97
98 /* Nonzero means count most punctuation as part of a name. */
99 static int keyword_parsing = 0;
100
101 /* Nonzero means do not evaluate this expression.
102 This is a count, since unevaluated expressions can nest. */
103 static int skip_evaluation;
104
105 /* Nonzero means warn if undefined identifiers are evaluated. */
106 static int warn_undef;
107
108 /* some external tables of character types */
109 extern unsigned char is_idstart[], is_idchar[], is_space[];
110
111 /* Flag for -pedantic. */
112 extern int pedantic;
113
114 /* Flag for -traditional. */
115 extern int traditional;
116
117 /* Flag for -lang-c89. */
118 extern int c89;
119
120 #ifndef CHAR_TYPE_SIZE
121 #define CHAR_TYPE_SIZE BITS_PER_UNIT
122 #endif
123
124 #ifndef INT_TYPE_SIZE
125 #define INT_TYPE_SIZE BITS_PER_WORD
126 #endif
127
128 #ifndef LONG_TYPE_SIZE
129 #define LONG_TYPE_SIZE BITS_PER_WORD
130 #endif
131
132 #ifndef WCHAR_TYPE_SIZE
133 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
134 #endif
135
136 #ifndef MAX_CHAR_TYPE_SIZE
137 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
138 #endif
139
140 #ifndef MAX_INT_TYPE_SIZE
141 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
142 #endif
143
144 #ifndef MAX_LONG_TYPE_SIZE
145 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
146 #endif
147
148 #ifndef MAX_WCHAR_TYPE_SIZE
149 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
150 #endif
151
152 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
153 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
154 : ~ (HOST_WIDE_INT) 0)
155
156 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
157 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
158 : ~ (HOST_WIDE_INT) 0)
159
160 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
161 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
162 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
163 Then this yields nonzero if overflow occurred during the addition.
164 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
165 and SIGNEDP is negative.
166 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
167 #define overflow_sum_sign(a, b, sum, signedp) \
168 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
169
170 struct constant;
171
172 GENERIC_PTR xmalloc PROTO((size_t));
173 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
174 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
175 struct hashnode *lookup PROTO((U_CHAR *, int, int));
176 void error PRINTF_PROTO_1((char *, ...));
177 void pedwarn PRINTF_PROTO_1((char *, ...));
178 void warning PRINTF_PROTO_1((char *, ...));
179
180 static int parse_number PROTO((int));
181 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
182 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
183 static void integer_overflow PROTO((void));
184
185 /* `signedp' values */
186 #define SIGNED (~0)
187 #define UNSIGNED 0
188 %}
189
190 %union {
191 struct constant {HOST_WIDE_INT value; int signedp;} integer;
192 struct name {U_CHAR *address; int length;} name;
193 struct arglist *keywords;
194 }
195
196 %type <integer> exp exp1 start
197 %type <keywords> keywords
198 %token <integer> INT CHAR
199 %token <name> NAME
200 %token <integer> ERROR
201
202 %right '?' ':'
203 %left ','
204 %left OR
205 %left AND
206 %left '|'
207 %left '^'
208 %left '&'
209 %left EQUAL NOTEQUAL
210 %left '<' '>' LEQ GEQ
211 %left LSH RSH
212 %left '+' '-'
213 %left '*' '/' '%'
214 %right UNARY
215
216 /* %expect 40 */
217 \f
218 %%
219
220 start : exp1
221 {
222 expression_value = $1.value;
223 #ifdef TEST_EXP_READER
224 expression_signedp = $1.signedp;
225 #endif
226 }
227 ;
228
229 /* Expressions, including the comma operator. */
230 exp1 : exp
231 | exp1 ',' exp
232 { if (pedantic)
233 pedwarn ("comma operator in operand of `#if'");
234 $$ = $3; }
235 ;
236
237 /* Expressions, not including the comma operator. */
238 exp : '-' exp %prec UNARY
239 { $$.value = - $2.value;
240 $$.signedp = $2.signedp;
241 if (($$.value & $2.value & $$.signedp) < 0)
242 integer_overflow (); }
243 | '!' exp %prec UNARY
244 { $$.value = ! $2.value;
245 $$.signedp = SIGNED; }
246 | '+' exp %prec UNARY
247 { $$ = $2; }
248 | '~' exp %prec UNARY
249 { $$.value = ~ $2.value;
250 $$.signedp = $2.signedp; }
251 | '#' NAME
252 { $$.value = check_assertion ($2.address, $2.length,
253 0, NULL_PTR);
254 $$.signedp = SIGNED; }
255 | '#' NAME
256 { keyword_parsing = 1; }
257 '(' keywords ')'
258 { $$.value = check_assertion ($2.address, $2.length,
259 1, $5);
260 keyword_parsing = 0;
261 $$.signedp = SIGNED; }
262 | '(' exp1 ')'
263 { $$ = $2; }
264 ;
265
266 /* Binary operators in order of decreasing precedence. */
267 exp : exp '*' exp
268 { $$.signedp = $1.signedp & $3.signedp;
269 if ($$.signedp)
270 {
271 $$.value = $1.value * $3.value;
272 if ($1.value
273 && ($$.value / $1.value != $3.value
274 || ($$.value & $1.value & $3.value) < 0))
275 integer_overflow ();
276 }
277 else
278 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
279 * $3.value); }
280 | exp '/' exp
281 { if ($3.value == 0)
282 {
283 if (!skip_evaluation)
284 error ("division by zero in #if");
285 $3.value = 1;
286 }
287 $$.signedp = $1.signedp & $3.signedp;
288 if ($$.signedp)
289 {
290 $$.value = $1.value / $3.value;
291 if (($$.value & $1.value & $3.value) < 0)
292 integer_overflow ();
293 }
294 else
295 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
296 / $3.value); }
297 | exp '%' exp
298 { if ($3.value == 0)
299 {
300 if (!skip_evaluation)
301 error ("division by zero in #if");
302 $3.value = 1;
303 }
304 $$.signedp = $1.signedp & $3.signedp;
305 if ($$.signedp)
306 $$.value = $1.value % $3.value;
307 else
308 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
309 % $3.value); }
310 | exp '+' exp
311 { $$.value = $1.value + $3.value;
312 $$.signedp = $1.signedp & $3.signedp;
313 if (overflow_sum_sign ($1.value, $3.value,
314 $$.value, $$.signedp))
315 integer_overflow (); }
316 | exp '-' exp
317 { $$.value = $1.value - $3.value;
318 $$.signedp = $1.signedp & $3.signedp;
319 if (overflow_sum_sign ($$.value, $3.value,
320 $1.value, $$.signedp))
321 integer_overflow (); }
322 | exp LSH exp
323 { $$.signedp = $1.signedp;
324 if (($3.value & $3.signedp) < 0)
325 $$.value = right_shift (&$1, -$3.value);
326 else
327 $$.value = left_shift (&$1, $3.value); }
328 | exp RSH exp
329 { $$.signedp = $1.signedp;
330 if (($3.value & $3.signedp) < 0)
331 $$.value = left_shift (&$1, -$3.value);
332 else
333 $$.value = right_shift (&$1, $3.value); }
334 | exp EQUAL exp
335 { $$.value = ($1.value == $3.value);
336 $$.signedp = SIGNED; }
337 | exp NOTEQUAL exp
338 { $$.value = ($1.value != $3.value);
339 $$.signedp = SIGNED; }
340 | exp LEQ exp
341 { $$.signedp = SIGNED;
342 if ($1.signedp & $3.signedp)
343 $$.value = $1.value <= $3.value;
344 else
345 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
346 <= $3.value); }
347 | exp GEQ exp
348 { $$.signedp = SIGNED;
349 if ($1.signedp & $3.signedp)
350 $$.value = $1.value >= $3.value;
351 else
352 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
353 >= $3.value); }
354 | exp '<' exp
355 { $$.signedp = SIGNED;
356 if ($1.signedp & $3.signedp)
357 $$.value = $1.value < $3.value;
358 else
359 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
360 < $3.value); }
361 | exp '>' exp
362 { $$.signedp = SIGNED;
363 if ($1.signedp & $3.signedp)
364 $$.value = $1.value > $3.value;
365 else
366 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
367 > $3.value); }
368 | exp '&' exp
369 { $$.value = $1.value & $3.value;
370 $$.signedp = $1.signedp & $3.signedp; }
371 | exp '^' exp
372 { $$.value = $1.value ^ $3.value;
373 $$.signedp = $1.signedp & $3.signedp; }
374 | exp '|' exp
375 { $$.value = $1.value | $3.value;
376 $$.signedp = $1.signedp & $3.signedp; }
377 | exp AND
378 { skip_evaluation += !$1.value; }
379 exp
380 { skip_evaluation -= !$1.value;
381 $$.value = ($1.value && $4.value);
382 $$.signedp = SIGNED; }
383 | exp OR
384 { skip_evaluation += !!$1.value; }
385 exp
386 { skip_evaluation -= !!$1.value;
387 $$.value = ($1.value || $4.value);
388 $$.signedp = SIGNED; }
389 | exp '?'
390 { skip_evaluation += !$1.value; }
391 exp ':'
392 { skip_evaluation += !!$1.value - !$1.value; }
393 exp
394 { skip_evaluation -= !!$1.value;
395 $$.value = $1.value ? $4.value : $7.value;
396 $$.signedp = $4.signedp & $7.signedp; }
397 | INT
398 { $$ = yylval.integer; }
399 | CHAR
400 { $$ = yylval.integer; }
401 | NAME
402 { if (warn_undef && !skip_evaluation)
403 warning ("`%.*s' is not defined",
404 $1.length, $1.address);
405 $$.value = 0;
406 $$.signedp = SIGNED; }
407 ;
408
409 keywords :
410 { $$ = 0; }
411 | '(' keywords ')' keywords
412 { struct arglist *temp;
413 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
414 $$->next = $2;
415 $$->name = (U_CHAR *) "(";
416 $$->length = 1;
417 temp = $$;
418 while (temp != 0 && temp->next != 0)
419 temp = temp->next;
420 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
421 temp->next->next = $4;
422 temp->next->name = (U_CHAR *) ")";
423 temp->next->length = 1; }
424 | NAME keywords
425 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
426 $$->name = $1.address;
427 $$->length = $1.length;
428 $$->next = $2; }
429 ;
430 %%
431 \f
432 /* During parsing of a C expression, the pointer to the next character
433 is in this variable. */
434
435 static char *lexptr;
436
437 /* Take care of parsing a number (anything that starts with a digit).
438 Set yylval and return the token type; update lexptr.
439 LEN is the number of characters in it. */
440
441 /* maybe needs to actually deal with floating point numbers */
442
443 static int
444 parse_number (olen)
445 int olen;
446 {
447 register char *p = lexptr;
448 register int c;
449 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
450 register int base = 10;
451 register int len = olen;
452 register int overflow = 0;
453 register int digit, largest_digit = 0;
454 int spec_long = 0;
455
456 yylval.integer.signedp = SIGNED;
457
458 if (*p == '0') {
459 base = 8;
460 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
461 p += 2;
462 base = 16;
463 len -= 2;
464 }
465 }
466
467 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
468
469 for (; len > 0; len--) {
470 c = *p++;
471
472 if (c >= '0' && c <= '9')
473 digit = c - '0';
474 else if (base == 16 && c >= 'a' && c <= 'f')
475 digit = c - 'a' + 10;
476 else if (base == 16 && c >= 'A' && c <= 'F')
477 digit = c - 'A' + 10;
478 else {
479 /* `l' means long, and `u' means unsigned. */
480 while (1) {
481 if (c == 'l' || c == 'L')
482 {
483 if (!pedantic < spec_long)
484 yyerror ("too many `l's in integer constant");
485 spec_long++;
486 }
487 else if (c == 'u' || c == 'U')
488 {
489 if (! yylval.integer.signedp)
490 yyerror ("two `u's in integer constant");
491 yylval.integer.signedp = UNSIGNED;
492 }
493 else {
494 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
495 yyerror ("Floating point numbers not allowed in #if expressions");
496 else {
497 char *buf = (char *) alloca (p - lexptr + 40);
498 sprintf (buf, "missing white space after number `%.*s'",
499 (int) (p - lexptr - 1), lexptr);
500 yyerror (buf);
501 }
502 }
503
504 if (--len == 0)
505 break;
506 c = *p++;
507 }
508 /* Don't look for any more digits after the suffixes. */
509 break;
510 }
511 if (largest_digit < digit)
512 largest_digit = digit;
513 nd = n * base + digit;
514 overflow |= (max_over_base < n) | (nd < n);
515 n = nd;
516 }
517
518 if (base <= largest_digit)
519 pedwarn ("integer constant contains digits beyond the radix");
520
521 if (overflow)
522 pedwarn ("integer constant out of range");
523
524 /* If too big to be signed, consider it unsigned. */
525 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
526 {
527 if (base == 10)
528 warning ("integer constant is so large that it is unsigned");
529 yylval.integer.signedp = UNSIGNED;
530 }
531
532 lexptr = p;
533 yylval.integer.value = n;
534 return INT;
535 }
536
537 struct token {
538 char *operator;
539 int token;
540 };
541
542 static struct token tokentab2[] = {
543 {"&&", AND},
544 {"||", OR},
545 {"<<", LSH},
546 {">>", RSH},
547 {"==", EQUAL},
548 {"!=", NOTEQUAL},
549 {"<=", LEQ},
550 {">=", GEQ},
551 {"++", ERROR},
552 {"--", ERROR},
553 {NULL, ERROR}
554 };
555
556 /* Read one token, getting characters through lexptr. */
557
558 static int
559 yylex ()
560 {
561 register int c;
562 register int namelen;
563 register unsigned char *tokstart;
564 register struct token *toktab;
565 int wide_flag;
566 HOST_WIDE_INT mask;
567
568 retry:
569
570 tokstart = (unsigned char *) lexptr;
571 c = *tokstart;
572 /* See if it is a special token of length 2. */
573 if (! keyword_parsing)
574 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
575 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
576 lexptr += 2;
577 if (toktab->token == ERROR)
578 {
579 char *buf = (char *) alloca (40);
580 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
581 yyerror (buf);
582 }
583 return toktab->token;
584 }
585
586 switch (c) {
587 case '\n':
588 return 0;
589
590 case ' ':
591 case '\t':
592 case '\r':
593 lexptr++;
594 goto retry;
595
596 case 'L':
597 /* Capital L may start a wide-string or wide-character constant. */
598 if (lexptr[1] == '\'')
599 {
600 lexptr++;
601 wide_flag = 1;
602 mask = MAX_WCHAR_TYPE_MASK;
603 goto char_constant;
604 }
605 if (lexptr[1] == '"')
606 {
607 lexptr++;
608 wide_flag = 1;
609 mask = MAX_WCHAR_TYPE_MASK;
610 goto string_constant;
611 }
612 break;
613
614 case '\'':
615 wide_flag = 0;
616 mask = MAX_CHAR_TYPE_MASK;
617 char_constant:
618 lexptr++;
619 if (keyword_parsing) {
620 char *start_ptr = lexptr - 1;
621 while (1) {
622 c = *lexptr++;
623 if (c == '\\')
624 c = parse_escape (&lexptr, mask);
625 else if (c == '\'')
626 break;
627 }
628 yylval.name.address = tokstart;
629 yylval.name.length = lexptr - start_ptr;
630 return NAME;
631 }
632
633 /* This code for reading a character constant
634 handles multicharacter constants and wide characters.
635 It is mostly copied from c-lex.c. */
636 {
637 register HOST_WIDE_INT result = 0;
638 register int num_chars = 0;
639 int chars_seen = 0;
640 unsigned width = MAX_CHAR_TYPE_SIZE;
641 int max_chars;
642 #ifdef MULTIBYTE_CHARS
643 int longest_char = local_mb_cur_max ();
644 char *token_buffer = (char *) alloca (longest_char);
645 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
646 #endif
647
648 max_chars = MAX_LONG_TYPE_SIZE / width;
649 if (wide_flag)
650 width = MAX_WCHAR_TYPE_SIZE;
651
652 while (1)
653 {
654 c = *lexptr++;
655
656 if (c == '\'' || c == EOF)
657 break;
658
659 ++chars_seen;
660 if (c == '\\')
661 {
662 c = parse_escape (&lexptr, mask);
663 }
664 else
665 {
666 #ifdef MULTIBYTE_CHARS
667 wchar_t wc;
668 int i;
669 int char_len = -1;
670 for (i = 1; i <= longest_char; ++i)
671 {
672 token_buffer[i - 1] = c;
673 char_len = local_mbtowc (& wc, token_buffer, i);
674 if (char_len != -1)
675 break;
676 c = *lexptr++;
677 }
678 if (char_len > 1)
679 {
680 /* mbtowc sometimes needs an extra char before accepting */
681 if (char_len < i)
682 lexptr--;
683 if (! wide_flag)
684 {
685 /* Merge character into result; ignore excess chars. */
686 for (i = 1; i <= char_len; ++i)
687 {
688 if (i > max_chars)
689 break;
690 if (width < HOST_BITS_PER_INT)
691 result = (result << width)
692 | (token_buffer[i - 1]
693 & ((1 << width) - 1));
694 else
695 result = token_buffer[i - 1];
696 }
697 num_chars += char_len;
698 continue;
699 }
700 }
701 else
702 {
703 if (char_len == -1)
704 warning ("Ignoring invalid multibyte character");
705 }
706 if (wide_flag)
707 c = wc;
708 #endif /* ! MULTIBYTE_CHARS */
709 }
710
711 if (wide_flag)
712 {
713 if (chars_seen == 1) /* only keep the first one */
714 result = c;
715 continue;
716 }
717
718 /* Merge character into result; ignore excess chars. */
719 num_chars++;
720 if (num_chars <= max_chars)
721 {
722 if (width < HOST_BITS_PER_INT)
723 result = (result << width) | (c & ((1 << width) - 1));
724 else
725 result = c;
726 }
727 }
728
729 if (c != '\'')
730 error ("malformatted character constant");
731 else if (chars_seen == 0)
732 error ("empty character constant");
733 else if (num_chars > max_chars)
734 {
735 num_chars = max_chars;
736 error ("character constant too long");
737 }
738 else if (chars_seen != 1 && ! traditional)
739 warning ("multi-character character constant");
740
741 /* If char type is signed, sign-extend the constant. */
742 if (! wide_flag)
743 {
744 int num_bits = num_chars * width;
745 if (num_bits == 0)
746 /* We already got an error; avoid invalid shift. */
747 yylval.integer.value = 0;
748 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
749 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
750 || ((result >> (num_bits - 1)) & 1) == 0)
751 yylval.integer.value
752 = result & (~ (unsigned_HOST_WIDE_INT) 0
753 >> (HOST_BITS_PER_WIDE_INT - num_bits));
754 else
755 yylval.integer.value
756 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
757 >> (HOST_BITS_PER_WIDE_INT - num_bits));
758 }
759 else
760 {
761 yylval.integer.value = result;
762 }
763 }
764
765 /* This is always a signed type. */
766 yylval.integer.signedp = SIGNED;
767
768 return CHAR;
769
770 /* some of these chars are invalid in constant expressions;
771 maybe do something about them later */
772 case '/':
773 case '+':
774 case '-':
775 case '*':
776 case '%':
777 case '|':
778 case '&':
779 case '^':
780 case '~':
781 case '!':
782 case '@':
783 case '<':
784 case '>':
785 case '[':
786 case ']':
787 case '.':
788 case '?':
789 case ':':
790 case '=':
791 case '{':
792 case '}':
793 case ',':
794 case '#':
795 if (keyword_parsing)
796 break;
797 case '(':
798 case ')':
799 lexptr++;
800 return c;
801
802 case '"':
803 mask = MAX_CHAR_TYPE_MASK;
804 string_constant:
805 if (keyword_parsing) {
806 char *start_ptr = lexptr;
807 lexptr++;
808 while (1) {
809 c = *lexptr++;
810 if (c == '\\')
811 c = parse_escape (&lexptr, mask);
812 else if (c == '"')
813 break;
814 }
815 yylval.name.address = tokstart;
816 yylval.name.length = lexptr - start_ptr;
817 return NAME;
818 }
819 yyerror ("string constants not allowed in #if expressions");
820 return ERROR;
821 }
822
823 if (c >= '0' && c <= '9' && !keyword_parsing) {
824 /* It's a number */
825 for (namelen = 1; ; namelen++) {
826 int d = tokstart[namelen];
827 if (! ((is_idchar[d] || d == '.')
828 || ((d == '-' || d == '+')
829 && (c == 'e' || c == 'E'
830 || ((c == 'p' || c == 'P') && ! c89))
831 && ! traditional)))
832 break;
833 c = d;
834 }
835 return parse_number (namelen);
836 }
837
838 /* It is a name. See how long it is. */
839
840 if (keyword_parsing) {
841 for (namelen = 0;; namelen++) {
842 if (is_space[tokstart[namelen]])
843 break;
844 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
845 break;
846 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
847 break;
848 }
849 } else {
850 if (!is_idstart[c]) {
851 yyerror ("Invalid token in expression");
852 return ERROR;
853 }
854
855 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
856 ;
857 }
858
859 lexptr += namelen;
860 yylval.name.address = tokstart;
861 yylval.name.length = namelen;
862 return NAME;
863 }
864
865
866 /* Parse a C escape sequence. STRING_PTR points to a variable
867 containing a pointer to the string to parse. That pointer
868 is updated past the characters we use. The value of the
869 escape sequence is returned.
870
871 RESULT_MASK is used to mask out the result;
872 an error is reported if bits are lost thereby.
873
874 A negative value means the sequence \ newline was seen,
875 which is supposed to be equivalent to nothing at all.
876
877 If \ is followed by a null character, we return a negative
878 value and leave the string pointer pointing at the null character.
879
880 If \ is followed by 000, we return 0 and leave the string pointer
881 after the zeros. A value of 0 does not mean end of string. */
882
883 HOST_WIDE_INT
884 parse_escape (string_ptr, result_mask)
885 char **string_ptr;
886 HOST_WIDE_INT result_mask;
887 {
888 register int c = *(*string_ptr)++;
889 switch (c)
890 {
891 case 'a':
892 return TARGET_BELL;
893 case 'b':
894 return TARGET_BS;
895 case 'e':
896 case 'E':
897 if (pedantic)
898 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
899 return 033;
900 case 'f':
901 return TARGET_FF;
902 case 'n':
903 return TARGET_NEWLINE;
904 case 'r':
905 return TARGET_CR;
906 case 't':
907 return TARGET_TAB;
908 case 'v':
909 return TARGET_VT;
910 case '\n':
911 return -2;
912 case 0:
913 (*string_ptr)--;
914 return 0;
915
916 case '0':
917 case '1':
918 case '2':
919 case '3':
920 case '4':
921 case '5':
922 case '6':
923 case '7':
924 {
925 register HOST_WIDE_INT i = c - '0';
926 register int count = 0;
927 while (++count < 3)
928 {
929 c = *(*string_ptr)++;
930 if (c >= '0' && c <= '7')
931 i = (i << 3) + c - '0';
932 else
933 {
934 (*string_ptr)--;
935 break;
936 }
937 }
938 if (i != (i & result_mask))
939 {
940 i &= result_mask;
941 pedwarn ("octal escape sequence out of range");
942 }
943 return i;
944 }
945 case 'x':
946 {
947 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
948 register int digits_found = 0, digit;
949 for (;;)
950 {
951 c = *(*string_ptr)++;
952 if (c >= '0' && c <= '9')
953 digit = c - '0';
954 else if (c >= 'a' && c <= 'f')
955 digit = c - 'a' + 10;
956 else if (c >= 'A' && c <= 'F')
957 digit = c - 'A' + 10;
958 else
959 {
960 (*string_ptr)--;
961 break;
962 }
963 overflow |= i ^ (i << 4 >> 4);
964 i = (i << 4) + digit;
965 digits_found = 1;
966 }
967 if (!digits_found)
968 yyerror ("\\x used with no following hex digits");
969 if (overflow | (i != (i & result_mask)))
970 {
971 i &= result_mask;
972 pedwarn ("hex escape sequence out of range");
973 }
974 return i;
975 }
976 default:
977 return c;
978 }
979 }
980
981 static void
982 yyerror (s)
983 char *s;
984 {
985 error ("%s", s);
986 skip_evaluation = 0;
987 longjmp (parse_return_error, 1);
988 }
989
990 static void
991 integer_overflow ()
992 {
993 if (!skip_evaluation && pedantic)
994 pedwarn ("integer overflow in preprocessor expression");
995 }
996
997 static HOST_WIDE_INT
998 left_shift (a, b)
999 struct constant *a;
1000 unsigned_HOST_WIDE_INT b;
1001 {
1002 /* It's unclear from the C standard whether shifts can overflow.
1003 The following code ignores overflow; perhaps a C standard
1004 interpretation ruling is needed. */
1005 if (b >= HOST_BITS_PER_WIDE_INT)
1006 return 0;
1007 else
1008 return (unsigned_HOST_WIDE_INT) a->value << b;
1009 }
1010
1011 static HOST_WIDE_INT
1012 right_shift (a, b)
1013 struct constant *a;
1014 unsigned_HOST_WIDE_INT b;
1015 {
1016 if (b >= HOST_BITS_PER_WIDE_INT)
1017 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1018 else if (a->signedp)
1019 return a->value >> b;
1020 else
1021 return (unsigned_HOST_WIDE_INT) a->value >> b;
1022 }
1023 \f
1024 /* This page contains the entry point to this file. */
1025
1026 /* Parse STRING as an expression, and complain if this fails
1027 to use up all of the contents of STRING.
1028 STRING may contain '\0' bytes; it is terminated by the first '\n'
1029 outside a string constant, so that we can diagnose '\0' properly.
1030 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1031 We do not support C comments. They should be removed before
1032 this function is called. */
1033
1034 HOST_WIDE_INT
1035 parse_c_expression (string, warn_undefined)
1036 char *string;
1037 int warn_undefined;
1038 {
1039 lexptr = string;
1040 warn_undef = warn_undefined;
1041
1042 /* if there is some sort of scanning error, just return 0 and assume
1043 the parsing routine has printed an error message somewhere.
1044 there is surely a better thing to do than this. */
1045 if (setjmp (parse_return_error))
1046 return 0;
1047
1048 if (yyparse () != 0)
1049 abort ();
1050
1051 if (*lexptr != '\n')
1052 error ("Junk after end of expression.");
1053
1054 return expression_value; /* set by yyparse () */
1055 }
1056 \f
1057 #ifdef TEST_EXP_READER
1058
1059 #if YYDEBUG
1060 extern int yydebug;
1061 #endif
1062
1063 int pedantic;
1064 int traditional;
1065
1066 int main PROTO((int, char **));
1067 static void initialize_random_junk PROTO((void));
1068 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1069
1070 /* Main program for testing purposes. */
1071 int
1072 main (argc, argv)
1073 int argc;
1074 char **argv;
1075 {
1076 int n, c;
1077 char buf[1024];
1078 unsigned_HOST_WIDE_INT u;
1079
1080 pedantic = 1 < argc;
1081 traditional = 2 < argc;
1082 #if YYDEBUG
1083 yydebug = 3 < argc;
1084 #endif
1085 initialize_random_junk ();
1086
1087 for (;;) {
1088 printf ("enter expression: ");
1089 n = 0;
1090 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1091 n++;
1092 if (c == EOF)
1093 break;
1094 parse_c_expression (buf, 1);
1095 printf ("parser returned ");
1096 u = (unsigned_HOST_WIDE_INT) expression_value;
1097 if (expression_value < 0 && expression_signedp) {
1098 u = -u;
1099 printf ("-");
1100 }
1101 if (u == 0)
1102 printf ("0");
1103 else
1104 print_unsigned_host_wide_int (u);
1105 if (! expression_signedp)
1106 printf("u");
1107 printf ("\n");
1108 }
1109
1110 return 0;
1111 }
1112
1113 static void
1114 print_unsigned_host_wide_int (u)
1115 unsigned_HOST_WIDE_INT u;
1116 {
1117 if (u) {
1118 print_unsigned_host_wide_int (u / 10);
1119 putchar ('0' + (int) (u % 10));
1120 }
1121 }
1122
1123 /* table to tell if char can be part of a C identifier. */
1124 unsigned char is_idchar[256];
1125 /* table to tell if char can be first char of a c identifier. */
1126 unsigned char is_idstart[256];
1127 /* table to tell if c is horizontal or vertical space. */
1128 unsigned char is_space[256];
1129
1130 /*
1131 * initialize random junk in the hash table and maybe other places
1132 */
1133 static void
1134 initialize_random_junk ()
1135 {
1136 register int i;
1137
1138 /*
1139 * Set up is_idchar and is_idstart tables. These should be
1140 * faster than saying (is_alpha (c) || c == '_'), etc.
1141 * Must do set up these things before calling any routines tthat
1142 * refer to them.
1143 */
1144 for (i = 'a'; i <= 'z'; i++) {
1145 ++is_idchar[i - 'a' + 'A'];
1146 ++is_idchar[i];
1147 ++is_idstart[i - 'a' + 'A'];
1148 ++is_idstart[i];
1149 }
1150 for (i = '0'; i <= '9'; i++)
1151 ++is_idchar[i];
1152 ++is_idchar['_'];
1153 ++is_idstart['_'];
1154 ++is_idchar['$'];
1155 ++is_idstart['$'];
1156
1157 ++is_space[' '];
1158 ++is_space['\t'];
1159 ++is_space['\v'];
1160 ++is_space['\f'];
1161 ++is_space['\n'];
1162 ++is_space['\r'];
1163 }
1164
1165 void
1166 error VPROTO ((char * msg, ...))
1167 {
1168 #ifndef __STDC__
1169 char * msg;
1170 #endif
1171 va_list args;
1172
1173 VA_START (args, msg);
1174
1175 #ifndef __STDC__
1176 msg = va_arg (args, char *);
1177 #endif
1178
1179 fprintf (stderr, "error: ");
1180 vfprintf (stderr, msg, args);
1181 fprintf (stderr, "\n");
1182 va_end (args);
1183 }
1184
1185 void
1186 pedwarn VPROTO ((char * msg, ...))
1187 {
1188 #ifndef __STDC__
1189 char * msg;
1190 #endif
1191 va_list args;
1192
1193 VA_START (args, msg);
1194
1195 #ifndef __STDC__
1196 msg = va_arg (args, char *);
1197 #endif
1198
1199 fprintf (stderr, "pedwarn: ");
1200 vfprintf (stderr, msg, args);
1201 fprintf (stderr, "\n");
1202 va_end (args);
1203 }
1204
1205 void
1206 warning VPROTO ((char * msg, ...))
1207 {
1208 #ifndef __STDC__
1209 char * msg;
1210 #endif
1211 va_list args;
1212
1213 VA_START (args, msg);
1214
1215 #ifndef __STDC__
1216 msg = va_arg (args, char *);
1217 #endif
1218
1219 fprintf (stderr, "warning: ");
1220 vfprintf (stderr, msg, args);
1221 fprintf (stderr, "\n");
1222 va_end (args);
1223 }
1224
1225 int
1226 check_assertion (name, sym_length, tokens_specified, tokens)
1227 U_CHAR *name;
1228 int sym_length;
1229 int tokens_specified;
1230 struct arglist *tokens;
1231 {
1232 return 0;
1233 }
1234
1235 struct hashnode *
1236 lookup (name, len, hash)
1237 U_CHAR *name;
1238 int len;
1239 int hash;
1240 {
1241 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1242 }
1243
1244 GENERIC_PTR
1245 xmalloc (size)
1246 size_t size;
1247 {
1248 return (GENERIC_PTR) malloc (size);
1249 }
1250 #endif
This page took 0.083052 seconds and 5 git commands to generate.