OSDN Git Service

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