OSDN Git Service

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