OSDN Git Service

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