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