OSDN Git Service

53rd Cygnus<->FSF merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / lex.c
1 /* Separate lexical analyzer for GNU C++.
2    Copyright (C) 1987, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
3    Hacked by Michael Tiemann (tiemann@cygnus.com)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21
22 /* This file is the lexical analyzer for GNU C++.  */
23
24 /* Cause the `yydebug' variable to be defined.  */
25 #define YYDEBUG 1
26
27 #include <sys/types.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <setjmp.h>
31 #include "config.h"
32 #include "input.h"
33 #include "tree.h"
34 #include "lex.h"
35 #include "parse.h"
36 #include "cp-tree.h"
37 #include "flags.h"
38 #include "obstack.h"
39
40 #ifdef MULTIBYTE_CHARS
41 #include <stdlib.h>
42 #include <locale.h>
43 #endif
44
45 #ifndef errno
46 extern int errno;               /* needed for VAX.  */
47 #endif
48 extern jmp_buf toplevel;
49
50 #define obstack_chunk_alloc xmalloc
51 #define obstack_chunk_free free
52
53 extern struct obstack *expression_obstack, permanent_obstack;
54 extern struct obstack *current_obstack, *saveable_obstack;
55
56 extern double atof ();
57
58 extern char *get_directive_line ();     /* In c-common.c */
59
60 /* Given a file name X, return the nondirectory portion.
61    Keep in mind that X can be computed more than once.  */
62 #ifndef FILE_NAME_NONDIRECTORY
63 #define FILE_NAME_NONDIRECTORY(X)               \
64  (rindex (X, '/') != 0 ? rindex (X, '/') + 1 : X)
65 #endif
66
67 extern char *index ();
68 extern char *rindex ();
69
70 void extract_interface_info ();
71 void yyerror ();
72
73 /* This obstack is needed to hold text.  It is not safe to use
74    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
75 struct obstack inline_text_obstack;
76 static char *inline_text_firstobj;
77
78 /* This obstack is used to hold information about methods to be
79    synthesized.  It should go away when synthesized methods are handled
80    properly (i.e. only when needed).  */
81 struct obstack synth_obstack;
82 static char *synth_firstobj;
83
84 int end_of_file;
85
86 /* Pending language change.
87    Positive is push count, negative is pop count.  */
88 int pending_lang_change = 0;
89
90 /* Wrap the current header file in extern "C".  */
91 static int c_header_level = 0;
92
93 extern int first_token;
94 extern struct obstack token_obstack;
95
96 /* ??? Don't really know where this goes yet.  */
97 #if 1
98 #include "input.c"
99 #else
100 extern void put_back (/* int */);
101 extern int input_redirected ();
102 extern void feed_input (/* char *, int, struct obstack * */);
103 #endif
104
105 /* Holds translations from TREE_CODEs to operator name strings,
106    i.e., opname_tab[PLUS_EXPR] == "+".  */
107 char **opname_tab;
108 char **assignop_tab;
109 \f
110 extern int yychar;              /*  the lookahead symbol                */
111 extern YYSTYPE yylval;          /*  the semantic value of the           */
112                                 /*  lookahead symbol                    */
113
114 #if 0
115 YYLTYPE yylloc;                 /*  location data for the lookahead     */
116                                 /*  symbol                              */
117 #endif
118
119
120 /* the declaration found for the last IDENTIFIER token read in.
121    yylex must look this up to detect typedefs, which get token type TYPENAME,
122    so it is left around in case the identifier is not a typedef but is
123    used in a context which makes it a reference to a variable.  */
124 tree lastiddecl;
125
126 /* The elements of `ridpointers' are identifier nodes
127    for the reserved type names and storage classes.
128    It is indexed by a RID_... value.  */
129 tree ridpointers[(int) RID_MAX];
130
131 /* We may keep statistics about how long which files took to compile.  */
132 static int header_time, body_time;
133 static tree get_time_identifier ();
134 static tree filename_times;
135 static tree this_filename_time;
136
137 /* For implementing #pragma unit.  */
138 tree current_unit_name;
139 tree current_unit_language;
140
141 /* Array for holding counts of the numbers of tokens seen.  */
142 extern int *token_count;
143
144 /* Textual definition used for default functions.  */
145 static void default_copy_constructor_body ();
146 static void default_assign_ref_body ();
147 \f
148 /* Return something to represent absolute declarators containing a *.
149    TARGET is the absolute declarator that the * contains.
150    TYPE_QUALS is a list of modifiers such as const or volatile
151    to apply to the pointer type, represented as identifiers.
152
153    We return an INDIRECT_REF whose "contents" are TARGET
154    and whose type is the modifier list.  */
155
156 tree
157 make_pointer_declarator (type_quals, target)
158      tree type_quals, target;
159 {
160   if (target && TREE_CODE (target) == IDENTIFIER_NODE
161       && ANON_AGGRNAME_P (target))
162     error ("type name expected before `*'");
163   target = build_parse_node (INDIRECT_REF, target);
164   TREE_TYPE (target) = type_quals;
165   return target;
166 }
167
168 /* Return something to represent absolute declarators containing a &.
169    TARGET is the absolute declarator that the & contains.
170    TYPE_QUALS is a list of modifiers such as const or volatile
171    to apply to the reference type, represented as identifiers.
172
173    We return an ADDR_EXPR whose "contents" are TARGET
174    and whose type is the modifier list.  */
175    
176 tree
177 make_reference_declarator (type_quals, target)
178      tree type_quals, target;
179 {
180   if (target)
181     {
182       if (TREE_CODE (target) == ADDR_EXPR)
183         {
184           error ("cannot declare references to references");
185           return target;
186         }
187       if (TREE_CODE (target) == INDIRECT_REF)
188         {
189           error ("cannot declare pointers to references");
190           return target;
191         }
192       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
193           error ("type name expected before `&'");
194     }
195   target = build_parse_node (ADDR_EXPR, target);
196   TREE_TYPE (target) = type_quals;
197   return target;
198 }
199 \f
200 /* Build names and nodes for overloaded operators.  */
201
202 tree ansi_opname[LAST_CPLUS_TREE_CODE];
203 tree ansi_assopname[LAST_CPLUS_TREE_CODE];
204
205 char *
206 operator_name_string (name)
207      tree name;
208 {
209   char *opname = IDENTIFIER_POINTER (name) + 2;
210   tree *opname_table;
211   int i, assign;
212
213   /* Works for builtin and user defined types.  */
214   if (IDENTIFIER_GLOBAL_VALUE (name)
215       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
216     return IDENTIFIER_POINTER (name);
217
218   if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
219     {
220       opname += 1;
221       assign = 1;
222       opname_table = ansi_assopname;
223     }
224   else
225     {
226       assign = 0;
227       opname_table = ansi_opname;
228     }
229
230   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
231     {
232       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
233           && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
234         break;
235     }
236
237   if (i == LAST_CPLUS_TREE_CODE)
238     return "<invalid operator>";
239
240   if (assign)
241     return assignop_tab[i];
242   else
243     return opname_tab[i];
244 }
245 \f
246 int interface_only;             /* whether or not current file is only for
247                                    interface definitions.  */
248 int interface_unknown;          /* whether or not we know this class
249                                    to behave according to #pragma interface.  */
250
251 /* lexical analyzer */
252
253 /* File used for outputting assembler code.  */
254 extern FILE *asm_out_file;
255
256 #ifndef WCHAR_TYPE_SIZE
257 #ifdef INT_TYPE_SIZE
258 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
259 #else
260 #define WCHAR_TYPE_SIZE BITS_PER_WORD
261 #endif
262 #endif
263
264 /* Number of bytes in a wide character.  */
265 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
266
267 static int maxtoken;            /* Current nominal length of token buffer.  */
268 char *token_buffer;             /* Pointer to token buffer.
269                                    Actual allocated length is maxtoken + 2.  */
270
271 #include "hash.h"
272 \f
273 int check_newline ();
274
275 /* Nonzero tells yylex to ignore \ in string constants.  */
276 static int ignore_escape_flag = 0;
277
278 static int skip_white_space ();
279
280 static tree
281 get_time_identifier (name)
282      char *name;
283 {
284   tree time_identifier;
285   int len = strlen (name);
286   char *buf = (char *) alloca (len + 6);
287   strcpy (buf, "file ");
288   bcopy (name, buf+5, len);
289   buf[len+5] = '\0';
290   time_identifier = get_identifier (buf);
291   if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
292     {
293       push_obstacks_nochange ();
294       end_temporary_allocation ();
295       IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
296       IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
297       IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
298       filename_times = time_identifier;
299       pop_obstacks ();
300     }
301   return time_identifier;
302 }
303
304 #ifdef __GNUC__
305 __inline
306 #endif
307 static int
308 my_get_run_time ()
309 {
310   int old_quiet_flag = quiet_flag;
311   int this_time;
312   quiet_flag = 0;
313   this_time = get_run_time ();
314   quiet_flag = old_quiet_flag;
315   return this_time;
316 }
317 \f
318 /* Table indexed by tree code giving a string containing a character
319    classifying the tree code.  Possibilities are
320    t, d, s, c, r, <, 1 and 2.  See cp/tree.def for details.  */
321
322 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
323
324 char *cplus_tree_code_type[] = {
325   "x",
326 #include "tree.def"
327 };
328 #undef DEFTREECODE
329
330 /* Table indexed by tree code giving number of expression
331    operands beyond the fixed part of the node structure.
332    Not used for types or decls.  */
333
334 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
335
336 int cplus_tree_code_length[] = {
337   0,
338 #include "tree.def"
339 };
340 #undef DEFTREECODE
341
342 /* Names of tree components.
343    Used for printing out the tree and error messages.  */
344 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
345
346 char *cplus_tree_code_name[] = {
347   "@@dummy",
348 #include "tree.def"
349 };
350 #undef DEFTREECODE
351 \f
352 /* toplev.c needs to call these.  */
353
354 void
355 lang_init ()
356 {
357   /* the beginning of the file is a new line; check for # */
358   /* With luck, we discover the real source file's name from that
359      and put it in input_filename.  */
360   put_back (check_newline ());
361
362   if (flag_cadillac)
363     cadillac_start ();
364   if (flag_gnu_xref) GNU_xref_begin (input_filename);
365 }
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 ();
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, name, kind)
1704      tree type, 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
1716   name = constructor_name (name);
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, 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
2323 check_newline ()
2324 {
2325   register int c;
2326   register int token;
2327
2328   /* Read first nonwhite char on the line.  Do this before incrementing the
2329      line number, in case we're at the end of saved text.  */
2330
2331   do
2332     c = getch ();
2333   while (c == ' ' || c == '\t');
2334
2335   lineno++;
2336
2337   if (c != '#')
2338     {
2339       /* If not #, return it so caller will use it.  */
2340       return c;
2341     }
2342
2343   /* Read first nonwhite char after the `#'.  */
2344
2345   do
2346     c = getch ();
2347   while (c == ' ' || c == '\t');
2348
2349   /* If a letter follows, then if the word here is `line', skip
2350      it and ignore it; otherwise, ignore the line, with an error
2351      if the word isn't `pragma'.  */
2352
2353   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
2354     {
2355       if (c == 'p')
2356         {
2357           if (getch () == 'r'
2358               && getch () == 'a'
2359               && getch () == 'g'
2360               && getch () == 'm'
2361               && getch () == 'a')
2362             {
2363               /* Read first nonwhite char after the `#pragma'.  */
2364
2365               do
2366                 c = getch ();
2367               while (c == ' ' || c == '\t');
2368
2369               if (c == 'v'
2370                   && getch () == 't'
2371                   && getch () == 'a'
2372                   && getch () == 'b'
2373                   && getch () == 'l'
2374                   && getch () == 'e'
2375                   && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2376                 {
2377                   extern tree pending_vtables;
2378
2379                   /* More follows: it must be a string constant (class name).  */
2380                   token = real_yylex ();
2381                   if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2382                     {
2383                       error ("invalid #pragma vtable");
2384                       goto skipline;
2385                     }
2386                   if (write_virtuals != 2)
2387                     {
2388                       warning ("use `+e2' option to enable #pragma vtable");
2389                       goto skipline;
2390                     }
2391                   pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
2392                   if (nextchar < 0)
2393                     nextchar = getch ();
2394                   c = nextchar;
2395                   if (c != '\n')
2396                     warning ("trailing characters ignored");
2397                 }
2398               else if (c == 'u'
2399                        && getch () == 'n'
2400                        && getch () == 'i'
2401                        && getch () == 't'
2402                        && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2403                 {
2404                   /* More follows: it must be a string constant (unit name).  */
2405                   token = real_yylex ();
2406                   if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2407                     {
2408                       error ("invalid #pragma unit");
2409                       goto skipline;
2410                     }
2411                   current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
2412                   current_unit_language = current_lang_name;
2413                   if (nextchar < 0)
2414                     nextchar = getch ();
2415                   c = nextchar;
2416                   if (c != '\n')
2417                     warning ("trailing characters ignored");
2418                 }
2419               else if (c == 'i')
2420                 {
2421                   tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
2422                   c = getch ();
2423
2424                   if (c == 'n'
2425                       && getch () == 't'
2426                       && getch () == 'e'
2427                       && getch () == 'r'
2428                       && getch () == 'f'
2429                       && getch () == 'a'
2430                       && getch () == 'c'
2431                       && getch () == 'e'
2432                       && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2433                     {
2434                       int warned_already = 0;
2435                       char *main_filename = input_filename;
2436
2437                       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
2438                       while (c == ' ' || c == '\t')
2439                         c = getch ();
2440                       if (c != '\n')
2441                         {
2442                           put_back (c);
2443                           token = real_yylex ();
2444                           if (token != STRING
2445                               || TREE_CODE (yylval.ttype) != STRING_CST)
2446                             {
2447                               error ("invalid `#pragma interface'");
2448                               goto skipline;
2449                             }
2450                           main_filename = TREE_STRING_POINTER (yylval.ttype);
2451                           c = getch();
2452                           put_back (c);
2453                         }
2454
2455                       while (c == ' ' || c == '\t')
2456                         c = getch ();
2457
2458                       while (c != '\n')
2459                         {
2460                           if (!warned_already && extra_warnings
2461                               && c != ' ' && c != '\t' && c != '\n')
2462                             {
2463                               warning ("garbage after `#pragma interface' ignored");
2464                               warned_already = 1;
2465                             }
2466                           c = getch ();
2467                         }
2468
2469                       write_virtuals = 3;
2470
2471                       if (impl_file_chain == 0)
2472                         {
2473                           /* If this is zero at this point, then we are
2474                              auto-implementing.  */
2475                           if (main_input_filename == 0)
2476                             main_input_filename = input_filename;
2477
2478 #ifdef AUTO_IMPLEMENT
2479                           filename = FILE_NAME_NONDIRECTORY (main_input_filename);
2480                           fi = get_time_identifier (filename);
2481                           fi = IDENTIFIER_CLASS_VALUE (fi);
2482                           TREE_INT_CST_LOW (fi) = 0;
2483                           TREE_INT_CST_HIGH (fi) = 1;
2484                           /* Get default.  */
2485                           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
2486                           impl_file_chain->filename = filename;
2487                           impl_file_chain->next = 0;
2488 #endif
2489                         }
2490
2491                       interface_only = interface_strcmp (main_filename);
2492                       interface_unknown = 0;
2493                       TREE_INT_CST_LOW (fileinfo) = interface_only;
2494                       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
2495                     }
2496                   else if (c == 'm'
2497                            && getch () == 'p'
2498                            && getch () == 'l'
2499                            && getch () == 'e'
2500                            && getch () == 'm'
2501                            && getch () == 'e'
2502                            && getch () == 'n'
2503                            && getch () == 't'
2504                            && getch () == 'a'
2505                            && getch () == 't'
2506                            && getch () == 'i'
2507                            && getch () == 'o'
2508                            && getch () == 'n'
2509                            && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2510                     {
2511                       int warned_already = 0;
2512                       char *main_filename = main_input_filename ? main_input_filename : input_filename;
2513
2514                       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
2515                       while (c == ' ' || c == '\t')
2516                         c = getch ();
2517                       if (c != '\n')
2518                         {
2519                           put_back (c);
2520                           token = real_yylex ();
2521                           if (token != STRING
2522                               || TREE_CODE (yylval.ttype) != STRING_CST)
2523                             {
2524                               error ("invalid `#pragma implementation'");
2525                               goto skipline;
2526                             }
2527                           main_filename = TREE_STRING_POINTER (yylval.ttype);
2528                           c = getch();
2529                           put_back (c);
2530                         }
2531
2532                       while (c == ' ' || c == '\t')
2533                         c = getch ();
2534
2535                       while (c != '\n')
2536                         {
2537                           if (!warned_already && extra_warnings
2538                               && c != ' ' && c != '\t' && c != '\n')
2539                             {
2540                               warning ("garbage after `#pragma implementation' ignored");
2541                               warned_already = 1;
2542                             }
2543                           c = getch ();
2544                         }
2545
2546                       if (write_virtuals == 3)
2547                         {
2548                           struct impl_files *ifiles = impl_file_chain;
2549                           while (ifiles)
2550                             {
2551                               if (! strcmp (ifiles->filename, main_filename))
2552                                 break;
2553                               ifiles = ifiles->next;
2554                             }
2555                           if (ifiles == 0)
2556                             {
2557                               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
2558                               ifiles->filename = main_filename;
2559                               ifiles->next = impl_file_chain;
2560                               impl_file_chain = ifiles;
2561                             }
2562                         }
2563                       else if ((main_input_filename != 0
2564                                 && ! strcmp (main_input_filename, input_filename))
2565                                || ! strcmp (input_filename, main_filename))
2566                         {
2567                           write_virtuals = 3;
2568                           if (impl_file_chain == 0)
2569                             {
2570                               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
2571                               impl_file_chain->filename = main_filename;
2572                               impl_file_chain->next = 0;
2573                             }
2574                         }
2575                       else
2576                         error ("`#pragma implementation' can only appear at top-level");
2577                       interface_only = 0;
2578 #if 1
2579                       /* We make this non-zero so that we infer decl linkage
2580                          in the impl file only for variables first declared
2581                          in the interface file.  */
2582                       interface_unknown = 1;
2583 #else
2584                       /* We make this zero so that templates in the impl
2585                          file will be emitted properly. */
2586                       interface_unknown = 0;
2587 #endif
2588                       TREE_INT_CST_LOW (fileinfo) = interface_only;
2589                       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
2590                     }
2591                 }
2592 #ifdef HANDLE_SYSV_PRAGMA
2593               else
2594                 return handle_sysv_pragma (finput, c);
2595 #else
2596 #ifdef HANDLE_PRAGMA
2597               else
2598                 HANDLE_PRAGMA (finput);
2599 #endif
2600 #endif
2601             }
2602           goto skipline;
2603         }
2604       else if (c == 'd')
2605         {
2606           if (getch () == 'e'
2607               && getch () == 'f'
2608               && getch () == 'i'
2609               && getch () == 'n'
2610               && getch () == 'e'
2611               && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2612             {
2613 #ifdef DWARF_DEBUGGING_INFO
2614               if ((debug_info_level == DINFO_LEVEL_VERBOSE)
2615                   && (write_symbols == DWARF_DEBUG))
2616                 dwarfout_define (lineno, get_directive_line (finput));
2617 #endif /* DWARF_DEBUGGING_INFO */
2618               goto skipline;
2619             }
2620         }
2621       else if (c == 'u')
2622         {
2623           if (getch () == 'n'
2624               && getch () == 'd'
2625               && getch () == 'e'
2626               && getch () == 'f'
2627               && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2628             {
2629 #ifdef DWARF_DEBUGGING_INFO
2630               if ((debug_info_level == DINFO_LEVEL_VERBOSE)
2631                   && (write_symbols == DWARF_DEBUG))
2632                 dwarfout_undef (lineno, get_directive_line (finput));
2633 #endif /* DWARF_DEBUGGING_INFO */
2634               goto skipline;
2635             }
2636         }
2637       else if (c == 'l')
2638         {
2639           if (getch () == 'i'
2640               && getch () == 'n'
2641               && getch () == 'e'
2642               && ((c = getch ()) == ' ' || c == '\t'))
2643             goto linenum;
2644         }
2645       else if (c == 'i')
2646         {
2647           if (getch () == 'd'
2648               && getch () == 'e'
2649               && getch () == 'n'
2650               && getch () == 't'
2651               && ((c = getch ()) == ' ' || c == '\t'))
2652             {
2653 #ifdef ASM_OUTPUT_IDENT
2654               extern FILE *asm_out_file;
2655 #endif
2656               /* #ident.  The pedantic warning is now in cccp.c.  */
2657
2658               /* Here we have just seen `#ident '.
2659                  A string constant should follow.  */
2660
2661               while (c == ' ' || c == '\t')
2662                 c = getch ();
2663
2664               /* If no argument, ignore the line.  */
2665               if (c == '\n')
2666                 return c;
2667
2668               put_back (c);
2669               token = real_yylex ();
2670               if (token != STRING
2671                   || TREE_CODE (yylval.ttype) != STRING_CST)
2672                 {
2673                   error ("invalid #ident");
2674                   goto skipline;
2675                 }
2676
2677               if (! flag_no_ident)
2678                 {
2679 #ifdef ASM_OUTPUT_IDENT
2680                   ASM_OUTPUT_IDENT (asm_out_file,
2681                                     TREE_STRING_POINTER (yylval.ttype));
2682 #endif
2683                 }
2684
2685               /* Skip the rest of this line.  */
2686               goto skipline;
2687             }
2688         }
2689       else if (c == 'n')
2690         {
2691           if (getch () == 'e'
2692               && getch () == 'w'
2693               && getch () == 'w'
2694               && getch () == 'o'
2695               && getch () == 'r'
2696               && getch () == 'l'
2697               && getch () == 'd'
2698               && ((c = getch ()) == ' ' || c == '\t'))
2699             {
2700               /* Used to test incremental compilation.  */
2701               sorry ("#pragma newworld");
2702               goto skipline;
2703             }
2704         }
2705       error ("undefined or invalid # directive");
2706       goto skipline;
2707     }
2708
2709 linenum:
2710   /* Here we have either `#line' or `# <nonletter>'.
2711      In either case, it should be a line number; a digit should follow.  */
2712
2713   while (c == ' ' || c == '\t')
2714     c = getch ();
2715
2716   /* If the # is the only nonwhite char on the line,
2717      just ignore it.  Check the new newline.  */
2718   if (c == '\n')
2719     return c;
2720
2721   /* Something follows the #; read a token.  */
2722
2723   put_back (c);
2724   token = real_yylex ();
2725
2726   if (token == CONSTANT
2727       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2728     {
2729       int old_lineno = lineno;
2730       enum { act_none, act_push, act_pop } action = act_none;
2731       int entering_system_header = 0;
2732       int entering_c_header = 0;
2733
2734       /* subtract one, because it is the following line that
2735          gets the specified number */
2736
2737       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2738       c = get_last_nonwhite_on_line ();
2739       if (c == '\n')
2740         {
2741           /* No more: store the line number and check following line.  */
2742           lineno = l;
2743           return c;
2744         }
2745       put_back (c);
2746
2747       /* More follows: it must be a string constant (filename).  */
2748
2749       /* Read the string constant, but don't treat \ as special.  */
2750       ignore_escape_flag = 1;
2751       token = real_yylex ();
2752       ignore_escape_flag = 0;
2753
2754       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2755         {
2756           error ("invalid #line");
2757           goto skipline;
2758         }
2759
2760       /* Changing files again.  This means currently collected time
2761          is charged against header time, and body time starts back
2762          at 0.  */
2763       if (flag_detailed_statistics)
2764         {
2765           int this_time = my_get_run_time ();
2766           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2767           header_time += this_time - body_time;
2768           TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
2769             += this_time - body_time;
2770           this_filename_time = time_identifier;
2771           body_time = this_time;
2772         }
2773
2774       if (flag_cadillac)
2775         cadillac_note_source ();
2776
2777       input_filename
2778         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2779       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2780       lineno = l;
2781       GNU_xref_file (input_filename);
2782       
2783       if (main_input_filename == 0)
2784         {
2785           struct impl_files *ifiles = impl_file_chain;
2786
2787           if (ifiles)
2788             {
2789               while (ifiles->next)
2790                 ifiles = ifiles->next;
2791               ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename);
2792             }
2793
2794           main_input_filename = input_filename;
2795           if (write_virtuals == 3)
2796             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2797         }
2798
2799       extract_interface_info ();
2800
2801       c = get_last_nonwhite_on_line ();
2802       if (c != '\n')
2803         {
2804           put_back (c);
2805
2806           token = real_yylex ();
2807
2808           /* `1' after file name means entering new file.
2809              `2' after file name means just left a file.  */
2810
2811           if (token == CONSTANT
2812               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2813             {
2814               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2815                 action = act_push;
2816               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2817                 action = act_pop;
2818
2819               if (action)
2820                 {
2821                   c = get_last_nonwhite_on_line ();
2822                   if (c != '\n')
2823                     {
2824                       put_back (c);
2825                       token = real_yylex ();
2826                     }
2827                 }
2828             }
2829
2830           /* `3' after file name means this is a system header file.  */
2831
2832           if (token == CONSTANT
2833               && TREE_CODE (yylval.ttype) == INTEGER_CST
2834               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2835             {
2836               entering_system_header = 1;
2837
2838               c = get_last_nonwhite_on_line ();
2839               if (c != '\n')
2840                 {
2841                   put_back (c);
2842                   token = real_yylex ();
2843                 }
2844             }
2845
2846           /* `4' after file name means this is a C header file.  */
2847
2848           if (token == CONSTANT
2849               && TREE_CODE (yylval.ttype) == INTEGER_CST
2850               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2851             {
2852               entering_c_header = 1;
2853
2854               c = get_last_nonwhite_on_line ();
2855               if (c != '\n')
2856                 {
2857                   put_back (c);
2858                   token = real_yylex ();
2859                 }
2860             }
2861
2862           /* Do the actions implied by the preceeding numbers.  */
2863
2864           if (action == act_push)
2865             {
2866               /* Pushing to a new file.  */
2867               struct file_stack *p;
2868
2869               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2870               input_file_stack->line = old_lineno;
2871               p->next = input_file_stack;
2872               p->name = input_filename;
2873               input_file_stack = p;
2874               input_file_stack_tick++;
2875 #ifdef DWARF_DEBUGGING_INFO
2876               if (debug_info_level == DINFO_LEVEL_VERBOSE
2877                   && write_symbols == DWARF_DEBUG)
2878                 dwarfout_start_new_source_file (input_filename);
2879 #endif /* DWARF_DEBUGGING_INFO */
2880               if (flag_cadillac)
2881                 cadillac_push_source ();
2882               in_system_header = entering_system_header;
2883               if (c_header_level)
2884                 ++c_header_level;
2885               else if (entering_c_header)
2886                 {
2887                   c_header_level = 1;
2888                   ++pending_lang_change;
2889                 }
2890             }
2891           else if (action == act_pop)
2892             {
2893               /* Popping out of a file.  */
2894               if (input_file_stack->next)
2895                 {
2896                   struct file_stack *p;
2897
2898                   if (c_header_level && --c_header_level == 0)
2899                     {
2900                       if (entering_c_header)
2901                         warning ("badly nested C headers from preprocessor");
2902                       --pending_lang_change;
2903                     }
2904                   if (flag_cadillac)
2905                     cadillac_pop_source ();
2906                   in_system_header = entering_system_header;
2907
2908                   p = input_file_stack;
2909                   input_file_stack = p->next;
2910                   free (p);
2911                   input_file_stack_tick++;
2912 #ifdef DWARF_DEBUGGING_INFO
2913                   if (debug_info_level == DINFO_LEVEL_VERBOSE
2914                       && write_symbols == DWARF_DEBUG)
2915                     dwarfout_resume_previous_source_file (input_file_stack->line);
2916 #endif /* DWARF_DEBUGGING_INFO */
2917                 }
2918               else
2919                 error ("#-lines for entering and leaving files don't match");
2920             }
2921           else
2922             {
2923               in_system_header = entering_system_header;
2924               if (flag_cadillac)
2925                 cadillac_switch_source (-1);
2926             }
2927         }
2928
2929       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2930       if (nextchar == '\n')
2931         return '\n';
2932     }
2933   else
2934     error ("invalid #-line");
2935
2936   /* skip the rest of this line.  */
2937  skipline:
2938   if (c == '\n')
2939     return c;
2940   while ((c = getch ()) != EOF && c != '\n');
2941   return c;
2942 }
2943
2944 void
2945 do_pending_lang_change ()
2946 {
2947   for (; pending_lang_change > 0; --pending_lang_change)
2948     push_lang_context (lang_name_c);
2949   for (; pending_lang_change < 0; ++pending_lang_change)
2950     pop_lang_context ();
2951 }
2952 \f
2953 #if 0
2954 #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
2955 #define isdigit(char) (char >= '0' && char <= '9')
2956 #else
2957 #include <ctype.h>
2958 #endif
2959
2960 #define ENDFILE -1  /* token that represents end-of-file */
2961
2962 /* Read an escape sequence, returning its equivalent as a character,
2963    or store 1 in *ignore_ptr if it is backslash-newline.  */
2964
2965 static int
2966 readescape (ignore_ptr)
2967      int *ignore_ptr;
2968 {
2969   register int c = getch ();
2970   register int code;
2971   register unsigned count;
2972   unsigned firstdig;
2973   int nonnull;
2974
2975   switch (c)
2976     {
2977     case 'x':
2978       if (warn_traditional)
2979         warning ("the meaning of `\\x' varies with -traditional");
2980
2981       if (flag_traditional)
2982         return c;
2983
2984       code = 0;
2985       count = 0;
2986       nonnull = 0;
2987       while (1)
2988         {
2989           c = getch ();
2990           if (! isxdigit (c))
2991             {
2992               put_back (c);
2993               break;
2994             }
2995           code *= 16;
2996           if (c >= 'a' && c <= 'f')
2997             code += c - 'a' + 10;
2998           if (c >= 'A' && c <= 'F')
2999             code += c - 'A' + 10;
3000           if (c >= '0' && c <= '9')
3001             code += c - '0';
3002           if (code != 0 || count != 0)
3003             {
3004               if (count == 0)
3005                 firstdig = code;
3006               count++;
3007             }
3008           nonnull = 1;
3009         }
3010       if (! nonnull)
3011         error ("\\x used with no following hex digits");
3012       else if (count == 0)
3013         /* Digits are all 0's.  Ok.  */
3014         ;
3015       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
3016                || (count > 1
3017                    && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
3018                        <= firstdig)))
3019         pedwarn ("hex escape out of range");
3020       return code;
3021
3022     case '0':  case '1':  case '2':  case '3':  case '4':
3023     case '5':  case '6':  case '7':
3024       code = 0;
3025       count = 0;
3026       while ((c <= '7') && (c >= '0') && (count++ < 3))
3027         {
3028           code = (code * 8) + (c - '0');
3029           c = getch ();
3030         }
3031       put_back (c);
3032       return code;
3033
3034     case '\\': case '\'': case '"':
3035       return c;
3036
3037     case '\n':
3038       lineno++;
3039       *ignore_ptr = 1;
3040       return 0;
3041
3042     case 'n':
3043       return TARGET_NEWLINE;
3044
3045     case 't':
3046       return TARGET_TAB;
3047
3048     case 'r':
3049       return TARGET_CR;
3050
3051     case 'f':
3052       return TARGET_FF;
3053
3054     case 'b':
3055       return TARGET_BS;
3056
3057     case 'a':
3058       if (warn_traditional)
3059         warning ("the meaning of `\\a' varies with -traditional");
3060
3061       if (flag_traditional)
3062         return c;
3063       return TARGET_BELL;
3064
3065     case 'v':
3066       return TARGET_VT;
3067
3068     case 'e':
3069     case 'E':
3070       if (pedantic)
3071         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
3072       return 033;
3073
3074     case '?':
3075       return c;
3076
3077       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
3078     case '(':
3079     case '{':
3080     case '[':
3081       /* `\%' is used to prevent SCCS from getting confused.  */
3082     case '%':
3083       if (pedantic)
3084         pedwarn ("unknown escape sequence `\\%c'", c);
3085       return c;
3086     }
3087   if (c >= 040 && c < 0177)
3088     pedwarn ("unknown escape sequence `\\%c'", c);
3089   else
3090     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
3091   return c;
3092 }
3093
3094 /* Value is 1 (or 2) if we should try to make the next identifier look like
3095    a typename (when it may be a local variable or a class variable).
3096    Value is 0 if we treat this name in a default fashion.  */
3097 int looking_for_typename = 0;
3098
3099 #if 0
3100 /* NO LONGER USED: Value is -1 if we must not see a type name.  */
3101 void
3102 dont_see_typename ()
3103 {
3104   looking_for_typename = -1;
3105   if (yychar == TYPENAME || yychar == PTYPENAME)
3106     {
3107       yychar = IDENTIFIER;
3108       lastiddecl = 0;
3109     }
3110 }
3111 #endif
3112
3113 #ifdef __GNUC__
3114 extern __inline int identifier_type ();
3115 __inline
3116 #endif
3117 int
3118 identifier_type (decl)
3119      tree decl;
3120 {
3121   if (TREE_CODE (decl) == TEMPLATE_DECL
3122       && DECL_TEMPLATE_IS_CLASS (decl))
3123     return PTYPENAME;
3124   if (TREE_CODE (decl) != TYPE_DECL)
3125     return IDENTIFIER;
3126   return TYPENAME;
3127 }
3128
3129 void
3130 see_typename ()
3131 {
3132   looking_for_typename = 0;
3133   if (yychar == IDENTIFIER)
3134     {
3135       lastiddecl = lookup_name (yylval.ttype, -2);
3136       if (lastiddecl == 0)
3137         {
3138           if (flag_labels_ok)
3139             lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
3140         }
3141       else
3142         yychar = identifier_type (lastiddecl);
3143     }
3144 }
3145
3146 tree
3147 do_identifier (token)
3148      register tree token;
3149 {
3150   register tree id = lastiddecl;
3151
3152   if (yychar == YYEMPTY)
3153     yychar = yylex ();
3154   /* Scope class declarations before global
3155      declarations.  */
3156   if (id == IDENTIFIER_GLOBAL_VALUE (token)
3157       && current_class_type != 0
3158       && TYPE_SIZE (current_class_type) == 0
3159       && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE)
3160     {
3161       /* Could be from one of the base classes.  */
3162       tree field = lookup_field (current_class_type, token, 1, 0);
3163       if (field == 0)
3164         ;
3165       else if (field == error_mark_node)
3166         /* We have already generated the error message.
3167            But we still want to return this value.  */
3168         id = lookup_field (current_class_type, token, 0, 0);
3169       else if (TREE_CODE (field) == VAR_DECL
3170                || TREE_CODE (field) == CONST_DECL)
3171         id = field;
3172       else if (TREE_CODE (field) != FIELD_DECL)
3173         my_friendly_abort (61);
3174       else
3175         {
3176           cp_error ("invalid use of member `%D' from base class `%T'", field,
3177                       DECL_FIELD_CONTEXT (field));
3178           id = error_mark_node;
3179           return id;
3180         }
3181     }
3182
3183   /* Remember that this name has been used in the class definition, as per
3184      [class.scope0] */
3185   if (id && current_class_type
3186       && TYPE_BEING_DEFINED (current_class_type)
3187       && ! IDENTIFIER_CLASS_VALUE (token))
3188     pushdecl_class_level (id);
3189     
3190   if (!id || id == error_mark_node)
3191     {
3192       if (id == error_mark_node && current_class_type != NULL_TREE)
3193         {
3194           id = lookup_nested_field (token, 1);
3195           /* In lookup_nested_field(), we marked this so we can gracefully
3196              leave this whole mess.  */
3197           if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
3198             return id;
3199         }
3200       if (yychar == '(' || yychar == LEFT_RIGHT)
3201         {
3202           id = implicitly_declare (token);
3203         }
3204       else if (current_function_decl == 0)
3205         {
3206           cp_error ("`%D' was not declared in this scope", token);
3207           id = error_mark_node;
3208         }
3209       else
3210         {
3211           if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
3212               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
3213             {
3214               static int undeclared_variable_notice;
3215
3216               cp_error ("`%D' undeclared (first use this function)", token);
3217
3218               if (! undeclared_variable_notice)
3219                 {
3220                   error ("(Each undeclared identifier is reported only once");
3221                   error ("for each function it appears in.)");
3222                   undeclared_variable_notice = 1;
3223                 }
3224             }
3225           id = error_mark_node;
3226           /* Prevent repeated error messages.  */
3227           IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
3228           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
3229         }
3230     }
3231   /* TREE_USED is set in `hack_identifier'.  */
3232   if (TREE_CODE (id) == CONST_DECL)
3233     {
3234       if (IDENTIFIER_CLASS_VALUE (token) == id)
3235         {
3236           /* Check access.  */
3237           enum access_type access
3238             = compute_access (TYPE_BINFO (current_class_type), id);
3239           if (access == access_private)
3240             cp_error ("enum `%D' is private", id);
3241           /* protected is OK, since it's an enum of `this'.  */
3242         }
3243       id = DECL_INITIAL (id);
3244     }
3245   else
3246     id = hack_identifier (id, token, yychar);
3247   return id;
3248 }
3249
3250 tree
3251 identifier_typedecl_value (node)
3252      tree node;
3253 {
3254   tree t, type;
3255   type = IDENTIFIER_TYPE_VALUE (node);
3256   if (type == NULL_TREE)
3257     return NULL_TREE;
3258 #define do(X) \
3259   { \
3260     t = (X); \
3261     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
3262       return t; \
3263   }
3264   do (IDENTIFIER_LOCAL_VALUE (node));
3265   do (IDENTIFIER_CLASS_VALUE (node));
3266   do (IDENTIFIER_GLOBAL_VALUE (node));
3267 #undef do
3268   /* Will this one ever happen?  */
3269   if (TYPE_NAME (type))
3270     return TYPE_NAME (type);
3271
3272   /* We used to do an internal error of 62 here, but instead we will
3273      handle the return of a null appropriately in the callers.  */
3274   return NULL_TREE;
3275 }
3276
3277 struct try_type
3278 {
3279   tree *node_var;
3280   char unsigned_flag;
3281   char long_flag;
3282   char long_long_flag;
3283 };
3284
3285 struct try_type type_sequence[] = 
3286 {
3287   { &integer_type_node, 0, 0, 0},
3288   { &unsigned_type_node, 1, 0, 0},
3289   { &long_integer_type_node, 0, 1, 0},
3290   { &long_unsigned_type_node, 1, 1, 0},
3291   { &long_long_integer_type_node, 0, 1, 1},
3292   { &long_long_unsigned_type_node, 1, 1, 1}
3293 };
3294
3295 int
3296 real_yylex ()
3297 {
3298   register int c;
3299   register int value;
3300   int wide_flag = 0;
3301   int dollar_seen = 0;
3302   int i;
3303
3304   if (nextchar >= 0)
3305     c = nextchar, nextchar = -1;
3306   else
3307     c = getch ();
3308
3309   /* Effectively do c = skip_white_space (c)
3310      but do it faster in the usual cases.  */
3311   while (1)
3312     switch (c)
3313       {
3314       case ' ':
3315       case '\t':
3316       case '\f':
3317       case '\v':
3318       case '\b':
3319         c = getch ();
3320         break;
3321
3322       case '\r':
3323         /* Call skip_white_space so we can warn if appropriate.  */
3324
3325       case '\n':
3326       case '/':
3327       case '\\':
3328         c = skip_white_space (c);
3329       default:
3330         goto found_nonwhite;
3331       }
3332  found_nonwhite:
3333
3334   token_buffer[0] = c;
3335   token_buffer[1] = 0;
3336
3337 /*  yylloc.first_line = lineno; */
3338
3339   switch (c)
3340     {
3341     case EOF:
3342       token_buffer[0] = '\0';
3343       end_of_file = 1;
3344       if (input_redirected ())
3345         value = END_OF_SAVED_INPUT;
3346       else if (do_pending_expansions ())
3347         /* this will set yychar for us */
3348         return yychar;
3349       else
3350         value = ENDFILE;
3351       break;
3352
3353     case '$':
3354       if (dollars_in_ident)
3355         {
3356           dollar_seen = 1;
3357           goto letter;
3358         }
3359       value = '$';
3360       goto done;
3361
3362     case 'L':
3363       /* Capital L may start a wide-string or wide-character constant.  */
3364       {
3365         register int c = getch ();
3366         if (c == '\'')
3367           {
3368             wide_flag = 1;
3369             goto char_constant;
3370           }
3371         if (c == '"')
3372           {
3373             wide_flag = 1;
3374             goto string_constant;
3375           }
3376         put_back (c);
3377       }
3378
3379     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
3380     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
3381     case 'K':             case 'M':  case 'N':  case 'O':
3382     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
3383     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
3384     case 'Z':
3385     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
3386     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
3387     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
3388     case 'p':  case 'q':  case 'r':  case 's':  case 't':
3389     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
3390     case 'z':
3391     case '_':
3392     letter:
3393       {
3394         register char *p;
3395
3396         p = token_buffer;
3397         if (input == 0)
3398           {
3399             /* We know that `token_buffer' can hold at least on char,
3400                so we install C immediately.
3401                We may have to read the value in `putback_char', so call
3402                `getch' once.  */
3403             *p++ = c;
3404             c = getch ();
3405
3406             /* Make this run fast.  We know that we are reading straight
3407                from FINPUT in this case (since identifiers cannot straddle
3408                input sources.  */
3409             while (isalnum (c) || (c == '_') || c == '$')
3410               {
3411                 if (c == '$' && ! dollars_in_ident)
3412                   break;
3413                 if (p >= token_buffer + maxtoken)
3414                   p = extend_token_buffer (p);
3415
3416                 *p++ = c;
3417                 c = getc (finput);
3418               }
3419           }
3420         else
3421           {
3422             /* We know that `token_buffer' can hold at least on char,
3423                so we install C immediately.  */
3424             *p++ = c;
3425             c = getch ();
3426
3427             while (isalnum (c) || (c == '_') || c == '$')
3428               {
3429                 if (c == '$' && ! dollars_in_ident)
3430                   break;
3431                 if (p >= token_buffer + maxtoken)
3432                   p = extend_token_buffer (p);
3433
3434                 *p++ = c;
3435                 c = getch ();
3436               }
3437           }
3438
3439         *p = 0;
3440         nextchar = c;
3441
3442         value = IDENTIFIER;
3443         yylval.itype = 0;
3444
3445       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
3446
3447         {
3448           register struct resword *ptr;
3449
3450           if (ptr = is_reserved_word (token_buffer, p - token_buffer))
3451             {
3452               if (ptr->rid)
3453                 {
3454                   tree old_ttype = ridpointers[(int) ptr->rid];
3455
3456                   /* If this provides a type for us, then revert lexical
3457                      state to standard state.  */
3458                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
3459                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
3460                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
3461                     looking_for_typename = 0;
3462                   else if (ptr->token == AGGR || ptr->token == ENUM)
3463                     looking_for_typename = 1;
3464
3465                   /* Check if this is a language-type declaration.
3466                      Just glimpse the next non-white character.  */
3467                   nextchar = skip_white_space (nextchar);
3468                   if (nextchar == '"')
3469                     {
3470                       /* We are looking at a string.  Complain
3471                          if the token before the string is no `extern'.
3472                          
3473                          Could cheat some memory by placing this string
3474                          on the temporary_, instead of the saveable_
3475                          obstack.  */
3476
3477                       if (ptr->rid != RID_EXTERN)
3478                         error ("invalid modifier `%s' for language string",
3479                                ptr->name);
3480                       real_yylex ();
3481                       value = EXTERN_LANG_STRING;
3482                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
3483                       break;
3484                     }
3485                   if (ptr->token == VISSPEC)
3486                     {
3487                       switch (ptr->rid)
3488                         {
3489                         case RID_PUBLIC:
3490                           yylval.itype = access_public;
3491                           break;
3492                         case RID_PRIVATE:
3493                           yylval.itype = access_private;
3494                           break;
3495                         case RID_PROTECTED:
3496                           yylval.itype = access_protected;
3497                           break;
3498                         default:
3499                           my_friendly_abort (63);
3500                         }
3501                     }
3502                   else
3503                     yylval.ttype = old_ttype;
3504                 }
3505               else if (ptr->token == EQCOMPARE)
3506                 {
3507                   yylval.code = NE_EXPR;
3508                   token_buffer[0] = '!';
3509                   token_buffer[1] = '=';
3510                   token_buffer[2] = 0;
3511                 }
3512               else if (ptr->token == ASSIGN)
3513                 {
3514                   if (strcmp ("and_eq", token_buffer) == 0)
3515                     {
3516                       yylval.code = BIT_AND_EXPR;
3517                       token_buffer[0] = '&';
3518                     }
3519                   else if (strcmp ("or_eq", token_buffer) == 0)
3520                     {
3521                       yylval.code = BIT_IOR_EXPR;
3522                       token_buffer[0] = '|';
3523                     }
3524                   else if (strcmp ("xor_eq", token_buffer) == 0)
3525                     {
3526                       yylval.code = BIT_XOR_EXPR;
3527                       token_buffer[0] = '^';
3528                     }
3529                   token_buffer[1] = '=';
3530                   token_buffer[2] = 0;
3531                 }
3532               else if (ptr->token == '&')
3533                 {
3534                   yylval.code = BIT_AND_EXPR;
3535                   token_buffer[0] = '&';
3536                   token_buffer[1] = 0;
3537                 }
3538               else if (ptr->token == '|')
3539                 {
3540                   yylval.code = BIT_IOR_EXPR;
3541                   token_buffer[0] = '|';
3542                   token_buffer[1] = 0;
3543                 }
3544               else if (ptr->token == '^')
3545                 {
3546                   yylval.code = BIT_XOR_EXPR;
3547                   token_buffer[0] = '^';
3548                   token_buffer[1] = 0;
3549                 }
3550
3551               value = (int) ptr->token;
3552             }
3553         }
3554
3555         /* If we did not find a keyword, look for an identifier
3556            (or a typename).  */
3557
3558         if (strcmp ("catch", token_buffer) == 0
3559             || strcmp ("throw", token_buffer) == 0
3560             || strcmp ("try", token_buffer) == 0)
3561           {
3562             static int did_warn = 0;
3563             if (! did_warn  && ! flag_handle_exceptions)
3564               {
3565                 pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
3566                 did_warn = 1;
3567               }
3568           }
3569
3570         if (value == IDENTIFIER || value == TYPESPEC)
3571           GNU_xref_ref (current_function_decl, token_buffer);
3572
3573         if (value == IDENTIFIER)
3574           {
3575             register tree tmp = get_identifier (token_buffer);
3576
3577 #if !defined(VMS) && defined(JOINER)
3578             /* Make sure that user does not collide with our internal
3579                naming scheme.  */
3580             if (JOINER == '$'
3581                 && dollar_seen
3582                 && (THIS_NAME_P (tmp)
3583                     || VPTR_NAME_P (tmp)
3584                     || DESTRUCTOR_NAME_P (tmp)
3585                     || VTABLE_NAME_P (tmp)
3586                     || TEMP_NAME_P (tmp)
3587                     || ANON_AGGRNAME_P (tmp)
3588                     || ANON_PARMNAME_P (tmp)))
3589               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3590                        token_buffer);
3591 #endif
3592
3593             yylval.ttype = tmp;
3594
3595             /* A user-invisible read-only initialized variable
3596                should be replaced by its value.  We only handle strings
3597                since that's the only case used in C (and C++).  */
3598             /* Note we go right after the local value for the identifier
3599                (e.g., __FUNCTION__ or __PRETTY_FUNCTION__).  We used to
3600                call lookup_name, but that could result in an error about
3601                ambiguities.  */
3602             tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype);
3603             if (tmp != NULL_TREE
3604                 && TREE_CODE (tmp) == VAR_DECL
3605                 && DECL_IGNORED_P (tmp)
3606                 && TREE_READONLY (tmp)
3607                 && DECL_INITIAL (tmp) != NULL_TREE
3608                 && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
3609               {
3610                 yylval.ttype = DECL_INITIAL (tmp);
3611                 value = STRING;
3612               }
3613           }
3614         if (value == NEW && ! global_bindings_p ())
3615           {
3616             value = NEW;
3617             goto done;
3618           }
3619       }
3620       break;
3621
3622     case '.':
3623       {
3624         register int c1 = getch ();
3625         token_buffer[0] = c;
3626         token_buffer[1] = c1;
3627         if (c1 == '*')
3628           {
3629             value = DOT_STAR;
3630             token_buffer[2] = 0;
3631             goto done;
3632           }
3633         if (c1 == '.')
3634           {
3635             c1 = getch ();
3636             if (c1 == '.')
3637               {
3638                 token_buffer[2] = c1;
3639                 token_buffer[3] = 0;
3640                 value = ELLIPSIS;
3641                 goto done;
3642               }
3643             error ("parse error at `..'");
3644           }
3645         if (isdigit (c1))
3646           {
3647             put_back (c1);
3648             goto resume_numerical_scan;
3649           }
3650         nextchar = c1;
3651         value = '.';
3652         token_buffer[1] = 0;
3653         goto done;
3654       }
3655     case '0':  case '1':
3656         /* Optimize for most frequent case.  */
3657       {
3658         register int c1 = getch ();
3659         if (! isalnum (c1) && c1 != '.')
3660           {
3661             /* Terminate string.  */
3662             token_buffer[0] = c;
3663             token_buffer[1] = 0;
3664             if (c == '0')
3665               yylval.ttype = integer_zero_node;
3666             else
3667               yylval.ttype = integer_one_node;
3668             nextchar = c1;
3669             value = CONSTANT;
3670             goto done;
3671           }
3672         put_back (c1);
3673       }
3674       /* fall through... */
3675                           case '2':  case '3':  case '4':
3676     case '5':  case '6':  case '7':  case '8':  case '9':
3677     resume_numerical_scan:
3678       {
3679         register char *p;
3680         int base = 10;
3681         int count = 0;
3682         int largest_digit = 0;
3683         int numdigits = 0;
3684         /* for multi-precision arithmetic,
3685            we actually store only HOST_BITS_PER_CHAR bits in each part.
3686            The number of parts is chosen so as to be sufficient to hold
3687            the enough bits to fit into the two HOST_WIDE_INTs that contain
3688            the integer value (this is always at least as many bits as are
3689            in a target `long long' value, but may be wider).  */
3690 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3691         int parts[TOTAL_PARTS];
3692         int overflow = 0;
3693
3694         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3695           = NOT_FLOAT;
3696
3697         p = token_buffer;
3698         *p++ = c;
3699
3700         for (count = 0; count < TOTAL_PARTS; count++)
3701           parts[count] = 0;
3702
3703         if (c == '0')
3704           {
3705             *p++ = (c = getch ());
3706             if ((c == 'x') || (c == 'X'))
3707               {
3708                 base = 16;
3709                 *p++ = (c = getch ());
3710               }
3711             /* Leading 0 forces octal unless the 0 is the only digit.  */
3712             else if (c >= '0' && c <= '9')
3713               {
3714                 base = 8;
3715                 numdigits++;
3716               }
3717             else
3718               numdigits++;
3719           }
3720
3721         /* Read all the digits-and-decimal-points.  */
3722
3723         while (c == '.'
3724                || (isalnum (c) && (c != 'l') && (c != 'L')
3725                    && (c != 'u') && (c != 'U')
3726                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3727           {
3728             if (c == '.')
3729               {
3730                 if (base == 16)
3731                   error ("floating constant may not be in radix 16");
3732                 if (floatflag == AFTER_POINT)
3733                   {
3734                     error ("malformed floating constant");
3735                     floatflag = TOO_MANY_POINTS;
3736                   }
3737                 else
3738                   floatflag = AFTER_POINT;
3739
3740                 base = 10;
3741                 *p++ = c = getch ();
3742                 /* Accept '.' as the start of a floating-point number
3743                    only when it is followed by a digit.
3744                    Otherwise, unread the following non-digit
3745                    and use the '.' as a structural token.  */
3746                 if (p == token_buffer + 2 && !isdigit (c))
3747                   {
3748                     if (c == '.')
3749                       {
3750                         c = getch ();
3751                         if (c == '.')
3752                           {
3753                             *p++ = '.';
3754                             *p = '\0';
3755                             value = ELLIPSIS;
3756                             goto done;
3757                           }
3758                         error ("parse error at `..'");
3759                       }
3760                     nextchar = c;
3761                     token_buffer[1] = '\0';
3762                     value = '.';
3763                     goto done;
3764                   }
3765               }
3766             else
3767               {
3768                 /* It is not a decimal point.
3769                    It should be a digit (perhaps a hex digit).  */
3770
3771                 if (isdigit (c))
3772                   {
3773                     c = c - '0';
3774                   }
3775                 else if (base <= 10)
3776                   {
3777                     if (c == 'e' || c == 'E')
3778                       {
3779                         base = 10;
3780                         floatflag = AFTER_POINT;
3781                         break;   /* start of exponent */
3782                       }
3783                     error ("nondigits in number and not hexadecimal");
3784                     c = 0;
3785                   }
3786                 else if (c >= 'a')
3787                   {
3788                     c = c - 'a' + 10;
3789                   }
3790                 else
3791                   {
3792                     c = c - 'A' + 10;
3793                   }
3794                 if (c >= largest_digit)
3795                   largest_digit = c;
3796                 numdigits++;
3797
3798                 for (count = 0; count < TOTAL_PARTS; count++)
3799                   {
3800                     parts[count] *= base;
3801                     if (count)
3802                       {
3803                         parts[count]
3804                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3805                         parts[count-1]
3806                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3807                       }
3808                     else
3809                       parts[0] += c;
3810                   }
3811
3812                 /* If the extra highest-order part ever gets anything in it,
3813                    the number is certainly too big.  */
3814                 if (parts[TOTAL_PARTS - 1] != 0)
3815                   overflow = 1;
3816
3817                 if (p >= token_buffer + maxtoken - 3)
3818                   p = extend_token_buffer (p);
3819                 *p++ = (c = getch ());
3820               }
3821           }
3822
3823         if (numdigits == 0)
3824           error ("numeric constant with no digits");
3825
3826         if (largest_digit >= base)
3827           error ("numeric constant contains digits beyond the radix");
3828
3829         /* Remove terminating char from the token buffer and delimit the string */
3830         *--p = 0;
3831
3832         if (floatflag != NOT_FLOAT)
3833           {
3834             tree type = double_type_node;
3835             char f_seen = 0;
3836             char l_seen = 0;
3837             int garbage_chars = 0;
3838             REAL_VALUE_TYPE value;
3839             jmp_buf handler;
3840
3841             /* Read explicit exponent if any, and put it in tokenbuf.  */
3842
3843             if ((c == 'e') || (c == 'E'))
3844               {
3845                 if (p >= token_buffer + maxtoken - 3)
3846                   p = extend_token_buffer (p);
3847                 *p++ = c;
3848                 c = getch ();
3849                 if ((c == '+') || (c == '-'))
3850                   {
3851                     *p++ = c;
3852                     c = getch ();
3853                   }
3854                 if (! isdigit (c))
3855                   error ("floating constant exponent has no digits");
3856                 while (isdigit (c))
3857                   {
3858                     if (p >= token_buffer + maxtoken - 3)
3859                       p = extend_token_buffer (p);
3860                     *p++ = c;
3861                     c = getch ();
3862                   }
3863               }
3864
3865             *p = 0;
3866             errno = 0;
3867
3868             /* Convert string to a double, checking for overflow.  */
3869             if (setjmp (handler))
3870               {
3871                 error ("floating constant out of range");
3872                 value = dconst0;
3873               }
3874             else
3875               {
3876                 set_float_handler (handler);
3877                 /*  The second argument, machine_mode, of REAL_VALUE_ATOF
3878                     tells the desired precision of the binary result of
3879                     decimal-to-binary conversion. */
3880
3881                 /* Read the suffixes to choose a data type.  */
3882                 switch (c)
3883                   {
3884                   case 'f': case 'F':
3885                     type = float_type_node;
3886                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3887                     garbage_chars = -1;
3888                     break;
3889
3890                   case 'l': case 'L':
3891                     type = long_double_type_node;
3892                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3893                     garbage_chars = -1;
3894                     break;
3895
3896                   default:
3897                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3898                   }
3899                 set_float_handler (NULL_PTR);
3900               }
3901             if (pedantic
3902                 && (REAL_VALUE_ISINF (value)
3903 #ifdef ERANGE
3904                     || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3905                         && errno == ERANGE
3906                         /* ERANGE is also reported for underflow, so test the
3907                            value to distinguish overflow from that.  */
3908                         && (REAL_VALUES_LESS (dconst1, value)
3909                             || REAL_VALUES_LESS (value, dconstm1)))
3910 #endif
3911                     ))
3912               {
3913                 pedwarn ("floating point number exceeds range of `%s'",
3914                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
3915               }
3916             /* Note: garbage_chars is -1 if first char is *not* garbage.  */
3917             while (isalnum (c))
3918               {
3919                 if (c == 'f' || c == 'F')
3920                   {
3921                     if (f_seen)
3922                       error ("two `f's in floating constant");
3923                     f_seen = 1;
3924                   }
3925                 if (c == 'l' || c == 'L')
3926                   {
3927                     if (l_seen)
3928                       error ("two `l's in floating constant");
3929                     l_seen = 1;
3930                   }
3931                 if (p >= token_buffer + maxtoken - 3)
3932                   p = extend_token_buffer (p);
3933                 *p++ = c;
3934                 c = getch ();
3935                 garbage_chars++;
3936               }
3937
3938             if (garbage_chars > 0)
3939               error ("garbage at end of number");
3940
3941             /* Create a node with determined type and value.  */
3942             yylval.ttype = build_real (type, value);
3943
3944             put_back (c);
3945             *p = 0;
3946           }
3947         else
3948           {
3949             tree type;
3950             HOST_WIDE_INT high, low;
3951             int spec_unsigned = 0;
3952             int spec_long = 0;
3953             int spec_long_long = 0;
3954             int bytes, warn;
3955
3956             while (1)
3957               {
3958                 if (c == 'u' || c == 'U')
3959                   {
3960                     if (spec_unsigned)
3961                       error ("two `u's in integer constant");
3962                     spec_unsigned = 1;
3963                   }
3964                 else if (c == 'l' || c == 'L')
3965                   {
3966                     if (spec_long)
3967                       {
3968                         if (spec_long_long)
3969                           error ("three `l's in integer constant");
3970                         else if (pedantic)
3971                           pedwarn ("ANSI C++ forbids long long integer constants");
3972                         spec_long_long = 1;
3973                       }
3974                     spec_long = 1;
3975                   }
3976                 else
3977                   {
3978                     if (isalnum (c))
3979                       {
3980                         error ("garbage at end of number");
3981                         while (isalnum (c))
3982                           {
3983                             if (p >= token_buffer + maxtoken - 3)
3984                               p = extend_token_buffer (p);
3985                             *p++ = c;
3986                             c = getch ();
3987                           }
3988                       }
3989                     break;
3990                   }
3991                 if (p >= token_buffer + maxtoken - 3)
3992                   p = extend_token_buffer (p);
3993                 *p++ = c;
3994                 c = getch ();
3995               }
3996
3997             put_back (c);
3998
3999             /* If the constant is not long long and it won't fit in an
4000                unsigned long, or if the constant is long long and won't fit
4001                in an unsigned long long, then warn that the constant is out
4002                of range.  */
4003
4004             /* ??? This assumes that long long and long integer types are
4005                a multiple of 8 bits.  This better than the original code
4006                though which assumed that long was exactly 32 bits and long
4007                long was exactly 64 bits.  */
4008
4009             if (spec_long_long)
4010               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
4011             else
4012               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
4013
4014             warn = overflow;
4015             for (i = bytes; i < TOTAL_PARTS; i++)
4016               if (parts[i])
4017                 warn = 1;
4018             if (warn)
4019               pedwarn ("integer constant out of range");
4020
4021             /* This is simplified by the fact that our constant
4022                is always positive.  */
4023             high = low = 0;
4024
4025             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
4026               {
4027                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
4028                                                     / HOST_BITS_PER_CHAR)]
4029                          << (i * HOST_BITS_PER_CHAR));
4030                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
4031               }
4032             
4033             
4034             yylval.ttype = build_int_2 (low, high);
4035             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
4036
4037 #if 0
4038             /* Find the first allowable type that the value fits in.  */
4039             type = 0;
4040             for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
4041                  i++)
4042               if (!(spec_long && !type_sequence[i].long_flag)
4043                   && !(spec_long_long && !type_sequence[i].long_long_flag)
4044                   && !(spec_unsigned && !type_sequence[i].unsigned_flag)
4045                   /* A hex or octal constant traditionally is unsigned.  */
4046                   && !(base != 10 && flag_traditional
4047                        && !type_sequence[i].unsigned_flag)
4048                   /* A decimal constant can't be unsigned int
4049                      unless explicitly specified.  */
4050                   && !(base == 10 && !spec_unsigned
4051                        && *type_sequence[i].node_var == unsigned_type_node))
4052                 if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
4053                   {
4054                     type = *type_sequence[i].node_var;
4055                     break;
4056                   }
4057             if (flag_traditional && type == long_unsigned_type_node
4058                 && !spec_unsigned)
4059               type = long_integer_type_node;
4060               
4061             if (type == 0)
4062               {
4063                 type = long_long_integer_type_node;
4064                 warning ("integer constant out of range");
4065               }
4066
4067             /* Warn about some cases where the type of a given constant
4068                changes from traditional C to ANSI C.  */
4069             if (warn_traditional)
4070               {
4071                 tree other_type = 0;
4072
4073                 /* This computation is the same as the previous one
4074                    except that flag_traditional is used backwards.  */
4075                 for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
4076                      i++)
4077                   if (!(spec_long && !type_sequence[i].long_flag)
4078                       && !(spec_long_long && !type_sequence[i].long_long_flag)
4079                       && !(spec_unsigned && !type_sequence[i].unsigned_flag)
4080                       /* A hex or octal constant traditionally is unsigned.  */
4081                       && !(base != 10 && !flag_traditional
4082                            && !type_sequence[i].unsigned_flag)
4083                       /* A decimal constant can't be unsigned int
4084                          unless explicitly specified.  */
4085                       && !(base == 10 && !spec_unsigned
4086                            && *type_sequence[i].node_var == unsigned_type_node))
4087                     if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
4088                       {
4089                         other_type = *type_sequence[i].node_var;
4090                         break;
4091                       }
4092                 if (!flag_traditional && type == long_unsigned_type_node
4093                     && !spec_unsigned)
4094                   type = long_integer_type_node;
4095               
4096                 if (other_type != 0 && other_type != type)
4097                   {
4098                     if (flag_traditional)
4099                       warning ("type of integer constant would be different without -traditional");
4100                     else
4101                       warning ("type of integer constant would be different with -traditional");
4102                   }
4103               }
4104
4105 #else /* 1 */
4106             if (!spec_long && !spec_unsigned
4107                 && !(flag_traditional && base != 10)
4108                 && int_fits_type_p (yylval.ttype, integer_type_node))
4109               {
4110 #if 0
4111                 if (warn_traditional && base != 10)
4112                   warning ("small nondecimal constant becomes signed in ANSI C++");
4113 #endif
4114                 type = integer_type_node;
4115               }
4116             else if (!spec_long && (base != 10 || spec_unsigned)
4117                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
4118               {
4119                 /* Nondecimal constants try unsigned even in traditional C.  */
4120                 type = unsigned_type_node;
4121               }
4122
4123             else if (!spec_unsigned && !spec_long_long
4124                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
4125               type = long_integer_type_node;
4126
4127             else if (! spec_long_long
4128                      && int_fits_type_p (yylval.ttype,
4129                                          long_unsigned_type_node))
4130               {
4131 #if 0
4132                 if (warn_traditional && !spec_unsigned)
4133                   warning ("large integer constant becomes unsigned in ANSI C++");
4134 #endif
4135                 if (flag_traditional && !spec_unsigned)
4136                   type = long_integer_type_node;
4137                 else
4138                   type = long_unsigned_type_node;
4139               }
4140
4141             else if (! spec_unsigned
4142                      /* Verify value does not overflow into sign bit.  */
4143                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
4144                      && int_fits_type_p (yylval.ttype,
4145                                          long_long_integer_type_node))
4146               type = long_long_integer_type_node;
4147
4148             else if (int_fits_type_p (yylval.ttype,
4149                                       long_long_unsigned_type_node))
4150               {
4151 #if 0
4152                 if (warn_traditional && !spec_unsigned)
4153                   warning ("large nondecimal constant is unsigned in ANSI C++");
4154 #endif
4155
4156                 if (flag_traditional && !spec_unsigned)
4157                   type = long_long_integer_type_node;
4158                 else
4159                   type = long_long_unsigned_type_node;
4160               }
4161
4162             else
4163               {
4164                 type = long_long_integer_type_node;
4165                 warning ("integer constant out of range");
4166
4167                 if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
4168                   warning ("decimal integer constant is so large that it is unsigned");
4169               }
4170 #endif
4171
4172             TREE_TYPE (yylval.ttype) = type;
4173             *p = 0;
4174           }
4175
4176         value = CONSTANT; break;
4177       }
4178
4179     case '\'':
4180     char_constant:
4181       {
4182         register int result = 0;
4183         register int num_chars = 0;
4184         unsigned width = TYPE_PRECISION (char_type_node);
4185         int max_chars;
4186
4187         if (wide_flag)
4188           {
4189             width = WCHAR_TYPE_SIZE;
4190 #ifdef MULTIBYTE_CHARS
4191             max_chars = MB_CUR_MAX;
4192 #else
4193             max_chars = 1;
4194 #endif
4195           }
4196         else
4197           max_chars = TYPE_PRECISION (integer_type_node) / width;
4198
4199         while (1)
4200           {
4201           tryagain:
4202
4203             c = getch ();
4204
4205             if (c == '\'' || c == EOF)
4206               break;
4207
4208             if (c == '\\')
4209               {
4210                 int ignore = 0;
4211                 c = readescape (&ignore);
4212                 if (ignore)
4213                   goto tryagain;
4214                 if (width < HOST_BITS_PER_INT
4215                     && (unsigned) c >= (1 << width))
4216                   warning ("escape sequence out of range for character");
4217 #ifdef MAP_CHARACTER
4218                 if (isprint (c))
4219                   c = MAP_CHARACTER (c);
4220 #endif
4221               }
4222             else if (c == '\n')
4223               {
4224                 if (pedantic)
4225                   pedwarn ("ANSI C++ forbids newline in character constant");
4226                 lineno++;
4227               }
4228 #ifdef MAP_CHARACTER
4229             else
4230               c = MAP_CHARACTER (c);
4231 #endif
4232
4233             num_chars++;
4234             if (num_chars > maxtoken - 4)
4235               extend_token_buffer (token_buffer);
4236
4237             token_buffer[num_chars] = c;
4238
4239             /* Merge character into result; ignore excess chars.  */
4240             if (num_chars < max_chars + 1)
4241               {
4242                 if (width < HOST_BITS_PER_INT)
4243                   result = (result << width) | (c & ((1 << width) - 1));
4244                 else
4245                   result = c;
4246               }
4247           }
4248
4249         token_buffer[num_chars + 1] = '\'';
4250         token_buffer[num_chars + 2] = 0;
4251
4252         if (c != '\'')
4253           error ("malformatted character constant");
4254         else if (num_chars == 0)
4255           error ("empty character constant");
4256         else if (num_chars > max_chars)
4257           {
4258             num_chars = max_chars;
4259             error ("character constant too long");
4260           }
4261         else if (num_chars != 1 && ! flag_traditional)
4262           warning ("multi-character character constant");
4263
4264         /* If char type is signed, sign-extend the constant.  */
4265         if (! wide_flag)
4266           {
4267             int num_bits = num_chars * width;
4268             if (num_bits == 0)
4269               /* We already got an error; avoid invalid shift.  */
4270               yylval.ttype = build_int_2 (0, 0);
4271             else if (TREE_UNSIGNED (char_type_node)
4272                      || ((result >> (num_bits - 1)) & 1) == 0)
4273               yylval.ttype
4274                 = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
4275                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4276                                0);
4277             else
4278               yylval.ttype
4279                 = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
4280                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4281                                -1);
4282             if (num_chars<=1)
4283               TREE_TYPE (yylval.ttype) = char_type_node;
4284             else
4285               TREE_TYPE (yylval.ttype) = integer_type_node;
4286           }
4287         else
4288           {
4289 #ifdef MULTIBYTE_CHARS
4290             /* Set the initial shift state and convert the next sequence.  */
4291             result = 0;
4292             /* In all locales L'\0' is zero and mbtowc will return zero,
4293                so don't use it.  */
4294             if (num_chars > 1
4295                 || (num_chars == 1 && token_buffer[1] != '\0'))
4296               {
4297                 wchar_t wc;
4298                 (void) mbtowc (NULL, NULL, 0);
4299                 if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
4300                   result = wc;
4301                 else
4302                   warning ("Ignoring invalid multibyte character");
4303               }
4304 #endif
4305             yylval.ttype = build_int_2 (result, 0);
4306             TREE_TYPE (yylval.ttype) = wchar_type_node;
4307           }
4308
4309         value = CONSTANT;
4310         break;
4311       }
4312
4313     case '"':
4314     string_constant:
4315       {
4316         register char *p;
4317
4318         c = getch ();
4319         p = token_buffer + 1;
4320
4321         while (c != '"' && c >= 0)
4322           {
4323             /* ignore_escape_flag is set for reading the filename in #line.  */
4324             if (!ignore_escape_flag && c == '\\')
4325               {
4326                 int ignore = 0;
4327                 c = readescape (&ignore);
4328                 if (ignore)
4329                   goto skipnewline;
4330                 if (!wide_flag
4331                     && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
4332                     && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node)))
4333                   warning ("escape sequence out of range for character");
4334               }
4335             else if (c == '\n')
4336               {
4337                 if (pedantic)
4338                   pedwarn ("ANSI C++ forbids newline in string constant");
4339                 lineno++;
4340               }
4341
4342             if (p == token_buffer + maxtoken)
4343               p = extend_token_buffer (p);
4344             *p++ = c;
4345
4346           skipnewline:
4347             c = getch ();
4348             if (c == EOF) {
4349                 error("Unterminated string");
4350                 break;
4351             }
4352           }
4353         *p = 0;
4354
4355         /* We have read the entire constant.
4356            Construct a STRING_CST for the result.  */
4357
4358         if (wide_flag)
4359           {
4360             /* If this is a L"..." wide-string, convert the multibyte string
4361                to a wide character string.  */
4362             char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
4363             int len;
4364
4365 #ifdef MULTIBYTE_CHARS
4366             len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
4367             if (len < 0 || len >= (p - token_buffer))
4368               {
4369                 warning ("Ignoring invalid multibyte string");
4370                 len = 0;
4371               }
4372             bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
4373 #else
4374             {
4375               union { long l; char c[sizeof (long)]; } u;
4376               int big_endian;
4377               char *wp, *cp;
4378
4379               /* Determine whether host is little or big endian.  */
4380               u.l = 1;
4381               big_endian = u.c[sizeof (long) - 1];
4382               wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
4383
4384               bzero (widep, (p - token_buffer) * WCHAR_BYTES);
4385               for (cp = token_buffer + 1; cp < p; cp++)
4386                 *wp = *cp, wp += WCHAR_BYTES;
4387               len = p - token_buffer - 1;
4388             }
4389 #endif
4390             yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
4391             TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4392           }
4393         else
4394           {
4395             yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
4396             TREE_TYPE (yylval.ttype) = char_array_type_node;
4397           }
4398
4399         *p++ = '"';
4400         *p = 0;
4401
4402         value = STRING; break;
4403       }
4404
4405     case '+':
4406     case '-':
4407     case '&':
4408     case '|':
4409     case '<':
4410     case '>':
4411     case '*':
4412     case '/':
4413     case '%':
4414     case '^':
4415     case '!':
4416     case '=':
4417       {
4418         register int c1;
4419
4420       combine:
4421
4422         switch (c)
4423           {
4424           case '+':
4425             yylval.code = PLUS_EXPR; break;
4426           case '-':
4427             yylval.code = MINUS_EXPR; break;
4428           case '&':
4429             yylval.code = BIT_AND_EXPR; break;
4430           case '|':
4431             yylval.code = BIT_IOR_EXPR; break;
4432           case '*':
4433             yylval.code = MULT_EXPR; break;
4434           case '/':
4435             yylval.code = TRUNC_DIV_EXPR; break;
4436           case '%':
4437             yylval.code = TRUNC_MOD_EXPR; break;
4438           case '^':
4439             yylval.code = BIT_XOR_EXPR; break;
4440           case LSHIFT:
4441             yylval.code = LSHIFT_EXPR; break;
4442           case RSHIFT:
4443             yylval.code = RSHIFT_EXPR; break;
4444           case '<':
4445             yylval.code = LT_EXPR; break;
4446           case '>':
4447             yylval.code = GT_EXPR; break;
4448           }
4449
4450         token_buffer[1] = c1 = getch ();
4451         token_buffer[2] = 0;
4452
4453         if (c1 == '=')
4454           {
4455             switch (c)
4456               {
4457               case '<':
4458                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4459               case '>':
4460                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4461               case '!':
4462                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4463               case '=':
4464                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4465               }
4466             value = ASSIGN; goto done;
4467           }
4468         else if (c == c1)
4469           switch (c)
4470             {
4471             case '+':
4472               value = PLUSPLUS; goto done;
4473             case '-':
4474               value = MINUSMINUS; goto done;
4475             case '&':
4476               value = ANDAND; goto done;
4477             case '|':
4478               value = OROR; goto done;
4479             case '<':
4480               c = LSHIFT;
4481               goto combine;
4482             case '>':
4483               c = RSHIFT;
4484               goto combine;
4485             }
4486         else if ((c == '-') && (c1 == '>'))
4487           {
4488             nextchar = getch ();
4489             if (nextchar == '*')
4490               {
4491                 nextchar = -1;
4492                 value = POINTSAT_STAR;
4493               }
4494             else
4495               value = POINTSAT;
4496             goto done;
4497           }
4498         else if (c1 == '?' && (c == '<' || c == '>'))
4499           {
4500             token_buffer[3] = 0;
4501
4502             c1 = getch ();
4503             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4504             if (c1 == '=')
4505               {
4506                 /* <?= or >?= expression.  */
4507                 token_buffer[2] = c1;
4508                 value = ASSIGN;
4509               }
4510             else
4511               {
4512                 value = MIN_MAX;
4513                 nextchar = c1;
4514               }
4515             if (pedantic)
4516               pedwarn ("use of `operator %s' is not standard C++",
4517                        token_buffer);
4518             goto done;
4519           }
4520         /* digraphs */
4521         else if (c == '<' && c1 == '%')
4522           { value = '{'; goto done; }
4523         else if (c == '<' && c1 == ':')
4524           { value = '['; goto done; }
4525         else if (c == '%' && c1 == '>')
4526           { value = '}'; goto done; }
4527         else if (c == '%' && c1 == ':')
4528           { value = '#'; goto done; }
4529         else if (c == ':' && c1 == '>')
4530           { value = ']'; goto done; }
4531
4532         nextchar = c1;
4533         token_buffer[1] = 0;
4534
4535         value = c;
4536         goto done;
4537       }
4538
4539     case ':':
4540       c = getch ();
4541       if (c == ':')
4542         {
4543           token_buffer[1] = ':';
4544           token_buffer[2] = '\0';
4545           value = SCOPE;
4546           yylval.itype = 1;
4547         }
4548       else
4549         {
4550           nextchar = c;
4551           value = ':';
4552         }
4553       break;
4554
4555     case 0:
4556       /* Don't make yyparse think this is eof.  */
4557       value = 1;
4558       break;
4559
4560     case '(':
4561       /* try, weakly, to handle casts to pointers to functions.  */
4562       nextchar = skip_white_space (getch ());
4563       if (nextchar == '*')
4564         {
4565           int next_c = skip_white_space (getch ());
4566           if (next_c == ')')
4567             {
4568               nextchar = -1;
4569               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4570               value = PAREN_STAR_PAREN;
4571             }
4572           else
4573             {
4574               put_back (next_c);
4575               value = c;
4576             }
4577         }
4578       else if (nextchar == ')')
4579         {
4580           nextchar = -1;
4581           yylval.ttype = NULL_TREE;
4582           value = LEFT_RIGHT;
4583         }
4584       else value = c;
4585       break;
4586
4587     default:
4588       value = c;
4589     }
4590
4591 done:
4592 /*  yylloc.last_line = lineno; */
4593 #ifdef GATHER_STATISTICS
4594   token_count[value] += 1;
4595 #endif
4596
4597   return value;
4598 }
4599
4600 typedef enum
4601 {
4602   d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
4603   id_kind, op_id_kind, perm_list_kind, temp_list_kind,
4604   vec_kind, x_kind, lang_decl, lang_type, all_kinds
4605 } tree_node_kind;
4606 extern int tree_node_counts[];
4607 extern int tree_node_sizes[];
4608 extern char *tree_node_kind_names[];
4609
4610 /* Place to save freed lang_decls which were allocated on the
4611    permanent_obstack.  @@ Not currently used.  */
4612 tree free_lang_decl_chain;
4613
4614 tree
4615 build_lang_decl (code, name, type)
4616      enum tree_code code;
4617      tree name;
4618      tree type;
4619 {
4620   register tree t = build_decl (code, name, type);
4621   struct obstack *obstack = current_obstack;
4622   register int i = sizeof (struct lang_decl) / sizeof (int);
4623   register int *pi;
4624
4625   if (! TREE_PERMANENT (t))
4626     obstack = saveable_obstack;
4627   else
4628     /* Could be that saveable is permanent and current is not.  */
4629     obstack = &permanent_obstack;
4630
4631   if (free_lang_decl_chain && obstack == &permanent_obstack)
4632     {
4633       pi = (int *)free_lang_decl_chain;
4634       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4635     }
4636   else
4637     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4638
4639   while (i > 0)
4640     pi[--i] = 0;
4641
4642   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4643   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4644     = obstack == &permanent_obstack;
4645   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4646           == TREE_PERMANENT  (t), 234);
4647   DECL_MAIN_VARIANT (t) = t;
4648   if (current_lang_name == lang_name_cplusplus)
4649     {
4650       DECL_LANGUAGE (t) = lang_cplusplus;
4651 #if 0
4652 #ifndef NO_AUTO_OVERLOAD
4653       if (code == FUNCTION_DECL && name != 0
4654           && ! (IDENTIFIER_LENGTH (name) == 4
4655                 && IDENTIFIER_POINTER (name)[0] == 'm'
4656                 && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
4657           && ! (IDENTIFIER_LENGTH (name) > 10
4658                 && IDENTIFIER_POINTER (name)[0] == '_'
4659                 && IDENTIFIER_POINTER (name)[1] == '_'
4660                 && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
4661         TREE_OVERLOADED (name) = 1;
4662 #endif
4663 #endif
4664     }
4665   else if (current_lang_name == lang_name_c)
4666     DECL_LANGUAGE (t) = lang_c;
4667   else my_friendly_abort (64);
4668
4669 #if 0 /* not yet, should get fixed properly later */
4670   if (code == TYPE_DECL)
4671     {
4672       tree id;
4673       id = get_identifier (build_overload_name (type, 1, 1));
4674       DECL_ASSEMBLER_NAME (t) = id;
4675     }
4676
4677 #endif
4678 #ifdef GATHER_STATISTICS
4679   tree_node_counts[(int)lang_decl] += 1;
4680   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4681 #endif
4682
4683   return t;
4684 }
4685
4686 tree
4687 build_lang_field_decl (code, name, type)
4688      enum tree_code code;
4689      tree name;
4690      tree type;
4691 {
4692   extern struct obstack *current_obstack, *saveable_obstack;
4693   register tree t = build_decl (code, name, type);
4694   struct obstack *obstack = current_obstack;
4695   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4696   register int *pi;
4697 #if 0 /* not yet, should get fixed properly later */
4698
4699   if (code == TYPE_DECL)
4700     {
4701       tree id;
4702       id = get_identifier (build_overload_name (type, 1, 1));
4703       DECL_ASSEMBLER_NAME (t) = id;
4704     }
4705 #endif
4706
4707   if (! TREE_PERMANENT (t))
4708     obstack = saveable_obstack;
4709   else
4710     my_friendly_assert (obstack == &permanent_obstack, 235);
4711
4712   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4713   while (i > 0)
4714     pi[--i] = 0;
4715
4716   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4717   return t;
4718 }
4719
4720 void
4721 copy_lang_decl (node)
4722      tree node;
4723 {
4724   int size;
4725   int *pi;
4726
4727   if (TREE_CODE (node) == FIELD_DECL)
4728     size = sizeof (struct lang_decl_flags);
4729   else
4730     size = sizeof (struct lang_decl);
4731   pi = (int *)obstack_alloc (&permanent_obstack, size);
4732   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4733   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4734 }
4735
4736 tree
4737 make_lang_type (code)
4738      enum tree_code code;
4739 {
4740   extern struct obstack *current_obstack, *saveable_obstack;
4741   register tree t = make_node (code);
4742   struct obstack *obstack = current_obstack;
4743   register int i = sizeof (struct lang_type) / sizeof (int);
4744   register int *pi;
4745
4746   /* Set up some flags that give proper default behavior.  */
4747   IS_AGGR_TYPE (t) = 1;
4748
4749   if (! TREE_PERMANENT (t))
4750     obstack = saveable_obstack;
4751   else
4752     my_friendly_assert (obstack == &permanent_obstack, 236);
4753
4754   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
4755   while (i > 0)
4756     pi[--i] = 0;
4757
4758   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
4759   CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
4760   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4761   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4762   CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
4763   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
4764                                NULL_TREE);
4765   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4766
4767   /* Make sure this is laid out, for ease of use later.
4768      In the presence of parse errors, the normal was of assuring
4769      this might not ever get executed, so we lay it out *immediately*.  */
4770   build_pointer_type (t);
4771
4772 #ifdef GATHER_STATISTICS
4773   tree_node_counts[(int)lang_type] += 1;
4774   tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
4775 #endif
4776
4777   return t;
4778 }
4779
4780 void
4781 copy_decl_lang_specific (decl)
4782      tree decl;
4783 {
4784   extern struct obstack *current_obstack, *saveable_obstack;
4785   register int *old = (int *)DECL_LANG_SPECIFIC (decl);
4786   struct obstack *obstack = current_obstack;
4787   register int i = sizeof (struct lang_decl) / sizeof (int);
4788   register int *pi;
4789
4790   if (! TREE_PERMANENT (decl))
4791     obstack = saveable_obstack;
4792   else
4793     my_friendly_assert (obstack == &permanent_obstack, 237);
4794
4795   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4796   while (i-- > 0)
4797     pi[i] = old[i];
4798
4799   DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
4800
4801 #ifdef GATHER_STATISTICS
4802   tree_node_counts[(int)lang_decl] += 1;
4803   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4804 #endif
4805 }
4806
4807 void
4808 dump_time_statistics ()
4809 {
4810   register tree prev = 0, decl, next;
4811   int this_time = my_get_run_time ();
4812   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
4813     += this_time - body_time;
4814
4815   fprintf (stderr, "\n******\n");
4816   print_time ("header files (total)", header_time);
4817   print_time ("main file (total)", this_time - body_time);
4818   fprintf (stderr, "ratio = %g : 1\n",
4819            (double)header_time / (double)(this_time - body_time));
4820   fprintf (stderr, "\n******\n");
4821
4822   for (decl = filename_times; decl; decl = next)
4823     {
4824       next = IDENTIFIER_GLOBAL_VALUE (decl);
4825       IDENTIFIER_GLOBAL_VALUE (decl) = prev;
4826       prev = decl;
4827     }
4828
4829   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4830     print_time (IDENTIFIER_POINTER (decl),
4831                 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4832 }
4833
4834 void
4835 compiler_error (s, v, v2)
4836      char *s;
4837      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4838 {
4839   char buf[1024];
4840   sprintf (buf, s, v, v2);
4841   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4842 }
4843
4844 void
4845 compiler_error_with_decl (decl, s)
4846      tree decl;
4847      char *s;
4848 {
4849   char *name;
4850   count_error (0);
4851
4852   report_error_function (0);
4853
4854   if (TREE_CODE (decl) == PARM_DECL)
4855     fprintf (stderr, "%s:%d: ",
4856              DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
4857              DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
4858   else
4859     fprintf (stderr, "%s:%d: ",
4860              DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4861
4862   name = lang_printable_name (decl);
4863   if (name)
4864     fprintf (stderr, s, name);
4865   else
4866     fprintf (stderr, s, "((anonymous))");
4867   fprintf (stderr, " (compiler error)\n");
4868 }
4869 \f
4870 void
4871 yyerror (string)
4872      char *string;
4873 {
4874   extern int end_of_file;
4875   char buf[200];
4876
4877   strcpy (buf, string);
4878
4879   /* We can't print string and character constants well
4880      because the token_buffer contains the result of processing escapes.  */
4881   if (end_of_file)
4882     strcat (buf, input_redirected ()
4883             ? " at end of saved text"
4884             : " at end of input");
4885   else if (token_buffer[0] == 0)
4886     strcat (buf, " at null character");
4887   else if (token_buffer[0] == '"')
4888     strcat (buf, " before string constant");
4889   else if (token_buffer[0] == '\'')
4890     strcat (buf, " before character constant");
4891   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
4892     sprintf (buf + strlen (buf), " before character 0%o",
4893              (unsigned char) token_buffer[0]);
4894   else
4895     strcat (buf, " before `%s'");
4896
4897   error (buf, token_buffer);
4898 }
4899 \f
4900 #ifdef HANDLE_SYSV_PRAGMA
4901
4902 /* Handle a #pragma directive.  INPUT is the current input stream,
4903    and C is a character to reread.  Processes the entire input line
4904    and returns a character for the caller to reread: either \n or EOF.  */
4905
4906 /* This function has to be in this file, in order to get at
4907    the token types.  */
4908
4909 int
4910 handle_sysv_pragma (input, c)
4911      FILE *input;
4912      int c;
4913 {
4914   for (;;)
4915     {
4916       while (c == ' ' || c == '\t')
4917         c = getc (input);
4918       if (c == '\n' || c == EOF)
4919         {
4920           handle_pragma_token (0, 0);
4921           return c;
4922         }
4923       ungetc (c, input);
4924       switch (yylex ())
4925         {
4926         case IDENTIFIER:
4927         case TYPENAME:
4928         case STRING:
4929         case CONSTANT:
4930           handle_pragma_token (token_buffer, yylval.ttype);
4931           break;
4932         default:
4933           handle_pragma_token (token_buffer, 0);
4934         }
4935       if (nextchar >= 0)
4936         c = nextchar, nextchar = -1;
4937       else
4938         c = getc (input);
4939     }
4940 }
4941 #endif /* HANDLE_SYSV_PRAGMA */