OSDN Git Service

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