OSDN Git Service

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