OSDN Git Service

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