OSDN Git Service

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