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