]> gcc.gnu.org Git - gcc.git/blame - gcc/c-lex.c
(forget_protocol_qualifiers): Cast enums to int before comparing.
[gcc.git] / gcc / c-lex.c
CommitLineData
d45cf215 1/* Lexical analyzer for C and Objective C.
e8bbfc4e
RK
2 Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <stdio.h>
22#include <errno.h>
23#include <setjmp.h>
24
25#include "config.h"
26#include "rtl.h"
27#include "tree.h"
28#include "input.h"
29#include "c-lex.h"
30#include "c-tree.h"
31#include "flags.h"
32#include "c-parse.h"
33
34#ifdef MULTIBYTE_CHARS
35#include <stdlib.h>
36#include <locale.h>
37#endif
38
39#ifndef errno
40extern int errno;
41#endif
42
43/* The elements of `ridpointers' are identifier nodes
44 for the reserved type names and storage classes.
45 It is indexed by a RID_... value. */
46tree ridpointers[(int) RID_MAX];
47
48/* Cause the `yydebug' variable to be defined. */
49#define YYDEBUG 1
50
51/* the declaration found for the last IDENTIFIER token read in.
52 yylex must look this up to detect typedefs, which get token type TYPENAME,
53 so it is left around in case the identifier is not a typedef but is
54 used in a context which makes it a reference to a variable. */
55tree lastiddecl;
56
57/* Nonzero enables objc features. */
58
59int doing_objc_thang;
60
e31c7eec 61extern tree is_class_name ();
e8bbfc4e
RK
62
63extern int yydebug;
64
65/* File used for outputting assembler code. */
66extern FILE *asm_out_file;
67
68#ifndef WCHAR_TYPE_SIZE
69#ifdef INT_TYPE_SIZE
70#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
71#else
72#define WCHAR_TYPE_SIZE BITS_PER_WORD
73#endif
74#endif
75
76/* Number of bytes in a wide character. */
77#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
78
79static int maxtoken; /* Current nominal length of token buffer. */
80char *token_buffer; /* Pointer to token buffer.
81 Actual allocated length is maxtoken + 2.
82 This is not static because objc-parse.y uses it. */
83
84/* Nonzero if end-of-file has been seen on input. */
85static int end_of_file;
86
87/* Buffered-back input character; faster than using ungetc. */
88static int nextchar = -1;
89
90int check_newline ();
91
92/* Nonzero tells yylex to ignore \ in string constants. */
93static int ignore_escape_flag = 0;
94\f
95/* C code produced by gperf version 2.5 (GNU C++ version) */
e31c7eec 96/* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */
e8bbfc4e
RK
97struct resword { char *name; short token; enum rid rid; };
98
e31c7eec 99#define TOTAL_KEYWORDS 79
e8bbfc4e 100#define MIN_WORD_LENGTH 2
e31c7eec 101#define MAX_WORD_LENGTH 20
c4c7fef1 102#define MIN_HASH_VALUE 10
e31c7eec
TW
103#define MAX_HASH_VALUE 144
104/* maximum key range = 135, duplicates = 0 */
e8bbfc4e
RK
105
106#ifdef __GNUC__
107__inline
108#endif
109static unsigned int
110hash (str, len)
111 register char *str;
112 register int unsigned len;
113{
114 static unsigned char asso_values[] =
115 {
e31c7eec
TW
116 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
117 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
118 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
119 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
120 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
121 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
122 145, 145, 145, 145, 25, 145, 145, 145, 145, 145,
123 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
124 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
125 145, 145, 145, 145, 145, 1, 145, 46, 8, 15,
126 61, 6, 36, 48, 3, 5, 145, 18, 63, 25,
127 29, 76, 1, 145, 13, 2, 1, 51, 37, 9,
128 9, 1, 3, 145, 145, 145, 145, 145,
e8bbfc4e
RK
129 };
130 register int hval = len;
131
132 switch (hval)
133 {
134 default:
135 case 3:
136 hval += asso_values[str[2]];
137 case 2:
138 case 1:
139 hval += asso_values[str[0]];
140 }
141 return hval + asso_values[str[len - 1]];
142}
143
e31c7eec
TW
144static struct resword wordlist[] =
145{
146 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
147 {"",},
148 {"int", TYPESPEC, RID_INT},
149 {"",}, {"",},
150 {"__typeof__", TYPEOF, NORID},
151 {"__signed__", TYPESPEC, RID_SIGNED},
152 {"__imag__", IMAGPART, NORID},
153 {"switch", SWITCH, NORID},
154 {"__inline__", SCSPEC, RID_INLINE},
155 {"else", ELSE, NORID},
156 {"__iterator__", SCSPEC, RID_ITERATOR},
157 {"__inline", SCSPEC, RID_INLINE},
158 {"__extension__", EXTENSION, NORID},
159 {"struct", STRUCT, NORID},
160 {"__real__", REALPART, NORID},
161 {"__const", TYPE_QUAL, RID_CONST},
162 {"while", WHILE, NORID},
163 {"__const__", TYPE_QUAL, RID_CONST},
164 {"case", CASE, NORID},
165 {"__complex__", TYPESPEC, RID_COMPLEX},
166 {"__iterator", SCSPEC, RID_ITERATOR},
167 {"bycopy", TYPE_QUAL, RID_BYCOPY},
168 {"",}, {"",}, {"",},
169 {"__complex", TYPESPEC, RID_COMPLEX},
170 {"",},
171 {"in", TYPE_QUAL, RID_IN},
172 {"break", BREAK, NORID},
173 {"@defs", DEFS, NORID},
174 {"",}, {"",}, {"",},
175 {"extern", SCSPEC, RID_EXTERN},
176 {"if", IF, NORID},
177 {"typeof", TYPEOF, NORID},
178 {"typedef", SCSPEC, RID_TYPEDEF},
179 {"__typeof", TYPEOF, NORID},
180 {"sizeof", SIZEOF, NORID},
181 {"",},
182 {"return", RETURN, NORID},
183 {"const", TYPE_QUAL, RID_CONST},
184 {"__volatile__", TYPE_QUAL, RID_VOLATILE},
185 {"@private", PRIVATE, NORID},
186 {"@selector", SELECTOR, NORID},
187 {"__volatile", TYPE_QUAL, RID_VOLATILE},
188 {"__asm__", ASM_KEYWORD, NORID},
189 {"",}, {"",},
190 {"continue", CONTINUE, NORID},
191 {"__alignof__", ALIGNOF, NORID},
192 {"__imag", IMAGPART, NORID},
193 {"__attribute__", ATTRIBUTE, NORID},
194 {"",}, {"",},
195 {"__attribute", ATTRIBUTE, NORID},
196 {"for", FOR, NORID},
197 {"",},
198 {"@encode", ENCODE, NORID},
199 {"id", OBJECTNAME, RID_ID},
200 {"static", SCSPEC, RID_STATIC},
201 {"@interface", INTERFACE, NORID},
202 {"",},
203 {"__signed", TYPESPEC, RID_SIGNED},
204 {"",},
205 {"__label__", LABEL, NORID},
206 {"",}, {"",},
207 {"__asm", ASM_KEYWORD, NORID},
208 {"char", TYPESPEC, RID_CHAR},
209 {"",},
210 {"inline", SCSPEC, RID_INLINE},
211 {"out", TYPE_QUAL, RID_OUT},
212 {"register", SCSPEC, RID_REGISTER},
213 {"__real", REALPART, NORID},
214 {"short", TYPESPEC, RID_SHORT},
215 {"",},
216 {"enum", ENUM, NORID},
217 {"inout", TYPE_QUAL, RID_INOUT},
218 {"",},
219 {"oneway", TYPE_QUAL, RID_ONEWAY},
220 {"union", UNION, NORID},
221 {"",},
222 {"__alignof", ALIGNOF, NORID},
223 {"",},
224 {"@implementation", IMPLEMENTATION, NORID},
225 {"",},
226 {"@class", CLASS, NORID},
227 {"",},
228 {"@public", PUBLIC, NORID},
229 {"asm", ASM_KEYWORD, NORID},
230 {"",}, {"",}, {"",}, {"",}, {"",},
231 {"default", DEFAULT, NORID},
232 {"",},
233 {"void", TYPESPEC, RID_VOID},
234 {"",},
235 {"@protected", PROTECTED, NORID},
236 {"@protocol", PROTOCOL, NORID},
237 {"",}, {"",}, {"",},
238 {"volatile", TYPE_QUAL, RID_VOLATILE},
239 {"",}, {"",},
240 {"signed", TYPESPEC, RID_SIGNED},
241 {"float", TYPESPEC, RID_FLOAT},
242 {"@end", END, NORID},
243 {"",}, {"",},
244 {"unsigned", TYPESPEC, RID_UNSIGNED},
245 {"@compatibility_alias", ALIAS, NORID},
246 {"double", TYPESPEC, RID_DOUBLE},
247 {"",}, {"",},
248 {"auto", SCSPEC, RID_AUTO},
249 {"",},
250 {"goto", GOTO, NORID},
251 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
252 {"do", DO, NORID},
253 {"",}, {"",}, {"",}, {"",},
254 {"long", TYPESPEC, RID_LONG},
255};
256
e8bbfc4e
RK
257#ifdef __GNUC__
258__inline
259#endif
260struct resword *
261is_reserved_word (str, len)
262 register char *str;
263 register unsigned int len;
264{
e8bbfc4e
RK
265 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
266 {
267 register int key = hash (str, len);
268
269 if (key <= MAX_HASH_VALUE && key >= 0)
270 {
271 register char *s = wordlist[key].name;
272
273 if (*s == *str && !strcmp (str + 1, s + 1))
274 return &wordlist[key];
275 }
276 }
277 return 0;
278}
279\f
280/* Return something to represent absolute declarators containing a *.
281 TARGET is the absolute declarator that the * contains.
282 TYPE_QUALS is a list of modifiers such as const or volatile
283 to apply to the pointer type, represented as identifiers.
284
285 We return an INDIRECT_REF whose "contents" are TARGET
286 and whose type is the modifier list. */
287
288tree
289make_pointer_declarator (type_quals, target)
290 tree type_quals, target;
291{
292 return build1 (INDIRECT_REF, type_quals, target);
293}
294\f
295void
e31c7eec
TW
296forget_protocol_qualifiers ()
297{
298 int i, n = sizeof wordlist / sizeof (struct resword);
299
300 for (i = 0; i < n; i++)
ea64849e
RK
301 if ((int) wordlist[i].rid >= (int) RID_IN
302 && (int) wordlist[i].rid <= (int) RID_ONEWAY)
e31c7eec
TW
303 wordlist[i].name = "";
304}
305
306void
307remember_protocol_qualifiers ()
308{
309 int i, n = sizeof wordlist / sizeof (struct resword);
310
311 for (i = 0; i < n; i++)
312 if (wordlist[i].rid == RID_IN)
313 wordlist[i].name = "in";
314 else if (wordlist[i].rid == RID_OUT)
315 wordlist[i].name = "out";
316 else if (wordlist[i].rid == RID_INOUT)
317 wordlist[i].name = "inout";
318 else if (wordlist[i].rid == RID_BYCOPY)
319 wordlist[i].name = "bycopy";
320 else if (wordlist[i].rid == RID_ONEWAY)
321 wordlist[i].name = "oneway";
322}
323\f
324void
e8bbfc4e
RK
325init_lex ()
326{
327 /* Make identifier nodes long enough for the language-specific slots. */
328 set_identifier_size (sizeof (struct lang_identifier));
329
330 /* Start it at 0, because check_newline is called at the very beginning
331 and will increment it to 1. */
332 lineno = 0;
333
334#ifdef MULTIBYTE_CHARS
335 /* Change to the native locale for multibyte conversions. */
336 setlocale (LC_CTYPE, "");
337#endif
338
339 maxtoken = 40;
340 token_buffer = (char *) xmalloc (maxtoken + 2);
341
342 ridpointers[(int) RID_INT] = get_identifier ("int");
343 ridpointers[(int) RID_CHAR] = get_identifier ("char");
344 ridpointers[(int) RID_VOID] = get_identifier ("void");
345 ridpointers[(int) RID_FLOAT] = get_identifier ("float");
346 ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
347 ridpointers[(int) RID_SHORT] = get_identifier ("short");
348 ridpointers[(int) RID_LONG] = get_identifier ("long");
349 ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
350 ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
351 ridpointers[(int) RID_INLINE] = get_identifier ("inline");
352 ridpointers[(int) RID_CONST] = get_identifier ("const");
353 ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
354 ridpointers[(int) RID_AUTO] = get_identifier ("auto");
355 ridpointers[(int) RID_STATIC] = get_identifier ("static");
356 ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
357 ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
358 ridpointers[(int) RID_REGISTER] = get_identifier ("register");
6506ecd7 359 ridpointers[(int) RID_ITERATOR] = get_identifier ("iterator");
122026c0 360 ridpointers[(int) RID_COMPLEX] = get_identifier ("complex");
e31c7eec
TW
361 ridpointers[(int) RID_ID] = get_identifier ("id");
362 ridpointers[(int) RID_IN] = get_identifier ("in");
363 ridpointers[(int) RID_OUT] = get_identifier ("out");
364 ridpointers[(int) RID_INOUT] = get_identifier ("inout");
365 ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
366 ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
367 forget_protocol_qualifiers();
e8bbfc4e
RK
368
369 /* Some options inhibit certain reserved words.
370 Clear those words out of the hash table so they won't be recognized. */
371#define UNSET_RESERVED_WORD(STRING) \
372 do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
373 if (s) s->name = ""; } while (0)
374
e31c7eec
TW
375 if (! doing_objc_thang)
376 UNSET_RESERVED_WORD ("id");
377
e8bbfc4e
RK
378 if (flag_traditional)
379 {
380 UNSET_RESERVED_WORD ("const");
381 UNSET_RESERVED_WORD ("volatile");
382 UNSET_RESERVED_WORD ("typeof");
383 UNSET_RESERVED_WORD ("signed");
384 UNSET_RESERVED_WORD ("inline");
6f2f09cd 385 UNSET_RESERVED_WORD ("iterator");
122026c0 386 UNSET_RESERVED_WORD ("complex");
e8bbfc4e
RK
387 }
388 if (flag_no_asm)
389 {
390 UNSET_RESERVED_WORD ("asm");
391 UNSET_RESERVED_WORD ("typeof");
392 UNSET_RESERVED_WORD ("inline");
6f2f09cd 393 UNSET_RESERVED_WORD ("iterator");
122026c0 394 UNSET_RESERVED_WORD ("complex");
e8bbfc4e
RK
395 }
396}
397
398void
399reinit_parse_for_function ()
400{
401}
402\f
403/* Function used when yydebug is set, to print a token in more detail. */
404
405void
406yyprint (file, yychar, yylval)
407 FILE *file;
408 int yychar;
409 YYSTYPE yylval;
410{
411 tree t;
412 switch (yychar)
413 {
414 case IDENTIFIER:
415 case TYPENAME:
e31c7eec 416 case OBJECTNAME:
e8bbfc4e
RK
417 t = yylval.ttype;
418 if (IDENTIFIER_POINTER (t))
419 fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
420 break;
421
422 case CONSTANT:
423 t = yylval.ttype;
424 if (TREE_CODE (t) == INTEGER_CST)
8d9bfdc5
RK
425 fprintf (file,
426#if HOST_BITS_PER_WIDE_INT == 64
427#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
428 " 0x%lx%016lx",
429#else
430 " 0x%x%016x",
431#endif
432#else
433#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
434 " 0x%lx%08lx",
435#else
436 " 0x%x%08x",
437#endif
438#endif
439 TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
e8bbfc4e
RK
440 break;
441 }
442}
443
444\f
445/* If C is not whitespace, return C.
446 Otherwise skip whitespace and return first nonwhite char read. */
447
448static int
449skip_white_space (c)
450 register int c;
451{
0dcd8cee 452 static int newline_warning = 0;
e8bbfc4e
RK
453
454 for (;;)
455 {
456 switch (c)
457 {
0dcd8cee
RS
458 /* We don't recognize comments here, because
459 cpp output can include / and * consecutively as operators.
460 Also, there's no need, since cpp removes all comments. */
e8bbfc4e
RK
461
462 case '\n':
463 c = check_newline ();
464 break;
465
466 case ' ':
467 case '\t':
468 case '\f':
e8bbfc4e
RK
469 case '\v':
470 case '\b':
471 c = getc (finput);
472 break;
473
0dcd8cee
RS
474 case '\r':
475 /* ANSI C says the effects of a carriage return in a source file
476 are undefined. */
477 if (pedantic && !newline_warning)
478 {
479 warning ("carriage return in source file");
480 warning ("(we only warn about the first carriage return)");
481 newline_warning = 1;
482 }
483 c = getc (finput);
484 break;
485
e8bbfc4e
RK
486 case '\\':
487 c = getc (finput);
488 if (c == '\n')
489 lineno++;
490 else
491 error ("stray '\\' in program");
492 c = getc (finput);
493 break;
494
495 default:
496 return (c);
497 }
498 }
499}
500
501/* Skips all of the white space at the current location in the input file.
502 Must use and reset nextchar if it has the next character. */
503
504void
505position_after_white_space ()
506{
507 register int c;
508
509 if (nextchar != -1)
510 c = nextchar, nextchar = -1;
511 else
512 c = getc (finput);
513
514 ungetc (skip_white_space (c), finput);
515}
516
517/* Make the token buffer longer, preserving the data in it.
518 P should point to just beyond the last valid character in the old buffer.
519 The value we return is a pointer to the new buffer
520 at a place corresponding to P. */
521
522static char *
523extend_token_buffer (p)
524 char *p;
525{
526 int offset = p - token_buffer;
527
528 maxtoken = maxtoken * 2 + 10;
529 token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
530
531 return token_buffer + offset;
532}
533\f
534/* At the beginning of a line, increment the line number
535 and process any #-directive on this line.
536 If the line is a #-directive, read the entire line and return a newline.
537 Otherwise, return the line's first non-whitespace character. */
538
539int
540check_newline ()
541{
542 register int c;
543 register int token;
544
545 lineno++;
546
547 /* Read first nonwhite char on the line. */
548
549 c = getc (finput);
550 while (c == ' ' || c == '\t')
551 c = getc (finput);
552
553 if (c != '#')
554 {
555 /* If not #, return it so caller will use it. */
556 return c;
557 }
558
559 /* Read first nonwhite char after the `#'. */
560
561 c = getc (finput);
562 while (c == ' ' || c == '\t')
563 c = getc (finput);
564
565 /* If a letter follows, then if the word here is `line', skip
566 it and ignore it; otherwise, ignore the line, with an error
567 if the word isn't `pragma', `ident', `define', or `undef'. */
568
569 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
570 {
571 if (c == 'p')
572 {
573 if (getc (finput) == 'r'
574 && getc (finput) == 'a'
575 && getc (finput) == 'g'
576 && getc (finput) == 'm'
577 && getc (finput) == 'a'
578 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
579 {
ca5b800a 580#ifdef HANDLE_SYSV_PRAGMA
a3100298 581 return handle_sysv_pragma (finput, c);
ca5b800a 582#endif /* HANDLE_SYSV_PRAGMA */
e8bbfc4e
RK
583#ifdef HANDLE_PRAGMA
584 HANDLE_PRAGMA (finput);
585#endif /* HANDLE_PRAGMA */
586 goto skipline;
587 }
588 }
589
590 else if (c == 'd')
591 {
592 if (getc (finput) == 'e'
593 && getc (finput) == 'f'
594 && getc (finput) == 'i'
595 && getc (finput) == 'n'
596 && getc (finput) == 'e'
597 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
598 {
599#ifdef DWARF_DEBUGGING_INFO
600 if ((debug_info_level == DINFO_LEVEL_VERBOSE)
601 && (write_symbols == DWARF_DEBUG))
602 dwarfout_define (lineno, get_directive_line (finput));
603#endif /* DWARF_DEBUGGING_INFO */
604 goto skipline;
605 }
606 }
607 else if (c == 'u')
608 {
609 if (getc (finput) == 'n'
610 && getc (finput) == 'd'
611 && getc (finput) == 'e'
612 && getc (finput) == 'f'
613 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
614 {
615#ifdef DWARF_DEBUGGING_INFO
616 if ((debug_info_level == DINFO_LEVEL_VERBOSE)
617 && (write_symbols == DWARF_DEBUG))
618 dwarfout_undef (lineno, get_directive_line (finput));
619#endif /* DWARF_DEBUGGING_INFO */
620 goto skipline;
621 }
622 }
623 else if (c == 'l')
624 {
625 if (getc (finput) == 'i'
626 && getc (finput) == 'n'
627 && getc (finput) == 'e'
628 && ((c = getc (finput)) == ' ' || c == '\t'))
629 goto linenum;
630 }
631 else if (c == 'i')
632 {
633 if (getc (finput) == 'd'
634 && getc (finput) == 'e'
635 && getc (finput) == 'n'
636 && getc (finput) == 't'
637 && ((c = getc (finput)) == ' ' || c == '\t'))
638 {
639 /* #ident. The pedantic warning is now in cccp.c. */
640
641 /* Here we have just seen `#ident '.
642 A string constant should follow. */
643
644 while (c == ' ' || c == '\t')
645 c = getc (finput);
646
647 /* If no argument, ignore the line. */
648 if (c == '\n')
649 return c;
650
651 ungetc (c, finput);
652 token = yylex ();
653 if (token != STRING
654 || TREE_CODE (yylval.ttype) != STRING_CST)
655 {
656 error ("invalid #ident");
657 goto skipline;
658 }
659
660 if (!flag_no_ident)
661 {
662#ifdef ASM_OUTPUT_IDENT
663 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
664#endif
665 }
666
667 /* Skip the rest of this line. */
668 goto skipline;
669 }
670 }
671
672 error ("undefined or invalid # directive");
673 goto skipline;
674 }
675
676linenum:
677 /* Here we have either `#line' or `# <nonletter>'.
678 In either case, it should be a line number; a digit should follow. */
679
680 while (c == ' ' || c == '\t')
681 c = getc (finput);
682
683 /* If the # is the only nonwhite char on the line,
684 just ignore it. Check the new newline. */
685 if (c == '\n')
686 return c;
687
688 /* Something follows the #; read a token. */
689
690 ungetc (c, finput);
691 token = yylex ();
692
693 if (token == CONSTANT
694 && TREE_CODE (yylval.ttype) == INTEGER_CST)
695 {
696 int old_lineno = lineno;
697 int used_up = 0;
698 /* subtract one, because it is the following line that
699 gets the specified number */
700
701 int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
702
703 /* Is this the last nonwhite stuff on the line? */
704 c = getc (finput);
705 while (c == ' ' || c == '\t')
706 c = getc (finput);
707 if (c == '\n')
708 {
709 /* No more: store the line number and check following line. */
710 lineno = l;
711 return c;
712 }
713 ungetc (c, finput);
714
715 /* More follows: it must be a string constant (filename). */
716
717 /* Read the string constant, but don't treat \ as special. */
718 ignore_escape_flag = 1;
719 token = yylex ();
720 ignore_escape_flag = 0;
721
722 if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
723 {
724 error ("invalid #line");
725 goto skipline;
726 }
727
728 input_filename
729 = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
730 strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
731 lineno = l;
732
733 /* Each change of file name
734 reinitializes whether we are now in a system header. */
735 in_system_header = 0;
736
737 if (main_input_filename == 0)
738 main_input_filename = input_filename;
739
740 /* Is this the last nonwhite stuff on the line? */
741 c = getc (finput);
742 while (c == ' ' || c == '\t')
743 c = getc (finput);
744 if (c == '\n')
5b450ae5
RS
745 {
746 /* Update the name in the top element of input_file_stack. */
747 if (input_file_stack)
748 input_file_stack->name = input_filename;
749
750 return c;
751 }
e8bbfc4e
RK
752 ungetc (c, finput);
753
754 token = yylex ();
755 used_up = 0;
756
757 /* `1' after file name means entering new file.
758 `2' after file name means just left a file. */
759
760 if (token == CONSTANT
761 && TREE_CODE (yylval.ttype) == INTEGER_CST)
762 {
763 if (TREE_INT_CST_LOW (yylval.ttype) == 1)
764 {
765 /* Pushing to a new file. */
766 struct file_stack *p
767 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
768 input_file_stack->line = old_lineno;
769 p->next = input_file_stack;
770 p->name = input_filename;
771 input_file_stack = p;
772 input_file_stack_tick++;
773#ifdef DWARF_DEBUGGING_INFO
774 if (debug_info_level == DINFO_LEVEL_VERBOSE
775 && write_symbols == DWARF_DEBUG)
776 dwarfout_start_new_source_file (input_filename);
777#endif /* DWARF_DEBUGGING_INFO */
778
779 used_up = 1;
780 }
781 else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
782 {
783 /* Popping out of a file. */
784 if (input_file_stack->next)
785 {
786 struct file_stack *p = input_file_stack;
787 input_file_stack = p->next;
788 free (p);
789 input_file_stack_tick++;
790#ifdef DWARF_DEBUGGING_INFO
791 if (debug_info_level == DINFO_LEVEL_VERBOSE
792 && write_symbols == DWARF_DEBUG)
793 dwarfout_resume_previous_source_file (input_file_stack->line);
794#endif /* DWARF_DEBUGGING_INFO */
795 }
796 else
797 error ("#-lines for entering and leaving files don't match");
798
799 used_up = 1;
800 }
801 }
802
5b450ae5
RS
803 /* Now that we've pushed or popped the input stack,
804 update the name in the top element. */
805 if (input_file_stack)
806 input_file_stack->name = input_filename;
807
e8bbfc4e
RK
808 /* If we have handled a `1' or a `2',
809 see if there is another number to read. */
810 if (used_up)
811 {
812 /* Is this the last nonwhite stuff on the line? */
813 c = getc (finput);
814 while (c == ' ' || c == '\t')
815 c = getc (finput);
816 if (c == '\n')
817 return c;
818 ungetc (c, finput);
819
820 token = yylex ();
821 used_up = 0;
822 }
823
824 /* `3' after file name means this is a system header file. */
825
826 if (token == CONSTANT
827 && TREE_CODE (yylval.ttype) == INTEGER_CST
828 && TREE_INT_CST_LOW (yylval.ttype) == 3)
829 in_system_header = 1;
830 }
831 else
832 error ("invalid #-line");
833
834 /* skip the rest of this line. */
835 skipline:
836 if (c == '\n')
837 return c;
838 while ((c = getc (finput)) != EOF && c != '\n');
839 return c;
840}
841\f
ca5b800a
RS
842#ifdef HANDLE_SYSV_PRAGMA
843
844/* Handle a #pragma directive. INPUT is the current input stream,
a3100298
TW
845 and C is a character to reread. Processes the entire input line
846 and returns a character for the caller to reread: either \n or EOF. */
ca5b800a
RS
847
848/* This function has to be in this file, in order to get at
849 the token types. */
850
851int
852handle_sysv_pragma (input, c)
853 FILE *input;
854 int c;
855{
a3100298 856 for (;;)
ca5b800a 857 {
a3100298
TW
858 while (c == ' ' || c == '\t')
859 c = getc (input);
860 if (c == '\n' || c == EOF)
861 {
862 handle_pragma_token (0, 0);
863 return c;
864 }
865 ungetc (c, input);
866 switch (yylex ())
867 {
868 case IDENTIFIER:
869 case TYPENAME:
870 case STRING:
871 case CONSTANT:
872 handle_pragma_token (token_buffer, yylval.ttype);
873 break;
874 default:
875 handle_pragma_token (token_buffer, 0);
876 }
877 if (nextchar >= 0)
878 c = nextchar, nextchar = -1;
879 else
880 c = getc (input);
ca5b800a 881 }
ca5b800a
RS
882}
883
884#endif /* HANDLE_SYSV_PRAGMA */
885\f
e8bbfc4e
RK
886#define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))
887#define isdigit(char) (char >= '0' && char <= '9')
888#define ENDFILE -1 /* token that represents end-of-file */
889
890/* Read an escape sequence, returning its equivalent as a character,
b70af677 891 or store 1 in *ignore_ptr if it is backslash-newline. */
e8bbfc4e
RK
892
893static int
b70af677
RS
894readescape (ignore_ptr)
895 int *ignore_ptr;
e8bbfc4e
RK
896{
897 register int c = getc (finput);
898 register int code;
899 register unsigned count;
900 unsigned firstdig;
8696da34 901 int nonnull;
e8bbfc4e
RK
902
903 switch (c)
904 {
905 case 'x':
906 if (warn_traditional)
907 warning ("the meaning of `\\x' varies with -traditional");
908
909 if (flag_traditional)
910 return c;
911
912 code = 0;
913 count = 0;
8696da34 914 nonnull = 0;
e8bbfc4e
RK
915 while (1)
916 {
917 c = getc (finput);
918 if (!(c >= 'a' && c <= 'f')
919 && !(c >= 'A' && c <= 'F')
920 && !(c >= '0' && c <= '9'))
921 {
922 ungetc (c, finput);
923 break;
924 }
925 code *= 16;
926 if (c >= 'a' && c <= 'f')
927 code += c - 'a' + 10;
928 if (c >= 'A' && c <= 'F')
929 code += c - 'A' + 10;
930 if (c >= '0' && c <= '9')
931 code += c - '0';
8696da34
RS
932 if (code != 0 || count != 0)
933 {
934 if (count == 0)
935 firstdig = code;
936 count++;
937 }
938 nonnull = 1;
e8bbfc4e 939 }
8696da34 940 if (! nonnull)
e8bbfc4e 941 error ("\\x used with no following hex digits");
be63d912
RS
942 else if (count == 0)
943 /* Digits are all 0's. Ok. */
944 ;
e8bbfc4e
RK
945 else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
946 || (count > 1
947 && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
948 <= firstdig)))
949 pedwarn ("hex escape out of range");
950 return code;
951
952 case '0': case '1': case '2': case '3': case '4':
953 case '5': case '6': case '7':
954 code = 0;
955 count = 0;
956 while ((c <= '7') && (c >= '0') && (count++ < 3))
957 {
958 code = (code * 8) + (c - '0');
959 c = getc (finput);
960 }
961 ungetc (c, finput);
962 return code;
963
964 case '\\': case '\'': case '"':
965 return c;
966
967 case '\n':
968 lineno++;
b70af677
RS
969 *ignore_ptr = 1;
970 return 0;
e8bbfc4e
RK
971
972 case 'n':
973 return TARGET_NEWLINE;
974
975 case 't':
976 return TARGET_TAB;
977
978 case 'r':
979 return TARGET_CR;
980
981 case 'f':
982 return TARGET_FF;
983
984 case 'b':
985 return TARGET_BS;
986
987 case 'a':
988 if (warn_traditional)
989 warning ("the meaning of `\\a' varies with -traditional");
990
991 if (flag_traditional)
992 return c;
993 return TARGET_BELL;
994
995 case 'v':
996#if 0 /* Vertical tab is present in common usage compilers. */
997 if (flag_traditional)
998 return c;
999#endif
1000 return TARGET_VT;
1001
dad112ca 1002 case 'e':
e8bbfc4e 1003 case 'E':
dad112ca
RS
1004 if (pedantic)
1005 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
e8bbfc4e
RK
1006 return 033;
1007
1008 case '?':
1009 return c;
1010
1011 /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */
1012 case '(':
1013 case '{':
1014 case '[':
1015 if (pedantic)
1016 pedwarn ("non-ANSI escape sequence `\\%c'", c);
1017 return c;
1018 }
7e6b19dc 1019 if (c >= 040 && c < 0177)
e8bbfc4e
RK
1020 pedwarn ("unknown escape sequence `\\%c'", c);
1021 else
1022 pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
1023 return c;
1024}
1025\f
1026void
1027yyerror (string)
1028 char *string;
1029{
1030 char buf[200];
1031
1032 strcpy (buf, string);
1033
1034 /* We can't print string and character constants well
1035 because the token_buffer contains the result of processing escapes. */
1036 if (end_of_file)
1037 strcat (buf, " at end of input");
1038 else if (token_buffer[0] == 0)
1039 strcat (buf, " at null character");
1040 else if (token_buffer[0] == '"')
1041 strcat (buf, " before string constant");
1042 else if (token_buffer[0] == '\'')
1043 strcat (buf, " before character constant");
1044 else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
1045 sprintf (buf + strlen (buf), " before character 0%o",
1046 (unsigned char) token_buffer[0]);
1047 else
1048 strcat (buf, " before `%s'");
1049
1050 error (buf, token_buffer);
1051}
1052
1053#if 0
1054
1055struct try_type
1056{
1057 tree *node_var;
1058 char unsigned_flag;
1059 char long_flag;
1060 char long_long_flag;
1061};
1062
1063struct try_type type_sequence[] =
1064{
1065 { &integer_type_node, 0, 0, 0},
1066 { &unsigned_type_node, 1, 0, 0},
1067 { &long_integer_type_node, 0, 1, 0},
1068 { &long_unsigned_type_node, 1, 1, 0},
1069 { &long_long_integer_type_node, 0, 1, 1},
1070 { &long_long_unsigned_type_node, 1, 1, 1}
1071};
1072#endif /* 0 */
1073\f
1074int
1075yylex ()
1076{
1077 register int c;
1078 register char *p;
1079 register int value;
1080 int wide_flag = 0;
e31c7eec 1081 int objc_flag = 0;
e8bbfc4e
RK
1082
1083 if (nextchar >= 0)
1084 c = nextchar, nextchar = -1;
1085 else
1086 c = getc (finput);
1087
1088 /* Effectively do c = skip_white_space (c)
1089 but do it faster in the usual cases. */
1090 while (1)
1091 switch (c)
1092 {
e8bbfc4e
RK
1093 case ' ':
1094 case '\t':
1095 case '\f':
1096 case '\v':
1097 case '\b':
1098 c = getc (finput);
1099 break;
1100
80f5b9d8
RS
1101 case '\r':
1102 /* Call skip_white_space so we can warn if appropriate. */
1103
e8bbfc4e
RK
1104 case '\n':
1105 case '/':
1106 case '\\':
1107 c = skip_white_space (c);
1108 default:
1109 goto found_nonwhite;
1110 }
1111 found_nonwhite:
1112
1113 token_buffer[0] = c;
1114 token_buffer[1] = 0;
1115
1116/* yylloc.first_line = lineno; */
1117
1118 switch (c)
1119 {
1120 case EOF:
1121 end_of_file = 1;
1122 token_buffer[0] = 0;
1123 value = ENDFILE;
1124 break;
1125
1126 case '$':
1127 if (dollars_in_ident)
1128 goto letter;
1129 return '$';
1130
1131 case 'L':
1132 /* Capital L may start a wide-string or wide-character constant. */
1133 {
1134 register int c = getc (finput);
1135 if (c == '\'')
1136 {
1137 wide_flag = 1;
1138 goto char_constant;
1139 }
1140 if (c == '"')
1141 {
1142 wide_flag = 1;
1143 goto string_constant;
1144 }
1145 ungetc (c, finput);
1146 }
1147 goto letter;
1148
1149 case '@':
1150 if (!doing_objc_thang)
1151 {
1152 value = c;
1153 break;
1154 }
e31c7eec 1155 else
e8bbfc4e 1156 {
e31c7eec
TW
1157 /* '@' may start a constant string object. */
1158 register int c = getc(finput);
1159 if (c == '"')
1160 {
1161 objc_flag = 1;
1162 goto string_constant;
1163 }
1164 ungetc(c, finput);
1165 /* Fall through to treat '@' as the start of an indentifier. */
e8bbfc4e
RK
1166 }
1167
e8bbfc4e
RK
1168 case 'A': case 'B': case 'C': case 'D': case 'E':
1169 case 'F': case 'G': case 'H': case 'I': case 'J':
1170 case 'K': case 'M': case 'N': case 'O':
1171 case 'P': case 'Q': case 'R': case 'S': case 'T':
1172 case 'U': case 'V': case 'W': case 'X': case 'Y':
1173 case 'Z':
1174 case 'a': case 'b': case 'c': case 'd': case 'e':
1175 case 'f': case 'g': case 'h': case 'i': case 'j':
1176 case 'k': case 'l': case 'm': case 'n': case 'o':
1177 case 'p': case 'q': case 'r': case 's': case 't':
1178 case 'u': case 'v': case 'w': case 'x': case 'y':
1179 case 'z':
1180 case '_':
1181 letter:
1182 p = token_buffer;
1183 while (isalnum (c) || c == '_' || c == '$' || c == '@')
1184 {
8355fc27
RS
1185 /* Make sure this char really belongs in an identifier. */
1186 if (c == '@' && ! doing_objc_thang)
1187 break;
e8bbfc4e
RK
1188 if (c == '$' && ! dollars_in_ident)
1189 break;
1190
8355fc27
RS
1191 if (p >= token_buffer + maxtoken)
1192 p = extend_token_buffer (p);
1193
e8bbfc4e
RK
1194 *p++ = c;
1195 c = getc (finput);
1196 }
1197
1198 *p = 0;
1199 nextchar = c;
1200
1201 value = IDENTIFIER;
1202 yylval.itype = 0;
1203
1204 /* Try to recognize a keyword. Uses minimum-perfect hash function */
1205
1206 {
1207 register struct resword *ptr;
1208
1209 if (ptr = is_reserved_word (token_buffer, p - token_buffer))
1210 {
1211 if (ptr->rid)
1212 yylval.ttype = ridpointers[(int) ptr->rid];
1213 value = (int) ptr->token;
1214
e31c7eec
TW
1215 /* Only return OBJECTNAME if it is a typedef. */
1216 if (doing_objc_thang && value == OBJECTNAME)
1217 {
1218 lastiddecl = lookup_name(yylval.ttype);
1219
1220 if (lastiddecl == NULL_TREE
1221 || TREE_CODE (lastiddecl) != TYPE_DECL)
1222 value = IDENTIFIER;
1223 }
1224
e8bbfc4e
RK
1225 /* Even if we decided to recognize asm, still perhaps warn. */
1226 if (pedantic
d45cf215 1227 && (value == ASM_KEYWORD || value == TYPEOF
e8bbfc4e
RK
1228 || ptr->rid == RID_INLINE)
1229 && token_buffer[0] != '_')
1230 pedwarn ("ANSI does not permit the keyword `%s'",
1231 token_buffer);
1232 }
1233 }
1234
1235 /* If we did not find a keyword, look for an identifier
1236 (or a typename). */
1237
1238 if (value == IDENTIFIER)
1239 {
e31c7eec
TW
1240 if (token_buffer[0] == '@')
1241 error("invalid identifier `%s'", token_buffer);
1242
e8bbfc4e
RK
1243 yylval.ttype = get_identifier (token_buffer);
1244 lastiddecl = lookup_name (yylval.ttype);
1245
1246 if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
1247 value = TYPENAME;
6dbf678a
RS
1248 /* A user-invisible read-only initialized variable
1249 should be replaced by its value.
1250 We handle only strings since that's the only case used in C. */
1251 else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL
1252 && DECL_IGNORED_P (lastiddecl)
1253 && TREE_READONLY (lastiddecl)
1254 && DECL_INITIAL (lastiddecl) != 0
1255 && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)
1256 {
8f7ac220
RS
1257 tree stringval = DECL_INITIAL (lastiddecl);
1258
1259 /* Copy the string value so that we won't clobber anything
1260 if we put something in the TREE_CHAIN of this one. */
1261 yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
1262 TREE_STRING_POINTER (stringval));
6dbf678a
RS
1263 value = STRING;
1264 }
e8bbfc4e
RK
1265 else if (doing_objc_thang)
1266 {
e31c7eec 1267 tree objc_interface_decl = is_class_name (yylval.ttype);
e8bbfc4e
RK
1268
1269 if (objc_interface_decl)
1270 {
1271 value = CLASSNAME;
1272 yylval.ttype = objc_interface_decl;
1273 }
1274 }
1275 }
1276
1277 break;
1278
1279 case '0': case '1': case '2': case '3': case '4':
1280 case '5': case '6': case '7': case '8': case '9':
1281 case '.':
1282 {
1283 int base = 10;
1284 int count = 0;
1285 int largest_digit = 0;
1286 int numdigits = 0;
1287 /* for multi-precision arithmetic,
4ca827d0
RS
1288 we actually store only HOST_BITS_PER_CHAR bits in each part.
1289 The number of parts is chosen so as to be sufficient to hold
9b0995aa
RK
1290 the enough bits to fit into the two HOST_WIDE_INTs that contain
1291 the integer value (this is always at least as many bits as are
1292 in a target `long long' value, but may be wider). */
1293#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
4ca827d0 1294 int parts[TOTAL_PARTS];
e8bbfc4e
RK
1295 int overflow = 0;
1296
1297 enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
1298 = NOT_FLOAT;
1299
4ca827d0
RS
1300 for (count = 0; count < TOTAL_PARTS; count++)
1301 parts[count] = 0;
e8bbfc4e
RK
1302
1303 p = token_buffer;
1304 *p++ = c;
1305
1306 if (c == '0')
1307 {
1308 *p++ = (c = getc (finput));
1309 if ((c == 'x') || (c == 'X'))
1310 {
1311 base = 16;
1312 *p++ = (c = getc (finput));
1313 }
1314 /* Leading 0 forces octal unless the 0 is the only digit. */
1315 else if (c >= '0' && c <= '9')
1316 {
1317 base = 8;
1318 numdigits++;
1319 }
1320 else
1321 numdigits++;
1322 }
1323
1324 /* Read all the digits-and-decimal-points. */
1325
1326 while (c == '.'
122026c0
RS
1327 || (isalnum (c) && c != 'l' && c != 'L'
1328 && c != 'u' && c != 'U'
1329 && c != 'i' && c != 'I' && c != 'j' && c != 'J'
e8bbfc4e
RK
1330 && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
1331 {
1332 if (c == '.')
1333 {
1334 if (base == 16)
1335 error ("floating constant may not be in radix 16");
1336 if (floatflag == AFTER_POINT)
1337 {
1338 error ("malformed floating constant");
1339 floatflag = TOO_MANY_POINTS;
1340 }
1341 else
1342 floatflag = AFTER_POINT;
1343
1344 base = 10;
1345 *p++ = c = getc (finput);
1346 /* Accept '.' as the start of a floating-point number
1347 only when it is followed by a digit.
1348 Otherwise, unread the following non-digit
1349 and use the '.' as a structural token. */
1350 if (p == token_buffer + 2 && !isdigit (c))
1351 {
1352 if (c == '.')
1353 {
1354 c = getc (finput);
1355 if (c == '.')
1356 {
1357 *p++ = c;
1358 *p = 0;
1359 return ELLIPSIS;
1360 }
1361 error ("parse error at `..'");
1362 }
1363 ungetc (c, finput);
1364 token_buffer[1] = 0;
1365 value = '.';
1366 goto done;
1367 }
1368 }
1369 else
1370 {
1371 /* It is not a decimal point.
1372 It should be a digit (perhaps a hex digit). */
1373
1374 if (isdigit (c))
1375 {
1376 c = c - '0';
1377 }
1378 else if (base <= 10)
1379 {
f3acae4d 1380 if (c == 'e' || c == 'E')
e8bbfc4e
RK
1381 {
1382 base = 10;
1383 floatflag = AFTER_POINT;
1384 break; /* start of exponent */
1385 }
1386 error ("nondigits in number and not hexadecimal");
1387 c = 0;
1388 }
1389 else if (c >= 'a')
1390 {
1391 c = c - 'a' + 10;
1392 }
1393 else
1394 {
1395 c = c - 'A' + 10;
1396 }
1397 if (c >= largest_digit)
1398 largest_digit = c;
1399 numdigits++;
1400
4ca827d0 1401 for (count = 0; count < TOTAL_PARTS; count++)
e8bbfc4e 1402 {
4ca827d0 1403 parts[count] *= base;
e8bbfc4e
RK
1404 if (count)
1405 {
4ca827d0
RS
1406 parts[count]
1407 += (parts[count-1] >> HOST_BITS_PER_CHAR);
1408 parts[count-1]
1409 &= (1 << HOST_BITS_PER_CHAR) - 1;
e8bbfc4e 1410 }
4ca827d0
RS
1411 else
1412 parts[0] += c;
e8bbfc4e
RK
1413 }
1414
4ca827d0
RS
1415 /* If the extra highest-order part ever gets anything in it,
1416 the number is certainly too big. */
1417 if (parts[TOTAL_PARTS - 1] != 0)
1418 overflow = 1;
e8bbfc4e
RK
1419
1420 if (p >= token_buffer + maxtoken - 3)
1421 p = extend_token_buffer (p);
1422 *p++ = (c = getc (finput));
1423 }
1424 }
1425
1426 if (numdigits == 0)
1427 error ("numeric constant with no digits");
1428
1429 if (largest_digit >= base)
1430 error ("numeric constant contains digits beyond the radix");
1431
1432 /* Remove terminating char from the token buffer and delimit the string */
1433 *--p = 0;
1434
1435 if (floatflag != NOT_FLOAT)
1436 {
1437 tree type = double_type_node;
63ea33ce 1438 int garbage_chars = 0, exceeds_double = 0;
122026c0 1439 int imag = 0;
e8bbfc4e
RK
1440 REAL_VALUE_TYPE value;
1441 jmp_buf handler;
1442
1443 /* Read explicit exponent if any, and put it in tokenbuf. */
1444
1445 if ((c == 'e') || (c == 'E'))
1446 {
1447 if (p >= token_buffer + maxtoken - 3)
1448 p = extend_token_buffer (p);
1449 *p++ = c;
1450 c = getc (finput);
1451 if ((c == '+') || (c == '-'))
1452 {
1453 *p++ = c;
1454 c = getc (finput);
1455 }
1456 if (! isdigit (c))
1457 error ("floating constant exponent has no digits");
1458 while (isdigit (c))
1459 {
1460 if (p >= token_buffer + maxtoken - 3)
1461 p = extend_token_buffer (p);
1462 *p++ = c;
1463 c = getc (finput);
1464 }
1465 }
1466
1467 *p = 0;
1468 errno = 0;
1469
1470 /* Convert string to a double, checking for overflow. */
1471 if (setjmp (handler))
1472 {
1473 error ("floating constant out of range");
1474 value = dconst0;
1475 }
1476 else
1477 {
1478 set_float_handler (handler);
1454a5ba
RS
1479
1480/* The second argument, machine_mode, of REAL_VALUE_ATOF tells the
1481 desired precision of the binary result of decimal-to-binary conversion. */
e8bbfc4e
RK
1482
1483 /* Read the suffixes to choose a data type. */
63ea33ce
RS
1484 switch (c)
1485 {
1486 case 'f': case 'F':
1487 type = float_type_node;
1454a5ba
RS
1488 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
1489 if (REAL_VALUE_ISINF (value) && pedantic)
63ea33ce
RS
1490 pedwarn ("floating point number exceeds range of `float'");
1491 garbage_chars = -1;
1492 break;
1493
1494 case 'l': case 'L':
1495 type = long_double_type_node;
1454a5ba
RS
1496 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
1497 if (REAL_VALUE_ISINF (value) && pedantic)
1498 pedwarn (
1499 "floating point number exceeds range of `long double'");
63ea33ce
RS
1500 garbage_chars = -1;
1501 break;
122026c0
RS
1502
1503 case 'i': case 'I':
1504 if (imag)
1505 error ("more than one `i' or `j' in numeric constant");
1506 imag = 1;
1507 garbage_chars = -1;
1454a5ba
RS
1508 break;
1509
1510 default:
1511 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
1512 if (REAL_VALUE_ISINF (value) && pedantic)
1513 pedwarn ("floating point number exceeds range of `double'");
63ea33ce 1514 }
1454a5ba
RS
1515 set_float_handler (NULL_PTR);
1516 }
1517#ifdef ERANGE
1518 if (errno == ERANGE && !flag_traditional && pedantic)
1519 {
1520 /* ERANGE is also reported for underflow,
1521 so test the value to distinguish overflow from that. */
1522 if (REAL_VALUES_LESS (dconst1, value)
1523 || REAL_VALUES_LESS (value, dconstm1))
1524 {
1525 pedwarn ("floating point number exceeds range of `double'");
1526 exceeds_double = 1;
1527 }
1528 }
1529#endif
63ea33ce 1530 /* Note: garbage_chars is -1 if first char is *not* garbage. */
f3acae4d
RS
1531 while (isalnum (c) || c == '.' || c == '_'
1532 || (!flag_traditional && (c == '+' || c == '-')
1533 && (p[-1] == 'e' || p[-1] == 'E')))
e8bbfc4e 1534 {
e8bbfc4e
RK
1535 if (p >= token_buffer + maxtoken - 3)
1536 p = extend_token_buffer (p);
1537 *p++ = c;
1538 c = getc (finput);
63ea33ce 1539 garbage_chars++;
e8bbfc4e 1540 }
63ea33ce
RS
1541 if (garbage_chars > 0)
1542 error ("garbage at end of number");
e8bbfc4e
RK
1543
1544 /* Create a node with determined type and value. */
122026c0
RS
1545 if (imag)
1546 yylval.ttype = build_complex (convert (type, integer_zero_node),
1547 build_real (type, value));
1548 else
1549 yylval.ttype = build_real (type, value);
e8bbfc4e
RK
1550
1551 ungetc (c, finput);
1552 *p = 0;
1553 }
1554 else
1555 {
1556 tree traditional_type, ansi_type, type;
8d9bfdc5 1557 HOST_WIDE_INT high, low;
e8bbfc4e
RK
1558 int spec_unsigned = 0;
1559 int spec_long = 0;
1560 int spec_long_long = 0;
122026c0 1561 int spec_imag = 0;
e8bbfc4e
RK
1562 int bytes, warn, i;
1563
1564 while (1)
1565 {
1566 if (c == 'u' || c == 'U')
1567 {
1568 if (spec_unsigned)
1569 error ("two `u's in integer constant");
1570 spec_unsigned = 1;
1571 }
1572 else if (c == 'l' || c == 'L')
1573 {
1574 if (spec_long)
1575 {
1576 if (spec_long_long)
1577 error ("three `l's in integer constant");
1578 else if (pedantic)
1579 pedwarn ("ANSI C forbids long long integer constants");
1580 spec_long_long = 1;
1581 }
1582 spec_long = 1;
1583 }
122026c0
RS
1584 else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
1585 {
1586 if (spec_imag)
1587 error ("more than one `i' or `j' in numeric constant");
1588 spec_imag = 1;
1589 }
e8bbfc4e
RK
1590 else
1591 {
f3acae4d
RS
1592 if (isalnum (c) || c == '.' || c == '_'
1593 || (!flag_traditional && (c == '+' || c == '-')
1594 && (p[-1] == 'e' || p[-1] == 'E')))
e8bbfc4e
RK
1595 {
1596 error ("garbage at end of number");
f3acae4d
RS
1597 while (isalnum (c) || c == '.' || c == '_'
1598 || (!flag_traditional && (c == '+' || c == '-')
1599 && (p[-1] == 'e' || p[-1] == 'E')))
e8bbfc4e
RK
1600 {
1601 if (p >= token_buffer + maxtoken - 3)
1602 p = extend_token_buffer (p);
1603 *p++ = c;
1604 c = getc (finput);
1605 }
1606 }
1607 break;
1608 }
1609 if (p >= token_buffer + maxtoken - 3)
1610 p = extend_token_buffer (p);
1611 *p++ = c;
1612 c = getc (finput);
1613 }
1614
1615 ungetc (c, finput);
1616
1617 /* If the constant is not long long and it won't fit in an
1618 unsigned long, or if the constant is long long and won't fit
1619 in an unsigned long long, then warn that the constant is out
1620 of range. */
1621
1622 /* ??? This assumes that long long and long integer types are
1623 a multiple of 8 bits. This better than the original code
1624 though which assumed that long was exactly 32 bits and long
1625 long was exactly 64 bits. */
1626
1627 if (spec_long_long)
1628 bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
1629 else
1630 bytes = TYPE_PRECISION (long_integer_type_node) / 8;
1631
4ca827d0
RS
1632 warn = overflow;
1633 for (i = bytes; i < TOTAL_PARTS; i++)
1634 if (parts[i])
1635 warn = 1;
1636 if (warn)
1637 pedwarn ("integer constant out of range");
e8bbfc4e
RK
1638
1639 /* This is simplified by the fact that our constant
1640 is always positive. */
8d9bfdc5
RK
1641
1642 high = low = 0;
1643
1644 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
1645 {
1646 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
1647 / HOST_BITS_PER_CHAR)]
1648 << (i * HOST_BITS_PER_CHAR));
1649 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
1650 }
1651
1652 yylval.ttype = build_int_2 (low, high);
5a9085c7 1653 TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
e8bbfc4e 1654
e8bbfc4e
RK
1655 /* If warn_traditional, calculate both the ANSI type and the
1656 traditional type, then see if they disagree.
1657 Otherwise, calculate only the type for the dialect in use. */
1658 if (warn_traditional || flag_traditional)
1659 {
1660 /* Calculate the traditional type. */
1661 /* Traditionally, any constant is signed;
1662 but if unsigned is specified explicitly, obey that.
1663 Use the smallest size with the right number of bits,
1664 except for one special case with decimal constants. */
1665 if (! spec_long && base != 10
1666 && int_fits_type_p (yylval.ttype, unsigned_type_node))
1667 traditional_type = (spec_unsigned ? unsigned_type_node
1668 : integer_type_node);
1669 /* A decimal constant must be long
1670 if it does not fit in type int.
1671 I think this is independent of whether
1672 the constant is signed. */
1673 else if (! spec_long && base == 10
1674 && int_fits_type_p (yylval.ttype, integer_type_node))
1675 traditional_type = (spec_unsigned ? unsigned_type_node
1676 : integer_type_node);
4ca827d0 1677 else if (! spec_long_long)
e8bbfc4e
RK
1678 traditional_type = (spec_unsigned ? long_unsigned_type_node
1679 : long_integer_type_node);
1680 else
1681 traditional_type = (spec_unsigned
1682 ? long_long_unsigned_type_node
1683 : long_long_integer_type_node);
1684 }
1685 if (warn_traditional || ! flag_traditional)
1686 {
1687 /* Calculate the ANSI type. */
1688 if (! spec_long && ! spec_unsigned
1689 && int_fits_type_p (yylval.ttype, integer_type_node))
1690 ansi_type = integer_type_node;
1691 else if (! spec_long && (base != 10 || spec_unsigned)
1692 && int_fits_type_p (yylval.ttype, unsigned_type_node))
1693 ansi_type = unsigned_type_node;
1694 else if (! spec_unsigned && !spec_long_long
1695 && int_fits_type_p (yylval.ttype, long_integer_type_node))
1696 ansi_type = long_integer_type_node;
4ca827d0 1697 else if (! spec_long_long)
e8bbfc4e
RK
1698 ansi_type = long_unsigned_type_node;
1699 else if (! spec_unsigned
a120b788
RS
1700 /* Verify value does not overflow into sign bit. */
1701 && TREE_INT_CST_HIGH (yylval.ttype) >= 0
e8bbfc4e
RK
1702 && int_fits_type_p (yylval.ttype,
1703 long_long_integer_type_node))
1704 ansi_type = long_long_integer_type_node;
1705 else
1706 ansi_type = long_long_unsigned_type_node;
1707 }
1708
1709 type = flag_traditional ? traditional_type : ansi_type;
1710
1711 if (warn_traditional && traditional_type != ansi_type)
1712 {
1713 if (TYPE_PRECISION (traditional_type)
1714 != TYPE_PRECISION (ansi_type))
1715 warning ("width of integer constant changes with -traditional");
1716 else if (TREE_UNSIGNED (traditional_type)
1717 != TREE_UNSIGNED (ansi_type))
1718 warning ("integer constant is unsigned in ANSI C, signed with -traditional");
a3ee5899
JW
1719 else
1720 warning ("width of integer constant may change on other systems with -traditional");
e8bbfc4e 1721 }
e8bbfc4e 1722
4ca827d0
RS
1723 if (!flag_traditional && !int_fits_type_p (yylval.ttype, type)
1724 && !warn)
88d92ca5
RS
1725 pedwarn ("integer constant out of range");
1726
c832a30e 1727 if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
ba99333a 1728 warning ("decimal constant is so large that it is unsigned");
c832a30e 1729
122026c0
RS
1730 if (spec_imag)
1731 {
1732 if (TYPE_PRECISION (type)
1733 <= TYPE_PRECISION (integer_type_node))
1734 yylval.ttype
1735 = build_complex (integer_zero_node,
1736 convert (integer_type_node, yylval.ttype));
1737 else
1738 error ("complex integer constant is too wide for `complex int'");
1739 }
1740 else if (flag_traditional && !int_fits_type_p (yylval.ttype, type))
88dd95c1
RS
1741 /* The traditional constant 0x80000000 is signed
1742 but doesn't fit in the range of int.
1743 This will change it to -0x80000000, which does fit. */
1744 {
1745 TREE_TYPE (yylval.ttype) = unsigned_type (type);
1746 yylval.ttype = convert (type, yylval.ttype);
1747 }
1748 else
1749 TREE_TYPE (yylval.ttype) = type;
1750
e8bbfc4e
RK
1751 *p = 0;
1752 }
1753
1754 value = CONSTANT; break;
1755 }
1756
1757 case '\'':
1758 char_constant:
1759 {
1760 register int result = 0;
a2543283 1761 register int num_chars = 0;
e8bbfc4e
RK
1762 unsigned width = TYPE_PRECISION (char_type_node);
1763 int max_chars;
1764
1765 if (wide_flag)
1766 {
1767 width = WCHAR_TYPE_SIZE;
1768#ifdef MULTIBYTE_CHARS
1769 max_chars = MB_CUR_MAX;
1770#else
1771 max_chars = 1;
1772#endif
1773 }
1774 else
1775 max_chars = TYPE_PRECISION (integer_type_node) / width;
1776
1777 while (1)
1778 {
1779 tryagain:
1780
1781 c = getc (finput);
1782
1783 if (c == '\'' || c == EOF)
1784 break;
1785
1786 if (c == '\\')
1787 {
b70af677
RS
1788 int ignore = 0;
1789 c = readescape (&ignore);
1790 if (ignore)
e8bbfc4e
RK
1791 goto tryagain;
1792 if (width < HOST_BITS_PER_INT
1793 && (unsigned) c >= (1 << width))
1794 pedwarn ("escape sequence out of range for character");
f6cb3487
RS
1795#ifdef MAP_CHARACTER
1796 if (isprint (c))
1797 c = MAP_CHARACTER (c);
1798#endif
e8bbfc4e
RK
1799 }
1800 else if (c == '\n')
1801 {
1802 if (pedantic)
1803 pedwarn ("ANSI C forbids newline in character constant");
1804 lineno++;
1805 }
b539a651
RS
1806#ifdef MAP_CHARACTER
1807 else
1808 c = MAP_CHARACTER (c);
1809#endif
e8bbfc4e
RK
1810
1811 num_chars++;
1812 if (num_chars > maxtoken - 4)
1813 extend_token_buffer (token_buffer);
1814
1815 token_buffer[num_chars] = c;
1816
1817 /* Merge character into result; ignore excess chars. */
1818 if (num_chars < max_chars + 1)
1819 {
1820 if (width < HOST_BITS_PER_INT)
1821 result = (result << width) | (c & ((1 << width) - 1));
1822 else
1823 result = c;
1824 }
1825 }
1826
1827 token_buffer[num_chars + 1] = '\'';
1828 token_buffer[num_chars + 2] = 0;
1829
1830 if (c != '\'')
1831 error ("malformatted character constant");
1832 else if (num_chars == 0)
1833 error ("empty character constant");
1834 else if (num_chars > max_chars)
1835 {
1836 num_chars = max_chars;
1837 error ("character constant too long");
1838 }
1839 else if (num_chars != 1 && ! flag_traditional)
1840 warning ("multi-character character constant");
1841
1842 /* If char type is signed, sign-extend the constant. */
1843 if (! wide_flag)
1844 {
1845 int num_bits = num_chars * width;
1846 if (TREE_UNSIGNED (char_type_node)
1847 || ((result >> (num_bits - 1)) & 1) == 0)
1848 yylval.ttype
8d9bfdc5
RK
1849 = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
1850 >> (HOST_BITS_PER_WIDE_INT - num_bits)),
e8bbfc4e
RK
1851 0);
1852 else
1853 yylval.ttype
8d9bfdc5
RK
1854 = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
1855 >> (HOST_BITS_PER_WIDE_INT - num_bits)),
e8bbfc4e 1856 -1);
f3acae4d 1857 TREE_TYPE (yylval.ttype) = integer_type_node;
e8bbfc4e
RK
1858 }
1859 else
1860 {
1861#ifdef MULTIBYTE_CHARS
1862 /* Set the initial shift state and convert the next sequence. */
1863 result = 0;
1864 /* In all locales L'\0' is zero and mbtowc will return zero,
1865 so don't use it. */
1866 if (num_chars > 1
1867 || (num_chars == 1 && token_buffer[1] != '\0'))
1868 {
1869 wchar_t wc;
8d9bfdc5 1870 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
e8bbfc4e
RK
1871 if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
1872 result = wc;
1873 else
1874 warning ("Ignoring invalid multibyte character");
1875 }
1876#endif
1877 yylval.ttype = build_int_2 (result, 0);
f3acae4d 1878 TREE_TYPE (yylval.ttype) = wchar_type_node;
e8bbfc4e
RK
1879 }
1880
e8bbfc4e
RK
1881 value = CONSTANT;
1882 break;
1883 }
1884
1885 case '"':
1886 string_constant:
1887 {
1888 c = getc (finput);
1889 p = token_buffer + 1;
1890
1891 while (c != '"' && c >= 0)
1892 {
1893 /* ignore_escape_flag is set for reading the filename in #line. */
1894 if (!ignore_escape_flag && c == '\\')
1895 {
fad04099 1896 int ignore = 0;
b70af677
RS
1897 c = readescape (&ignore);
1898 if (ignore)
e8bbfc4e
RK
1899 goto skipnewline;
1900 if (!wide_flag
1901 && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
1902 && c >= (1 << TYPE_PRECISION (char_type_node)))
1903 pedwarn ("escape sequence out of range for character");
1904 }
1905 else if (c == '\n')
1906 {
1907 if (pedantic)
1908 pedwarn ("ANSI C forbids newline in string constant");
1909 lineno++;
1910 }
1911
1912 if (p == token_buffer + maxtoken)
1913 p = extend_token_buffer (p);
1914 *p++ = c;
1915
1916 skipnewline:
1917 c = getc (finput);
1918 }
1919 *p = 0;
1920
1921 /* We have read the entire constant.
1922 Construct a STRING_CST for the result. */
1923
1924 if (wide_flag)
1925 {
1926 /* If this is a L"..." wide-string, convert the multibyte string
1927 to a wide character string. */
1928 char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
1929 int len;
1930
1931#ifdef MULTIBYTE_CHARS
1932 len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
1933 if ((unsigned) len >= (p - token_buffer))
1934 {
1935 warning ("Ignoring invalid multibyte string");
1936 len = 0;
1937 }
1938 bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
1939#else
1940 {
1941 union { long l; char c[sizeof (long)]; } u;
1942 int big_endian;
1943 char *wp, *cp;
1944
1945 /* Determine whether host is little or big endian. */
1946 u.l = 1;
1947 big_endian = u.c[sizeof (long) - 1];
1948 wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
1949
1950 bzero (widep, (p - token_buffer) * WCHAR_BYTES);
1951 for (cp = token_buffer + 1; cp < p; cp++)
1952 *wp = *cp, wp += WCHAR_BYTES;
1953 len = p - token_buffer - 1;
1954 }
1955#endif
1956 yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
1957 TREE_TYPE (yylval.ttype) = wchar_array_type_node;
e31c7eec
TW
1958 value = STRING;
1959 }
1960 else if (objc_flag)
1961 {
1962 extern tree build_objc_string();
1963 /* Return an Objective-C @"..." constant string object. */
1964 yylval.ttype = build_objc_string (p - token_buffer,
1965 token_buffer + 1);
1966 TREE_TYPE (yylval.ttype) = char_array_type_node;
1967 value = OBJC_STRING;
e8bbfc4e
RK
1968 }
1969 else
1970 {
1971 yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
1972 TREE_TYPE (yylval.ttype) = char_array_type_node;
e31c7eec 1973 value = STRING;
e8bbfc4e
RK
1974 }
1975
1976 *p++ = '"';
1977 *p = 0;
1978
e31c7eec 1979 break;
e8bbfc4e
RK
1980 }
1981
1982 case '+':
1983 case '-':
1984 case '&':
1985 case '|':
1986 case '<':
1987 case '>':
1988 case '*':
1989 case '/':
1990 case '%':
1991 case '^':
1992 case '!':
1993 case '=':
1994 {
1995 register int c1;
1996
1997 combine:
1998
1999 switch (c)
2000 {
2001 case '+':
2002 yylval.code = PLUS_EXPR; break;
2003 case '-':
2004 yylval.code = MINUS_EXPR; break;
2005 case '&':
2006 yylval.code = BIT_AND_EXPR; break;
2007 case '|':
2008 yylval.code = BIT_IOR_EXPR; break;
2009 case '*':
2010 yylval.code = MULT_EXPR; break;
2011 case '/':
2012 yylval.code = TRUNC_DIV_EXPR; break;
2013 case '%':
2014 yylval.code = TRUNC_MOD_EXPR; break;
2015 case '^':
2016 yylval.code = BIT_XOR_EXPR; break;
2017 case LSHIFT:
2018 yylval.code = LSHIFT_EXPR; break;
2019 case RSHIFT:
2020 yylval.code = RSHIFT_EXPR; break;
2021 case '<':
2022 yylval.code = LT_EXPR; break;
2023 case '>':
2024 yylval.code = GT_EXPR; break;
2025 }
2026
2027 token_buffer[1] = c1 = getc (finput);
2028 token_buffer[2] = 0;
2029
2030 if (c1 == '=')
2031 {
2032 switch (c)
2033 {
2034 case '<':
2035 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
2036 case '>':
2037 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
2038 case '!':
2039 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
2040 case '=':
2041 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
2042 }
2043 value = ASSIGN; goto done;
2044 }
2045 else if (c == c1)
2046 switch (c)
2047 {
2048 case '+':
2049 value = PLUSPLUS; goto done;
2050 case '-':
2051 value = MINUSMINUS; goto done;
2052 case '&':
2053 value = ANDAND; goto done;
2054 case '|':
2055 value = OROR; goto done;
2056 case '<':
2057 c = LSHIFT;
2058 goto combine;
2059 case '>':
2060 c = RSHIFT;
2061 goto combine;
2062 }
2063 else if ((c == '-') && (c1 == '>'))
2064 { value = POINTSAT; goto done; }
2065 ungetc (c1, finput);
2066 token_buffer[1] = 0;
2067
2068 if ((c == '<') || (c == '>'))
2069 value = ARITHCOMPARE;
2070 else value = c;
2071 goto done;
2072 }
2073
2074 case 0:
2075 /* Don't make yyparse think this is eof. */
2076 value = 1;
2077 break;
2078
2079 default:
2080 value = c;
2081 }
2082
2083done:
2084/* yylloc.last_line = lineno; */
2085
2086 return value;
2087}
2088
d45cf215 2089/* Sets the value of the 'yydebug' variable to VALUE.
e8bbfc4e
RK
2090 This is a function so we don't have to have YYDEBUG defined
2091 in order to build the compiler. */
2092
2093void
2094set_yydebug (value)
2095 int value;
2096{
2097#if YYDEBUG != 0
2098 yydebug = value;
2099#else
2100 warning ("YYDEBUG not defined.");
2101#endif
2102}
This page took 0.311781 seconds and 5 git commands to generate.