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