OSDN Git Service

Formattign changes.
[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 ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
742               || ((result >> (num_bits - 1)) & 1) == 0)
743             yylval.integer.value
744               = result & (~ (unsigned HOST_WIDE_INT) 0
745                           >> (HOST_BITS_PER_WIDE_INT - num_bits));
746           else
747             yylval.integer.value
748               = result | ~(~ (unsigned HOST_WIDE_INT) 0
749                            >> (HOST_BITS_PER_WIDE_INT - num_bits));
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.  */
774     yylval.integer.signedp = SIGNED;
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 '"':
811     mask = MAX_CHAR_TYPE_MASK;
812   string_constant:
813     if (keyword_parsing) {
814       char *start_ptr = lexptr;
815       lexptr++;
816       while (1) {
817         c = *lexptr++;
818         if (c == '\\')
819           c = parse_escape (&lexptr, mask);
820         else if (c == '"')
821           break;
822       }
823       yylval.name.address = tokstart;
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 */
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     }
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;
866   yylval.name.address = tokstart;
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
877    RESULT_MASK is used to mask out the result;
878    an error is reported if bits are lost thereby.
879
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
889 HOST_WIDE_INT
890 parse_escape (string_ptr, result_mask)
891      char **string_ptr;
892      HOST_WIDE_INT result_mask;
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':
902     case 'E':
903       if (pedantic)
904         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
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;
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       {
931         register HOST_WIDE_INT i = c - '0';
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           }
944         if (i != (i & result_mask))
945           {
946             i &= result_mask;
947             pedwarn ("octal escape sequence out of range");
948           }
949         return i;
950       }
951     case 'x':
952       {
953         register unsigned HOST_WIDE_INT i = 0, overflow = 0;
954         register int digits_found = 0, digit;
955         for (;;)
956           {
957             c = *(*string_ptr)++;
958             if (c >= '0' && c <= '9')
959               digit = c - '0';
960             else if (c >= 'a' && c <= 'f')
961               digit = c - 'a' + 10;
962             else if (c >= 'A' && c <= 'F')
963               digit = c - 'A' + 10;
964             else
965               {
966                 (*string_ptr)--;
967                 break;
968               }
969             overflow |= i ^ (i << 4 >> 4);
970             i = (i << 4) + digit;
971             digits_found = 1;
972           }
973         if (!digits_found)
974           yyerror ("\\x used with no following hex digits");
975         if (overflow | (i != (i & result_mask)))
976           {
977             i &= result_mask;
978             pedwarn ("hex escape sequence out of range");
979           }
980         return i;
981       }
982     default:
983       return c;
984     }
985 }
986
987 static void
988 yyerror (s)
989      char *s;
990 {
991   error ("%s", s);
992   skip_evaluation = 0;
993   longjmp (parse_return_error, 1);
994 }
995
996 static void
997 integer_overflow ()
998 {
999   if (!skip_evaluation && pedantic)
1000     pedwarn ("integer overflow in preprocessor expression");
1001 }
1002
1003 static HOST_WIDE_INT
1004 left_shift (a, b)
1005      struct constant *a;
1006      unsigned HOST_WIDE_INT b;
1007 {
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.  */
1011   if (b >= HOST_BITS_PER_WIDE_INT)
1012     return 0;
1013   else
1014     return (unsigned HOST_WIDE_INT) a->value << b;
1015 }
1016
1017 static HOST_WIDE_INT
1018 right_shift (a, b)
1019      struct constant *a;
1020      unsigned HOST_WIDE_INT b;
1021 {
1022   if (b >= HOST_BITS_PER_WIDE_INT)
1023     return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1024   else if (a->signedp)
1025     return a->value >> b;
1026   else
1027     return (unsigned HOST_WIDE_INT) a->value >> b;
1028 }
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.  */
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.  */
1036 /* We do not support C comments.  They should be removed before
1037    this function is called.  */
1038
1039 HOST_WIDE_INT
1040 parse_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. */
1059   if (*lexptr != '\n')
1060     error ("Junk after end of expression.");
1061
1062   return expression_value;      /* set by yyparse () */
1063 }
1064 \f
1065 #ifdef TEST_EXP_READER
1066
1067 #if YYDEBUG
1068 extern int yydebug;
1069 #endif
1070
1071 int pedantic;
1072 int traditional;
1073
1074 int main PROTO((int, char **));
1075 static void initialize_random_junk PROTO((void));
1076
1077 /* Main program for testing purposes.  */
1078 int
1079 main (argc, argv)
1080      int argc;
1081      char **argv;
1082 {
1083   int n, c;
1084   char buf[1024];
1085
1086   pedantic = 1 < argc;
1087   traditional = 2 < argc;
1088 #if YYDEBUG
1089   yydebug = 3 < argc;
1090 #endif
1091   initialize_random_junk ();
1092
1093   for (;;) {
1094     printf ("enter expression: ");
1095     n = 0;
1096     while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1097       n++;
1098     if (c == EOF)
1099       break;
1100     printf ("parser returned %ld\n", (long) parse_c_expression (buf));
1101   }
1102
1103   return 0;
1104 }
1105
1106 /* table to tell if char can be part of a C identifier. */
1107 unsigned char is_idchar[256];
1108 /* table to tell if char can be first char of a c identifier. */
1109 unsigned 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. */
1112 unsigned char is_hor_space[256];
1113
1114 /*
1115  * initialize random junk in the hash table and maybe other places
1116  */
1117 static void
1118 initialize_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
1148 void
1149 error (PRINTF_ALIST (msg))
1150      PRINTF_DCL (msg)
1151 {
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);
1159 }
1160
1161 void
1162 pedwarn (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
1174 void
1175 warning (PRINTF_ALIST (msg))
1176      PRINTF_DCL (msg)
1177 {
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
1187 int
1188 check_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;
1195 }
1196
1197 struct hashnode *
1198 lookup (name, len, hash)
1199      U_CHAR *name;
1200      int len;
1201      int hash;
1202 {
1203   return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1204 }
1205
1206 GENERIC_PTR
1207 xmalloc (size)
1208      size_t size;
1209 {
1210   return (GENERIC_PTR) malloc (size);
1211 }
1212 #endif