OSDN Git Service

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