OSDN Git Service

Change HANDLE_PRAGMA macro so that it will work with USE_CPPLIB
[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 #if defined HANDLE_PRAGMA
2220 /* Local versions of these macros, that can be passed as function pointers.  */
2221 static int
2222 pragma_getc ()
2223 {
2224   int c;
2225       
2226   if (nextchar != EOF)
2227     {
2228       c = nextchar;
2229       nextchar = EOF;
2230     }
2231   else
2232     c = getch ();
2233
2234   return c;
2235 }
2236
2237 static void
2238 pragma_ungetc (arg)
2239      int arg;
2240 {
2241   yyungetc (arg, 0);
2242 }
2243 #endif /* HANDLE_PRAGMA */
2244
2245 /* At the beginning of a line, increment the line number
2246    and process any #-directive on this line.
2247    If the line is a #-directive, read the entire line and return a newline.
2248    Otherwise, return the line's first non-whitespace character.  */
2249
2250 int linemode;
2251
2252 static int handle_cp_pragma PROTO((char *));
2253
2254 static int
2255 check_newline ()
2256 {
2257   register int c;
2258   register int token;
2259
2260   /* Read first nonwhite char on the line.  Do this before incrementing the
2261      line number, in case we're at the end of saved text.  */
2262
2263   do
2264     c = getch ();
2265   while (c == ' ' || c == '\t');
2266
2267   lineno++;
2268
2269   if (c != '#')
2270     {
2271       /* If not #, return it so caller will use it.  */
2272       return c;
2273     }
2274
2275   /* Don't read beyond this line.  */
2276   linemode = 1;
2277   
2278   /* Read first nonwhite char after the `#'.  */
2279
2280   do
2281     c = getch ();
2282   while (c == ' ' || c == '\t');
2283
2284   /* If a letter follows, then if the word here is `line', skip
2285      it and ignore it; otherwise, ignore the line, with an error
2286      if the word isn't `pragma'.  */
2287
2288   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
2289     {
2290       if (c == 'p')
2291         {
2292           if (getch () == 'r'
2293               && getch () == 'a'
2294               && getch () == 'g'
2295               && getch () == 'm'
2296               && getch () == 'a')
2297             {
2298               token = real_yylex ();
2299               if (token == IDENTIFIER
2300                   && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
2301                 {
2302                   /* If this is 1, we handled it; if it's -1, it was one we
2303                      wanted but had something wrong with it.  Only if it's
2304                      0 was it not handled.  */
2305                   if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
2306                     goto skipline;
2307                 }
2308               else if (token == END_OF_LINE)
2309                 goto skipline;
2310
2311 #ifdef HANDLE_PRAGMA
2312               /* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA
2313                  (if both are defined), in order to give the back
2314                  end a chance to override the interpretation of
2315                  SYSV style pragmas.  */
2316               if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
2317                                  IDENTIFIER_POINTER (yylval.ttype)))
2318                 goto skipline;
2319 #endif /* HANDLE_PRAGMA */
2320               
2321 #ifdef HANDLE_SYSV_PRAGMA
2322               if (handle_sysv_pragma (token))
2323                 goto skipline;
2324 #endif /* !HANDLE_SYSV_PRAGMA */
2325
2326               /* Issue a warning message if we have been asked to do so.
2327                  Ignoring unknown pragmas in system header file unless
2328                  an explcit -Wunknown-pragmas has been given. */
2329               if (warn_unknown_pragmas > 1
2330                   || (warn_unknown_pragmas && ! in_system_header))
2331                 warning ("ignoring pragma: %s", token_buffer);
2332             }
2333           
2334           goto skipline;
2335         }
2336       else if (c == 'd')
2337         {
2338           if (getch () == 'e'
2339               && getch () == 'f'
2340               && getch () == 'i'
2341               && getch () == 'n'
2342               && getch () == 'e'
2343               && ((c = getch ()) == ' ' || c == '\t'))
2344             {
2345               debug_define (lineno, GET_DIRECTIVE_LINE ());
2346               goto skipline;
2347             }
2348         }
2349       else if (c == 'u')
2350         {
2351           if (getch () == 'n'
2352               && getch () == 'd'
2353               && getch () == 'e'
2354               && getch () == 'f'
2355               && ((c = getch ()) == ' ' || c == '\t'))
2356             {
2357               debug_undef (lineno, GET_DIRECTIVE_LINE ());
2358               goto skipline;
2359             }
2360         }
2361       else if (c == 'l')
2362         {
2363           if (getch () == 'i'
2364               && getch () == 'n'
2365               && getch () == 'e'
2366               && ((c = getch ()) == ' ' || c == '\t'))
2367             goto linenum;
2368         }
2369       else if (c == 'i')
2370         {
2371           if (getch () == 'd'
2372               && getch () == 'e'
2373               && getch () == 'n'
2374               && getch () == 't'
2375               && ((c = getch ()) == ' ' || c == '\t'))
2376             {
2377               /* #ident.  The pedantic warning is now in cccp.c.  */
2378
2379               /* Here we have just seen `#ident '.
2380                  A string constant should follow.  */
2381
2382               token = real_yylex ();
2383               if (token == END_OF_LINE)
2384                 goto skipline;
2385               if (token != STRING
2386                   || TREE_CODE (yylval.ttype) != STRING_CST)
2387                 {
2388                   error ("invalid #ident");
2389                   goto skipline;
2390                 }
2391
2392               if (! flag_no_ident)
2393                 {
2394 #ifdef ASM_OUTPUT_IDENT
2395                   ASM_OUTPUT_IDENT (asm_out_file,
2396                                     TREE_STRING_POINTER (yylval.ttype));
2397 #endif
2398                 }
2399
2400               /* Skip the rest of this line.  */
2401               goto skipline;
2402             }
2403         }
2404       else if (c == 'n')
2405         {
2406           if (getch () == 'e'
2407               && getch () == 'w'
2408               && getch () == 'w'
2409               && getch () == 'o'
2410               && getch () == 'r'
2411               && getch () == 'l'
2412               && getch () == 'd'
2413               && ((c = getch ()) == ' ' || c == '\t'))
2414             {
2415               /* Used to test incremental compilation.  */
2416               sorry ("#pragma newworld");
2417               goto skipline;
2418             }
2419         }
2420       error ("undefined or invalid # directive");
2421       goto skipline;
2422     }
2423
2424 linenum:
2425   /* Here we have either `#line' or `# <nonletter>'.
2426      In either case, it should be a line number; a digit should follow.  */
2427
2428   while (c == ' ' || c == '\t')
2429     c = getch ();
2430
2431   /* If the # is the only nonwhite char on the line,
2432      just ignore it.  Check the new newline.  */
2433   if (c == EOF)
2434     goto skipline;
2435
2436   /* Something follows the #; read a token.  */
2437
2438   put_back (c);
2439   token = real_yylex ();
2440
2441   if (token == CONSTANT
2442       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2443     {
2444       int old_lineno = lineno;
2445       enum { act_none, act_push, act_pop } action = act_none;
2446       int entering_system_header = 0;
2447       int entering_c_header = 0;
2448
2449       /* subtract one, because it is the following line that
2450          gets the specified number */
2451
2452       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2453       c = get_last_nonwhite_on_line ();
2454       if (c == EOF)
2455         {
2456           /* No more: store the line number and check following line.  */
2457           lineno = l;
2458           goto skipline;
2459         }
2460       put_back (c);
2461
2462       /* More follows: it must be a string constant (filename).  */
2463
2464       /* Read the string constant, but don't treat \ as special.  */
2465       ignore_escape_flag = 1;
2466       token = real_yylex ();
2467       ignore_escape_flag = 0;
2468
2469       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2470         {
2471           error ("invalid #line");
2472           goto skipline;
2473         }
2474
2475       /* Changing files again.  This means currently collected time
2476          is charged against header time, and body time starts back
2477          at 0.  */
2478       if (flag_detailed_statistics)
2479         {
2480           int this_time = my_get_run_time ();
2481           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2482           header_time += this_time - body_time;
2483           TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
2484             += this_time - body_time;
2485           this_filename_time = time_identifier;
2486           body_time = this_time;
2487         }
2488
2489       input_filename
2490         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2491       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2492       lineno = l;
2493       GNU_xref_file (input_filename);
2494       
2495       if (main_input_filename == 0)
2496         {
2497           struct impl_files *ifiles = impl_file_chain;
2498
2499           if (ifiles)
2500             {
2501               while (ifiles->next)
2502                 ifiles = ifiles->next;
2503               ifiles->filename = file_name_nondirectory (input_filename);
2504             }
2505
2506           main_input_filename = input_filename;
2507           if (write_virtuals == 3)
2508             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2509         }
2510
2511       extract_interface_info ();
2512
2513       c = get_last_nonwhite_on_line ();
2514       if (c == EOF)
2515         {
2516           /* Update the name in the top element of input_file_stack.  */
2517           if (input_file_stack)
2518             input_file_stack->name = input_filename;
2519         }
2520       else
2521         {
2522           put_back (c);
2523
2524           token = real_yylex ();
2525
2526           /* `1' after file name means entering new file.
2527              `2' after file name means just left a file.  */
2528
2529           if (token == CONSTANT
2530               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2531             {
2532               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2533                 action = act_push;
2534               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2535                 action = act_pop;
2536
2537               if (action)
2538                 {
2539                   c = get_last_nonwhite_on_line ();
2540                   if (c != EOF)
2541                     {
2542                       put_back (c);
2543                       token = real_yylex ();
2544                     }
2545                 }
2546             }
2547
2548           /* `3' after file name means this is a system header file.  */
2549
2550           if (token == CONSTANT
2551               && TREE_CODE (yylval.ttype) == INTEGER_CST
2552               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2553             {
2554               entering_system_header = 1;
2555
2556               c = get_last_nonwhite_on_line ();
2557               if (c != EOF)
2558                 {
2559                   put_back (c);
2560                   token = real_yylex ();
2561                 }
2562             }
2563
2564           /* `4' after file name means this is a C header file.  */
2565
2566           if (token == CONSTANT
2567               && TREE_CODE (yylval.ttype) == INTEGER_CST
2568               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2569             {
2570               entering_c_header = 1;
2571
2572               c = get_last_nonwhite_on_line ();
2573               if (c != EOF)
2574                 {
2575                   put_back (c);
2576                   token = real_yylex ();
2577                 }
2578             }
2579
2580           /* Do the actions implied by the preceding numbers.  */
2581
2582           if (action == act_push)
2583             {
2584               /* Pushing to a new file.  */
2585               struct file_stack *p;
2586
2587               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2588               input_file_stack->line = old_lineno;
2589               p->next = input_file_stack;
2590               p->name = input_filename;
2591               input_file_stack = p;
2592               input_file_stack_tick++;
2593               debug_start_source_file (input_filename);
2594               in_system_header = entering_system_header;
2595               if (c_header_level)
2596                 ++c_header_level;
2597               else if (entering_c_header)
2598                 {
2599                   c_header_level = 1;
2600                   ++pending_lang_change;
2601                 }
2602             }
2603           else if (action == act_pop)
2604             {
2605               /* Popping out of a file.  */
2606               if (input_file_stack->next)
2607                 {
2608                   struct file_stack *p;
2609
2610                   if (c_header_level && --c_header_level == 0)
2611                     {
2612                       if (entering_c_header)
2613                         warning ("badly nested C headers from preprocessor");
2614                       --pending_lang_change;
2615                     }
2616                   in_system_header = entering_system_header;
2617
2618                   p = input_file_stack;
2619                   input_file_stack = p->next;
2620                   free (p);
2621                   input_file_stack_tick++;
2622                   debug_end_source_file (input_file_stack->line);
2623                 }
2624               else
2625                 error ("#-lines for entering and leaving files don't match");
2626             }
2627           else
2628             in_system_header = entering_system_header;
2629         }
2630
2631       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2632       if (nextchar == EOF)
2633         c = EOF;
2634     }
2635   else
2636     error ("invalid #-line");
2637
2638   /* skip the rest of this line.  */
2639  skipline:
2640   linemode = 0;
2641   end_of_file = 0;
2642   nextchar = -1;
2643   while ((c = getch ()) != EOF && c != '\n');
2644   return c;
2645 }
2646
2647 void
2648 do_pending_lang_change ()
2649 {
2650   for (; pending_lang_change > 0; --pending_lang_change)
2651     push_lang_context (lang_name_c);
2652   for (; pending_lang_change < 0; ++pending_lang_change)
2653     pop_lang_context ();
2654 }
2655 \f
2656 #define ENDFILE -1  /* token that represents end-of-file */
2657
2658 /* Read an escape sequence, returning its equivalent as a character,
2659    or store 1 in *ignore_ptr if it is backslash-newline.  */
2660
2661 static int
2662 readescape (ignore_ptr)
2663      int *ignore_ptr;
2664 {
2665   register int c = getch ();
2666   register int code;
2667   register unsigned count;
2668   unsigned firstdig = 0;
2669   int nonnull;
2670
2671   switch (c)
2672     {
2673     case 'x':
2674       code = 0;
2675       count = 0;
2676       nonnull = 0;
2677       while (1)
2678         {
2679           c = getch ();
2680           if (! ISXDIGIT (c))
2681             {
2682               put_back (c);
2683               break;
2684             }
2685           code *= 16;
2686           if (c >= 'a' && c <= 'f')
2687             code += c - 'a' + 10;
2688           if (c >= 'A' && c <= 'F')
2689             code += c - 'A' + 10;
2690           if (c >= '0' && c <= '9')
2691             code += c - '0';
2692           if (code != 0 || count != 0)
2693             {
2694               if (count == 0)
2695                 firstdig = code;
2696               count++;
2697             }
2698           nonnull = 1;
2699         }
2700       if (! nonnull)
2701         error ("\\x used with no following hex digits");
2702       else if (count == 0)
2703         /* Digits are all 0's.  Ok.  */
2704         ;
2705       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2706                || (count > 1
2707                    && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2708                        <= firstdig)))
2709         pedwarn ("hex escape out of range");
2710       return code;
2711
2712     case '0':  case '1':  case '2':  case '3':  case '4':
2713     case '5':  case '6':  case '7':
2714       code = 0;
2715       count = 0;
2716       while ((c <= '7') && (c >= '0') && (count++ < 3))
2717         {
2718           code = (code * 8) + (c - '0');
2719           c = getch ();
2720         }
2721       put_back (c);
2722       return code;
2723
2724     case '\\': case '\'': case '"':
2725       return c;
2726
2727     case '\n':
2728       lineno++;
2729       *ignore_ptr = 1;
2730       return 0;
2731
2732     case 'n':
2733       return TARGET_NEWLINE;
2734
2735     case 't':
2736       return TARGET_TAB;
2737
2738     case 'r':
2739       return TARGET_CR;
2740
2741     case 'f':
2742       return TARGET_FF;
2743
2744     case 'b':
2745       return TARGET_BS;
2746
2747     case 'a':
2748       return TARGET_BELL;
2749
2750     case 'v':
2751       return TARGET_VT;
2752
2753     case 'e':
2754     case 'E':
2755       if (pedantic)
2756         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
2757       return 033;
2758
2759     case '?':
2760       return c;
2761
2762       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
2763     case '(':
2764     case '{':
2765     case '[':
2766       /* `\%' is used to prevent SCCS from getting confused.  */
2767     case '%':
2768       if (pedantic)
2769         pedwarn ("unknown escape sequence `\\%c'", c);
2770       return c;
2771     }
2772   if (c >= 040 && c < 0177)
2773     pedwarn ("unknown escape sequence `\\%c'", c);
2774   else
2775     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2776   return c;
2777 }
2778
2779 /* Value is 1 (or 2) if we should try to make the next identifier look like
2780    a typename (when it may be a local variable or a class variable).
2781    Value is 0 if we treat this name in a default fashion.  */
2782 int looking_for_typename;
2783
2784 #ifdef __GNUC__
2785 __inline
2786 #endif
2787 int
2788 identifier_type (decl)
2789      tree decl;
2790 {
2791   tree t;
2792   if (TREE_CODE (decl) == TEMPLATE_DECL)
2793     {
2794       if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
2795         return PTYPENAME;
2796       else if (looking_for_template) 
2797         return PFUNCNAME;
2798     }
2799   if (looking_for_template && really_overloaded_fn (decl))
2800     {
2801       for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
2802         if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) 
2803           return PFUNCNAME;
2804     }
2805   if (TREE_CODE (decl) == NAMESPACE_DECL)
2806     return NSNAME;
2807   if (TREE_CODE (decl) != TYPE_DECL)
2808     return IDENTIFIER;
2809   if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
2810     return SELFNAME;
2811
2812   /* A constructor declarator for a template type will get here as an
2813      implicit typename, a TYPENAME_TYPE with a type.  */
2814   t = got_scope;
2815   if (t && TREE_CODE (t) == TYPENAME_TYPE)
2816     t = TREE_TYPE (t);
2817   decl = TREE_TYPE (decl);
2818   if (TREE_CODE (decl) == TYPENAME_TYPE)
2819     decl = TREE_TYPE (decl);
2820   if (t && t == decl)
2821     return SELFNAME;
2822
2823   return TYPENAME;
2824 }
2825
2826 void
2827 see_typename ()
2828 {
2829   /* Only types expected, not even namespaces. */
2830   looking_for_typename = 2;
2831   if (yychar < 0)
2832     if ((yychar = yylex ()) < 0) yychar = 0;
2833   looking_for_typename = 0;
2834   if (yychar == IDENTIFIER)
2835     {
2836       lastiddecl = lookup_name (yylval.ttype, -2);
2837       if (lastiddecl == 0)
2838         {
2839           if (flag_labels_ok)
2840             lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2841         }
2842       else
2843         yychar = identifier_type (lastiddecl);
2844     }
2845 }
2846
2847 /* Return true if d is in a global scope. */
2848
2849 static int
2850 is_global (d)
2851   tree d;
2852 {
2853   while (1)
2854     switch (TREE_CODE (d))
2855       {
2856       case OVERLOAD: d = OVL_FUNCTION (d); continue;
2857       case TREE_LIST: d = TREE_VALUE (d); continue;
2858       default:
2859         my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629);
2860         d = CP_DECL_CONTEXT (d);
2861         return TREE_CODE (d) == NAMESPACE_DECL;
2862       }
2863 }
2864
2865 tree
2866 do_identifier (token, parsing, args)
2867      register tree token;
2868      int parsing;
2869      tree args;
2870 {
2871   register tree id;
2872   int lexing = (parsing == 1);
2873   int in_call = (parsing == 2);
2874
2875   if (! lexing || IDENTIFIER_OPNAME_P (token))
2876     id = lookup_name (token, 0);
2877   else
2878     id = lastiddecl;
2879
2880   /* Scope class declarations before global
2881      declarations.  */
2882   if ((!id || is_global (id))
2883       && current_class_type != 0
2884       && TYPE_SIZE (current_class_type) == 0)
2885     {
2886       /* Could be from one of the base classes.  */
2887       tree field = lookup_field (current_class_type, token, 1, 0);
2888       if (field == 0)
2889         ;
2890       else if (field == error_mark_node)
2891         /* We have already generated the error message.
2892            But we still want to return this value.  */
2893         id = lookup_field (current_class_type, token, 0, 0);
2894       else if (TREE_CODE (field) == VAR_DECL
2895                || TREE_CODE (field) == CONST_DECL
2896                || TREE_CODE (field) == TEMPLATE_DECL)
2897         id = field;
2898       else if (TREE_CODE (field) != FIELD_DECL)
2899         my_friendly_abort (61);
2900       else
2901         {
2902           cp_error ("invalid use of member `%D' from base class `%T'", field,
2903                       DECL_FIELD_CONTEXT (field));
2904           id = error_mark_node;
2905           return id;
2906         }
2907     }
2908
2909   /* Do Koenig lookup if appropriate (inside templates we build lookup
2910      expressions instead).  */
2911   if (args && !current_template_parms && (!id || is_global (id)))
2912     {
2913       /* If we have arguments and we only found global names,
2914          do Koenig lookup. */
2915       id = lookup_arg_dependent (token, id, args);
2916     }
2917
2918   /* Remember that this name has been used in the class definition, as per
2919      [class.scope0] */
2920   if (id && current_class_type && parsing
2921       && TYPE_BEING_DEFINED (current_class_type)
2922       && ! IDENTIFIER_CLASS_VALUE (token)
2923       /* Avoid breaking if we get called for a default argument that
2924          refers to an overloaded method.  Eventually this will not be
2925          necessary, since default arguments shouldn't be parsed until
2926          after the class is complete.  (jason 3/12/97) */
2927       && TREE_CODE (id) != OVERLOAD)
2928     pushdecl_class_level (id);
2929     
2930   if (!id || id == error_mark_node)
2931     {
2932       if (id == error_mark_node && current_class_type != NULL_TREE)
2933         {
2934           id = lookup_nested_field (token, 1);
2935           /* In lookup_nested_field(), we marked this so we can gracefully
2936              leave this whole mess.  */
2937           if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
2938             return id;
2939         }
2940
2941       if (current_template_parms)
2942         return build_min_nt (LOOKUP_EXPR, token);
2943       else if (IDENTIFIER_OPNAME_P (token))
2944         {
2945           if (token != ansi_opname[ERROR_MARK])
2946             cp_error ("`%D' not defined", token);
2947           id = error_mark_node;
2948         }
2949       else if (in_call && ! flag_strict_prototype)
2950         {
2951           id = implicitly_declare (token);
2952         }
2953       else if (current_function_decl == 0)
2954         {
2955           cp_error ("`%D' was not declared in this scope", token);
2956           id = error_mark_node;
2957         }
2958       else
2959         {
2960           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
2961               || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2962             {
2963               static int undeclared_variable_notice;
2964
2965               cp_error ("`%D' undeclared (first use this function)", token);
2966
2967               if (! undeclared_variable_notice)
2968                 {
2969                   error ("(Each undeclared identifier is reported only once");
2970                   error ("for each function it appears in.)");
2971                   undeclared_variable_notice = 1;
2972                 }
2973             }
2974           id = error_mark_node;
2975           /* Prevent repeated error messages.  */
2976           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
2977           SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
2978         }
2979     }
2980
2981   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
2982     {
2983       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
2984       while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
2985              && DECL_DEAD_FOR_LOCAL (shadowed))
2986         shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
2987       if (!shadowed)
2988         shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
2989       if (shadowed)
2990         {
2991           if (!DECL_ERROR_REPORTED (id))
2992             {
2993               warning ("name lookup of `%s' changed",
2994                        IDENTIFIER_POINTER (token));
2995               cp_warning_at ("  matches this `%D' under current ANSI rules",
2996                              shadowed);
2997               cp_warning_at ("  matches this `%D' under old rules", id);
2998               DECL_ERROR_REPORTED (id) = 1;
2999             }
3000           id = shadowed;
3001         }
3002       else if (!DECL_ERROR_REPORTED (id))
3003         {
3004           static char msg[]
3005             = "name lookup of `%s' changed for new ANSI `for' scoping";
3006           DECL_ERROR_REPORTED (id) = 1;
3007           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
3008             {
3009               error (msg, IDENTIFIER_POINTER (token));
3010               cp_error_at ("  cannot use obsolete binding at `%D' because it has a destructor", id);
3011               id = error_mark_node;
3012             }
3013           else
3014             {
3015               pedwarn (msg, IDENTIFIER_POINTER (token));
3016               cp_pedwarn_at ("  using obsolete binding at `%D'", id);
3017             }
3018         }
3019     }
3020   /* TREE_USED is set in `hack_identifier'.  */
3021   if (TREE_CODE (id) == CONST_DECL)
3022     {
3023       if (IDENTIFIER_CLASS_VALUE (token) == id)
3024         {
3025           /* Check access.  */
3026           tree access = compute_access (TYPE_BINFO (current_class_type), id);
3027           if (access == access_private_node)
3028             cp_error ("enum `%D' is private", id);
3029           /* protected is OK, since it's an enum of `this'.  */
3030         }
3031       if (!processing_template_decl
3032           /* Really, if we're processing a template, we just want to
3033              resolve template parameters, and not enumeration
3034              constants.  But, they're hard to tell apart.  (Note that
3035              a non-type template parameter may have enumeration type.)
3036              Fortunately, there's no harm in resolving *global*
3037              enumeration constants, since they can't depend on
3038              template parameters.  */
3039           || (TREE_CODE (CP_DECL_CONTEXT (id)) == NAMESPACE_DECL
3040               && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX))
3041         id = DECL_INITIAL (id);
3042     }
3043   else
3044     id = hack_identifier (id, token);
3045
3046   /* We must look up dependent names when the template is
3047      instantiated, not while parsing it.  For now, we don't
3048      distinguish between dependent and independent names.  So, for
3049      example, we look up all overloaded functions at
3050      instantiation-time, even though in some cases we should just use
3051      the DECL we have here.  We also use LOOKUP_EXPRs to find things
3052      like local variables, rather than creating TEMPLATE_DECLs for the
3053      local variables and then finding matching instantiations.  */
3054   if (current_template_parms
3055       && (is_overloaded_fn (id) 
3056           /* If it's not going to be around at instantiation time, we
3057              look it up then.  This is a hack, and should go when we
3058              really get dependent/independent name lookup right.  */
3059           || !TREE_PERMANENT (id)
3060           /* Some local VAR_DECLs (such as those for local variables
3061              in member functions of local classes) are built on the
3062              permanent obstack.  */
3063           || (TREE_CODE (id) == VAR_DECL 
3064               && CP_DECL_CONTEXT (id)
3065               && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
3066           || TREE_CODE (id) == PARM_DECL
3067           || TREE_CODE (id) == USING_DECL))
3068     id = build_min_nt (LOOKUP_EXPR, token);
3069       
3070   return id;
3071 }
3072
3073 tree
3074 do_scoped_id (token, parsing)
3075      tree token;
3076      int parsing;
3077 {
3078   tree id;
3079   /* during parsing, this is ::name. Otherwise, it is black magic. */
3080   if (parsing)
3081     {
3082       struct tree_binding _b;
3083       id = binding_init (&_b);
3084       if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
3085         id = NULL_TREE;
3086       else
3087         id = BINDING_VALUE (id);
3088     } 
3089   else
3090     id = IDENTIFIER_GLOBAL_VALUE (token);
3091   if (parsing && yychar == YYEMPTY)
3092     yychar = yylex ();
3093   if (! id)
3094     {
3095       if (processing_template_decl)
3096         {
3097           id = build_min_nt (LOOKUP_EXPR, token);
3098           LOOKUP_EXPR_GLOBAL (id) = 1;
3099           return id;
3100         }
3101       if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
3102           && ! flag_strict_prototype)
3103         id = implicitly_declare (token);
3104       else
3105         {
3106           if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
3107             cp_error ("`::%D' undeclared (first use here)", token);
3108           id = error_mark_node;
3109           /* Prevent repeated error messages.  */
3110           SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
3111         }
3112     }
3113   else
3114     {
3115       if (TREE_CODE (id) == ADDR_EXPR)
3116         mark_used (TREE_OPERAND (id, 0));
3117       else if (TREE_CODE (id) != OVERLOAD)
3118         mark_used (id);
3119     }
3120   if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
3121     {
3122       /* XXX CHS - should we set TREE_USED of the constant? */
3123       id = DECL_INITIAL (id);
3124       /* This is to prevent an enum whose value is 0
3125          from being considered a null pointer constant.  */
3126       id = build1 (NOP_EXPR, TREE_TYPE (id), id);
3127       TREE_CONSTANT (id) = 1;
3128     }
3129
3130   if (processing_template_decl)
3131     {
3132       if (is_overloaded_fn (id))
3133         {
3134           id = build_min_nt (LOOKUP_EXPR, token);
3135           LOOKUP_EXPR_GLOBAL (id) = 1;
3136           return id;
3137         }
3138       /* else just use the decl */
3139     }
3140   return convert_from_reference (id);
3141 }
3142
3143 tree
3144 identifier_typedecl_value (node)
3145      tree node;
3146 {
3147   tree t, type;
3148   type = IDENTIFIER_TYPE_VALUE (node);
3149   if (type == NULL_TREE)
3150     return NULL_TREE;
3151 #define do(X) \
3152   { \
3153     t = (X); \
3154     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
3155       return t; \
3156   }
3157   do (IDENTIFIER_LOCAL_VALUE (node));
3158   do (IDENTIFIER_CLASS_VALUE (node));
3159   do (IDENTIFIER_NAMESPACE_VALUE (node));
3160 #undef do
3161   /* Will this one ever happen?  */
3162   if (TYPE_MAIN_DECL (type))
3163     return TYPE_MAIN_DECL (type);
3164
3165   /* We used to do an internal error of 62 here, but instead we will
3166      handle the return of a null appropriately in the callers.  */
3167   return NULL_TREE;
3168 }
3169
3170 int
3171 real_yylex ()
3172 {
3173   register int c;
3174   register int value;
3175   int wide_flag = 0;
3176   int dollar_seen = 0;
3177   int i;
3178
3179   if (nextchar >= 0)
3180     c = nextchar, nextchar = -1;
3181   else
3182     c = getch ();
3183
3184   /* Effectively do c = skip_white_space (c)
3185      but do it faster in the usual cases.  */
3186   while (1)
3187     switch (c)
3188       {
3189       case ' ':
3190       case '\t':
3191       case '\f':
3192       case '\v':
3193       case '\b':
3194         c = getch ();
3195         break;
3196
3197       case '\r':
3198         /* Call skip_white_space so we can warn if appropriate.  */
3199
3200       case '\n':
3201       case '/':
3202       case '\\':
3203         c = skip_white_space (c);
3204       default:
3205         goto found_nonwhite;
3206       }
3207  found_nonwhite:
3208
3209   token_buffer[0] = c;
3210   token_buffer[1] = 0;
3211
3212 /*  yylloc.first_line = lineno; */
3213
3214   switch (c)
3215     {
3216     case EOF:
3217       token_buffer[0] = '\0';
3218       end_of_file = 1;
3219       if (input_redirected ())
3220         value = END_OF_SAVED_INPUT;
3221       else if (linemode)
3222         value = END_OF_LINE;
3223       else
3224         value = ENDFILE;
3225       break;
3226
3227     case '$':
3228       if (! dollars_in_ident)
3229         error ("`$' in identifier");
3230       else if (pedantic)
3231         pedwarn ("`$' in identifier");
3232       dollar_seen = 1;
3233       goto letter;
3234
3235     case 'L':
3236       /* Capital L may start a wide-string or wide-character constant.  */
3237       {
3238         register int c = getch ();
3239         if (c == '\'')
3240           {
3241             wide_flag = 1;
3242             goto char_constant;
3243           }
3244         if (c == '"')
3245           {
3246             wide_flag = 1;
3247             goto string_constant;
3248           }
3249         put_back (c);
3250       }
3251
3252     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
3253     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
3254     case 'K':             case 'M':  case 'N':  case 'O':
3255     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
3256     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
3257     case 'Z':
3258     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
3259     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
3260     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
3261     case 'p':  case 'q':  case 'r':  case 's':  case 't':
3262     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
3263     case 'z':
3264     case '_':
3265     letter:
3266       {
3267         register char *p;
3268
3269         p = token_buffer;
3270         if (input == 0)
3271           {
3272             /* We know that `token_buffer' can hold at least on char,
3273                so we install C immediately.
3274                We may have to read the value in `putback_char', so call
3275                `getch' once.  */
3276             *p++ = c;
3277             c = getch ();
3278
3279             /* Make this run fast.  We know that we are reading straight
3280                from FINPUT in this case (since identifiers cannot straddle
3281                input sources.  */
3282             while (ISALNUM (c) || (c == '_') || c == '$')
3283               {
3284                 if (c == '$')
3285                   {
3286                     if (! dollars_in_ident)
3287                       error ("`$' in identifier");
3288                     else if (pedantic)
3289                       pedwarn ("`$' in identifier");
3290                   }
3291
3292                 if (p >= token_buffer + maxtoken)
3293                   p = extend_token_buffer (p);
3294
3295                 *p++ = c;
3296                 c = getch ();
3297               }
3298
3299             if (linemode && c == '\n')
3300               {
3301                 put_back (c);
3302                 c = EOF;
3303               }
3304           }
3305         else
3306           {
3307             /* We know that `token_buffer' can hold at least on char,
3308                so we install C immediately.  */
3309             *p++ = c;
3310             c = getch ();
3311
3312             while (ISALNUM (c) || (c == '_') || c == '$')
3313               {
3314                 if (c == '$')
3315                   {
3316                     if (! dollars_in_ident)
3317                       error ("`$' in identifier");
3318                     else if (pedantic)
3319                       pedwarn ("`$' in identifier");
3320                   }
3321
3322                 if (p >= token_buffer + maxtoken)
3323                   p = extend_token_buffer (p);
3324
3325                 *p++ = c;
3326                 c = getch ();
3327               }
3328           }
3329
3330         *p = 0;
3331         nextchar = c;
3332
3333         value = IDENTIFIER;
3334         yylval.itype = 0;
3335
3336       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
3337
3338         {
3339           register struct resword *ptr;
3340
3341           if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
3342             {
3343               if (ptr->rid)
3344                 {
3345                   tree old_ttype = ridpointers[(int) ptr->rid];
3346
3347                   /* If this provides a type for us, then revert lexical
3348                      state to standard state.  */
3349                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
3350                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
3351                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
3352                     looking_for_typename = 0;
3353                   else if (ptr->token == AGGR || ptr->token == ENUM)
3354                     looking_for_typename = 2;
3355
3356                   /* Check if this is a language-type declaration.
3357                      Just glimpse the next non-white character.  */
3358                   nextchar = skip_white_space (nextchar);
3359                   if (nextchar == '"')
3360                     {
3361                       /* We are looking at a string.  Complain
3362                          if the token before the string is no `extern'.
3363                          
3364                          Could cheat some memory by placing this string
3365                          on the temporary_, instead of the saveable_
3366                          obstack.  */
3367
3368                       if (ptr->rid != RID_EXTERN)
3369                         error ("invalid modifier `%s' for language string",
3370                                ptr->name);
3371                       real_yylex ();
3372                       value = EXTERN_LANG_STRING;
3373                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
3374                       break;
3375                     }
3376                   if (ptr->token == VISSPEC)
3377                     {
3378                       switch (ptr->rid)
3379                         {
3380                         case RID_PUBLIC:
3381                           yylval.ttype = access_public_node;
3382                           break;
3383                         case RID_PRIVATE:
3384                           yylval.ttype = access_private_node;
3385                           break;
3386                         case RID_PROTECTED:
3387                           yylval.ttype = access_protected_node;
3388                           break;
3389                         default:
3390                           my_friendly_abort (63);
3391                         }
3392                     }
3393                   else
3394                     yylval.ttype = old_ttype;
3395                 }
3396               else if (ptr->token == EQCOMPARE)
3397                 {
3398                   yylval.code = NE_EXPR;
3399                   token_buffer[0] = '!';
3400                   token_buffer[1] = '=';
3401                   token_buffer[2] = 0;
3402                 }
3403               else if (ptr->token == ASSIGN)
3404                 {
3405                   if (strcmp ("and_eq", token_buffer) == 0)
3406                     {
3407                       yylval.code = BIT_AND_EXPR;
3408                       token_buffer[0] = '&';
3409                     }
3410                   else if (strcmp ("or_eq", token_buffer) == 0)
3411                     {
3412                       yylval.code = BIT_IOR_EXPR;
3413                       token_buffer[0] = '|';
3414                     }
3415                   else if (strcmp ("xor_eq", token_buffer) == 0)
3416                     {
3417                       yylval.code = BIT_XOR_EXPR;
3418                       token_buffer[0] = '^';
3419                     }
3420                   token_buffer[1] = '=';
3421                   token_buffer[2] = 0;
3422                 }
3423               else if (ptr->token == '&')
3424                 {
3425                   yylval.code = BIT_AND_EXPR;
3426                   token_buffer[0] = '&';
3427                   token_buffer[1] = 0;
3428                 }
3429               else if (ptr->token == '|')
3430                 {
3431                   yylval.code = BIT_IOR_EXPR;
3432                   token_buffer[0] = '|';
3433                   token_buffer[1] = 0;
3434                 }
3435               else if (ptr->token == '^')
3436                 {
3437                   yylval.code = BIT_XOR_EXPR;
3438                   token_buffer[0] = '^';
3439                   token_buffer[1] = 0;
3440                 }
3441
3442               value = (int) ptr->token;
3443             }
3444         }
3445
3446         /* If we did not find a keyword, look for an identifier
3447            (or a typename).  */
3448
3449         if (value == IDENTIFIER || value == TYPESPEC)
3450           GNU_xref_ref (current_function_decl, token_buffer);
3451
3452         if (value == IDENTIFIER)
3453           {
3454             register tree tmp = get_identifier (token_buffer);
3455
3456 #if !defined(VMS) && defined(JOINER)
3457             /* Make sure that user does not collide with our internal
3458                naming scheme.  */
3459             if (JOINER == '$'
3460                 && dollar_seen
3461                 && (THIS_NAME_P (tmp)
3462                     || VPTR_NAME_P (tmp)
3463                     || DESTRUCTOR_NAME_P (tmp)
3464                     || VTABLE_NAME_P (tmp)
3465                     || TEMP_NAME_P (tmp)
3466                     || ANON_AGGRNAME_P (tmp)
3467                     || ANON_PARMNAME_P (tmp)))
3468               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3469                        token_buffer);
3470 #endif
3471
3472             yylval.ttype = tmp;
3473           }
3474         if (value == NEW && ! global_bindings_p ())
3475           {
3476             value = NEW;
3477             goto done;
3478           }
3479       }
3480       break;
3481
3482     case '.':
3483       {
3484         register int c1 = getch ();
3485         token_buffer[0] = c;
3486         token_buffer[1] = c1;
3487         if (c1 == '*')
3488           {
3489             value = DOT_STAR;
3490             token_buffer[2] = 0;
3491             goto done;
3492           }
3493         if (c1 == '.')
3494           {
3495             c1 = getch ();
3496             if (c1 == '.')
3497               {
3498                 token_buffer[2] = c1;
3499                 token_buffer[3] = 0;
3500                 value = ELLIPSIS;
3501                 goto done;
3502               }
3503             error ("parse error at `..'");
3504           }
3505         if (ISDIGIT (c1))
3506           {
3507             put_back (c1);
3508             goto resume_numerical_scan;
3509           }
3510         nextchar = c1;
3511         value = '.';
3512         token_buffer[1] = 0;
3513         goto done;
3514       }
3515     case '0':  case '1':
3516         /* Optimize for most frequent case.  */
3517       {
3518         register int c1 = getch ();
3519         if (! ISALNUM (c1) && c1 != '.')
3520           {
3521             /* Terminate string.  */
3522             token_buffer[0] = c;
3523             token_buffer[1] = 0;
3524             if (c == '0')
3525               yylval.ttype = integer_zero_node;
3526             else
3527               yylval.ttype = integer_one_node;
3528             nextchar = c1;
3529             value = CONSTANT;
3530             goto done;
3531           }
3532         put_back (c1);
3533       }
3534       /* fall through...  */
3535                           case '2':  case '3':  case '4':
3536     case '5':  case '6':  case '7':  case '8':  case '9':
3537     resume_numerical_scan:
3538       {
3539         register char *p;
3540         int base = 10;
3541         int count = 0;
3542         int largest_digit = 0;
3543         int numdigits = 0;
3544         /* for multi-precision arithmetic,
3545            we actually store only HOST_BITS_PER_CHAR bits in each part.
3546            The number of parts is chosen so as to be sufficient to hold
3547            the enough bits to fit into the two HOST_WIDE_INTs that contain
3548            the integer value (this is always at least as many bits as are
3549            in a target `long long' value, but may be wider).  */
3550 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3551         int parts[TOTAL_PARTS];
3552         int overflow = 0;
3553
3554         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3555           = NOT_FLOAT;
3556
3557         for (count = 0; count < TOTAL_PARTS; count++)
3558           parts[count] = 0;
3559
3560         p = token_buffer;
3561         *p++ = c;
3562
3563         if (c == '0')
3564           {
3565             *p++ = (c = getch ());
3566             if ((c == 'x') || (c == 'X'))
3567               {
3568                 base = 16;
3569                 *p++ = (c = getch ());
3570               }
3571             /* Leading 0 forces octal unless the 0 is the only digit.  */
3572             else if (c >= '0' && c <= '9')
3573               {
3574                 base = 8;
3575                 numdigits++;
3576               }
3577             else
3578               numdigits++;
3579           }
3580
3581         /* Read all the digits-and-decimal-points.  */
3582
3583         while (c == '.'
3584                || (ISALNUM (c) && (c != 'l') && (c != 'L')
3585                    && (c != 'u') && (c != 'U')
3586                    && c != 'i' && c != 'I' && c != 'j' && c != 'J'
3587                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3588           {
3589             if (c == '.')
3590               {
3591                 if (base == 16)
3592                   error ("floating constant may not be in radix 16");
3593                 if (floatflag == TOO_MANY_POINTS)
3594                   /* We have already emitted an error.  Don't need another.  */
3595                   ;
3596                 else if (floatflag == AFTER_POINT)
3597                   {
3598                     error ("malformed floating constant");
3599                     floatflag = TOO_MANY_POINTS;
3600                     /* Avoid another error from atof by forcing all characters
3601                        from here on to be ignored.  */
3602                     p[-1] = '\0';
3603                   }
3604                 else
3605                   floatflag = AFTER_POINT;
3606
3607                 base = 10;
3608                 *p++ = c = getch ();
3609                 /* Accept '.' as the start of a floating-point number
3610                    only when it is followed by a digit.
3611                    Otherwise, unread the following non-digit
3612                    and use the '.' as a structural token.  */
3613                 if (p == token_buffer + 2 && !ISDIGIT (c))
3614                   {
3615                     if (c == '.')
3616                       {
3617                         c = getch ();
3618                         if (c == '.')
3619                           {
3620                             *p++ = '.';
3621                             *p = '\0';
3622                             value = ELLIPSIS;
3623                             goto done;
3624                           }
3625                         error ("parse error at `..'");
3626                       }
3627                     nextchar = c;
3628                     token_buffer[1] = '\0';
3629                     value = '.';
3630                     goto done;
3631                   }
3632               }
3633             else
3634               {
3635                 /* It is not a decimal point.
3636                    It should be a digit (perhaps a hex digit).  */
3637
3638                 if (ISDIGIT (c))
3639                   {
3640                     c = c - '0';
3641                   }
3642                 else if (base <= 10)
3643                   {
3644                     if (c == 'e' || c == 'E')
3645                       {
3646                         base = 10;
3647                         floatflag = AFTER_POINT;
3648                         break;   /* start of exponent */
3649                       }
3650                     error ("nondigits in number and not hexadecimal");
3651                     c = 0;
3652                   }
3653                 else if (c >= 'a')
3654                   {
3655                     c = c - 'a' + 10;
3656                   }
3657                 else
3658                   {
3659                     c = c - 'A' + 10;
3660                   }
3661                 if (c >= largest_digit)
3662                   largest_digit = c;
3663                 numdigits++;
3664
3665                 for (count = 0; count < TOTAL_PARTS; count++)
3666                   {
3667                     parts[count] *= base;
3668                     if (count)
3669                       {
3670                         parts[count]
3671                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3672                         parts[count-1]
3673                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3674                       }
3675                     else
3676                       parts[0] += c;
3677                   }
3678
3679                 /* If the extra highest-order part ever gets anything in it,
3680                    the number is certainly too big.  */
3681                 if (parts[TOTAL_PARTS - 1] != 0)
3682                   overflow = 1;
3683
3684                 if (p >= token_buffer + maxtoken - 3)
3685                   p = extend_token_buffer (p);
3686                 *p++ = (c = getch ());
3687               }
3688           }
3689
3690         if (numdigits == 0)
3691           error ("numeric constant with no digits");
3692
3693         if (largest_digit >= base)
3694           error ("numeric constant contains digits beyond the radix");
3695
3696         /* Remove terminating char from the token buffer and delimit the string */
3697         *--p = 0;
3698
3699         if (floatflag != NOT_FLOAT)
3700           {
3701             tree type = double_type_node;
3702             int exceeds_double = 0;
3703             int imag = 0;
3704             REAL_VALUE_TYPE value;
3705             jmp_buf handler;
3706
3707             /* Read explicit exponent if any, and put it in tokenbuf.  */
3708
3709             if ((c == 'e') || (c == 'E'))
3710               {
3711                 if (p >= token_buffer + maxtoken - 3)
3712                   p = extend_token_buffer (p);
3713                 *p++ = c;
3714                 c = getch ();
3715                 if ((c == '+') || (c == '-'))
3716                   {
3717                     *p++ = c;
3718                     c = getch ();
3719                   }
3720                 if (! ISDIGIT (c))
3721                   error ("floating constant exponent has no digits");
3722                 while (ISDIGIT (c))
3723                   {
3724                     if (p >= token_buffer + maxtoken - 3)
3725                       p = extend_token_buffer (p);
3726                     *p++ = c;
3727                     c = getch ();
3728                   }
3729               }
3730
3731             *p = 0;
3732             errno = 0;
3733
3734             /* Convert string to a double, checking for overflow.  */
3735             if (setjmp (handler))
3736               {
3737                 error ("floating constant out of range");
3738                 value = dconst0;
3739               }
3740             else
3741               {
3742                 int fflag = 0, lflag = 0;
3743                 /* Copy token_buffer now, while it has just the number
3744                    and not the suffixes; once we add `f' or `i',
3745                    REAL_VALUE_ATOF may not work any more.  */
3746                 char *copy = (char *) alloca (p - token_buffer + 1);
3747                 bcopy (token_buffer, copy, p - token_buffer + 1);
3748
3749                 set_float_handler (handler);
3750
3751                 while (1)
3752                   {
3753                     int lose = 0;
3754
3755                     /* Read the suffixes to choose a data type.  */
3756                     switch (c)
3757                       {
3758                       case 'f': case 'F':
3759                         if (fflag)
3760                           error ("more than one `f' in numeric constant");
3761                         fflag = 1;
3762                         break;
3763
3764                       case 'l': case 'L':
3765                         if (lflag)
3766                           error ("more than one `l' in numeric constant");
3767                         lflag = 1;
3768                         break;
3769
3770                       case 'i': case 'I':
3771                         if (imag)
3772                           error ("more than one `i' or `j' in numeric constant");
3773                         else if (pedantic)
3774                           pedwarn ("ANSI C++ forbids imaginary numeric constants");
3775                         imag = 1;
3776                         break;
3777
3778                       default:
3779                         lose = 1;
3780                       }
3781
3782                     if (lose)
3783                       break;
3784
3785                     if (p >= token_buffer + maxtoken - 3)
3786                       p = extend_token_buffer (p);
3787                     *p++ = c;
3788                     *p = 0;
3789                     c = getch ();
3790                   }
3791
3792                 /* The second argument, machine_mode, of REAL_VALUE_ATOF
3793                    tells the desired precision of the binary result
3794                    of decimal-to-binary conversion.  */
3795
3796                 if (fflag)
3797                   {
3798                     if (lflag)
3799                       error ("both `f' and `l' in floating constant");
3800
3801                     type = float_type_node;
3802                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3803                     /* A diagnostic is required here by some ANSI C testsuites.
3804                        This is not pedwarn, become some people don't want
3805                        an error for this.  */
3806                     if (REAL_VALUE_ISINF (value) && pedantic)
3807                       warning ("floating point number exceeds range of `float'");
3808                   }
3809                 else if (lflag)
3810                   {
3811                     type = long_double_type_node;
3812                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3813                     if (REAL_VALUE_ISINF (value) && pedantic)
3814                       warning ("floating point number exceeds range of `long double'");
3815                   }
3816                 else
3817                   {
3818                     value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
3819                     if (REAL_VALUE_ISINF (value) && pedantic)
3820                       warning ("floating point number exceeds range of `double'");
3821                   }
3822
3823                 set_float_handler (NULL_PTR);
3824               }
3825 #ifdef ERANGE
3826             if (errno == ERANGE && pedantic)
3827               {
3828                 /* ERANGE is also reported for underflow,
3829                    so test the value to distinguish overflow from that.  */
3830                 if (REAL_VALUES_LESS (dconst1, value)
3831                     || REAL_VALUES_LESS (value, dconstm1))
3832                   {
3833                     pedwarn ("floating point number exceeds range of `%s'",
3834                              IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
3835                     exceeds_double = 1;
3836                   }
3837               }
3838 #endif
3839
3840             /* If the result is not a number, assume it must have been
3841                due to some error message above, so silently convert
3842                it to a zero.  */
3843             if (REAL_VALUE_ISNAN (value))
3844               value = dconst0;
3845
3846             /* Create a node with determined type and value.  */
3847             if (imag)
3848               yylval.ttype = build_complex (NULL_TREE,
3849                                             cp_convert (type, integer_zero_node),
3850                                             build_real (type, value));
3851             else
3852               yylval.ttype = build_real (type, value);
3853           }
3854         else
3855           {
3856             tree type;
3857             HOST_WIDE_INT high, low;
3858             int spec_unsigned = 0;
3859             int spec_long = 0;
3860             int spec_long_long = 0;
3861             int spec_imag = 0;
3862             int bytes, warn;
3863
3864             while (1)
3865               {
3866                 if (c == 'u' || c == 'U')
3867                   {
3868                     if (spec_unsigned)
3869                       error ("two `u's in integer constant");
3870                     spec_unsigned = 1;
3871                   }
3872                 else if (c == 'l' || c == 'L')
3873                   {
3874                     if (spec_long)
3875                       {
3876                         if (spec_long_long)
3877                           error ("three `l's in integer constant");
3878                         else if (pedantic && ! in_system_header && warn_long_long)
3879                           pedwarn ("ANSI C++ forbids long long integer constants");
3880                         spec_long_long = 1;
3881                       }
3882                     spec_long = 1;
3883                   }
3884                 else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
3885                   {
3886                     if (spec_imag)
3887                       error ("more than one `i' or `j' in numeric constant");
3888                     else if (pedantic)
3889                       pedwarn ("ANSI C++ forbids imaginary numeric constants");
3890                     spec_imag = 1;
3891                   }
3892                 else
3893                   break;
3894                 if (p >= token_buffer + maxtoken - 3)
3895                   p = extend_token_buffer (p);
3896                 *p++ = c;
3897                 c = getch ();
3898               }
3899
3900             /* If the constant is not long long and it won't fit in an
3901                unsigned long, or if the constant is long long and won't fit
3902                in an unsigned long long, then warn that the constant is out
3903                of range.  */
3904
3905             /* ??? This assumes that long long and long integer types are
3906                a multiple of 8 bits.  This better than the original code
3907                though which assumed that long was exactly 32 bits and long
3908                long was exactly 64 bits.  */
3909
3910             if (spec_long_long)
3911               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3912             else
3913               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3914
3915             warn = overflow;
3916             for (i = bytes; i < TOTAL_PARTS; i++)
3917               if (parts[i])
3918                 warn = 1;
3919             if (warn)
3920               pedwarn ("integer constant out of range");
3921
3922             /* This is simplified by the fact that our constant
3923                is always positive.  */
3924             high = low = 0;
3925
3926             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3927               {
3928                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3929                                                     / HOST_BITS_PER_CHAR)]
3930                          << (i * HOST_BITS_PER_CHAR));
3931                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3932               }
3933             
3934             
3935             yylval.ttype = build_int_2 (low, high);
3936             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3937
3938             /* Calculate the ANSI type.  */
3939             if (!spec_long && !spec_unsigned
3940                 && int_fits_type_p (yylval.ttype, integer_type_node))
3941               type = integer_type_node;
3942             else if (!spec_long && (base != 10 || spec_unsigned)
3943                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
3944               /* Nondecimal constants try unsigned even in traditional C.  */
3945               type = unsigned_type_node;
3946             else if (!spec_unsigned && !spec_long_long
3947                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
3948               type = long_integer_type_node;
3949             else if (! spec_long_long)
3950               type = long_unsigned_type_node;
3951             else if (! spec_unsigned
3952                      /* Verify value does not overflow into sign bit.  */
3953                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
3954                      && int_fits_type_p (yylval.ttype,
3955                                          long_long_integer_type_node))
3956               type = long_long_integer_type_node;
3957             else
3958               type = long_long_unsigned_type_node;
3959
3960             if (!int_fits_type_p (yylval.ttype, type) && !warn)
3961               pedwarn ("integer constant out of range");
3962
3963             if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
3964               warning ("decimal integer constant is so large that it is unsigned");
3965
3966             if (spec_imag)
3967               {
3968                 if (TYPE_PRECISION (type)
3969                     <= TYPE_PRECISION (integer_type_node))
3970                   yylval.ttype
3971                     = build_complex (NULL_TREE, integer_zero_node,
3972                                      cp_convert (integer_type_node,
3973                                                  yylval.ttype));
3974                 else
3975                   error ("complex integer constant is too wide for `__complex int'");
3976               }
3977             else
3978               TREE_TYPE (yylval.ttype) = type;
3979           }
3980
3981         put_back (c);
3982         *p = 0;
3983
3984         value = CONSTANT; break;
3985       }
3986
3987     case '\'':
3988     char_constant:
3989       {
3990         register int result = 0;
3991         register int num_chars = 0;
3992         int chars_seen = 0;
3993         unsigned width = TYPE_PRECISION (char_type_node);
3994         int max_chars;
3995 #ifdef MULTIBYTE_CHARS
3996         int longest_char = local_mb_cur_max ();
3997         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
3998 #endif
3999
4000         max_chars = TYPE_PRECISION (integer_type_node) / width;
4001         if (wide_flag)
4002           width = WCHAR_TYPE_SIZE;
4003
4004         while (1)
4005           {
4006           tryagain:
4007             c = getch ();
4008
4009             if (c == '\'' || c == EOF)
4010               break;
4011
4012             ++chars_seen;
4013             if (c == '\\')
4014               {
4015                 int ignore = 0;
4016                 c = readescape (&ignore);
4017                 if (ignore)
4018                   goto tryagain;
4019                 if (width < HOST_BITS_PER_INT
4020                     && (unsigned) c >= (1 << width))
4021                   pedwarn ("escape sequence out of range for character");
4022 #ifdef MAP_CHARACTER
4023                 if (ISPRINT (c))
4024                   c = MAP_CHARACTER (c);
4025 #endif
4026               }
4027             else if (c == '\n')
4028               {
4029                 if (pedantic)
4030                   pedwarn ("ANSI C forbids newline in character constant");
4031                 lineno++;
4032               }
4033             else
4034               {
4035 #ifdef MULTIBYTE_CHARS
4036                 wchar_t wc;
4037                 int i;
4038                 int char_len = -1;
4039                 for (i = 1; i <= longest_char; ++i)
4040                   {
4041                     if (i > maxtoken - 4)
4042                       extend_token_buffer (token_buffer);
4043
4044                     token_buffer[i] = c;
4045                     char_len = local_mbtowc (& wc,
4046                                              token_buffer + 1,
4047                                              i);
4048                     if (char_len != -1)
4049                       break;
4050                     c = getch ();
4051                   }
4052                 if (char_len > 1)
4053                   {
4054                     /* mbtowc sometimes needs an extra char before accepting */
4055                     if (char_len < i)
4056                       put_back (c);
4057                     if (! wide_flag)
4058                       {
4059                         /* Merge character into result; ignore excess chars.  */
4060                         for (i = 1; i <= char_len; ++i)
4061                           {
4062                             if (i > max_chars)
4063                               break;
4064                             if (width < HOST_BITS_PER_INT)
4065                               result = (result << width)
4066                                 | (token_buffer[i]
4067                                    & ((1 << width) - 1));
4068                             else
4069                               result = token_buffer[i];
4070                           }
4071                         num_chars += char_len;
4072                         goto tryagain;
4073                       }
4074                     c = wc;
4075                   }
4076                 else
4077                   {
4078                     if (char_len == -1)
4079                       warning ("Ignoring invalid multibyte character");
4080                     if (wide_flag)
4081                       c = wc;
4082 #ifdef MAP_CHARACTER
4083                     else
4084                       c = MAP_CHARACTER (c);
4085 #endif
4086                   }
4087 #else /* ! MULTIBYTE_CHARS */
4088 #ifdef MAP_CHARACTER
4089                 c = MAP_CHARACTER (c);
4090 #endif
4091 #endif /* ! MULTIBYTE_CHARS */
4092               }
4093
4094             if (wide_flag)
4095               {
4096                 if (chars_seen == 1) /* only keep the first one */
4097                   result = c;
4098                 goto tryagain;
4099               }
4100
4101             /* Merge character into result; ignore excess chars.  */
4102             num_chars++;
4103             if (num_chars < max_chars + 1)
4104               {
4105                 if (width < HOST_BITS_PER_INT)
4106                   result = (result << width) | (c & ((1 << width) - 1));
4107                 else
4108                   result = c;
4109               }
4110           }
4111
4112         if (c != '\'')
4113           error ("malformatted character constant");
4114         else if (chars_seen == 0)
4115           error ("empty character constant");
4116         else if (num_chars > max_chars)
4117           {
4118             num_chars = max_chars;
4119             error ("character constant too long");
4120           }
4121         else if (chars_seen != 1 && warn_multichar)
4122           warning ("multi-character character constant");
4123
4124         /* If char type is signed, sign-extend the constant.  */
4125         if (! wide_flag)
4126           {
4127             int num_bits = num_chars * width;
4128             if (num_bits == 0)
4129               /* We already got an error; avoid invalid shift.  */
4130               yylval.ttype = build_int_2 (0, 0);
4131             else if (TREE_UNSIGNED (char_type_node)
4132                      || ((result >> (num_bits - 1)) & 1) == 0)
4133               yylval.ttype
4134                 = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
4135                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4136                                0);
4137             else
4138               yylval.ttype
4139                 = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
4140                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4141                                -1);
4142             if (chars_seen <= 1)
4143               TREE_TYPE (yylval.ttype) = char_type_node;
4144             else
4145               TREE_TYPE (yylval.ttype) = integer_type_node;
4146           }
4147         else
4148           {
4149             yylval.ttype = build_int_2 (result, 0);
4150             TREE_TYPE (yylval.ttype) = wchar_type_node;
4151           }
4152
4153         value = CONSTANT;
4154         break;
4155       }
4156
4157     case '"':
4158     string_constant:
4159       {
4160         register char *p;
4161         unsigned width = wide_flag ? WCHAR_TYPE_SIZE
4162                                    : TYPE_PRECISION (char_type_node);
4163 #ifdef MULTIBYTE_CHARS
4164         int longest_char = local_mb_cur_max ();
4165         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
4166 #endif
4167
4168         c = getch ();
4169         p = token_buffer + 1;
4170
4171         while (c != '"' && c >= 0)
4172           {
4173             /* ignore_escape_flag is set for reading the filename in #line.  */
4174             if (!ignore_escape_flag && c == '\\')
4175               {
4176                 int ignore = 0;
4177                 c = readescape (&ignore);
4178                 if (ignore)
4179                   goto skipnewline;
4180                 if (width < HOST_BITS_PER_INT
4181                     && (unsigned) c >= (1 << width))
4182                   warning ("escape sequence out of range for character");
4183               }
4184             else if (c == '\n')
4185               {
4186                 if (pedantic)
4187                   pedwarn ("ANSI C++ forbids newline in string constant");
4188                 lineno++;
4189               }
4190             else
4191               {
4192 #ifdef MULTIBYTE_CHARS
4193                 wchar_t wc;
4194                 int i;
4195                 int char_len = -1;
4196                 for (i = 0; i < longest_char; ++i)
4197                   {
4198                     if (p + i >= token_buffer + maxtoken)
4199                       p = extend_token_buffer (p);
4200                     p[i] = c;
4201
4202                     char_len = local_mbtowc (& wc, p, i + 1);
4203                     if (char_len != -1)
4204                       break;
4205                     c = getch ();
4206                   }
4207                 if (char_len == -1)
4208                   warning ("Ignoring invalid multibyte character");
4209                 else
4210                   {
4211                     /* mbtowc sometimes needs an extra char before accepting */
4212                     if (char_len <= i)
4213                       put_back (c);
4214                     if (wide_flag)
4215                       {
4216                         *(wchar_t *)p = wc;
4217                         p += sizeof (wc);
4218                       }
4219                     else
4220                       p += (i + 1);
4221                     c = getch ();
4222                     continue;
4223                   }
4224 #endif /* MULTIBYTE_CHARS */
4225               }
4226
4227             /* Add this single character into the buffer either as a wchar_t
4228                or as a single byte.  */
4229             if (wide_flag)
4230               {
4231                 unsigned width = TYPE_PRECISION (char_type_node);
4232                 unsigned bytemask = (1 << width) - 1;
4233                 int byte;
4234
4235                 if (p + WCHAR_BYTES > token_buffer + maxtoken)
4236                   p = extend_token_buffer (p);
4237
4238                 for (byte = 0; byte < WCHAR_BYTES; ++byte)
4239                   {
4240                     int value;
4241                     if (byte >= sizeof (c))
4242                       value = 0;
4243                     else
4244                       value = (c >> (byte * width)) & bytemask;
4245                     if (BYTES_BIG_ENDIAN)
4246                       p[WCHAR_BYTES - byte - 1] = value;
4247                     else
4248                       p[byte] = value;
4249                   }
4250                 p += WCHAR_BYTES;
4251               }
4252             else
4253               {
4254                 if (p >= token_buffer + maxtoken)
4255                   p = extend_token_buffer (p);
4256                 *p++ = c;
4257               }
4258
4259           skipnewline:
4260             c = getch ();
4261             if (c == EOF) {
4262                 error ("Unterminated string");
4263                 break;
4264             }
4265           }
4266
4267         /* Terminate the string value, either with a single byte zero
4268            or with a wide zero.  */
4269         if (wide_flag)
4270           {
4271             if (p + WCHAR_BYTES > token_buffer + maxtoken)
4272               p = extend_token_buffer (p);
4273             bzero (p, WCHAR_BYTES);
4274             p += WCHAR_BYTES;
4275           }
4276         else
4277           {
4278             if (p >= token_buffer + maxtoken)
4279               p = extend_token_buffer (p);
4280             *p++ = 0;
4281           }
4282
4283         /* We have read the entire constant.
4284            Construct a STRING_CST for the result.  */
4285
4286         if (processing_template_decl)
4287           push_obstacks (&permanent_obstack, &permanent_obstack);
4288         yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1);
4289         if (processing_template_decl)
4290           pop_obstacks ();
4291
4292         if (wide_flag)
4293           TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4294         else
4295           TREE_TYPE (yylval.ttype) = char_array_type_node;
4296
4297         value = STRING; break;
4298       }
4299
4300     case '+':
4301     case '-':
4302     case '&':
4303     case '|':
4304     case '<':
4305     case '>':
4306     case '*':
4307     case '/':
4308     case '%':
4309     case '^':
4310     case '!':
4311     case '=':
4312       {
4313         register int c1;
4314
4315       combine:
4316
4317         switch (c)
4318           {
4319           case '+':
4320             yylval.code = PLUS_EXPR; break;
4321           case '-':
4322             yylval.code = MINUS_EXPR; break;
4323           case '&':
4324             yylval.code = BIT_AND_EXPR; break;
4325           case '|':
4326             yylval.code = BIT_IOR_EXPR; break;
4327           case '*':
4328             yylval.code = MULT_EXPR; break;
4329           case '/':
4330             yylval.code = TRUNC_DIV_EXPR; break;
4331           case '%':
4332             yylval.code = TRUNC_MOD_EXPR; break;
4333           case '^':
4334             yylval.code = BIT_XOR_EXPR; break;
4335           case LSHIFT:
4336             yylval.code = LSHIFT_EXPR; break;
4337           case RSHIFT:
4338             yylval.code = RSHIFT_EXPR; break;
4339           case '<':
4340             yylval.code = LT_EXPR; break;
4341           case '>':
4342             yylval.code = GT_EXPR; break;
4343           }
4344
4345         token_buffer[1] = c1 = getch ();
4346         token_buffer[2] = 0;
4347
4348         if (c1 == '=')
4349           {
4350             switch (c)
4351               {
4352               case '<':
4353                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4354               case '>':
4355                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4356               case '!':
4357                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4358               case '=':
4359                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4360               }
4361             value = ASSIGN; goto done;
4362           }
4363         else if (c == c1)
4364           switch (c)
4365             {
4366             case '+':
4367               value = PLUSPLUS; goto done;
4368             case '-':
4369               value = MINUSMINUS; goto done;
4370             case '&':
4371               value = ANDAND; goto done;
4372             case '|':
4373               value = OROR; goto done;
4374             case '<':
4375               c = LSHIFT;
4376               goto combine;
4377             case '>':
4378               c = RSHIFT;
4379               goto combine;
4380             }
4381         else if ((c == '-') && (c1 == '>'))
4382           {
4383             nextchar = getch ();
4384             if (nextchar == '*')
4385               {
4386                 nextchar = -1;
4387                 value = POINTSAT_STAR;
4388               }
4389             else
4390               value = POINTSAT;
4391             goto done;
4392           }
4393         else if (c1 == '?' && (c == '<' || c == '>'))
4394           {
4395             token_buffer[3] = 0;
4396
4397             c1 = getch ();
4398             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4399             if (c1 == '=')
4400               {
4401                 /* <?= or >?= expression.  */
4402                 token_buffer[2] = c1;
4403                 value = ASSIGN;
4404               }
4405             else
4406               {
4407                 value = MIN_MAX;
4408                 nextchar = c1;
4409               }
4410             if (pedantic)
4411               pedwarn ("use of `operator %s' is not standard C++",
4412                        token_buffer);
4413             goto done;
4414           }
4415         /* digraphs */
4416         else if (c == '<' && c1 == '%')
4417           { value = '{'; goto done; }
4418         else if (c == '<' && c1 == ':')
4419           { value = '['; goto done; }
4420         else if (c == '%' && c1 == '>')
4421           { value = '}'; goto done; }
4422         else if (c == '%' && c1 == ':')
4423           { value = '#'; goto done; }
4424
4425         nextchar = c1;
4426         token_buffer[1] = 0;
4427
4428         value = c;
4429         goto done;
4430       }
4431
4432     case ':':
4433       c = getch ();
4434       if (c == ':')
4435         {
4436           token_buffer[1] = ':';
4437           token_buffer[2] = '\0';
4438           value = SCOPE;
4439           yylval.itype = 1;
4440         }
4441       else if (c == '>')
4442         {
4443           value = ']';
4444           goto done;
4445         }
4446       else
4447         {
4448           nextchar = c;
4449           value = ':';
4450         }
4451       break;
4452
4453     case 0:
4454       /* Don't make yyparse think this is eof.  */
4455       value = 1;
4456       break;
4457
4458     case '(':
4459       /* try, weakly, to handle casts to pointers to functions.  */
4460       nextchar = skip_white_space (getch ());
4461       if (nextchar == '*')
4462         {
4463           int next_c = skip_white_space (getch ());
4464           if (next_c == ')')
4465             {
4466               nextchar = -1;
4467               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4468               value = PAREN_STAR_PAREN;
4469             }
4470           else
4471             {
4472               put_back (next_c);
4473               value = c;
4474             }
4475         }
4476       else if (nextchar == ')')
4477         {
4478           nextchar = -1;
4479           yylval.ttype = NULL_TREE;
4480           value = LEFT_RIGHT;
4481         }
4482       else value = c;
4483       break;
4484
4485     default:
4486       value = c;
4487     }
4488
4489 done:
4490 /*  yylloc.last_line = lineno; */
4491 #ifdef GATHER_STATISTICS
4492 #ifdef REDUCE_LENGTH
4493   token_count[value] += 1;
4494 #endif
4495 #endif
4496
4497   return value;
4498 }
4499
4500 int
4501 is_rid (t)
4502      tree t;
4503 {
4504   return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
4505 }
4506
4507 #ifdef GATHER_STATISTICS
4508 /* The original for tree_node_kind is in the toplevel tree.c; changes there
4509    need to be brought into here, unless this were actually put into a header
4510    instead.  */
4511 /* Statistics-gathering stuff.  */
4512 typedef enum
4513 {
4514   d_kind,
4515   t_kind,
4516   b_kind,
4517   s_kind,
4518   r_kind,
4519   e_kind,
4520   c_kind,
4521   id_kind,
4522   op_id_kind,
4523   perm_list_kind,
4524   temp_list_kind,
4525   vec_kind,
4526   x_kind,
4527   lang_decl,
4528   lang_type,
4529   all_kinds
4530 } tree_node_kind;
4531
4532 extern int tree_node_counts[];
4533 extern int tree_node_sizes[];
4534 #endif
4535
4536 /* Place to save freed lang_decls which were allocated on the
4537    permanent_obstack.  @@ Not currently used.  */
4538 tree free_lang_decl_chain;
4539
4540 tree
4541 build_lang_decl (code, name, type)
4542      enum tree_code code;
4543      tree name;
4544      tree type;
4545 {
4546   register tree t = build_decl (code, name, type);
4547   struct obstack *obstack = current_obstack;
4548   register int i = sizeof (struct lang_decl) / sizeof (int);
4549   register int *pi;
4550
4551   if (! TREE_PERMANENT (t))
4552     obstack = saveable_obstack;
4553   else
4554     /* Could be that saveable is permanent and current is not.  */
4555     obstack = &permanent_obstack;
4556
4557   if (free_lang_decl_chain && obstack == &permanent_obstack)
4558     {
4559       pi = (int *)free_lang_decl_chain;
4560       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4561     }
4562   else
4563     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4564
4565   while (i > 0)
4566     pi[--i] = 0;
4567
4568   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4569   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4570     = obstack == &permanent_obstack;
4571   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4572           == TREE_PERMANENT  (t), 234);
4573   DECL_MAIN_VARIANT (t) = t;
4574   if (current_lang_name == lang_name_cplusplus)
4575     DECL_LANGUAGE (t) = lang_cplusplus;
4576   else if (current_lang_name == lang_name_c)
4577     DECL_LANGUAGE (t) = lang_c;
4578   else if (current_lang_name == lang_name_java)
4579     DECL_LANGUAGE (t) = lang_java;
4580   else my_friendly_abort (64);
4581
4582 #if 0 /* not yet, should get fixed properly later */
4583   if (code == TYPE_DECL)
4584     {
4585       tree id;
4586       id = get_identifier (build_overload_name (type, 1, 1));
4587       DECL_ASSEMBLER_NAME (t) = id;
4588     }
4589
4590 #endif
4591 #ifdef GATHER_STATISTICS
4592   tree_node_counts[(int)lang_decl] += 1;
4593   tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
4594 #endif
4595
4596   return t;
4597 }
4598
4599 tree
4600 build_lang_field_decl (code, name, type)
4601      enum tree_code code;
4602      tree name;
4603      tree type;
4604 {
4605   extern struct obstack *current_obstack, *saveable_obstack;
4606   register tree t = build_decl (code, name, type);
4607   struct obstack *obstack = current_obstack;
4608   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4609   register int *pi;
4610 #if 0 /* not yet, should get fixed properly later */
4611
4612   if (code == TYPE_DECL)
4613     {
4614       tree id;
4615       id = get_identifier (build_overload_name (type, 1, 1));
4616       DECL_ASSEMBLER_NAME (t) = id;
4617     }
4618 #endif
4619
4620   if (! TREE_PERMANENT (t))
4621     obstack = saveable_obstack;
4622   else
4623     my_friendly_assert (obstack == &permanent_obstack, 235);
4624
4625   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4626   while (i > 0)
4627     pi[--i] = 0;
4628
4629   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4630   return t;
4631 }
4632
4633 void
4634 copy_lang_decl (node)
4635      tree node;
4636 {
4637   int size;
4638   int *pi;
4639
4640   if (! DECL_LANG_SPECIFIC (node))
4641     return;
4642
4643   if (TREE_CODE (node) == FIELD_DECL)
4644     size = sizeof (struct lang_decl_flags);
4645   else
4646     size = sizeof (struct lang_decl);
4647   pi = (int *)obstack_alloc (&permanent_obstack, size);
4648   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4649   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4650 }
4651
4652 tree
4653 make_lang_type (code)
4654      enum tree_code code;
4655 {
4656   extern struct obstack *current_obstack, *saveable_obstack;
4657   register tree t = make_node (code);
4658   struct obstack *obstack = current_obstack;
4659   register int i = sizeof (struct lang_type) / sizeof (int);
4660   register int *pi;
4661
4662   /* Set up some flags that give proper default behavior.  */
4663   IS_AGGR_TYPE (t) = 1;
4664
4665   if (! TREE_PERMANENT (t))
4666     obstack = saveable_obstack;
4667   else
4668     my_friendly_assert (obstack == &permanent_obstack, 236);
4669
4670   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
4671   while (i > 0)
4672     pi[--i] = 0;
4673
4674   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
4675   CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
4676   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4677   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4678   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
4679   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4680
4681   /* Make sure this is laid out, for ease of use later.
4682      In the presence of parse errors, the normal was of assuring
4683      this might not ever get executed, so we lay it out *immediately*.  */
4684   build_pointer_type (t);
4685
4686 #ifdef GATHER_STATISTICS
4687   tree_node_counts[(int)lang_type] += 1;
4688   tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
4689 #endif
4690
4691   return t;
4692 }
4693
4694 void
4695 dump_time_statistics ()
4696 {
4697   register tree prev = 0, decl, next;
4698   int this_time = my_get_run_time ();
4699   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
4700     += this_time - body_time;
4701
4702   fprintf (stderr, "\n******\n");
4703   print_time ("header files (total)", header_time);
4704   print_time ("main file (total)", this_time - body_time);
4705   fprintf (stderr, "ratio = %g : 1\n",
4706            (double)header_time / (double)(this_time - body_time));
4707   fprintf (stderr, "\n******\n");
4708
4709   for (decl = filename_times; decl; decl = next)
4710     {
4711       next = IDENTIFIER_GLOBAL_VALUE (decl);
4712       SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
4713       prev = decl;
4714     }
4715
4716   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4717     print_time (IDENTIFIER_POINTER (decl),
4718                 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4719 }
4720
4721 void
4722 compiler_error (s, v, v2)
4723      char *s;
4724      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4725 {
4726   char buf[1024];
4727   sprintf (buf, s, v, v2);
4728   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4729 }
4730 \f
4731 void
4732 yyerror (string)
4733      char *string;
4734 {
4735   extern int end_of_file;
4736   char buf[200];
4737
4738   strcpy (buf, string);
4739
4740   /* We can't print string and character constants well
4741      because the token_buffer contains the result of processing escapes.  */
4742   if (end_of_file)
4743     strcat (buf, input_redirected ()
4744             ? " at end of saved text"
4745             : " at end of input");
4746   else if (token_buffer[0] == 0)
4747     strcat (buf, " at null character");
4748   else if (token_buffer[0] == '"')
4749     strcat (buf, " before string constant");
4750   else if (token_buffer[0] == '\'')
4751     strcat (buf, " before character constant");
4752   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
4753     sprintf (buf + strlen (buf), " before character 0%o",
4754              (unsigned char) token_buffer[0]);
4755   else
4756     strcat (buf, " before `%s'");
4757
4758   error (buf, token_buffer);
4759 }
4760 \f
4761 static int
4762 handle_cp_pragma (pname)
4763      char *pname;
4764 {
4765   register int token;
4766
4767   if (! strcmp (pname, "vtable"))
4768     {
4769       extern tree pending_vtables;
4770
4771       /* More follows: it must be a string constant (class name).  */
4772       token = real_yylex ();
4773       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4774         {
4775           error ("invalid #pragma vtable");
4776           return -1;
4777         }
4778
4779       if (write_virtuals != 2)
4780         {
4781           warning ("use `+e2' option to enable #pragma vtable");
4782           return -1;
4783         }
4784       pending_vtables
4785         = perm_tree_cons (NULL_TREE,
4786                           get_identifier (TREE_STRING_POINTER (yylval.ttype)),
4787                           pending_vtables);
4788       token = real_yylex ();
4789       if (token != END_OF_LINE)
4790         warning ("trailing characters ignored");
4791       return 1;
4792     }
4793   else if (! strcmp (pname, "unit"))
4794     {
4795       /* More follows: it must be a string constant (unit name).  */
4796       token = real_yylex ();
4797       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
4798         {
4799           error ("invalid #pragma unit");
4800           return -1;
4801         }
4802       token = real_yylex ();
4803       if (token != END_OF_LINE)
4804         warning ("trailing characters ignored");
4805       return 1;
4806     }
4807   else if (! strcmp (pname, "interface"))
4808     {
4809       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
4810       char *main_filename = input_filename;
4811
4812       main_filename = file_name_nondirectory (main_filename);
4813
4814       token = real_yylex ();
4815       
4816       if (token != END_OF_LINE)
4817         {
4818           if (token != STRING
4819               || TREE_CODE (yylval.ttype) != STRING_CST)
4820             {
4821               error ("invalid `#pragma interface'");
4822               return -1;
4823             }
4824           main_filename = TREE_STRING_POINTER (yylval.ttype);
4825           token = real_yylex ();
4826         }
4827
4828       if (token != END_OF_LINE)
4829         warning ("garbage after `#pragma interface' ignored");
4830
4831 #ifndef NO_LINKAGE_HEURISTICS
4832       write_virtuals = 3;
4833
4834       if (impl_file_chain == 0)
4835         {
4836           /* If this is zero at this point, then we are
4837              auto-implementing.  */
4838           if (main_input_filename == 0)
4839             main_input_filename = input_filename;
4840
4841 #ifdef AUTO_IMPLEMENT
4842           filename = file_name_nondirectory (main_input_filename);
4843           fi = get_time_identifier (filename);
4844           fi = IDENTIFIER_CLASS_VALUE (fi);
4845           TREE_INT_CST_LOW (fi) = 0;
4846           TREE_INT_CST_HIGH (fi) = 1;
4847           /* Get default.  */
4848           impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
4849           impl_file_chain->filename = filename;
4850           impl_file_chain->next = 0;
4851 #endif
4852         }
4853
4854       interface_only = interface_strcmp (main_filename);
4855       interface_unknown = 0;
4856       TREE_INT_CST_LOW (fileinfo) = interface_only;
4857       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4858 #endif /* NO_LINKAGE_HEURISTICS */
4859
4860       return 1;
4861     }
4862   else if (! strcmp (pname, "implementation"))
4863     {
4864       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
4865       char *main_filename = main_input_filename ? main_input_filename : input_filename;
4866
4867       main_filename = file_name_nondirectory (main_filename);
4868       token = real_yylex ();
4869       if (token != END_OF_LINE)
4870         {
4871           if (token != STRING
4872               || TREE_CODE (yylval.ttype) != STRING_CST)
4873             {
4874               error ("invalid `#pragma implementation'");
4875               return -1;
4876             }
4877           main_filename = TREE_STRING_POINTER (yylval.ttype);
4878           token = real_yylex ();
4879         }
4880
4881       if (token != END_OF_LINE)
4882         warning ("garbage after `#pragma implementation' ignored");
4883
4884 #ifndef NO_LINKAGE_HEURISTICS
4885       if (write_virtuals == 3)
4886         {
4887           struct impl_files *ifiles = impl_file_chain;
4888           while (ifiles)
4889             {
4890               if (! strcmp (ifiles->filename, main_filename))
4891                 break;
4892               ifiles = ifiles->next;
4893             }
4894           if (ifiles == 0)
4895             {
4896               ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
4897               ifiles->filename = main_filename;
4898               ifiles->next = impl_file_chain;
4899               impl_file_chain = ifiles;
4900             }
4901         }
4902       else if ((main_input_filename != 0
4903                 && ! strcmp (main_input_filename, input_filename))
4904                || ! strcmp (input_filename, main_filename))
4905         {
4906           write_virtuals = 3;
4907           if (impl_file_chain == 0)
4908             {
4909               impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
4910               impl_file_chain->filename = main_filename;
4911               impl_file_chain->next = 0;
4912             }
4913         }
4914       else
4915         error ("`#pragma implementation' can only appear at top-level");
4916       interface_only = 0;
4917 #if 1
4918       /* We make this non-zero so that we infer decl linkage
4919          in the impl file only for variables first declared
4920          in the interface file.  */
4921       interface_unknown = 1;
4922 #else
4923       /* We make this zero so that templates in the impl
4924          file will be emitted properly.  */
4925       interface_unknown = 0;
4926 #endif
4927       TREE_INT_CST_LOW (fileinfo) = interface_only;
4928       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
4929 #endif /* NO_LINKAGE_HEURISTICS */
4930
4931       return 1;
4932     }
4933
4934   return 0;
4935 }
4936 \f
4937 #ifdef HANDLE_SYSV_PRAGMA
4938
4939 /* Handle a #pragma directive.  INPUT is the current input stream,
4940    and C is a character to reread.  Processes the entire input line
4941    and returns a character for the caller to reread: either \n or EOF.  */
4942
4943 /* This function has to be in this file, in order to get at
4944    the token types.  */
4945
4946 static int
4947 handle_sysv_pragma (token)
4948      register int token;
4949 {
4950   for (;;)
4951     {
4952       switch (token)
4953         {
4954         case IDENTIFIER:
4955         case TYPENAME:
4956         case STRING:
4957         case CONSTANT:
4958           handle_pragma_token (IDENTIFIER_POINTER(yylval.ttype), yylval.ttype);
4959           break;
4960         case '(':
4961           handle_pragma_token ("(", NULL_TREE);
4962           break;
4963         case ')':
4964           handle_pragma_token (")", NULL_TREE);
4965           break;
4966         case ',':
4967           handle_pragma_token (",", NULL_TREE);
4968           break;
4969         case '=':
4970           handle_pragma_token ("=", NULL_TREE);
4971           break;
4972         case LEFT_RIGHT:
4973           handle_pragma_token ("(", NULL_TREE);
4974           handle_pragma_token (")", NULL_TREE);
4975           break;
4976         case END_OF_LINE:
4977         default:
4978           return handle_pragma_token (NULL_PTR, NULL_TREE);
4979         }
4980       token = real_yylex ();
4981     }
4982 }
4983 #endif /* HANDLE_SYSV_PRAGMA */