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