OSDN Git Service

* pt.c (unify): Call coerce_template_parms with the COMPLAIN flag
[pf3gnuchains/gcc-fork.git] / gcc / cp / lex.c
1 /* Separate lexical analyzer for GNU C++.
2    Copyright (C) 1987, 89, 92-98, 1999 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 static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
88
89 /* Given a file name X, return the nondirectory portion.
90    Keep in mind that X can be computed more than once.  */
91 char *
92 file_name_nondirectory (x)
93      char *x;
94 {
95   char *tmp = (char *) rindex (x, '/');
96   if (DIR_SEPARATOR != '/' && ! tmp)
97     tmp = (char *) rindex (x, DIR_SEPARATOR);
98   if (tmp)
99     return (char *) (tmp + 1);
100   else
101     return x;
102 }
103
104 /* This obstack is needed to hold text.  It is not safe to use
105    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
106 struct obstack inline_text_obstack;
107 char *inline_text_firstobj;
108
109 #if USE_CPPLIB
110 #include "cpplib.h"
111 extern cpp_reader  parse_in;
112 extern cpp_options parse_options;
113 extern unsigned char *yy_cur, *yy_lim;
114 #else
115 FILE *finput;
116 #endif
117 int end_of_file;
118
119 /* Pending language change.
120    Positive is push count, negative is pop count.  */
121 int pending_lang_change = 0;
122
123 /* Wrap the current header file in extern "C".  */
124 static int c_header_level = 0;
125
126 extern int first_token;
127 extern struct obstack token_obstack;
128
129 /* ??? Don't really know where this goes yet.  */
130 #if 1
131 #include "input.c"
132 #else
133 extern void put_back (/* int */);
134 extern int input_redirected ();
135 extern void feed_input (/* char *, int */);
136 #endif
137
138 /* Holds translations from TREE_CODEs to operator name strings,
139    i.e., opname_tab[PLUS_EXPR] == "+".  */
140 char **opname_tab;
141 char **assignop_tab;
142 \f
143 extern int yychar;              /*  the lookahead symbol                */
144 extern YYSTYPE yylval;          /*  the semantic value of the           */
145                                 /*  lookahead symbol                    */
146
147 #if 0
148 YYLTYPE yylloc;                 /*  location data for the lookahead     */
149                                 /*  symbol                              */
150 #endif
151
152
153 /* the declaration found for the last IDENTIFIER token read in.
154    yylex must look this up to detect typedefs, which get token type TYPENAME,
155    so it is left around in case the identifier is not a typedef but is
156    used in a context which makes it a reference to a variable.  */
157 tree lastiddecl;
158
159 /* The elements of `ridpointers' are identifier nodes
160    for the reserved type names and storage classes.
161    It is indexed by a RID_... value.  */
162 tree ridpointers[(int) RID_MAX];
163
164 /* We may keep statistics about how long which files took to compile.  */
165 static int header_time, body_time;
166 static tree filename_times;
167 static tree this_filename_time;
168
169 /* Array for holding counts of the numbers of tokens seen.  */
170 extern int *token_count;
171 \f
172 /* Return something to represent absolute declarators containing a *.
173    TARGET is the absolute declarator that the * contains.
174    CV_QUALIFIERS is a list of modifiers such as const or volatile
175    to apply to the pointer type, represented as identifiers.
176
177    We return an INDIRECT_REF whose "contents" are TARGET
178    and whose type is the modifier list.  */
179
180 tree
181 make_pointer_declarator (cv_qualifiers, target)
182      tree cv_qualifiers, target;
183 {
184   if (target && TREE_CODE (target) == IDENTIFIER_NODE
185       && ANON_AGGRNAME_P (target))
186     error ("type name expected before `*'");
187   target = build_parse_node (INDIRECT_REF, target);
188   TREE_TYPE (target) = cv_qualifiers;
189   return target;
190 }
191
192 /* Return something to represent absolute declarators containing a &.
193    TARGET is the absolute declarator that the & contains.
194    CV_QUALIFIERS is a list of modifiers such as const or volatile
195    to apply to the reference type, represented as identifiers.
196
197    We return an ADDR_EXPR whose "contents" are TARGET
198    and whose type is the modifier list.  */
199    
200 tree
201 make_reference_declarator (cv_qualifiers, target)
202      tree cv_qualifiers, target;
203 {
204   if (target)
205     {
206       if (TREE_CODE (target) == ADDR_EXPR)
207         {
208           error ("cannot declare references to references");
209           return target;
210         }
211       if (TREE_CODE (target) == INDIRECT_REF)
212         {
213           error ("cannot declare pointers to references");
214           return target;
215         }
216       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
217           error ("type name expected before `&'");
218     }
219   target = build_parse_node (ADDR_EXPR, target);
220   TREE_TYPE (target) = cv_qualifiers;
221   return target;
222 }
223
224 tree
225 make_call_declarator (target, parms, cv_qualifiers, exception_specification)
226      tree target, parms, cv_qualifiers, exception_specification;
227 {
228   target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
229   TREE_TYPE (target) = exception_specification;
230   return target;
231 }
232
233 void
234 set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
235      tree call_declarator, cv_qualifiers, exception_specification;
236 {
237   TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
238   TREE_TYPE (call_declarator) = exception_specification;
239 }
240 \f
241 /* Build names and nodes for overloaded operators.  */
242
243 tree ansi_opname[LAST_CPLUS_TREE_CODE];
244 tree ansi_assopname[LAST_CPLUS_TREE_CODE];
245
246 char *
247 operator_name_string (name)
248      tree name;
249 {
250   char *opname = IDENTIFIER_POINTER (name) + 2;
251   tree *opname_table;
252   int i, assign;
253
254   /* Works for builtin and user defined types.  */
255   if (IDENTIFIER_GLOBAL_VALUE (name)
256       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
257     return IDENTIFIER_POINTER (name);
258
259   if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
260     {
261       opname += 1;
262       assign = 1;
263       opname_table = ansi_assopname;
264     }
265   else
266     {
267       assign = 0;
268       opname_table = ansi_opname;
269     }
270
271   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
272     {
273       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
274           && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
275         break;
276     }
277
278   if (i == LAST_CPLUS_TREE_CODE)
279     return "<invalid operator>";
280
281   if (assign)
282     return assignop_tab[i];
283   else
284     return opname_tab[i];
285 }
286 \f
287 int interface_only;             /* whether or not current file is only for
288                                    interface definitions.  */
289 int interface_unknown;          /* whether or not we know this class
290                                    to behave according to #pragma interface.  */
291
292 /* lexical analyzer */
293
294 #ifndef WCHAR_TYPE_SIZE
295 #ifdef INT_TYPE_SIZE
296 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
297 #else
298 #define WCHAR_TYPE_SIZE BITS_PER_WORD
299 #endif
300 #endif
301
302 /* Number of bytes in a wide character.  */
303 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
304
305 static int maxtoken;            /* Current nominal length of token buffer.  */
306 char *token_buffer;             /* Pointer to token buffer.
307                                    Actual allocated length is maxtoken + 2.  */
308
309 #include "hash.h"
310 \f
311
312 /* Nonzero tells yylex to ignore \ in string constants.  */
313 static int ignore_escape_flag = 0;
314
315 static tree
316 get_time_identifier (name)
317      char *name;
318 {
319   tree time_identifier;
320   int len = strlen (name);
321   char *buf = (char *) alloca (len + 6);
322   strcpy (buf, "file ");
323   bcopy (name, buf+5, len);
324   buf[len+5] = '\0';
325   time_identifier = get_identifier (buf);
326   if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
327     {
328       push_obstacks_nochange ();
329       end_temporary_allocation ();
330       TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
331       TIME_IDENTIFIER_FILEINFO (time_identifier) 
332         = build_int_2 (0, 1);
333       SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
334       filename_times = time_identifier;
335       pop_obstacks ();
336     }
337   return time_identifier;
338 }
339
340 #ifdef __GNUC__
341 __inline
342 #endif
343 static int
344 my_get_run_time ()
345 {
346   int old_quiet_flag = quiet_flag;
347   int this_time;
348   quiet_flag = 0;
349   this_time = get_run_time ();
350   quiet_flag = old_quiet_flag;
351   return this_time;
352 }
353 \f
354 /* Table indexed by tree code giving a string containing a character
355    classifying the tree code.  Possibilities are
356    t, d, s, c, r, <, 1 and 2.  See cp/cp-tree.def for details.  */
357
358 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
359
360 char cplus_tree_code_type[] = {
361   'x',
362 #include "cp-tree.def"
363 };
364 #undef DEFTREECODE
365
366 /* Table indexed by tree code giving number of expression
367    operands beyond the fixed part of the node structure.
368    Not used for types or decls.  */
369
370 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
371
372 int cplus_tree_code_length[] = {
373   0,
374 #include "cp-tree.def"
375 };
376 #undef DEFTREECODE
377
378 /* Names of tree components.
379    Used for printing out the tree and error messages.  */
380 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
381
382 char *cplus_tree_code_name[] = {
383   "@@dummy",
384 #include "cp-tree.def"
385 };
386 #undef DEFTREECODE
387 \f
388 /* toplev.c needs to call these.  */
389
390 void
391 lang_init_options ()
392 {
393 #if USE_CPPLIB
394   cpp_reader_init (&parse_in);
395   parse_in.opts = &parse_options;
396   cpp_options_init (&parse_options);
397 #endif
398
399   /* Default exceptions on.  */
400   flag_exceptions = 1;
401 }
402
403 void
404 lang_init ()
405 {
406   /* the beginning of the file is a new line; check for # */
407   /* With luck, we discover the real source file's name from that
408      and put it in input_filename.  */
409 #if ! USE_CPPLIB
410   put_back (check_newline ());
411 #else
412   check_newline ();
413   yy_cur--;
414 #endif
415   if (flag_gnu_xref) GNU_xref_begin (input_filename);
416   init_repo (input_filename);
417 }
418
419 void
420 lang_finish ()
421 {
422   extern int errorcount, sorrycount;
423   if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
424 }
425
426 char *
427 lang_identify ()
428 {
429   return "cplusplus";
430 }
431
432 void
433 init_filename_times ()
434 {
435   this_filename_time = get_time_identifier ("<top level>");
436   if (flag_detailed_statistics)
437     {
438       header_time = 0;
439       body_time = my_get_run_time ();
440       TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) 
441         = body_time;
442     }
443 }
444
445 /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
446    Stuck this hack in to get the files open correctly; this is called
447    in place of init_parse if we are an unexec'd binary.    */
448
449 #if 0
450 void
451 reinit_lang_specific ()
452 {
453   init_filename_times ();
454   reinit_search_statistics ();
455 }
456 #endif
457
458 static int *
459 init_cpp_parse ()
460 {
461 #ifdef GATHER_STATISTICS
462 #ifdef REDUCE_LENGTH
463   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
464   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
465   reduce_count += 1;
466   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
467   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
468   token_count += 1;
469 #endif
470 #endif
471   return token_count;
472 }
473
474 char *
475 init_parse (filename)
476      char *filename;
477 {
478   extern int flag_no_gnu_keywords;
479   extern int flag_operator_names;
480
481   int i;
482
483 #ifdef MULTIBYTE_CHARS
484   /* Change to the native locale for multibyte conversions.  */
485   setlocale (LC_CTYPE, "");
486   literal_codeset = getenv ("LANG");
487 #endif
488
489 #if USE_CPPLIB
490   parse_in.show_column = 1;
491   if (! cpp_start_read (&parse_in, filename))
492     abort ();
493
494   /* cpp_start_read always puts at least one line directive into the
495      token buffer.  We must arrange to read it out here. */
496   yy_cur = parse_in.token_buffer;
497   yy_lim = CPP_PWRITTEN (&parse_in);
498
499 #else
500   /* Open input file.  */
501   if (filename == 0 || !strcmp (filename, "-"))
502     {
503       finput = stdin;
504       filename = "stdin";
505     }
506   else
507     finput = fopen (filename, "r");
508   if (finput == 0)
509     pfatal_with_name (filename);
510
511 #ifdef IO_BUFFER_SIZE
512   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
513 #endif
514 #endif /* !USE_CPPLIB */
515
516   /* Initialize the lookahead machinery.  */
517   init_spew ();
518
519   /* Make identifier nodes long enough for the language-specific slots.  */
520   set_identifier_size (sizeof (struct lang_identifier));
521   decl_printable_name = lang_printable_name;
522
523   init_cplus_expand ();
524
525   bcopy (cplus_tree_code_type,
526          tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
527          (int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
528   bcopy ((char *)cplus_tree_code_length,
529          (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
530          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
531   bcopy ((char *)cplus_tree_code_name,
532          (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
533          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
534
535   opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
536   bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
537   assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
538   bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
539
540   ansi_opname[0] = get_identifier ("<invalid operator>");
541   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
542     {
543       ansi_opname[i] = ansi_opname[0];
544       ansi_assopname[i] = ansi_opname[0];
545     }
546
547   ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
548   IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
549   ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
550   ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
551   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
552   ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
553   ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
554   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
555   ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
556   IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
557   ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
558   ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
559   ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
560   ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
561   IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
562   ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
563   ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
564   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
565   ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
566   ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
567   IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
568   ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
569   IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
570   ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
571   IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
572   ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
573   IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
574   ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
575   IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
576   ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
577   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
578   ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
579   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
580   ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
581   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
582   ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
583   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
584   ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
585   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
586   ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
587   ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
588   IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
589   ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
590   ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
591   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
592   ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
593   IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
594   ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
595   IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
596   ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
597   ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
598   ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
599   ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
600   ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
601   ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
602   ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
603   ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
604   ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
605   IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
606   ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
607   IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
608   ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
609   ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
610   ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
611   IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
612   ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
613   IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
614   ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
615   IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
616   ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
617   IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
618   ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
619   IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
620   ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
621   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
622   ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
623   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
624   ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
625   ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
626   ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
627   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
628   ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
629   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
630   ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
631   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
632   ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
633   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
634   ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
635   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
636   ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
637   ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
638   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
639   ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
640   IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
641   ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
642   IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
643   ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
644   IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
645   ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
646   IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
647   ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
648   IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
649   ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
650   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
651   ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
652   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
653   ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT);
654   IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
655
656   /* This is not true: these operators are not defined in ANSI,
657      but we need them anyway.  */
658   ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
659   IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
660   ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
661   IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
662   ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
663   IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
664   ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz");
665   IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1;
666
667   init_method ();
668   init_error ();
669   gcc_obstack_init (&inline_text_obstack);
670   inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
671
672   /* Start it at 0, because check_newline is called at the very beginning
673      and will increment it to 1.  */
674   lineno = 0;
675   input_filename = "<internal>";
676   current_function_decl = NULL;
677
678   maxtoken = 40;
679   token_buffer = (char *) xmalloc (maxtoken + 2);
680
681   ridpointers[(int) RID_INT] = get_identifier ("int");
682   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
683                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
684   ridpointers[(int) RID_BOOL] = get_identifier ("bool");
685   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
686                           build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
687   ridpointers[(int) RID_CHAR] = get_identifier ("char");
688   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
689                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
690   ridpointers[(int) RID_VOID] = get_identifier ("void");
691   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
692                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
693   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
694   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
695                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
696   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
697   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
698                           build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
699   ridpointers[(int) RID_SHORT] = get_identifier ("short");
700   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
701                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
702   ridpointers[(int) RID_LONG] = get_identifier ("long");
703   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
704                           build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
705   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
706   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
707                           build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
708   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
709   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
710                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
711   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
712   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
713                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
714   ridpointers[(int) RID_CONST] = get_identifier ("const");
715   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
716                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
717   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
718   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
719                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
720   ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
721   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT],
722                           build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT]));
723   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
724   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
725                           build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
726   ridpointers[(int) RID_STATIC] = get_identifier ("static");
727   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
728                           build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
729   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
730   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
731                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
732   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
733   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
734                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
735   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
736   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
737                           build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
738   ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex");
739   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX],
740                           build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX]));
741
742   /* C++ extensions. These are probably not correctly named.  */
743   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
744   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
745                           build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
746   class_type_node = build_int_2 (class_type, 0);
747   TREE_TYPE (class_type_node) = class_type_node;
748   ridpointers[(int) RID_CLASS] = class_type_node;
749
750   record_type_node = build_int_2 (record_type, 0);
751   TREE_TYPE (record_type_node) = record_type_node;
752   ridpointers[(int) RID_RECORD] = record_type_node;
753
754   union_type_node = build_int_2 (union_type, 0);
755   TREE_TYPE (union_type_node) = union_type_node;
756   ridpointers[(int) RID_UNION] = union_type_node;
757
758   enum_type_node = build_int_2 (enum_type, 0);
759   TREE_TYPE (enum_type_node) = enum_type_node;
760   ridpointers[(int) RID_ENUM] = enum_type_node;
761
762   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
763   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
764                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
765   ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
766   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT],
767                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT]));
768   ridpointers[(int) RID_EXPORT] = get_identifier ("export");
769   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPORT],
770                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPORT]));
771   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
772   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
773                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
774
775   ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
776   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
777                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
778   ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
779   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
780                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
781   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
782   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
783                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
784   ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
785   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
786                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
787   /* This is for ANSI C++.  */
788   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
789   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
790                           build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
791
792   /* Signature handling extensions.  */
793   signature_type_node = build_int_2 (signature_type, 0);
794   TREE_TYPE (signature_type_node) = signature_type_node;
795   ridpointers[(int) RID_SIGNATURE] = signature_type_node;
796
797   /* Create the built-in __null node.  Note that we can't yet call for
798      type_for_size here because integer_type_node and so forth are not
799      set up.  Therefore, we don't set the type of these nodes until
800      init_decl_processing.  */
801   null_node = build_int_2 (0, 0);
802   ridpointers[RID_NULL] = null_node;
803
804   opname_tab[(int) COMPONENT_REF] = "->";
805   opname_tab[(int) MEMBER_REF] = "->*";
806   opname_tab[(int) INDIRECT_REF] = "*";
807   opname_tab[(int) ARRAY_REF] = "[]";
808   opname_tab[(int) MODIFY_EXPR] = "=";
809   opname_tab[(int) NEW_EXPR] = "new";
810   opname_tab[(int) DELETE_EXPR] = "delete";
811   opname_tab[(int) VEC_NEW_EXPR] = "new []";
812   opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
813   opname_tab[(int) COND_EXPR] = "?:";
814   opname_tab[(int) CALL_EXPR] = "()";
815   opname_tab[(int) PLUS_EXPR] = "+";
816   opname_tab[(int) MINUS_EXPR] = "-";
817   opname_tab[(int) MULT_EXPR] = "*";
818   opname_tab[(int) TRUNC_DIV_EXPR] = "/";
819   opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
820   opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
821   opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
822   opname_tab[(int) TRUNC_MOD_EXPR] = "%";
823   opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
824   opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
825   opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
826   opname_tab[(int) NEGATE_EXPR] = "-";
827   opname_tab[(int) MIN_EXPR] = "<?";
828   opname_tab[(int) MAX_EXPR] = ">?";
829   opname_tab[(int) ABS_EXPR] = "abs";
830   opname_tab[(int) FFS_EXPR] = "ffs";
831   opname_tab[(int) LSHIFT_EXPR] = "<<";
832   opname_tab[(int) RSHIFT_EXPR] = ">>";
833   opname_tab[(int) BIT_IOR_EXPR] = "|";
834   opname_tab[(int) BIT_XOR_EXPR] = "^";
835   opname_tab[(int) BIT_AND_EXPR] = "&";
836   opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
837   opname_tab[(int) BIT_NOT_EXPR] = "~";
838   opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
839   opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
840   opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
841   opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
842   opname_tab[(int) TRUTH_NOT_EXPR] = "!";
843   opname_tab[(int) LT_EXPR] = "<";
844   opname_tab[(int) LE_EXPR] = "<=";
845   opname_tab[(int) GT_EXPR] = ">";
846   opname_tab[(int) GE_EXPR] = ">=";
847   opname_tab[(int) EQ_EXPR] = "==";
848   opname_tab[(int) NE_EXPR] = "!=";
849   opname_tab[(int) IN_EXPR] = "in";
850   opname_tab[(int) RANGE_EXPR] = "...";
851   opname_tab[(int) CONVERT_EXPR] = "+";
852   opname_tab[(int) ADDR_EXPR] = "&";
853   opname_tab[(int) PREDECREMENT_EXPR] = "--";
854   opname_tab[(int) PREINCREMENT_EXPR] = "++";
855   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
856   opname_tab[(int) POSTINCREMENT_EXPR] = "++";
857   opname_tab[(int) COMPOUND_EXPR] = ",";
858
859   assignop_tab[(int) NOP_EXPR] = "=";
860   assignop_tab[(int) PLUS_EXPR] =  "+=";
861   assignop_tab[(int) CONVERT_EXPR] =  "+=";
862   assignop_tab[(int) MINUS_EXPR] = "-=";
863   assignop_tab[(int) NEGATE_EXPR] = "-=";
864   assignop_tab[(int) MULT_EXPR] = "*=";
865   assignop_tab[(int) INDIRECT_REF] = "*=";
866   assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
867   assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
868   assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
869   assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
870   assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
871   assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
872   assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
873   assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
874   assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
875   assignop_tab[(int) MIN_EXPR] = "<?=";
876   assignop_tab[(int) MAX_EXPR] = ">?=";
877   assignop_tab[(int) LSHIFT_EXPR] = "<<=";
878   assignop_tab[(int) RSHIFT_EXPR] = ">>=";
879   assignop_tab[(int) BIT_IOR_EXPR] = "|=";
880   assignop_tab[(int) BIT_XOR_EXPR] = "^=";
881   assignop_tab[(int) BIT_AND_EXPR] = "&=";
882   assignop_tab[(int) ADDR_EXPR] = "&=";
883
884   init_filename_times ();
885
886   /* Some options inhibit certain reserved words.
887      Clear those words out of the hash table so they won't be recognized.  */
888 #define UNSET_RESERVED_WORD(STRING) \
889   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
890        if (s) s->name = ""; } while (0)
891
892 #if 0
893   /* let's parse things, and if they use it, then give them an error.  */
894   if (!flag_exceptions)
895     {
896       UNSET_RESERVED_WORD ("throw");
897       UNSET_RESERVED_WORD ("try");
898       UNSET_RESERVED_WORD ("catch");
899     }
900 #endif
901
902   if (!flag_rtti || flag_no_gnu_keywords)
903     {
904       UNSET_RESERVED_WORD ("classof");
905       UNSET_RESERVED_WORD ("headof");
906     }
907
908   if (! flag_handle_signatures || flag_no_gnu_keywords)
909     {
910       /* Easiest way to not recognize signature
911          handling extensions...  */
912       UNSET_RESERVED_WORD ("signature");
913       UNSET_RESERVED_WORD ("sigof");
914     }
915   if (flag_no_asm || flag_no_gnu_keywords)
916     UNSET_RESERVED_WORD ("typeof");
917   if (! flag_operator_names)
918     {
919       /* These are new ANSI keywords that may break code.  */
920       UNSET_RESERVED_WORD ("and");
921       UNSET_RESERVED_WORD ("and_eq");
922       UNSET_RESERVED_WORD ("bitand");
923       UNSET_RESERVED_WORD ("bitor");
924       UNSET_RESERVED_WORD ("compl");
925       UNSET_RESERVED_WORD ("not");
926       UNSET_RESERVED_WORD ("not_eq");
927       UNSET_RESERVED_WORD ("or");
928       UNSET_RESERVED_WORD ("or_eq");
929       UNSET_RESERVED_WORD ("xor");
930       UNSET_RESERVED_WORD ("xor_eq");
931     }
932
933   token_count = init_cpp_parse ();
934   interface_unknown = 1;
935
936   return filename;
937 }
938
939 void
940 finish_parse ()
941 {
942 #if USE_CPPLIB
943   cpp_finish (&parse_in);
944 #else
945   fclose (finput);
946 #endif
947 }
948
949 void
950 reinit_parse_for_function ()
951 {
952   current_base_init_list = NULL_TREE;
953   current_member_init_list = NULL_TREE;
954 }
955 \f
956 #ifdef __GNUC__
957 __inline
958 #endif
959 void
960 yyprint (file, yychar, yylval)
961      FILE *file;
962      int yychar;
963      YYSTYPE yylval;
964 {
965   tree t;
966   switch (yychar)
967     {
968     case IDENTIFIER:
969     case TYPENAME:
970     case TYPESPEC:
971     case PTYPENAME:
972     case IDENTIFIER_DEFN:
973     case TYPENAME_DEFN:
974     case PTYPENAME_DEFN:
975     case SCSPEC:
976     case PRE_PARSED_CLASS_DECL:
977       t = yylval.ttype;
978       if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
979         {
980           fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
981           break;
982         }
983       my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
984       if (IDENTIFIER_POINTER (t))
985           fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
986       break;
987     case AGGR:
988       if (yylval.ttype == class_type_node)
989         fprintf (file, " `class'");
990       else if (yylval.ttype == record_type_node)
991         fprintf (file, " `struct'");
992       else if (yylval.ttype == union_type_node)
993         fprintf (file, " `union'");
994       else if (yylval.ttype == enum_type_node)
995         fprintf (file, " `enum'");
996       else if (yylval.ttype == signature_type_node)
997         fprintf (file, " `signature'");
998       else
999         my_friendly_abort (80);
1000       break;
1001     }
1002 }
1003
1004 #if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
1005 static int *reduce_count;
1006 #endif
1007
1008 int *token_count;
1009
1010 #if 0
1011 #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
1012 #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
1013 #endif
1014
1015 #ifdef GATHER_STATISTICS
1016 #ifdef REDUCE_LENGTH
1017 void
1018 yyhook (yyn)
1019      int yyn;
1020 {
1021   reduce_count[yyn] += 1;
1022 }
1023
1024 static int
1025 reduce_cmp (p, q)
1026      int *p, *q;
1027 {
1028   return reduce_count[*q] - reduce_count[*p];
1029 }
1030
1031 static int
1032 token_cmp (p, q)
1033      int *p, *q;
1034 {
1035   return token_count[*q] - token_count[*p];
1036 }
1037 #endif
1038 #endif
1039
1040 void
1041 print_parse_statistics ()
1042 {
1043 #ifdef GATHER_STATISTICS
1044 #ifdef REDUCE_LENGTH
1045 #if YYDEBUG != 0
1046   int i;
1047   int maxlen = REDUCE_LENGTH;
1048   unsigned *sorted;
1049   
1050   if (reduce_count[-1] == 0)
1051     return;
1052
1053   if (TOKEN_LENGTH > REDUCE_LENGTH)
1054     maxlen = TOKEN_LENGTH;
1055   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
1056
1057   for (i = 0; i < TOKEN_LENGTH; i++)
1058     sorted[i] = i;
1059   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
1060   for (i = 0; i < TOKEN_LENGTH; i++)
1061     {
1062       int idx = sorted[i];
1063       if (token_count[idx] == 0)
1064         break;
1065       if (token_count[idx] < token_count[-1])
1066         break;
1067       fprintf (stderr, "token %d, `%s', count = %d\n",
1068                idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
1069     }
1070   fprintf (stderr, "\n");
1071   for (i = 0; i < REDUCE_LENGTH; i++)
1072     sorted[i] = i;
1073   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
1074   for (i = 0; i < REDUCE_LENGTH; i++)
1075     {
1076       int idx = sorted[i];
1077       if (reduce_count[idx] == 0)
1078         break;
1079       if (reduce_count[idx] < reduce_count[-1])
1080         break;
1081       fprintf (stderr, "rule %d, line %d, count = %d\n",
1082                idx, yyrline[idx], reduce_count[idx]);
1083     }
1084   fprintf (stderr, "\n");
1085 #endif
1086 #endif
1087 #endif
1088 }
1089
1090 /* Sets the value of the 'yydebug' variable to VALUE.
1091    This is a function so we don't have to have YYDEBUG defined
1092    in order to build the compiler.  */
1093
1094 void
1095 set_yydebug (value)
1096      int value;
1097 {
1098 #if YYDEBUG != 0
1099   extern int yydebug;
1100   yydebug = value;
1101 #else
1102   warning ("YYDEBUG not defined.");
1103 #endif
1104 }
1105
1106 \f
1107 /* Functions and data structures for #pragma interface.
1108
1109    `#pragma implementation' means that the main file being compiled
1110    is considered to implement (provide) the classes that appear in
1111    its main body.  I.e., if this is file "foo.cc", and class `bar'
1112    is defined in "foo.cc", then we say that "foo.cc implements bar".
1113
1114    All main input files "implement" themselves automagically.
1115
1116    `#pragma interface' means that unless this file (of the form "foo.h"
1117    is not presently being included by file "foo.cc", the
1118    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
1119    of the vtables nor any of the inline functions defined in foo.h
1120    will ever be output.
1121
1122    There are cases when we want to link files such as "defs.h" and
1123    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
1124    and "main.cc" has `#pragma implementation "defs.h"'.  */
1125
1126 struct impl_files
1127 {
1128   char *filename;
1129   struct impl_files *next;
1130 };
1131
1132 static struct impl_files *impl_file_chain;
1133
1134 /* Helper function to load global variables with interface
1135    information.  */
1136
1137 void
1138 extract_interface_info ()
1139 {
1140   tree fileinfo = 0;
1141
1142   if (flag_alt_external_templates)
1143     {
1144       struct tinst_level *til = tinst_for_decl ();
1145   
1146       if (til)
1147         fileinfo = get_time_identifier (til->file);
1148     }
1149   if (!fileinfo)
1150     fileinfo = get_time_identifier (input_filename);
1151   fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
1152   interface_only = TREE_INT_CST_LOW (fileinfo);
1153   interface_unknown = TREE_INT_CST_HIGH (fileinfo);
1154 }
1155
1156 /* Return nonzero if S is not considered part of an
1157    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
1158
1159 static int
1160 interface_strcmp (s)
1161      char *s;
1162 {
1163   /* Set the interface/implementation bits for this scope.  */
1164   struct impl_files *ifiles;
1165   char *s1;
1166
1167   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
1168     {
1169       char *t1 = ifiles->filename;
1170       s1 = s;
1171
1172       if (*s1 != *t1 || *s1 == 0)
1173         continue;
1174
1175       while (*s1 == *t1 && *s1 != 0)
1176         s1++, t1++;
1177
1178       /* A match.  */
1179       if (*s1 == *t1)
1180         return 0;
1181
1182       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
1183       if (index (s1, '.') || index (t1, '.'))
1184         continue;
1185
1186       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
1187         continue;
1188
1189       /* A match.  */
1190       return 0;
1191     }
1192
1193   /* No matches.  */
1194   return 1;
1195 }
1196
1197 static void
1198 set_typedecl_interface_info (prev, vars)
1199      tree prev ATTRIBUTE_UNUSED, vars;
1200 {
1201   tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
1202   tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
1203   tree type = TREE_TYPE (vars);
1204
1205   CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
1206     = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars)));
1207 }
1208
1209 static int
1210 set_vardecl_interface_info (prev, vars)
1211      tree prev, vars;
1212 {
1213   tree type = DECL_CONTEXT (vars);
1214
1215   if (CLASSTYPE_INTERFACE_KNOWN (type))
1216     {
1217       if (CLASSTYPE_INTERFACE_ONLY (type))
1218         set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));
1219       else
1220         CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
1221       DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
1222       TREE_PUBLIC (vars) = 1;
1223       return 1;
1224     }
1225   return 0;
1226 }
1227 \f
1228 /* Set up the state required to correctly handle the definition of the
1229    inline function whose preparsed state has been saved in PI.  */
1230
1231 static void
1232 begin_definition_of_inclass_inline (pi)
1233      struct pending_inline* pi;
1234 {
1235   tree context;
1236
1237   if (!pi->fndecl)
1238     return;
1239
1240   /* If this is an inline function in a local class, we must make sure
1241      that we save all pertinent information about the function
1242      surrounding the local class.  */
1243   context = hack_decl_function_context (pi->fndecl);
1244   if (context)
1245     push_cp_function_context (context);
1246
1247   feed_input (pi->buf, pi->len);
1248   lineno = pi->lineno;
1249   input_filename = pi->filename;
1250   yychar = PRE_PARSED_FUNCTION_DECL;
1251   yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
1252   /* Pass back a handle to the rest of the inline functions, so that they
1253      can be processed later.  */
1254   DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
1255   interface_unknown = pi->interface == 1;
1256   interface_only  = pi->interface == 0;
1257 }
1258
1259 /* Called from the top level: if there are any pending inlines to
1260    do, set up to process them now.  This function sets up the first function
1261    to be parsed; after it has been, the rule for fndef in parse.y will
1262    call process_next_inline to start working on the next one.  */
1263
1264 void
1265 do_pending_inlines ()
1266 {
1267   struct pending_inline *t;
1268
1269   /* Oops, we're still dealing with the last batch.  */
1270   if (yychar == PRE_PARSED_FUNCTION_DECL)
1271     return;
1272
1273   /* Reverse the pending inline functions, since
1274      they were cons'd instead of appended.  */
1275   {
1276     struct pending_inline *prev = 0, *tail;
1277     t = pending_inlines;
1278     pending_inlines = 0;
1279
1280     for (; t; t = tail)
1281       {
1282         tail = t->next;
1283         t->next = prev;
1284         t->deja_vu = 1;
1285         prev = t;
1286       }
1287     t = prev;
1288   }
1289
1290   if (t == 0)
1291     return;
1292             
1293   /* Now start processing the first inline function.  */
1294   begin_definition_of_inclass_inline (t);
1295 }
1296
1297 static int nextchar = -1;
1298
1299 /* Called from the fndecl rule in the parser when the function just parsed
1300    was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
1301    do_pending_inlines).  */
1302
1303 void
1304 process_next_inline (t)
1305      tree t;
1306 {
1307   tree context;
1308   struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
1309   context = hack_decl_function_context (i->fndecl);  
1310   if (context)
1311     pop_cp_function_context (context);
1312   i = i->next;
1313   if (yychar == YYEMPTY)
1314     yychar = yylex ();
1315   if (yychar != END_OF_SAVED_INPUT)
1316     {
1317       error ("parse error at end of saved function text");
1318
1319       /* restore_pending_input will abort unless yychar is either
1320          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1321          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1322          since that may have gotten set as well.  */
1323       nextchar = -1;
1324     }
1325   yychar = YYEMPTY;
1326   end_input ();
1327   if (i)
1328     begin_definition_of_inclass_inline (i);
1329   else
1330     extract_interface_info ();
1331 }
1332
1333 /* Since inline methods can refer to text which has not yet been seen,
1334    we store the text of the method in a structure which is placed in the
1335    DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
1336    After parsing the body of the class definition, the FUNCTION_DECL's are
1337    scanned to see which ones have this field set.  Those are then digested
1338    one at a time.
1339
1340    This function's FUNCTION_DECL will have a bit set in its common so
1341    that we know to watch out for it.  */
1342
1343 static void
1344 consume_string (this_obstack, matching_char)
1345      register struct obstack *this_obstack;
1346      int matching_char;
1347 {
1348   register int c;
1349   int starting_lineno = lineno;
1350   do
1351     {
1352       c = getch ();
1353       if (c == EOF)
1354         {
1355           int save_lineno = lineno;
1356           lineno = starting_lineno;
1357           if (matching_char == '"')
1358             error ("end of file encountered inside string constant");
1359           else
1360             error ("end of file encountered inside character constant");
1361           lineno = save_lineno;
1362           return;
1363         }
1364       if (c == '\\')
1365         {
1366           obstack_1grow (this_obstack, c);
1367           c = getch ();
1368           obstack_1grow (this_obstack, c);
1369
1370           /* Make sure we continue the loop */
1371           c = 0;
1372           continue;
1373         }
1374       if (c == '\n')
1375         {
1376           if (pedantic)
1377             pedwarn ("ANSI C++ forbids newline in string constant");
1378           lineno++;
1379         }
1380       obstack_1grow (this_obstack, c);
1381     }
1382   while (c != matching_char);
1383 }
1384
1385 static int nextyychar = YYEMPTY;
1386 static YYSTYPE nextyylval;
1387
1388 struct pending_input {
1389   int nextchar, yychar, nextyychar, eof;
1390   YYSTYPE yylval, nextyylval;
1391   struct obstack token_obstack;
1392   int first_token;
1393 };
1394
1395 struct pending_input *
1396 save_pending_input ()
1397 {
1398   struct pending_input *p;
1399   p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
1400   p->nextchar = nextchar;
1401   p->yychar = yychar;
1402   p->nextyychar = nextyychar;
1403   p->yylval = yylval;
1404   p->nextyylval = nextyylval;
1405   p->eof = end_of_file;
1406   yychar = nextyychar = YYEMPTY;
1407   nextchar = -1;
1408   p->first_token = first_token;
1409   p->token_obstack = token_obstack;
1410
1411   first_token = 0;
1412   gcc_obstack_init (&token_obstack);
1413   end_of_file = 0;
1414   return p;
1415 }
1416
1417 void
1418 restore_pending_input (p)
1419      struct pending_input *p;
1420 {
1421   my_friendly_assert (nextchar == -1, 229);
1422   nextchar = p->nextchar;
1423   my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230);
1424   yychar = p->yychar;
1425   my_friendly_assert (nextyychar == YYEMPTY, 231);
1426   nextyychar = p->nextyychar;
1427   yylval = p->yylval;
1428   nextyylval = p->nextyylval;
1429   first_token = p->first_token;
1430   obstack_free (&token_obstack, (char *) 0);
1431   token_obstack = p->token_obstack;
1432   end_of_file = p->eof;
1433   free (p);
1434 }
1435
1436 /* Unget character CH from the input stream.
1437    If RESCAN is non-zero, then we want to `see' this
1438    character as the next input token.  */
1439
1440 void
1441 yyungetc (ch, rescan)
1442      int ch;
1443      int rescan;
1444 {
1445   /* Unget a character from the input stream.  */
1446   if (yychar == YYEMPTY || rescan == 0)
1447     {
1448       if (nextchar >= 0)
1449         put_back (nextchar);
1450       nextchar = ch;
1451     }
1452   else
1453     {
1454       my_friendly_assert (nextyychar == YYEMPTY, 232);
1455       nextyychar = yychar;
1456       nextyylval = yylval;
1457       yychar = ch;
1458     }
1459 }
1460
1461 void
1462 clear_inline_text_obstack ()
1463 {
1464   obstack_free (&inline_text_obstack, inline_text_firstobj);
1465 }
1466
1467 /* This function stores away the text for an inline function that should
1468    be processed later.  It decides how much later, and may need to move
1469    the info between obstacks; therefore, the caller should not refer to
1470    the T parameter after calling this function.  */
1471
1472 static void
1473 store_pending_inline (decl, t)
1474      tree decl;
1475      struct pending_inline *t;
1476 {
1477   t->fndecl = decl;
1478   DECL_PENDING_INLINE_INFO (decl) = t;
1479
1480   /* Because we use obstacks, we must process these in precise order.  */
1481   t->next = pending_inlines;
1482   pending_inlines = t;
1483 }
1484
1485 void
1486 reinit_parse_for_method (yychar, decl)
1487      int yychar;
1488      tree decl;
1489 {
1490   int len;
1491   int starting_lineno = lineno;
1492   char *starting_filename = input_filename;
1493
1494   reinit_parse_for_block (yychar, &inline_text_obstack);
1495
1496   len = obstack_object_size (&inline_text_obstack);
1497   current_base_init_list = NULL_TREE;
1498   current_member_init_list = NULL_TREE;
1499   if (decl == void_type_node
1500       || (current_class_type && TYPE_REDEFINED (current_class_type)))
1501     {
1502       /* Happens when we get two declarations of the same
1503          function in the same scope.  */
1504       char *buf = obstack_finish (&inline_text_obstack);
1505       obstack_free (&inline_text_obstack, buf);
1506       return;
1507     }
1508   else
1509     {
1510       struct pending_inline *t;
1511       char *buf = obstack_finish (&inline_text_obstack);
1512
1513       t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1514                                                    sizeof (struct pending_inline));
1515       t->lineno = starting_lineno;
1516       t->filename = starting_filename;
1517       t->token = YYEMPTY;
1518       t->token_value = 0;
1519       t->buf = buf;
1520       t->len = len;
1521       t->deja_vu = 0;
1522 #if 0
1523       if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
1524         warn_if_unknown_interface (decl);
1525 #endif
1526       t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
1527       store_pending_inline (decl, t);
1528     }
1529 }
1530
1531 /* Consume a block -- actually, a method beginning
1532    with `:' or `{' -- and save it away on the specified obstack.  */
1533
1534 void
1535 reinit_parse_for_block (pyychar, obstackp)
1536      int pyychar;
1537      struct obstack *obstackp;
1538 {
1539   register int c = 0;
1540   int blev = 1;
1541   int starting_lineno = lineno;
1542   char *starting_filename = input_filename;
1543   int len;
1544   int look_for_semicolon = 0;
1545   int look_for_lbrac = 0;
1546
1547   if (pyychar == '{')
1548     obstack_1grow (obstackp, '{');
1549   else if (pyychar == '=')
1550     look_for_semicolon = 1;
1551   else if (pyychar == ':')
1552     {
1553       obstack_1grow (obstackp, pyychar);
1554       /* Add a space so we don't get confused by ': ::A(20)'.  */
1555       obstack_1grow (obstackp, ' ');
1556       look_for_lbrac = 1;
1557       blev = 0;
1558     }
1559   else if (pyychar == RETURN)
1560     {
1561       obstack_grow (obstackp, "return", 6);
1562       look_for_lbrac = 1;
1563       blev = 0;
1564     }
1565   else if (pyychar == TRY)
1566     {
1567       obstack_grow (obstackp, "try", 3);
1568       look_for_lbrac = 1;
1569       blev = 0;
1570     }
1571   else
1572     {
1573       yyerror ("parse error in method specification");
1574       obstack_1grow (obstackp, '{');
1575     }
1576
1577   if (nextchar != EOF)
1578     {
1579       c = nextchar;
1580       nextchar = EOF;
1581     }
1582   else
1583     c = getch ();
1584   
1585   while (c != EOF)
1586     {
1587       int this_lineno = lineno;
1588
1589       c = skip_white_space (c);
1590
1591       /* Don't lose our cool if there are lots of comments.  */
1592       if (lineno == this_lineno + 1)
1593         obstack_1grow (obstackp, '\n');
1594       else if (lineno == this_lineno)
1595         ;
1596       else if (lineno - this_lineno < 10)
1597         {
1598           int i;
1599           for (i = lineno - this_lineno; i > 0; i--)
1600             obstack_1grow (obstackp, '\n');
1601         }
1602       else
1603         {
1604           char buf[16];
1605           sprintf (buf, "\n# %d \"", lineno);
1606           len = strlen (buf);
1607           obstack_grow (obstackp, buf, len);
1608
1609           len = strlen (input_filename);
1610           obstack_grow (obstackp, input_filename, len);
1611           obstack_1grow (obstackp, '\"');
1612           obstack_1grow (obstackp, '\n');
1613         }
1614
1615       while (c > ' ')           /* ASCII dependent...  */
1616         {
1617           obstack_1grow (obstackp, c);
1618           if (c == '{')
1619             {
1620               look_for_lbrac = 0;
1621               blev++;
1622             }
1623           else if (c == '}')
1624             {
1625               blev--;
1626               if (blev == 0 && !look_for_semicolon)
1627                 {
1628                   if (pyychar == TRY)
1629                     {
1630                       if (peekyylex () == CATCH)
1631                         {
1632                           yylex ();
1633                           obstack_grow (obstackp, " catch ", 7);
1634                           look_for_lbrac = 1;
1635                         }
1636                       else
1637                         {
1638                           yychar = '{';
1639                           goto done;
1640                         }
1641                     }
1642                   else
1643                     {
1644                       goto done;
1645                     }
1646                 }
1647             }
1648           else if (c == '\\')
1649             {
1650               /* Don't act on the next character...e.g, doing an escaped
1651                  double-quote.  */
1652               c = getch ();
1653               if (c == EOF)
1654                 {
1655                   error_with_file_and_line (starting_filename,
1656                                             starting_lineno,
1657                                             "end of file read inside definition");
1658                   goto done;
1659                 }
1660               obstack_1grow (obstackp, c);
1661             }
1662           else if (c == '\"')
1663             consume_string (obstackp, c);
1664           else if (c == '\'')
1665             consume_string (obstackp, c);
1666           else if (c == ';')
1667             {
1668               if (look_for_lbrac)
1669                 {
1670                   error ("function body for constructor missing");
1671                   obstack_1grow (obstackp, '{');
1672                   obstack_1grow (obstackp, '}');
1673                   len += 2;
1674                   goto done;
1675                 }
1676               else if (look_for_semicolon && blev == 0)
1677                 goto done;
1678             }
1679           c = getch ();
1680         }
1681
1682       if (c == EOF)
1683         {
1684           error_with_file_and_line (starting_filename,
1685                                     starting_lineno,
1686                                     "end of file read inside definition");
1687           goto done;
1688         }
1689       else if (c != '\n')
1690         {
1691           obstack_1grow (obstackp, c);
1692           c = getch ();
1693         }
1694     }
1695  done:
1696   obstack_1grow (obstackp, '\0');
1697 }
1698
1699 /* Consume a no-commas expression -- actually, a default argument -- and
1700    save it away on the specified obstack.  */
1701
1702 static void
1703 reinit_parse_for_expr (obstackp)
1704      struct obstack *obstackp;
1705 {
1706   register int c = 0;
1707   int starting_lineno = lineno;
1708   char *starting_filename = input_filename;
1709   int len;
1710   int plev = 0;
1711
1712   if (nextchar != EOF)
1713     {
1714       c = nextchar;
1715       nextchar = EOF;
1716     }
1717   else
1718     c = getch ();
1719   
1720   while (c != EOF)
1721     {
1722       int this_lineno = lineno;
1723
1724       c = skip_white_space (c);
1725
1726       /* Don't lose our cool if there are lots of comments.  */
1727       if (lineno == this_lineno + 1)
1728         obstack_1grow (obstackp, '\n');
1729       else if (lineno == this_lineno)
1730         ;
1731       else if (lineno - this_lineno < 10)
1732         {
1733           int i;
1734           for (i = lineno - this_lineno; i > 0; --i)
1735             obstack_1grow (obstackp, '\n');
1736         }
1737       else
1738         {
1739           char buf[16];
1740           sprintf (buf, "\n# %d \"", lineno);
1741           len = strlen (buf);
1742           obstack_grow (obstackp, buf, len);
1743
1744           len = strlen (input_filename);
1745           obstack_grow (obstackp, input_filename, len);
1746           obstack_1grow (obstackp, '\"');
1747           obstack_1grow (obstackp, '\n');
1748         }
1749
1750       while (c > ' ')           /* ASCII dependent...  */
1751         {
1752           if (plev <= 0 && (c == ')' || c == ','))
1753             {
1754               put_back (c);
1755               goto done;
1756             }
1757           obstack_1grow (obstackp, c);
1758           if (c == '(' || c == '[')
1759             ++plev;
1760           else if (c == ']' || c == ')')
1761             --plev;
1762           else if (c == '\\')
1763             {
1764               /* Don't act on the next character...e.g, doing an escaped
1765                  double-quote.  */
1766               c = getch ();
1767               if (c == EOF)
1768                 {
1769                   error_with_file_and_line (starting_filename,
1770                                             starting_lineno,
1771                                             "end of file read inside definition");
1772                   goto done;
1773                 }
1774               obstack_1grow (obstackp, c);
1775             }
1776           else if (c == '\"')
1777             consume_string (obstackp, c);
1778           else if (c == '\'')
1779             consume_string (obstackp, c);
1780           c = getch ();
1781         }
1782
1783       if (c == EOF)
1784         {
1785           error_with_file_and_line (starting_filename,
1786                                     starting_lineno,
1787                                     "end of file read inside definition");
1788           goto done;
1789         }
1790       else if (c != '\n')
1791         {
1792           obstack_1grow (obstackp, c);
1793           c = getch ();
1794         }
1795     }
1796  done:
1797   obstack_1grow (obstackp, '\0');
1798 }
1799
1800 int do_snarf_defarg;
1801
1802 /* Decide whether the default argument we are about to see should be
1803    gobbled up as text for later parsing.  */
1804
1805 void
1806 maybe_snarf_defarg ()
1807 {
1808   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
1809     do_snarf_defarg = 1;
1810 }
1811
1812 /* When we see a default argument in a method declaration, we snarf it as
1813    text using snarf_defarg.  When we get up to namespace scope, we then go
1814    through and parse all of them using do_pending_defargs.  Since yacc
1815    parsers are not reentrant, we retain defargs state in these two
1816    variables so that subsequent calls to do_pending_defargs can resume
1817    where the previous call left off.  */
1818
1819 tree defarg_fns;
1820 tree defarg_parm;
1821
1822 tree
1823 snarf_defarg ()
1824 {
1825   int len;
1826   char *buf;
1827   tree arg;
1828
1829   reinit_parse_for_expr (&inline_text_obstack);
1830   len = obstack_object_size (&inline_text_obstack);
1831   buf = obstack_finish (&inline_text_obstack);
1832
1833   push_obstacks (&inline_text_obstack, &inline_text_obstack);
1834   arg = make_node (DEFAULT_ARG);
1835   DEFARG_LENGTH (arg) = len - 1;
1836   DEFARG_POINTER (arg) = buf;
1837   pop_obstacks ();
1838
1839   return arg;
1840 }
1841
1842 /* Called from grokfndecl to note a function decl with unparsed default
1843    arguments for later processing.  Also called from grokdeclarator
1844    for function types with unparsed defargs; the call from grokfndecl
1845    will always come second, so we can overwrite the entry from the type.  */
1846
1847 void
1848 add_defarg_fn (decl)
1849      tree decl;
1850 {
1851   if (TREE_CODE (decl) == FUNCTION_DECL)
1852     TREE_VALUE (defarg_fns) = decl;
1853   else
1854     {
1855       push_obstacks (&inline_text_obstack, &inline_text_obstack);
1856       defarg_fns = tree_cons (current_class_type, decl, defarg_fns);  
1857       pop_obstacks ();
1858     }
1859 }
1860
1861 /* Helper for do_pending_defargs.  Starts the parsing of a default arg.  */
1862
1863 static void
1864 feed_defarg (f, p)
1865      tree f, p;
1866 {
1867   tree d = TREE_PURPOSE (p);
1868   feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
1869   if (TREE_CODE (f) == FUNCTION_DECL)
1870     {
1871       lineno = DECL_SOURCE_LINE (f);
1872       input_filename = DECL_SOURCE_FILE (f);
1873     }
1874   yychar = DEFARG_MARKER;
1875   yylval.ttype = p;
1876 }
1877
1878 /* Helper for do_pending_defargs.  Ends the parsing of a default arg.  */
1879
1880 static void
1881 finish_defarg ()
1882 {
1883   if (yychar == YYEMPTY)
1884     yychar = yylex ();
1885   if (yychar != END_OF_SAVED_INPUT)
1886     {
1887       error ("parse error at end of saved function text");
1888
1889       /* restore_pending_input will abort unless yychar is either
1890          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1891          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1892          since that may have gotten set as well.  */
1893       nextchar = -1;
1894     }
1895   yychar = YYEMPTY;
1896   end_input ();
1897 }  
1898
1899 /* Main function for deferred parsing of default arguments.  Called from
1900    the parser.  */
1901
1902 void
1903 do_pending_defargs ()
1904 {
1905   if (defarg_parm)
1906     finish_defarg ();
1907
1908   for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
1909     {
1910       tree defarg_fn = TREE_VALUE (defarg_fns);
1911       if (defarg_parm == NULL_TREE)
1912         {
1913           push_nested_class (TREE_PURPOSE (defarg_fns), 1);
1914           pushlevel (0);
1915           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1916             maybe_begin_member_template_processing (defarg_fn);
1917
1918           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1919             {
1920 #if 0
1921               tree p;
1922               for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
1923                 pushdecl (copy_node (p));
1924 #endif
1925               defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
1926             }
1927           else
1928             defarg_parm = TYPE_ARG_TYPES (defarg_fn);
1929         }
1930       else
1931         defarg_parm = TREE_CHAIN (defarg_parm);
1932
1933       for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
1934         if (TREE_PURPOSE (defarg_parm)
1935             && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG)
1936           {
1937             feed_defarg (defarg_fn, defarg_parm);
1938
1939             /* Return to the parser, which will process this defarg
1940                and call us again.  */
1941             return;
1942           }
1943
1944       if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1945         {
1946           maybe_end_member_template_processing ();
1947           check_default_args (defarg_fn);
1948         }
1949
1950       poplevel (0, 0, 0);
1951       pop_nested_class (1);
1952     }
1953 }
1954
1955 /* Build a default function named NAME for type TYPE.
1956    KIND says what to build.
1957
1958    When KIND == 0, build default destructor.
1959    When KIND == 1, build virtual destructor.
1960    When KIND == 2, build default constructor.
1961    When KIND == 3, build default X(const X&) constructor.
1962    When KIND == 4, build default X(X&) constructor.
1963    When KIND == 5, build default operator = (const X&).
1964    When KIND == 6, build default operator = (X&).  */
1965
1966 tree
1967 cons_up_default_function (type, full_name, kind)
1968      tree type, full_name;
1969      int kind;
1970 {
1971   extern tree void_list_node;
1972   tree declspecs = NULL_TREE;
1973   tree fn, args = NULL_TREE;
1974   tree argtype;
1975   int retref = 0;
1976   tree name = constructor_name (full_name);
1977
1978   switch (kind)
1979     {
1980       /* Destructors.  */
1981     case 1:
1982       declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
1983       /* Fall through...  */
1984     case 0:
1985       name = build_parse_node (BIT_NOT_EXPR, name);
1986       args = void_list_node;
1987       break;
1988
1989     case 2:
1990       /* Default constructor.  */
1991       args = void_list_node;
1992       break;
1993
1994     case 3:
1995       type = build_qualified_type (type, TYPE_QUAL_CONST);
1996       /* Fall through...  */
1997     case 4:
1998       /* According to ARM $12.8, the default copy ctor will be declared, but
1999          not defined, unless it's needed.  */
2000       argtype = build_reference_type (type);
2001       args = tree_cons (NULL_TREE,
2002                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
2003                                          get_identifier ("_ctor_arg")),
2004                         void_list_node);
2005       break;
2006
2007     case 5:
2008     case 6:
2009       retref = 1;
2010       declspecs = build_decl_list (NULL_TREE, type);
2011
2012       if (kind == 5)
2013         type = build_qualified_type (type, TYPE_QUAL_CONST);
2014
2015       name = ansi_opname [(int) MODIFY_EXPR];
2016
2017       argtype = build_reference_type (type);
2018       args = tree_cons (NULL_TREE,
2019                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
2020                                          get_identifier ("_ctor_arg")),
2021                         void_list_node);
2022       break;
2023
2024     default:
2025       my_friendly_abort (59);
2026     }
2027
2028   declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
2029                               declspecs);
2030
2031   TREE_PARMLIST (args) = 1;
2032
2033   {
2034     tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
2035     if (retref)
2036       declarator = build_parse_node (ADDR_EXPR, declarator);
2037
2038     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
2039   }
2040   
2041   if (fn == void_type_node)
2042     return fn;
2043
2044   if (kind > 2)
2045     SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
2046
2047 #if 0
2048   if (processing_template_defn)
2049     {
2050       SET_DECL_IMPLICIT_INSTANTIATION (fn);
2051       repo_template_used (fn);
2052     }
2053 #endif
2054
2055 #if 0
2056   if (CLASSTYPE_INTERFACE_KNOWN (type))
2057     {
2058       DECL_INTERFACE_KNOWN (fn) = 1;
2059       DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
2060                                      && flag_implement_inlines);
2061     }
2062   else
2063 #endif
2064     DECL_NOT_REALLY_EXTERN (fn) = 1;
2065
2066   mark_inline_for_output (fn);
2067
2068 #ifdef DEBUG_DEFAULT_FUNCTIONS
2069   { char *fn_type = NULL;
2070     tree t = name;
2071     switch (kind)
2072       {
2073       case 0: fn_type = "default destructor"; break;
2074       case 1: fn_type = "virtual destructor"; break;
2075       case 2: fn_type = "default constructor"; break;
2076       case 3: fn_type = "default X(const X&)"; break;
2077       case 4: fn_type = "default X(X&)"; break;
2078       }
2079     if (fn_type)
2080       {
2081         if (TREE_CODE (name) == BIT_NOT_EXPR)
2082           t = TREE_OPERAND (name, 0);
2083         fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
2084                  IDENTIFIER_POINTER (t), func_buf);
2085       }
2086   }
2087 #endif /* DEBUG_DEFAULT_FUNCTIONS */
2088
2089   /* Show that this function was generated by the compiler.  */
2090   SET_DECL_ARTIFICIAL (fn);
2091   
2092   return fn;
2093 }
2094
2095 /* Heuristic to tell whether the user is missing a semicolon
2096    after a struct or enum declaration.  Emit an error message
2097    if we know the user has blown it.  */
2098
2099 void
2100 check_for_missing_semicolon (type)
2101      tree type;
2102 {
2103   if (yychar < 0)
2104     yychar = yylex ();
2105
2106   if ((yychar > 255
2107        && yychar != SCSPEC
2108        && yychar != IDENTIFIER
2109        && yychar != TYPENAME
2110        && yychar != CV_QUALIFIER
2111        && yychar != SELFNAME)
2112       || end_of_file)
2113     {
2114       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
2115         error ("semicolon missing after %s declaration",
2116                TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
2117       else
2118         cp_error ("semicolon missing after declaration of `%T'", type);
2119       shadow_tag (build_tree_list (0, type));
2120     }
2121   /* Could probably also hack cases where class { ... } f (); appears.  */
2122   clear_anon_tags ();
2123 }
2124
2125 void
2126 note_got_semicolon (type)
2127      tree type;
2128 {
2129   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
2130     my_friendly_abort (60);
2131   if (CLASS_TYPE_P (type))
2132     CLASSTYPE_GOT_SEMICOLON (type) = 1;
2133 }
2134
2135 void
2136 note_list_got_semicolon (declspecs)
2137      tree declspecs;
2138 {
2139   tree link;
2140
2141   for (link = declspecs; link; link = TREE_CHAIN (link))
2142     {
2143       tree type = TREE_VALUE (link);
2144       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
2145         note_got_semicolon (type);
2146     }
2147   clear_anon_tags ();
2148 }
2149 \f
2150 /* If C is not whitespace, return C.
2151    Otherwise skip whitespace and return first nonwhite char read.  */
2152
2153 static int
2154 skip_white_space (c)
2155      register int c;
2156 {
2157   for (;;)
2158     {
2159       switch (c)
2160         {
2161         case '\n':
2162           c = check_newline ();
2163           break;
2164
2165         case ' ':
2166         case '\t':
2167         case '\f':
2168         case '\r':
2169         case '\v':
2170         case '\b':
2171           do
2172             c = getch ();
2173           while (c == ' ' || c == '\t');
2174           break;
2175
2176         case '\\':
2177           c = getch ();
2178           if (c == '\n')
2179             lineno++;
2180           else
2181             error ("stray '\\' in program");
2182           c = getch ();
2183           break;
2184
2185         default:
2186           return (c);
2187         }
2188     }
2189 }
2190
2191
2192
2193 /* Make the token buffer longer, preserving the data in it.
2194    P should point to just beyond the last valid character in the old buffer.
2195    The value we return is a pointer to the new buffer
2196    at a place corresponding to P.  */
2197
2198 static char *
2199 extend_token_buffer (p)
2200      char *p;
2201 {
2202   int offset = p - token_buffer;
2203
2204   maxtoken = maxtoken * 2 + 10;
2205   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
2206
2207   return token_buffer + offset;
2208 }
2209 \f
2210 static int
2211 get_last_nonwhite_on_line ()
2212 {
2213   register int c;
2214
2215   /* Is this the last nonwhite stuff on the line?  */
2216   if (nextchar >= 0)
2217     c = nextchar, nextchar = -1;
2218   else
2219     c = getch ();
2220
2221   while (c == ' ' || c == '\t')
2222     c = getch ();
2223   return c;
2224 }
2225
2226 #if defined HANDLE_PRAGMA
2227 /* Local versions of these macros, that can be passed as function pointers.  */
2228 static int
2229 pragma_getc ()
2230 {
2231   int c;
2232       
2233   if (nextchar != EOF)
2234     {
2235       c = nextchar;
2236       nextchar = EOF;
2237     }
2238   else
2239     c = getch ();
2240
2241   return c;
2242 }
2243
2244 static void
2245 pragma_ungetc (arg)
2246      int arg;
2247 {
2248   yyungetc (arg, 0);
2249 }
2250 #endif /* HANDLE_PRAGMA */
2251
2252 /* At the beginning of a line, increment the line number
2253    and process any #-directive on this line.
2254    If the line is a #-directive, read the entire line and return a newline.
2255    Otherwise, return the line's first non-whitespace character.  */
2256
2257 int linemode;
2258
2259 static int handle_cp_pragma PROTO((char *));
2260
2261 static int
2262 check_newline ()
2263 {
2264   register int c;
2265   register int token;
2266   int saw_line = 0;
2267
2268   /* Read first nonwhite char on the line.  Do this before incrementing the
2269      line number, in case we're at the end of saved text.  */
2270
2271   do
2272     c = getch ();
2273   while (c == ' ' || c == '\t');
2274
2275   lineno++;
2276
2277   if (c != '#')
2278     {
2279       /* If not #, return it so caller will use it.  */
2280       return c;
2281     }
2282
2283   /* Don't read beyond this line.  */
2284   linemode = 1;
2285   
2286   /* Read first nonwhite char after the `#'.  */
2287
2288   do
2289     c = getch ();
2290   while (c == ' ' || c == '\t');
2291
2292   /* If a letter follows, then if the word here is `line', skip
2293      it and ignore it; otherwise, ignore the line, with an error
2294      if the word isn't `pragma'.  */
2295
2296   if (ISALPHA (c))
2297     {
2298       if (c == 'p')
2299         {
2300           if (getch () == 'r'
2301               && getch () == 'a'
2302               && getch () == 'g'
2303               && getch () == 'm'
2304               && getch () == 'a')
2305             {
2306               token = real_yylex ();
2307               if (token == IDENTIFIER
2308                   && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
2309                 {
2310                   /* If this is 1, we handled it; if it's -1, it was one we
2311                      wanted but had something wrong with it.  Only if it's
2312                      0 was it not handled.  */
2313                   if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
2314                     goto skipline;
2315                 }
2316               else if (token == END_OF_LINE)
2317                 goto skipline;
2318
2319 #ifdef HANDLE_PRAGMA
2320               /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS
2321                  (if both are defined), in order to give the back
2322                  end a chance to override the interpretation of
2323                  SYSV style pragmas.  */
2324               if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
2325                                  IDENTIFIER_POINTER (yylval.ttype)))
2326                 goto skipline;
2327 #endif /* HANDLE_PRAGMA */
2328               
2329 #ifdef HANDLE_GENERIC_PRAGMAS
2330               if (handle_generic_pragma (token))
2331                 goto skipline;
2332 #endif /* HANDLE_GENERIC_PRAGMAS */
2333
2334               /* Issue a warning message if we have been asked to do so.
2335                  Ignoring unknown pragmas in system header file unless
2336                  an explcit -Wunknown-pragmas has been given. */
2337               if (warn_unknown_pragmas > 1
2338                   || (warn_unknown_pragmas && ! in_system_header))
2339                 warning ("ignoring pragma: %s", token_buffer);
2340             }
2341           
2342           goto skipline;
2343         }
2344       else if (c == 'd')
2345         {
2346           if (getch () == 'e'
2347               && getch () == 'f'
2348               && getch () == 'i'
2349               && getch () == 'n'
2350               && getch () == 'e'
2351               && ((c = getch ()) == ' ' || c == '\t'))
2352             {
2353               debug_define (lineno, GET_DIRECTIVE_LINE ());
2354               goto skipline;
2355             }
2356         }
2357       else if (c == 'u')
2358         {
2359           if (getch () == 'n'
2360               && getch () == 'd'
2361               && getch () == 'e'
2362               && getch () == 'f'
2363               && ((c = getch ()) == ' ' || c == '\t'))
2364             {
2365               debug_undef (lineno, GET_DIRECTIVE_LINE ());
2366               goto skipline;
2367             }
2368         }
2369       else if (c == 'l')
2370         {
2371           if (getch () == 'i'
2372               && getch () == 'n'
2373               && getch () == 'e'
2374               && ((c = getch ()) == ' ' || c == '\t'))
2375             {
2376               saw_line = 1;
2377               goto linenum;
2378             }
2379         }
2380       else if (c == 'i')
2381         {
2382           if (getch () == 'd'
2383               && getch () == 'e'
2384               && getch () == 'n'
2385               && getch () == 't'
2386               && ((c = getch ()) == ' ' || c == '\t'))
2387             {
2388               /* #ident.  The pedantic warning is now in cccp.c.  */
2389
2390               /* Here we have just seen `#ident '.
2391                  A string constant should follow.  */
2392
2393               token = real_yylex ();
2394               if (token == END_OF_LINE)
2395                 goto skipline;
2396               if (token != STRING
2397                   || TREE_CODE (yylval.ttype) != STRING_CST)
2398                 {
2399                   error ("invalid #ident");
2400                   goto skipline;
2401                 }
2402
2403               if (! flag_no_ident)
2404                 {
2405 #ifdef ASM_OUTPUT_IDENT
2406                   ASM_OUTPUT_IDENT (asm_out_file,
2407                                     TREE_STRING_POINTER (yylval.ttype));
2408 #endif
2409                 }
2410
2411               /* Skip the rest of this line.  */
2412               goto skipline;
2413             }
2414         }
2415       else if (c == 'n')
2416         {
2417           if (getch () == 'e'
2418               && getch () == 'w'
2419               && getch () == 'w'
2420               && getch () == 'o'
2421               && getch () == 'r'
2422               && getch () == 'l'
2423               && getch () == 'd'
2424               && ((c = getch ()) == ' ' || c == '\t'))
2425             {
2426               /* Used to test incremental compilation.  */
2427               sorry ("#pragma newworld");
2428               goto skipline;
2429             }
2430         }
2431       error ("undefined or invalid # directive");
2432       goto skipline;
2433     }
2434
2435 linenum:
2436   /* Here we have either `#line' or `# <nonletter>'.
2437      In either case, it should be a line number; a digit should follow.  */
2438
2439   while (c == ' ' || c == '\t')
2440     c = getch ();
2441
2442   /* If the # is the only nonwhite char on the line,
2443      just ignore it.  Check the new newline.  */
2444   if (c == EOF)
2445     goto skipline;
2446
2447   /* Something follows the #; read a token.  */
2448
2449   put_back (c);
2450   token = real_yylex ();
2451
2452   if (token == CONSTANT
2453       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2454     {
2455       int old_lineno = lineno;
2456       enum { act_none, act_push, act_pop } action = act_none;
2457       int entering_system_header = 0;
2458       int entering_c_header = 0;
2459
2460       /* subtract one, because it is the following line that
2461          gets the specified number */
2462
2463       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2464       c = get_last_nonwhite_on_line ();
2465       if (c == EOF)
2466         {
2467           /* No more: store the line number and check following line.  */
2468           lineno = l;
2469           goto skipline;
2470         }
2471       put_back (c);
2472
2473       /* More follows: it must be a string constant (filename).  */
2474
2475       if (saw_line)
2476         {
2477           /* Don't treat \ as special if we are processing #line 1 "...".
2478              If you want it to be treated specially, use # 1 "...".  */
2479           ignore_escape_flag = 1;
2480         }
2481
2482       /* Read the string constant.  */
2483       token = real_yylex ();
2484
2485       ignore_escape_flag = 0;
2486
2487       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2488         {
2489           error ("invalid #line");
2490           goto skipline;
2491         }
2492
2493       /* Changing files again.  This means currently collected time
2494          is charged against header time, and body time starts back
2495          at 0.  */
2496       if (flag_detailed_statistics)
2497         {
2498           int this_time = my_get_run_time ();
2499           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2500           header_time += this_time - body_time;
2501           TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
2502             += this_time - body_time;
2503           this_filename_time = time_identifier;
2504           body_time = this_time;
2505         }
2506
2507       input_filename
2508         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2509       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2510       lineno = l;
2511       GNU_xref_file (input_filename);
2512       
2513       if (main_input_filename == 0)
2514         {
2515           struct impl_files *ifiles = impl_file_chain;
2516
2517           if (ifiles)
2518             {
2519               while (ifiles->next)
2520                 ifiles = ifiles->next;
2521               ifiles->filename = file_name_nondirectory (input_filename);
2522             }
2523
2524           main_input_filename = input_filename;
2525           if (write_virtuals == 3)
2526             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2527         }
2528
2529       extract_interface_info ();
2530
2531       c = get_last_nonwhite_on_line ();
2532       if (c == EOF)
2533         {
2534           /* Update the name in the top element of input_file_stack.  */
2535           if (input_file_stack)
2536             input_file_stack->name = input_filename;
2537         }
2538       else
2539         {
2540           put_back (c);
2541
2542           token = real_yylex ();
2543
2544           /* `1' after file name means entering new file.
2545              `2' after file name means just left a file.  */
2546
2547           if (token == CONSTANT
2548               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2549             {
2550               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2551                 action = act_push;
2552               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2553                 action = act_pop;
2554
2555               if (action)
2556                 {
2557                   c = get_last_nonwhite_on_line ();
2558                   if (c != EOF)
2559                     {
2560                       put_back (c);
2561                       token = real_yylex ();
2562                     }
2563                 }
2564             }
2565
2566           /* `3' after file name means this is a system header file.  */
2567
2568           if (token == CONSTANT
2569               && TREE_CODE (yylval.ttype) == INTEGER_CST
2570               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2571             {
2572               entering_system_header = 1;
2573
2574               c = get_last_nonwhite_on_line ();
2575               if (c != EOF)
2576                 {
2577                   put_back (c);
2578                   token = real_yylex ();
2579                 }
2580             }
2581
2582           /* `4' after file name means this is a C header file.  */
2583
2584           if (token == CONSTANT
2585               && TREE_CODE (yylval.ttype) == INTEGER_CST
2586               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2587             {
2588               entering_c_header = 1;
2589
2590               c = get_last_nonwhite_on_line ();
2591               if (c != EOF)
2592                 {
2593                   put_back (c);
2594                   token = real_yylex ();
2595                 }
2596             }
2597
2598           /* Do the actions implied by the preceding numbers.  */
2599
2600           if (action == act_push)
2601             {
2602               /* Pushing to a new file.  */
2603               struct file_stack *p;
2604
2605               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2606               input_file_stack->line = old_lineno;
2607               p->next = input_file_stack;
2608               p->name = input_filename;
2609               input_file_stack = p;
2610               input_file_stack_tick++;
2611               debug_start_source_file (input_filename);
2612               in_system_header = entering_system_header;
2613               if (c_header_level)
2614                 ++c_header_level;
2615               else if (entering_c_header)
2616                 {
2617                   c_header_level = 1;
2618                   ++pending_lang_change;
2619                 }
2620             }
2621           else if (action == act_pop)
2622             {
2623               /* Popping out of a file.  */
2624               if (input_file_stack->next)
2625                 {
2626                   struct file_stack *p;
2627
2628                   if (c_header_level && --c_header_level == 0)
2629                     {
2630                       if (entering_c_header)
2631                         warning ("badly nested C headers from preprocessor");
2632                       --pending_lang_change;
2633                     }
2634                   in_system_header = entering_system_header;
2635
2636                   p = input_file_stack;
2637                   input_file_stack = p->next;
2638                   free (p);
2639                   input_file_stack_tick++;
2640                   debug_end_source_file (input_file_stack->line);
2641                 }
2642               else
2643                 error ("#-lines for entering and leaving files don't match");
2644             }
2645           else
2646             in_system_header = entering_system_header;
2647         }
2648
2649       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2650       if (nextchar == EOF)
2651         c = EOF;
2652     }
2653   else
2654     error ("invalid #-line");
2655
2656   /* skip the rest of this line.  */
2657  skipline:
2658   linemode = 0;
2659   end_of_file = 0;
2660   nextchar = -1;
2661   while ((c = getch ()) != EOF && c != '\n');
2662   return c;
2663 }
2664
2665 void
2666 do_pending_lang_change ()
2667 {
2668   for (; pending_lang_change > 0; --pending_lang_change)
2669     push_lang_context (lang_name_c);
2670   for (; pending_lang_change < 0; ++pending_lang_change)
2671     pop_lang_context ();
2672 }
2673 \f
2674 #define ENDFILE -1  /* token that represents end-of-file */
2675
2676 /* Read an escape sequence, returning its equivalent as a character,
2677    or store 1 in *ignore_ptr if it is backslash-newline.  */
2678
2679 static int
2680 readescape (ignore_ptr)
2681      int *ignore_ptr;
2682 {
2683   register int c = getch ();
2684   register int code;
2685   register unsigned count;
2686   unsigned firstdig = 0;
2687   int nonnull;
2688
2689   switch (c)
2690     {
2691     case 'x':
2692       code = 0;
2693       count = 0;
2694       nonnull = 0;
2695       while (1)
2696         {
2697           c = getch ();
2698           if (! ISXDIGIT (c))
2699             {
2700               put_back (c);
2701               break;
2702             }
2703           code *= 16;
2704           if (c >= 'a' && c <= 'f')
2705             code += c - 'a' + 10;
2706           if (c >= 'A' && c <= 'F')
2707             code += c - 'A' + 10;
2708           if (c >= '0' && c <= '9')
2709             code += c - '0';
2710           if (code != 0 || count != 0)
2711             {
2712               if (count == 0)
2713                 firstdig = code;
2714               count++;
2715             }
2716           nonnull = 1;
2717         }
2718       if (! nonnull)
2719         error ("\\x used with no following hex digits");
2720       else if (count == 0)
2721         /* Digits are all 0's.  Ok.  */
2722         ;
2723       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2724                || (count > 1
2725                    && (((unsigned)1 <<
2726                         (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2727                        <= firstdig)))
2728         pedwarn ("hex escape out of range");
2729       return code;
2730
2731     case '0':  case '1':  case '2':  case '3':  case '4':
2732     case '5':  case '6':  case '7':
2733       code = 0;
2734       count = 0;
2735       while ((c <= '7') && (c >= '0') && (count++ < 3))
2736         {
2737           code = (code * 8) + (c - '0');
2738           c = getch ();
2739         }
2740       put_back (c);
2741       return code;
2742
2743     case '\\': case '\'': case '"':
2744       return c;
2745
2746     case '\n':
2747       lineno++;
2748       *ignore_ptr = 1;
2749       return 0;
2750
2751     case 'n':
2752       return TARGET_NEWLINE;
2753
2754     case 't':
2755       return TARGET_TAB;
2756
2757     case 'r':
2758       return TARGET_CR;
2759
2760     case 'f':
2761       return TARGET_FF;
2762
2763     case 'b':
2764       return TARGET_BS;
2765
2766     case 'a':
2767       return TARGET_BELL;
2768
2769     case 'v':
2770       return TARGET_VT;
2771
2772     case 'e':
2773     case 'E':
2774       if (pedantic)
2775         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
2776       return 033;
2777
2778     case '?':
2779       return c;
2780
2781       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
2782     case '(':
2783     case '{':
2784     case '[':
2785       /* `\%' is used to prevent SCCS from getting confused.  */
2786     case '%':
2787       if (pedantic)
2788         pedwarn ("unknown escape sequence `\\%c'", c);
2789       return c;
2790     }
2791   if (ISGRAPH (c))
2792     pedwarn ("unknown escape sequence `\\%c'", c);
2793   else
2794     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2795   return c;
2796 }
2797
2798 /* Value is 1 (or 2) if we should try to make the next identifier look like
2799    a typename (when it may be a local variable or a class variable).
2800    Value is 0 if we treat this name in a default fashion.  */
2801 int looking_for_typename;
2802
2803 #ifdef __GNUC__
2804 __inline
2805 #endif
2806 int
2807 identifier_type (decl)
2808      tree decl;
2809 {
2810   tree t;
2811   if (TREE_CODE (decl) == TEMPLATE_DECL)
2812     {
2813       if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
2814         return PTYPENAME;
2815       else if (looking_for_template) 
2816         return PFUNCNAME;
2817     }
2818   if (looking_for_template && really_overloaded_fn (decl))
2819     {
2820       /* See through a baselink.  */
2821       if (TREE_CODE (decl) == TREE_LIST)
2822         decl = TREE_VALUE (decl);
2823
2824       for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
2825         if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) 
2826           return PFUNCNAME;
2827     }
2828   if (TREE_CODE (decl) == NAMESPACE_DECL)
2829     return NSNAME;
2830   if (TREE_CODE (decl) != TYPE_DECL)
2831     return IDENTIFIER;
2832   if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
2833     return SELFNAME;
2834
2835   /* A constructor declarator for a template type will get here as an
2836      implicit typename, a TYPENAME_TYPE with a type.  */
2837   t = got_scope;
2838   if (t && TREE_CODE (t) == TYPENAME_TYPE)
2839     t = TREE_TYPE (t);
2840   decl = TREE_TYPE (decl);
2841   if (TREE_CODE (decl) == TYPENAME_TYPE)
2842     decl = TREE_TYPE (decl);
2843   if (t && t == decl)
2844     return SELFNAME;
2845
2846   return TYPENAME;
2847 }
2848
2849 void
2850 see_typename ()
2851 {
2852   /* Only types expected, not even namespaces. */
2853   looking_for_typename = 2;
2854   if (yychar < 0)
2855     if ((yychar = yylex ()) < 0) yychar = 0;
2856   looking_for_typename = 0;
2857   if (yychar == IDENTIFIER)
2858     {
2859       lastiddecl = lookup_name (yylval.ttype, -2);
2860       if (lastiddecl == 0)
2861         {
2862           if (flag_labels_ok)
2863             lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2864         }
2865       else
2866         yychar = identifier_type (lastiddecl);
2867     }
2868 }
2869
2870 /* Return true if d is in a global scope. */
2871
2872 static int
2873 is_global (d)
2874   tree d;
2875 {
2876   while (1)
2877     switch (TREE_CODE (d))
2878       {
2879       case ERROR_MARK:
2880         return 1;
2881
2882       case OVERLOAD: d = OVL_FUNCTION (d); continue;
2883       case TREE_LIST: d = TREE_VALUE (d); continue;
2884       default:
2885         my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629);
2886         d = CP_DECL_CONTEXT (d);
2887         return TREE_CODE (d) == NAMESPACE_DECL;
2888       }
2889 }
2890
2891 tree
2892 do_identifier (token, parsing, args)
2893      register tree token;
2894      int parsing;
2895      tree args;
2896 {
2897   register tree id;
2898   int lexing = (parsing == 1);
2899   int in_call = (parsing == 2);
2900
2901   if (! lexing || IDENTIFIER_OPNAME_P (token))
2902     id = lookup_name (token, 0);
2903   else
2904     id = lastiddecl;
2905
2906   /* Scope class declarations before global
2907      declarations.  */
2908   if ((!id || is_global (id))
2909       && current_class_type != 0
2910       && TYPE_SIZE (current_class_type) == 0)
2911     {
2912       /* Could be from one of the base classes.  */
2913       tree field = lookup_field (current_class_type, token, 1, 0);
2914       if (field == 0)
2915         ;
2916       else if (field == error_mark_node)
2917         /* We have already generated the error message.
2918            But we still want to return this value.  */
2919         id = lookup_field (current_class_type, token, 0, 0);
2920       else if (TREE_CODE (field) == VAR_DECL
2921                || TREE_CODE (field) == CONST_DECL
2922                || TREE_CODE (field) == TEMPLATE_DECL)
2923         id = field;
2924       else if (TREE_CODE (field) != FIELD_DECL)
2925         my_friendly_abort (61);
2926       else
2927         {
2928           cp_error ("invalid use of member `%D'", field);
2929           id = error_mark_node;
2930           return id;
2931         }
2932     }
2933
2934   /* Do Koenig lookup if appropriate (inside templates we build lookup
2935      expressions instead).  */
2936   if (args && !current_template_parms && (!id || is_global (id)))
2937     /* If we have arguments and we only found global names, do Koenig
2938          lookup. */
2939     id = lookup_arg_dependent (token, id, args);
2940
2941   /* Remember that this name has been used in the class definition, as per
2942      [class.scope0] */
2943   if (id && current_class_type && parsing
2944       && TYPE_BEING_DEFINED (current_class_type)
2945       && ! IDENTIFIER_CLASS_VALUE (token)
2946       /* Avoid breaking if we get called for a default argument that
2947          refers to an overloaded method.  Eventually this will not be
2948          necessary, since default arguments shouldn't be parsed until
2949          after the class is complete.  (jason 3/12/97) */
2950       && TREE_CODE (id) != OVERLOAD)
2951     pushdecl_class_level (id);
2952     
2953   if (!id || id == error_mark_node)
2954     {
2955       if (id == error_mark_node && current_class_type != NULL_TREE)
2956         {
2957           id = lookup_nested_field (token, 1);
2958           /* In lookup_nested_field(), we marked this so we can gracefully
2959              leave this whole mess.  */
2960           if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
2961             return id;
2962         }
2963
2964       if (current_template_parms)
2965         return build_min_nt (LOOKUP_EXPR, token);
2966       else if (IDENTIFIER_OPNAME_P (token))
2967         {
2968           if (token != ansi_opname[ERROR_MARK])
2969             cp_error ("`%D' not defined", token);
2970           id = error_mark_node;
2971         }
2972       else if (in_call && ! flag_strict_prototype)
2973         {
2974           id = implicitly_declare (token);
2975         }
2976       else if (current_function_decl == 0)
2977         {
2978           cp_error ("`%D' was not declared in this scope", token);
2979           id = error_mark_node;
2980         }
2981       else
2982         {
2983           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
2984               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2985             {
2986               static int undeclared_variable_notice;
2987
2988               cp_error ("`%D' undeclared (first use this function)", token);
2989
2990               if (! undeclared_variable_notice)
2991                 {
2992                   error ("(Each undeclared identifier is reported only once");
2993                   error ("for each function it appears in.)");
2994                   undeclared_variable_notice = 1;
2995                 }
2996             }
2997           id = error_mark_node;
2998           /* Prevent repeated error messages.  */
2999           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3000           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
3001         }
3002     }
3003
3004   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
3005     {
3006       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
3007       while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
3008              && DECL_DEAD_FOR_LOCAL (shadowed))
3009         shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
3010       if (!shadowed)
3011         shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
3012       if (shadowed)
3013         {
3014           if (!DECL_ERROR_REPORTED (id))
3015             {
3016               warning ("name lookup of `%s' changed",
3017                        IDENTIFIER_POINTER (token));
3018               cp_warning_at ("  matches this `%D' under current ANSI rules",
3019                              shadowed);
3020               cp_warning_at ("  matches this `%D' under old rules", id);
3021               DECL_ERROR_REPORTED (id) = 1;
3022             }
3023           id = shadowed;
3024         }
3025       else if (!DECL_ERROR_REPORTED (id))
3026         {
3027           static char msg[]
3028             = "name lookup of `%s' changed for new ANSI `for' scoping";
3029           DECL_ERROR_REPORTED (id) = 1;
3030           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
3031             {
3032               error (msg, IDENTIFIER_POINTER (token));
3033               cp_error_at ("  cannot use obsolete binding at `%D' because it has a destructor", id);
3034               id = error_mark_node;
3035             }
3036           else
3037             {
3038               pedwarn (msg, IDENTIFIER_POINTER (token));
3039               cp_pedwarn_at ("  using obsolete binding at `%D'", id);
3040             }
3041         }
3042     }
3043   /* TREE_USED is set in `hack_identifier'.  */
3044   if (TREE_CODE (id) == CONST_DECL)
3045     {
3046       if (IDENTIFIER_CLASS_VALUE (token) == id)
3047         {
3048           /* Check access.  */
3049           tree access = compute_access (TYPE_BINFO (current_class_type), id);
3050           if (access == access_private_node)
3051             cp_error ("enum `%D' is private", id);
3052           /* protected is OK, since it's an enum of `this'.  */
3053         }
3054       if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
3055         id = DECL_INITIAL (id);
3056     }
3057   else
3058     id = hack_identifier (id, token);
3059
3060   /* We must look up dependent names when the template is
3061      instantiated, not while parsing it.  For now, we don't
3062      distinguish between dependent and independent names.  So, for
3063      example, we look up all overloaded functions at
3064      instantiation-time, even though in some cases we should just use
3065      the DECL we have here.  We also use LOOKUP_EXPRs to find things
3066      like local variables, rather than creating TEMPLATE_DECLs for the
3067      local variables and then finding matching instantiations.  */
3068   if (current_template_parms
3069       && (is_overloaded_fn (id) 
3070           /* If it's not going to be around at instantiation time, we
3071              look it up then.  This is a hack, and should go when we
3072              really get dependent/independent name lookup right.  */
3073           || !TREE_PERMANENT (id)
3074           /* Some local VAR_DECLs (such as those for local variables
3075              in member functions of local classes) are built on the
3076              permanent obstack.  */
3077           || (TREE_CODE (id) == VAR_DECL 
3078               && CP_DECL_CONTEXT (id)
3079               && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
3080           || TREE_CODE (id) == PARM_DECL
3081           || TREE_CODE (id) == RESULT_DECL
3082           || TREE_CODE (id) == USING_DECL))
3083     id = build_min_nt (LOOKUP_EXPR, token);
3084       
3085   return id;
3086 }
3087
3088 tree
3089 do_scoped_id (token, parsing)
3090      tree token;
3091      int parsing;
3092 {
3093   tree id;
3094   /* during parsing, this is ::name. Otherwise, it is black magic. */
3095   if (parsing)
3096     {
3097       struct tree_binding _b;
3098       id = binding_init (&_b);
3099       if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
3100         id = NULL_TREE;
3101       else
3102         id = BINDING_VALUE (id);
3103     } 
3104   else
3105     id = IDENTIFIER_GLOBAL_VALUE (token);
3106   if (parsing && yychar == YYEMPTY)
3107     yychar = yylex ();
3108   if (! id)
3109     {
3110       if (processing_template_decl)
3111         {
3112           id = build_min_nt (LOOKUP_EXPR, token);
3113           LOOKUP_EXPR_GLOBAL (id) = 1;
3114           return id;
3115         }
3116       if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
3117           && ! flag_strict_prototype)
3118         id = implicitly_declare (token);
3119       else
3120         {
3121           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
3122             cp_error ("`::%D' undeclared (first use here)", token);
3123           id = error_mark_node;
3124           /* Prevent repeated error messages.  */
3125           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3126         }
3127     }
3128   else
3129     {
3130       if (TREE_CODE (id) == ADDR_EXPR)
3131         mark_used (TREE_OPERAND (id, 0));
3132       else if (TREE_CODE (id) != OVERLOAD)
3133         mark_used (id);
3134     }
3135   if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
3136     {
3137       /* XXX CHS - should we set TREE_USED of the constant? */
3138       id = DECL_INITIAL (id);
3139       /* This is to prevent an enum whose value is 0
3140          from being considered a null pointer constant.  */
3141       id = build1 (NOP_EXPR, TREE_TYPE (id), id);
3142       TREE_CONSTANT (id) = 1;
3143     }
3144
3145   if (processing_template_decl)
3146     {
3147       if (is_overloaded_fn (id))
3148         {
3149           id = build_min_nt (LOOKUP_EXPR, token);
3150           LOOKUP_EXPR_GLOBAL (id) = 1;
3151           return id;
3152         }
3153       /* else just use the decl */
3154     }
3155   return convert_from_reference (id);
3156 }
3157
3158 tree
3159 identifier_typedecl_value (node)
3160      tree node;
3161 {
3162   tree t, type;
3163   type = IDENTIFIER_TYPE_VALUE (node);
3164   if (type == NULL_TREE)
3165     return NULL_TREE;
3166
3167   if (IDENTIFIER_BINDING (node))
3168     {
3169       t = IDENTIFIER_VALUE (node);
3170       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3171         return t;
3172     }
3173   if (IDENTIFIER_NAMESPACE_VALUE (node))
3174     {
3175       t = IDENTIFIER_NAMESPACE_VALUE (node);
3176       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3177         return t;
3178     }
3179
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   retrofit_lang_decl (t);
4565   return t;
4566 }
4567
4568 /* Add DECL_LANG_SPECIFIC info to T.  Called from build_lang_decl
4569    and pushdecl (for functions generated by the backend).  */
4570
4571 void
4572 retrofit_lang_decl (t)
4573      tree t;
4574 {
4575   struct obstack *obstack = current_obstack;
4576   register int i = sizeof (struct lang_decl) / sizeof (int);
4577   register int *pi;
4578
4579   if (! TREE_PERMANENT (t))
4580     obstack = saveable_obstack;
4581   else
4582     /* Could be that saveable is permanent and current is not.  */
4583     obstack = &permanent_obstack;
4584
4585   if (free_lang_decl_chain && obstack == &permanent_obstack)
4586     {
4587       pi = (int *)free_lang_decl_chain;
4588       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4589     }
4590   else
4591     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4592
4593   while (i > 0)
4594     pi[--i] = 0;
4595
4596   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4597   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4598     = obstack == &permanent_obstack;
4599   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4600           == TREE_PERMANENT  (t), 234);
4601   DECL_MAIN_VARIANT (t) = t;
4602   if (current_lang_name == lang_name_cplusplus)
4603     DECL_LANGUAGE (t) = lang_cplusplus;
4604   else if (current_lang_name == lang_name_c)
4605     DECL_LANGUAGE (t) = lang_c;
4606   else if (current_lang_name == lang_name_java)
4607     DECL_LANGUAGE (t) = lang_java;
4608   else my_friendly_abort (64);
4609
4610 #if 0 /* not yet, should get fixed properly later */
4611   if (code == TYPE_DECL)
4612     {
4613       tree id;
4614       id = get_identifier (build_overload_name (type, 1, 1));
4615       DECL_ASSEMBLER_NAME (t) = id;
4616     }
4617
4618 #endif
4619 #ifdef GATHER_STATISTICS
4620   tree_node_counts[(int)lang_decl] += 1;
4621   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4622 #endif
4623 }
4624
4625 tree
4626 build_lang_field_decl (code, name, type)
4627      enum tree_code code;
4628      tree name;
4629      tree type;
4630 {
4631   extern struct obstack *current_obstack, *saveable_obstack;
4632   register tree t = build_decl (code, name, type);
4633   struct obstack *obstack = current_obstack;
4634   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4635   register int *pi;
4636 #if 0 /* not yet, should get fixed properly later */
4637
4638   if (code == TYPE_DECL)
4639     {
4640       tree id;
4641       id = get_identifier (build_overload_name (type, 1, 1));
4642       DECL_ASSEMBLER_NAME (t) = id;
4643     }
4644 #endif
4645
4646   if (! TREE_PERMANENT (t))
4647     obstack = saveable_obstack;
4648   else
4649     my_friendly_assert (obstack == &permanent_obstack, 235);
4650
4651   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4652   while (i > 0)
4653     pi[--i] = 0;
4654
4655   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4656   return t;
4657 }
4658
4659 void
4660 copy_lang_decl (node)
4661      tree node;
4662 {
4663   int size;
4664   int *pi;
4665
4666   if (! DECL_LANG_SPECIFIC (node))
4667     return;
4668
4669   if (TREE_CODE (node) == FIELD_DECL)
4670     size = sizeof (struct lang_decl_flags);
4671   else
4672     size = sizeof (struct lang_decl);
4673   pi = (int *)obstack_alloc (&permanent_obstack, size);
4674   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4675   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4676 }
4677
4678 tree
4679 make_lang_type (code)
4680      enum tree_code code;
4681 {
4682   extern struct obstack *current_obstack, *saveable_obstack;
4683   register tree t = make_node (code);
4684
4685   /* Set up some flags that give proper default behavior.  */
4686   if (IS_AGGR_TYPE_CODE (code))
4687     {
4688       struct obstack *obstack = current_obstack;
4689       struct lang_type *pi;
4690
4691       SET_IS_AGGR_TYPE (t, 1);
4692
4693       if (! TREE_PERMANENT (t))
4694         obstack = saveable_obstack;
4695       else
4696         my_friendly_assert (obstack == &permanent_obstack, 236);
4697
4698       pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
4699       bzero ((char *) pi, (int) sizeof (struct lang_type));
4700
4701       TYPE_LANG_SPECIFIC (t) = pi;
4702       CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
4703       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4704       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4705       TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
4706       CLASSTYPE_BINFO_AS_LIST (t) 
4707         = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4708
4709       /* Make sure this is laid out, for ease of use later.  In the
4710          presence of parse errors, the normal was of assuring this
4711          might not ever get executed, so we lay it out *immediately*.  */
4712       build_pointer_type (t);
4713
4714 #ifdef GATHER_STATISTICS
4715       tree_node_counts[(int)lang_type] += 1;
4716       tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
4717 #endif
4718     }
4719   else
4720     /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
4721        TYPE_ALIAS_SET is initialized to -1 by default, so we must
4722        clear it here.  */
4723     TYPE_ALIAS_SET (t) = 0;
4724
4725   return t;
4726 }
4727
4728 void
4729 dump_time_statistics ()
4730 {
4731   register tree prev = 0, decl, next;
4732   int this_time = my_get_run_time ();
4733   TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
4734     += this_time - body_time;
4735
4736   fprintf (stderr, "\n******\n");
4737   print_time ("header files (total)", header_time);
4738   print_time ("main file (total)", this_time - body_time);
4739   fprintf (stderr, "ratio = %g : 1\n",
4740            (double)header_time / (double)(this_time - body_time));
4741   fprintf (stderr, "\n******\n");
4742
4743   for (decl = filename_times; decl; decl = next)
4744     {
4745       next = IDENTIFIER_GLOBAL_VALUE (decl);
4746       SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
4747       prev = decl;
4748     }
4749
4750   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4751     print_time (IDENTIFIER_POINTER (decl),
4752                 TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
4753 }
4754
4755 void
4756 compiler_error (s, v, v2)
4757      char *s;
4758      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4759 {
4760   char buf[1024];
4761   sprintf (buf, s, v, v2);
4762   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4763 }
4764 \f
4765 void
4766 yyerror (string)
4767      char *string;
4768 {
4769   extern int end_of_file;
4770   char buf[200];
4771
4772   strcpy (buf, string);
4773
4774   /* We can't print string and character constants well
4775      because the token_buffer contains the result of processing escapes.  */
4776   if (end_of_file)
4777     strcat (buf, input_redirected ()
4778             ? " at end of saved text"
4779             : " at end of input");
4780   else if (token_buffer[0] == 0)
4781     strcat (buf, " at null character");
4782   else if (token_buffer[0] == '"')
4783     strcat (buf, " before string constant");
4784   else if (token_buffer[0] == '\'')
4785     strcat (buf, " before character constant");
4786   else if (!ISGRAPH ((unsigned char)token_buffer[0]))
4787     sprintf (buf + strlen (buf), " before character 0%o",
4788              (unsigned char) token_buffer[0]);
4789   else
4790     strcat (buf, " before `%s'");
4791
4792   error (buf, token_buffer);
4793 }
4794 \f
4795 static int
4796 handle_cp_pragma (pname)
4797      char *pname;
4798 {
4799   register int token;
4800
4801   if (! strcmp (pname, "vtable"))
4802     {
4803       extern tree pending_vtables;
4804
4805       /* More follows: it must be a string constant (class name).  */
4806       token = real_yylex ();
4807       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4808         {
4809           error ("invalid #pragma vtable");
4810           return -1;
4811         }
4812
4813       if (write_virtuals != 2)
4814         {
4815           warning ("use `+e2' option to enable #pragma vtable");
4816           return -1;
4817         }
4818       pending_vtables
4819         = perm_tree_cons (NULL_TREE,
4820                           get_identifier (TREE_STRING_POINTER (yylval.ttype)),
4821                           pending_vtables);
4822       token = real_yylex ();
4823       if (token != END_OF_LINE)
4824         warning ("trailing characters ignored");
4825       return 1;
4826     }
4827   else if (! strcmp (pname, "unit"))
4828     {
4829       /* More follows: it must be a string constant (unit name).  */
4830       token = real_yylex ();
4831       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4832         {
4833           error ("invalid #pragma unit");
4834           return -1;
4835         }
4836       token = real_yylex ();
4837       if (token != END_OF_LINE)
4838         warning ("trailing characters ignored");
4839       return 1;
4840     }
4841   else if (! strcmp (pname, "interface"))
4842     {
4843       tree fileinfo 
4844         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4845       char *main_filename = input_filename;
4846
4847       main_filename = file_name_nondirectory (main_filename);
4848
4849       token = real_yylex ();
4850       
4851       if (token != END_OF_LINE)
4852         {
4853           if (token != STRING
4854               || TREE_CODE (yylval.ttype) != STRING_CST)
4855             {
4856               error ("invalid `#pragma interface'");
4857               return -1;
4858             }
4859           main_filename = TREE_STRING_POINTER (yylval.ttype);
4860           token = real_yylex ();
4861         }
4862
4863       if (token != END_OF_LINE)
4864         warning ("garbage after `#pragma interface' ignored");
4865
4866       write_virtuals = 3;
4867
4868       if (impl_file_chain == 0)
4869         {
4870           /* If this is zero at this point, then we are
4871              auto-implementing.  */
4872           if (main_input_filename == 0)
4873             main_input_filename = input_filename;
4874
4875 #ifdef AUTO_IMPLEMENT
4876           filename = file_name_nondirectory (main_input_filename);
4877           fi = get_time_identifier (filename);
4878           fi = TIME_IDENTIFIER_FILEINFO (fi);
4879           TREE_INT_CST_LOW (fi) = 0;
4880           TREE_INT_CST_HIGH (fi) = 1;
4881           /* Get default.  */
4882           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
4883           impl_file_chain->filename = filename;
4884           impl_file_chain->next = 0;
4885 #endif
4886         }
4887
4888       interface_only = interface_strcmp (main_filename);
4889 #ifdef MULTIPLE_SYMBOL_SPACES
4890       if (! interface_only)
4891         interface_unknown = 0;
4892 #else /* MULTIPLE_SYMBOL_SPACES */
4893       interface_unknown = 0;
4894 #endif /* MULTIPLE_SYMBOL_SPACES */
4895       TREE_INT_CST_LOW (fileinfo) = interface_only;
4896       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4897
4898       return 1;
4899     }
4900   else if (! strcmp (pname, "implementation"))
4901     {
4902       tree fileinfo 
4903         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4904       char *main_filename = main_input_filename ? main_input_filename : input_filename;
4905
4906       main_filename = file_name_nondirectory (main_filename);
4907       token = real_yylex ();
4908       if (token != END_OF_LINE)
4909         {
4910           if (token != STRING
4911               || TREE_CODE (yylval.ttype) != STRING_CST)
4912             {
4913               error ("invalid `#pragma implementation'");
4914               return -1;
4915             }
4916           main_filename = TREE_STRING_POINTER (yylval.ttype);
4917           token = real_yylex ();
4918         }
4919
4920       if (token != END_OF_LINE)
4921         warning ("garbage after `#pragma implementation' ignored");
4922
4923       if (write_virtuals == 3)
4924         {
4925           struct impl_files *ifiles = impl_file_chain;
4926           while (ifiles)
4927             {
4928               if (! strcmp (ifiles->filename, main_filename))
4929                 break;
4930               ifiles = ifiles->next;
4931             }
4932           if (ifiles == 0)
4933             {
4934               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
4935               ifiles->filename = main_filename;
4936               ifiles->next = impl_file_chain;
4937               impl_file_chain = ifiles;
4938             }
4939         }
4940       else if ((main_input_filename != 0
4941                 && ! strcmp (main_input_filename, input_filename))
4942                || ! strcmp (input_filename, main_filename))
4943         {
4944           write_virtuals = 3;
4945           if (impl_file_chain == 0)
4946             {
4947               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
4948               impl_file_chain->filename = main_filename;
4949               impl_file_chain->next = 0;
4950             }
4951         }
4952       else
4953         error ("`#pragma implementation' can only appear at top-level");
4954       interface_only = 0;
4955 #if 1
4956       /* We make this non-zero so that we infer decl linkage
4957          in the impl file only for variables first declared
4958          in the interface file.  */
4959       interface_unknown = 1;
4960 #else
4961       /* We make this zero so that templates in the impl
4962          file will be emitted properly.  */
4963       interface_unknown = 0;
4964 #endif
4965       TREE_INT_CST_LOW (fileinfo) = interface_only;
4966       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4967
4968       return 1;
4969     }
4970
4971   return 0;
4972 }
4973
4974 /* Return the type-qualifier corresponding to the identifier given by
4975    RID.  */
4976
4977 int
4978 cp_type_qual_from_rid (rid)
4979      tree rid;
4980 {
4981   if (rid == ridpointers[(int) RID_CONST])
4982     return TYPE_QUAL_CONST;
4983   else if (rid == ridpointers[(int) RID_VOLATILE])
4984     return TYPE_QUAL_VOLATILE;
4985   else if (rid == ridpointers[(int) RID_RESTRICT])
4986     return TYPE_QUAL_RESTRICT;
4987
4988   my_friendly_abort (0);
4989   return TYPE_UNQUALIFIED;
4990 }
4991
4992 \f
4993 #ifdef HANDLE_GENERIC_PRAGMAS
4994
4995 /* Handle a #pragma directive.  TOKEN is the type of the word following
4996    the #pragma directive on the line.  Process the entire input line and
4997    return non-zero iff the directive successfully parsed.  */
4998
4999 /* This function has to be in this file, in order to get at
5000    the token types.  */
5001
5002 static int
5003 handle_generic_pragma (token)
5004      register int token;
5005 {
5006   for (;;)
5007     {
5008       switch (token)
5009         {
5010         case IDENTIFIER:
5011         case TYPENAME:
5012         case STRING:
5013         case CONSTANT:
5014           handle_pragma_token (token_buffer, yylval.ttype);
5015           break;
5016
5017         case LEFT_RIGHT:
5018           handle_pragma_token ("(", NULL_TREE);
5019           handle_pragma_token (")", NULL_TREE);
5020           break;
5021
5022         case END_OF_LINE:
5023           return handle_pragma_token (NULL_PTR, NULL_TREE);
5024
5025         default:
5026           handle_pragma_token (token_buffer, NULL);
5027         }
5028       
5029       token = real_yylex ();
5030     }
5031 }
5032 #endif /* HANDLE_GENERIC_PRAGMAS */