OSDN Git Service

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