OSDN Git Service

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