OSDN Git Service

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