OSDN Git Service

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