OSDN Git Service

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