OSDN Git Service

451f598d5f5694df27e21fdaeab9de4b60009a4d
[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     case 6:
1675       retref = 1;
1676       declspecs = build_decl_list (NULL_TREE, type);
1677
1678       if (kind == 5)
1679         type = build_type_variant (type, 1, 0);
1680
1681       name = ansi_opname [(int) MODIFY_EXPR];
1682
1683       argtype = build_reference_type (type);
1684       args = tree_cons (NULL_TREE,
1685                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
1686                                          get_identifier ("_ctor_arg")),
1687                         void_list_node);
1688       break;
1689
1690     default:
1691       my_friendly_abort (59);
1692     }
1693
1694   declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
1695                               declspecs);
1696
1697   TREE_PARMLIST (args) = 1;
1698
1699   {
1700     tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
1701     if (retref)
1702       declarator = build_parse_node (ADDR_EXPR, declarator);
1703     
1704     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
1705   }
1706   
1707   if (fn == void_type_node)
1708     return fn;
1709
1710   if (kind > 2)
1711     SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
1712
1713 #if 0
1714   if (processing_template_defn)
1715     {
1716       SET_DECL_IMPLICIT_INSTANTIATION (fn);
1717       repo_template_used (fn);
1718     }
1719 #endif
1720
1721 #if 0
1722   if (CLASSTYPE_INTERFACE_KNOWN (type))
1723     {
1724       DECL_INTERFACE_KNOWN (fn) = 1;
1725       DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
1726                                      && flag_implement_inlines);
1727     }
1728   else
1729 #endif
1730     DECL_NOT_REALLY_EXTERN (fn) = 1;
1731
1732   mark_inline_for_output (fn);
1733
1734 #ifdef DEBUG_DEFAULT_FUNCTIONS
1735   { char *fn_type = NULL;
1736     tree t = name;
1737     switch (kind)
1738       {
1739       case 0: fn_type = "default destructor"; break;
1740       case 1: fn_type = "virtual destructor"; break;
1741       case 2: fn_type = "default constructor"; break;
1742       case 3: fn_type = "default X(const X&)"; break;
1743       case 4: fn_type = "default X(X&)"; break;
1744       }
1745     if (fn_type)
1746       {
1747         if (TREE_CODE (name) == BIT_NOT_EXPR)
1748           t = TREE_OPERAND (name, 0);
1749         fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
1750                  IDENTIFIER_POINTER (t), func_buf);
1751       }
1752   }
1753 #endif /* DEBUG_DEFAULT_FUNCTIONS */
1754
1755   /* Show that this function was generated by the compiler.  */
1756   SET_DECL_ARTIFICIAL (fn);
1757   
1758   return fn;
1759 }
1760
1761 /* Heuristic to tell whether the user is missing a semicolon
1762    after a struct or enum declaration.  Emit an error message
1763    if we know the user has blown it.  */
1764
1765 void
1766 check_for_missing_semicolon (type)
1767      tree type;
1768 {
1769   if (yychar < 0)
1770     yychar = yylex ();
1771
1772   if ((yychar > 255
1773        && yychar != SCSPEC
1774        && yychar != IDENTIFIER
1775        && yychar != TYPENAME
1776        && yychar != SELFNAME)
1777       || end_of_file)
1778     {
1779       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
1780         error ("semicolon missing after %s declaration",
1781                TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
1782       else
1783         cp_error ("semicolon missing after declaration of `%T'", type);
1784       shadow_tag (build_tree_list (0, type));
1785     }
1786   /* Could probably also hack cases where class { ... } f (); appears.  */
1787   clear_anon_tags ();
1788 }
1789
1790 void
1791 note_got_semicolon (type)
1792      tree type;
1793 {
1794   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
1795     my_friendly_abort (60);
1796   if (IS_AGGR_TYPE (type))
1797     CLASSTYPE_GOT_SEMICOLON (type) = 1;
1798 }
1799
1800 void
1801 note_list_got_semicolon (declspecs)
1802      tree declspecs;
1803 {
1804   tree link;
1805
1806   for (link = declspecs; link; link = TREE_CHAIN (link))
1807     {
1808       tree type = TREE_VALUE (link);
1809       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
1810         note_got_semicolon (type);
1811     }
1812   clear_anon_tags ();
1813 }
1814 \f
1815 /* If C is not whitespace, return C.
1816    Otherwise skip whitespace and return first nonwhite char read.  */
1817
1818 static int
1819 skip_white_space (c)
1820      register int c;
1821 {
1822   for (;;)
1823     {
1824       switch (c)
1825         {
1826         case '\n':
1827           c = check_newline ();
1828           break;
1829
1830         case ' ':
1831         case '\t':
1832         case '\f':
1833         case '\r':
1834         case '\v':
1835         case '\b':
1836           do
1837             c = getch ();
1838           while (c == ' ' || c == '\t');
1839           break;
1840
1841         case '\\':
1842           c = getch ();
1843           if (c == '\n')
1844             lineno++;
1845           else
1846             error ("stray '\\' in program");
1847           c = getch ();
1848           break;
1849
1850         default:
1851           return (c);
1852         }
1853     }
1854 }
1855
1856
1857
1858 /* Make the token buffer longer, preserving the data in it.
1859    P should point to just beyond the last valid character in the old buffer.
1860    The value we return is a pointer to the new buffer
1861    at a place corresponding to P.  */
1862
1863 static char *
1864 extend_token_buffer (p)
1865      char *p;
1866 {
1867   int offset = p - token_buffer;
1868
1869   maxtoken = maxtoken * 2 + 10;
1870   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
1871
1872   return token_buffer + offset;
1873 }
1874 \f
1875 static int
1876 get_last_nonwhite_on_line ()
1877 {
1878   register int c;
1879
1880   /* Is this the last nonwhite stuff on the line?  */
1881   if (nextchar >= 0)
1882     c = nextchar, nextchar = -1;
1883   else
1884     c = getch ();
1885
1886   while (c == ' ' || c == '\t')
1887     c = getch ();
1888   return c;
1889 }
1890
1891 /* At the beginning of a line, increment the line number
1892    and process any #-directive on this line.
1893    If the line is a #-directive, read the entire line and return a newline.
1894    Otherwise, return the line's first non-whitespace character.  */
1895
1896 int linemode;
1897
1898 #ifdef HANDLE_SYSV_PRAGMA
1899 static int handle_sysv_pragma ();
1900 #endif
1901 static int handle_cp_pragma ();
1902
1903 int
1904 check_newline ()
1905 {
1906   register int c;
1907   register int token;
1908
1909   /* Read first nonwhite char on the line.  Do this before incrementing the
1910      line number, in case we're at the end of saved text.  */
1911
1912   do
1913     c = getch ();
1914   while (c == ' ' || c == '\t');
1915
1916   lineno++;
1917
1918   if (c != '#')
1919     {
1920       /* If not #, return it so caller will use it.  */
1921       return c;
1922     }
1923
1924   /* Don't read beyond this line.  */
1925   linemode = 1;
1926   
1927   /* Read first nonwhite char after the `#'.  */
1928
1929   do
1930     c = getch ();
1931   while (c == ' ' || c == '\t');
1932
1933   /* If a letter follows, then if the word here is `line', skip
1934      it and ignore it; otherwise, ignore the line, with an error
1935      if the word isn't `pragma'.  */
1936
1937   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
1938     {
1939       if (c == 'p')
1940         {
1941           if (getch () == 'r'
1942               && getch () == 'a'
1943               && getch () == 'g'
1944               && getch () == 'm'
1945               && getch () == 'a')
1946             {
1947               token = real_yylex ();
1948               if (token == IDENTIFIER
1949                   && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
1950                 {
1951                   /* If this is 1, we handled it; if it's -1, it was one we
1952                      wanted but had something wrong with it.  Only if it's
1953                      0 was it not handled.  */
1954                   if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
1955                     goto skipline;
1956                 }
1957               else if (token == END_OF_LINE)
1958                 goto skipline;
1959
1960 #ifdef HANDLE_SYSV_PRAGMA
1961               if (handle_sysv_pragma (finput, token))
1962                 goto skipline;
1963 #else
1964 #ifdef HANDLE_PRAGMA
1965               if (HANDLE_PRAGMA (finput, yylval.ttype))
1966                 goto skipline;
1967 #endif
1968 #endif
1969             }
1970           goto skipline;
1971         }
1972       else if (c == 'd')
1973         {
1974           if (getch () == 'e'
1975               && getch () == 'f'
1976               && getch () == 'i'
1977               && getch () == 'n'
1978               && getch () == 'e'
1979               && ((c = getch ()) == ' ' || c == '\t'))
1980             {
1981               debug_define (lineno, get_directive_line (finput));
1982               goto skipline;
1983             }
1984         }
1985       else if (c == 'u')
1986         {
1987           if (getch () == 'n'
1988               && getch () == 'd'
1989               && getch () == 'e'
1990               && getch () == 'f'
1991               && ((c = getch ()) == ' ' || c == '\t'))
1992             {
1993               debug_undef (lineno, get_directive_line (finput));
1994               goto skipline;
1995             }
1996         }
1997       else if (c == 'l')
1998         {
1999           if (getch () == 'i'
2000               && getch () == 'n'
2001               && getch () == 'e'
2002               && ((c = getch ()) == ' ' || c == '\t'))
2003             goto linenum;
2004         }
2005       else if (c == 'i')
2006         {
2007           if (getch () == 'd'
2008               && getch () == 'e'
2009               && getch () == 'n'
2010               && getch () == 't'
2011               && ((c = getch ()) == ' ' || c == '\t'))
2012             {
2013 #ifdef ASM_OUTPUT_IDENT
2014               extern FILE *asm_out_file;
2015 #endif
2016               /* #ident.  The pedantic warning is now in cccp.c.  */
2017
2018               /* Here we have just seen `#ident '.
2019                  A string constant should follow.  */
2020
2021               token = real_yylex ();
2022               if (token == END_OF_LINE)
2023                 goto skipline;
2024               if (token != STRING
2025                   || TREE_CODE (yylval.ttype) != STRING_CST)
2026                 {
2027                   error ("invalid #ident");
2028                   goto skipline;
2029                 }
2030
2031               if (! flag_no_ident)
2032                 {
2033 #ifdef ASM_OUTPUT_IDENT
2034                   ASM_OUTPUT_IDENT (asm_out_file,
2035                                     TREE_STRING_POINTER (yylval.ttype));
2036 #endif
2037                 }
2038
2039               /* Skip the rest of this line.  */
2040               goto skipline;
2041             }
2042         }
2043       else if (c == 'n')
2044         {
2045           if (getch () == 'e'
2046               && getch () == 'w'
2047               && getch () == 'w'
2048               && getch () == 'o'
2049               && getch () == 'r'
2050               && getch () == 'l'
2051               && getch () == 'd'
2052               && ((c = getch ()) == ' ' || c == '\t'))
2053             {
2054               /* Used to test incremental compilation.  */
2055               sorry ("#pragma newworld");
2056               goto skipline;
2057             }
2058         }
2059       error ("undefined or invalid # directive");
2060       goto skipline;
2061     }
2062
2063 linenum:
2064   /* Here we have either `#line' or `# <nonletter>'.
2065      In either case, it should be a line number; a digit should follow.  */
2066
2067   while (c == ' ' || c == '\t')
2068     c = getch ();
2069
2070   /* If the # is the only nonwhite char on the line,
2071      just ignore it.  Check the new newline.  */
2072   if (c == EOF)
2073     goto skipline;
2074
2075   /* Something follows the #; read a token.  */
2076
2077   put_back (c);
2078   token = real_yylex ();
2079
2080   if (token == CONSTANT
2081       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2082     {
2083       int old_lineno = lineno;
2084       enum { act_none, act_push, act_pop } action = act_none;
2085       int entering_system_header = 0;
2086       int entering_c_header = 0;
2087
2088       /* subtract one, because it is the following line that
2089          gets the specified number */
2090
2091       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2092       c = get_last_nonwhite_on_line ();
2093       if (c == EOF)
2094         {
2095           /* No more: store the line number and check following line.  */
2096           lineno = l;
2097           goto skipline;
2098         }
2099       put_back (c);
2100
2101       /* More follows: it must be a string constant (filename).  */
2102
2103       /* Read the string constant, but don't treat \ as special.  */
2104       ignore_escape_flag = 1;
2105       token = real_yylex ();
2106       ignore_escape_flag = 0;
2107
2108       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2109         {
2110           error ("invalid #line");
2111           goto skipline;
2112         }
2113
2114       /* Changing files again.  This means currently collected time
2115          is charged against header time, and body time starts back
2116          at 0.  */
2117       if (flag_detailed_statistics)
2118         {
2119           int this_time = my_get_run_time ();
2120           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2121           header_time += this_time - body_time;
2122           TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
2123             += this_time - body_time;
2124           this_filename_time = time_identifier;
2125           body_time = this_time;
2126         }
2127
2128       input_filename
2129         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2130       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2131       lineno = l;
2132       GNU_xref_file (input_filename);
2133       
2134       if (main_input_filename == 0)
2135         {
2136           struct impl_files *ifiles = impl_file_chain;
2137
2138           if (ifiles)
2139             {
2140               while (ifiles->next)
2141                 ifiles = ifiles->next;
2142               ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename);
2143             }
2144
2145           main_input_filename = input_filename;
2146           if (write_virtuals == 3)
2147             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2148         }
2149
2150       extract_interface_info ();
2151
2152       c = get_last_nonwhite_on_line ();
2153       if (c == EOF)
2154         {
2155           /* Update the name in the top element of input_file_stack.  */
2156           if (input_file_stack)
2157             input_file_stack->name = input_filename;
2158         }
2159       else
2160         {
2161           put_back (c);
2162
2163           token = real_yylex ();
2164
2165           /* `1' after file name means entering new file.
2166              `2' after file name means just left a file.  */
2167
2168           if (token == CONSTANT
2169               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2170             {
2171               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2172                 action = act_push;
2173               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2174                 action = act_pop;
2175
2176               if (action)
2177                 {
2178                   c = get_last_nonwhite_on_line ();
2179                   if (c != EOF)
2180                     {
2181                       put_back (c);
2182                       token = real_yylex ();
2183                     }
2184                 }
2185             }
2186
2187           /* `3' after file name means this is a system header file.  */
2188
2189           if (token == CONSTANT
2190               && TREE_CODE (yylval.ttype) == INTEGER_CST
2191               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2192             {
2193               entering_system_header = 1;
2194
2195               c = get_last_nonwhite_on_line ();
2196               if (c != EOF)
2197                 {
2198                   put_back (c);
2199                   token = real_yylex ();
2200                 }
2201             }
2202
2203           /* `4' after file name means this is a C header file.  */
2204
2205           if (token == CONSTANT
2206               && TREE_CODE (yylval.ttype) == INTEGER_CST
2207               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2208             {
2209               entering_c_header = 1;
2210
2211               c = get_last_nonwhite_on_line ();
2212               if (c != EOF)
2213                 {
2214                   put_back (c);
2215                   token = real_yylex ();
2216                 }
2217             }
2218
2219           /* Do the actions implied by the preceding numbers.  */
2220
2221           if (action == act_push)
2222             {
2223               /* Pushing to a new file.  */
2224               struct file_stack *p;
2225
2226               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2227               input_file_stack->line = old_lineno;
2228               p->next = input_file_stack;
2229               p->name = input_filename;
2230               input_file_stack = p;
2231               input_file_stack_tick++;
2232               debug_start_source_file (input_filename);
2233               in_system_header = entering_system_header;
2234               if (c_header_level)
2235                 ++c_header_level;
2236               else if (entering_c_header)
2237                 {
2238                   c_header_level = 1;
2239                   ++pending_lang_change;
2240                 }
2241             }
2242           else if (action == act_pop)
2243             {
2244               /* Popping out of a file.  */
2245               if (input_file_stack->next)
2246                 {
2247                   struct file_stack *p;
2248
2249                   if (c_header_level && --c_header_level == 0)
2250                     {
2251                       if (entering_c_header)
2252                         warning ("badly nested C headers from preprocessor");
2253                       --pending_lang_change;
2254                     }
2255                   in_system_header = entering_system_header;
2256
2257                   p = input_file_stack;
2258                   input_file_stack = p->next;
2259                   free (p);
2260                   input_file_stack_tick++;
2261                   debug_end_source_file (input_file_stack->line);
2262                 }
2263               else
2264                 error ("#-lines for entering and leaving files don't match");
2265             }
2266           else
2267             in_system_header = entering_system_header;
2268         }
2269
2270       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2271       if (nextchar == EOF)
2272         c = EOF;
2273     }
2274   else
2275     error ("invalid #-line");
2276
2277   /* skip the rest of this line.  */
2278  skipline:
2279   linemode = 0;
2280   end_of_file = 0;
2281   nextchar = -1;
2282   while ((c = getch ()) != EOF && c != '\n');
2283   return c;
2284 }
2285
2286 void
2287 do_pending_lang_change ()
2288 {
2289   for (; pending_lang_change > 0; --pending_lang_change)
2290     push_lang_context (lang_name_c);
2291   for (; pending_lang_change < 0; ++pending_lang_change)
2292     pop_lang_context ();
2293 }
2294 \f
2295 #if 0
2296 #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
2297 #define isdigit(char) (char >= '0' && char <= '9')
2298 #else
2299 #include <ctype.h>
2300 #endif
2301
2302 #define ENDFILE -1  /* token that represents end-of-file */
2303
2304 /* Read an escape sequence, returning its equivalent as a character,
2305    or store 1 in *ignore_ptr if it is backslash-newline.  */
2306
2307 static int
2308 readescape (ignore_ptr)
2309      int *ignore_ptr;
2310 {
2311   register int c = getch ();
2312   register int code;
2313   register unsigned count;
2314   unsigned firstdig;
2315   int nonnull;
2316
2317   switch (c)
2318     {
2319     case 'x':
2320       code = 0;
2321       count = 0;
2322       nonnull = 0;
2323       while (1)
2324         {
2325           c = getch ();
2326           if (! isxdigit (c))
2327             {
2328               put_back (c);
2329               break;
2330             }
2331           code *= 16;
2332           if (c >= 'a' && c <= 'f')
2333             code += c - 'a' + 10;
2334           if (c >= 'A' && c <= 'F')
2335             code += c - 'A' + 10;
2336           if (c >= '0' && c <= '9')
2337             code += c - '0';
2338           if (code != 0 || count != 0)
2339             {
2340               if (count == 0)
2341                 firstdig = code;
2342               count++;
2343             }
2344           nonnull = 1;
2345         }
2346       if (! nonnull)
2347         error ("\\x used with no following hex digits");
2348       else if (count == 0)
2349         /* Digits are all 0's.  Ok.  */
2350         ;
2351       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2352                || (count > 1
2353                    && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2354                        <= firstdig)))
2355         pedwarn ("hex escape out of range");
2356       return code;
2357
2358     case '0':  case '1':  case '2':  case '3':  case '4':
2359     case '5':  case '6':  case '7':
2360       code = 0;
2361       count = 0;
2362       while ((c <= '7') && (c >= '0') && (count++ < 3))
2363         {
2364           code = (code * 8) + (c - '0');
2365           c = getch ();
2366         }
2367       put_back (c);
2368       return code;
2369
2370     case '\\': case '\'': case '"':
2371       return c;
2372
2373     case '\n':
2374       lineno++;
2375       *ignore_ptr = 1;
2376       return 0;
2377
2378     case 'n':
2379       return TARGET_NEWLINE;
2380
2381     case 't':
2382       return TARGET_TAB;
2383
2384     case 'r':
2385       return TARGET_CR;
2386
2387     case 'f':
2388       return TARGET_FF;
2389
2390     case 'b':
2391       return TARGET_BS;
2392
2393     case 'a':
2394       return TARGET_BELL;
2395
2396     case 'v':
2397       return TARGET_VT;
2398
2399     case 'e':
2400     case 'E':
2401       if (pedantic)
2402         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
2403       return 033;
2404
2405     case '?':
2406       return c;
2407
2408       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
2409     case '(':
2410     case '{':
2411     case '[':
2412       /* `\%' is used to prevent SCCS from getting confused.  */
2413     case '%':
2414       if (pedantic)
2415         pedwarn ("unknown escape sequence `\\%c'", c);
2416       return c;
2417     }
2418   if (c >= 040 && c < 0177)
2419     pedwarn ("unknown escape sequence `\\%c'", c);
2420   else
2421     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2422   return c;
2423 }
2424
2425 /* Value is 1 (or 2) if we should try to make the next identifier look like
2426    a typename (when it may be a local variable or a class variable).
2427    Value is 0 if we treat this name in a default fashion.  */
2428 int looking_for_typename = 0;
2429
2430 #ifdef __GNUC__
2431 extern __inline int identifier_type ();
2432 __inline
2433 #endif
2434 int
2435 identifier_type (decl)
2436      tree decl;
2437 {
2438   if (TREE_CODE (decl) == TEMPLATE_DECL)
2439     {
2440       if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
2441         return PTYPENAME;
2442     }
2443   if (TREE_CODE (decl) == NAMESPACE_DECL)
2444     return NSNAME;
2445   if (TREE_CODE (decl) != TYPE_DECL)
2446     return IDENTIFIER;
2447   if (((got_scope && TREE_TYPE (decl) == got_scope)
2448        || TREE_TYPE (decl) == current_class_type)
2449       && DECL_ARTIFICIAL (decl))
2450     return SELFNAME;
2451   return TYPENAME;
2452 }
2453
2454 void
2455 see_typename ()
2456 {
2457   looking_for_typename = 1;
2458   if (yychar < 0)
2459     if ((yychar = yylex ()) < 0) yychar = 0;
2460   looking_for_typename = 0;
2461   if (yychar == IDENTIFIER)
2462     {
2463       lastiddecl = lookup_name (yylval.ttype, -2);
2464       if (lastiddecl == 0)
2465         {
2466           if (flag_labels_ok)
2467             lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2468         }
2469       else
2470         yychar = identifier_type (lastiddecl);
2471     }
2472 }
2473
2474 tree
2475 do_identifier (token, parsing)
2476      register tree token;
2477      int parsing;
2478 {
2479   register tree id;
2480
2481   if (! parsing || IDENTIFIER_OPNAME_P (token))
2482     id = lookup_name (token, 0);
2483   else
2484     id = lastiddecl;
2485
2486   if (parsing && yychar == YYEMPTY)
2487     yychar = yylex ();
2488   /* Scope class declarations before global
2489      declarations.  */
2490   if (id == IDENTIFIER_GLOBAL_VALUE (token)
2491       && current_class_type != 0
2492       && TYPE_SIZE (current_class_type) == 0)
2493     {
2494       /* Could be from one of the base classes.  */
2495       tree field = lookup_field (current_class_type, token, 1, 0);
2496       if (field == 0)
2497         ;
2498       else if (field == error_mark_node)
2499         /* We have already generated the error message.
2500            But we still want to return this value.  */
2501         id = lookup_field (current_class_type, token, 0, 0);
2502       else if (TREE_CODE (field) == VAR_DECL
2503                || TREE_CODE (field) == CONST_DECL)
2504         id = field;
2505       else if (TREE_CODE (field) != FIELD_DECL)
2506         my_friendly_abort (61);
2507       else
2508         {
2509           cp_error ("invalid use of member `%D' from base class `%T'", field,
2510                       DECL_FIELD_CONTEXT (field));
2511           id = error_mark_node;
2512           return id;
2513         }
2514     }
2515
2516   /* Remember that this name has been used in the class definition, as per
2517      [class.scope0] */
2518   if (id && current_class_type && parsing
2519       && TYPE_BEING_DEFINED (current_class_type)
2520       && ! IDENTIFIER_CLASS_VALUE (token))
2521     pushdecl_class_level (id);
2522     
2523   if (!id || id == error_mark_node)
2524     {
2525       if (id == error_mark_node && current_class_type != NULL_TREE)
2526         {
2527           id = lookup_nested_field (token, 1);
2528           /* In lookup_nested_field(), we marked this so we can gracefully
2529              leave this whole mess.  */
2530           if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
2531             return id;
2532         }
2533
2534       if (current_template_parms)
2535         return build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
2536       else if (IDENTIFIER_OPNAME_P (token))
2537         {
2538           if (token != ansi_opname[ERROR_MARK])
2539             cp_error ("`%D' not defined", token);
2540           id = error_mark_node;
2541         }
2542       else if (parsing && (yychar == '(' || yychar == LEFT_RIGHT))
2543         {
2544           id = implicitly_declare (token);
2545         }
2546       else if (current_function_decl == 0)
2547         {
2548           cp_error ("`%D' was not declared in this scope", token);
2549           id = error_mark_node;
2550         }
2551       else
2552         {
2553           if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
2554               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2555             {
2556               static int undeclared_variable_notice;
2557
2558               cp_error ("`%D' undeclared (first use this function)", token);
2559
2560               if (! undeclared_variable_notice)
2561                 {
2562                   error ("(Each undeclared identifier is reported only once");
2563                   error ("for each function it appears in.)");
2564                   undeclared_variable_notice = 1;
2565                 }
2566             }
2567           id = error_mark_node;
2568           /* Prevent repeated error messages.  */
2569           IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
2570           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
2571         }
2572     }
2573
2574   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
2575     {
2576       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
2577       while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
2578              && DECL_DEAD_FOR_LOCAL (shadowed))
2579         shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
2580       if (!shadowed)
2581         shadowed = IDENTIFIER_GLOBAL_VALUE (DECL_NAME (id));
2582       if (shadowed)
2583         {
2584           if (!DECL_ERROR_REPORTED (id))
2585             {
2586               warning ("name lookup of `%s' changed",
2587                        IDENTIFIER_POINTER (token));
2588               cp_warning_at ("  matches this `%D' under current ANSI rules",
2589                              shadowed);
2590               cp_warning_at ("  matches this `%D' under old rules", id);
2591               DECL_ERROR_REPORTED (id) = 1;
2592             }
2593           id = shadowed;
2594         }
2595       else if (!DECL_ERROR_REPORTED (id))
2596         {
2597           static char msg[]
2598             = "name lookup of `%s' changed for new ANSI `for' scoping";
2599           DECL_ERROR_REPORTED (id) = 1;
2600           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
2601             {
2602               error (msg, IDENTIFIER_POINTER (token));
2603               cp_error_at ("  cannot use obsolete binding at `%D' because it has a destructor", id);
2604               id = error_mark_node;
2605             }
2606           else
2607             {
2608               pedwarn (msg, IDENTIFIER_POINTER (token));
2609               cp_pedwarn_at ("  using obsolete binding at `%D'", id);
2610             }
2611         }
2612     }
2613   /* TREE_USED is set in `hack_identifier'.  */
2614   if (TREE_CODE (id) == CONST_DECL)
2615     {
2616       if (IDENTIFIER_CLASS_VALUE (token) == id)
2617         {
2618           /* Check access.  */
2619           tree access = compute_access (TYPE_BINFO (current_class_type), id);
2620           if (access == access_private_node)
2621             cp_error ("enum `%D' is private", id);
2622           /* protected is OK, since it's an enum of `this'.  */
2623         }
2624       if (! processing_template_decl
2625           || (DECL_INITIAL (id)
2626               && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
2627         id = DECL_INITIAL (id);
2628     }
2629   else
2630     id = hack_identifier (id, token);
2631
2632   if (current_template_parms)
2633     {
2634       if (is_overloaded_fn (id))
2635         {
2636           tree t = build_min (LOOKUP_EXPR, unknown_type_node,
2637                               token, get_first_fn (id));
2638           if (id != IDENTIFIER_GLOBAL_VALUE (token))
2639             TREE_OPERAND (t, 1) = error_mark_node;
2640           id = t;
2641         }
2642       else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL
2643                || TREE_CODE (id) == USING_DECL)
2644         id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node);
2645       /* else just use the decl */
2646     }
2647       
2648   return id;
2649 }
2650
2651 tree
2652 do_scoped_id (token, parsing)
2653      tree token;
2654      int parsing;
2655 {
2656   tree id = IDENTIFIER_GLOBAL_VALUE (token);
2657   if (parsing && yychar == YYEMPTY)
2658     yychar = yylex ();
2659   if (! id)
2660     {
2661       if (processing_template_decl)
2662         {
2663           id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
2664           LOOKUP_EXPR_GLOBAL (id) = 1;
2665           return id;
2666         }
2667       if (parsing && yychar == '(' || yychar == LEFT_RIGHT)
2668         id = implicitly_declare (token);
2669       else
2670         {
2671           if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node)
2672             error ("undeclared variable `%s' (first use here)",
2673                    IDENTIFIER_POINTER (token));
2674           id = error_mark_node;
2675           /* Prevent repeated error messages.  */
2676           IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
2677         }
2678     }
2679   else
2680     {
2681       if (TREE_CODE (id) == ADDR_EXPR)
2682         mark_used (TREE_OPERAND (id, 0));
2683       else if (TREE_CODE (id) != TREE_LIST)
2684         mark_used (id);
2685     }
2686   if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
2687     {
2688       /* XXX CHS - should we set TREE_USED of the constant? */
2689       id = DECL_INITIAL (id);
2690       /* This is to prevent an enum whose value is 0
2691          from being considered a null pointer constant.  */
2692       id = build1 (NOP_EXPR, TREE_TYPE (id), id);
2693       TREE_CONSTANT (id) = 1;
2694     }
2695
2696   if (processing_template_decl)
2697     {
2698       if (is_overloaded_fn (id))
2699         {
2700           id = build_min (LOOKUP_EXPR, unknown_type_node,
2701                           token, get_first_fn (id));
2702           LOOKUP_EXPR_GLOBAL (id) = 1;
2703         }
2704       /* else just use the decl */
2705     }
2706   return id;
2707 }
2708
2709 tree
2710 identifier_typedecl_value (node)
2711      tree node;
2712 {
2713   tree t, type;
2714   type = IDENTIFIER_TYPE_VALUE (node);
2715   if (type == NULL_TREE)
2716     return NULL_TREE;
2717 #define do(X) \
2718   { \
2719     t = (X); \
2720     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
2721       return t; \
2722   }
2723   do (IDENTIFIER_LOCAL_VALUE (node));
2724   do (IDENTIFIER_CLASS_VALUE (node));
2725   do (IDENTIFIER_GLOBAL_VALUE (node));
2726 #undef do
2727   /* Will this one ever happen?  */
2728   if (TYPE_MAIN_DECL (type))
2729     return TYPE_MAIN_DECL (type);
2730
2731   /* We used to do an internal error of 62 here, but instead we will
2732      handle the return of a null appropriately in the callers.  */
2733   return NULL_TREE;
2734 }
2735
2736 int
2737 real_yylex ()
2738 {
2739   register int c;
2740   register int value;
2741   int wide_flag = 0;
2742   int dollar_seen = 0;
2743   int i;
2744
2745   if (nextchar >= 0)
2746     c = nextchar, nextchar = -1;
2747   else
2748     c = getch ();
2749
2750   /* Effectively do c = skip_white_space (c)
2751      but do it faster in the usual cases.  */
2752   while (1)
2753     switch (c)
2754       {
2755       case ' ':
2756       case '\t':
2757       case '\f':
2758       case '\v':
2759       case '\b':
2760         c = getch ();
2761         break;
2762
2763       case '\r':
2764         /* Call skip_white_space so we can warn if appropriate.  */
2765
2766       case '\n':
2767       case '/':
2768       case '\\':
2769         c = skip_white_space (c);
2770       default:
2771         goto found_nonwhite;
2772       }
2773  found_nonwhite:
2774
2775   token_buffer[0] = c;
2776   token_buffer[1] = 0;
2777
2778 /*  yylloc.first_line = lineno; */
2779
2780   switch (c)
2781     {
2782     case EOF:
2783       token_buffer[0] = '\0';
2784       end_of_file = 1;
2785       if (input_redirected ())
2786         value = END_OF_SAVED_INPUT;
2787       else if (linemode)
2788         value = END_OF_LINE;
2789       else
2790         value = ENDFILE;
2791       break;
2792
2793     case '$':
2794       if (dollars_in_ident)
2795         {
2796           dollar_seen = 1;
2797           goto letter;
2798         }
2799       value = '$';
2800       goto done;
2801
2802     case 'L':
2803       /* Capital L may start a wide-string or wide-character constant.  */
2804       {
2805         register int c = getch ();
2806         if (c == '\'')
2807           {
2808             wide_flag = 1;
2809             goto char_constant;
2810           }
2811         if (c == '"')
2812           {
2813             wide_flag = 1;
2814             goto string_constant;
2815           }
2816         put_back (c);
2817       }
2818
2819     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
2820     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
2821     case 'K':             case 'M':  case 'N':  case 'O':
2822     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
2823     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
2824     case 'Z':
2825     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
2826     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
2827     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
2828     case 'p':  case 'q':  case 'r':  case 's':  case 't':
2829     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
2830     case 'z':
2831     case '_':
2832     letter:
2833       {
2834         register char *p;
2835
2836         p = token_buffer;
2837         if (input == 0)
2838           {
2839             /* We know that `token_buffer' can hold at least on char,
2840                so we install C immediately.
2841                We may have to read the value in `putback_char', so call
2842                `getch' once.  */
2843             *p++ = c;
2844             c = getch ();
2845
2846             /* Make this run fast.  We know that we are reading straight
2847                from FINPUT in this case (since identifiers cannot straddle
2848                input sources.  */
2849             while (isalnum (c) || (c == '_') || c == '$')
2850               {
2851                 if (c == '$' && ! dollars_in_ident)
2852                   break;
2853                 if (p >= token_buffer + maxtoken)
2854                   p = extend_token_buffer (p);
2855
2856                 *p++ = c;
2857                 c = getc (finput);
2858               }
2859
2860             if (linemode && c == '\n')
2861               {
2862                 put_back (c);
2863                 c = EOF;
2864               }
2865           }
2866         else
2867           {
2868             /* We know that `token_buffer' can hold at least on char,
2869                so we install C immediately.  */
2870             *p++ = c;
2871             c = getch ();
2872
2873             while (isalnum (c) || (c == '_') || c == '$')
2874               {
2875                 if (c == '$' && ! dollars_in_ident)
2876                   break;
2877                 if (p >= token_buffer + maxtoken)
2878                   p = extend_token_buffer (p);
2879
2880                 *p++ = c;
2881                 c = getch ();
2882               }
2883           }
2884
2885         *p = 0;
2886         nextchar = c;
2887
2888         value = IDENTIFIER;
2889         yylval.itype = 0;
2890
2891       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
2892
2893         {
2894           register struct resword *ptr;
2895
2896           if (ptr = is_reserved_word (token_buffer, p - token_buffer))
2897             {
2898               if (ptr->rid)
2899                 {
2900                   tree old_ttype = ridpointers[(int) ptr->rid];
2901
2902                   /* If this provides a type for us, then revert lexical
2903                      state to standard state.  */
2904                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
2905                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
2906                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
2907                     looking_for_typename = 0;
2908                   else if (ptr->token == AGGR || ptr->token == ENUM)
2909                     looking_for_typename = 1;
2910
2911                   /* Check if this is a language-type declaration.
2912                      Just glimpse the next non-white character.  */
2913                   nextchar = skip_white_space (nextchar);
2914                   if (nextchar == '"')
2915                     {
2916                       /* We are looking at a string.  Complain
2917                          if the token before the string is no `extern'.
2918                          
2919                          Could cheat some memory by placing this string
2920                          on the temporary_, instead of the saveable_
2921                          obstack.  */
2922
2923                       if (ptr->rid != RID_EXTERN)
2924                         error ("invalid modifier `%s' for language string",
2925                                ptr->name);
2926                       real_yylex ();
2927                       value = EXTERN_LANG_STRING;
2928                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
2929                       break;
2930                     }
2931                   if (ptr->token == VISSPEC)
2932                     {
2933                       switch (ptr->rid)
2934                         {
2935                         case RID_PUBLIC:
2936                           yylval.ttype = access_public_node;
2937                           break;
2938                         case RID_PRIVATE:
2939                           yylval.ttype = access_private_node;
2940                           break;
2941                         case RID_PROTECTED:
2942                           yylval.ttype = access_protected_node;
2943                           break;
2944                         default:
2945                           my_friendly_abort (63);
2946                         }
2947                     }
2948                   else
2949                     yylval.ttype = old_ttype;
2950                 }
2951               else if (ptr->token == EQCOMPARE)
2952                 {
2953                   yylval.code = NE_EXPR;
2954                   token_buffer[0] = '!';
2955                   token_buffer[1] = '=';
2956                   token_buffer[2] = 0;
2957                 }
2958               else if (ptr->token == ASSIGN)
2959                 {
2960                   if (strcmp ("and_eq", token_buffer) == 0)
2961                     {
2962                       yylval.code = BIT_AND_EXPR;
2963                       token_buffer[0] = '&';
2964                     }
2965                   else if (strcmp ("or_eq", token_buffer) == 0)
2966                     {
2967                       yylval.code = BIT_IOR_EXPR;
2968                       token_buffer[0] = '|';
2969                     }
2970                   else if (strcmp ("xor_eq", token_buffer) == 0)
2971                     {
2972                       yylval.code = BIT_XOR_EXPR;
2973                       token_buffer[0] = '^';
2974                     }
2975                   token_buffer[1] = '=';
2976                   token_buffer[2] = 0;
2977                 }
2978               else if (ptr->token == '&')
2979                 {
2980                   yylval.code = BIT_AND_EXPR;
2981                   token_buffer[0] = '&';
2982                   token_buffer[1] = 0;
2983                 }
2984               else if (ptr->token == '|')
2985                 {
2986                   yylval.code = BIT_IOR_EXPR;
2987                   token_buffer[0] = '|';
2988                   token_buffer[1] = 0;
2989                 }
2990               else if (ptr->token == '^')
2991                 {
2992                   yylval.code = BIT_XOR_EXPR;
2993                   token_buffer[0] = '^';
2994                   token_buffer[1] = 0;
2995                 }
2996               else if (ptr->token == NAMESPACE)
2997                 {
2998                   static int warned;
2999                   if (! warned)
3000                     warning ("namespaces are mostly broken in this version of g++");
3001
3002                   warned = 1;
3003                 }
3004
3005               value = (int) ptr->token;
3006             }
3007         }
3008
3009         /* If we did not find a keyword, look for an identifier
3010            (or a typename).  */
3011
3012         if (value == IDENTIFIER || value == TYPESPEC)
3013           GNU_xref_ref (current_function_decl, token_buffer);
3014
3015         if (value == IDENTIFIER)
3016           {
3017             register tree tmp = get_identifier (token_buffer);
3018
3019 #if !defined(VMS) && defined(JOINER)
3020             /* Make sure that user does not collide with our internal
3021                naming scheme.  */
3022             if (JOINER == '$'
3023                 && dollar_seen
3024                 && (THIS_NAME_P (tmp)
3025                     || VPTR_NAME_P (tmp)
3026                     || DESTRUCTOR_NAME_P (tmp)
3027                     || VTABLE_NAME_P (tmp)
3028                     || TEMP_NAME_P (tmp)
3029                     || ANON_AGGRNAME_P (tmp)
3030                     || ANON_PARMNAME_P (tmp)))
3031               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3032                        token_buffer);
3033 #endif
3034
3035             yylval.ttype = tmp;
3036
3037             /* A user-invisible read-only initialized variable
3038                should be replaced by its value.  We only handle strings
3039                since that's the only case used in C (and C++).  */
3040             /* Note we go right after the local value for the identifier
3041                (e.g., __FUNCTION__ or __PRETTY_FUNCTION__).  We used to
3042                call lookup_name, but that could result in an error about
3043                ambiguities.  */
3044             tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype);
3045             if (tmp != NULL_TREE
3046                 && TREE_CODE (tmp) == VAR_DECL
3047                 && DECL_IGNORED_P (tmp)
3048                 && TREE_READONLY (tmp)
3049                 && DECL_INITIAL (tmp) != NULL_TREE
3050                 && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
3051               {
3052                 tree stringval = DECL_INITIAL (tmp);
3053               
3054                 /* Copy the string value so that we won't clobber anything
3055                    if we put something in the TREE_CHAIN of this one.  */
3056                 yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
3057                                              TREE_STRING_POINTER (stringval));
3058                 value = STRING;
3059               }
3060           }
3061         if (value == NEW && ! global_bindings_p ())
3062           {
3063             value = NEW;
3064             goto done;
3065           }
3066       }
3067       break;
3068
3069     case '.':
3070       {
3071         register int c1 = getch ();
3072         token_buffer[0] = c;
3073         token_buffer[1] = c1;
3074         if (c1 == '*')
3075           {
3076             value = DOT_STAR;
3077             token_buffer[2] = 0;
3078             goto done;
3079           }
3080         if (c1 == '.')
3081           {
3082             c1 = getch ();
3083             if (c1 == '.')
3084               {
3085                 token_buffer[2] = c1;
3086                 token_buffer[3] = 0;
3087                 value = ELLIPSIS;
3088                 goto done;
3089               }
3090             error ("parse error at `..'");
3091           }
3092         if (isdigit (c1))
3093           {
3094             put_back (c1);
3095             goto resume_numerical_scan;
3096           }
3097         nextchar = c1;
3098         value = '.';
3099         token_buffer[1] = 0;
3100         goto done;
3101       }
3102     case '0':  case '1':
3103         /* Optimize for most frequent case.  */
3104       {
3105         register int c1 = getch ();
3106         if (! isalnum (c1) && c1 != '.')
3107           {
3108             /* Terminate string.  */
3109             token_buffer[0] = c;
3110             token_buffer[1] = 0;
3111             if (c == '0')
3112               yylval.ttype = integer_zero_node;
3113             else
3114               yylval.ttype = integer_one_node;
3115             nextchar = c1;
3116             value = CONSTANT;
3117             goto done;
3118           }
3119         put_back (c1);
3120       }
3121       /* fall through...  */
3122                           case '2':  case '3':  case '4':
3123     case '5':  case '6':  case '7':  case '8':  case '9':
3124     resume_numerical_scan:
3125       {
3126         register char *p;
3127         int base = 10;
3128         int count = 0;
3129         int largest_digit = 0;
3130         int numdigits = 0;
3131         /* for multi-precision arithmetic,
3132            we actually store only HOST_BITS_PER_CHAR bits in each part.
3133            The number of parts is chosen so as to be sufficient to hold
3134            the enough bits to fit into the two HOST_WIDE_INTs that contain
3135            the integer value (this is always at least as many bits as are
3136            in a target `long long' value, but may be wider).  */
3137 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3138         int parts[TOTAL_PARTS];
3139         int overflow = 0;
3140
3141         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3142           = NOT_FLOAT;
3143
3144         p = token_buffer;
3145         *p++ = c;
3146
3147         for (count = 0; count < TOTAL_PARTS; count++)
3148           parts[count] = 0;
3149
3150         if (c == '0')
3151           {
3152             *p++ = (c = getch ());
3153             if ((c == 'x') || (c == 'X'))
3154               {
3155                 base = 16;
3156                 *p++ = (c = getch ());
3157               }
3158             /* Leading 0 forces octal unless the 0 is the only digit.  */
3159             else if (c >= '0' && c <= '9')
3160               {
3161                 base = 8;
3162                 numdigits++;
3163               }
3164             else
3165               numdigits++;
3166           }
3167
3168         /* Read all the digits-and-decimal-points.  */
3169
3170         while (c == '.'
3171                || (isalnum (c) && (c != 'l') && (c != 'L')
3172                    && (c != 'u') && (c != 'U')
3173                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3174           {
3175             if (c == '.')
3176               {
3177                 if (base == 16)
3178                   error ("floating constant may not be in radix 16");
3179                 if (floatflag == AFTER_POINT)
3180                   {
3181                     error ("malformed floating constant");
3182                     floatflag = TOO_MANY_POINTS;
3183                   }
3184                 else
3185                   floatflag = AFTER_POINT;
3186
3187                 base = 10;
3188                 *p++ = c = getch ();
3189                 /* Accept '.' as the start of a floating-point number
3190                    only when it is followed by a digit.
3191                    Otherwise, unread the following non-digit
3192                    and use the '.' as a structural token.  */
3193                 if (p == token_buffer + 2 && !isdigit (c))
3194                   {
3195                     if (c == '.')
3196                       {
3197                         c = getch ();
3198                         if (c == '.')
3199                           {
3200                             *p++ = '.';
3201                             *p = '\0';
3202                             value = ELLIPSIS;
3203                             goto done;
3204                           }
3205                         error ("parse error at `..'");
3206                       }
3207                     nextchar = c;
3208                     token_buffer[1] = '\0';
3209                     value = '.';
3210                     goto done;
3211                   }
3212               }
3213             else
3214               {
3215                 /* It is not a decimal point.
3216                    It should be a digit (perhaps a hex digit).  */
3217
3218                 if (isdigit (c))
3219                   {
3220                     c = c - '0';
3221                   }
3222                 else if (base <= 10)
3223                   {
3224                     if (c == 'e' || c == 'E')
3225                       {
3226                         base = 10;
3227                         floatflag = AFTER_POINT;
3228                         break;   /* start of exponent */
3229                       }
3230                     error ("nondigits in number and not hexadecimal");
3231                     c = 0;
3232                   }
3233                 else if (c >= 'a')
3234                   {
3235                     c = c - 'a' + 10;
3236                   }
3237                 else
3238                   {
3239                     c = c - 'A' + 10;
3240                   }
3241                 if (c >= largest_digit)
3242                   largest_digit = c;
3243                 numdigits++;
3244
3245                 for (count = 0; count < TOTAL_PARTS; count++)
3246                   {
3247                     parts[count] *= base;
3248                     if (count)
3249                       {
3250                         parts[count]
3251                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3252                         parts[count-1]
3253                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3254                       }
3255                     else
3256                       parts[0] += c;
3257                   }
3258
3259                 /* If the extra highest-order part ever gets anything in it,
3260                    the number is certainly too big.  */
3261                 if (parts[TOTAL_PARTS - 1] != 0)
3262                   overflow = 1;
3263
3264                 if (p >= token_buffer + maxtoken - 3)
3265                   p = extend_token_buffer (p);
3266                 *p++ = (c = getch ());
3267               }
3268           }
3269
3270         if (numdigits == 0)
3271           error ("numeric constant with no digits");
3272
3273         if (largest_digit >= base)
3274           error ("numeric constant contains digits beyond the radix");
3275
3276         /* Remove terminating char from the token buffer and delimit the string */
3277         *--p = 0;
3278
3279         if (floatflag != NOT_FLOAT)
3280           {
3281             tree type = double_type_node;
3282             char f_seen = 0;
3283             char l_seen = 0;
3284             int garbage_chars = 0;
3285             REAL_VALUE_TYPE value;
3286             jmp_buf handler;
3287
3288             /* Read explicit exponent if any, and put it in tokenbuf.  */
3289
3290             if ((c == 'e') || (c == 'E'))
3291               {
3292                 if (p >= token_buffer + maxtoken - 3)
3293                   p = extend_token_buffer (p);
3294                 *p++ = c;
3295                 c = getch ();
3296                 if ((c == '+') || (c == '-'))
3297                   {
3298                     *p++ = c;
3299                     c = getch ();
3300                   }
3301                 if (! isdigit (c))
3302                   error ("floating constant exponent has no digits");
3303                 while (isdigit (c))
3304                   {
3305                     if (p >= token_buffer + maxtoken - 3)
3306                       p = extend_token_buffer (p);
3307                     *p++ = c;
3308                     c = getch ();
3309                   }
3310               }
3311
3312             *p = 0;
3313             errno = 0;
3314
3315             /* Convert string to a double, checking for overflow.  */
3316             if (setjmp (handler))
3317               {
3318                 error ("floating constant out of range");
3319                 value = dconst0;
3320               }
3321             else
3322               {
3323                 set_float_handler (handler);
3324                 /*  The second argument, machine_mode, of REAL_VALUE_ATOF
3325                     tells the desired precision of the binary result of
3326                     decimal-to-binary conversion.  */
3327
3328                 /* Read the suffixes to choose a data type.  */
3329                 switch (c)
3330                   {
3331                   case 'f': case 'F':
3332                     type = float_type_node;
3333                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3334                     garbage_chars = -1;
3335                     break;
3336
3337                   case 'l': case 'L':
3338                     type = long_double_type_node;
3339                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3340                     garbage_chars = -1;
3341                     break;
3342
3343                   default:
3344                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3345                   }
3346                 set_float_handler (NULL_PTR);
3347               }
3348             if (pedantic
3349                 && (REAL_VALUE_ISINF (value)
3350 #ifdef ERANGE
3351                     || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3352                         && errno == ERANGE
3353                         /* ERANGE is also reported for underflow, so test the
3354                            value to distinguish overflow from that.  */
3355                         && (REAL_VALUES_LESS (dconst1, value)
3356                             || REAL_VALUES_LESS (value, dconstm1)))
3357 #endif
3358                     ))
3359               {
3360                 pedwarn ("floating point number exceeds range of `%s'",
3361                          IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
3362               }
3363             /* Note: garbage_chars is -1 if first char is *not* garbage.  */
3364             while (isalnum (c))
3365               {
3366                 if (c == 'f' || c == 'F')
3367                   {
3368                     if (f_seen)
3369                       error ("two `f's in floating constant");
3370                     f_seen = 1;
3371                   }
3372                 if (c == 'l' || c == 'L')
3373                   {
3374                     if (l_seen)
3375                       error ("two `l's in floating constant");
3376                     l_seen = 1;
3377                   }
3378                 if (p >= token_buffer + maxtoken - 3)
3379                   p = extend_token_buffer (p);
3380                 *p++ = c;
3381                 c = getch ();
3382                 garbage_chars++;
3383               }
3384
3385             if (garbage_chars > 0)
3386               error ("garbage at end of number");
3387
3388             /* Create a node with determined type and value.  */
3389             yylval.ttype = build_real (type, value);
3390
3391             put_back (c);
3392             *p = 0;
3393           }
3394         else
3395           {
3396             tree type;
3397             HOST_WIDE_INT high, low;
3398             int spec_unsigned = 0;
3399             int spec_long = 0;
3400             int spec_long_long = 0;
3401             int bytes, warn;
3402
3403             while (1)
3404               {
3405                 if (c == 'u' || c == 'U')
3406                   {
3407                     if (spec_unsigned)
3408                       error ("two `u's in integer constant");
3409                     spec_unsigned = 1;
3410                   }
3411                 else if (c == 'l' || c == 'L')
3412                   {
3413                     if (spec_long)
3414                       {
3415                         if (spec_long_long)
3416                           error ("three `l's in integer constant");
3417                         else if (pedantic)
3418                           pedwarn ("ANSI C++ forbids long long integer constants");
3419                         spec_long_long = 1;
3420                       }
3421                     spec_long = 1;
3422                   }
3423                 else
3424                   {
3425                     if (isalnum (c))
3426                       {
3427                         error ("garbage at end of number");
3428                         while (isalnum (c))
3429                           {
3430                             if (p >= token_buffer + maxtoken - 3)
3431                               p = extend_token_buffer (p);
3432                             *p++ = c;
3433                             c = getch ();
3434                           }
3435                       }
3436                     break;
3437                   }
3438                 if (p >= token_buffer + maxtoken - 3)
3439                   p = extend_token_buffer (p);
3440                 *p++ = c;
3441                 c = getch ();
3442               }
3443
3444             put_back (c);
3445
3446             /* If the constant is not long long and it won't fit in an
3447                unsigned long, or if the constant is long long and won't fit
3448                in an unsigned long long, then warn that the constant is out
3449                of range.  */
3450
3451             /* ??? This assumes that long long and long integer types are
3452                a multiple of 8 bits.  This better than the original code
3453                though which assumed that long was exactly 32 bits and long
3454                long was exactly 64 bits.  */
3455
3456             if (spec_long_long)
3457               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3458             else
3459               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3460
3461             warn = overflow;
3462             for (i = bytes; i < TOTAL_PARTS; i++)
3463               if (parts[i])
3464                 warn = 1;
3465             if (warn)
3466               pedwarn ("integer constant out of range");
3467
3468             /* This is simplified by the fact that our constant
3469                is always positive.  */
3470             high = low = 0;
3471
3472             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3473               {
3474                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3475                                                     / HOST_BITS_PER_CHAR)]
3476                          << (i * HOST_BITS_PER_CHAR));
3477                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3478               }
3479             
3480             
3481             yylval.ttype = build_int_2 (low, high);
3482             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3483
3484             if (!spec_long && !spec_unsigned
3485                 && int_fits_type_p (yylval.ttype, integer_type_node))
3486               {
3487                 type = integer_type_node;
3488               }
3489             else if (!spec_long && (base != 10 || spec_unsigned)
3490                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
3491               {
3492                 /* Nondecimal constants try unsigned even in traditional C.  */
3493                 type = unsigned_type_node;
3494               }
3495
3496             else if (!spec_unsigned && !spec_long_long
3497                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
3498               type = long_integer_type_node;
3499
3500             else if (! spec_long_long
3501                      && int_fits_type_p (yylval.ttype,
3502                                          long_unsigned_type_node))
3503               type = long_unsigned_type_node;
3504
3505             else if (! spec_unsigned
3506                      /* Verify value does not overflow into sign bit.  */
3507                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
3508                      && int_fits_type_p (yylval.ttype,
3509                                          long_long_integer_type_node))
3510               type = long_long_integer_type_node;
3511
3512             else if (int_fits_type_p (yylval.ttype,
3513                                       long_long_unsigned_type_node))
3514               type = long_long_unsigned_type_node;
3515
3516             else
3517               {
3518                 type = long_long_integer_type_node;
3519                 warning ("integer constant out of range");
3520
3521                 if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
3522                   warning ("decimal integer constant is so large that it is unsigned");
3523               }
3524
3525             TREE_TYPE (yylval.ttype) = type;
3526             *p = 0;
3527           }
3528
3529         value = CONSTANT; break;
3530       }
3531
3532     case '\'':
3533     char_constant:
3534       {
3535         register int result = 0;
3536         register int num_chars = 0;
3537         unsigned width = TYPE_PRECISION (char_type_node);
3538         int max_chars;
3539
3540         if (wide_flag)
3541           {
3542             width = WCHAR_TYPE_SIZE;
3543 #ifdef MULTIBYTE_CHARS
3544             max_chars = MB_CUR_MAX;
3545 #else
3546             max_chars = 1;
3547 #endif
3548           }
3549         else
3550           max_chars = TYPE_PRECISION (integer_type_node) / width;
3551
3552         while (1)
3553           {
3554           tryagain:
3555
3556             c = getch ();
3557
3558             if (c == '\'' || c == EOF)
3559               break;
3560
3561             if (c == '\\')
3562               {
3563                 int ignore = 0;
3564                 c = readescape (&ignore);
3565                 if (ignore)
3566                   goto tryagain;
3567                 if (width < HOST_BITS_PER_INT
3568                     && (unsigned) c >= (1 << width))
3569                   warning ("escape sequence out of range for character");
3570 #ifdef MAP_CHARACTER
3571                 if (isprint (c))
3572                   c = MAP_CHARACTER (c);
3573 #endif
3574               }
3575             else if (c == '\n')
3576               {
3577                 if (pedantic)
3578                   pedwarn ("ANSI C++ forbids newline in character constant");
3579                 lineno++;
3580               }
3581 #ifdef MAP_CHARACTER
3582             else
3583               c = MAP_CHARACTER (c);
3584 #endif
3585
3586             num_chars++;
3587             if (num_chars > maxtoken - 4)
3588               extend_token_buffer (token_buffer);
3589
3590             token_buffer[num_chars] = c;
3591
3592             /* Merge character into result; ignore excess chars.  */
3593             if (num_chars < max_chars + 1)
3594               {
3595                 if (width < HOST_BITS_PER_INT)
3596                   result = (result << width) | (c & ((1 << width) - 1));
3597                 else
3598                   result = c;
3599               }
3600           }
3601
3602         token_buffer[num_chars + 1] = '\'';
3603         token_buffer[num_chars + 2] = 0;
3604
3605         if (c != '\'')
3606           error ("malformatted character constant");
3607         else if (num_chars == 0)
3608           error ("empty character constant");
3609         else if (num_chars > max_chars)
3610           {
3611             num_chars = max_chars;
3612             error ("character constant too long");
3613           }
3614         else if (num_chars != 1)
3615           warning ("multi-character character constant");
3616
3617         /* If char type is signed, sign-extend the constant.  */
3618         if (! wide_flag)
3619           {
3620             int num_bits = num_chars * width;
3621             if (num_bits == 0)
3622               /* We already got an error; avoid invalid shift.  */
3623               yylval.ttype = build_int_2 (0, 0);
3624             else if (TREE_UNSIGNED (char_type_node)
3625                      || ((result >> (num_bits - 1)) & 1) == 0)
3626               yylval.ttype
3627                 = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
3628                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
3629                                0);
3630             else
3631               yylval.ttype
3632                 = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
3633                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
3634                                -1);
3635             if (num_chars<=1)
3636               TREE_TYPE (yylval.ttype) = char_type_node;
3637             else
3638               TREE_TYPE (yylval.ttype) = integer_type_node;
3639           }
3640         else
3641           {
3642 #ifdef MULTIBYTE_CHARS
3643             /* Set the initial shift state and convert the next sequence.  */
3644             result = 0;
3645             /* In all locales L'\0' is zero and mbtowc will return zero,
3646                so don't use it.  */
3647             if (num_chars > 1
3648                 || (num_chars == 1 && token_buffer[1] != '\0'))
3649               {
3650                 wchar_t wc;
3651                 (void) mbtowc (NULL, NULL, 0);
3652                 if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
3653                   result = wc;
3654                 else
3655                   warning ("Ignoring invalid multibyte character");
3656               }
3657 #endif
3658             yylval.ttype = build_int_2 (result, 0);
3659             TREE_TYPE (yylval.ttype) = wchar_type_node;
3660           }
3661
3662         value = CONSTANT;
3663         break;
3664       }
3665
3666     case '"':
3667     string_constant:
3668       {
3669         register char *p;
3670
3671         c = getch ();
3672         p = token_buffer + 1;
3673
3674         while (c != '"' && c >= 0)
3675           {
3676             /* ignore_escape_flag is set for reading the filename in #line.  */
3677             if (!ignore_escape_flag && c == '\\')
3678               {
3679                 int ignore = 0;
3680                 c = readescape (&ignore);
3681                 if (ignore)
3682                   goto skipnewline;
3683                 if (!wide_flag
3684                     && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
3685                     && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node)))
3686                   warning ("escape sequence out of range for character");
3687               }
3688             else if (c == '\n')
3689               {
3690                 if (pedantic)
3691                   pedwarn ("ANSI C++ forbids newline in string constant");
3692                 lineno++;
3693               }
3694
3695             if (p == token_buffer + maxtoken)
3696               p = extend_token_buffer (p);
3697             *p++ = c;
3698
3699           skipnewline:
3700             c = getch ();
3701             if (c == EOF) {
3702                 error ("Unterminated string");
3703                 break;
3704             }
3705           }
3706         *p = 0;
3707
3708         /* We have read the entire constant.
3709            Construct a STRING_CST for the result.  */
3710
3711         if (wide_flag)
3712           {
3713             /* If this is a L"..." wide-string, convert the multibyte string
3714                to a wide character string.  */
3715             char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
3716             int len;
3717
3718 #ifdef MULTIBYTE_CHARS
3719             len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
3720             if (len < 0 || len >= (p - token_buffer))
3721               {
3722                 warning ("Ignoring invalid multibyte string");
3723                 len = 0;
3724               }
3725             bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
3726 #else
3727             {
3728               union { long l; char c[sizeof (long)]; } u;
3729               int big_endian;
3730               char *wp, *cp;
3731
3732               /* Determine whether host is little or big endian.  */
3733               u.l = 1;
3734               big_endian = u.c[sizeof (long) - 1];
3735               wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
3736
3737               bzero (widep, (p - token_buffer) * WCHAR_BYTES);
3738               for (cp = token_buffer + 1; cp < p; cp++)
3739                 *wp = *cp, wp += WCHAR_BYTES;
3740               len = p - token_buffer - 1;
3741             }
3742 #endif
3743             if (processing_template_decl)
3744               push_obstacks (&permanent_obstack, &permanent_obstack);
3745             yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
3746             if (processing_template_decl)
3747               pop_obstacks ();
3748             TREE_TYPE (yylval.ttype) = wchar_array_type_node;
3749           }
3750         else
3751           {
3752             if (processing_template_decl)
3753               push_obstacks (&permanent_obstack, &permanent_obstack);
3754             yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
3755             if (processing_template_decl)
3756               pop_obstacks ();
3757             TREE_TYPE (yylval.ttype) = char_array_type_node;
3758           }
3759
3760         *p++ = '"';
3761         *p = 0;
3762
3763         value = STRING; break;
3764       }
3765
3766     case '+':
3767     case '-':
3768     case '&':
3769     case '|':
3770     case '<':
3771     case '>':
3772     case '*':
3773     case '/':
3774     case '%':
3775     case '^':
3776     case '!':
3777     case '=':
3778       {
3779         register int c1;
3780
3781       combine:
3782
3783         switch (c)
3784           {
3785           case '+':
3786             yylval.code = PLUS_EXPR; break;
3787           case '-':
3788             yylval.code = MINUS_EXPR; break;
3789           case '&':
3790             yylval.code = BIT_AND_EXPR; break;
3791           case '|':
3792             yylval.code = BIT_IOR_EXPR; break;
3793           case '*':
3794             yylval.code = MULT_EXPR; break;
3795           case '/':
3796             yylval.code = TRUNC_DIV_EXPR; break;
3797           case '%':
3798             yylval.code = TRUNC_MOD_EXPR; break;
3799           case '^':
3800             yylval.code = BIT_XOR_EXPR; break;
3801           case LSHIFT:
3802             yylval.code = LSHIFT_EXPR; break;
3803           case RSHIFT:
3804             yylval.code = RSHIFT_EXPR; break;
3805           case '<':
3806             yylval.code = LT_EXPR; break;
3807           case '>':
3808             yylval.code = GT_EXPR; break;
3809           }
3810
3811         token_buffer[1] = c1 = getch ();
3812         token_buffer[2] = 0;
3813
3814         if (c1 == '=')
3815           {
3816             switch (c)
3817               {
3818               case '<':
3819                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
3820               case '>':
3821                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
3822               case '!':
3823                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
3824               case '=':
3825                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
3826               }
3827             value = ASSIGN; goto done;
3828           }
3829         else if (c == c1)
3830           switch (c)
3831             {
3832             case '+':
3833               value = PLUSPLUS; goto done;
3834             case '-':
3835               value = MINUSMINUS; goto done;
3836             case '&':
3837               value = ANDAND; goto done;
3838             case '|':
3839               value = OROR; goto done;
3840             case '<':
3841               c = LSHIFT;
3842               goto combine;
3843             case '>':
3844               c = RSHIFT;
3845               goto combine;
3846             }
3847         else if ((c == '-') && (c1 == '>'))
3848           {
3849             nextchar = getch ();
3850             if (nextchar == '*')
3851               {
3852                 nextchar = -1;
3853                 value = POINTSAT_STAR;
3854               }
3855             else
3856               value = POINTSAT;
3857             goto done;
3858           }
3859         else if (c1 == '?' && (c == '<' || c == '>'))
3860           {
3861             token_buffer[3] = 0;
3862
3863             c1 = getch ();
3864             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
3865             if (c1 == '=')
3866               {
3867                 /* <?= or >?= expression.  */
3868                 token_buffer[2] = c1;
3869                 value = ASSIGN;
3870               }
3871             else
3872               {
3873                 value = MIN_MAX;
3874                 nextchar = c1;
3875               }
3876             if (pedantic)
3877               pedwarn ("use of `operator %s' is not standard C++",
3878                        token_buffer);
3879             goto done;
3880           }
3881         /* digraphs */
3882         else if (c == '<' && c1 == '%')
3883           { value = '{'; goto done; }
3884         else if (c == '<' && c1 == ':')
3885           { value = '['; goto done; }
3886         else if (c == '%' && c1 == '>')
3887           { value = '}'; goto done; }
3888         else if (c == '%' && c1 == ':')
3889           { value = '#'; goto done; }
3890
3891         nextchar = c1;
3892         token_buffer[1] = 0;
3893
3894         value = c;
3895         goto done;
3896       }
3897
3898     case ':':
3899       c = getch ();
3900       if (c == ':')
3901         {
3902           token_buffer[1] = ':';
3903           token_buffer[2] = '\0';
3904           value = SCOPE;
3905           yylval.itype = 1;
3906         }
3907       else if (c == '>')
3908         {
3909           value = ']';
3910           goto done;
3911         }
3912       else
3913         {
3914           nextchar = c;
3915           value = ':';
3916         }
3917       break;
3918
3919     case 0:
3920       /* Don't make yyparse think this is eof.  */
3921       value = 1;
3922       break;
3923
3924     case '(':
3925       /* try, weakly, to handle casts to pointers to functions.  */
3926       nextchar = skip_white_space (getch ());
3927       if (nextchar == '*')
3928         {
3929           int next_c = skip_white_space (getch ());
3930           if (next_c == ')')
3931             {
3932               nextchar = -1;
3933               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
3934               value = PAREN_STAR_PAREN;
3935             }
3936           else
3937             {
3938               put_back (next_c);
3939               value = c;
3940             }
3941         }
3942       else if (nextchar == ')')
3943         {
3944           nextchar = -1;
3945           yylval.ttype = NULL_TREE;
3946           value = LEFT_RIGHT;
3947         }
3948       else value = c;
3949       break;
3950
3951     default:
3952       value = c;
3953     }
3954
3955 done:
3956 /*  yylloc.last_line = lineno; */
3957 #ifdef GATHER_STATISTICS
3958 #ifdef REDUCE_LENGTH
3959   token_count[value] += 1;
3960 #endif
3961 #endif
3962
3963   return value;
3964 }
3965
3966 int
3967 is_rid (t)
3968      tree t;
3969 {
3970   return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
3971 }
3972
3973 #ifdef GATHER_STATISTICS
3974 /* The original for tree_node_kind is in the toplevel tree.c; changes there
3975    need to be brought into here, unless this were actually put into a header
3976    instead.  */
3977 /* Statistics-gathering stuff.  */
3978 typedef enum
3979 {
3980   d_kind,
3981   t_kind,
3982   b_kind,
3983   s_kind,
3984   r_kind,
3985   e_kind,
3986   c_kind,
3987   id_kind,
3988   op_id_kind,
3989   perm_list_kind,
3990   temp_list_kind,
3991   vec_kind,
3992   x_kind,
3993   lang_decl,
3994   lang_type,
3995   all_kinds
3996 } tree_node_kind;
3997
3998 extern int tree_node_counts[];
3999 extern int tree_node_sizes[];
4000 #endif
4001
4002 /* Place to save freed lang_decls which were allocated on the
4003    permanent_obstack.  @@ Not currently used.  */
4004 tree free_lang_decl_chain;
4005
4006 tree
4007 build_lang_decl (code, name, type)
4008      enum tree_code code;
4009      tree name;
4010      tree type;
4011 {
4012   register tree t = build_decl (code, name, type);
4013   struct obstack *obstack = current_obstack;
4014   register int i = sizeof (struct lang_decl) / sizeof (int);
4015   register int *pi;
4016
4017   if (! TREE_PERMANENT (t))
4018     obstack = saveable_obstack;
4019   else
4020     /* Could be that saveable is permanent and current is not.  */
4021     obstack = &permanent_obstack;
4022
4023   if (free_lang_decl_chain && obstack == &permanent_obstack)
4024     {
4025       pi = (int *)free_lang_decl_chain;
4026       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4027     }
4028   else
4029     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4030
4031   while (i > 0)
4032     pi[--i] = 0;
4033
4034   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4035   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4036     = obstack == &permanent_obstack;
4037   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4038           == TREE_PERMANENT  (t), 234);
4039   DECL_MAIN_VARIANT (t) = t;
4040   if (current_lang_name == lang_name_cplusplus)
4041     DECL_LANGUAGE (t) = lang_cplusplus;
4042   else if (current_lang_name == lang_name_c)
4043     DECL_LANGUAGE (t) = lang_c;
4044   else my_friendly_abort (64);
4045
4046 #if 0 /* not yet, should get fixed properly later */
4047   if (code == TYPE_DECL)
4048     {
4049       tree id;
4050       id = get_identifier (build_overload_name (type, 1, 1));
4051       DECL_ASSEMBLER_NAME (t) = id;
4052     }
4053
4054 #endif
4055 #ifdef GATHER_STATISTICS
4056   tree_node_counts[(int)lang_decl] += 1;
4057   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4058 #endif
4059
4060   return t;
4061 }
4062
4063 tree
4064 build_lang_field_decl (code, name, type)
4065      enum tree_code code;
4066      tree name;
4067      tree type;
4068 {
4069   extern struct obstack *current_obstack, *saveable_obstack;
4070   register tree t = build_decl (code, name, type);
4071   struct obstack *obstack = current_obstack;
4072   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4073   register int *pi;
4074 #if 0 /* not yet, should get fixed properly later */
4075
4076   if (code == TYPE_DECL)
4077     {
4078       tree id;
4079       id = get_identifier (build_overload_name (type, 1, 1));
4080       DECL_ASSEMBLER_NAME (t) = id;
4081     }
4082 #endif
4083
4084   if (! TREE_PERMANENT (t))
4085     obstack = saveable_obstack;
4086   else
4087     my_friendly_assert (obstack == &permanent_obstack, 235);
4088
4089   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4090   while (i > 0)
4091     pi[--i] = 0;
4092
4093   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4094   return t;
4095 }
4096
4097 void
4098 copy_lang_decl (node)
4099      tree node;
4100 {
4101   int size;
4102   int *pi;
4103
4104   if (! DECL_LANG_SPECIFIC (node))
4105     return;
4106
4107   if (TREE_CODE (node) == FIELD_DECL)
4108     size = sizeof (struct lang_decl_flags);
4109   else
4110     size = sizeof (struct lang_decl);
4111   pi = (int *)obstack_alloc (&permanent_obstack, size);
4112   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4113   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4114 }
4115
4116 tree
4117 make_lang_type (code)
4118      enum tree_code code;
4119 {
4120   extern struct obstack *current_obstack, *saveable_obstack;
4121   register tree t = make_node (code);
4122   struct obstack *obstack = current_obstack;
4123   register int i = sizeof (struct lang_type) / sizeof (int);
4124   register int *pi;
4125
4126   /* Set up some flags that give proper default behavior.  */
4127   IS_AGGR_TYPE (t) = 1;
4128
4129   if (! TREE_PERMANENT (t))
4130     obstack = saveable_obstack;
4131   else
4132     my_friendly_assert (obstack == &permanent_obstack, 236);
4133
4134   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
4135   while (i > 0)
4136     pi[--i] = 0;
4137
4138   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
4139   CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
4140   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4141   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4142   CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
4143   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
4144                                NULL_TREE);
4145   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4146
4147   /* Make sure this is laid out, for ease of use later.
4148      In the presence of parse errors, the normal was of assuring
4149      this might not ever get executed, so we lay it out *immediately*.  */
4150   build_pointer_type (t);
4151
4152 #ifdef GATHER_STATISTICS
4153   tree_node_counts[(int)lang_type] += 1;
4154   tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
4155 #endif
4156
4157   return t;
4158 }
4159
4160 void
4161 copy_decl_lang_specific (decl)
4162      tree decl;
4163 {
4164   extern struct obstack *current_obstack, *saveable_obstack;
4165   register int *old = (int *)DECL_LANG_SPECIFIC (decl);
4166   struct obstack *obstack = current_obstack;
4167   register int i = sizeof (struct lang_decl) / sizeof (int);
4168   register int *pi;
4169
4170   if (! TREE_PERMANENT (decl))
4171     obstack = saveable_obstack;
4172   else
4173     my_friendly_assert (obstack == &permanent_obstack, 237);
4174
4175   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4176   while (i-- > 0)
4177     pi[i] = old[i];
4178
4179   DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
4180
4181 #ifdef GATHER_STATISTICS
4182   tree_node_counts[(int)lang_decl] += 1;
4183   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4184 #endif
4185 }
4186
4187 void
4188 dump_time_statistics ()
4189 {
4190   register tree prev = 0, decl, next;
4191   int this_time = my_get_run_time ();
4192   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
4193     += this_time - body_time;
4194
4195   fprintf (stderr, "\n******\n");
4196   print_time ("header files (total)", header_time);
4197   print_time ("main file (total)", this_time - body_time);
4198   fprintf (stderr, "ratio = %g : 1\n",
4199            (double)header_time / (double)(this_time - body_time));
4200   fprintf (stderr, "\n******\n");
4201
4202   for (decl = filename_times; decl; decl = next)
4203     {
4204       next = IDENTIFIER_GLOBAL_VALUE (decl);
4205       IDENTIFIER_GLOBAL_VALUE (decl) = prev;
4206       prev = decl;
4207     }
4208
4209   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4210     print_time (IDENTIFIER_POINTER (decl),
4211                 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4212 }
4213
4214 void
4215 compiler_error (s, v, v2)
4216      char *s;
4217      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4218 {
4219   char buf[1024];
4220   sprintf (buf, s, v, v2);
4221   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4222 }
4223 \f
4224 void
4225 yyerror (string)
4226      char *string;
4227 {
4228   extern int end_of_file;
4229   char buf[200];
4230
4231   strcpy (buf, string);
4232
4233   /* We can't print string and character constants well
4234      because the token_buffer contains the result of processing escapes.  */
4235   if (end_of_file)
4236     strcat (buf, input_redirected ()
4237             ? " at end of saved text"
4238             : " at end of input");
4239   else if (token_buffer[0] == 0)
4240     strcat (buf, " at null character");
4241   else if (token_buffer[0] == '"')
4242     strcat (buf, " before string constant");
4243   else if (token_buffer[0] == '\'')
4244     strcat (buf, " before character constant");
4245   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
4246     sprintf (buf + strlen (buf), " before character 0%o",
4247              (unsigned char) token_buffer[0]);
4248   else
4249     strcat (buf, " before `%s'");
4250
4251   error (buf, token_buffer);
4252 }
4253 \f
4254 static int
4255 handle_cp_pragma (pname)
4256      char *pname;
4257 {
4258   register int token;
4259
4260   if (! strcmp (pname, "vtable"))
4261     {
4262       extern tree pending_vtables;
4263
4264       /* More follows: it must be a string constant (class name).  */
4265       token = real_yylex ();
4266       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4267         {
4268           error ("invalid #pragma vtable");
4269           return -1;
4270         }
4271
4272       if (write_virtuals != 2)
4273         {
4274           warning ("use `+e2' option to enable #pragma vtable");
4275           return -1;
4276         }
4277       pending_vtables
4278         = perm_tree_cons (NULL_TREE,
4279                           get_identifier (TREE_STRING_POINTER (yylval.ttype)),
4280                           pending_vtables);
4281       token = real_yylex ();
4282       if (token != END_OF_LINE)
4283         warning ("trailing characters ignored");
4284       return 1;
4285     }
4286   else if (! strcmp (pname, "unit"))
4287     {
4288       /* More follows: it must be a string constant (unit name).  */
4289       token = real_yylex ();
4290       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4291         {
4292           error ("invalid #pragma unit");
4293           return -1;
4294         }
4295       token = real_yylex ();
4296       if (token != END_OF_LINE)
4297         warning ("trailing characters ignored");
4298       return 1;
4299     }
4300   else if (! strcmp (pname, "interface"))
4301     {
4302       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
4303       char *main_filename = input_filename;
4304
4305       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
4306
4307       token = real_yylex ();
4308       
4309       if (token != END_OF_LINE)
4310         {
4311           if (token != STRING
4312               || TREE_CODE (yylval.ttype) != STRING_CST)
4313             {
4314               error ("invalid `#pragma interface'");
4315               return -1;
4316             }
4317           main_filename = TREE_STRING_POINTER (yylval.ttype);
4318           token = real_yylex ();
4319         }
4320
4321       if (token != END_OF_LINE)
4322         warning ("garbage after `#pragma interface' ignored");
4323
4324 #ifndef NO_LINKAGE_HEURISTICS
4325       write_virtuals = 3;
4326
4327       if (impl_file_chain == 0)
4328         {
4329           /* If this is zero at this point, then we are
4330              auto-implementing.  */
4331           if (main_input_filename == 0)
4332             main_input_filename = input_filename;
4333
4334 #ifdef AUTO_IMPLEMENT
4335           filename = FILE_NAME_NONDIRECTORY (main_input_filename);
4336           fi = get_time_identifier (filename);
4337           fi = IDENTIFIER_CLASS_VALUE (fi);
4338           TREE_INT_CST_LOW (fi) = 0;
4339           TREE_INT_CST_HIGH (fi) = 1;
4340           /* Get default.  */
4341           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
4342           impl_file_chain->filename = filename;
4343           impl_file_chain->next = 0;
4344 #endif
4345         }
4346
4347       interface_only = interface_strcmp (main_filename);
4348       interface_unknown = 0;
4349       TREE_INT_CST_LOW (fileinfo) = interface_only;
4350       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4351 #endif /* NO_LINKAGE_HEURISTICS */
4352
4353       return 1;
4354     }
4355   else if (! strcmp (pname, "implementation"))
4356     {
4357       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
4358       char *main_filename = main_input_filename ? main_input_filename : input_filename;
4359
4360       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
4361       token = real_yylex ();
4362       if (token != END_OF_LINE)
4363         {
4364           if (token != STRING
4365               || TREE_CODE (yylval.ttype) != STRING_CST)
4366             {
4367               error ("invalid `#pragma implementation'");
4368               return -1;
4369             }
4370           main_filename = TREE_STRING_POINTER (yylval.ttype);
4371           token = real_yylex ();
4372         }
4373
4374       if (token != END_OF_LINE)
4375         warning ("garbage after `#pragma implementation' ignored");
4376
4377 #ifndef NO_LINKAGE_HEURISTICS
4378       if (write_virtuals == 3)
4379         {
4380           struct impl_files *ifiles = impl_file_chain;
4381           while (ifiles)
4382             {
4383               if (! strcmp (ifiles->filename, main_filename))
4384                 break;
4385               ifiles = ifiles->next;
4386             }
4387           if (ifiles == 0)
4388             {
4389               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
4390               ifiles->filename = main_filename;
4391               ifiles->next = impl_file_chain;
4392               impl_file_chain = ifiles;
4393             }
4394         }
4395       else if ((main_input_filename != 0
4396                 && ! strcmp (main_input_filename, input_filename))
4397                || ! strcmp (input_filename, main_filename))
4398         {
4399           write_virtuals = 3;
4400           if (impl_file_chain == 0)
4401             {
4402               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
4403               impl_file_chain->filename = main_filename;
4404               impl_file_chain->next = 0;
4405             }
4406         }
4407       else
4408         error ("`#pragma implementation' can only appear at top-level");
4409       interface_only = 0;
4410 #if 1
4411       /* We make this non-zero so that we infer decl linkage
4412          in the impl file only for variables first declared
4413          in the interface file.  */
4414       interface_unknown = 1;
4415 #else
4416       /* We make this zero so that templates in the impl
4417          file will be emitted properly.  */
4418       interface_unknown = 0;
4419 #endif
4420       TREE_INT_CST_LOW (fileinfo) = interface_only;
4421       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4422 #endif /* NO_LINKAGE_HEURISTICS */
4423
4424       return 1;
4425     }
4426
4427   return 0;
4428 }
4429 \f
4430 #ifdef HANDLE_SYSV_PRAGMA
4431
4432 /* Handle a #pragma directive.  INPUT is the current input stream,
4433    and C is a character to reread.  Processes the entire input line
4434    and returns a character for the caller to reread: either \n or EOF.  */
4435
4436 /* This function has to be in this file, in order to get at
4437    the token types.  */
4438
4439 static int
4440 handle_sysv_pragma (finput, token)
4441      FILE *finput;
4442      register int token;
4443 {
4444   for (;;)
4445     {
4446       switch (token)
4447         {
4448         case IDENTIFIER:
4449         case TYPENAME:
4450         case STRING:
4451         case CONSTANT:
4452           handle_pragma_token ("ignored", yylval.ttype);
4453           break;
4454         case '(':
4455           handle_pragma_token ("(", NULL_TREE);
4456           break;
4457         case ')':
4458           handle_pragma_token (")", NULL_TREE);
4459           break;
4460         case ',':
4461           handle_pragma_token (",", NULL_TREE);
4462           break;
4463         case '=':
4464           handle_pragma_token ("=", NULL_TREE);
4465           break;
4466         case LEFT_RIGHT:
4467           handle_pragma_token ("(", NULL_TREE);
4468           handle_pragma_token (")", NULL_TREE);
4469           break;
4470         case END_OF_LINE:
4471         default:
4472           handle_pragma_token (NULL_PTR, NULL_TREE);
4473           return 1;
4474         }
4475       token = real_yylex ();
4476     }
4477 }
4478 #endif /* HANDLE_SYSV_PRAGMA */