OSDN Git Service

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