OSDN Git Service

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