OSDN Git Service

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