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