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