OSDN Git Service

* lex.c (do_identifier): Correct call to enforce_access.
[pf3gnuchains/gcc-fork.git] / gcc / cp / lex.c
1 /* Separate lexical analyzer for GNU C++.
2    Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc.
3    Hacked by Michael Tiemann (tiemann@cygnus.com)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 /* This file is the lexical analyzer for GNU C++.  */
24
25 /* Cause the `yydebug' variable to be defined.  */
26 #define YYDEBUG 1
27
28 #include "config.h"
29 #include "system.h"
30 #include <setjmp.h>
31 #include "input.h"
32 #include "tree.h"
33 #include "lex.h"
34 #include "cp-tree.h"
35 #include "parse.h"
36 #include "flags.h"
37 #include "obstack.h"
38 #include "c-pragma.h"
39 #include "toplev.h"
40 #include "output.h"
41
42 #ifdef MULTIBYTE_CHARS
43 #include "mbchar.h"
44 #include <locale.h>
45 #endif
46
47 #define obstack_chunk_alloc xmalloc
48 #define obstack_chunk_free free
49
50 #ifndef DIR_SEPARATOR
51 #define DIR_SEPARATOR '/'
52 #endif
53
54 extern struct obstack permanent_obstack;
55 extern struct obstack *current_obstack, *saveable_obstack;
56
57 extern void yyprint PROTO((FILE *, int, YYSTYPE));
58 extern void compiler_error PROTO((char *, HOST_WIDE_INT,
59                                   HOST_WIDE_INT));
60
61 static tree get_time_identifier PROTO((char *));
62 static int check_newline PROTO((void));
63 static int skip_white_space PROTO((int));
64 static void finish_defarg PROTO((void));
65 static int my_get_run_time PROTO((void));
66 static int get_last_nonwhite_on_line PROTO((void));
67 static int interface_strcmp PROTO((char *));
68 static int readescape PROTO((int *));
69 static char *extend_token_buffer PROTO((char *));
70 static void consume_string PROTO((struct obstack *, int));
71 static void set_typedecl_interface_info PROTO((tree, tree));
72 static void feed_defarg PROTO((tree, tree));
73 static int set_vardecl_interface_info PROTO((tree, tree));
74 static void store_pending_inline PROTO((tree, struct pending_inline *));
75 static void reinit_parse_for_expr PROTO((struct obstack *));
76 static int *init_cpp_parse PROTO((void));
77 static int handle_cp_pragma PROTO((char *));
78 #ifdef HANDLE_GENERIC_PRAGMAS
79 static int handle_generic_pragma PROTO((int));
80 #endif
81 #ifdef GATHER_STATISTICS
82 #ifdef REDUCE_LENGTH
83 static int reduce_cmp PROTO((int *, int *));
84 static int token_cmp PROTO((int *, int *));
85 #endif
86 #endif
87 static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
88
89 /* Given a file name X, return the nondirectory portion.
90    Keep in mind that X can be computed more than once.  */
91 char *
92 file_name_nondirectory (x)
93      char *x;
94 {
95   char *tmp = (char *) rindex (x, '/');
96   if (DIR_SEPARATOR != '/' && ! tmp)
97     tmp = (char *) rindex (x, DIR_SEPARATOR);
98   if (tmp)
99     return (char *) (tmp + 1);
100   else
101     return x;
102 }
103
104 /* This obstack is needed to hold text.  It is not safe to use
105    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
106 struct obstack inline_text_obstack;
107 char *inline_text_firstobj;
108
109 #if USE_CPPLIB
110 #include "cpplib.h"
111 extern cpp_reader  parse_in;
112 extern cpp_options parse_options;
113 extern unsigned char *yy_cur, *yy_lim;
114 #else
115 FILE *finput;
116 #endif
117 int end_of_file;
118
119 /* Pending language change.
120    Positive is push count, negative is pop count.  */
121 int pending_lang_change = 0;
122
123 /* Wrap the current header file in extern "C".  */
124 static int c_header_level = 0;
125
126 extern int first_token;
127 extern struct obstack token_obstack;
128
129 /* ??? Don't really know where this goes yet.  */
130 #if 1
131 #include "input.c"
132 #else
133 extern void put_back (/* int */);
134 extern int input_redirected ();
135 extern void feed_input (/* char *, int */);
136 #endif
137
138 /* Holds translations from TREE_CODEs to operator name strings,
139    i.e., opname_tab[PLUS_EXPR] == "+".  */
140 char **opname_tab;
141 char **assignop_tab;
142 \f
143 extern int yychar;              /*  the lookahead symbol                */
144 extern YYSTYPE yylval;          /*  the semantic value of the           */
145                                 /*  lookahead symbol                    */
146
147 #if 0
148 YYLTYPE yylloc;                 /*  location data for the lookahead     */
149                                 /*  symbol                              */
150 #endif
151
152
153 /* the declaration found for the last IDENTIFIER token read in.
154    yylex must look this up to detect typedefs, which get token type TYPENAME,
155    so it is left around in case the identifier is not a typedef but is
156    used in a context which makes it a reference to a variable.  */
157 tree lastiddecl;
158
159 /* The elements of `ridpointers' are identifier nodes
160    for the reserved type names and storage classes.
161    It is indexed by a RID_... value.  */
162 tree ridpointers[(int) RID_MAX];
163
164 /* We may keep statistics about how long which files took to compile.  */
165 static int header_time, body_time;
166 static tree filename_times;
167 static tree this_filename_time;
168
169 /* Array for holding counts of the numbers of tokens seen.  */
170 extern int *token_count;
171 \f
172 /* Return something to represent absolute declarators containing a *.
173    TARGET is the absolute declarator that the * contains.
174    CV_QUALIFIERS is a list of modifiers such as const or volatile
175    to apply to the pointer type, represented as identifiers.
176
177    We return an INDIRECT_REF whose "contents" are TARGET
178    and whose type is the modifier list.  */
179
180 tree
181 make_pointer_declarator (cv_qualifiers, target)
182      tree cv_qualifiers, target;
183 {
184   if (target && TREE_CODE (target) == IDENTIFIER_NODE
185       && ANON_AGGRNAME_P (target))
186     error ("type name expected before `*'");
187   target = build_parse_node (INDIRECT_REF, target);
188   TREE_TYPE (target) = cv_qualifiers;
189   return target;
190 }
191
192 /* Return something to represent absolute declarators containing a &.
193    TARGET is the absolute declarator that the & contains.
194    CV_QUALIFIERS is a list of modifiers such as const or volatile
195    to apply to the reference type, represented as identifiers.
196
197    We return an ADDR_EXPR whose "contents" are TARGET
198    and whose type is the modifier list.  */
199    
200 tree
201 make_reference_declarator (cv_qualifiers, target)
202      tree cv_qualifiers, target;
203 {
204   if (target)
205     {
206       if (TREE_CODE (target) == ADDR_EXPR)
207         {
208           error ("cannot declare references to references");
209           return target;
210         }
211       if (TREE_CODE (target) == INDIRECT_REF)
212         {
213           error ("cannot declare pointers to references");
214           return target;
215         }
216       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
217           error ("type name expected before `&'");
218     }
219   target = build_parse_node (ADDR_EXPR, target);
220   TREE_TYPE (target) = cv_qualifiers;
221   return target;
222 }
223
224 tree
225 make_call_declarator (target, parms, cv_qualifiers, exception_specification)
226      tree target, parms, cv_qualifiers, exception_specification;
227 {
228   target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
229   TREE_TYPE (target) = exception_specification;
230   return target;
231 }
232
233 void
234 set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
235      tree call_declarator, cv_qualifiers, exception_specification;
236 {
237   TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
238   TREE_TYPE (call_declarator) = exception_specification;
239 }
240 \f
241 /* Build names and nodes for overloaded operators.  */
242
243 tree ansi_opname[LAST_CPLUS_TREE_CODE];
244 tree ansi_assopname[LAST_CPLUS_TREE_CODE];
245
246 char *
247 operator_name_string (name)
248      tree name;
249 {
250   char *opname = IDENTIFIER_POINTER (name) + 2;
251   tree *opname_table;
252   int i, assign;
253
254   /* Works for builtin and user defined types.  */
255   if (IDENTIFIER_GLOBAL_VALUE (name)
256       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
257     return IDENTIFIER_POINTER (name);
258
259   if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
260     {
261       opname += 1;
262       assign = 1;
263       opname_table = ansi_assopname;
264     }
265   else
266     {
267       assign = 0;
268       opname_table = ansi_opname;
269     }
270
271   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
272     {
273       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
274           && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
275         break;
276     }
277
278   if (i == LAST_CPLUS_TREE_CODE)
279     return "<invalid operator>";
280
281   if (assign)
282     return assignop_tab[i];
283   else
284     return opname_tab[i];
285 }
286 \f
287 int interface_only;             /* whether or not current file is only for
288                                    interface definitions.  */
289 int interface_unknown;          /* whether or not we know this class
290                                    to behave according to #pragma interface.  */
291
292 /* lexical analyzer */
293
294 #ifndef WCHAR_TYPE_SIZE
295 #ifdef INT_TYPE_SIZE
296 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
297 #else
298 #define WCHAR_TYPE_SIZE BITS_PER_WORD
299 #endif
300 #endif
301
302 /* Number of bytes in a wide character.  */
303 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
304
305 static int maxtoken;            /* Current nominal length of token buffer.  */
306 char *token_buffer;             /* Pointer to token buffer.
307                                    Actual allocated length is maxtoken + 2.  */
308
309 #include "hash.h"
310 \f
311
312 /* Nonzero tells yylex to ignore \ in string constants.  */
313 static int ignore_escape_flag = 0;
314
315 static tree
316 get_time_identifier (name)
317      char *name;
318 {
319   tree time_identifier;
320   int len = strlen (name);
321   char *buf = (char *) alloca (len + 6);
322   strcpy (buf, "file ");
323   bcopy (name, buf+5, len);
324   buf[len+5] = '\0';
325   time_identifier = get_identifier (buf);
326   if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
327     {
328       push_obstacks_nochange ();
329       end_temporary_allocation ();
330       TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
331       TIME_IDENTIFIER_FILEINFO (time_identifier) 
332         = build_int_2 (0, 1);
333       SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
334       filename_times = time_identifier;
335       pop_obstacks ();
336     }
337   return time_identifier;
338 }
339
340 #ifdef __GNUC__
341 __inline
342 #endif
343 static int
344 my_get_run_time ()
345 {
346   int old_quiet_flag = quiet_flag;
347   int this_time;
348   quiet_flag = 0;
349   this_time = get_run_time ();
350   quiet_flag = old_quiet_flag;
351   return this_time;
352 }
353 \f
354 /* Table indexed by tree code giving a string containing a character
355    classifying the tree code.  Possibilities are
356    t, d, s, c, r, <, 1 and 2.  See cp/cp-tree.def for details.  */
357
358 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
359
360 char cplus_tree_code_type[] = {
361   'x',
362 #include "cp-tree.def"
363 };
364 #undef DEFTREECODE
365
366 /* Table indexed by tree code giving number of expression
367    operands beyond the fixed part of the node structure.
368    Not used for types or decls.  */
369
370 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
371
372 int cplus_tree_code_length[] = {
373   0,
374 #include "cp-tree.def"
375 };
376 #undef DEFTREECODE
377
378 /* Names of tree components.
379    Used for printing out the tree and error messages.  */
380 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
381
382 char *cplus_tree_code_name[] = {
383   "@@dummy",
384 #include "cp-tree.def"
385 };
386 #undef DEFTREECODE
387 \f
388 /* toplev.c needs to call these.  */
389
390 void
391 lang_init_options ()
392 {
393 #if USE_CPPLIB
394   cpp_reader_init (&parse_in);
395   parse_in.opts = &parse_options;
396   cpp_options_init (&parse_options);
397 #endif
398
399   /* Default exceptions on.  */
400   flag_exceptions = 1;
401 }
402
403 void
404 lang_init ()
405 {
406   /* the beginning of the file is a new line; check for # */
407   /* With luck, we discover the real source file's name from that
408      and put it in input_filename.  */
409 #if ! USE_CPPLIB
410   put_back (check_newline ());
411 #else
412   check_newline ();
413   yy_cur--;
414 #endif
415   if (flag_gnu_xref) GNU_xref_begin (input_filename);
416   init_repo (input_filename);
417 }
418
419 void
420 lang_finish ()
421 {
422   extern int errorcount, sorrycount;
423   if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
424 }
425
426 char *
427 lang_identify ()
428 {
429   return "cplusplus";
430 }
431
432 void
433 init_filename_times ()
434 {
435   this_filename_time = get_time_identifier ("<top level>");
436   if (flag_detailed_statistics)
437     {
438       header_time = 0;
439       body_time = my_get_run_time ();
440       TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) 
441         = body_time;
442     }
443 }
444
445 /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
446    Stuck this hack in to get the files open correctly; this is called
447    in place of init_parse if we are an unexec'd binary.    */
448
449 #if 0
450 void
451 reinit_lang_specific ()
452 {
453   init_filename_times ();
454   reinit_search_statistics ();
455 }
456 #endif
457
458 static int *
459 init_cpp_parse ()
460 {
461 #ifdef GATHER_STATISTICS
462 #ifdef REDUCE_LENGTH
463   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
464   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
465   reduce_count += 1;
466   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
467   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
468   token_count += 1;
469 #endif
470 #endif
471   return token_count;
472 }
473
474 char *
475 init_parse (filename)
476      char *filename;
477 {
478   extern int flag_no_gnu_keywords;
479   extern int flag_operator_names;
480
481   int i;
482
483 #ifdef MULTIBYTE_CHARS
484   /* Change to the native locale for multibyte conversions.  */
485   setlocale (LC_CTYPE, "");
486   literal_codeset = getenv ("LANG");
487 #endif
488
489 #if USE_CPPLIB
490   parse_in.show_column = 1;
491   if (! cpp_start_read (&parse_in, filename))
492     abort ();
493
494   /* cpp_start_read always puts at least one line directive into the
495      token buffer.  We must arrange to read it out here. */
496   yy_cur = parse_in.token_buffer;
497   yy_lim = CPP_PWRITTEN (&parse_in);
498
499 #else
500   /* Open input file.  */
501   if (filename == 0 || !strcmp (filename, "-"))
502     {
503       finput = stdin;
504       filename = "stdin";
505     }
506   else
507     finput = fopen (filename, "r");
508   if (finput == 0)
509     pfatal_with_name (filename);
510
511 #ifdef IO_BUFFER_SIZE
512   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
513 #endif
514 #endif /* !USE_CPPLIB */
515
516   /* Initialize the lookahead machinery.  */
517   init_spew ();
518
519   /* Make identifier nodes long enough for the language-specific slots.  */
520   set_identifier_size (sizeof (struct lang_identifier));
521   decl_printable_name = lang_printable_name;
522
523   init_cplus_expand ();
524
525   bcopy (cplus_tree_code_type,
526          tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
527          (int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
528   bcopy ((char *)cplus_tree_code_length,
529          (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
530          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
531   bcopy ((char *)cplus_tree_code_name,
532          (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
533          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
534
535   opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
536   bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
537   assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
538   bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
539
540   ansi_opname[0] = get_identifier ("<invalid operator>");
541   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
542     {
543       ansi_opname[i] = ansi_opname[0];
544       ansi_assopname[i] = ansi_opname[0];
545     }
546
547   ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
548   IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
549   ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
550   ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
551   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
552   ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
553   ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
554   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
555   ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
556   IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
557   ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
558   ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
559   ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
560   ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
561   IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
562   ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
563   ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
564   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
565   ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
566   ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
567   IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
568   ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
569   IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
570   ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
571   IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
572   ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
573   IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
574   ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
575   IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
576   ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
577   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
578   ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
579   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
580   ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
581   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
582   ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
583   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
584   ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
585   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
586   ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
587   ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
588   IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
589   ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
590   ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
591   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
592   ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
593   IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
594   ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
595   IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
596   ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
597   ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
598   ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
599   ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
600   ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
601   ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
602   ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
603   ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
604   ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
605   IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
606   ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
607   IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
608   ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
609   ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
610   ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
611   IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
612   ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
613   IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
614   ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
615   IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
616   ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
617   IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
618   ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
619   IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
620   ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
621   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
622   ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
623   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
624   ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
625   ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
626   ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
627   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
628   ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
629   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
630   ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
631   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
632   ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
633   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
634   ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
635   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
636   ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
637   ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
638   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
639   ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
640   IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
641   ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
642   IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
643   ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
644   IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
645   ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
646   IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
647   ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
648   IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
649   ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
650   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
651   ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
652   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
653   ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT);
654   IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
655
656   /* This is not true: these operators are not defined in ANSI,
657      but we need them anyway.  */
658   ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
659   IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
660   ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
661   IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
662   ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
663   IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
664   ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz");
665   IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1;
666
667   init_method ();
668   init_error ();
669   gcc_obstack_init (&inline_text_obstack);
670   inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
671
672   /* Start it at 0, because check_newline is called at the very beginning
673      and will increment it to 1.  */
674   lineno = 0;
675   input_filename = "<internal>";
676   current_function_decl = NULL;
677
678   maxtoken = 40;
679   token_buffer = (char *) xmalloc (maxtoken + 2);
680
681   ridpointers[(int) RID_INT] = get_identifier ("int");
682   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
683                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
684   ridpointers[(int) RID_BOOL] = get_identifier ("bool");
685   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
686                           build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
687   ridpointers[(int) RID_CHAR] = get_identifier ("char");
688   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
689                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
690   ridpointers[(int) RID_VOID] = get_identifier ("void");
691   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
692                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
693   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
694   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
695                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
696   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
697   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
698                           build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
699   ridpointers[(int) RID_SHORT] = get_identifier ("short");
700   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
701                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
702   ridpointers[(int) RID_LONG] = get_identifier ("long");
703   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
704                           build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
705   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
706   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
707                           build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
708   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
709   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
710                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
711   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
712   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
713                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
714   ridpointers[(int) RID_CONST] = get_identifier ("const");
715   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
716                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
717   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
718   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
719                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
720   ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
721   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT],
722                           build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT]));
723   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
724   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
725                           build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
726   ridpointers[(int) RID_STATIC] = get_identifier ("static");
727   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
728                           build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
729   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
730   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
731                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
732   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
733   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
734                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
735   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
736   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
737                           build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
738   ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex");
739   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX],
740                           build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX]));
741
742   /* C++ extensions. These are probably not correctly named.  */
743   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
744   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
745                           build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
746   class_type_node = build_int_2 (class_type, 0);
747   TREE_TYPE (class_type_node) = class_type_node;
748   ridpointers[(int) RID_CLASS] = class_type_node;
749
750   record_type_node = build_int_2 (record_type, 0);
751   TREE_TYPE (record_type_node) = record_type_node;
752   ridpointers[(int) RID_RECORD] = record_type_node;
753
754   union_type_node = build_int_2 (union_type, 0);
755   TREE_TYPE (union_type_node) = union_type_node;
756   ridpointers[(int) RID_UNION] = union_type_node;
757
758   enum_type_node = build_int_2 (enum_type, 0);
759   TREE_TYPE (enum_type_node) = enum_type_node;
760   ridpointers[(int) RID_ENUM] = enum_type_node;
761
762   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
763   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
764                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
765   ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
766   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT],
767                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT]));
768   ridpointers[(int) RID_EXPORT] = get_identifier ("export");
769   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPORT],
770                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPORT]));
771   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
772   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
773                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
774
775   ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
776   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
777                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
778   ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
779   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
780                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
781   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
782   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
783                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
784   ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
785   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
786                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
787   /* This is for ANSI C++.  */
788   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
789   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
790                           build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
791
792   /* Signature handling extensions.  */
793   signature_type_node = build_int_2 (signature_type, 0);
794   TREE_TYPE (signature_type_node) = signature_type_node;
795   ridpointers[(int) RID_SIGNATURE] = signature_type_node;
796
797   /* Create the built-in __null node.  Note that we can't yet call for
798      type_for_size here because integer_type_node and so forth are not
799      set up.  Therefore, we don't set the type of these nodes until
800      init_decl_processing.  */
801   null_node = build_int_2 (0, 0);
802   ridpointers[RID_NULL] = null_node;
803
804   opname_tab[(int) COMPONENT_REF] = "->";
805   opname_tab[(int) MEMBER_REF] = "->*";
806   opname_tab[(int) INDIRECT_REF] = "*";
807   opname_tab[(int) ARRAY_REF] = "[]";
808   opname_tab[(int) MODIFY_EXPR] = "=";
809   opname_tab[(int) NEW_EXPR] = "new";
810   opname_tab[(int) DELETE_EXPR] = "delete";
811   opname_tab[(int) VEC_NEW_EXPR] = "new []";
812   opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
813   opname_tab[(int) COND_EXPR] = "?:";
814   opname_tab[(int) CALL_EXPR] = "()";
815   opname_tab[(int) PLUS_EXPR] = "+";
816   opname_tab[(int) MINUS_EXPR] = "-";
817   opname_tab[(int) MULT_EXPR] = "*";
818   opname_tab[(int) TRUNC_DIV_EXPR] = "/";
819   opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
820   opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
821   opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
822   opname_tab[(int) TRUNC_MOD_EXPR] = "%";
823   opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
824   opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
825   opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
826   opname_tab[(int) NEGATE_EXPR] = "-";
827   opname_tab[(int) MIN_EXPR] = "<?";
828   opname_tab[(int) MAX_EXPR] = ">?";
829   opname_tab[(int) ABS_EXPR] = "abs";
830   opname_tab[(int) FFS_EXPR] = "ffs";
831   opname_tab[(int) LSHIFT_EXPR] = "<<";
832   opname_tab[(int) RSHIFT_EXPR] = ">>";
833   opname_tab[(int) BIT_IOR_EXPR] = "|";
834   opname_tab[(int) BIT_XOR_EXPR] = "^";
835   opname_tab[(int) BIT_AND_EXPR] = "&";
836   opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
837   opname_tab[(int) BIT_NOT_EXPR] = "~";
838   opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
839   opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
840   opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
841   opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
842   opname_tab[(int) TRUTH_NOT_EXPR] = "!";
843   opname_tab[(int) LT_EXPR] = "<";
844   opname_tab[(int) LE_EXPR] = "<=";
845   opname_tab[(int) GT_EXPR] = ">";
846   opname_tab[(int) GE_EXPR] = ">=";
847   opname_tab[(int) EQ_EXPR] = "==";
848   opname_tab[(int) NE_EXPR] = "!=";
849   opname_tab[(int) IN_EXPR] = "in";
850   opname_tab[(int) RANGE_EXPR] = "...";
851   opname_tab[(int) CONVERT_EXPR] = "+";
852   opname_tab[(int) ADDR_EXPR] = "&";
853   opname_tab[(int) PREDECREMENT_EXPR] = "--";
854   opname_tab[(int) PREINCREMENT_EXPR] = "++";
855   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
856   opname_tab[(int) POSTINCREMENT_EXPR] = "++";
857   opname_tab[(int) COMPOUND_EXPR] = ",";
858
859   assignop_tab[(int) NOP_EXPR] = "=";
860   assignop_tab[(int) PLUS_EXPR] =  "+=";
861   assignop_tab[(int) CONVERT_EXPR] =  "+=";
862   assignop_tab[(int) MINUS_EXPR] = "-=";
863   assignop_tab[(int) NEGATE_EXPR] = "-=";
864   assignop_tab[(int) MULT_EXPR] = "*=";
865   assignop_tab[(int) INDIRECT_REF] = "*=";
866   assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
867   assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
868   assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
869   assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
870   assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
871   assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
872   assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
873   assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
874   assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
875   assignop_tab[(int) MIN_EXPR] = "<?=";
876   assignop_tab[(int) MAX_EXPR] = ">?=";
877   assignop_tab[(int) LSHIFT_EXPR] = "<<=";
878   assignop_tab[(int) RSHIFT_EXPR] = ">>=";
879   assignop_tab[(int) BIT_IOR_EXPR] = "|=";
880   assignop_tab[(int) BIT_XOR_EXPR] = "^=";
881   assignop_tab[(int) BIT_AND_EXPR] = "&=";
882   assignop_tab[(int) ADDR_EXPR] = "&=";
883
884   init_filename_times ();
885
886   /* Some options inhibit certain reserved words.
887      Clear those words out of the hash table so they won't be recognized.  */
888 #define UNSET_RESERVED_WORD(STRING) \
889   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
890        if (s) s->name = ""; } while (0)
891
892 #if 0
893   /* let's parse things, and if they use it, then give them an error.  */
894   if (!flag_exceptions)
895     {
896       UNSET_RESERVED_WORD ("throw");
897       UNSET_RESERVED_WORD ("try");
898       UNSET_RESERVED_WORD ("catch");
899     }
900 #endif
901
902   if (!flag_rtti || flag_no_gnu_keywords)
903     {
904       UNSET_RESERVED_WORD ("classof");
905       UNSET_RESERVED_WORD ("headof");
906     }
907
908   if (! flag_handle_signatures || flag_no_gnu_keywords)
909     {
910       /* Easiest way to not recognize signature
911          handling extensions...  */
912       UNSET_RESERVED_WORD ("signature");
913       UNSET_RESERVED_WORD ("sigof");
914     }
915   if (flag_no_asm || flag_no_gnu_keywords)
916     UNSET_RESERVED_WORD ("typeof");
917   if (! flag_operator_names)
918     {
919       /* These are new ANSI keywords that may break code.  */
920       UNSET_RESERVED_WORD ("and");
921       UNSET_RESERVED_WORD ("and_eq");
922       UNSET_RESERVED_WORD ("bitand");
923       UNSET_RESERVED_WORD ("bitor");
924       UNSET_RESERVED_WORD ("compl");
925       UNSET_RESERVED_WORD ("not");
926       UNSET_RESERVED_WORD ("not_eq");
927       UNSET_RESERVED_WORD ("or");
928       UNSET_RESERVED_WORD ("or_eq");
929       UNSET_RESERVED_WORD ("xor");
930       UNSET_RESERVED_WORD ("xor_eq");
931     }
932
933   token_count = init_cpp_parse ();
934   interface_unknown = 1;
935
936   return filename;
937 }
938
939 void
940 finish_parse ()
941 {
942 #if USE_CPPLIB
943   cpp_finish (&parse_in);
944 #else
945   fclose (finput);
946 #endif
947 }
948
949 void
950 reinit_parse_for_function ()
951 {
952   current_base_init_list = NULL_TREE;
953   current_member_init_list = NULL_TREE;
954 }
955 \f
956 #ifdef __GNUC__
957 __inline
958 #endif
959 void
960 yyprint (file, yychar, yylval)
961      FILE *file;
962      int yychar;
963      YYSTYPE yylval;
964 {
965   tree t;
966   switch (yychar)
967     {
968     case IDENTIFIER:
969     case TYPENAME:
970     case TYPESPEC:
971     case PTYPENAME:
972     case IDENTIFIER_DEFN:
973     case TYPENAME_DEFN:
974     case PTYPENAME_DEFN:
975     case SCSPEC:
976     case PRE_PARSED_CLASS_DECL:
977       t = yylval.ttype;
978       if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
979         {
980           fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
981           break;
982         }
983       my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
984       if (IDENTIFIER_POINTER (t))
985           fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
986       break;
987     case AGGR:
988       if (yylval.ttype == class_type_node)
989         fprintf (file, " `class'");
990       else if (yylval.ttype == record_type_node)
991         fprintf (file, " `struct'");
992       else if (yylval.ttype == union_type_node)
993         fprintf (file, " `union'");
994       else if (yylval.ttype == enum_type_node)
995         fprintf (file, " `enum'");
996       else if (yylval.ttype == signature_type_node)
997         fprintf (file, " `signature'");
998       else
999         my_friendly_abort (80);
1000       break;
1001     }
1002 }
1003
1004 #if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
1005 static int *reduce_count;
1006 #endif
1007
1008 int *token_count;
1009
1010 #if 0
1011 #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
1012 #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
1013 #endif
1014
1015 #ifdef GATHER_STATISTICS
1016 #ifdef REDUCE_LENGTH
1017 void
1018 yyhook (yyn)
1019      int yyn;
1020 {
1021   reduce_count[yyn] += 1;
1022 }
1023
1024 static int
1025 reduce_cmp (p, q)
1026      int *p, *q;
1027 {
1028   return reduce_count[*q] - reduce_count[*p];
1029 }
1030
1031 static int
1032 token_cmp (p, q)
1033      int *p, *q;
1034 {
1035   return token_count[*q] - token_count[*p];
1036 }
1037 #endif
1038 #endif
1039
1040 void
1041 print_parse_statistics ()
1042 {
1043 #ifdef GATHER_STATISTICS
1044 #ifdef REDUCE_LENGTH
1045 #if YYDEBUG != 0
1046   int i;
1047   int maxlen = REDUCE_LENGTH;
1048   unsigned *sorted;
1049   
1050   if (reduce_count[-1] == 0)
1051     return;
1052
1053   if (TOKEN_LENGTH > REDUCE_LENGTH)
1054     maxlen = TOKEN_LENGTH;
1055   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
1056
1057   for (i = 0; i < TOKEN_LENGTH; i++)
1058     sorted[i] = i;
1059   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
1060   for (i = 0; i < TOKEN_LENGTH; i++)
1061     {
1062       int idx = sorted[i];
1063       if (token_count[idx] == 0)
1064         break;
1065       if (token_count[idx] < token_count[-1])
1066         break;
1067       fprintf (stderr, "token %d, `%s', count = %d\n",
1068                idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
1069     }
1070   fprintf (stderr, "\n");
1071   for (i = 0; i < REDUCE_LENGTH; i++)
1072     sorted[i] = i;
1073   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
1074   for (i = 0; i < REDUCE_LENGTH; i++)
1075     {
1076       int idx = sorted[i];
1077       if (reduce_count[idx] == 0)
1078         break;
1079       if (reduce_count[idx] < reduce_count[-1])
1080         break;
1081       fprintf (stderr, "rule %d, line %d, count = %d\n",
1082                idx, yyrline[idx], reduce_count[idx]);
1083     }
1084   fprintf (stderr, "\n");
1085 #endif
1086 #endif
1087 #endif
1088 }
1089
1090 /* Sets the value of the 'yydebug' variable to VALUE.
1091    This is a function so we don't have to have YYDEBUG defined
1092    in order to build the compiler.  */
1093
1094 void
1095 set_yydebug (value)
1096      int value;
1097 {
1098 #if YYDEBUG != 0
1099   extern int yydebug;
1100   yydebug = value;
1101 #else
1102   warning ("YYDEBUG not defined.");
1103 #endif
1104 }
1105
1106 \f
1107 /* Functions and data structures for #pragma interface.
1108
1109    `#pragma implementation' means that the main file being compiled
1110    is considered to implement (provide) the classes that appear in
1111    its main body.  I.e., if this is file "foo.cc", and class `bar'
1112    is defined in "foo.cc", then we say that "foo.cc implements bar".
1113
1114    All main input files "implement" themselves automagically.
1115
1116    `#pragma interface' means that unless this file (of the form "foo.h"
1117    is not presently being included by file "foo.cc", the
1118    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
1119    of the vtables nor any of the inline functions defined in foo.h
1120    will ever be output.
1121
1122    There are cases when we want to link files such as "defs.h" and
1123    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
1124    and "main.cc" has `#pragma implementation "defs.h"'.  */
1125
1126 struct impl_files
1127 {
1128   char *filename;
1129   struct impl_files *next;
1130 };
1131
1132 static struct impl_files *impl_file_chain;
1133
1134 /* Helper function to load global variables with interface
1135    information.  */
1136
1137 void
1138 extract_interface_info ()
1139 {
1140   tree fileinfo = 0;
1141
1142   if (flag_alt_external_templates)
1143     {
1144       struct tinst_level *til = tinst_for_decl ();
1145   
1146       if (til)
1147         fileinfo = get_time_identifier (til->file);
1148     }
1149   if (!fileinfo)
1150     fileinfo = get_time_identifier (input_filename);
1151   fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
1152   interface_only = TREE_INT_CST_LOW (fileinfo);
1153   interface_unknown = TREE_INT_CST_HIGH (fileinfo);
1154 }
1155
1156 /* Return nonzero if S is not considered part of an
1157    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
1158
1159 static int
1160 interface_strcmp (s)
1161      char *s;
1162 {
1163   /* Set the interface/implementation bits for this scope.  */
1164   struct impl_files *ifiles;
1165   char *s1;
1166
1167   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
1168     {
1169       char *t1 = ifiles->filename;
1170       s1 = s;
1171
1172       if (*s1 != *t1 || *s1 == 0)
1173         continue;
1174
1175       while (*s1 == *t1 && *s1 != 0)
1176         s1++, t1++;
1177
1178       /* A match.  */
1179       if (*s1 == *t1)
1180         return 0;
1181
1182       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
1183       if (index (s1, '.') || index (t1, '.'))
1184         continue;
1185
1186       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
1187         continue;
1188
1189       /* A match.  */
1190       return 0;
1191     }
1192
1193   /* No matches.  */
1194   return 1;
1195 }
1196
1197 static void
1198 set_typedecl_interface_info (prev, vars)
1199      tree prev ATTRIBUTE_UNUSED, vars;
1200 {
1201   tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
1202   tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
1203   tree type = TREE_TYPE (vars);
1204
1205   CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
1206     = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars)));
1207 }
1208
1209 static int
1210 set_vardecl_interface_info (prev, vars)
1211      tree prev, vars;
1212 {
1213   tree type = DECL_CONTEXT (vars);
1214
1215   if (CLASSTYPE_INTERFACE_KNOWN (type))
1216     {
1217       if (CLASSTYPE_INTERFACE_ONLY (type))
1218         set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));
1219       else
1220         CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
1221       DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
1222       TREE_PUBLIC (vars) = 1;
1223       return 1;
1224     }
1225   return 0;
1226 }
1227 \f
1228 /* Set up the state required to correctly handle the definition of the
1229    inline function whose preparsed state has been saved in PI.  */
1230
1231 static void
1232 begin_definition_of_inclass_inline (pi)
1233      struct pending_inline* pi;
1234 {
1235   tree context;
1236
1237   if (!pi->fndecl)
1238     return;
1239
1240   /* If this is an inline function in a local class, we must make sure
1241      that we save all pertinent information about the function
1242      surrounding the local class.  */
1243   context = hack_decl_function_context (pi->fndecl);
1244   if (context)
1245     push_cp_function_context (context);
1246
1247   feed_input (pi->buf, pi->len);
1248   lineno = pi->lineno;
1249   input_filename = pi->filename;
1250   yychar = PRE_PARSED_FUNCTION_DECL;
1251   yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
1252   /* Pass back a handle to the rest of the inline functions, so that they
1253      can be processed later.  */
1254   DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
1255   interface_unknown = pi->interface == 1;
1256   interface_only  = pi->interface == 0;
1257 }
1258
1259 /* Called from the top level: if there are any pending inlines to
1260    do, set up to process them now.  This function sets up the first function
1261    to be parsed; after it has been, the rule for fndef in parse.y will
1262    call process_next_inline to start working on the next one.  */
1263
1264 void
1265 do_pending_inlines ()
1266 {
1267   struct pending_inline *t;
1268
1269   /* Oops, we're still dealing with the last batch.  */
1270   if (yychar == PRE_PARSED_FUNCTION_DECL)
1271     return;
1272
1273   /* Reverse the pending inline functions, since
1274      they were cons'd instead of appended.  */
1275   {
1276     struct pending_inline *prev = 0, *tail;
1277     t = pending_inlines;
1278     pending_inlines = 0;
1279
1280     for (; t; t = tail)
1281       {
1282         tail = t->next;
1283         t->next = prev;
1284         t->deja_vu = 1;
1285         prev = t;
1286       }
1287     t = prev;
1288   }
1289
1290   if (t == 0)
1291     return;
1292             
1293   /* Now start processing the first inline function.  */
1294   begin_definition_of_inclass_inline (t);
1295 }
1296
1297 static int nextchar = -1;
1298
1299 /* Called from the fndecl rule in the parser when the function just parsed
1300    was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
1301    do_pending_inlines).  */
1302
1303 void
1304 process_next_inline (t)
1305      tree t;
1306 {
1307   tree context;
1308   struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
1309   context = hack_decl_function_context (i->fndecl);  
1310   if (context)
1311     pop_cp_function_context (context);
1312   i = i->next;
1313   if (yychar == YYEMPTY)
1314     yychar = yylex ();
1315   if (yychar != END_OF_SAVED_INPUT)
1316     {
1317       error ("parse error at end of saved function text");
1318
1319       /* restore_pending_input will abort unless yychar is either
1320          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1321          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1322          since that may have gotten set as well.  */
1323       nextchar = -1;
1324     }
1325   yychar = YYEMPTY;
1326   end_input ();
1327   if (i)
1328     begin_definition_of_inclass_inline (i);
1329   else
1330     extract_interface_info ();
1331 }
1332
1333 /* Since inline methods can refer to text which has not yet been seen,
1334    we store the text of the method in a structure which is placed in the
1335    DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
1336    After parsing the body of the class definition, the FUNCTION_DECL's are
1337    scanned to see which ones have this field set.  Those are then digested
1338    one at a time.
1339
1340    This function's FUNCTION_DECL will have a bit set in its common so
1341    that we know to watch out for it.  */
1342
1343 static void
1344 consume_string (this_obstack, matching_char)
1345      register struct obstack *this_obstack;
1346      int matching_char;
1347 {
1348   register int c;
1349   int starting_lineno = lineno;
1350   do
1351     {
1352       c = getch ();
1353       if (c == EOF)
1354         {
1355           int save_lineno = lineno;
1356           lineno = starting_lineno;
1357           if (matching_char == '"')
1358             error ("end of file encountered inside string constant");
1359           else
1360             error ("end of file encountered inside character constant");
1361           lineno = save_lineno;
1362           return;
1363         }
1364       if (c == '\\')
1365         {
1366           obstack_1grow (this_obstack, c);
1367           c = getch ();
1368           obstack_1grow (this_obstack, c);
1369
1370           /* Make sure we continue the loop */
1371           c = 0;
1372           continue;
1373         }
1374       if (c == '\n')
1375         {
1376           if (pedantic)
1377             pedwarn ("ANSI C++ forbids newline in string constant");
1378           lineno++;
1379         }
1380       obstack_1grow (this_obstack, c);
1381     }
1382   while (c != matching_char);
1383 }
1384
1385 static int nextyychar = YYEMPTY;
1386 static YYSTYPE nextyylval;
1387
1388 struct pending_input {
1389   int nextchar, yychar, nextyychar, eof;
1390   YYSTYPE yylval, nextyylval;
1391   struct obstack token_obstack;
1392   int first_token;
1393 };
1394
1395 struct pending_input *
1396 save_pending_input ()
1397 {
1398   struct pending_input *p;
1399   p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
1400   p->nextchar = nextchar;
1401   p->yychar = yychar;
1402   p->nextyychar = nextyychar;
1403   p->yylval = yylval;
1404   p->nextyylval = nextyylval;
1405   p->eof = end_of_file;
1406   yychar = nextyychar = YYEMPTY;
1407   nextchar = -1;
1408   p->first_token = first_token;
1409   p->token_obstack = token_obstack;
1410
1411   first_token = 0;
1412   gcc_obstack_init (&token_obstack);
1413   end_of_file = 0;
1414   return p;
1415 }
1416
1417 void
1418 restore_pending_input (p)
1419      struct pending_input *p;
1420 {
1421   my_friendly_assert (nextchar == -1, 229);
1422   nextchar = p->nextchar;
1423   my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230);
1424   yychar = p->yychar;
1425   my_friendly_assert (nextyychar == YYEMPTY, 231);
1426   nextyychar = p->nextyychar;
1427   yylval = p->yylval;
1428   nextyylval = p->nextyylval;
1429   first_token = p->first_token;
1430   obstack_free (&token_obstack, (char *) 0);
1431   token_obstack = p->token_obstack;
1432   end_of_file = p->eof;
1433   free (p);
1434 }
1435
1436 /* Unget character CH from the input stream.
1437    If RESCAN is non-zero, then we want to `see' this
1438    character as the next input token.  */
1439
1440 void
1441 yyungetc (ch, rescan)
1442      int ch;
1443      int rescan;
1444 {
1445   /* Unget a character from the input stream.  */
1446   if (yychar == YYEMPTY || rescan == 0)
1447     {
1448       if (nextchar >= 0)
1449         put_back (nextchar);
1450       nextchar = ch;
1451     }
1452   else
1453     {
1454       my_friendly_assert (nextyychar == YYEMPTY, 232);
1455       nextyychar = yychar;
1456       nextyylval = yylval;
1457       yychar = ch;
1458     }
1459 }
1460
1461 void
1462 clear_inline_text_obstack ()
1463 {
1464   obstack_free (&inline_text_obstack, inline_text_firstobj);
1465 }
1466
1467 /* This function stores away the text for an inline function that should
1468    be processed later.  It decides how much later, and may need to move
1469    the info between obstacks; therefore, the caller should not refer to
1470    the T parameter after calling this function.  */
1471
1472 static void
1473 store_pending_inline (decl, t)
1474      tree decl;
1475      struct pending_inline *t;
1476 {
1477   t->fndecl = decl;
1478   DECL_PENDING_INLINE_INFO (decl) = t;
1479
1480   /* Because we use obstacks, we must process these in precise order.  */
1481   t->next = pending_inlines;
1482   pending_inlines = t;
1483 }
1484
1485 void
1486 reinit_parse_for_method (yychar, decl)
1487      int yychar;
1488      tree decl;
1489 {
1490   int len;
1491   int starting_lineno = lineno;
1492   char *starting_filename = input_filename;
1493
1494   reinit_parse_for_block (yychar, &inline_text_obstack);
1495
1496   len = obstack_object_size (&inline_text_obstack);
1497   current_base_init_list = NULL_TREE;
1498   current_member_init_list = NULL_TREE;
1499   if (decl == void_type_node
1500       || (current_class_type && TYPE_REDEFINED (current_class_type)))
1501     {
1502       /* Happens when we get two declarations of the same
1503          function in the same scope.  */
1504       char *buf = obstack_finish (&inline_text_obstack);
1505       obstack_free (&inline_text_obstack, buf);
1506       return;
1507     }
1508   else
1509     {
1510       struct pending_inline *t;
1511       char *buf = obstack_finish (&inline_text_obstack);
1512
1513       t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1514                                                    sizeof (struct pending_inline));
1515       t->lineno = starting_lineno;
1516       t->filename = starting_filename;
1517       t->token = YYEMPTY;
1518       t->token_value = 0;
1519       t->buf = buf;
1520       t->len = len;
1521       t->deja_vu = 0;
1522 #if 0
1523       if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
1524         warn_if_unknown_interface (decl);
1525 #endif
1526       t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
1527       store_pending_inline (decl, t);
1528     }
1529 }
1530
1531 /* Consume a block -- actually, a method beginning
1532    with `:' or `{' -- and save it away on the specified obstack.  */
1533
1534 void
1535 reinit_parse_for_block (pyychar, obstackp)
1536      int pyychar;
1537      struct obstack *obstackp;
1538 {
1539   register int c = 0;
1540   int blev = 1;
1541   int starting_lineno = lineno;
1542   char *starting_filename = input_filename;
1543   int len;
1544   int look_for_semicolon = 0;
1545   int look_for_lbrac = 0;
1546
1547   if (pyychar == '{')
1548     obstack_1grow (obstackp, '{');
1549   else if (pyychar == '=')
1550     look_for_semicolon = 1;
1551   else if (pyychar == ':')
1552     {
1553       obstack_1grow (obstackp, pyychar);
1554       /* Add a space so we don't get confused by ': ::A(20)'.  */
1555       obstack_1grow (obstackp, ' ');
1556       look_for_lbrac = 1;
1557       blev = 0;
1558     }
1559   else if (pyychar == RETURN)
1560     {
1561       obstack_grow (obstackp, "return", 6);
1562       look_for_lbrac = 1;
1563       blev = 0;
1564     }
1565   else if (pyychar == TRY)
1566     {
1567       obstack_grow (obstackp, "try", 3);
1568       look_for_lbrac = 1;
1569       blev = 0;
1570     }
1571   else
1572     {
1573       yyerror ("parse error in method specification");
1574       obstack_1grow (obstackp, '{');
1575     }
1576
1577   if (nextchar != EOF)
1578     {
1579       c = nextchar;
1580       nextchar = EOF;
1581     }
1582   else
1583     c = getch ();
1584   
1585   while (c != EOF)
1586     {
1587       int this_lineno = lineno;
1588
1589       c = skip_white_space (c);
1590
1591       /* Don't lose our cool if there are lots of comments.  */
1592       if (lineno == this_lineno + 1)
1593         obstack_1grow (obstackp, '\n');
1594       else if (lineno == this_lineno)
1595         ;
1596       else if (lineno - this_lineno < 10)
1597         {
1598           int i;
1599           for (i = lineno - this_lineno; i > 0; i--)
1600             obstack_1grow (obstackp, '\n');
1601         }
1602       else
1603         {
1604           char buf[16];
1605           sprintf (buf, "\n# %d \"", lineno);
1606           len = strlen (buf);
1607           obstack_grow (obstackp, buf, len);
1608
1609           len = strlen (input_filename);
1610           obstack_grow (obstackp, input_filename, len);
1611           obstack_1grow (obstackp, '\"');
1612           obstack_1grow (obstackp, '\n');
1613         }
1614
1615       while (c > ' ')           /* ASCII dependent...  */
1616         {
1617           obstack_1grow (obstackp, c);
1618           if (c == '{')
1619             {
1620               look_for_lbrac = 0;
1621               blev++;
1622             }
1623           else if (c == '}')
1624             {
1625               blev--;
1626               if (blev == 0 && !look_for_semicolon)
1627                 {
1628                   if (pyychar == TRY)
1629                     {
1630                       if (peekyylex () == CATCH)
1631                         {
1632                           yylex ();
1633                           obstack_grow (obstackp, " catch ", 7);
1634                           look_for_lbrac = 1;
1635                         }
1636                       else
1637                         {
1638                           yychar = '{';
1639                           goto done;
1640                         }
1641                     }
1642                   else
1643                     {
1644                       goto done;
1645                     }
1646                 }
1647             }
1648           else if (c == '\\')
1649             {
1650               /* Don't act on the next character...e.g, doing an escaped
1651                  double-quote.  */
1652               c = getch ();
1653               if (c == EOF)
1654                 {
1655                   error_with_file_and_line (starting_filename,
1656                                             starting_lineno,
1657                                             "end of file read inside definition");
1658                   goto done;
1659                 }
1660               obstack_1grow (obstackp, c);
1661             }
1662           else if (c == '\"')
1663             consume_string (obstackp, c);
1664           else if (c == '\'')
1665             consume_string (obstackp, c);
1666           else if (c == ';')
1667             {
1668               if (look_for_lbrac)
1669                 {
1670                   error ("function body for constructor missing");
1671                   obstack_1grow (obstackp, '{');
1672                   obstack_1grow (obstackp, '}');
1673                   len += 2;
1674                   goto done;
1675                 }
1676               else if (look_for_semicolon && blev == 0)
1677                 goto done;
1678             }
1679           c = getch ();
1680         }
1681
1682       if (c == EOF)
1683         {
1684           error_with_file_and_line (starting_filename,
1685                                     starting_lineno,
1686                                     "end of file read inside definition");
1687           goto done;
1688         }
1689       else if (c != '\n')
1690         {
1691           obstack_1grow (obstackp, c);
1692           c = getch ();
1693         }
1694     }
1695  done:
1696   obstack_1grow (obstackp, '\0');
1697 }
1698
1699 /* Consume a no-commas expression -- actually, a default argument -- and
1700    save it away on the specified obstack.  */
1701
1702 static void
1703 reinit_parse_for_expr (obstackp)
1704      struct obstack *obstackp;
1705 {
1706   register int c = 0;
1707   int starting_lineno = lineno;
1708   char *starting_filename = input_filename;
1709   int len;
1710   int plev = 0;
1711
1712   if (nextchar != EOF)
1713     {
1714       c = nextchar;
1715       nextchar = EOF;
1716     }
1717   else
1718     c = getch ();
1719   
1720   while (c != EOF)
1721     {
1722       int this_lineno = lineno;
1723
1724       c = skip_white_space (c);
1725
1726       /* Don't lose our cool if there are lots of comments.  */
1727       if (lineno == this_lineno + 1)
1728         obstack_1grow (obstackp, '\n');
1729       else if (lineno == this_lineno)
1730         ;
1731       else if (lineno - this_lineno < 10)
1732         {
1733           int i;
1734           for (i = lineno - this_lineno; i > 0; --i)
1735             obstack_1grow (obstackp, '\n');
1736         }
1737       else
1738         {
1739           char buf[16];
1740           sprintf (buf, "\n# %d \"", lineno);
1741           len = strlen (buf);
1742           obstack_grow (obstackp, buf, len);
1743
1744           len = strlen (input_filename);
1745           obstack_grow (obstackp, input_filename, len);
1746           obstack_1grow (obstackp, '\"');
1747           obstack_1grow (obstackp, '\n');
1748         }
1749
1750       while (c > ' ')           /* ASCII dependent...  */
1751         {
1752           if (plev <= 0 && (c == ')' || c == ','))
1753             {
1754               put_back (c);
1755               goto done;
1756             }
1757           obstack_1grow (obstackp, c);
1758           if (c == '(' || c == '[')
1759             ++plev;
1760           else if (c == ']' || c == ')')
1761             --plev;
1762           else if (c == '\\')
1763             {
1764               /* Don't act on the next character...e.g, doing an escaped
1765                  double-quote.  */
1766               c = getch ();
1767               if (c == EOF)
1768                 {
1769                   error_with_file_and_line (starting_filename,
1770                                             starting_lineno,
1771                                             "end of file read inside definition");
1772                   goto done;
1773                 }
1774               obstack_1grow (obstackp, c);
1775             }
1776           else if (c == '\"')
1777             consume_string (obstackp, c);
1778           else if (c == '\'')
1779             consume_string (obstackp, c);
1780           c = getch ();
1781         }
1782
1783       if (c == EOF)
1784         {
1785           error_with_file_and_line (starting_filename,
1786                                     starting_lineno,
1787                                     "end of file read inside definition");
1788           goto done;
1789         }
1790       else if (c != '\n')
1791         {
1792           obstack_1grow (obstackp, c);
1793           c = getch ();
1794         }
1795     }
1796  done:
1797   obstack_1grow (obstackp, '\0');
1798 }
1799
1800 int do_snarf_defarg;
1801
1802 /* Decide whether the default argument we are about to see should be
1803    gobbled up as text for later parsing.  */
1804
1805 void
1806 maybe_snarf_defarg ()
1807 {
1808   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
1809     do_snarf_defarg = 1;
1810 }
1811
1812 /* When we see a default argument in a method declaration, we snarf it as
1813    text using snarf_defarg.  When we get up to namespace scope, we then go
1814    through and parse all of them using do_pending_defargs.  Since yacc
1815    parsers are not reentrant, we retain defargs state in these two
1816    variables so that subsequent calls to do_pending_defargs can resume
1817    where the previous call left off.  */
1818
1819 tree defarg_fns;
1820 tree defarg_parm;
1821
1822 tree
1823 snarf_defarg ()
1824 {
1825   int len;
1826   char *buf;
1827   tree arg;
1828
1829   reinit_parse_for_expr (&inline_text_obstack);
1830   len = obstack_object_size (&inline_text_obstack);
1831   buf = obstack_finish (&inline_text_obstack);
1832
1833   push_obstacks (&inline_text_obstack, &inline_text_obstack);
1834   arg = make_node (DEFAULT_ARG);
1835   DEFARG_LENGTH (arg) = len - 1;
1836   DEFARG_POINTER (arg) = buf;
1837   pop_obstacks ();
1838
1839   return arg;
1840 }
1841
1842 /* Called from grokfndecl to note a function decl with unparsed default
1843    arguments for later processing.  Also called from grokdeclarator
1844    for function types with unparsed defargs; the call from grokfndecl
1845    will always come second, so we can overwrite the entry from the type.  */
1846
1847 void
1848 add_defarg_fn (decl)
1849      tree decl;
1850 {
1851   if (TREE_CODE (decl) == FUNCTION_DECL)
1852     TREE_VALUE (defarg_fns) = decl;
1853   else
1854     {
1855       push_obstacks (&inline_text_obstack, &inline_text_obstack);
1856       defarg_fns = tree_cons (current_class_type, decl, defarg_fns);  
1857       pop_obstacks ();
1858     }
1859 }
1860
1861 /* Helper for do_pending_defargs.  Starts the parsing of a default arg.  */
1862
1863 static void
1864 feed_defarg (f, p)
1865      tree f, p;
1866 {
1867   tree d = TREE_PURPOSE (p);
1868   feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
1869   if (TREE_CODE (f) == FUNCTION_DECL)
1870     {
1871       lineno = DECL_SOURCE_LINE (f);
1872       input_filename = DECL_SOURCE_FILE (f);
1873     }
1874   yychar = DEFARG_MARKER;
1875   yylval.ttype = p;
1876 }
1877
1878 /* Helper for do_pending_defargs.  Ends the parsing of a default arg.  */
1879
1880 static void
1881 finish_defarg ()
1882 {
1883   if (yychar == YYEMPTY)
1884     yychar = yylex ();
1885   if (yychar != END_OF_SAVED_INPUT)
1886     {
1887       error ("parse error at end of saved function text");
1888
1889       /* restore_pending_input will abort unless yychar is either
1890          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1891          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1892          since that may have gotten set as well.  */
1893       nextchar = -1;
1894     }
1895   yychar = YYEMPTY;
1896   end_input ();
1897 }  
1898
1899 /* Main function for deferred parsing of default arguments.  Called from
1900    the parser.  */
1901
1902 void
1903 do_pending_defargs ()
1904 {
1905   if (defarg_parm)
1906     finish_defarg ();
1907
1908   for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
1909     {
1910       tree defarg_fn = TREE_VALUE (defarg_fns);
1911       if (defarg_parm == NULL_TREE)
1912         {
1913           push_nested_class (TREE_PURPOSE (defarg_fns), 1);
1914           pushlevel (0);
1915           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1916             maybe_begin_member_template_processing (defarg_fn);
1917
1918           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1919             {
1920 #if 0
1921               tree p;
1922               for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
1923                 pushdecl (copy_node (p));
1924 #endif
1925               defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
1926             }
1927           else
1928             defarg_parm = TYPE_ARG_TYPES (defarg_fn);
1929         }
1930       else
1931         defarg_parm = TREE_CHAIN (defarg_parm);
1932
1933       for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
1934         if (TREE_PURPOSE (defarg_parm)
1935             && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG)
1936           {
1937             feed_defarg (defarg_fn, defarg_parm);
1938
1939             /* Return to the parser, which will process this defarg
1940                and call us again.  */
1941             return;
1942           }
1943
1944       if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1945         {
1946           maybe_end_member_template_processing ();
1947           check_default_args (defarg_fn);
1948         }
1949
1950       poplevel (0, 0, 0);
1951       pop_nested_class (1);
1952     }
1953 }
1954
1955 /* Build a default function named NAME for type TYPE.
1956    KIND says what to build.
1957
1958    When KIND == 0, build default destructor.
1959    When KIND == 1, build virtual destructor.
1960    When KIND == 2, build default constructor.
1961    When KIND == 3, build default X(const X&) constructor.
1962    When KIND == 4, build default X(X&) constructor.
1963    When KIND == 5, build default operator = (const X&).
1964    When KIND == 6, build default operator = (X&).  */
1965
1966 tree
1967 cons_up_default_function (type, full_name, kind)
1968      tree type, full_name;
1969      int kind;
1970 {
1971   extern tree void_list_node;
1972   tree declspecs = NULL_TREE;
1973   tree fn, args = NULL_TREE;
1974   tree argtype;
1975   int retref = 0;
1976   tree name = constructor_name (full_name);
1977
1978   switch (kind)
1979     {
1980       /* Destructors.  */
1981     case 1:
1982       declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
1983       /* Fall through...  */
1984     case 0:
1985       name = build_parse_node (BIT_NOT_EXPR, name);
1986       args = void_list_node;
1987       break;
1988
1989     case 2:
1990       /* Default constructor.  */
1991       args = void_list_node;
1992       break;
1993
1994     case 3:
1995       type = build_qualified_type (type, TYPE_QUAL_CONST);
1996       /* Fall through...  */
1997     case 4:
1998       /* According to ARM $12.8, the default copy ctor will be declared, but
1999          not defined, unless it's needed.  */
2000       argtype = build_reference_type (type);
2001       args = tree_cons (NULL_TREE,
2002                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
2003                                          get_identifier ("_ctor_arg")),
2004                         void_list_node);
2005       break;
2006
2007     case 5:
2008     case 6:
2009       retref = 1;
2010       declspecs = build_decl_list (NULL_TREE, type);
2011
2012       if (kind == 5)
2013         type = build_qualified_type (type, TYPE_QUAL_CONST);
2014
2015       name = ansi_opname [(int) MODIFY_EXPR];
2016
2017       argtype = build_reference_type (type);
2018       args = tree_cons (NULL_TREE,
2019                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
2020                                          get_identifier ("_ctor_arg")),
2021                         void_list_node);
2022       break;
2023
2024     default:
2025       my_friendly_abort (59);
2026     }
2027
2028   declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
2029                               declspecs);
2030
2031   TREE_PARMLIST (args) = 1;
2032
2033   {
2034     tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
2035     if (retref)
2036       declarator = build_parse_node (ADDR_EXPR, declarator);
2037
2038     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
2039   }
2040   
2041   if (fn == void_type_node)
2042     return fn;
2043
2044   if (kind > 2)
2045     SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
2046
2047 #if 0
2048   if (processing_template_defn)
2049     {
2050       SET_DECL_IMPLICIT_INSTANTIATION (fn);
2051       repo_template_used (fn);
2052     }
2053 #endif
2054
2055 #if 0
2056   if (CLASSTYPE_INTERFACE_KNOWN (type))
2057     {
2058       DECL_INTERFACE_KNOWN (fn) = 1;
2059       DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
2060                                      && flag_implement_inlines);
2061     }
2062   else
2063 #endif
2064     DECL_NOT_REALLY_EXTERN (fn) = 1;
2065
2066   mark_inline_for_output (fn);
2067
2068 #ifdef DEBUG_DEFAULT_FUNCTIONS
2069   { char *fn_type = NULL;
2070     tree t = name;
2071     switch (kind)
2072       {
2073       case 0: fn_type = "default destructor"; break;
2074       case 1: fn_type = "virtual destructor"; break;
2075       case 2: fn_type = "default constructor"; break;
2076       case 3: fn_type = "default X(const X&)"; break;
2077       case 4: fn_type = "default X(X&)"; break;
2078       }
2079     if (fn_type)
2080       {
2081         if (TREE_CODE (name) == BIT_NOT_EXPR)
2082           t = TREE_OPERAND (name, 0);
2083         fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
2084                  IDENTIFIER_POINTER (t), func_buf);
2085       }
2086   }
2087 #endif /* DEBUG_DEFAULT_FUNCTIONS */
2088
2089   /* Show that this function was generated by the compiler.  */
2090   SET_DECL_ARTIFICIAL (fn);
2091   
2092   return fn;
2093 }
2094
2095 /* Heuristic to tell whether the user is missing a semicolon
2096    after a struct or enum declaration.  Emit an error message
2097    if we know the user has blown it.  */
2098
2099 void
2100 check_for_missing_semicolon (type)
2101      tree type;
2102 {
2103   if (yychar < 0)
2104     yychar = yylex ();
2105
2106   if ((yychar > 255
2107        && yychar != SCSPEC
2108        && yychar != IDENTIFIER
2109        && yychar != TYPENAME
2110        && yychar != CV_QUALIFIER
2111        && yychar != SELFNAME)
2112       || end_of_file)
2113     {
2114       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
2115         error ("semicolon missing after %s declaration",
2116                TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
2117       else
2118         cp_error ("semicolon missing after declaration of `%T'", type);
2119       shadow_tag (build_tree_list (0, type));
2120     }
2121   /* Could probably also hack cases where class { ... } f (); appears.  */
2122   clear_anon_tags ();
2123 }
2124
2125 void
2126 note_got_semicolon (type)
2127      tree type;
2128 {
2129   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
2130     my_friendly_abort (60);
2131   if (CLASS_TYPE_P (type))
2132     CLASSTYPE_GOT_SEMICOLON (type) = 1;
2133 }
2134
2135 void
2136 note_list_got_semicolon (declspecs)
2137      tree declspecs;
2138 {
2139   tree link;
2140
2141   for (link = declspecs; link; link = TREE_CHAIN (link))
2142     {
2143       tree type = TREE_VALUE (link);
2144       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
2145         note_got_semicolon (type);
2146     }
2147   clear_anon_tags ();
2148 }
2149 \f
2150 /* If C is not whitespace, return C.
2151    Otherwise skip whitespace and return first nonwhite char read.  */
2152
2153 static int
2154 skip_white_space (c)
2155      register int c;
2156 {
2157   for (;;)
2158     {
2159       switch (c)
2160         {
2161         case '\n':
2162           c = check_newline ();
2163           break;
2164
2165         case ' ':
2166         case '\t':
2167         case '\f':
2168         case '\r':
2169         case '\v':
2170         case '\b':
2171           do
2172             c = getch ();
2173           while (c == ' ' || c == '\t');
2174           break;
2175
2176         case '\\':
2177           c = getch ();
2178           if (c == '\n')
2179             lineno++;
2180           else
2181             error ("stray '\\' in program");
2182           c = getch ();
2183           break;
2184
2185         default:
2186           return (c);
2187         }
2188     }
2189 }
2190
2191
2192
2193 /* Make the token buffer longer, preserving the data in it.
2194    P should point to just beyond the last valid character in the old buffer.
2195    The value we return is a pointer to the new buffer
2196    at a place corresponding to P.  */
2197
2198 static char *
2199 extend_token_buffer (p)
2200      char *p;
2201 {
2202   int offset = p - token_buffer;
2203
2204   maxtoken = maxtoken * 2 + 10;
2205   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
2206
2207   return token_buffer + offset;
2208 }
2209 \f
2210 static int
2211 get_last_nonwhite_on_line ()
2212 {
2213   register int c;
2214
2215   /* Is this the last nonwhite stuff on the line?  */
2216   if (nextchar >= 0)
2217     c = nextchar, nextchar = -1;
2218   else
2219     c = getch ();
2220
2221   while (c == ' ' || c == '\t')
2222     c = getch ();
2223   return c;
2224 }
2225
2226 #if defined HANDLE_PRAGMA
2227 /* Local versions of these macros, that can be passed as function pointers.  */
2228 static int
2229 pragma_getc ()
2230 {
2231   int c;
2232       
2233   if (nextchar != EOF)
2234     {
2235       c = nextchar;
2236       nextchar = EOF;
2237     }
2238   else
2239     c = getch ();
2240
2241   return c;
2242 }
2243
2244 static void
2245 pragma_ungetc (arg)
2246      int arg;
2247 {
2248   yyungetc (arg, 0);
2249 }
2250 #endif /* HANDLE_PRAGMA */
2251
2252 /* At the beginning of a line, increment the line number
2253    and process any #-directive on this line.
2254    If the line is a #-directive, read the entire line and return a newline.
2255    Otherwise, return the line's first non-whitespace character.  */
2256
2257 int linemode;
2258
2259 static int handle_cp_pragma PROTO((char *));
2260
2261 static int
2262 check_newline ()
2263 {
2264   register int c;
2265   register int token;
2266   int saw_line = 0;
2267
2268   /* Read first nonwhite char on the line.  Do this before incrementing the
2269      line number, in case we're at the end of saved text.  */
2270
2271   do
2272     c = getch ();
2273   while (c == ' ' || c == '\t');
2274
2275   lineno++;
2276
2277   if (c != '#')
2278     {
2279       /* If not #, return it so caller will use it.  */
2280       return c;
2281     }
2282
2283   /* Don't read beyond this line.  */
2284   linemode = 1;
2285   
2286   /* Read first nonwhite char after the `#'.  */
2287
2288   do
2289     c = getch ();
2290   while (c == ' ' || c == '\t');
2291
2292   /* If a letter follows, then if the word here is `line', skip
2293      it and ignore it; otherwise, ignore the line, with an error
2294      if the word isn't `pragma'.  */
2295
2296   if (ISALPHA (c))
2297     {
2298       if (c == 'p')
2299         {
2300           if (getch () == 'r'
2301               && getch () == 'a'
2302               && getch () == 'g'
2303               && getch () == 'm'
2304               && getch () == 'a')
2305             {
2306               token = real_yylex ();
2307               if (token == IDENTIFIER
2308                   && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
2309                 {
2310                   /* If this is 1, we handled it; if it's -1, it was one we
2311                      wanted but had something wrong with it.  Only if it's
2312                      0 was it not handled.  */
2313                   if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
2314                     goto skipline;
2315                 }
2316               else if (token == END_OF_LINE)
2317                 goto skipline;
2318
2319 #ifdef HANDLE_PRAGMA
2320               /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS
2321                  (if both are defined), in order to give the back
2322                  end a chance to override the interpretation of
2323                  SYSV style pragmas.  */
2324               if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
2325                                  IDENTIFIER_POINTER (yylval.ttype)))
2326                 goto skipline;
2327 #endif /* HANDLE_PRAGMA */
2328               
2329 #ifdef HANDLE_GENERIC_PRAGMAS
2330               if (handle_generic_pragma (token))
2331                 goto skipline;
2332 #endif /* HANDLE_GENERIC_PRAGMAS */
2333
2334               /* Issue a warning message if we have been asked to do so.
2335                  Ignoring unknown pragmas in system header file unless
2336                  an explcit -Wunknown-pragmas has been given. */
2337               if (warn_unknown_pragmas > 1
2338                   || (warn_unknown_pragmas && ! in_system_header))
2339                 warning ("ignoring pragma: %s", token_buffer);
2340             }
2341           
2342           goto skipline;
2343         }
2344       else if (c == 'd')
2345         {
2346           if (getch () == 'e'
2347               && getch () == 'f'
2348               && getch () == 'i'
2349               && getch () == 'n'
2350               && getch () == 'e'
2351               && ((c = getch ()) == ' ' || c == '\t'))
2352             {
2353               debug_define (lineno, GET_DIRECTIVE_LINE ());
2354               goto skipline;
2355             }
2356         }
2357       else if (c == 'u')
2358         {
2359           if (getch () == 'n'
2360               && getch () == 'd'
2361               && getch () == 'e'
2362               && getch () == 'f'
2363               && ((c = getch ()) == ' ' || c == '\t'))
2364             {
2365               debug_undef (lineno, GET_DIRECTIVE_LINE ());
2366               goto skipline;
2367             }
2368         }
2369       else if (c == 'l')
2370         {
2371           if (getch () == 'i'
2372               && getch () == 'n'
2373               && getch () == 'e'
2374               && ((c = getch ()) == ' ' || c == '\t'))
2375             {
2376               saw_line = 1;
2377               goto linenum;
2378             }
2379         }
2380       else if (c == 'i')
2381         {
2382           if (getch () == 'd'
2383               && getch () == 'e'
2384               && getch () == 'n'
2385               && getch () == 't'
2386               && ((c = getch ()) == ' ' || c == '\t'))
2387             {
2388               /* #ident.  The pedantic warning is now in cccp.c.  */
2389
2390               /* Here we have just seen `#ident '.
2391                  A string constant should follow.  */
2392
2393               token = real_yylex ();
2394               if (token == END_OF_LINE)
2395                 goto skipline;
2396               if (token != STRING
2397                   || TREE_CODE (yylval.ttype) != STRING_CST)
2398                 {
2399                   error ("invalid #ident");
2400                   goto skipline;
2401                 }
2402
2403               if (! flag_no_ident)
2404                 {
2405 #ifdef ASM_OUTPUT_IDENT
2406                   ASM_OUTPUT_IDENT (asm_out_file,
2407                                     TREE_STRING_POINTER (yylval.ttype));
2408 #endif
2409                 }
2410
2411               /* Skip the rest of this line.  */
2412               goto skipline;
2413             }
2414         }
2415       else if (c == 'n')
2416         {
2417           if (getch () == 'e'
2418               && getch () == 'w'
2419               && getch () == 'w'
2420               && getch () == 'o'
2421               && getch () == 'r'
2422               && getch () == 'l'
2423               && getch () == 'd'
2424               && ((c = getch ()) == ' ' || c == '\t'))
2425             {
2426               /* Used to test incremental compilation.  */
2427               sorry ("#pragma newworld");
2428               goto skipline;
2429             }
2430         }
2431       error ("undefined or invalid # directive");
2432       goto skipline;
2433     }
2434
2435 linenum:
2436   /* Here we have either `#line' or `# <nonletter>'.
2437      In either case, it should be a line number; a digit should follow.  */
2438
2439   while (c == ' ' || c == '\t')
2440     c = getch ();
2441
2442   /* If the # is the only nonwhite char on the line,
2443      just ignore it.  Check the new newline.  */
2444   if (c == EOF)
2445     goto skipline;
2446
2447   /* Something follows the #; read a token.  */
2448
2449   put_back (c);
2450   token = real_yylex ();
2451
2452   if (token == CONSTANT
2453       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2454     {
2455       int old_lineno = lineno;
2456       enum { act_none, act_push, act_pop } action = act_none;
2457       int entering_system_header = 0;
2458       int entering_c_header = 0;
2459
2460       /* subtract one, because it is the following line that
2461          gets the specified number */
2462
2463       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2464       c = get_last_nonwhite_on_line ();
2465       if (c == EOF)
2466         {
2467           /* No more: store the line number and check following line.  */
2468           lineno = l;
2469           goto skipline;
2470         }
2471       put_back (c);
2472
2473       /* More follows: it must be a string constant (filename).  */
2474
2475       if (saw_line)
2476         {
2477           /* Don't treat \ as special if we are processing #line 1 "...".
2478              If you want it to be treated specially, use # 1 "...".  */
2479           ignore_escape_flag = 1;
2480         }
2481
2482       /* Read the string constant.  */
2483       token = real_yylex ();
2484
2485       ignore_escape_flag = 0;
2486
2487       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2488         {
2489           error ("invalid #line");
2490           goto skipline;
2491         }
2492
2493       /* Changing files again.  This means currently collected time
2494          is charged against header time, and body time starts back
2495          at 0.  */
2496       if (flag_detailed_statistics)
2497         {
2498           int this_time = my_get_run_time ();
2499           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2500           header_time += this_time - body_time;
2501           TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
2502             += this_time - body_time;
2503           this_filename_time = time_identifier;
2504           body_time = this_time;
2505         }
2506
2507       input_filename
2508         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2509       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2510       lineno = l;
2511       GNU_xref_file (input_filename);
2512       
2513       if (main_input_filename == 0)
2514         {
2515           struct impl_files *ifiles = impl_file_chain;
2516
2517           if (ifiles)
2518             {
2519               while (ifiles->next)
2520                 ifiles = ifiles->next;
2521               ifiles->filename = file_name_nondirectory (input_filename);
2522             }
2523
2524           main_input_filename = input_filename;
2525           if (write_virtuals == 3)
2526             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2527         }
2528
2529       extract_interface_info ();
2530
2531       c = get_last_nonwhite_on_line ();
2532       if (c == EOF)
2533         {
2534           /* Update the name in the top element of input_file_stack.  */
2535           if (input_file_stack)
2536             input_file_stack->name = input_filename;
2537         }
2538       else
2539         {
2540           put_back (c);
2541
2542           token = real_yylex ();
2543
2544           /* `1' after file name means entering new file.
2545              `2' after file name means just left a file.  */
2546
2547           if (token == CONSTANT
2548               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2549             {
2550               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2551                 action = act_push;
2552               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2553                 action = act_pop;
2554
2555               if (action)
2556                 {
2557                   c = get_last_nonwhite_on_line ();
2558                   if (c != EOF)
2559                     {
2560                       put_back (c);
2561                       token = real_yylex ();
2562                     }
2563                 }
2564             }
2565
2566           /* `3' after file name means this is a system header file.  */
2567
2568           if (token == CONSTANT
2569               && TREE_CODE (yylval.ttype) == INTEGER_CST
2570               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2571             {
2572               entering_system_header = 1;
2573
2574               c = get_last_nonwhite_on_line ();
2575               if (c != EOF)
2576                 {
2577                   put_back (c);
2578                   token = real_yylex ();
2579                 }
2580             }
2581
2582           /* `4' after file name means this is a C header file.  */
2583
2584           if (token == CONSTANT
2585               && TREE_CODE (yylval.ttype) == INTEGER_CST
2586               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2587             {
2588               entering_c_header = 1;
2589
2590               c = get_last_nonwhite_on_line ();
2591               if (c != EOF)
2592                 {
2593                   put_back (c);
2594                   token = real_yylex ();
2595                 }
2596             }
2597
2598           /* Do the actions implied by the preceding numbers.  */
2599
2600           if (action == act_push)
2601             {
2602               /* Pushing to a new file.  */
2603               struct file_stack *p;
2604
2605               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2606               input_file_stack->line = old_lineno;
2607               p->next = input_file_stack;
2608               p->name = input_filename;
2609               input_file_stack = p;
2610               input_file_stack_tick++;
2611               debug_start_source_file (input_filename);
2612               in_system_header = entering_system_header;
2613               if (c_header_level)
2614                 ++c_header_level;
2615               else if (entering_c_header)
2616                 {
2617                   c_header_level = 1;
2618                   ++pending_lang_change;
2619                 }
2620             }
2621           else if (action == act_pop)
2622             {
2623               /* Popping out of a file.  */
2624               if (input_file_stack->next)
2625                 {
2626                   struct file_stack *p;
2627
2628                   if (c_header_level && --c_header_level == 0)
2629                     {
2630                       if (entering_c_header)
2631                         warning ("badly nested C headers from preprocessor");
2632                       --pending_lang_change;
2633                     }
2634                   in_system_header = entering_system_header;
2635
2636                   p = input_file_stack;
2637                   input_file_stack = p->next;
2638                   free (p);
2639                   input_file_stack_tick++;
2640                   debug_end_source_file (input_file_stack->line);
2641                 }
2642               else
2643                 error ("#-lines for entering and leaving files don't match");
2644             }
2645           else
2646             in_system_header = entering_system_header;
2647         }
2648
2649       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2650       if (nextchar == EOF)
2651         c = EOF;
2652     }
2653   else
2654     error ("invalid #-line");
2655
2656   /* skip the rest of this line.  */
2657  skipline:
2658   linemode = 0;
2659   end_of_file = 0;
2660   nextchar = -1;
2661   while ((c = getch ()) != EOF && c != '\n');
2662   return c;
2663 }
2664
2665 void
2666 do_pending_lang_change ()
2667 {
2668   for (; pending_lang_change > 0; --pending_lang_change)
2669     push_lang_context (lang_name_c);
2670   for (; pending_lang_change < 0; ++pending_lang_change)
2671     pop_lang_context ();
2672 }
2673 \f
2674 #define ENDFILE -1  /* token that represents end-of-file */
2675
2676 /* Read an escape sequence, returning its equivalent as a character,
2677    or store 1 in *ignore_ptr if it is backslash-newline.  */
2678
2679 static int
2680 readescape (ignore_ptr)
2681      int *ignore_ptr;
2682 {
2683   register int c = getch ();
2684   register int code;
2685   register unsigned count;
2686   unsigned firstdig = 0;
2687   int nonnull;
2688
2689   switch (c)
2690     {
2691     case 'x':
2692       code = 0;
2693       count = 0;
2694       nonnull = 0;
2695       while (1)
2696         {
2697           c = getch ();
2698           if (! ISXDIGIT (c))
2699             {
2700               put_back (c);
2701               break;
2702             }
2703           code *= 16;
2704           if (c >= 'a' && c <= 'f')
2705             code += c - 'a' + 10;
2706           if (c >= 'A' && c <= 'F')
2707             code += c - 'A' + 10;
2708           if (c >= '0' && c <= '9')
2709             code += c - '0';
2710           if (code != 0 || count != 0)
2711             {
2712               if (count == 0)
2713                 firstdig = code;
2714               count++;
2715             }
2716           nonnull = 1;
2717         }
2718       if (! nonnull)
2719         error ("\\x used with no following hex digits");
2720       else if (count == 0)
2721         /* Digits are all 0's.  Ok.  */
2722         ;
2723       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2724                || (count > 1
2725                    && (((unsigned)1 <<
2726                         (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2727                        <= firstdig)))
2728         pedwarn ("hex escape out of range");
2729       return code;
2730
2731     case '0':  case '1':  case '2':  case '3':  case '4':
2732     case '5':  case '6':  case '7':
2733       code = 0;
2734       count = 0;
2735       while ((c <= '7') && (c >= '0') && (count++ < 3))
2736         {
2737           code = (code * 8) + (c - '0');
2738           c = getch ();
2739         }
2740       put_back (c);
2741       return code;
2742
2743     case '\\': case '\'': case '"':
2744       return c;
2745
2746     case '\n':
2747       lineno++;
2748       *ignore_ptr = 1;
2749       return 0;
2750
2751     case 'n':
2752       return TARGET_NEWLINE;
2753
2754     case 't':
2755       return TARGET_TAB;
2756
2757     case 'r':
2758       return TARGET_CR;
2759
2760     case 'f':
2761       return TARGET_FF;
2762
2763     case 'b':
2764       return TARGET_BS;
2765
2766     case 'a':
2767       return TARGET_BELL;
2768
2769     case 'v':
2770       return TARGET_VT;
2771
2772     case 'e':
2773     case 'E':
2774       if (pedantic)
2775         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
2776       return 033;
2777
2778     case '?':
2779       return c;
2780
2781       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
2782     case '(':
2783     case '{':
2784     case '[':
2785       /* `\%' is used to prevent SCCS from getting confused.  */
2786     case '%':
2787       if (pedantic)
2788         pedwarn ("unknown escape sequence `\\%c'", c);
2789       return c;
2790     }
2791   if (ISGRAPH (c))
2792     pedwarn ("unknown escape sequence `\\%c'", c);
2793   else
2794     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2795   return c;
2796 }
2797
2798 /* Value is 1 (or 2) if we should try to make the next identifier look like
2799    a typename (when it may be a local variable or a class variable).
2800    Value is 0 if we treat this name in a default fashion.  */
2801 int looking_for_typename;
2802
2803 #ifdef __GNUC__
2804 __inline
2805 #endif
2806 int
2807 identifier_type (decl)
2808      tree decl;
2809 {
2810   tree t;
2811   if (TREE_CODE (decl) == TEMPLATE_DECL)
2812     {
2813       if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
2814         return PTYPENAME;
2815       else if (looking_for_template) 
2816         return PFUNCNAME;
2817     }
2818   if (looking_for_template && really_overloaded_fn (decl))
2819     {
2820       /* See through a baselink.  */
2821       if (TREE_CODE (decl) == TREE_LIST)
2822         decl = TREE_VALUE (decl);
2823
2824       for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
2825         if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) 
2826           return PFUNCNAME;
2827     }
2828   if (TREE_CODE (decl) == NAMESPACE_DECL)
2829     return NSNAME;
2830   if (TREE_CODE (decl) != TYPE_DECL)
2831     return IDENTIFIER;
2832   if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
2833     return SELFNAME;
2834
2835   /* A constructor declarator for a template type will get here as an
2836      implicit typename, a TYPENAME_TYPE with a type.  */
2837   t = got_scope;
2838   if (t && TREE_CODE (t) == TYPENAME_TYPE)
2839     t = TREE_TYPE (t);
2840   decl = TREE_TYPE (decl);
2841   if (TREE_CODE (decl) == TYPENAME_TYPE)
2842     decl = TREE_TYPE (decl);
2843   if (t && t == decl)
2844     return SELFNAME;
2845
2846   return TYPENAME;
2847 }
2848
2849 void
2850 see_typename ()
2851 {
2852   /* Only types expected, not even namespaces. */
2853   looking_for_typename = 2;
2854   if (yychar < 0)
2855     if ((yychar = yylex ()) < 0) yychar = 0;
2856   looking_for_typename = 0;
2857   if (yychar == IDENTIFIER)
2858     {
2859       lastiddecl = lookup_name (yylval.ttype, -2);
2860       if (lastiddecl == 0)
2861         {
2862           if (flag_labels_ok)
2863             lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2864         }
2865       else
2866         yychar = identifier_type (lastiddecl);
2867     }
2868 }
2869
2870 /* Return true if d is in a global scope. */
2871
2872 static int
2873 is_global (d)
2874   tree d;
2875 {
2876   while (1)
2877     switch (TREE_CODE (d))
2878       {
2879       case ERROR_MARK:
2880         return 1;
2881
2882       case OVERLOAD: d = OVL_FUNCTION (d); continue;
2883       case TREE_LIST: d = TREE_VALUE (d); continue;
2884       default:
2885         my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629);
2886         d = CP_DECL_CONTEXT (d);
2887         return TREE_CODE (d) == NAMESPACE_DECL;
2888       }
2889 }
2890
2891 tree
2892 do_identifier (token, parsing, args)
2893      register tree token;
2894      int parsing;
2895      tree args;
2896 {
2897   register tree id;
2898   int lexing = (parsing == 1);
2899   int in_call = (parsing == 2);
2900
2901   if (! lexing || IDENTIFIER_OPNAME_P (token))
2902     id = lookup_name (token, 0);
2903   else
2904     id = lastiddecl;
2905
2906   /* Scope class declarations before global
2907      declarations.  */
2908   if ((!id || is_global (id))
2909       && current_class_type != 0
2910       && TYPE_SIZE (current_class_type) == 0)
2911     {
2912       /* Could be from one of the base classes.  */
2913       tree field = lookup_field (current_class_type, token, 1, 0);
2914       if (field == 0)
2915         ;
2916       else if (field == error_mark_node)
2917         /* We have already generated the error message.
2918            But we still want to return this value.  */
2919         id = lookup_field (current_class_type, token, 0, 0);
2920       else if (TREE_CODE (field) == VAR_DECL
2921                || TREE_CODE (field) == CONST_DECL
2922                || TREE_CODE (field) == TEMPLATE_DECL)
2923         id = field;
2924       else if (TREE_CODE (field) != FIELD_DECL)
2925         my_friendly_abort (61);
2926       else
2927         {
2928           cp_error ("invalid use of member `%D'", field);
2929           id = error_mark_node;
2930           return id;
2931         }
2932     }
2933
2934   /* Do Koenig lookup if appropriate (inside templates we build lookup
2935      expressions instead).  */
2936   if (args && !current_template_parms && (!id || is_global (id)))
2937     /* If we have arguments and we only found global names, do Koenig
2938          lookup. */
2939     id = lookup_arg_dependent (token, id, args);
2940
2941   /* Remember that this name has been used in the class definition, as per
2942      [class.scope0] */
2943   if (id && current_class_type && parsing
2944       && TYPE_BEING_DEFINED (current_class_type)
2945       && ! IDENTIFIER_CLASS_VALUE (token)
2946       /* Avoid breaking if we get called for a default argument that
2947          refers to an overloaded method.  Eventually this will not be
2948          necessary, since default arguments shouldn't be parsed until
2949          after the class is complete.  (jason 3/12/97) */
2950       && TREE_CODE (id) != OVERLOAD)
2951     pushdecl_class_level (id);
2952     
2953   if (!id || id == error_mark_node)
2954     {
2955       if (id == error_mark_node && current_class_type != NULL_TREE)
2956         {
2957           id = lookup_nested_field (token, 1);
2958           /* In lookup_nested_field(), we marked this so we can gracefully
2959              leave this whole mess.  */
2960           if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
2961             return id;
2962         }
2963
2964       if (current_template_parms)
2965         return build_min_nt (LOOKUP_EXPR, token);
2966       else if (IDENTIFIER_OPNAME_P (token))
2967         {
2968           if (token != ansi_opname[ERROR_MARK])
2969             cp_error ("`%D' not defined", token);
2970           id = error_mark_node;
2971         }
2972       else if (in_call && ! flag_strict_prototype)
2973         {
2974           id = implicitly_declare (token);
2975         }
2976       else if (current_function_decl == 0)
2977         {
2978           cp_error ("`%D' was not declared in this scope", token);
2979           id = error_mark_node;
2980         }
2981       else
2982         {
2983           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
2984               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2985             {
2986               static int undeclared_variable_notice;
2987
2988               cp_error ("`%D' undeclared (first use this function)", token);
2989
2990               if (! undeclared_variable_notice)
2991                 {
2992                   error ("(Each undeclared identifier is reported only once");
2993                   error ("for each function it appears in.)");
2994                   undeclared_variable_notice = 1;
2995                 }
2996             }
2997           id = error_mark_node;
2998           /* Prevent repeated error messages.  */
2999           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3000           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
3001         }
3002     }
3003
3004   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
3005     {
3006       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
3007       while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
3008              && DECL_DEAD_FOR_LOCAL (shadowed))
3009         shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
3010       if (!shadowed)
3011         shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
3012       if (shadowed)
3013         {
3014           if (!DECL_ERROR_REPORTED (id))
3015             {
3016               warning ("name lookup of `%s' changed",
3017                        IDENTIFIER_POINTER (token));
3018               cp_warning_at ("  matches this `%D' under current ANSI rules",
3019                              shadowed);
3020               cp_warning_at ("  matches this `%D' under old rules", id);
3021               DECL_ERROR_REPORTED (id) = 1;
3022             }
3023           id = shadowed;
3024         }
3025       else if (!DECL_ERROR_REPORTED (id))
3026         {
3027           static char msg[]
3028             = "name lookup of `%s' changed for new ANSI `for' scoping";
3029           DECL_ERROR_REPORTED (id) = 1;
3030           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
3031             {
3032               error (msg, IDENTIFIER_POINTER (token));
3033               cp_error_at ("  cannot use obsolete binding at `%D' because it has a destructor", id);
3034               id = error_mark_node;
3035             }
3036           else
3037             {
3038               pedwarn (msg, IDENTIFIER_POINTER (token));
3039               cp_pedwarn_at ("  using obsolete binding at `%D'", id);
3040             }
3041         }
3042     }
3043   /* TREE_USED is set in `hack_identifier'.  */
3044   if (TREE_CODE (id) == CONST_DECL)
3045     {
3046       /* Check access.  */
3047       if (IDENTIFIER_CLASS_VALUE (token) == id)
3048         enforce_access (DECL_REAL_CONTEXT(id), id);
3049       if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
3050         id = DECL_INITIAL (id);
3051     }
3052   else
3053     id = hack_identifier (id, token);
3054
3055   /* We must look up dependent names when the template is
3056      instantiated, not while parsing it.  For now, we don't
3057      distinguish between dependent and independent names.  So, for
3058      example, we look up all overloaded functions at
3059      instantiation-time, even though in some cases we should just use
3060      the DECL we have here.  We also use LOOKUP_EXPRs to find things
3061      like local variables, rather than creating TEMPLATE_DECLs for the
3062      local variables and then finding matching instantiations.  */
3063   if (current_template_parms
3064       && (is_overloaded_fn (id) 
3065           /* If it's not going to be around at instantiation time, we
3066              look it up then.  This is a hack, and should go when we
3067              really get dependent/independent name lookup right.  */
3068           || !TREE_PERMANENT (id)
3069           /* Some local VAR_DECLs (such as those for local variables
3070              in member functions of local classes) are built on the
3071              permanent obstack.  */
3072           || (TREE_CODE (id) == VAR_DECL 
3073               && CP_DECL_CONTEXT (id)
3074               && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
3075           || TREE_CODE (id) == PARM_DECL
3076           || TREE_CODE (id) == RESULT_DECL
3077           || TREE_CODE (id) == USING_DECL))
3078     id = build_min_nt (LOOKUP_EXPR, token);
3079       
3080   return id;
3081 }
3082
3083 tree
3084 do_scoped_id (token, parsing)
3085      tree token;
3086      int parsing;
3087 {
3088   tree id;
3089   /* during parsing, this is ::name. Otherwise, it is black magic. */
3090   if (parsing)
3091     {
3092       struct tree_binding _b;
3093       id = binding_init (&_b);
3094       if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
3095         id = NULL_TREE;
3096       else
3097         id = BINDING_VALUE (id);
3098     } 
3099   else
3100     id = IDENTIFIER_GLOBAL_VALUE (token);
3101   if (parsing && yychar == YYEMPTY)
3102     yychar = yylex ();
3103   if (! id)
3104     {
3105       if (processing_template_decl)
3106         {
3107           id = build_min_nt (LOOKUP_EXPR, token);
3108           LOOKUP_EXPR_GLOBAL (id) = 1;
3109           return id;
3110         }
3111       if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
3112           && ! flag_strict_prototype)
3113         id = implicitly_declare (token);
3114       else
3115         {
3116           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
3117             cp_error ("`::%D' undeclared (first use here)", token);
3118           id = error_mark_node;
3119           /* Prevent repeated error messages.  */
3120           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3121         }
3122     }
3123   else
3124     {
3125       if (TREE_CODE (id) == ADDR_EXPR)
3126         mark_used (TREE_OPERAND (id, 0));
3127       else if (TREE_CODE (id) != OVERLOAD)
3128         mark_used (id);
3129     }
3130   if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
3131     {
3132       /* XXX CHS - should we set TREE_USED of the constant? */
3133       id = DECL_INITIAL (id);
3134       /* This is to prevent an enum whose value is 0
3135          from being considered a null pointer constant.  */
3136       id = build1 (NOP_EXPR, TREE_TYPE (id), id);
3137       TREE_CONSTANT (id) = 1;
3138     }
3139
3140   if (processing_template_decl)
3141     {
3142       if (is_overloaded_fn (id))
3143         {
3144           id = build_min_nt (LOOKUP_EXPR, token);
3145           LOOKUP_EXPR_GLOBAL (id) = 1;
3146           return id;
3147         }
3148       /* else just use the decl */
3149     }
3150   return convert_from_reference (id);
3151 }
3152
3153 tree
3154 identifier_typedecl_value (node)
3155      tree node;
3156 {
3157   tree t, type;
3158   type = IDENTIFIER_TYPE_VALUE (node);
3159   if (type == NULL_TREE)
3160     return NULL_TREE;
3161
3162   if (IDENTIFIER_BINDING (node))
3163     {
3164       t = IDENTIFIER_VALUE (node);
3165       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3166         return t;
3167     }
3168   if (IDENTIFIER_NAMESPACE_VALUE (node))
3169     {
3170       t = IDENTIFIER_NAMESPACE_VALUE (node);
3171       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3172         return t;
3173     }
3174
3175   /* Will this one ever happen?  */
3176   if (TYPE_MAIN_DECL (type))
3177     return TYPE_MAIN_DECL (type);
3178
3179   /* We used to do an internal error of 62 here, but instead we will
3180      handle the return of a null appropriately in the callers.  */
3181   return NULL_TREE;
3182 }
3183
3184 int
3185 real_yylex ()
3186 {
3187   register int c;
3188   register int value;
3189   int wide_flag = 0;
3190   int dollar_seen = 0;
3191   int i;
3192
3193   if (nextchar >= 0)
3194     c = nextchar, nextchar = -1;
3195   else
3196     c = getch ();
3197
3198   /* Effectively do c = skip_white_space (c)
3199      but do it faster in the usual cases.  */
3200   while (1)
3201     switch (c)
3202       {
3203       case ' ':
3204       case '\t':
3205       case '\f':
3206       case '\v':
3207       case '\b':
3208         c = getch ();
3209         break;
3210
3211       case '\r':
3212         /* Call skip_white_space so we can warn if appropriate.  */
3213
3214       case '\n':
3215       case '/':
3216       case '\\':
3217         c = skip_white_space (c);
3218       default:
3219         goto found_nonwhite;
3220       }
3221  found_nonwhite:
3222
3223   token_buffer[0] = c;
3224   token_buffer[1] = 0;
3225
3226 /*  yylloc.first_line = lineno; */
3227
3228   switch (c)
3229     {
3230     case EOF:
3231       token_buffer[0] = '\0';
3232       end_of_file = 1;
3233       if (input_redirected ())
3234         value = END_OF_SAVED_INPUT;
3235       else if (linemode)
3236         value = END_OF_LINE;
3237       else
3238         value = ENDFILE;
3239       break;
3240
3241     case '$':
3242       if (! dollars_in_ident)
3243         error ("`$' in identifier");
3244       else if (pedantic)
3245         pedwarn ("`$' in identifier");
3246       dollar_seen = 1;
3247       goto letter;
3248
3249     case 'L':
3250       /* Capital L may start a wide-string or wide-character constant.  */
3251       {
3252         register int c = getch ();
3253         if (c == '\'')
3254           {
3255             wide_flag = 1;
3256             goto char_constant;
3257           }
3258         if (c == '"')
3259           {
3260             wide_flag = 1;
3261             goto string_constant;
3262           }
3263         put_back (c);
3264       }
3265
3266     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
3267     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
3268     case 'K':             case 'M':  case 'N':  case 'O':
3269     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
3270     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
3271     case 'Z':
3272     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
3273     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
3274     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
3275     case 'p':  case 'q':  case 'r':  case 's':  case 't':
3276     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
3277     case 'z':
3278     case '_':
3279     letter:
3280       {
3281         register char *p;
3282
3283         p = token_buffer;
3284         if (input == 0)
3285           {
3286             /* We know that `token_buffer' can hold at least on char,
3287                so we install C immediately.
3288                We may have to read the value in `putback_char', so call
3289                `getch' once.  */
3290             *p++ = c;
3291             c = getch ();
3292
3293             /* Make this run fast.  We know that we are reading straight
3294                from FINPUT in this case (since identifiers cannot straddle
3295                input sources.  */
3296             while (ISALNUM (c) || (c == '_') || c == '$')
3297               {
3298                 if (c == '$')
3299                   {
3300                     if (! dollars_in_ident)
3301                       error ("`$' in identifier");
3302                     else if (pedantic)
3303                       pedwarn ("`$' in identifier");
3304                   }
3305
3306                 if (p >= token_buffer + maxtoken)
3307                   p = extend_token_buffer (p);
3308
3309                 *p++ = c;
3310                 c = getch ();
3311               }
3312
3313             if (linemode && c == '\n')
3314               {
3315                 put_back (c);
3316                 c = EOF;
3317               }
3318           }
3319         else
3320           {
3321             /* We know that `token_buffer' can hold at least on char,
3322                so we install C immediately.  */
3323             *p++ = c;
3324             c = getch ();
3325
3326             while (ISALNUM (c) || (c == '_') || c == '$')
3327               {
3328                 if (c == '$')
3329                   {
3330                     if (! dollars_in_ident)
3331                       error ("`$' in identifier");
3332                     else if (pedantic)
3333                       pedwarn ("`$' in identifier");
3334                   }
3335
3336                 if (p >= token_buffer + maxtoken)
3337                   p = extend_token_buffer (p);
3338
3339                 *p++ = c;
3340                 c = getch ();
3341               }
3342           }
3343
3344         *p = 0;
3345         nextchar = c;
3346
3347         value = IDENTIFIER;
3348         yylval.itype = 0;
3349
3350       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
3351
3352         {
3353           register struct resword *ptr;
3354
3355           if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
3356             {
3357               if (ptr->rid)
3358                 {
3359                   tree old_ttype = ridpointers[(int) ptr->rid];
3360
3361                   /* If this provides a type for us, then revert lexical
3362                      state to standard state.  */
3363                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
3364                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
3365                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
3366                     looking_for_typename = 0;
3367                   else if (ptr->token == AGGR || ptr->token == ENUM)
3368                     looking_for_typename = 2;
3369
3370                   /* Check if this is a language-type declaration.
3371                      Just glimpse the next non-white character.  */
3372                   nextchar = skip_white_space (nextchar);
3373                   if (nextchar == '"')
3374                     {
3375                       /* We are looking at a string.  Complain
3376                          if the token before the string is no `extern'.
3377                          
3378                          Could cheat some memory by placing this string
3379                          on the temporary_, instead of the saveable_
3380                          obstack.  */
3381
3382                       if (ptr->rid != RID_EXTERN)
3383                         error ("invalid modifier `%s' for language string",
3384                                ptr->name);
3385                       real_yylex ();
3386                       value = EXTERN_LANG_STRING;
3387                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
3388                       break;
3389                     }
3390                   if (ptr->token == VISSPEC)
3391                     {
3392                       switch (ptr->rid)
3393                         {
3394                         case RID_PUBLIC:
3395                           yylval.ttype = access_public_node;
3396                           break;
3397                         case RID_PRIVATE:
3398                           yylval.ttype = access_private_node;
3399                           break;
3400                         case RID_PROTECTED:
3401                           yylval.ttype = access_protected_node;
3402                           break;
3403                         default:
3404                           my_friendly_abort (63);
3405                         }
3406                     }
3407                   else
3408                     yylval.ttype = old_ttype;
3409                 }
3410               else if (ptr->token == EQCOMPARE)
3411                 {
3412                   yylval.code = NE_EXPR;
3413                   token_buffer[0] = '!';
3414                   token_buffer[1] = '=';
3415                   token_buffer[2] = 0;
3416                 }
3417               else if (ptr->token == ASSIGN)
3418                 {
3419                   if (strcmp ("and_eq", token_buffer) == 0)
3420                     {
3421                       yylval.code = BIT_AND_EXPR;
3422                       token_buffer[0] = '&';
3423                     }
3424                   else if (strcmp ("or_eq", token_buffer) == 0)
3425                     {
3426                       yylval.code = BIT_IOR_EXPR;
3427                       token_buffer[0] = '|';
3428                     }
3429                   else if (strcmp ("xor_eq", token_buffer) == 0)
3430                     {
3431                       yylval.code = BIT_XOR_EXPR;
3432                       token_buffer[0] = '^';
3433                     }
3434                   token_buffer[1] = '=';
3435                   token_buffer[2] = 0;
3436                 }
3437               else if (ptr->token == '&')
3438                 {
3439                   yylval.code = BIT_AND_EXPR;
3440                   token_buffer[0] = '&';
3441                   token_buffer[1] = 0;
3442                 }
3443               else if (ptr->token == '|')
3444                 {
3445                   yylval.code = BIT_IOR_EXPR;
3446                   token_buffer[0] = '|';
3447                   token_buffer[1] = 0;
3448                 }
3449               else if (ptr->token == '^')
3450                 {
3451                   yylval.code = BIT_XOR_EXPR;
3452                   token_buffer[0] = '^';
3453                   token_buffer[1] = 0;
3454                 }
3455
3456               value = (int) ptr->token;
3457             }
3458         }
3459
3460         /* If we did not find a keyword, look for an identifier
3461            (or a typename).  */
3462
3463         if (value == IDENTIFIER || value == TYPESPEC)
3464           GNU_xref_ref (current_function_decl, token_buffer);
3465
3466         if (value == IDENTIFIER)
3467           {
3468             register tree tmp = get_identifier (token_buffer);
3469
3470 #if !defined(VMS) && defined(JOINER)
3471             /* Make sure that user does not collide with our internal
3472                naming scheme.  */
3473             if (JOINER == '$'
3474                 && dollar_seen
3475                 && (THIS_NAME_P (tmp)
3476                     || VPTR_NAME_P (tmp)
3477                     || DESTRUCTOR_NAME_P (tmp)
3478                     || VTABLE_NAME_P (tmp)
3479                     || TEMP_NAME_P (tmp)
3480                     || ANON_AGGRNAME_P (tmp)
3481                     || ANON_PARMNAME_P (tmp)))
3482               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3483                        token_buffer);
3484 #endif
3485
3486             yylval.ttype = tmp;
3487           }
3488         if (value == NEW && ! global_bindings_p ())
3489           {
3490             value = NEW;
3491             goto done;
3492           }
3493       }
3494       break;
3495
3496     case '.':
3497       {
3498         register int c1 = getch ();
3499         token_buffer[0] = c;
3500         token_buffer[1] = c1;
3501         if (c1 == '*')
3502           {
3503             value = DOT_STAR;
3504             token_buffer[2] = 0;
3505             goto done;
3506           }
3507         if (c1 == '.')
3508           {
3509             c1 = getch ();
3510             if (c1 == '.')
3511               {
3512                 token_buffer[2] = c1;
3513                 token_buffer[3] = 0;
3514                 value = ELLIPSIS;
3515                 goto done;
3516               }
3517             error ("parse error at `..'");
3518           }
3519         if (ISDIGIT (c1))
3520           {
3521             put_back (c1);
3522             goto resume_numerical_scan;
3523           }
3524         nextchar = c1;
3525         value = '.';
3526         token_buffer[1] = 0;
3527         goto done;
3528       }
3529     case '0':  case '1':
3530         /* Optimize for most frequent case.  */
3531       {
3532         register int c1 = getch ();
3533         if (! ISALNUM (c1) && c1 != '.')
3534           {
3535             /* Terminate string.  */
3536             token_buffer[0] = c;
3537             token_buffer[1] = 0;
3538             if (c == '0')
3539               yylval.ttype = integer_zero_node;
3540             else
3541               yylval.ttype = integer_one_node;
3542             nextchar = c1;
3543             value = CONSTANT;
3544             goto done;
3545           }
3546         put_back (c1);
3547       }
3548       /* fall through...  */
3549                           case '2':  case '3':  case '4':
3550     case '5':  case '6':  case '7':  case '8':  case '9':
3551     resume_numerical_scan:
3552       {
3553         register char *p;
3554         int base = 10;
3555         int count = 0;
3556         int largest_digit = 0;
3557         int numdigits = 0;
3558         /* for multi-precision arithmetic,
3559            we actually store only HOST_BITS_PER_CHAR bits in each part.
3560            The number of parts is chosen so as to be sufficient to hold
3561            the enough bits to fit into the two HOST_WIDE_INTs that contain
3562            the integer value (this is always at least as many bits as are
3563            in a target `long long' value, but may be wider).  */
3564 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3565         int parts[TOTAL_PARTS];
3566         int overflow = 0;
3567
3568         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3569           = NOT_FLOAT;
3570
3571         for (count = 0; count < TOTAL_PARTS; count++)
3572           parts[count] = 0;
3573
3574         p = token_buffer;
3575         *p++ = c;
3576
3577         if (c == '0')
3578           {
3579             *p++ = (c = getch ());
3580             if ((c == 'x') || (c == 'X'))
3581               {
3582                 base = 16;
3583                 *p++ = (c = getch ());
3584               }
3585             /* Leading 0 forces octal unless the 0 is the only digit.  */
3586             else if (c >= '0' && c <= '9')
3587               {
3588                 base = 8;
3589                 numdigits++;
3590               }
3591             else
3592               numdigits++;
3593           }
3594
3595         /* Read all the digits-and-decimal-points.  */
3596
3597         while (c == '.'
3598                || (ISALNUM (c) && (c != 'l') && (c != 'L')
3599                    && (c != 'u') && (c != 'U')
3600                    && c != 'i' && c != 'I' && c != 'j' && c != 'J'
3601                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3602           {
3603             if (c == '.')
3604               {
3605                 if (base == 16)
3606                   error ("floating constant may not be in radix 16");
3607                 if (floatflag == TOO_MANY_POINTS)
3608                   /* We have already emitted an error.  Don't need another.  */
3609                   ;
3610                 else if (floatflag == AFTER_POINT)
3611                   {
3612                     error ("malformed floating constant");
3613                     floatflag = TOO_MANY_POINTS;
3614                     /* Avoid another error from atof by forcing all characters
3615                        from here on to be ignored.  */
3616                     p[-1] = '\0';
3617                   }
3618                 else
3619                   floatflag = AFTER_POINT;
3620
3621                 base = 10;
3622                 *p++ = c = getch ();
3623                 /* Accept '.' as the start of a floating-point number
3624                    only when it is followed by a digit.
3625                    Otherwise, unread the following non-digit
3626                    and use the '.' as a structural token.  */
3627                 if (p == token_buffer + 2 && !ISDIGIT (c))
3628                   {
3629                     if (c == '.')
3630                       {
3631                         c = getch ();
3632                         if (c == '.')
3633                           {
3634                             *p++ = '.';
3635                             *p = '\0';
3636                             value = ELLIPSIS;
3637                             goto done;
3638                           }
3639                         error ("parse error at `..'");
3640                       }
3641                     nextchar = c;
3642                     token_buffer[1] = '\0';
3643                     value = '.';
3644                     goto done;
3645                   }
3646               }
3647             else
3648               {
3649                 /* It is not a decimal point.
3650                    It should be a digit (perhaps a hex digit).  */
3651
3652                 if (ISDIGIT (c))
3653                   {
3654                     c = c - '0';
3655                   }
3656                 else if (base <= 10)
3657                   {
3658                     if (c == 'e' || c == 'E')
3659                       {
3660                         base = 10;
3661                         floatflag = AFTER_POINT;
3662                         break;   /* start of exponent */
3663                       }
3664                     error ("nondigits in number and not hexadecimal");
3665                     c = 0;
3666                   }
3667                 else if (c >= 'a')
3668                   {
3669                     c = c - 'a' + 10;
3670                   }
3671                 else
3672                   {
3673                     c = c - 'A' + 10;
3674                   }
3675                 if (c >= largest_digit)
3676                   largest_digit = c;
3677                 numdigits++;
3678
3679                 for (count = 0; count < TOTAL_PARTS; count++)
3680                   {
3681                     parts[count] *= base;
3682                     if (count)
3683                       {
3684                         parts[count]
3685                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3686                         parts[count-1]
3687                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3688                       }
3689                     else
3690                       parts[0] += c;
3691                   }
3692
3693                 /* If the extra highest-order part ever gets anything in it,
3694                    the number is certainly too big.  */
3695                 if (parts[TOTAL_PARTS - 1] != 0)
3696                   overflow = 1;
3697
3698                 if (p >= token_buffer + maxtoken - 3)
3699                   p = extend_token_buffer (p);
3700                 *p++ = (c = getch ());
3701               }
3702           }
3703
3704         if (numdigits == 0)
3705           error ("numeric constant with no digits");
3706
3707         if (largest_digit >= base)
3708           error ("numeric constant contains digits beyond the radix");
3709
3710         /* Remove terminating char from the token buffer and delimit the string */
3711         *--p = 0;
3712
3713         if (floatflag != NOT_FLOAT)
3714           {
3715             tree type = double_type_node;
3716             int exceeds_double = 0;
3717             int imag = 0;
3718             REAL_VALUE_TYPE value;
3719             jmp_buf handler;
3720
3721             /* Read explicit exponent if any, and put it in tokenbuf.  */
3722
3723             if ((c == 'e') || (c == 'E'))
3724               {
3725                 if (p >= token_buffer + maxtoken - 3)
3726                   p = extend_token_buffer (p);
3727                 *p++ = c;
3728                 c = getch ();
3729                 if ((c == '+') || (c == '-'))
3730                   {
3731                     *p++ = c;
3732                     c = getch ();
3733                   }
3734                 if (! ISDIGIT (c))
3735                   error ("floating constant exponent has no digits");
3736                 while (ISDIGIT (c))
3737                   {
3738                     if (p >= token_buffer + maxtoken - 3)
3739                       p = extend_token_buffer (p);
3740                     *p++ = c;
3741                     c = getch ();
3742                   }
3743               }
3744
3745             *p = 0;
3746             errno = 0;
3747
3748             /* Convert string to a double, checking for overflow.  */
3749             if (setjmp (handler))
3750               {
3751                 error ("floating constant out of range");
3752                 value = dconst0;
3753               }
3754             else
3755               {
3756                 int fflag = 0, lflag = 0;
3757                 /* Copy token_buffer now, while it has just the number
3758                    and not the suffixes; once we add `f' or `i',
3759                    REAL_VALUE_ATOF may not work any more.  */
3760                 char *copy = (char *) alloca (p - token_buffer + 1);
3761                 bcopy (token_buffer, copy, p - token_buffer + 1);
3762
3763                 set_float_handler (handler);
3764
3765                 while (1)
3766                   {
3767                     int lose = 0;
3768
3769                     /* Read the suffixes to choose a data type.  */
3770                     switch (c)
3771                       {
3772                       case 'f': case 'F':
3773                         if (fflag)
3774                           error ("more than one `f' in numeric constant");
3775                         fflag = 1;
3776                         break;
3777
3778                       case 'l': case 'L':
3779                         if (lflag)
3780                           error ("more than one `l' in numeric constant");
3781                         lflag = 1;
3782                         break;
3783
3784                       case 'i': case 'I':
3785                         if (imag)
3786                           error ("more than one `i' or `j' in numeric constant");
3787                         else if (pedantic)
3788                           pedwarn ("ANSI C++ forbids imaginary numeric constants");
3789                         imag = 1;
3790                         break;
3791
3792                       default:
3793                         lose = 1;
3794                       }
3795
3796                     if (lose)
3797                       break;
3798
3799                     if (p >= token_buffer + maxtoken - 3)
3800                       p = extend_token_buffer (p);
3801                     *p++ = c;
3802                     *p = 0;
3803                     c = getch ();
3804                   }
3805
3806                 /* The second argument, machine_mode, of REAL_VALUE_ATOF
3807                    tells the desired precision of the binary result
3808                    of decimal-to-binary conversion.  */
3809
3810                 if (fflag)
3811                   {
3812                     if (lflag)
3813                       error ("both `f' and `l' in floating constant");
3814
3815                     type = float_type_node;
3816                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3817                     /* A diagnostic is required here by some ANSI C testsuites.
3818                        This is not pedwarn, become some people don't want
3819                        an error for this.  */
3820                     if (REAL_VALUE_ISINF (value) && pedantic)
3821                       warning ("floating point number exceeds range of `float'");
3822                   }
3823                 else if (lflag)
3824                   {
3825                     type = long_double_type_node;
3826                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3827                     if (REAL_VALUE_ISINF (value) && pedantic)
3828                       warning ("floating point number exceeds range of `long double'");
3829                   }
3830                 else
3831                   {
3832                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3833                     if (REAL_VALUE_ISINF (value) && pedantic)
3834                       warning ("floating point number exceeds range of `double'");
3835                   }
3836
3837                 set_float_handler (NULL_PTR);
3838               }
3839 #ifdef ERANGE
3840             if (errno == ERANGE && pedantic)
3841               {
3842                 /* ERANGE is also reported for underflow,
3843                    so test the value to distinguish overflow from that.  */
3844                 if (REAL_VALUES_LESS (dconst1, value)
3845                     || REAL_VALUES_LESS (value, dconstm1))
3846                   {
3847                     pedwarn ("floating point number exceeds range of `%s'",
3848                              IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
3849                     exceeds_double = 1;
3850                   }
3851               }
3852 #endif
3853
3854             /* If the result is not a number, assume it must have been
3855                due to some error message above, so silently convert
3856                it to a zero.  */
3857             if (REAL_VALUE_ISNAN (value))
3858               value = dconst0;
3859
3860             /* Create a node with determined type and value.  */
3861             if (imag)
3862               yylval.ttype = build_complex (NULL_TREE,
3863                                             cp_convert (type, integer_zero_node),
3864                                             build_real (type, value));
3865             else
3866               yylval.ttype = build_real (type, value);
3867           }
3868         else
3869           {
3870             tree type;
3871             HOST_WIDE_INT high, low;
3872             int spec_unsigned = 0;
3873             int spec_long = 0;
3874             int spec_long_long = 0;
3875             int spec_imag = 0;
3876             int bytes, warn;
3877
3878             while (1)
3879               {
3880                 if (c == 'u' || c == 'U')
3881                   {
3882                     if (spec_unsigned)
3883                       error ("two `u's in integer constant");
3884                     spec_unsigned = 1;
3885                   }
3886                 else if (c == 'l' || c == 'L')
3887                   {
3888                     if (spec_long)
3889                       {
3890                         if (spec_long_long)
3891                           error ("three `l's in integer constant");
3892                         else if (pedantic && ! in_system_header && warn_long_long)
3893                           pedwarn ("ANSI C++ forbids long long integer constants");
3894                         spec_long_long = 1;
3895                       }
3896                     spec_long = 1;
3897                   }
3898                 else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
3899                   {
3900                     if (spec_imag)
3901                       error ("more than one `i' or `j' in numeric constant");
3902                     else if (pedantic)
3903                       pedwarn ("ANSI C++ forbids imaginary numeric constants");
3904                     spec_imag = 1;
3905                   }
3906                 else
3907                   break;
3908                 if (p >= token_buffer + maxtoken - 3)
3909                   p = extend_token_buffer (p);
3910                 *p++ = c;
3911                 c = getch ();
3912               }
3913
3914             /* If the constant is not long long and it won't fit in an
3915                unsigned long, or if the constant is long long and won't fit
3916                in an unsigned long long, then warn that the constant is out
3917                of range.  */
3918
3919             /* ??? This assumes that long long and long integer types are
3920                a multiple of 8 bits.  This better than the original code
3921                though which assumed that long was exactly 32 bits and long
3922                long was exactly 64 bits.  */
3923
3924             if (spec_long_long)
3925               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3926             else
3927               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3928
3929             warn = overflow;
3930             for (i = bytes; i < TOTAL_PARTS; i++)
3931               if (parts[i])
3932                 warn = 1;
3933             if (warn)
3934               pedwarn ("integer constant out of range");
3935
3936             /* This is simplified by the fact that our constant
3937                is always positive.  */
3938             high = low = 0;
3939
3940             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3941               {
3942                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3943                                                     / HOST_BITS_PER_CHAR)]
3944                          << (i * HOST_BITS_PER_CHAR));
3945                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3946               }
3947             
3948             
3949             yylval.ttype = build_int_2 (low, high);
3950             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3951
3952             /* Calculate the ANSI type.  */
3953             if (!spec_long && !spec_unsigned
3954                 && int_fits_type_p (yylval.ttype, integer_type_node))
3955               type = integer_type_node;
3956             else if (!spec_long && (base != 10 || spec_unsigned)
3957                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
3958               /* Nondecimal constants try unsigned even in traditional C.  */
3959               type = unsigned_type_node;
3960             else if (!spec_unsigned && !spec_long_long
3961                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
3962               type = long_integer_type_node;
3963             else if (! spec_long_long)
3964               type = long_unsigned_type_node;
3965             else if (! spec_unsigned
3966                      /* Verify value does not overflow into sign bit.  */
3967                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
3968                      && int_fits_type_p (yylval.ttype,
3969                                          long_long_integer_type_node))
3970               type = long_long_integer_type_node;
3971             else
3972               type = long_long_unsigned_type_node;
3973
3974             if (!int_fits_type_p (yylval.ttype, type) && !warn)
3975               pedwarn ("integer constant out of range");
3976
3977             if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
3978               warning ("decimal integer constant is so large that it is unsigned");
3979
3980             if (spec_imag)
3981               {
3982                 if (TYPE_PRECISION (type)
3983                     <= TYPE_PRECISION (integer_type_node))
3984                   yylval.ttype
3985                     = build_complex (NULL_TREE, integer_zero_node,
3986                                      cp_convert (integer_type_node,
3987                                                  yylval.ttype));
3988                 else
3989                   error ("complex integer constant is too wide for `__complex int'");
3990               }
3991             else
3992               TREE_TYPE (yylval.ttype) = type;
3993           }
3994
3995         put_back (c);
3996         *p = 0;
3997
3998         value = CONSTANT; break;
3999       }
4000
4001     case '\'':
4002     char_constant:
4003       {
4004         register int result = 0;
4005         register int num_chars = 0;
4006         int chars_seen = 0;
4007         unsigned width = TYPE_PRECISION (char_type_node);
4008         int max_chars;
4009 #ifdef MULTIBYTE_CHARS
4010         int longest_char = local_mb_cur_max ();
4011         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
4012 #endif
4013
4014         max_chars = TYPE_PRECISION (integer_type_node) / width;
4015         if (wide_flag)
4016           width = WCHAR_TYPE_SIZE;
4017
4018         while (1)
4019           {
4020           tryagain:
4021             c = getch ();
4022
4023             if (c == '\'' || c == EOF)
4024               break;
4025
4026             ++chars_seen;
4027             if (c == '\\')
4028               {
4029                 int ignore = 0;
4030                 c = readescape (&ignore);
4031                 if (ignore)
4032                   goto tryagain;
4033                 if (width < HOST_BITS_PER_INT
4034                     && (unsigned) c >= ((unsigned)1 << width))
4035                   pedwarn ("escape sequence out of range for character");
4036 #ifdef MAP_CHARACTER
4037                 if (ISPRINT (c))
4038                   c = MAP_CHARACTER (c);
4039 #endif
4040               }
4041             else if (c == '\n')
4042               {
4043                 if (pedantic)
4044                   pedwarn ("ANSI C forbids newline in character constant");
4045                 lineno++;
4046               }
4047             else
4048               {
4049 #ifdef MULTIBYTE_CHARS
4050                 wchar_t wc;
4051                 int i;
4052                 int char_len = -1;
4053                 for (i = 1; i <= longest_char; ++i)
4054                   {
4055                     if (i > maxtoken - 4)
4056                       extend_token_buffer (token_buffer);
4057
4058                     token_buffer[i] = c;
4059                     char_len = local_mbtowc (& wc,
4060                                              token_buffer + 1,
4061                                              i);
4062                     if (char_len != -1)
4063                       break;
4064                     c = getch ();
4065                   }
4066                 if (char_len > 1)
4067                   {
4068                     /* mbtowc sometimes needs an extra char before accepting */
4069                     if (char_len < i)
4070                       put_back (c);
4071                     if (! wide_flag)
4072                       {
4073                         /* Merge character into result; ignore excess chars.  */
4074                         for (i = 1; i <= char_len; ++i)
4075                           {
4076                             if (i > max_chars)
4077                               break;
4078                             if (width < HOST_BITS_PER_INT)
4079                               result = (result << width)
4080                                 | (token_buffer[i]
4081                                    & ((1 << width) - 1));
4082                             else
4083                               result = token_buffer[i];
4084                           }
4085                         num_chars += char_len;
4086                         goto tryagain;
4087                       }
4088                     c = wc;
4089                   }
4090                 else
4091                   {
4092                     if (char_len == -1)
4093                       warning ("Ignoring invalid multibyte character");
4094                     if (wide_flag)
4095                       c = wc;
4096 #ifdef MAP_CHARACTER
4097                     else
4098                       c = MAP_CHARACTER (c);
4099 #endif
4100                   }
4101 #else /* ! MULTIBYTE_CHARS */
4102 #ifdef MAP_CHARACTER
4103                 c = MAP_CHARACTER (c);
4104 #endif
4105 #endif /* ! MULTIBYTE_CHARS */
4106               }
4107
4108             if (wide_flag)
4109               {
4110                 if (chars_seen == 1) /* only keep the first one */
4111                   result = c;
4112                 goto tryagain;
4113               }
4114
4115             /* Merge character into result; ignore excess chars.  */
4116             num_chars++;
4117             if (num_chars < max_chars + 1)
4118               {
4119                 if (width < HOST_BITS_PER_INT)
4120                   result = (result << width) | (c & ((1 << width) - 1));
4121                 else
4122                   result = c;
4123               }
4124           }
4125
4126         if (c != '\'')
4127           error ("malformatted character constant");
4128         else if (chars_seen == 0)
4129           error ("empty character constant");
4130         else if (num_chars > max_chars)
4131           {
4132             num_chars = max_chars;
4133             error ("character constant too long");
4134           }
4135         else if (chars_seen != 1 && warn_multichar)
4136           warning ("multi-character character constant");
4137
4138         /* If char type is signed, sign-extend the constant.  */
4139         if (! wide_flag)
4140           {
4141             int num_bits = num_chars * width;
4142             if (num_bits == 0)
4143               /* We already got an error; avoid invalid shift.  */
4144               yylval.ttype = build_int_2 (0, 0);
4145             else if (TREE_UNSIGNED (char_type_node)
4146                      || ((result >> (num_bits - 1)) & 1) == 0)
4147               yylval.ttype
4148                 = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
4149                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4150                                0);
4151             else
4152               yylval.ttype
4153                 = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
4154                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4155                                -1);
4156             if (chars_seen <= 1)
4157               TREE_TYPE (yylval.ttype) = char_type_node;
4158             else
4159               TREE_TYPE (yylval.ttype) = integer_type_node;
4160           }
4161         else
4162           {
4163             yylval.ttype = build_int_2 (result, 0);
4164             TREE_TYPE (yylval.ttype) = wchar_type_node;
4165           }
4166
4167         value = CONSTANT;
4168         break;
4169       }
4170
4171     case '"':
4172     string_constant:
4173       {
4174         register char *p;
4175         unsigned width = wide_flag ? WCHAR_TYPE_SIZE
4176                                    : TYPE_PRECISION (char_type_node);
4177 #ifdef MULTIBYTE_CHARS
4178         int longest_char = local_mb_cur_max ();
4179         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
4180 #endif
4181
4182         c = getch ();
4183         p = token_buffer + 1;
4184
4185         while (c != '"' && c >= 0)
4186           {
4187             /* ignore_escape_flag is set for reading the filename in #line.  */
4188             if (!ignore_escape_flag && c == '\\')
4189               {
4190                 int ignore = 0;
4191                 c = readescape (&ignore);
4192                 if (ignore)
4193                   goto skipnewline;
4194                 if (width < HOST_BITS_PER_INT
4195                     && (unsigned) c >= ((unsigned)1 << width))
4196                   warning ("escape sequence out of range for character");
4197               }
4198             else if (c == '\n')
4199               {
4200                 if (pedantic)
4201                   pedwarn ("ANSI C++ forbids newline in string constant");
4202                 lineno++;
4203               }
4204             else
4205               {
4206 #ifdef MULTIBYTE_CHARS
4207                 wchar_t wc;
4208                 int i;
4209                 int char_len = -1;
4210                 for (i = 0; i < longest_char; ++i)
4211                   {
4212                     if (p + i >= token_buffer + maxtoken)
4213                       p = extend_token_buffer (p);
4214                     p[i] = c;
4215
4216                     char_len = local_mbtowc (& wc, p, i + 1);
4217                     if (char_len != -1)
4218                       break;
4219                     c = getch ();
4220                   }
4221                 if (char_len == -1)
4222                   warning ("Ignoring invalid multibyte character");
4223                 else
4224                   {
4225                     /* mbtowc sometimes needs an extra char before accepting */
4226                     if (char_len <= i)
4227                       put_back (c);
4228                     if (! wide_flag)
4229                       {
4230                         p += (i + 1);
4231                         c = getch ();
4232                         continue;
4233                       }
4234                     c = wc;
4235                   }
4236 #endif /* MULTIBYTE_CHARS */
4237               }
4238
4239             /* Add this single character into the buffer either as a wchar_t
4240                or as a single byte.  */
4241             if (wide_flag)
4242               {
4243                 unsigned width = TYPE_PRECISION (char_type_node);
4244                 unsigned bytemask = (1 << width) - 1;
4245                 int byte;
4246
4247                 if (p + WCHAR_BYTES > token_buffer + maxtoken)
4248                   p = extend_token_buffer (p);
4249
4250                 for (byte = 0; byte < WCHAR_BYTES; ++byte)
4251                   {
4252                     int value;
4253                     if (byte >= (int) sizeof(c))
4254                       value = 0;
4255                     else
4256                       value = (c >> (byte * width)) & bytemask;
4257                     if (BYTES_BIG_ENDIAN)
4258                       p[WCHAR_BYTES - byte - 1] = value;
4259                     else
4260                       p[byte] = value;
4261                   }
4262                 p += WCHAR_BYTES;
4263               }
4264             else
4265               {
4266                 if (p >= token_buffer + maxtoken)
4267                   p = extend_token_buffer (p);
4268                 *p++ = c;
4269               }
4270
4271           skipnewline:
4272             c = getch ();
4273             if (c == EOF) {
4274                 error ("Unterminated string");
4275                 break;
4276             }
4277           }
4278
4279         /* Terminate the string value, either with a single byte zero
4280            or with a wide zero.  */
4281         if (wide_flag)
4282           {
4283             if (p + WCHAR_BYTES > token_buffer + maxtoken)
4284               p = extend_token_buffer (p);
4285             bzero (p, WCHAR_BYTES);
4286             p += WCHAR_BYTES;
4287           }
4288         else
4289           {
4290             if (p >= token_buffer + maxtoken)
4291               p = extend_token_buffer (p);
4292             *p++ = 0;
4293           }
4294
4295         /* We have read the entire constant.
4296            Construct a STRING_CST for the result.  */
4297
4298         if (processing_template_decl)
4299           push_obstacks (&permanent_obstack, &permanent_obstack);
4300         yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1);
4301         if (processing_template_decl)
4302           pop_obstacks ();
4303
4304         if (wide_flag)
4305           TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4306         else
4307           TREE_TYPE (yylval.ttype) = char_array_type_node;
4308
4309         value = STRING; break;
4310       }
4311
4312     case '+':
4313     case '-':
4314     case '&':
4315     case '|':
4316     case '<':
4317     case '>':
4318     case '*':
4319     case '/':
4320     case '%':
4321     case '^':
4322     case '!':
4323     case '=':
4324       {
4325         register int c1;
4326
4327       combine:
4328
4329         switch (c)
4330           {
4331           case '+':
4332             yylval.code = PLUS_EXPR; break;
4333           case '-':
4334             yylval.code = MINUS_EXPR; break;
4335           case '&':
4336             yylval.code = BIT_AND_EXPR; break;
4337           case '|':
4338             yylval.code = BIT_IOR_EXPR; break;
4339           case '*':
4340             yylval.code = MULT_EXPR; break;
4341           case '/':
4342             yylval.code = TRUNC_DIV_EXPR; break;
4343           case '%':
4344             yylval.code = TRUNC_MOD_EXPR; break;
4345           case '^':
4346             yylval.code = BIT_XOR_EXPR; break;
4347           case LSHIFT:
4348             yylval.code = LSHIFT_EXPR; break;
4349           case RSHIFT:
4350             yylval.code = RSHIFT_EXPR; break;
4351           case '<':
4352             yylval.code = LT_EXPR; break;
4353           case '>':
4354             yylval.code = GT_EXPR; break;
4355           }
4356
4357         token_buffer[1] = c1 = getch ();
4358         token_buffer[2] = 0;
4359
4360         if (c1 == '=')
4361           {
4362             switch (c)
4363               {
4364               case '<':
4365                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4366               case '>':
4367                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4368               case '!':
4369                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4370               case '=':
4371                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4372               }
4373             value = ASSIGN; goto done;
4374           }
4375         else if (c == c1)
4376           switch (c)
4377             {
4378             case '+':
4379               value = PLUSPLUS; goto done;
4380             case '-':
4381               value = MINUSMINUS; goto done;
4382             case '&':
4383               value = ANDAND; goto done;
4384             case '|':
4385               value = OROR; goto done;
4386             case '<':
4387               c = LSHIFT;
4388               goto combine;
4389             case '>':
4390               c = RSHIFT;
4391               goto combine;
4392             }
4393         else if ((c == '-') && (c1 == '>'))
4394           {
4395             nextchar = getch ();
4396             if (nextchar == '*')
4397               {
4398                 nextchar = -1;
4399                 value = POINTSAT_STAR;
4400               }
4401             else
4402               value = POINTSAT;
4403             goto done;
4404           }
4405         else if (c1 == '?' && (c == '<' || c == '>'))
4406           {
4407             token_buffer[3] = 0;
4408
4409             c1 = getch ();
4410             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4411             if (c1 == '=')
4412               {
4413                 /* <?= or >?= expression.  */
4414                 token_buffer[2] = c1;
4415                 value = ASSIGN;
4416               }
4417             else
4418               {
4419                 value = MIN_MAX;
4420                 nextchar = c1;
4421               }
4422             if (pedantic)
4423               pedwarn ("use of `operator %s' is not standard C++",
4424                        token_buffer);
4425             goto done;
4426           }
4427         /* digraphs */
4428         else if (c == '<' && c1 == '%')
4429           { value = '{'; goto done; }
4430         else if (c == '<' && c1 == ':')
4431           { value = '['; goto done; }
4432         else if (c == '%' && c1 == '>')
4433           { value = '}'; goto done; }
4434         else if (c == '%' && c1 == ':')
4435           { value = '#'; goto done; }
4436
4437         nextchar = c1;
4438         token_buffer[1] = 0;
4439
4440         value = c;
4441         goto done;
4442       }
4443
4444     case ':':
4445       c = getch ();
4446       if (c == ':')
4447         {
4448           token_buffer[1] = ':';
4449           token_buffer[2] = '\0';
4450           value = SCOPE;
4451           yylval.itype = 1;
4452         }
4453       else if (c == '>')
4454         {
4455           value = ']';
4456           goto done;
4457         }
4458       else
4459         {
4460           nextchar = c;
4461           value = ':';
4462         }
4463       break;
4464
4465     case 0:
4466       /* Don't make yyparse think this is eof.  */
4467       value = 1;
4468       break;
4469
4470     case '(':
4471       /* try, weakly, to handle casts to pointers to functions.  */
4472       nextchar = skip_white_space (getch ());
4473       if (nextchar == '*')
4474         {
4475           int next_c = skip_white_space (getch ());
4476           if (next_c == ')')
4477             {
4478               nextchar = -1;
4479               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4480               value = PAREN_STAR_PAREN;
4481             }
4482           else
4483             {
4484               put_back (next_c);
4485               value = c;
4486             }
4487         }
4488       else if (nextchar == ')')
4489         {
4490           nextchar = -1;
4491           yylval.ttype = NULL_TREE;
4492           value = LEFT_RIGHT;
4493         }
4494       else value = c;
4495       break;
4496
4497     default:
4498       value = c;
4499     }
4500
4501 done:
4502 /*  yylloc.last_line = lineno; */
4503 #ifdef GATHER_STATISTICS
4504 #ifdef REDUCE_LENGTH
4505   token_count[value] += 1;
4506 #endif
4507 #endif
4508
4509   return value;
4510 }
4511
4512 int
4513 is_rid (t)
4514      tree t;
4515 {
4516   return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
4517 }
4518
4519 #ifdef GATHER_STATISTICS
4520 /* The original for tree_node_kind is in the toplevel tree.c; changes there
4521    need to be brought into here, unless this were actually put into a header
4522    instead.  */
4523 /* Statistics-gathering stuff.  */
4524 typedef enum
4525 {
4526   d_kind,
4527   t_kind,
4528   b_kind,
4529   s_kind,
4530   r_kind,
4531   e_kind,
4532   c_kind,
4533   id_kind,
4534   op_id_kind,
4535   perm_list_kind,
4536   temp_list_kind,
4537   vec_kind,
4538   x_kind,
4539   lang_decl,
4540   lang_type,
4541   all_kinds
4542 } tree_node_kind;
4543
4544 extern int tree_node_counts[];
4545 extern int tree_node_sizes[];
4546 #endif
4547
4548 /* Place to save freed lang_decls which were allocated on the
4549    permanent_obstack.  @@ Not currently used.  */
4550 tree free_lang_decl_chain;
4551
4552 tree
4553 build_lang_decl (code, name, type)
4554      enum tree_code code;
4555      tree name;
4556      tree type;
4557 {
4558   register tree t = build_decl (code, name, type);
4559   retrofit_lang_decl (t);
4560   return t;
4561 }
4562
4563 /* Add DECL_LANG_SPECIFIC info to T.  Called from build_lang_decl
4564    and pushdecl (for functions generated by the backend).  */
4565
4566 void
4567 retrofit_lang_decl (t)
4568      tree t;
4569 {
4570   struct obstack *obstack = current_obstack;
4571   register int i = sizeof (struct lang_decl) / sizeof (int);
4572   register int *pi;
4573
4574   if (! TREE_PERMANENT (t))
4575     obstack = saveable_obstack;
4576   else
4577     /* Could be that saveable is permanent and current is not.  */
4578     obstack = &permanent_obstack;
4579
4580   if (free_lang_decl_chain && obstack == &permanent_obstack)
4581     {
4582       pi = (int *)free_lang_decl_chain;
4583       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4584     }
4585   else
4586     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4587
4588   while (i > 0)
4589     pi[--i] = 0;
4590
4591   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4592   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4593     = obstack == &permanent_obstack;
4594   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4595           == TREE_PERMANENT  (t), 234);
4596   DECL_MAIN_VARIANT (t) = t;
4597   if (current_lang_name == lang_name_cplusplus)
4598     DECL_LANGUAGE (t) = lang_cplusplus;
4599   else if (current_lang_name == lang_name_c)
4600     DECL_LANGUAGE (t) = lang_c;
4601   else if (current_lang_name == lang_name_java)
4602     DECL_LANGUAGE (t) = lang_java;
4603   else my_friendly_abort (64);
4604
4605 #if 0 /* not yet, should get fixed properly later */
4606   if (code == TYPE_DECL)
4607     {
4608       tree id;
4609       id = get_identifier (build_overload_name (type, 1, 1));
4610       DECL_ASSEMBLER_NAME (t) = id;
4611     }
4612
4613 #endif
4614 #ifdef GATHER_STATISTICS
4615   tree_node_counts[(int)lang_decl] += 1;
4616   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4617 #endif
4618 }
4619
4620 tree
4621 build_lang_field_decl (code, name, type)
4622      enum tree_code code;
4623      tree name;
4624      tree type;
4625 {
4626   extern struct obstack *current_obstack, *saveable_obstack;
4627   register tree t = build_decl (code, name, type);
4628   struct obstack *obstack = current_obstack;
4629   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4630   register int *pi;
4631 #if 0 /* not yet, should get fixed properly later */
4632
4633   if (code == TYPE_DECL)
4634     {
4635       tree id;
4636       id = get_identifier (build_overload_name (type, 1, 1));
4637       DECL_ASSEMBLER_NAME (t) = id;
4638     }
4639 #endif
4640
4641   if (! TREE_PERMANENT (t))
4642     obstack = saveable_obstack;
4643   else
4644     my_friendly_assert (obstack == &permanent_obstack, 235);
4645
4646   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4647   while (i > 0)
4648     pi[--i] = 0;
4649
4650   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4651   return t;
4652 }
4653
4654 void
4655 copy_lang_decl (node)
4656      tree node;
4657 {
4658   int size;
4659   int *pi;
4660
4661   if (! DECL_LANG_SPECIFIC (node))
4662     return;
4663
4664   if (TREE_CODE (node) == FIELD_DECL)
4665     size = sizeof (struct lang_decl_flags);
4666   else
4667     size = sizeof (struct lang_decl);
4668   pi = (int *)obstack_alloc (&permanent_obstack, size);
4669   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4670   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4671 }
4672
4673 tree
4674 make_lang_type (code)
4675      enum tree_code code;
4676 {
4677   extern struct obstack *current_obstack, *saveable_obstack;
4678   register tree t = make_node (code);
4679
4680   /* Set up some flags that give proper default behavior.  */
4681   if (IS_AGGR_TYPE_CODE (code))
4682     {
4683       struct obstack *obstack = current_obstack;
4684       struct lang_type *pi;
4685
4686       SET_IS_AGGR_TYPE (t, 1);
4687
4688       if (! TREE_PERMANENT (t))
4689         obstack = saveable_obstack;
4690       else
4691         my_friendly_assert (obstack == &permanent_obstack, 236);
4692
4693       pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
4694       bzero ((char *) pi, (int) sizeof (struct lang_type));
4695
4696       TYPE_LANG_SPECIFIC (t) = pi;
4697       CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
4698       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4699       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4700       TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
4701       CLASSTYPE_BINFO_AS_LIST (t) 
4702         = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4703
4704       /* Make sure this is laid out, for ease of use later.  In the
4705          presence of parse errors, the normal was of assuring this
4706          might not ever get executed, so we lay it out *immediately*.  */
4707       build_pointer_type (t);
4708
4709 #ifdef GATHER_STATISTICS
4710       tree_node_counts[(int)lang_type] += 1;
4711       tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
4712 #endif
4713     }
4714   else
4715     /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
4716        TYPE_ALIAS_SET is initialized to -1 by default, so we must
4717        clear it here.  */
4718     TYPE_ALIAS_SET (t) = 0;
4719
4720   return t;
4721 }
4722
4723 void
4724 dump_time_statistics ()
4725 {
4726   register tree prev = 0, decl, next;
4727   int this_time = my_get_run_time ();
4728   TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
4729     += this_time - body_time;
4730
4731   fprintf (stderr, "\n******\n");
4732   print_time ("header files (total)", header_time);
4733   print_time ("main file (total)", this_time - body_time);
4734   fprintf (stderr, "ratio = %g : 1\n",
4735            (double)header_time / (double)(this_time - body_time));
4736   fprintf (stderr, "\n******\n");
4737
4738   for (decl = filename_times; decl; decl = next)
4739     {
4740       next = IDENTIFIER_GLOBAL_VALUE (decl);
4741       SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
4742       prev = decl;
4743     }
4744
4745   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4746     print_time (IDENTIFIER_POINTER (decl),
4747                 TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
4748 }
4749
4750 void
4751 compiler_error (s, v, v2)
4752      char *s;
4753      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4754 {
4755   char buf[1024];
4756   sprintf (buf, s, v, v2);
4757   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4758 }
4759 \f
4760 void
4761 yyerror (string)
4762      char *string;
4763 {
4764   extern int end_of_file;
4765   char buf[200];
4766
4767   strcpy (buf, string);
4768
4769   /* We can't print string and character constants well
4770      because the token_buffer contains the result of processing escapes.  */
4771   if (end_of_file)
4772     strcat (buf, input_redirected ()
4773             ? " at end of saved text"
4774             : " at end of input");
4775   else if (token_buffer[0] == 0)
4776     strcat (buf, " at null character");
4777   else if (token_buffer[0] == '"')
4778     strcat (buf, " before string constant");
4779   else if (token_buffer[0] == '\'')
4780     strcat (buf, " before character constant");
4781   else if (!ISGRAPH ((unsigned char)token_buffer[0]))
4782     sprintf (buf + strlen (buf), " before character 0%o",
4783              (unsigned char) token_buffer[0]);
4784   else
4785     strcat (buf, " before `%s'");
4786
4787   error (buf, token_buffer);
4788 }
4789 \f
4790 static int
4791 handle_cp_pragma (pname)
4792      char *pname;
4793 {
4794   register int token;
4795
4796   if (! strcmp (pname, "vtable"))
4797     {
4798       extern tree pending_vtables;
4799
4800       /* More follows: it must be a string constant (class name).  */
4801       token = real_yylex ();
4802       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4803         {
4804           error ("invalid #pragma vtable");
4805           return -1;
4806         }
4807
4808       if (write_virtuals != 2)
4809         {
4810           warning ("use `+e2' option to enable #pragma vtable");
4811           return -1;
4812         }
4813       pending_vtables
4814         = perm_tree_cons (NULL_TREE,
4815                           get_identifier (TREE_STRING_POINTER (yylval.ttype)),
4816                           pending_vtables);
4817       token = real_yylex ();
4818       if (token != END_OF_LINE)
4819         warning ("trailing characters ignored");
4820       return 1;
4821     }
4822   else if (! strcmp (pname, "unit"))
4823     {
4824       /* More follows: it must be a string constant (unit name).  */
4825       token = real_yylex ();
4826       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4827         {
4828           error ("invalid #pragma unit");
4829           return -1;
4830         }
4831       token = real_yylex ();
4832       if (token != END_OF_LINE)
4833         warning ("trailing characters ignored");
4834       return 1;
4835     }
4836   else if (! strcmp (pname, "interface"))
4837     {
4838       tree fileinfo 
4839         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4840       char *main_filename = input_filename;
4841
4842       main_filename = file_name_nondirectory (main_filename);
4843
4844       token = real_yylex ();
4845       
4846       if (token != END_OF_LINE)
4847         {
4848           if (token != STRING
4849               || TREE_CODE (yylval.ttype) != STRING_CST)
4850             {
4851               error ("invalid `#pragma interface'");
4852               return -1;
4853             }
4854           main_filename = TREE_STRING_POINTER (yylval.ttype);
4855           token = real_yylex ();
4856         }
4857
4858       if (token != END_OF_LINE)
4859         warning ("garbage after `#pragma interface' ignored");
4860
4861       write_virtuals = 3;
4862
4863       if (impl_file_chain == 0)
4864         {
4865           /* If this is zero at this point, then we are
4866              auto-implementing.  */
4867           if (main_input_filename == 0)
4868             main_input_filename = input_filename;
4869
4870 #ifdef AUTO_IMPLEMENT
4871           filename = file_name_nondirectory (main_input_filename);
4872           fi = get_time_identifier (filename);
4873           fi = TIME_IDENTIFIER_FILEINFO (fi);
4874           TREE_INT_CST_LOW (fi) = 0;
4875           TREE_INT_CST_HIGH (fi) = 1;
4876           /* Get default.  */
4877           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
4878           impl_file_chain->filename = filename;
4879           impl_file_chain->next = 0;
4880 #endif
4881         }
4882
4883       interface_only = interface_strcmp (main_filename);
4884 #ifdef MULTIPLE_SYMBOL_SPACES
4885       if (! interface_only)
4886         interface_unknown = 0;
4887 #else /* MULTIPLE_SYMBOL_SPACES */
4888       interface_unknown = 0;
4889 #endif /* MULTIPLE_SYMBOL_SPACES */
4890       TREE_INT_CST_LOW (fileinfo) = interface_only;
4891       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4892
4893       return 1;
4894     }
4895   else if (! strcmp (pname, "implementation"))
4896     {
4897       tree fileinfo 
4898         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4899       char *main_filename = main_input_filename ? main_input_filename : input_filename;
4900
4901       main_filename = file_name_nondirectory (main_filename);
4902       token = real_yylex ();
4903       if (token != END_OF_LINE)
4904         {
4905           if (token != STRING
4906               || TREE_CODE (yylval.ttype) != STRING_CST)
4907             {
4908               error ("invalid `#pragma implementation'");
4909               return -1;
4910             }
4911           main_filename = TREE_STRING_POINTER (yylval.ttype);
4912           token = real_yylex ();
4913         }
4914
4915       if (token != END_OF_LINE)
4916         warning ("garbage after `#pragma implementation' ignored");
4917
4918       if (write_virtuals == 3)
4919         {
4920           struct impl_files *ifiles = impl_file_chain;
4921           while (ifiles)
4922             {
4923               if (! strcmp (ifiles->filename, main_filename))
4924                 break;
4925               ifiles = ifiles->next;
4926             }
4927           if (ifiles == 0)
4928             {
4929               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
4930               ifiles->filename = main_filename;
4931               ifiles->next = impl_file_chain;
4932               impl_file_chain = ifiles;
4933             }
4934         }
4935       else if ((main_input_filename != 0
4936                 && ! strcmp (main_input_filename, input_filename))
4937                || ! strcmp (input_filename, main_filename))
4938         {
4939           write_virtuals = 3;
4940           if (impl_file_chain == 0)
4941             {
4942               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
4943               impl_file_chain->filename = main_filename;
4944               impl_file_chain->next = 0;
4945             }
4946         }
4947       else
4948         error ("`#pragma implementation' can only appear at top-level");
4949       interface_only = 0;
4950 #if 1
4951       /* We make this non-zero so that we infer decl linkage
4952          in the impl file only for variables first declared
4953          in the interface file.  */
4954       interface_unknown = 1;
4955 #else
4956       /* We make this zero so that templates in the impl
4957          file will be emitted properly.  */
4958       interface_unknown = 0;
4959 #endif
4960       TREE_INT_CST_LOW (fileinfo) = interface_only;
4961       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4962
4963       return 1;
4964     }
4965
4966   return 0;
4967 }
4968
4969 /* Return the type-qualifier corresponding to the identifier given by
4970    RID.  */
4971
4972 int
4973 cp_type_qual_from_rid (rid)
4974      tree rid;
4975 {
4976   if (rid == ridpointers[(int) RID_CONST])
4977     return TYPE_QUAL_CONST;
4978   else if (rid == ridpointers[(int) RID_VOLATILE])
4979     return TYPE_QUAL_VOLATILE;
4980   else if (rid == ridpointers[(int) RID_RESTRICT])
4981     return TYPE_QUAL_RESTRICT;
4982
4983   my_friendly_abort (0);
4984   return TYPE_UNQUALIFIED;
4985 }
4986
4987 \f
4988 #ifdef HANDLE_GENERIC_PRAGMAS
4989
4990 /* Handle a #pragma directive.  TOKEN is the type of the word following
4991    the #pragma directive on the line.  Process the entire input line and
4992    return non-zero iff the directive successfully parsed.  */
4993
4994 /* This function has to be in this file, in order to get at
4995    the token types.  */
4996
4997 static int
4998 handle_generic_pragma (token)
4999      register int token;
5000 {
5001   for (;;)
5002     {
5003       switch (token)
5004         {
5005         case IDENTIFIER:
5006         case TYPENAME:
5007         case STRING:
5008         case CONSTANT:
5009           handle_pragma_token (token_buffer, yylval.ttype);
5010           break;
5011
5012         case LEFT_RIGHT:
5013           handle_pragma_token ("(", NULL_TREE);
5014           handle_pragma_token (")", NULL_TREE);
5015           break;
5016
5017         case END_OF_LINE:
5018           return handle_pragma_token (NULL_PTR, NULL_TREE);
5019
5020         default:
5021           handle_pragma_token (token_buffer, NULL);
5022         }
5023       
5024       token = real_yylex ();
5025     }
5026 }
5027 #endif /* HANDLE_GENERIC_PRAGMAS */