OSDN Git Service

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