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