OSDN Git Service

* typeck.c (common_type): Handle cv-qual unification for pointers
[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 "input.h"
31 #include "tree.h"
32 #include "lex.h"
33 #include "cp-tree.h"
34 #include "parse.h"
35 #include "flags.h"
36 #include "obstack.h"
37 #include "c-pragma.h"
38 #include "toplev.h"
39 #include "output.h"
40
41 #ifdef MULTIBYTE_CHARS
42 #include "mbchar.h"
43 #include <locale.h>
44 #endif
45
46 #define obstack_chunk_alloc xmalloc
47 #define obstack_chunk_free free
48
49 #ifndef DIR_SEPARATOR
50 #define DIR_SEPARATOR '/'
51 #endif
52
53 extern struct obstack permanent_obstack;
54 extern struct obstack *current_obstack, *saveable_obstack;
55
56 extern void yyprint PROTO((FILE *, int, YYSTYPE));
57 extern void compiler_error PROTO((char *, HOST_WIDE_INT,
58                                   HOST_WIDE_INT));
59
60 static tree get_time_identifier PROTO((char *));
61 static int check_newline PROTO((void));
62 static int skip_white_space PROTO((int));
63 static void finish_defarg PROTO((void));
64 static int my_get_run_time PROTO((void));
65 static int get_last_nonwhite_on_line PROTO((void));
66 static int interface_strcmp PROTO((char *));
67 static int readescape PROTO((int *));
68 static char *extend_token_buffer PROTO((char *));
69 static void consume_string PROTO((struct obstack *, int));
70 static void set_typedecl_interface_info PROTO((tree, tree));
71 static void feed_defarg PROTO((tree, tree));
72 static int set_vardecl_interface_info PROTO((tree, tree));
73 static void store_pending_inline PROTO((tree, struct pending_inline *));
74 static void reinit_parse_for_expr PROTO((struct obstack *));
75 static int *init_cpp_parse PROTO((void));
76 static int handle_cp_pragma PROTO((char *));
77 #ifdef HANDLE_GENERIC_PRAGMAS
78 static int handle_generic_pragma PROTO((int));
79 #endif
80 #ifdef GATHER_STATISTICS
81 #ifdef REDUCE_LENGTH
82 static int reduce_cmp PROTO((int *, int *));
83 static int token_cmp PROTO((int *, int *));
84 #endif
85 #endif
86 static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
87 static void parse_float PROTO((PTR));
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 == error_mark_node)
2954     {
2955       /* lookup_name quietly returns error_mark_node if we're parsing,
2956          as we don't want to complain about an identifier that ends up
2957          being used as a declarator.  So we call it again to get the error
2958          message.  */
2959       id = lookup_name (token, 0);
2960       return error_mark_node;
2961     }
2962       
2963   if (!id)
2964     {
2965       if (current_template_parms)
2966         return build_min_nt (LOOKUP_EXPR, token);
2967       else if (IDENTIFIER_OPNAME_P (token))
2968         {
2969           if (token != ansi_opname[ERROR_MARK])
2970             cp_error ("`%D' not defined", token);
2971           id = error_mark_node;
2972         }
2973       else if (in_call && ! flag_strict_prototype)
2974         {
2975           id = implicitly_declare (token);
2976         }
2977       else if (current_function_decl == 0)
2978         {
2979           cp_error ("`%D' was not declared in this scope", token);
2980           id = error_mark_node;
2981         }
2982       else
2983         {
2984           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
2985               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2986             {
2987               static int undeclared_variable_notice;
2988
2989               cp_error ("`%D' undeclared (first use this function)", token);
2990
2991               if (! undeclared_variable_notice)
2992                 {
2993                   error ("(Each undeclared identifier is reported only once");
2994                   error ("for each function it appears in.)");
2995                   undeclared_variable_notice = 1;
2996                 }
2997             }
2998           id = error_mark_node;
2999           /* Prevent repeated error messages.  */
3000           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3001           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
3002         }
3003     }
3004
3005   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
3006     {
3007       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
3008       while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
3009              && DECL_DEAD_FOR_LOCAL (shadowed))
3010         shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
3011       if (!shadowed)
3012         shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
3013       if (shadowed)
3014         {
3015           if (!DECL_ERROR_REPORTED (id))
3016             {
3017               warning ("name lookup of `%s' changed",
3018                        IDENTIFIER_POINTER (token));
3019               cp_warning_at ("  matches this `%D' under current ANSI rules",
3020                              shadowed);
3021               cp_warning_at ("  matches this `%D' under old rules", id);
3022               DECL_ERROR_REPORTED (id) = 1;
3023             }
3024           id = shadowed;
3025         }
3026       else if (!DECL_ERROR_REPORTED (id))
3027         {
3028           static char msg[]
3029             = "name lookup of `%s' changed for new ANSI `for' scoping";
3030           DECL_ERROR_REPORTED (id) = 1;
3031           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
3032             {
3033               error (msg, IDENTIFIER_POINTER (token));
3034               cp_error_at ("  cannot use obsolete binding at `%D' because it has a destructor", id);
3035               id = error_mark_node;
3036             }
3037           else
3038             {
3039               pedwarn (msg, IDENTIFIER_POINTER (token));
3040               cp_pedwarn_at ("  using obsolete binding at `%D'", id);
3041             }
3042         }
3043     }
3044   /* TREE_USED is set in `hack_identifier'.  */
3045   if (TREE_CODE (id) == CONST_DECL)
3046     {
3047       /* Check access.  */
3048       if (IDENTIFIER_CLASS_VALUE (token) == id)
3049         enforce_access (DECL_REAL_CONTEXT(id), id);
3050       if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
3051         id = DECL_INITIAL (id);
3052     }
3053   else
3054     id = hack_identifier (id, token);
3055
3056   /* We must look up dependent names when the template is
3057      instantiated, not while parsing it.  For now, we don't
3058      distinguish between dependent and independent names.  So, for
3059      example, we look up all overloaded functions at
3060      instantiation-time, even though in some cases we should just use
3061      the DECL we have here.  We also use LOOKUP_EXPRs to find things
3062      like local variables, rather than creating TEMPLATE_DECLs for the
3063      local variables and then finding matching instantiations.  */
3064   if (current_template_parms
3065       && (is_overloaded_fn (id) 
3066           /* If it's not going to be around at instantiation time, we
3067              look it up then.  This is a hack, and should go when we
3068              really get dependent/independent name lookup right.  */
3069           || !TREE_PERMANENT (id)
3070           /* Some local VAR_DECLs (such as those for local variables
3071              in member functions of local classes) are built on the
3072              permanent obstack.  */
3073           || (TREE_CODE (id) == VAR_DECL 
3074               && CP_DECL_CONTEXT (id)
3075               && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
3076           || TREE_CODE (id) == PARM_DECL
3077           || TREE_CODE (id) == RESULT_DECL
3078           || TREE_CODE (id) == USING_DECL))
3079     id = build_min_nt (LOOKUP_EXPR, token);
3080       
3081   return id;
3082 }
3083
3084 tree
3085 do_scoped_id (token, parsing)
3086      tree token;
3087      int parsing;
3088 {
3089   tree id;
3090   /* during parsing, this is ::name. Otherwise, it is black magic. */
3091   if (parsing)
3092     {
3093       struct tree_binding _b;
3094       id = binding_init (&_b);
3095       if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
3096         id = NULL_TREE;
3097       else
3098         id = BINDING_VALUE (id);
3099     } 
3100   else
3101     id = IDENTIFIER_GLOBAL_VALUE (token);
3102   if (parsing && yychar == YYEMPTY)
3103     yychar = yylex ();
3104   if (! id)
3105     {
3106       if (processing_template_decl)
3107         {
3108           id = build_min_nt (LOOKUP_EXPR, token);
3109           LOOKUP_EXPR_GLOBAL (id) = 1;
3110           return id;
3111         }
3112       if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
3113           && ! flag_strict_prototype)
3114         id = implicitly_declare (token);
3115       else
3116         {
3117           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
3118             cp_error ("`::%D' undeclared (first use here)", token);
3119           id = error_mark_node;
3120           /* Prevent repeated error messages.  */
3121           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3122         }
3123     }
3124   else
3125     {
3126       if (TREE_CODE (id) == ADDR_EXPR)
3127         mark_used (TREE_OPERAND (id, 0));
3128       else if (TREE_CODE (id) != OVERLOAD)
3129         mark_used (id);
3130     }
3131   if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
3132     {
3133       /* XXX CHS - should we set TREE_USED of the constant? */
3134       id = DECL_INITIAL (id);
3135       /* This is to prevent an enum whose value is 0
3136          from being considered a null pointer constant.  */
3137       id = build1 (NOP_EXPR, TREE_TYPE (id), id);
3138       TREE_CONSTANT (id) = 1;
3139     }
3140
3141   if (processing_template_decl)
3142     {
3143       if (is_overloaded_fn (id))
3144         {
3145           id = build_min_nt (LOOKUP_EXPR, token);
3146           LOOKUP_EXPR_GLOBAL (id) = 1;
3147           return id;
3148         }
3149       /* else just use the decl */
3150     }
3151   return convert_from_reference (id);
3152 }
3153
3154 tree
3155 identifier_typedecl_value (node)
3156      tree node;
3157 {
3158   tree t, type;
3159   type = IDENTIFIER_TYPE_VALUE (node);
3160   if (type == NULL_TREE)
3161     return NULL_TREE;
3162
3163   if (IDENTIFIER_BINDING (node))
3164     {
3165       t = IDENTIFIER_VALUE (node);
3166       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3167         return t;
3168     }
3169   if (IDENTIFIER_NAMESPACE_VALUE (node))
3170     {
3171       t = IDENTIFIER_NAMESPACE_VALUE (node);
3172       if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
3173         return t;
3174     }
3175
3176   /* Will this one ever happen?  */
3177   if (TYPE_MAIN_DECL (type))
3178     return TYPE_MAIN_DECL (type);
3179
3180   /* We used to do an internal error of 62 here, but instead we will
3181      handle the return of a null appropriately in the callers.  */
3182   return NULL_TREE;
3183 }
3184
3185 struct pf_args 
3186 {
3187   /* Input */
3188   /* I/O */
3189   char *p;
3190   int c;
3191   int imag;
3192   tree type;
3193   /* Output */
3194   REAL_VALUE_TYPE value;
3195 };
3196
3197 static void
3198 parse_float (data)
3199      PTR data;
3200 {
3201   struct pf_args * args = (struct pf_args *) data;
3202   int fflag = 0, lflag = 0;
3203   /* Copy token_buffer now, while it has just the number
3204      and not the suffixes; once we add `f' or `i',
3205      REAL_VALUE_ATOF may not work any more.  */
3206   char *copy = (char *) alloca (args->p - token_buffer + 1);
3207   bcopy (token_buffer, copy, args->p - token_buffer + 1);
3208   
3209   while (1)
3210     {
3211       int lose = 0;
3212       
3213       /* Read the suffixes to choose a data type.  */
3214       switch (args->c)
3215         {
3216         case 'f': case 'F':
3217           if (fflag)
3218             error ("more than one `f' in numeric constant");
3219           fflag = 1;
3220           break;
3221           
3222         case 'l': case 'L':
3223           if (lflag)
3224             error ("more than one `l' in numeric constant");
3225           lflag = 1;
3226           break;
3227           
3228         case 'i': case 'I':
3229           if (args->imag)
3230             error ("more than one `i' or `j' in numeric constant");
3231           else if (pedantic)
3232             pedwarn ("ANSI C++ forbids imaginary numeric constants");
3233           args->imag = 1;
3234           break;
3235           
3236         default:
3237           lose = 1;
3238         }
3239       
3240       if (lose)
3241         break;
3242       
3243       if (args->p >= token_buffer + maxtoken - 3)
3244         args->p = extend_token_buffer (args->p);
3245       *(args->p++) = args->c;
3246       *(args->p) = 0;
3247       args->c = getch ();
3248     }
3249   
3250   /* The second argument, machine_mode, of REAL_VALUE_ATOF
3251      tells the desired precision of the binary result
3252      of decimal-to-binary conversion.  */
3253   
3254   if (fflag)
3255     {
3256       if (lflag)
3257         error ("both `f' and `l' in floating constant");
3258       
3259       args->type = float_type_node;
3260       args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
3261       /* A diagnostic is required here by some ANSI C testsuites.
3262          This is not pedwarn, become some people don't want
3263          an error for this.  */
3264       if (REAL_VALUE_ISINF (args->value) && pedantic)
3265         warning ("floating point number exceeds range of `float'");
3266     }
3267   else if (lflag)
3268     {
3269       args->type = long_double_type_node;
3270       args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
3271       if (REAL_VALUE_ISINF (args->value) && pedantic)
3272         warning ("floating point number exceeds range of `long double'");
3273     }
3274   else
3275     {
3276       args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
3277       if (REAL_VALUE_ISINF (args->value) && pedantic)
3278         warning ("floating point number exceeds range of `double'");
3279     }
3280 }
3281
3282 int
3283 real_yylex ()
3284 {
3285   register int c;
3286   register int value;
3287   int wide_flag = 0;
3288   int dollar_seen = 0;
3289   int i;
3290
3291   if (nextchar >= 0)
3292     c = nextchar, nextchar = -1;
3293   else
3294     c = getch ();
3295
3296   /* Effectively do c = skip_white_space (c)
3297      but do it faster in the usual cases.  */
3298   while (1)
3299     switch (c)
3300       {
3301       case ' ':
3302       case '\t':
3303       case '\f':
3304       case '\v':
3305       case '\b':
3306         c = getch ();
3307         break;
3308
3309       case '\r':
3310         /* Call skip_white_space so we can warn if appropriate.  */
3311
3312       case '\n':
3313       case '/':
3314       case '\\':
3315         c = skip_white_space (c);
3316       default:
3317         goto found_nonwhite;
3318       }
3319  found_nonwhite:
3320
3321   token_buffer[0] = c;
3322   token_buffer[1] = 0;
3323
3324 /*  yylloc.first_line = lineno; */
3325
3326   switch (c)
3327     {
3328     case EOF:
3329       token_buffer[0] = '\0';
3330       end_of_file = 1;
3331       if (input_redirected ())
3332         value = END_OF_SAVED_INPUT;
3333       else if (linemode)
3334         value = END_OF_LINE;
3335       else
3336         value = ENDFILE;
3337       break;
3338
3339     case '$':
3340       if (! dollars_in_ident)
3341         error ("`$' in identifier");
3342       else if (pedantic)
3343         pedwarn ("`$' in identifier");
3344       dollar_seen = 1;
3345       goto letter;
3346
3347     case 'L':
3348       /* Capital L may start a wide-string or wide-character constant.  */
3349       {
3350         register int c = getch ();
3351         if (c == '\'')
3352           {
3353             wide_flag = 1;
3354             goto char_constant;
3355           }
3356         if (c == '"')
3357           {
3358             wide_flag = 1;
3359             goto string_constant;
3360           }
3361         put_back (c);
3362       }
3363
3364     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
3365     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
3366     case 'K':             case 'M':  case 'N':  case 'O':
3367     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
3368     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
3369     case 'Z':
3370     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
3371     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
3372     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
3373     case 'p':  case 'q':  case 'r':  case 's':  case 't':
3374     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
3375     case 'z':
3376     case '_':
3377     letter:
3378       {
3379         register char *p;
3380
3381         p = token_buffer;
3382         if (input == 0)
3383           {
3384             /* We know that `token_buffer' can hold at least on char,
3385                so we install C immediately.
3386                We may have to read the value in `putback_char', so call
3387                `getch' once.  */
3388             *p++ = c;
3389             c = getch ();
3390
3391             /* Make this run fast.  We know that we are reading straight
3392                from FINPUT in this case (since identifiers cannot straddle
3393                input sources.  */
3394             while (ISALNUM (c) || (c == '_') || c == '$')
3395               {
3396                 if (c == '$')
3397                   {
3398                     if (! dollars_in_ident)
3399                       error ("`$' in identifier");
3400                     else if (pedantic)
3401                       pedwarn ("`$' in identifier");
3402                   }
3403
3404                 if (p >= token_buffer + maxtoken)
3405                   p = extend_token_buffer (p);
3406
3407                 *p++ = c;
3408                 c = getch ();
3409               }
3410
3411             if (linemode && c == '\n')
3412               {
3413                 put_back (c);
3414                 c = EOF;
3415               }
3416           }
3417         else
3418           {
3419             /* We know that `token_buffer' can hold at least on char,
3420                so we install C immediately.  */
3421             *p++ = c;
3422             c = getch ();
3423
3424             while (ISALNUM (c) || (c == '_') || c == '$')
3425               {
3426                 if (c == '$')
3427                   {
3428                     if (! dollars_in_ident)
3429                       error ("`$' in identifier");
3430                     else if (pedantic)
3431                       pedwarn ("`$' in identifier");
3432                   }
3433
3434                 if (p >= token_buffer + maxtoken)
3435                   p = extend_token_buffer (p);
3436
3437                 *p++ = c;
3438                 c = getch ();
3439               }
3440           }
3441
3442         *p = 0;
3443         nextchar = c;
3444
3445         value = IDENTIFIER;
3446         yylval.itype = 0;
3447
3448       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
3449
3450         {
3451           register struct resword *ptr;
3452
3453           if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
3454             {
3455               if (ptr->rid)
3456                 {
3457                   tree old_ttype = ridpointers[(int) ptr->rid];
3458
3459                   /* If this provides a type for us, then revert lexical
3460                      state to standard state.  */
3461                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
3462                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
3463                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
3464                     looking_for_typename = 0;
3465                   else if (ptr->token == AGGR || ptr->token == ENUM)
3466                     looking_for_typename = 2;
3467
3468                   /* Check if this is a language-type declaration.
3469                      Just glimpse the next non-white character.  */
3470                   nextchar = skip_white_space (nextchar);
3471                   if (nextchar == '"')
3472                     {
3473                       /* We are looking at a string.  Complain
3474                          if the token before the string is no `extern'.
3475                          
3476                          Could cheat some memory by placing this string
3477                          on the temporary_, instead of the saveable_
3478                          obstack.  */
3479
3480                       if (ptr->rid != RID_EXTERN)
3481                         error ("invalid modifier `%s' for language string",
3482                                ptr->name);
3483                       real_yylex ();
3484                       value = EXTERN_LANG_STRING;
3485                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
3486                       break;
3487                     }
3488                   if (ptr->token == VISSPEC)
3489                     {
3490                       switch (ptr->rid)
3491                         {
3492                         case RID_PUBLIC:
3493                           yylval.ttype = access_public_node;
3494                           break;
3495                         case RID_PRIVATE:
3496                           yylval.ttype = access_private_node;
3497                           break;
3498                         case RID_PROTECTED:
3499                           yylval.ttype = access_protected_node;
3500                           break;
3501                         default:
3502                           my_friendly_abort (63);
3503                         }
3504                     }
3505                   else
3506                     yylval.ttype = old_ttype;
3507                 }
3508               else if (ptr->token == EQCOMPARE)
3509                 {
3510                   yylval.code = NE_EXPR;
3511                   token_buffer[0] = '!';
3512                   token_buffer[1] = '=';
3513                   token_buffer[2] = 0;
3514                 }
3515               else if (ptr->token == ASSIGN)
3516                 {
3517                   if (strcmp ("and_eq", token_buffer) == 0)
3518                     {
3519                       yylval.code = BIT_AND_EXPR;
3520                       token_buffer[0] = '&';
3521                     }
3522                   else if (strcmp ("or_eq", token_buffer) == 0)
3523                     {
3524                       yylval.code = BIT_IOR_EXPR;
3525                       token_buffer[0] = '|';
3526                     }
3527                   else if (strcmp ("xor_eq", token_buffer) == 0)
3528                     {
3529                       yylval.code = BIT_XOR_EXPR;
3530                       token_buffer[0] = '^';
3531                     }
3532                   token_buffer[1] = '=';
3533                   token_buffer[2] = 0;
3534                 }
3535               else if (ptr->token == '&')
3536                 {
3537                   yylval.code = BIT_AND_EXPR;
3538                   token_buffer[0] = '&';
3539                   token_buffer[1] = 0;
3540                 }
3541               else if (ptr->token == '|')
3542                 {
3543                   yylval.code = BIT_IOR_EXPR;
3544                   token_buffer[0] = '|';
3545                   token_buffer[1] = 0;
3546                 }
3547               else if (ptr->token == '^')
3548                 {
3549                   yylval.code = BIT_XOR_EXPR;
3550                   token_buffer[0] = '^';
3551                   token_buffer[1] = 0;
3552                 }
3553
3554               value = (int) ptr->token;
3555             }
3556         }
3557
3558         /* If we did not find a keyword, look for an identifier
3559            (or a typename).  */
3560
3561         if (value == IDENTIFIER || value == TYPESPEC)
3562           GNU_xref_ref (current_function_decl, token_buffer);
3563
3564         if (value == IDENTIFIER)
3565           {
3566             register tree tmp = get_identifier (token_buffer);
3567
3568 #if !defined(VMS) && defined(JOINER)
3569             /* Make sure that user does not collide with our internal
3570                naming scheme.  */
3571             if (JOINER == '$'
3572                 && dollar_seen
3573                 && (THIS_NAME_P (tmp)
3574                     || VPTR_NAME_P (tmp)
3575                     || DESTRUCTOR_NAME_P (tmp)
3576                     || VTABLE_NAME_P (tmp)
3577                     || TEMP_NAME_P (tmp)
3578                     || ANON_AGGRNAME_P (tmp)
3579                     || ANON_PARMNAME_P (tmp)))
3580               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3581                        token_buffer);
3582 #endif
3583
3584             yylval.ttype = tmp;
3585           }
3586         if (value == NEW && ! global_bindings_p ())
3587           {
3588             value = NEW;
3589             goto done;
3590           }
3591       }
3592       break;
3593
3594     case '.':
3595       {
3596         register int c1 = getch ();
3597         token_buffer[0] = c;
3598         token_buffer[1] = c1;
3599         if (c1 == '*')
3600           {
3601             value = DOT_STAR;
3602             token_buffer[2] = 0;
3603             goto done;
3604           }
3605         if (c1 == '.')
3606           {
3607             c1 = getch ();
3608             if (c1 == '.')
3609               {
3610                 token_buffer[2] = c1;
3611                 token_buffer[3] = 0;
3612                 value = ELLIPSIS;
3613                 goto done;
3614               }
3615             error ("parse error at `..'");
3616           }
3617         if (ISDIGIT (c1))
3618           {
3619             put_back (c1);
3620             goto resume_numerical_scan;
3621           }
3622         nextchar = c1;
3623         value = '.';
3624         token_buffer[1] = 0;
3625         goto done;
3626       }
3627     case '0':  case '1':
3628         /* Optimize for most frequent case.  */
3629       {
3630         register int c1 = getch ();
3631         if (! ISALNUM (c1) && c1 != '.')
3632           {
3633             /* Terminate string.  */
3634             token_buffer[0] = c;
3635             token_buffer[1] = 0;
3636             if (c == '0')
3637               yylval.ttype = integer_zero_node;
3638             else
3639               yylval.ttype = integer_one_node;
3640             nextchar = c1;
3641             value = CONSTANT;
3642             goto done;
3643           }
3644         put_back (c1);
3645       }
3646       /* fall through...  */
3647                           case '2':  case '3':  case '4':
3648     case '5':  case '6':  case '7':  case '8':  case '9':
3649     resume_numerical_scan:
3650       {
3651         register char *p;
3652         int base = 10;
3653         int count = 0;
3654         int largest_digit = 0;
3655         int numdigits = 0;
3656         /* for multi-precision arithmetic,
3657            we actually store only HOST_BITS_PER_CHAR bits in each part.
3658            The number of parts is chosen so as to be sufficient to hold
3659            the enough bits to fit into the two HOST_WIDE_INTs that contain
3660            the integer value (this is always at least as many bits as are
3661            in a target `long long' value, but may be wider).  */
3662 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3663         int parts[TOTAL_PARTS];
3664         int overflow = 0;
3665
3666         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3667           = NOT_FLOAT;
3668
3669         for (count = 0; count < TOTAL_PARTS; count++)
3670           parts[count] = 0;
3671
3672         p = token_buffer;
3673         *p++ = c;
3674
3675         if (c == '0')
3676           {
3677             *p++ = (c = getch ());
3678             if ((c == 'x') || (c == 'X'))
3679               {
3680                 base = 16;
3681                 *p++ = (c = getch ());
3682               }
3683             /* Leading 0 forces octal unless the 0 is the only digit.  */
3684             else if (c >= '0' && c <= '9')
3685               {
3686                 base = 8;
3687                 numdigits++;
3688               }
3689             else
3690               numdigits++;
3691           }
3692
3693         /* Read all the digits-and-decimal-points.  */
3694
3695         while (c == '.'
3696                || (ISALNUM (c) && (c != 'l') && (c != 'L')
3697                    && (c != 'u') && (c != 'U')
3698                    && c != 'i' && c != 'I' && c != 'j' && c != 'J'
3699                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3700           {
3701             if (c == '.')
3702               {
3703                 if (base == 16)
3704                   error ("floating constant may not be in radix 16");
3705                 if (floatflag == TOO_MANY_POINTS)
3706                   /* We have already emitted an error.  Don't need another.  */
3707                   ;
3708                 else if (floatflag == AFTER_POINT)
3709                   {
3710                     error ("malformed floating constant");
3711                     floatflag = TOO_MANY_POINTS;
3712                     /* Avoid another error from atof by forcing all characters
3713                        from here on to be ignored.  */
3714                     p[-1] = '\0';
3715                   }
3716                 else
3717                   floatflag = AFTER_POINT;
3718
3719                 base = 10;
3720                 *p++ = c = getch ();
3721                 /* Accept '.' as the start of a floating-point number
3722                    only when it is followed by a digit.
3723                    Otherwise, unread the following non-digit
3724                    and use the '.' as a structural token.  */
3725                 if (p == token_buffer + 2 && !ISDIGIT (c))
3726                   {
3727                     if (c == '.')
3728                       {
3729                         c = getch ();
3730                         if (c == '.')
3731                           {
3732                             *p++ = '.';
3733                             *p = '\0';
3734                             value = ELLIPSIS;
3735                             goto done;
3736                           }
3737                         error ("parse error at `..'");
3738                       }
3739                     nextchar = c;
3740                     token_buffer[1] = '\0';
3741                     value = '.';
3742                     goto done;
3743                   }
3744               }
3745             else
3746               {
3747                 /* It is not a decimal point.
3748                    It should be a digit (perhaps a hex digit).  */
3749
3750                 if (ISDIGIT (c))
3751                   {
3752                     c = c - '0';
3753                   }
3754                 else if (base <= 10)
3755                   {
3756                     if (c == 'e' || c == 'E')
3757                       {
3758                         base = 10;
3759                         floatflag = AFTER_POINT;
3760                         break;   /* start of exponent */
3761                       }
3762                     error ("nondigits in number and not hexadecimal");
3763                     c = 0;
3764                   }
3765                 else if (c >= 'a')
3766                   {
3767                     c = c - 'a' + 10;
3768                   }
3769                 else
3770                   {
3771                     c = c - 'A' + 10;
3772                   }
3773                 if (c >= largest_digit)
3774                   largest_digit = c;
3775                 numdigits++;
3776
3777                 for (count = 0; count < TOTAL_PARTS; count++)
3778                   {
3779                     parts[count] *= base;
3780                     if (count)
3781                       {
3782                         parts[count]
3783                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3784                         parts[count-1]
3785                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3786                       }
3787                     else
3788                       parts[0] += c;
3789                   }
3790
3791                 /* If the extra highest-order part ever gets anything in it,
3792                    the number is certainly too big.  */
3793                 if (parts[TOTAL_PARTS - 1] != 0)
3794                   overflow = 1;
3795
3796                 if (p >= token_buffer + maxtoken - 3)
3797                   p = extend_token_buffer (p);
3798                 *p++ = (c = getch ());
3799               }
3800           }
3801
3802         if (numdigits == 0)
3803           error ("numeric constant with no digits");
3804
3805         if (largest_digit >= base)
3806           error ("numeric constant contains digits beyond the radix");
3807
3808         /* Remove terminating char from the token buffer and delimit the string */
3809         *--p = 0;
3810
3811         if (floatflag != NOT_FLOAT)
3812           {
3813             tree type = double_type_node;
3814             int exceeds_double = 0;
3815             int imag = 0;
3816             REAL_VALUE_TYPE value;
3817             struct pf_args args;
3818
3819             /* Read explicit exponent if any, and put it in tokenbuf.  */
3820
3821             if ((c == 'e') || (c == 'E'))
3822               {
3823                 if (p >= token_buffer + maxtoken - 3)
3824                   p = extend_token_buffer (p);
3825                 *p++ = c;
3826                 c = getch ();
3827                 if ((c == '+') || (c == '-'))
3828                   {
3829                     *p++ = c;
3830                     c = getch ();
3831                   }
3832                 if (! ISDIGIT (c))
3833                   error ("floating constant exponent has no digits");
3834                 while (ISDIGIT (c))
3835                   {
3836                     if (p >= token_buffer + maxtoken - 3)
3837                       p = extend_token_buffer (p);
3838                     *p++ = c;
3839                     c = getch ();
3840                   }
3841               }
3842
3843             *p = 0;
3844             errno = 0;
3845
3846             /* Setup input for parse_float() */
3847             args.p = p;
3848             args.c = c;
3849             args.imag = imag;
3850             args.type = type;
3851             
3852             /* Convert string to a double, checking for overflow.  */
3853             if (do_float_handler (parse_float, (PTR) &args))
3854               {
3855                 /* Receive output from parse_float() */
3856                 value = args.value;
3857               }
3858             else
3859               {
3860                 /* We got an exception from parse_float() */
3861                 error ("floating constant out of range");
3862                 value = dconst0;
3863               }
3864
3865             /* Receive output from parse_float() */
3866             p = args.p;
3867             c = args.c;
3868             imag = args.imag;
3869             type = args.type;
3870             
3871 #ifdef ERANGE
3872             if (errno == ERANGE && pedantic)
3873               {
3874                 /* ERANGE is also reported for underflow,
3875                    so test the value to distinguish overflow from that.  */
3876                 if (REAL_VALUES_LESS (dconst1, value)
3877                     || REAL_VALUES_LESS (value, dconstm1))
3878                   {
3879                     pedwarn ("floating point number exceeds range of `%s'",
3880                              IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
3881                     exceeds_double = 1;
3882                   }
3883               }
3884 #endif
3885
3886             /* If the result is not a number, assume it must have been
3887                due to some error message above, so silently convert
3888                it to a zero.  */
3889             if (REAL_VALUE_ISNAN (value))
3890               value = dconst0;
3891
3892             /* Create a node with determined type and value.  */
3893             if (imag)
3894               yylval.ttype = build_complex (NULL_TREE,
3895                                             cp_convert (type, integer_zero_node),
3896                                             build_real (type, value));
3897             else
3898               yylval.ttype = build_real (type, value);
3899           }
3900         else
3901           {
3902             tree type;
3903             HOST_WIDE_INT high, low;
3904             int spec_unsigned = 0;
3905             int spec_long = 0;
3906             int spec_long_long = 0;
3907             int spec_imag = 0;
3908             int bytes, warn;
3909
3910             while (1)
3911               {
3912                 if (c == 'u' || c == 'U')
3913                   {
3914                     if (spec_unsigned)
3915                       error ("two `u's in integer constant");
3916                     spec_unsigned = 1;
3917                   }
3918                 else if (c == 'l' || c == 'L')
3919                   {
3920                     if (spec_long)
3921                       {
3922                         if (spec_long_long)
3923                           error ("three `l's in integer constant");
3924                         else if (pedantic && ! in_system_header && warn_long_long)
3925                           pedwarn ("ANSI C++ forbids long long integer constants");
3926                         spec_long_long = 1;
3927                       }
3928                     spec_long = 1;
3929                   }
3930                 else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
3931                   {
3932                     if (spec_imag)
3933                       error ("more than one `i' or `j' in numeric constant");
3934                     else if (pedantic)
3935                       pedwarn ("ANSI C++ forbids imaginary numeric constants");
3936                     spec_imag = 1;
3937                   }
3938                 else
3939                   break;
3940                 if (p >= token_buffer + maxtoken - 3)
3941                   p = extend_token_buffer (p);
3942                 *p++ = c;
3943                 c = getch ();
3944               }
3945
3946             /* If the constant is not long long and it won't fit in an
3947                unsigned long, or if the constant is long long and won't fit
3948                in an unsigned long long, then warn that the constant is out
3949                of range.  */
3950
3951             /* ??? This assumes that long long and long integer types are
3952                a multiple of 8 bits.  This better than the original code
3953                though which assumed that long was exactly 32 bits and long
3954                long was exactly 64 bits.  */
3955
3956             if (spec_long_long)
3957               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3958             else
3959               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3960
3961             warn = overflow;
3962             for (i = bytes; i < TOTAL_PARTS; i++)
3963               if (parts[i])
3964                 warn = 1;
3965             if (warn)
3966               pedwarn ("integer constant out of range");
3967
3968             /* This is simplified by the fact that our constant
3969                is always positive.  */
3970             high = low = 0;
3971
3972             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3973               {
3974                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3975                                                     / HOST_BITS_PER_CHAR)]
3976                          << (i * HOST_BITS_PER_CHAR));
3977                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3978               }
3979             
3980             
3981             yylval.ttype = build_int_2 (low, high);
3982             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3983
3984             /* Calculate the ANSI type.  */
3985             if (!spec_long && !spec_unsigned
3986                 && int_fits_type_p (yylval.ttype, integer_type_node))
3987               type = integer_type_node;
3988             else if (!spec_long && (base != 10 || spec_unsigned)
3989                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
3990               /* Nondecimal constants try unsigned even in traditional C.  */
3991               type = unsigned_type_node;
3992             else if (!spec_unsigned && !spec_long_long
3993                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
3994               type = long_integer_type_node;
3995             else if (! spec_long_long)
3996               type = long_unsigned_type_node;
3997             else if (! spec_unsigned
3998                      /* Verify value does not overflow into sign bit.  */
3999                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
4000                      && int_fits_type_p (yylval.ttype,
4001                                          long_long_integer_type_node))
4002               type = long_long_integer_type_node;
4003             else
4004               type = long_long_unsigned_type_node;
4005
4006             if (!int_fits_type_p (yylval.ttype, type) && !warn)
4007               pedwarn ("integer constant out of range");
4008
4009             if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
4010               warning ("decimal integer constant is so large that it is unsigned");
4011
4012             if (spec_imag)
4013               {
4014                 if (TYPE_PRECISION (type)
4015                     <= TYPE_PRECISION (integer_type_node))
4016                   yylval.ttype
4017                     = build_complex (NULL_TREE, integer_zero_node,
4018                                      cp_convert (integer_type_node,
4019                                                  yylval.ttype));
4020                 else
4021                   error ("complex integer constant is too wide for `__complex int'");
4022               }
4023             else
4024               TREE_TYPE (yylval.ttype) = type;
4025           }
4026
4027         put_back (c);
4028         *p = 0;
4029
4030         value = CONSTANT; break;
4031       }
4032
4033     case '\'':
4034     char_constant:
4035       {
4036         register int result = 0;
4037         register int num_chars = 0;
4038         int chars_seen = 0;
4039         unsigned width = TYPE_PRECISION (char_type_node);
4040         int max_chars;
4041 #ifdef MULTIBYTE_CHARS
4042         int longest_char = local_mb_cur_max ();
4043         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
4044 #endif
4045
4046         max_chars = TYPE_PRECISION (integer_type_node) / width;
4047         if (wide_flag)
4048           width = WCHAR_TYPE_SIZE;
4049
4050         while (1)
4051           {
4052           tryagain:
4053             c = getch ();
4054
4055             if (c == '\'' || c == EOF)
4056               break;
4057
4058             ++chars_seen;
4059             if (c == '\\')
4060               {
4061                 int ignore = 0;
4062                 c = readescape (&ignore);
4063                 if (ignore)
4064                   goto tryagain;
4065                 if (width < HOST_BITS_PER_INT
4066                     && (unsigned) c >= ((unsigned)1 << width))
4067                   pedwarn ("escape sequence out of range for character");
4068 #ifdef MAP_CHARACTER
4069                 if (ISPRINT (c))
4070                   c = MAP_CHARACTER (c);
4071 #endif
4072               }
4073             else if (c == '\n')
4074               {
4075                 if (pedantic)
4076                   pedwarn ("ANSI C forbids newline in character constant");
4077                 lineno++;
4078               }
4079             else
4080               {
4081 #ifdef MULTIBYTE_CHARS
4082                 wchar_t wc;
4083                 int i;
4084                 int char_len = -1;
4085                 for (i = 1; i <= longest_char; ++i)
4086                   {
4087                     if (i > maxtoken - 4)
4088                       extend_token_buffer (token_buffer);
4089
4090                     token_buffer[i] = c;
4091                     char_len = local_mbtowc (& wc,
4092                                              token_buffer + 1,
4093                                              i);
4094                     if (char_len != -1)
4095                       break;
4096                     c = getch ();
4097                   }
4098                 if (char_len > 1)
4099                   {
4100                     /* mbtowc sometimes needs an extra char before accepting */
4101                     if (char_len < i)
4102                       put_back (c);
4103                     if (! wide_flag)
4104                       {
4105                         /* Merge character into result; ignore excess chars.  */
4106                         for (i = 1; i <= char_len; ++i)
4107                           {
4108                             if (i > max_chars)
4109                               break;
4110                             if (width < HOST_BITS_PER_INT)
4111                               result = (result << width)
4112                                 | (token_buffer[i]
4113                                    & ((1 << width) - 1));
4114                             else
4115                               result = token_buffer[i];
4116                           }
4117                         num_chars += char_len;
4118                         goto tryagain;
4119                       }
4120                     c = wc;
4121                   }
4122                 else
4123                   {
4124                     if (char_len == -1)
4125                       warning ("Ignoring invalid multibyte character");
4126                     if (wide_flag)
4127                       c = wc;
4128 #ifdef MAP_CHARACTER
4129                     else
4130                       c = MAP_CHARACTER (c);
4131 #endif
4132                   }
4133 #else /* ! MULTIBYTE_CHARS */
4134 #ifdef MAP_CHARACTER
4135                 c = MAP_CHARACTER (c);
4136 #endif
4137 #endif /* ! MULTIBYTE_CHARS */
4138               }
4139
4140             if (wide_flag)
4141               {
4142                 if (chars_seen == 1) /* only keep the first one */
4143                   result = c;
4144                 goto tryagain;
4145               }
4146
4147             /* Merge character into result; ignore excess chars.  */
4148             num_chars++;
4149             if (num_chars < max_chars + 1)
4150               {
4151                 if (width < HOST_BITS_PER_INT)
4152                   result = (result << width) | (c & ((1 << width) - 1));
4153                 else
4154                   result = c;
4155               }
4156           }
4157
4158         if (c != '\'')
4159           error ("malformatted character constant");
4160         else if (chars_seen == 0)
4161           error ("empty character constant");
4162         else if (num_chars > max_chars)
4163           {
4164             num_chars = max_chars;
4165             error ("character constant too long");
4166           }
4167         else if (chars_seen != 1 && warn_multichar)
4168           warning ("multi-character character constant");
4169
4170         /* If char type is signed, sign-extend the constant.  */
4171         if (! wide_flag)
4172           {
4173             int num_bits = num_chars * width;
4174             if (num_bits == 0)
4175               /* We already got an error; avoid invalid shift.  */
4176               yylval.ttype = build_int_2 (0, 0);
4177             else if (TREE_UNSIGNED (char_type_node)
4178                      || ((result >> (num_bits - 1)) & 1) == 0)
4179               yylval.ttype
4180                 = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
4181                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4182                                0);
4183             else
4184               yylval.ttype
4185                 = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
4186                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4187                                -1);
4188             if (chars_seen <= 1)
4189               TREE_TYPE (yylval.ttype) = char_type_node;
4190             else
4191               TREE_TYPE (yylval.ttype) = integer_type_node;
4192           }
4193         else
4194           {
4195             yylval.ttype = build_int_2 (result, 0);
4196             TREE_TYPE (yylval.ttype) = wchar_type_node;
4197           }
4198
4199         value = CONSTANT;
4200         break;
4201       }
4202
4203     case '"':
4204     string_constant:
4205       {
4206         register char *p;
4207         unsigned width = wide_flag ? WCHAR_TYPE_SIZE
4208                                    : TYPE_PRECISION (char_type_node);
4209 #ifdef MULTIBYTE_CHARS
4210         int longest_char = local_mb_cur_max ();
4211         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
4212 #endif
4213
4214         c = getch ();
4215         p = token_buffer + 1;
4216
4217         while (c != '"' && c >= 0)
4218           {
4219             /* ignore_escape_flag is set for reading the filename in #line.  */
4220             if (!ignore_escape_flag && c == '\\')
4221               {
4222                 int ignore = 0;
4223                 c = readescape (&ignore);
4224                 if (ignore)
4225                   goto skipnewline;
4226                 if (width < HOST_BITS_PER_INT
4227                     && (unsigned) c >= ((unsigned)1 << width))
4228                   warning ("escape sequence out of range for character");
4229               }
4230             else if (c == '\n')
4231               {
4232                 if (pedantic)
4233                   pedwarn ("ANSI C++ forbids newline in string constant");
4234                 lineno++;
4235               }
4236             else
4237               {
4238 #ifdef MULTIBYTE_CHARS
4239                 wchar_t wc;
4240                 int i;
4241                 int char_len = -1;
4242                 for (i = 0; i < longest_char; ++i)
4243                   {
4244                     if (p + i >= token_buffer + maxtoken)
4245                       p = extend_token_buffer (p);
4246                     p[i] = c;
4247
4248                     char_len = local_mbtowc (& wc, p, i + 1);
4249                     if (char_len != -1)
4250                       break;
4251                     c = getch ();
4252                   }
4253                 if (char_len == -1)
4254                   warning ("Ignoring invalid multibyte character");
4255                 else
4256                   {
4257                     /* mbtowc sometimes needs an extra char before accepting */
4258                     if (char_len <= i)
4259                       put_back (c);
4260                     if (! wide_flag)
4261                       {
4262                         p += (i + 1);
4263                         c = getch ();
4264                         continue;
4265                       }
4266                     c = wc;
4267                   }
4268 #endif /* MULTIBYTE_CHARS */
4269               }
4270
4271             /* Add this single character into the buffer either as a wchar_t
4272                or as a single byte.  */
4273             if (wide_flag)
4274               {
4275                 unsigned width = TYPE_PRECISION (char_type_node);
4276                 unsigned bytemask = (1 << width) - 1;
4277                 int byte;
4278
4279                 if (p + WCHAR_BYTES > token_buffer + maxtoken)
4280                   p = extend_token_buffer (p);
4281
4282                 for (byte = 0; byte < WCHAR_BYTES; ++byte)
4283                   {
4284                     int value;
4285                     if (byte >= (int) sizeof(c))
4286                       value = 0;
4287                     else
4288                       value = (c >> (byte * width)) & bytemask;
4289                     if (BYTES_BIG_ENDIAN)
4290                       p[WCHAR_BYTES - byte - 1] = value;
4291                     else
4292                       p[byte] = value;
4293                   }
4294                 p += WCHAR_BYTES;
4295               }
4296             else
4297               {
4298                 if (p >= token_buffer + maxtoken)
4299                   p = extend_token_buffer (p);
4300                 *p++ = c;
4301               }
4302
4303           skipnewline:
4304             c = getch ();
4305             if (c == EOF) {
4306                 error ("Unterminated string");
4307                 break;
4308             }
4309           }
4310
4311         /* Terminate the string value, either with a single byte zero
4312            or with a wide zero.  */
4313         if (wide_flag)
4314           {
4315             if (p + WCHAR_BYTES > token_buffer + maxtoken)
4316               p = extend_token_buffer (p);
4317             bzero (p, WCHAR_BYTES);
4318             p += WCHAR_BYTES;
4319           }
4320         else
4321           {
4322             if (p >= token_buffer + maxtoken)
4323               p = extend_token_buffer (p);
4324             *p++ = 0;
4325           }
4326
4327         /* We have read the entire constant.
4328            Construct a STRING_CST for the result.  */
4329
4330         if (processing_template_decl)
4331           push_obstacks (&permanent_obstack, &permanent_obstack);
4332         yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1);
4333         if (processing_template_decl)
4334           pop_obstacks ();
4335
4336         if (wide_flag)
4337           TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4338         else
4339           TREE_TYPE (yylval.ttype) = char_array_type_node;
4340
4341         value = STRING; break;
4342       }
4343
4344     case '+':
4345     case '-':
4346     case '&':
4347     case '|':
4348     case '<':
4349     case '>':
4350     case '*':
4351     case '/':
4352     case '%':
4353     case '^':
4354     case '!':
4355     case '=':
4356       {
4357         register int c1;
4358
4359       combine:
4360
4361         switch (c)
4362           {
4363           case '+':
4364             yylval.code = PLUS_EXPR; break;
4365           case '-':
4366             yylval.code = MINUS_EXPR; break;
4367           case '&':
4368             yylval.code = BIT_AND_EXPR; break;
4369           case '|':
4370             yylval.code = BIT_IOR_EXPR; break;
4371           case '*':
4372             yylval.code = MULT_EXPR; break;
4373           case '/':
4374             yylval.code = TRUNC_DIV_EXPR; break;
4375           case '%':
4376             yylval.code = TRUNC_MOD_EXPR; break;
4377           case '^':
4378             yylval.code = BIT_XOR_EXPR; break;
4379           case LSHIFT:
4380             yylval.code = LSHIFT_EXPR; break;
4381           case RSHIFT:
4382             yylval.code = RSHIFT_EXPR; break;
4383           case '<':
4384             yylval.code = LT_EXPR; break;
4385           case '>':
4386             yylval.code = GT_EXPR; break;
4387           }
4388
4389         token_buffer[1] = c1 = getch ();
4390         token_buffer[2] = 0;
4391
4392         if (c1 == '=')
4393           {
4394             switch (c)
4395               {
4396               case '<':
4397                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4398               case '>':
4399                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4400               case '!':
4401                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4402               case '=':
4403                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4404               }
4405             value = ASSIGN; goto done;
4406           }
4407         else if (c == c1)
4408           switch (c)
4409             {
4410             case '+':
4411               value = PLUSPLUS; goto done;
4412             case '-':
4413               value = MINUSMINUS; goto done;
4414             case '&':
4415               value = ANDAND; goto done;
4416             case '|':
4417               value = OROR; goto done;
4418             case '<':
4419               c = LSHIFT;
4420               goto combine;
4421             case '>':
4422               c = RSHIFT;
4423               goto combine;
4424             }
4425         else if ((c == '-') && (c1 == '>'))
4426           {
4427             nextchar = getch ();
4428             if (nextchar == '*')
4429               {
4430                 nextchar = -1;
4431                 value = POINTSAT_STAR;
4432               }
4433             else
4434               value = POINTSAT;
4435             goto done;
4436           }
4437         else if (c1 == '?' && (c == '<' || c == '>'))
4438           {
4439             token_buffer[3] = 0;
4440
4441             c1 = getch ();
4442             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4443             if (c1 == '=')
4444               {
4445                 /* <?= or >?= expression.  */
4446                 token_buffer[2] = c1;
4447                 value = ASSIGN;
4448               }
4449             else
4450               {
4451                 value = MIN_MAX;
4452                 nextchar = c1;
4453               }
4454             if (pedantic)
4455               pedwarn ("use of `operator %s' is not standard C++",
4456                        token_buffer);
4457             goto done;
4458           }
4459         /* digraphs */
4460         else if (c == '<' && c1 == '%')
4461           { value = '{'; goto done; }
4462         else if (c == '<' && c1 == ':')
4463           { value = '['; goto done; }
4464         else if (c == '%' && c1 == '>')
4465           { value = '}'; goto done; }
4466         else if (c == '%' && c1 == ':')
4467           { value = '#'; goto done; }
4468
4469         nextchar = c1;
4470         token_buffer[1] = 0;
4471
4472         value = c;
4473         goto done;
4474       }
4475
4476     case ':':
4477       c = getch ();
4478       if (c == ':')
4479         {
4480           token_buffer[1] = ':';
4481           token_buffer[2] = '\0';
4482           value = SCOPE;
4483           yylval.itype = 1;
4484         }
4485       else if (c == '>')
4486         {
4487           value = ']';
4488           goto done;
4489         }
4490       else
4491         {
4492           nextchar = c;
4493           value = ':';
4494         }
4495       break;
4496
4497     case 0:
4498       /* Don't make yyparse think this is eof.  */
4499       value = 1;
4500       break;
4501
4502     case '(':
4503       /* try, weakly, to handle casts to pointers to functions.  */
4504       nextchar = skip_white_space (getch ());
4505       if (nextchar == '*')
4506         {
4507           int next_c = skip_white_space (getch ());
4508           if (next_c == ')')
4509             {
4510               nextchar = -1;
4511               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4512               value = PAREN_STAR_PAREN;
4513             }
4514           else
4515             {
4516               put_back (next_c);
4517               value = c;
4518             }
4519         }
4520       else if (nextchar == ')')
4521         {
4522           nextchar = -1;
4523           yylval.ttype = NULL_TREE;
4524           value = LEFT_RIGHT;
4525         }
4526       else value = c;
4527       break;
4528
4529     default:
4530       value = c;
4531     }
4532
4533 done:
4534 /*  yylloc.last_line = lineno; */
4535 #ifdef GATHER_STATISTICS
4536 #ifdef REDUCE_LENGTH
4537   token_count[value] += 1;
4538 #endif
4539 #endif
4540
4541   return value;
4542 }
4543
4544 int
4545 is_rid (t)
4546      tree t;
4547 {
4548   return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
4549 }
4550
4551 #ifdef GATHER_STATISTICS
4552 /* The original for tree_node_kind is in the toplevel tree.c; changes there
4553    need to be brought into here, unless this were actually put into a header
4554    instead.  */
4555 /* Statistics-gathering stuff.  */
4556 typedef enum
4557 {
4558   d_kind,
4559   t_kind,
4560   b_kind,
4561   s_kind,
4562   r_kind,
4563   e_kind,
4564   c_kind,
4565   id_kind,
4566   op_id_kind,
4567   perm_list_kind,
4568   temp_list_kind,
4569   vec_kind,
4570   x_kind,
4571   lang_decl,
4572   lang_type,
4573   all_kinds
4574 } tree_node_kind;
4575
4576 extern int tree_node_counts[];
4577 extern int tree_node_sizes[];
4578 #endif
4579
4580 /* Place to save freed lang_decls which were allocated on the
4581    permanent_obstack.  @@ Not currently used.  */
4582 tree free_lang_decl_chain;
4583
4584 tree
4585 build_lang_decl (code, name, type)
4586      enum tree_code code;
4587      tree name;
4588      tree type;
4589 {
4590   register tree t = build_decl (code, name, type);
4591   retrofit_lang_decl (t);
4592   return t;
4593 }
4594
4595 /* Add DECL_LANG_SPECIFIC info to T.  Called from build_lang_decl
4596    and pushdecl (for functions generated by the backend).  */
4597
4598 void
4599 retrofit_lang_decl (t)
4600      tree t;
4601 {
4602   struct obstack *obstack = current_obstack;
4603   register int i = sizeof (struct lang_decl) / sizeof (int);
4604   register int *pi;
4605
4606   if (! TREE_PERMANENT (t))
4607     obstack = saveable_obstack;
4608   else
4609     /* Could be that saveable is permanent and current is not.  */
4610     obstack = &permanent_obstack;
4611
4612   if (free_lang_decl_chain && obstack == &permanent_obstack)
4613     {
4614       pi = (int *)free_lang_decl_chain;
4615       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4616     }
4617   else
4618     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4619
4620   while (i > 0)
4621     pi[--i] = 0;
4622
4623   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4624   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4625     = obstack == &permanent_obstack;
4626   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4627           == TREE_PERMANENT  (t), 234);
4628   DECL_MAIN_VARIANT (t) = t;
4629   if (current_lang_name == lang_name_cplusplus)
4630     DECL_LANGUAGE (t) = lang_cplusplus;
4631   else if (current_lang_name == lang_name_c)
4632     DECL_LANGUAGE (t) = lang_c;
4633   else if (current_lang_name == lang_name_java)
4634     DECL_LANGUAGE (t) = lang_java;
4635   else my_friendly_abort (64);
4636
4637 #if 0 /* not yet, should get fixed properly later */
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
4645 #endif
4646 #ifdef GATHER_STATISTICS
4647   tree_node_counts[(int)lang_decl] += 1;
4648   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4649 #endif
4650 }
4651
4652 tree
4653 build_lang_field_decl (code, name, type)
4654      enum tree_code code;
4655      tree name;
4656      tree type;
4657 {
4658   extern struct obstack *current_obstack, *saveable_obstack;
4659   register tree t = build_decl (code, name, type);
4660   struct obstack *obstack = current_obstack;
4661   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4662   register int *pi;
4663 #if 0 /* not yet, should get fixed properly later */
4664
4665   if (code == TYPE_DECL)
4666     {
4667       tree id;
4668       id = get_identifier (build_overload_name (type, 1, 1));
4669       DECL_ASSEMBLER_NAME (t) = id;
4670     }
4671 #endif
4672
4673   if (! TREE_PERMANENT (t))
4674     obstack = saveable_obstack;
4675   else
4676     my_friendly_assert (obstack == &permanent_obstack, 235);
4677
4678   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4679   while (i > 0)
4680     pi[--i] = 0;
4681
4682   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4683   return t;
4684 }
4685
4686 void
4687 copy_lang_decl (node)
4688      tree node;
4689 {
4690   int size;
4691   int *pi;
4692
4693   if (! DECL_LANG_SPECIFIC (node))
4694     return;
4695
4696   if (TREE_CODE (node) == FIELD_DECL)
4697     size = sizeof (struct lang_decl_flags);
4698   else
4699     size = sizeof (struct lang_decl);
4700   pi = (int *)obstack_alloc (&permanent_obstack, size);
4701   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4702   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4703 }
4704
4705 tree
4706 make_lang_type (code)
4707      enum tree_code code;
4708 {
4709   extern struct obstack *current_obstack, *saveable_obstack;
4710   register tree t = make_node (code);
4711
4712   /* Set up some flags that give proper default behavior.  */
4713   if (IS_AGGR_TYPE_CODE (code))
4714     {
4715       struct obstack *obstack = current_obstack;
4716       struct lang_type *pi;
4717
4718       SET_IS_AGGR_TYPE (t, 1);
4719
4720       if (! TREE_PERMANENT (t))
4721         obstack = saveable_obstack;
4722       else
4723         my_friendly_assert (obstack == &permanent_obstack, 236);
4724
4725       pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
4726       bzero ((char *) pi, (int) sizeof (struct lang_type));
4727
4728       TYPE_LANG_SPECIFIC (t) = pi;
4729       CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
4730       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4731       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4732       TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
4733       CLASSTYPE_BINFO_AS_LIST (t) 
4734         = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4735
4736       /* Make sure this is laid out, for ease of use later.  In the
4737          presence of parse errors, the normal was of assuring this
4738          might not ever get executed, so we lay it out *immediately*.  */
4739       build_pointer_type (t);
4740
4741 #ifdef GATHER_STATISTICS
4742       tree_node_counts[(int)lang_type] += 1;
4743       tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
4744 #endif
4745     }
4746   else
4747     /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
4748        TYPE_ALIAS_SET is initialized to -1 by default, so we must
4749        clear it here.  */
4750     TYPE_ALIAS_SET (t) = 0;
4751
4752   return t;
4753 }
4754
4755 void
4756 dump_time_statistics ()
4757 {
4758   register tree prev = 0, decl, next;
4759   int this_time = my_get_run_time ();
4760   TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
4761     += this_time - body_time;
4762
4763   fprintf (stderr, "\n******\n");
4764   print_time ("header files (total)", header_time);
4765   print_time ("main file (total)", this_time - body_time);
4766   fprintf (stderr, "ratio = %g : 1\n",
4767            (double)header_time / (double)(this_time - body_time));
4768   fprintf (stderr, "\n******\n");
4769
4770   for (decl = filename_times; decl; decl = next)
4771     {
4772       next = IDENTIFIER_GLOBAL_VALUE (decl);
4773       SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
4774       prev = decl;
4775     }
4776
4777   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4778     print_time (IDENTIFIER_POINTER (decl),
4779                 TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
4780 }
4781
4782 void
4783 compiler_error (s, v, v2)
4784      char *s;
4785      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4786 {
4787   char buf[1024];
4788   sprintf (buf, s, v, v2);
4789   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4790 }
4791 \f
4792 void
4793 yyerror (string)
4794      char *string;
4795 {
4796   extern int end_of_file;
4797   char buf[200];
4798
4799   strcpy (buf, string);
4800
4801   /* We can't print string and character constants well
4802      because the token_buffer contains the result of processing escapes.  */
4803   if (end_of_file)
4804     strcat (buf, input_redirected ()
4805             ? " at end of saved text"
4806             : " at end of input");
4807   else if (token_buffer[0] == 0)
4808     strcat (buf, " at null character");
4809   else if (token_buffer[0] == '"')
4810     strcat (buf, " before string constant");
4811   else if (token_buffer[0] == '\'')
4812     strcat (buf, " before character constant");
4813   else if (!ISGRAPH ((unsigned char)token_buffer[0]))
4814     sprintf (buf + strlen (buf), " before character 0%o",
4815              (unsigned char) token_buffer[0]);
4816   else
4817     strcat (buf, " before `%s'");
4818
4819   error (buf, token_buffer);
4820 }
4821 \f
4822 static int
4823 handle_cp_pragma (pname)
4824      char *pname;
4825 {
4826   register int token;
4827
4828   if (! strcmp (pname, "vtable"))
4829     {
4830       extern tree pending_vtables;
4831
4832       /* More follows: it must be a string constant (class name).  */
4833       token = real_yylex ();
4834       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4835         {
4836           error ("invalid #pragma vtable");
4837           return -1;
4838         }
4839
4840       if (write_virtuals != 2)
4841         {
4842           warning ("use `+e2' option to enable #pragma vtable");
4843           return -1;
4844         }
4845       pending_vtables
4846         = perm_tree_cons (NULL_TREE,
4847                           get_identifier (TREE_STRING_POINTER (yylval.ttype)),
4848                           pending_vtables);
4849       token = real_yylex ();
4850       if (token != END_OF_LINE)
4851         warning ("trailing characters ignored");
4852       return 1;
4853     }
4854   else if (! strcmp (pname, "unit"))
4855     {
4856       /* More follows: it must be a string constant (unit name).  */
4857       token = real_yylex ();
4858       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4859         {
4860           error ("invalid #pragma unit");
4861           return -1;
4862         }
4863       token = real_yylex ();
4864       if (token != END_OF_LINE)
4865         warning ("trailing characters ignored");
4866       return 1;
4867     }
4868   else if (! strcmp (pname, "interface"))
4869     {
4870       tree fileinfo 
4871         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4872       char *main_filename = input_filename;
4873
4874       main_filename = file_name_nondirectory (main_filename);
4875
4876       token = real_yylex ();
4877       
4878       if (token != END_OF_LINE)
4879         {
4880           if (token != STRING
4881               || TREE_CODE (yylval.ttype) != STRING_CST)
4882             {
4883               error ("invalid `#pragma interface'");
4884               return -1;
4885             }
4886           main_filename = TREE_STRING_POINTER (yylval.ttype);
4887           token = real_yylex ();
4888         }
4889
4890       if (token != END_OF_LINE)
4891         warning ("garbage after `#pragma interface' ignored");
4892
4893       write_virtuals = 3;
4894
4895       if (impl_file_chain == 0)
4896         {
4897           /* If this is zero at this point, then we are
4898              auto-implementing.  */
4899           if (main_input_filename == 0)
4900             main_input_filename = input_filename;
4901
4902 #ifdef AUTO_IMPLEMENT
4903           filename = file_name_nondirectory (main_input_filename);
4904           fi = get_time_identifier (filename);
4905           fi = TIME_IDENTIFIER_FILEINFO (fi);
4906           TREE_INT_CST_LOW (fi) = 0;
4907           TREE_INT_CST_HIGH (fi) = 1;
4908           /* Get default.  */
4909           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
4910           impl_file_chain->filename = filename;
4911           impl_file_chain->next = 0;
4912 #endif
4913         }
4914
4915       interface_only = interface_strcmp (main_filename);
4916 #ifdef MULTIPLE_SYMBOL_SPACES
4917       if (! interface_only)
4918         interface_unknown = 0;
4919 #else /* MULTIPLE_SYMBOL_SPACES */
4920       interface_unknown = 0;
4921 #endif /* MULTIPLE_SYMBOL_SPACES */
4922       TREE_INT_CST_LOW (fileinfo) = interface_only;
4923       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4924
4925       return 1;
4926     }
4927   else if (! strcmp (pname, "implementation"))
4928     {
4929       tree fileinfo 
4930         = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
4931       char *main_filename = main_input_filename ? main_input_filename : input_filename;
4932
4933       main_filename = file_name_nondirectory (main_filename);
4934       token = real_yylex ();
4935       if (token != END_OF_LINE)
4936         {
4937           if (token != STRING
4938               || TREE_CODE (yylval.ttype) != STRING_CST)
4939             {
4940               error ("invalid `#pragma implementation'");
4941               return -1;
4942             }
4943           main_filename = TREE_STRING_POINTER (yylval.ttype);
4944           token = real_yylex ();
4945         }
4946
4947       if (token != END_OF_LINE)
4948         warning ("garbage after `#pragma implementation' ignored");
4949
4950       if (write_virtuals == 3)
4951         {
4952           struct impl_files *ifiles = impl_file_chain;
4953           while (ifiles)
4954             {
4955               if (! strcmp (ifiles->filename, main_filename))
4956                 break;
4957               ifiles = ifiles->next;
4958             }
4959           if (ifiles == 0)
4960             {
4961               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
4962               ifiles->filename = main_filename;
4963               ifiles->next = impl_file_chain;
4964               impl_file_chain = ifiles;
4965             }
4966         }
4967       else if ((main_input_filename != 0
4968                 && ! strcmp (main_input_filename, input_filename))
4969                || ! strcmp (input_filename, main_filename))
4970         {
4971           write_virtuals = 3;
4972           if (impl_file_chain == 0)
4973             {
4974               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
4975               impl_file_chain->filename = main_filename;
4976               impl_file_chain->next = 0;
4977             }
4978         }
4979       else
4980         error ("`#pragma implementation' can only appear at top-level");
4981       interface_only = 0;
4982 #if 1
4983       /* We make this non-zero so that we infer decl linkage
4984          in the impl file only for variables first declared
4985          in the interface file.  */
4986       interface_unknown = 1;
4987 #else
4988       /* We make this zero so that templates in the impl
4989          file will be emitted properly.  */
4990       interface_unknown = 0;
4991 #endif
4992       TREE_INT_CST_LOW (fileinfo) = interface_only;
4993       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4994
4995       return 1;
4996     }
4997
4998   return 0;
4999 }
5000
5001 /* Return the type-qualifier corresponding to the identifier given by
5002    RID.  */
5003
5004 int
5005 cp_type_qual_from_rid (rid)
5006      tree rid;
5007 {
5008   if (rid == ridpointers[(int) RID_CONST])
5009     return TYPE_QUAL_CONST;
5010   else if (rid == ridpointers[(int) RID_VOLATILE])
5011     return TYPE_QUAL_VOLATILE;
5012   else if (rid == ridpointers[(int) RID_RESTRICT])
5013     return TYPE_QUAL_RESTRICT;
5014
5015   my_friendly_abort (0);
5016   return TYPE_UNQUALIFIED;
5017 }
5018
5019 \f
5020 #ifdef HANDLE_GENERIC_PRAGMAS
5021
5022 /* Handle a #pragma directive.  TOKEN is the type of the word following
5023    the #pragma directive on the line.  Process the entire input line and
5024    return non-zero iff the directive successfully parsed.  */
5025
5026 /* This function has to be in this file, in order to get at
5027    the token types.  */
5028
5029 static int
5030 handle_generic_pragma (token)
5031      register int token;
5032 {
5033   for (;;)
5034     {
5035       switch (token)
5036         {
5037         case IDENTIFIER:
5038         case TYPENAME:
5039         case STRING:
5040         case CONSTANT:
5041           handle_pragma_token (token_buffer, yylval.ttype);
5042           break;
5043
5044         case LEFT_RIGHT:
5045           handle_pragma_token ("(", NULL_TREE);
5046           handle_pragma_token (")", NULL_TREE);
5047           break;
5048
5049         case END_OF_LINE:
5050           return handle_pragma_token (NULL_PTR, NULL_TREE);
5051
5052         default:
5053           handle_pragma_token (token_buffer, NULL);
5054         }
5055       
5056       token = real_yylex ();
5057     }
5058 }
5059 #endif /* HANDLE_GENERIC_PRAGMAS */