OSDN Git Service

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