OSDN Git Service

(cppmain.o): New rule.
[pf3gnuchains/gcc-fork.git] / gcc / cexp.y
1 /* Parse C expressions for CCCP.
2    Copyright (C) 1987, 1992, 1994, 1995, 1996 Free Software Foundation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18
19  In other words, you are welcome to use, share and improve this program.
20  You are forbidden to forbid anyone else to use, share and improve
21  what you give them.   Help stamp out software-hoarding!
22
23  Adapted from expread.y of GDB by Paul Rubin, July 1986.  */
24
25 /* Parse a C expression from text in a string  */
26    
27 %{
28 #include "config.h"
29 #include <setjmp.h>
30 /* #define YYDEBUG 1 */
31
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
55 #ifdef MULTIBYTE_CHARS
56 #include <locale.h>
57 #endif
58
59 #include <stdio.h>
60
61 typedef unsigned char U_CHAR;
62
63 /* This is used for communicating lists of keywords with cccp.c.  */
64 struct arglist {
65   struct arglist *next;
66   U_CHAR *name;
67   int length;
68   int argno;
69 };
70
71 /* Define a generic NULL if one hasn't already been defined.  */
72
73 #ifndef NULL
74 #define NULL 0
75 #endif
76
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
85 #ifndef NULL_PTR
86 #define NULL_PTR ((GENERIC_PTR) 0)
87 #endif
88
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
104 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
105 # define __attribute__(x)
106 #endif
107
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
114 #endif
115
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     }
136 #endif
137
138 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
139
140 HOST_WIDE_INT parse_c_expression PROTO((char *));
141
142 static int yylex PROTO((void));
143 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
144 static HOST_WIDE_INT expression_value;
145
146 static jmp_buf parse_return_error;
147
148 /* Nonzero means count most punctuation as part of a name.  */
149 static int keyword_parsing = 0;
150
151 /* Nonzero means do not evaluate this expression.
152    This is a count, since unevaluated expressions can nest.  */
153 static int skip_evaluation;
154
155 /* some external tables of character types */
156 extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
157
158 /* Flag for -pedantic.  */
159 extern int pedantic;
160
161 /* Flag for -traditional.  */
162 extern 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
179
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
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
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
218 struct constant;
219
220 GENERIC_PTR xmalloc PROTO((size_t));
221 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
222 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
223 struct hashnode *lookup PROTO((U_CHAR *, int, int));
224 void error PRINTF_PROTO_1((char *, ...));
225 void pedwarn PRINTF_PROTO_1((char *, ...));
226 void warning PRINTF_PROTO_1((char *, ...));
227
228 static int parse_number PROTO((int));
229 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
230 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
231 static void integer_overflow PROTO((void));
232
233 /* `signedp' values */
234 #define SIGNED (~0)
235 #define UNSIGNED 0
236 %}
237
238 %union {
239   struct constant {HOST_WIDE_INT value; int signedp;} integer;
240   struct name {U_CHAR *address; int length;} name;
241   struct arglist *keywords;
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
268 start   :       exp1
269                 { expression_value = $1.value; }
270         ;
271
272 /* Expressions, including the comma operator.  */
273 exp1    :       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.  */
281 exp     :       '-' exp    %prec UNARY
282                         { $$.value = - $2.value;
283                           $$.signedp = $2.signedp;
284                           if (($$.value & $2.value & $$.signedp) < 0)
285                             integer_overflow (); }
286         |       '!' exp    %prec UNARY
287                         { $$.value = ! $2.value;
288                           $$.signedp = SIGNED; }
289         |       '+' exp    %prec UNARY
290                         { $$ = $2; }
291         |       '~' exp    %prec UNARY
292                         { $$.value = ~ $2.value;
293                           $$.signedp = $2.signedp; }
294         |       '#' NAME
295                         { $$.value = check_assertion ($2.address, $2.length,
296                                                       0, NULL_PTR);
297                           $$.signedp = SIGNED; }
298         |       '#' NAME
299                         { keyword_parsing = 1; }
300                 '(' keywords ')'
301                         { $$.value = check_assertion ($2.address, $2.length,
302                                                       1, $5);
303                           keyword_parsing = 0;
304                           $$.signedp = SIGNED; }
305         |       '(' exp1 ')'
306                         { $$ = $2; }
307         ;
308
309 /* Binary operators in order of decreasing precedence.  */
310 exp     :       exp '*' exp
311                         { $$.signedp = $1.signedp & $3.signedp;
312                           if ($$.signedp)
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 ();
319                             }
320                           else
321                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
322                                         * $3.value); }
323         |       exp '/' exp
324                         { if ($3.value == 0)
325                             {
326                               if (!skip_evaluation)
327                                 error ("division by zero in #if");
328                               $3.value = 1;
329                             }
330                           $$.signedp = $1.signedp & $3.signedp;
331                           if ($$.signedp)
332                             {
333                               $$.value = $1.value / $3.value;
334                               if (($$.value & $1.value & $3.value) < 0)
335                                 integer_overflow ();
336                             }
337                           else
338                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
339                                         / $3.value); }
340         |       exp '%' exp
341                         { if ($3.value == 0)
342                             {
343                               if (!skip_evaluation)
344                                 error ("division by zero in #if");
345                               $3.value = 1;
346                             }
347                           $$.signedp = $1.signedp & $3.signedp;
348                           if ($$.signedp)
349                             $$.value = $1.value % $3.value;
350                           else
351                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
352                                         % $3.value); }
353         |       exp '+' exp
354                         { $$.value = $1.value + $3.value;
355                           $$.signedp = $1.signedp & $3.signedp;
356                           if (overflow_sum_sign ($1.value, $3.value,
357                                                  $$.value, $$.signedp))
358                             integer_overflow (); }
359         |       exp '-' exp
360                         { $$.value = $1.value - $3.value;
361                           $$.signedp = $1.signedp & $3.signedp;
362                           if (overflow_sum_sign ($$.value, $3.value,
363                                                  $1.value, $$.signedp))
364                             integer_overflow (); }
365         |       exp LSH exp
366                         { $$.signedp = $1.signedp;
367                           if (($3.value & $3.signedp) < 0)
368                             $$.value = right_shift (&$1, -$3.value);
369                           else
370                             $$.value = left_shift (&$1, $3.value); }
371         |       exp RSH exp
372                         { $$.signedp = $1.signedp;
373                           if (($3.value & $3.signedp) < 0)
374                             $$.value = left_shift (&$1, -$3.value);
375                           else
376                             $$.value = right_shift (&$1, $3.value); }
377         |       exp EQUAL exp
378                         { $$.value = ($1.value == $3.value);
379                           $$.signedp = SIGNED; }
380         |       exp NOTEQUAL exp
381                         { $$.value = ($1.value != $3.value);
382                           $$.signedp = SIGNED; }
383         |       exp LEQ exp
384                         { $$.signedp = SIGNED;
385                           if ($1.signedp & $3.signedp)
386                             $$.value = $1.value <= $3.value;
387                           else
388                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
389                                         <= $3.value); }
390         |       exp GEQ exp
391                         { $$.signedp = SIGNED;
392                           if ($1.signedp & $3.signedp)
393                             $$.value = $1.value >= $3.value;
394                           else
395                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
396                                         >= $3.value); }
397         |       exp '<' exp
398                         { $$.signedp = SIGNED;
399                           if ($1.signedp & $3.signedp)
400                             $$.value = $1.value < $3.value;
401                           else
402                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
403                                         < $3.value); }
404         |       exp '>' exp
405                         { $$.signedp = SIGNED;
406                           if ($1.signedp & $3.signedp)
407                             $$.value = $1.value > $3.value;
408                           else
409                             $$.value = ((unsigned HOST_WIDE_INT) $1.value
410                                         > $3.value); }
411         |       exp '&' exp
412                         { $$.value = $1.value & $3.value;
413                           $$.signedp = $1.signedp & $3.signedp; }
414         |       exp '^' exp
415                         { $$.value = $1.value ^ $3.value;
416                           $$.signedp = $1.signedp & $3.signedp; }
417         |       exp '|' exp
418                         { $$.value = $1.value | $3.value;
419                           $$.signedp = $1.signedp & $3.signedp; }
420         |       exp AND
421                         { skip_evaluation += !$1.value; }
422                 exp
423                         { skip_evaluation -= !$1.value;
424                           $$.value = ($1.value && $4.value);
425                           $$.signedp = SIGNED; }
426         |       exp OR
427                         { skip_evaluation += !!$1.value; }
428                 exp
429                         { skip_evaluation -= !!$1.value;
430                           $$.value = ($1.value || $4.value);
431                           $$.signedp = SIGNED; }
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;
439                           $$.signedp = $4.signedp & $7.signedp; }
440         |       INT
441                         { $$ = yylval.integer; }
442         |       CHAR
443                         { $$ = yylval.integer; }
444         |       NAME
445                         { $$.value = 0;
446                           $$.signedp = SIGNED; }
447         ;
448
449 keywords :
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
475 static 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
483 static int
484 parse_number (olen)
485      int olen;
486 {
487   register char *p = lexptr;
488   register int c;
489   register unsigned HOST_WIDE_INT n = 0, nd, max_over_base;
490   register int base = 10;
491   register int len = olen;
492   register int overflow = 0;
493   register int digit, largest_digit = 0;
494   int spec_long = 0;
495
496   yylval.integer.signedp = SIGNED;
497
498   if (*p == '0') {
499     base = 8;
500     if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
501       p += 2;
502       base = 16;
503       len -= 2;
504     }
505   }
506
507   max_over_base = (unsigned HOST_WIDE_INT) -1 / base;
508
509   for (; len > 0; len--) {
510     c = *p++;
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 {
519       /* `l' means long, and `u' means unsigned.  */
520       while (1) {
521         if (c == 'l' || c == 'L')
522           {
523             if (!pedantic < spec_long)
524               yyerror ("too many `l's in integer constant");
525             spec_long++;
526           }
527         else if (c == 'u' || c == 'U')
528           {
529             if (! yylval.integer.signedp)
530               yyerror ("two `u's in integer constant");
531             yylval.integer.signedp = UNSIGNED;
532           }
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         }
543
544         if (--len == 0)
545           break;
546         c = *p++;
547       }
548       /* Don't look for any more digits after the suffixes.  */
549       break;
550     }
551     if (largest_digit < digit)
552       largest_digit = digit;
553     nd = n * base + digit;
554     overflow |= (max_over_base < n) | (nd < n);
555     n = nd;
556   }
557
558   if (base <= largest_digit)
559     warning ("integer constant contains digits beyond the radix");
560
561   if (overflow)
562     warning ("integer constant out of range");
563
564   /* If too big to be signed, consider it unsigned.  */
565   if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
566     {
567       if (base == 10)
568         warning ("integer constant is so large that it is unsigned");
569       yylval.integer.signedp = UNSIGNED;
570     }
571
572   lexptr = p;
573   yylval.integer.value = n;
574   return INT;
575 }
576
577 struct token {
578   char *operator;
579   int token;
580 };
581
582 static 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
598 static int
599 yylex ()
600 {
601   register int c;
602   register int namelen;
603   register unsigned char *tokstart;
604   register struct token *toktab;
605   int wide_flag;
606   HOST_WIDE_INT mask;
607
608  retry:
609
610   tokstart = (unsigned char *) lexptr;
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) {
627   case '\n':
628     return 0;
629     
630   case ' ':
631   case '\t':
632   case '\r':
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;
642         mask = MAX_WCHAR_TYPE_MASK;
643         goto char_constant;
644       }
645     if (lexptr[1] == '"')
646       {
647         lexptr++;
648         wide_flag = 1;
649         mask = MAX_WCHAR_TYPE_MASK;
650         goto string_constant;
651       }
652     break;
653
654   case '\'':
655     wide_flag = 0;
656     mask = MAX_CHAR_TYPE_MASK;
657   char_constant:
658     lexptr++;
659     if (keyword_parsing) {
660       char *start_ptr = lexptr - 1;
661       while (1) {
662         c = *lexptr++;
663         if (c == '\\')
664           c = parse_escape (&lexptr, mask);
665         else if (c == '\'')
666           break;
667       }
668       yylval.name.address = tokstart;
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     {
677       register HOST_WIDE_INT result = 0;
678       register num_chars = 0;
679       unsigned width = MAX_CHAR_TYPE_SIZE;
680       int max_chars;
681       char *token_buffer;
682
683       if (wide_flag)
684         {
685           width = MAX_WCHAR_TYPE_SIZE;
686 #ifdef MULTIBYTE_CHARS
687           max_chars = MB_CUR_MAX;
688 #else
689           max_chars = 1;
690 #endif
691         }
692       else
693         max_chars = MAX_LONG_TYPE_SIZE / width;
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             {
706               c = parse_escape (&lexptr, mask);
707             }
708
709           num_chars++;
710
711           /* Merge character into result; ignore excess chars.  */
712           if (num_chars <= max_chars)
713             {
714               if (width < HOST_BITS_PER_WIDE_INT)
715                 result = (result << width) | c;
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 ((U_CHAR *) "__CHAR_UNSIGNED__",
742                       sizeof ("__CHAR_UNSIGNED__") - 1, -1)
743               || ((result >> (num_bits - 1)) & 1) == 0)
744             yylval.integer.value
745               = result & (~ (unsigned HOST_WIDE_INT) 0
746                           >> (HOST_BITS_PER_WIDE_INT - num_bits));
747           else
748             yylval.integer.value
749               = result | ~(~ (unsigned HOST_WIDE_INT) 0
750                            >> (HOST_BITS_PER_WIDE_INT - num_bits));
751         }
752       else
753         {
754 #ifdef MULTIBYTE_CHARS
755           /* Set the initial shift state and convert the next sequence.  */
756           result = 0;
757           /* In all locales L'\0' is zero and mbtowc will return zero,
758              so don't use it.  */
759           if (num_chars > 1
760               || (num_chars == 1 && token_buffer[0] != '\0'))
761             {
762               wchar_t wc;
763               (void) mbtowc (NULL_PTR, NULL_PTR, 0);
764               if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
765                 result = wc;
766               else
767                 warning ("Ignoring invalid multibyte character");
768             }
769 #endif
770           yylval.integer.value = result;
771         }
772     }
773
774     /* This is always a signed type.  */
775     yylval.integer.signedp = SIGNED;
776     
777     return CHAR;
778
779     /* some of these chars are invalid in constant expressions;
780        maybe do something about them later */
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   case '#':
804     if (keyword_parsing)
805       break;
806   case '(':
807   case ')':
808     lexptr++;
809     return c;
810
811   case '"':
812     mask = MAX_CHAR_TYPE_MASK;
813   string_constant:
814     if (keyword_parsing) {
815       char *start_ptr = lexptr;
816       lexptr++;
817       while (1) {
818         c = *lexptr++;
819         if (c == '\\')
820           c = parse_escape (&lexptr, mask);
821         else if (c == '"')
822           break;
823       }
824       yylval.name.address = tokstart;
825       yylval.name.length = lexptr - start_ptr;
826       return NAME;
827     }
828     yyerror ("string constants not allowed in #if expressions");
829     return ERROR;
830   }
831
832   if (c >= '0' && c <= '9' && !keyword_parsing) {
833     /* It's a number */
834     for (namelen = 1; ; namelen++) {
835       int d = tokstart[namelen];
836       if (! ((is_idchar[d] || d == '.')
837              || ((d == '-' || d == '+') && (c == 'e' || c == 'E')
838                  && ! traditional)))
839         break;
840       c = d;
841     }
842     return parse_number (namelen);
843   }
844
845   /* It is a name.  See how long it is.  */
846
847   if (keyword_parsing) {
848     for (namelen = 0;; namelen++) {
849       if (is_hor_space[tokstart[namelen]])
850         break;
851       if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
852         break;
853       if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
854         break;
855     }
856   } else {
857     if (!is_idstart[c]) {
858       yyerror ("Invalid token in expression");
859       return ERROR;
860     }
861
862     for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
863       ;
864   }
865   
866   lexptr += namelen;
867   yylval.name.address = tokstart;
868   yylval.name.length = namelen;
869   return NAME;
870 }
871
872
873 /* Parse a C escape sequence.  STRING_PTR points to a variable
874    containing a pointer to the string to parse.  That pointer
875    is updated past the characters we use.  The value of the
876    escape sequence is returned.
877
878    RESULT_MASK is used to mask out the result;
879    an error is reported if bits are lost thereby.
880
881    A negative value means the sequence \ newline was seen,
882    which is supposed to be equivalent to nothing at all.
883
884    If \ is followed by a null character, we return a negative
885    value and leave the string pointer pointing at the null character.
886
887    If \ is followed by 000, we return 0 and leave the string pointer
888    after the zeros.  A value of 0 does not mean end of string.  */
889
890 HOST_WIDE_INT
891 parse_escape (string_ptr, result_mask)
892      char **string_ptr;
893      HOST_WIDE_INT result_mask;
894 {
895   register int c = *(*string_ptr)++;
896   switch (c)
897     {
898     case 'a':
899       return TARGET_BELL;
900     case 'b':
901       return TARGET_BS;
902     case 'e':
903     case 'E':
904       if (pedantic)
905         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
906       return 033;
907     case 'f':
908       return TARGET_FF;
909     case 'n':
910       return TARGET_NEWLINE;
911     case 'r':
912       return TARGET_CR;
913     case 't':
914       return TARGET_TAB;
915     case 'v':
916       return TARGET_VT;
917     case '\n':
918       return -2;
919     case 0:
920       (*string_ptr)--;
921       return 0;
922       
923     case '0':
924     case '1':
925     case '2':
926     case '3':
927     case '4':
928     case '5':
929     case '6':
930     case '7':
931       {
932         register HOST_WIDE_INT i = c - '0';
933         register int count = 0;
934         while (++count < 3)
935           {
936             c = *(*string_ptr)++;
937             if (c >= '0' && c <= '7')
938               i = (i << 3) + c - '0';
939             else
940               {
941                 (*string_ptr)--;
942                 break;
943               }
944           }
945         if (i != (i & result_mask))
946           {
947             i &= result_mask;
948             pedwarn ("octal escape sequence out of range");
949           }
950         return i;
951       }
952     case 'x':
953       {
954         register unsigned HOST_WIDE_INT i = 0, overflow = 0;
955         register int digits_found = 0, digit;
956         for (;;)
957           {
958             c = *(*string_ptr)++;
959             if (c >= '0' && c <= '9')
960               digit = c - '0';
961             else if (c >= 'a' && c <= 'f')
962               digit = c - 'a' + 10;
963             else if (c >= 'A' && c <= 'F')
964               digit = c - 'A' + 10;
965             else
966               {
967                 (*string_ptr)--;
968                 break;
969               }
970             overflow |= i ^ (i << 4 >> 4);
971             i = (i << 4) + digit;
972             digits_found = 1;
973           }
974         if (!digits_found)
975           yyerror ("\\x used with no following hex digits");
976         if (overflow | (i != (i & result_mask)))
977           {
978             i &= result_mask;
979             pedwarn ("hex escape sequence out of range");
980           }
981         return i;
982       }
983     default:
984       return c;
985     }
986 }
987
988 static void
989 yyerror (s)
990      char *s;
991 {
992   error ("%s", s);
993   skip_evaluation = 0;
994   longjmp (parse_return_error, 1);
995 }
996
997 static void
998 integer_overflow ()
999 {
1000   if (!skip_evaluation && pedantic)
1001     pedwarn ("integer overflow in preprocessor expression");
1002 }
1003
1004 static HOST_WIDE_INT
1005 left_shift (a, b)
1006      struct constant *a;
1007      unsigned HOST_WIDE_INT b;
1008 {
1009    /* It's unclear from the C standard whether shifts can overflow.
1010       The following code ignores overflow; perhaps a C standard
1011       interpretation ruling is needed.  */
1012   if (b >= HOST_BITS_PER_WIDE_INT)
1013     return 0;
1014   else
1015     return (unsigned HOST_WIDE_INT) a->value << b;
1016 }
1017
1018 static HOST_WIDE_INT
1019 right_shift (a, b)
1020      struct constant *a;
1021      unsigned HOST_WIDE_INT b;
1022 {
1023   if (b >= HOST_BITS_PER_WIDE_INT)
1024     return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1025   else if (a->signedp)
1026     return a->value >> b;
1027   else
1028     return (unsigned HOST_WIDE_INT) a->value >> b;
1029 }
1030 \f
1031 /* This page contains the entry point to this file.  */
1032
1033 /* Parse STRING as an expression, and complain if this fails
1034    to use up all of the contents of STRING.  */
1035 /* STRING may contain '\0' bytes; it is terminated by the first '\n'
1036    outside a string constant, so that we can diagnose '\0' properly.  */
1037 /* We do not support C comments.  They should be removed before
1038    this function is called.  */
1039
1040 HOST_WIDE_INT
1041 parse_c_expression (string)
1042      char *string;
1043 {
1044   lexptr = string;
1045   
1046   if (lexptr == 0 || *lexptr == 0) {
1047     error ("empty #if expression");
1048     return 0;                   /* don't include the #if group */
1049   }
1050
1051   /* if there is some sort of scanning error, just return 0 and assume
1052      the parsing routine has printed an error message somewhere.
1053      there is surely a better thing to do than this.     */
1054   if (setjmp (parse_return_error))
1055     return 0;
1056
1057   if (yyparse ())
1058     return 0;                   /* actually this is never reached
1059                                    the way things stand. */
1060   if (*lexptr != '\n')
1061     error ("Junk after end of expression.");
1062
1063   return expression_value;      /* set by yyparse () */
1064 }
1065 \f
1066 #ifdef TEST_EXP_READER
1067
1068 #if YYDEBUG
1069 extern int yydebug;
1070 #endif
1071
1072 int pedantic;
1073 int traditional;
1074
1075 int main PROTO((int, char **));
1076 static void initialize_random_junk PROTO((void));
1077
1078 /* Main program for testing purposes.  */
1079 int
1080 main (argc, argv)
1081      int argc;
1082      char **argv;
1083 {
1084   int n, c;
1085   char buf[1024];
1086
1087   pedantic = 1 < argc;
1088   traditional = 2 < argc;
1089 #if YYDEBUG
1090   yydebug = 3 < argc;
1091 #endif
1092   initialize_random_junk ();
1093
1094   for (;;) {
1095     printf ("enter expression: ");
1096     n = 0;
1097     while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1098       n++;
1099     if (c == EOF)
1100       break;
1101     printf ("parser returned %ld\n", (long) parse_c_expression (buf));
1102   }
1103
1104   return 0;
1105 }
1106
1107 /* table to tell if char can be part of a C identifier. */
1108 unsigned char is_idchar[256];
1109 /* table to tell if char can be first char of a c identifier. */
1110 unsigned char is_idstart[256];
1111 /* table to tell if c is horizontal space.  isspace () thinks that
1112    newline is space; this is not a good idea for this program. */
1113 unsigned char is_hor_space[256];
1114
1115 /*
1116  * initialize random junk in the hash table and maybe other places
1117  */
1118 static void
1119 initialize_random_junk ()
1120 {
1121   register int i;
1122
1123   /*
1124    * Set up is_idchar and is_idstart tables.  These should be
1125    * faster than saying (is_alpha (c) || c == '_'), etc.
1126    * Must do set up these things before calling any routines tthat
1127    * refer to them.
1128    */
1129   for (i = 'a'; i <= 'z'; i++) {
1130     ++is_idchar[i - 'a' + 'A'];
1131     ++is_idchar[i];
1132     ++is_idstart[i - 'a' + 'A'];
1133     ++is_idstart[i];
1134   }
1135   for (i = '0'; i <= '9'; i++)
1136     ++is_idchar[i];
1137   ++is_idchar['_'];
1138   ++is_idstart['_'];
1139   ++is_idchar['$'];
1140   ++is_idstart['$'];
1141
1142   /* horizontal space table */
1143   ++is_hor_space[' '];
1144   ++is_hor_space['\t'];
1145 }
1146
1147 void
1148 error (PRINTF_ALIST (msg))
1149      PRINTF_DCL (msg)
1150 {
1151   va_list args;
1152
1153   VA_START (args, msg);
1154   fprintf (stderr, "error: ");
1155   vfprintf (stderr, msg, args);
1156   fprintf (stderr, "\n");
1157   va_end (args);
1158 }
1159
1160 void
1161 pedwarn (PRINTF_ALIST (msg))
1162      PRINTF_DCL (msg)
1163 {
1164   va_list args;
1165
1166   VA_START (args, msg);
1167   fprintf (stderr, "pedwarn: ");
1168   vfprintf (stderr, msg, args);
1169   fprintf (stderr, "\n");
1170   va_end (args);
1171 }
1172
1173 void
1174 warning (PRINTF_ALIST (msg))
1175      PRINTF_DCL (msg)
1176 {
1177   va_list args;
1178
1179   VA_START (args, msg);
1180   fprintf (stderr, "warning: ");
1181   vfprintf (stderr, msg, args);
1182   fprintf (stderr, "\n");
1183   va_end (args);
1184 }
1185
1186 int
1187 check_assertion (name, sym_length, tokens_specified, tokens)
1188      U_CHAR *name;
1189      int sym_length;
1190      int tokens_specified;
1191      struct arglist *tokens;
1192 {
1193   return 0;
1194 }
1195
1196 struct hashnode *
1197 lookup (name, len, hash)
1198      U_CHAR *name;
1199      int len;
1200      int hash;
1201 {
1202   return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1203 }
1204
1205 GENERIC_PTR
1206 xmalloc (size)
1207      size_t size;
1208 {
1209   return (GENERIC_PTR) malloc (size);
1210 }
1211 #endif