OSDN Git Service

Warning fixes:
[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 #endif
46
47 #define obstack_chunk_alloc xmalloc
48 #define obstack_chunk_free free
49
50 #ifndef DIR_SEPARATOR
51 #define DIR_SEPARATOR '/'
52 #endif
53
54 extern struct obstack permanent_obstack;
55 extern struct obstack *current_obstack, *saveable_obstack;
56
57 extern void yyprint PROTO((FILE *, int, YYSTYPE));
58 extern void compiler_error PROTO((char *, HOST_WIDE_INT,
59                                   HOST_WIDE_INT));
60
61 static tree get_time_identifier PROTO((char *));
62 static int check_newline PROTO((void));
63 static int skip_white_space PROTO((int));
64 static void finish_defarg PROTO((void));
65 static int my_get_run_time PROTO((void));
66 static int get_last_nonwhite_on_line PROTO((void));
67 static int interface_strcmp PROTO((char *));
68 static int readescape PROTO((int *));
69 static char *extend_token_buffer PROTO((char *));
70 static void consume_string PROTO((struct obstack *, int));
71 static void set_typedecl_interface_info PROTO((tree, tree));
72 static void feed_defarg PROTO((tree, tree));
73 static int set_vardecl_interface_info PROTO((tree, tree));
74 static void store_pending_inline PROTO((tree, struct pending_inline *));
75 static void reinit_parse_for_expr PROTO((struct obstack *));
76 static int *init_cpp_parse PROTO((void));
77 static int handle_cp_pragma PROTO((char *));
78 #ifdef HANDLE_SYSV_PRAGMA
79 static int handle_sysv_pragma PROTO((int));
80 #endif
81 #ifdef GATHER_STATISTICS
82 #ifdef REDUCE_LENGTH
83 static int reduce_cmp PROTO((int *, int *));
84 static int token_cmp PROTO((int *, int *));
85 #endif
86 #endif
87
88 /* Given a file name X, return the nondirectory portion.
89    Keep in mind that X can be computed more than once.  */
90 char *
91 file_name_nondirectory (x)
92      char *x;
93 {
94   char *tmp = (char *) rindex (x, '/');
95   if (DIR_SEPARATOR != '/' && ! tmp)
96     tmp = (char *) rindex (x, DIR_SEPARATOR);
97   if (tmp)
98     return (char *) (tmp + 1);
99   else
100     return x;
101 }
102
103 /* This obstack is needed to hold text.  It is not safe to use
104    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
105 struct obstack inline_text_obstack;
106 char *inline_text_firstobj;
107
108 #if USE_CPPLIB
109 #include "cpplib.h"
110 extern cpp_reader  parse_in;
111 extern cpp_options parse_options;
112 extern unsigned char *yy_cur, *yy_lim;
113 #else
114 FILE *finput;
115 #endif
116 int end_of_file;
117
118 /* Pending language change.
119    Positive is push count, negative is pop count.  */
120 int pending_lang_change = 0;
121
122 /* Wrap the current header file in extern "C".  */
123 static int c_header_level = 0;
124
125 extern int first_token;
126 extern struct obstack token_obstack;
127
128 /* ??? Don't really know where this goes yet.  */
129 #if 1
130 #include "input.c"
131 #else
132 extern void put_back (/* int */);
133 extern int input_redirected ();
134 extern void feed_input (/* char *, int */);
135 #endif
136
137 /* Holds translations from TREE_CODEs to operator name strings,
138    i.e., opname_tab[PLUS_EXPR] == "+".  */
139 char **opname_tab;
140 char **assignop_tab;
141 \f
142 extern int yychar;              /*  the lookahead symbol                */
143 extern YYSTYPE yylval;          /*  the semantic value of the           */
144                                 /*  lookahead symbol                    */
145
146 #if 0
147 YYLTYPE yylloc;                 /*  location data for the lookahead     */
148                                 /*  symbol                              */
149 #endif
150
151
152 /* the declaration found for the last IDENTIFIER token read in.
153    yylex must look this up to detect typedefs, which get token type TYPENAME,
154    so it is left around in case the identifier is not a typedef but is
155    used in a context which makes it a reference to a variable.  */
156 tree lastiddecl;
157
158 /* The elements of `ridpointers' are identifier nodes
159    for the reserved type names and storage classes.
160    It is indexed by a RID_... value.  */
161 tree ridpointers[(int) RID_MAX];
162
163 /* We may keep statistics about how long which files took to compile.  */
164 static int header_time, body_time;
165 static tree filename_times;
166 static tree this_filename_time;
167
168 /* Array for holding counts of the numbers of tokens seen.  */
169 extern int *token_count;
170 \f
171 /* Return something to represent absolute declarators containing a *.
172    TARGET is the absolute declarator that the * contains.
173    CV_QUALIFIERS is a list of modifiers such as const or volatile
174    to apply to the pointer type, represented as identifiers.
175
176    We return an INDIRECT_REF whose "contents" are TARGET
177    and whose type is the modifier list.  */
178
179 tree
180 make_pointer_declarator (cv_qualifiers, target)
181      tree cv_qualifiers, target;
182 {
183   if (target && TREE_CODE (target) == IDENTIFIER_NODE
184       && ANON_AGGRNAME_P (target))
185     error ("type name expected before `*'");
186   target = build_parse_node (INDIRECT_REF, target);
187   TREE_TYPE (target) = cv_qualifiers;
188   return target;
189 }
190
191 /* Return something to represent absolute declarators containing a &.
192    TARGET is the absolute declarator that the & contains.
193    CV_QUALIFIERS is a list of modifiers such as const or volatile
194    to apply to the reference type, represented as identifiers.
195
196    We return an ADDR_EXPR whose "contents" are TARGET
197    and whose type is the modifier list.  */
198    
199 tree
200 make_reference_declarator (cv_qualifiers, target)
201      tree cv_qualifiers, target;
202 {
203   if (target)
204     {
205       if (TREE_CODE (target) == ADDR_EXPR)
206         {
207           error ("cannot declare references to references");
208           return target;
209         }
210       if (TREE_CODE (target) == INDIRECT_REF)
211         {
212           error ("cannot declare pointers to references");
213           return target;
214         }
215       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
216           error ("type name expected before `&'");
217     }
218   target = build_parse_node (ADDR_EXPR, target);
219   TREE_TYPE (target) = cv_qualifiers;
220   return target;
221 }
222
223 tree
224 make_call_declarator (target, parms, cv_qualifiers, exception_specification)
225      tree target, parms, cv_qualifiers, exception_specification;
226 {
227   target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
228   TREE_TYPE (target) = exception_specification;
229   return target;
230 }
231
232 void
233 set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
234      tree call_declarator, cv_qualifiers, exception_specification;
235 {
236   TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
237   TREE_TYPE (call_declarator) = exception_specification;
238 }
239 \f
240 /* Build names and nodes for overloaded operators.  */
241
242 tree ansi_opname[LAST_CPLUS_TREE_CODE];
243 tree ansi_assopname[LAST_CPLUS_TREE_CODE];
244
245 char *
246 operator_name_string (name)
247      tree name;
248 {
249   char *opname = IDENTIFIER_POINTER (name) + 2;
250   tree *opname_table;
251   int i, assign;
252
253   /* Works for builtin and user defined types.  */
254   if (IDENTIFIER_GLOBAL_VALUE (name)
255       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
256     return IDENTIFIER_POINTER (name);
257
258   if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
259     {
260       opname += 1;
261       assign = 1;
262       opname_table = ansi_assopname;
263     }
264   else
265     {
266       assign = 0;
267       opname_table = ansi_opname;
268     }
269
270   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
271     {
272       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
273           && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
274         break;
275     }
276
277   if (i == LAST_CPLUS_TREE_CODE)
278     return "<invalid operator>";
279
280   if (assign)
281     return assignop_tab[i];
282   else
283     return opname_tab[i];
284 }
285 \f
286 int interface_only;             /* whether or not current file is only for
287                                    interface definitions.  */
288 int interface_unknown;          /* whether or not we know this class
289                                    to behave according to #pragma interface.  */
290
291 /* lexical analyzer */
292
293 #ifndef WCHAR_TYPE_SIZE
294 #ifdef INT_TYPE_SIZE
295 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
296 #else
297 #define WCHAR_TYPE_SIZE BITS_PER_WORD
298 #endif
299 #endif
300
301 /* Number of bytes in a wide character.  */
302 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
303
304 static int maxtoken;            /* Current nominal length of token buffer.  */
305 char *token_buffer;             /* Pointer to token buffer.
306                                    Actual allocated length is maxtoken + 2.  */
307
308 #include "hash.h"
309 \f
310
311 /* Nonzero tells yylex to ignore \ in string constants.  */
312 static int ignore_escape_flag = 0;
313
314 static tree
315 get_time_identifier (name)
316      char *name;
317 {
318   tree time_identifier;
319   int len = strlen (name);
320   char *buf = (char *) alloca (len + 6);
321   strcpy (buf, "file ");
322   bcopy (name, buf+5, len);
323   buf[len+5] = '\0';
324   time_identifier = get_identifier (buf);
325   if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
326     {
327       push_obstacks_nochange ();
328       end_temporary_allocation ();
329       IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
330       IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
331       SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
332       filename_times = time_identifier;
333       pop_obstacks ();
334     }
335   return time_identifier;
336 }
337
338 #ifdef __GNUC__
339 __inline
340 #endif
341 static int
342 my_get_run_time ()
343 {
344   int old_quiet_flag = quiet_flag;
345   int this_time;
346   quiet_flag = 0;
347   this_time = get_run_time ();
348   quiet_flag = old_quiet_flag;
349   return this_time;
350 }
351 \f
352 /* Table indexed by tree code giving a string containing a character
353    classifying the tree code.  Possibilities are
354    t, d, s, c, r, <, 1 and 2.  See cp/cp-tree.def for details.  */
355
356 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
357
358 char cplus_tree_code_type[] = {
359   'x',
360 #include "cp-tree.def"
361 };
362 #undef DEFTREECODE
363
364 /* Table indexed by tree code giving number of expression
365    operands beyond the fixed part of the node structure.
366    Not used for types or decls.  */
367
368 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
369
370 int cplus_tree_code_length[] = {
371   0,
372 #include "cp-tree.def"
373 };
374 #undef DEFTREECODE
375
376 /* Names of tree components.
377    Used for printing out the tree and error messages.  */
378 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
379
380 char *cplus_tree_code_name[] = {
381   "@@dummy",
382 #include "cp-tree.def"
383 };
384 #undef DEFTREECODE
385 \f
386 /* toplev.c needs to call these.  */
387
388 void
389 lang_init_options ()
390 {
391   /* Default exceptions on.  */
392   flag_exceptions = 1;
393 }
394
395 void
396 lang_init ()
397 {
398 #if ! USE_CPPLIB
399   /* the beginning of the file is a new line; check for # */
400   /* With luck, we discover the real source file's name from that
401      and put it in input_filename.  */
402   put_back (check_newline ());
403 #endif
404   if (flag_gnu_xref) GNU_xref_begin (input_filename);
405   init_repo (input_filename);
406 }
407
408 void
409 lang_finish ()
410 {
411   extern int errorcount, sorrycount;
412   if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
413 }
414
415 char *
416 lang_identify ()
417 {
418   return "cplusplus";
419 }
420
421 void
422 init_filename_times ()
423 {
424   this_filename_time = get_time_identifier ("<top level>");
425   if (flag_detailed_statistics)
426     {
427       header_time = 0;
428       body_time = my_get_run_time ();
429       TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
430     }
431 }
432
433 /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
434    Stuck this hack in to get the files open correctly; this is called
435    in place of init_parse if we are an unexec'd binary.    */
436
437 #if 0
438 void
439 reinit_lang_specific ()
440 {
441   init_filename_times ();
442   reinit_search_statistics ();
443 }
444 #endif
445
446 static int *
447 init_cpp_parse ()
448 {
449 #ifdef GATHER_STATISTICS
450 #ifdef REDUCE_LENGTH
451   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
452   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
453   reduce_count += 1;
454   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
455   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
456   token_count += 1;
457 #endif
458 #endif
459   return token_count;
460 }
461
462 char *
463 init_parse (filename)
464      char *filename;
465 {
466   extern int flag_no_gnu_keywords;
467   extern int flag_operator_names;
468
469   int i;
470
471 #ifdef MULTIBYTE_CHARS
472   /* Change to the native locale for multibyte conversions.  */
473   setlocale (LC_CTYPE, "");
474   literal_codeset = getenv ("LANG");
475 #endif
476
477 #if USE_CPPLIB
478   yy_cur = "\n";
479   yy_lim = yy_cur + 1;
480
481   parse_in.show_column = 1;
482   if (! cpp_start_read (&parse_in, filename))
483     abort ();
484 #else
485   /* Open input file.  */
486   if (filename == 0 || !strcmp (filename, "-"))
487     {
488       finput = stdin;
489       filename = "stdin";
490     }
491   else
492     finput = fopen (filename, "r");
493   if (finput == 0)
494     pfatal_with_name (filename);
495
496 #ifdef IO_BUFFER_SIZE
497   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
498 #endif
499 #endif /* !USE_CPPLIB */
500
501   /* Initialize the lookahead machinery.  */
502   init_spew ();
503
504   /* Make identifier nodes long enough for the language-specific slots.  */
505   set_identifier_size (sizeof (struct lang_identifier));
506   decl_printable_name = lang_printable_name;
507
508   init_cplus_expand ();
509
510   bcopy (cplus_tree_code_type,
511          tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
512          (int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
513   bcopy ((char *)cplus_tree_code_length,
514          (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
515          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
516   bcopy ((char *)cplus_tree_code_name,
517          (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
518          (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
519
520   opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
521   bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
522   assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
523   bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
524
525   ansi_opname[0] = get_identifier ("<invalid operator>");
526   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
527     {
528       ansi_opname[i] = ansi_opname[0];
529       ansi_assopname[i] = ansi_opname[0];
530     }
531
532   ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
533   IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
534   ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
535   ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
536   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
537   ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
538   ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
539   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
540   ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
541   IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
542   ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
543   ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
544   ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
545   ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
546   IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
547   ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
548   ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
549   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
550   ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
551   ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
552   IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
553   ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
554   IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
555   ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
556   IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
557   ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
558   IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
559   ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
560   IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
561   ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
562   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
563   ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
564   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
565   ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
566   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
567   ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
568   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
569   ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
570   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
571   ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
572   ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
573   IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
574   ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
575   ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
576   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
577   ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
578   IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
579   ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
580   IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
581   ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
582   ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
583   ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
584   ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
585   ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
586   ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
587   ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
588   ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
589   ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
590   IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
591   ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
592   IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
593   ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
594   ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
595   ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
596   IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
597   ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
598   IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
599   ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
600   IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
601   ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
602   IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
603   ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
604   IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
605   ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
606   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
607   ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
608   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
609   ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
610   ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
611   ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
612   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
613   ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
614   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
615   ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
616   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
617   ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
618   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
619   ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
620   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
621   ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
622   ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
623   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
624   ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
625   IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
626   ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
627   IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
628   ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
629   IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
630   ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
631   IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
632   ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
633   IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
634   ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
635   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
636   ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
637   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
638   ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
639   IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
640
641   /* This is not true: these operators are not defined in ANSI,
642      but we need them anyway.  */
643   ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
644   IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
645   ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
646   IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
647   ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
648   IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
649   ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz");
650   IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1;
651
652   init_method ();
653   init_error ();
654   gcc_obstack_init (&inline_text_obstack);
655   inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
656
657   /* Start it at 0, because check_newline is called at the very beginning
658      and will increment it to 1.  */
659   lineno = 0;
660   input_filename = "<internal>";
661   current_function_decl = NULL;
662
663   maxtoken = 40;
664   token_buffer = (char *) xmalloc (maxtoken + 2);
665
666   ridpointers[(int) RID_INT] = get_identifier ("int");
667   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
668                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
669   ridpointers[(int) RID_BOOL] = get_identifier ("bool");
670   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
671                           build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
672   ridpointers[(int) RID_CHAR] = get_identifier ("char");
673   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
674                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
675   ridpointers[(int) RID_VOID] = get_identifier ("void");
676   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
677                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
678   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
679   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
680                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
681   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
682   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
683                           build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
684   ridpointers[(int) RID_SHORT] = get_identifier ("short");
685   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
686                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
687   ridpointers[(int) RID_LONG] = get_identifier ("long");
688   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
689                           build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
690   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
691   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
692                           build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
693   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
694   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
695                           build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
696   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
697   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
698                           build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
699   ridpointers[(int) RID_CONST] = get_identifier ("const");
700   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
701                           build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
702   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
703   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
704                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
705   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
706   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
707                           build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
708   ridpointers[(int) RID_STATIC] = get_identifier ("static");
709   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
710                           build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
711   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
712   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
713                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
714   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
715   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
716                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
717   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
718   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
719                           build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
720   ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex");
721   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX],
722                           build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX]));
723
724   /* C++ extensions. These are probably not correctly named.  */
725   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
726   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
727                           build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
728   class_type_node = build_int_2 (class_type, 0);
729   TREE_TYPE (class_type_node) = class_type_node;
730   ridpointers[(int) RID_CLASS] = class_type_node;
731
732   record_type_node = build_int_2 (record_type, 0);
733   TREE_TYPE (record_type_node) = record_type_node;
734   ridpointers[(int) RID_RECORD] = record_type_node;
735
736   union_type_node = build_int_2 (union_type, 0);
737   TREE_TYPE (union_type_node) = union_type_node;
738   ridpointers[(int) RID_UNION] = union_type_node;
739
740   enum_type_node = build_int_2 (enum_type, 0);
741   TREE_TYPE (enum_type_node) = enum_type_node;
742   ridpointers[(int) RID_ENUM] = enum_type_node;
743
744   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
745   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
746                           build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
747   ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
748   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT],
749                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT]));
750   ridpointers[(int) RID_EXPORT] = get_identifier ("export");
751   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPORT],
752                           build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPORT]));
753   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
754   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
755                           build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
756
757   ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
758   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
759                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
760   ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
761   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
762                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
763   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
764   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
765                           build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
766   ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
767   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
768                           build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
769   /* This is for ANSI C++.  */
770   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
771   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
772                           build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
773
774   /* Signature handling extensions.  */
775   signature_type_node = build_int_2 (signature_type, 0);
776   TREE_TYPE (signature_type_node) = signature_type_node;
777   ridpointers[(int) RID_SIGNATURE] = signature_type_node;
778
779   /* Create the built-in __null node.  Note that we can't yet call for
780      type_for_size here because integer_type_node and so forth are not
781      set up.  Therefore, we don't set the type of these nodes until
782      init_decl_processing.  */
783   null_node = build_int_2 (0, 0);
784   ridpointers[RID_NULL] = null_node;
785
786   opname_tab[(int) COMPONENT_REF] = "->";
787   opname_tab[(int) MEMBER_REF] = "->*";
788   opname_tab[(int) INDIRECT_REF] = "*";
789   opname_tab[(int) ARRAY_REF] = "[]";
790   opname_tab[(int) MODIFY_EXPR] = "=";
791   opname_tab[(int) NEW_EXPR] = "new";
792   opname_tab[(int) DELETE_EXPR] = "delete";
793   opname_tab[(int) VEC_NEW_EXPR] = "new []";
794   opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
795   opname_tab[(int) COND_EXPR] = "?:";
796   opname_tab[(int) CALL_EXPR] = "()";
797   opname_tab[(int) PLUS_EXPR] = "+";
798   opname_tab[(int) MINUS_EXPR] = "-";
799   opname_tab[(int) MULT_EXPR] = "*";
800   opname_tab[(int) TRUNC_DIV_EXPR] = "/";
801   opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
802   opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
803   opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
804   opname_tab[(int) TRUNC_MOD_EXPR] = "%";
805   opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
806   opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
807   opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
808   opname_tab[(int) NEGATE_EXPR] = "-";
809   opname_tab[(int) MIN_EXPR] = "<?";
810   opname_tab[(int) MAX_EXPR] = ">?";
811   opname_tab[(int) ABS_EXPR] = "abs";
812   opname_tab[(int) FFS_EXPR] = "ffs";
813   opname_tab[(int) LSHIFT_EXPR] = "<<";
814   opname_tab[(int) RSHIFT_EXPR] = ">>";
815   opname_tab[(int) BIT_IOR_EXPR] = "|";
816   opname_tab[(int) BIT_XOR_EXPR] = "^";
817   opname_tab[(int) BIT_AND_EXPR] = "&";
818   opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
819   opname_tab[(int) BIT_NOT_EXPR] = "~";
820   opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
821   opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
822   opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
823   opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
824   opname_tab[(int) TRUTH_NOT_EXPR] = "!";
825   opname_tab[(int) LT_EXPR] = "<";
826   opname_tab[(int) LE_EXPR] = "<=";
827   opname_tab[(int) GT_EXPR] = ">";
828   opname_tab[(int) GE_EXPR] = ">=";
829   opname_tab[(int) EQ_EXPR] = "==";
830   opname_tab[(int) NE_EXPR] = "!=";
831   opname_tab[(int) IN_EXPR] = "in";
832   opname_tab[(int) RANGE_EXPR] = "...";
833   opname_tab[(int) CONVERT_EXPR] = "+";
834   opname_tab[(int) ADDR_EXPR] = "&";
835   opname_tab[(int) PREDECREMENT_EXPR] = "--";
836   opname_tab[(int) PREINCREMENT_EXPR] = "++";
837   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
838   opname_tab[(int) POSTINCREMENT_EXPR] = "++";
839   opname_tab[(int) COMPOUND_EXPR] = ",";
840
841   assignop_tab[(int) NOP_EXPR] = "=";
842   assignop_tab[(int) PLUS_EXPR] =  "+=";
843   assignop_tab[(int) CONVERT_EXPR] =  "+=";
844   assignop_tab[(int) MINUS_EXPR] = "-=";
845   assignop_tab[(int) NEGATE_EXPR] = "-=";
846   assignop_tab[(int) MULT_EXPR] = "*=";
847   assignop_tab[(int) INDIRECT_REF] = "*=";
848   assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
849   assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
850   assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
851   assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
852   assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
853   assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
854   assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
855   assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
856   assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
857   assignop_tab[(int) MIN_EXPR] = "<?=";
858   assignop_tab[(int) MAX_EXPR] = ">?=";
859   assignop_tab[(int) LSHIFT_EXPR] = "<<=";
860   assignop_tab[(int) RSHIFT_EXPR] = ">>=";
861   assignop_tab[(int) BIT_IOR_EXPR] = "|=";
862   assignop_tab[(int) BIT_XOR_EXPR] = "^=";
863   assignop_tab[(int) BIT_AND_EXPR] = "&=";
864   assignop_tab[(int) ADDR_EXPR] = "&=";
865
866   init_filename_times ();
867
868   /* Some options inhibit certain reserved words.
869      Clear those words out of the hash table so they won't be recognized.  */
870 #define UNSET_RESERVED_WORD(STRING) \
871   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
872        if (s) s->name = ""; } while (0)
873
874 #if 0
875   /* let's parse things, and if they use it, then give them an error.  */
876   if (!flag_exceptions)
877     {
878       UNSET_RESERVED_WORD ("throw");
879       UNSET_RESERVED_WORD ("try");
880       UNSET_RESERVED_WORD ("catch");
881     }
882 #endif
883
884   if (!flag_rtti || flag_no_gnu_keywords)
885     {
886       UNSET_RESERVED_WORD ("classof");
887       UNSET_RESERVED_WORD ("headof");
888     }
889
890   if (! flag_handle_signatures || flag_no_gnu_keywords)
891     {
892       /* Easiest way to not recognize signature
893          handling extensions...  */
894       UNSET_RESERVED_WORD ("signature");
895       UNSET_RESERVED_WORD ("sigof");
896     }
897   if (flag_no_asm || flag_no_gnu_keywords)
898     UNSET_RESERVED_WORD ("typeof");
899   if (! flag_operator_names)
900     {
901       /* These are new ANSI keywords that may break code.  */
902       UNSET_RESERVED_WORD ("and");
903       UNSET_RESERVED_WORD ("and_eq");
904       UNSET_RESERVED_WORD ("bitand");
905       UNSET_RESERVED_WORD ("bitor");
906       UNSET_RESERVED_WORD ("compl");
907       UNSET_RESERVED_WORD ("not");
908       UNSET_RESERVED_WORD ("not_eq");
909       UNSET_RESERVED_WORD ("or");
910       UNSET_RESERVED_WORD ("or_eq");
911       UNSET_RESERVED_WORD ("xor");
912       UNSET_RESERVED_WORD ("xor_eq");
913     }
914
915   token_count = init_cpp_parse ();
916   interface_unknown = 1;
917
918   return filename;
919 }
920
921 void
922 finish_parse ()
923 {
924 #if USE_CPPLIB
925   cpp_finish (&parse_in);
926 #else
927   fclose (finput);
928 #endif
929 }
930
931 void
932 reinit_parse_for_function ()
933 {
934   current_base_init_list = NULL_TREE;
935   current_member_init_list = NULL_TREE;
936 }
937 \f
938 #ifdef __GNUC__
939 __inline
940 #endif
941 void
942 yyprint (file, yychar, yylval)
943      FILE *file;
944      int yychar;
945      YYSTYPE yylval;
946 {
947   tree t;
948   switch (yychar)
949     {
950     case IDENTIFIER:
951     case TYPENAME:
952     case TYPESPEC:
953     case PTYPENAME:
954     case IDENTIFIER_DEFN:
955     case TYPENAME_DEFN:
956     case PTYPENAME_DEFN:
957     case SCSPEC:
958     case PRE_PARSED_CLASS_DECL:
959       t = yylval.ttype;
960       if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
961         {
962           fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
963           break;
964         }
965       my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
966       if (IDENTIFIER_POINTER (t))
967           fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
968       break;
969     case AGGR:
970       if (yylval.ttype == class_type_node)
971         fprintf (file, " `class'");
972       else if (yylval.ttype == record_type_node)
973         fprintf (file, " `struct'");
974       else if (yylval.ttype == union_type_node)
975         fprintf (file, " `union'");
976       else if (yylval.ttype == enum_type_node)
977         fprintf (file, " `enum'");
978       else if (yylval.ttype == signature_type_node)
979         fprintf (file, " `signature'");
980       else
981         my_friendly_abort (80);
982       break;
983     }
984 }
985
986 #if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
987 static int *reduce_count;
988 #endif
989
990 int *token_count;
991
992 #if 0
993 #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
994 #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
995 #endif
996
997 #ifdef GATHER_STATISTICS
998 #ifdef REDUCE_LENGTH
999 void
1000 yyhook (yyn)
1001      int yyn;
1002 {
1003   reduce_count[yyn] += 1;
1004 }
1005
1006 static int
1007 reduce_cmp (p, q)
1008      int *p, *q;
1009 {
1010   return reduce_count[*q] - reduce_count[*p];
1011 }
1012
1013 static int
1014 token_cmp (p, q)
1015      int *p, *q;
1016 {
1017   return token_count[*q] - token_count[*p];
1018 }
1019 #endif
1020 #endif
1021
1022 void
1023 print_parse_statistics ()
1024 {
1025 #ifdef GATHER_STATISTICS
1026 #ifdef REDUCE_LENGTH
1027 #if YYDEBUG != 0
1028   int i;
1029   int maxlen = REDUCE_LENGTH;
1030   unsigned *sorted;
1031   
1032   if (reduce_count[-1] == 0)
1033     return;
1034
1035   if (TOKEN_LENGTH > REDUCE_LENGTH)
1036     maxlen = TOKEN_LENGTH;
1037   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
1038
1039   for (i = 0; i < TOKEN_LENGTH; i++)
1040     sorted[i] = i;
1041   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
1042   for (i = 0; i < TOKEN_LENGTH; i++)
1043     {
1044       int idx = sorted[i];
1045       if (token_count[idx] == 0)
1046         break;
1047       if (token_count[idx] < token_count[-1])
1048         break;
1049       fprintf (stderr, "token %d, `%s', count = %d\n",
1050                idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
1051     }
1052   fprintf (stderr, "\n");
1053   for (i = 0; i < REDUCE_LENGTH; i++)
1054     sorted[i] = i;
1055   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
1056   for (i = 0; i < REDUCE_LENGTH; i++)
1057     {
1058       int idx = sorted[i];
1059       if (reduce_count[idx] == 0)
1060         break;
1061       if (reduce_count[idx] < reduce_count[-1])
1062         break;
1063       fprintf (stderr, "rule %d, line %d, count = %d\n",
1064                idx, yyrline[idx], reduce_count[idx]);
1065     }
1066   fprintf (stderr, "\n");
1067 #endif
1068 #endif
1069 #endif
1070 }
1071
1072 /* Sets the value of the 'yydebug' variable to VALUE.
1073    This is a function so we don't have to have YYDEBUG defined
1074    in order to build the compiler.  */
1075
1076 void
1077 set_yydebug (value)
1078      int value;
1079 {
1080 #if YYDEBUG != 0
1081   extern int yydebug;
1082   yydebug = value;
1083 #else
1084   warning ("YYDEBUG not defined.");
1085 #endif
1086 }
1087
1088 \f
1089 /* Functions and data structures for #pragma interface.
1090
1091    `#pragma implementation' means that the main file being compiled
1092    is considered to implement (provide) the classes that appear in
1093    its main body.  I.e., if this is file "foo.cc", and class `bar'
1094    is defined in "foo.cc", then we say that "foo.cc implements bar".
1095
1096    All main input files "implement" themselves automagically.
1097
1098    `#pragma interface' means that unless this file (of the form "foo.h"
1099    is not presently being included by file "foo.cc", the
1100    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
1101    of the vtables nor any of the inline functions defined in foo.h
1102    will ever be output.
1103
1104    There are cases when we want to link files such as "defs.h" and
1105    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
1106    and "main.cc" has `#pragma implementation "defs.h"'.  */
1107
1108 struct impl_files
1109 {
1110   char *filename;
1111   struct impl_files *next;
1112 };
1113
1114 static struct impl_files *impl_file_chain;
1115
1116 /* Helper function to load global variables with interface
1117    information.  */
1118
1119 void
1120 extract_interface_info ()
1121 {
1122   tree fileinfo = 0;
1123
1124   if (flag_alt_external_templates)
1125     {
1126       struct tinst_level *til = tinst_for_decl ();
1127   
1128       if (til)
1129         fileinfo = get_time_identifier (til->file);
1130     }
1131   if (!fileinfo)
1132     fileinfo = get_time_identifier (input_filename);
1133   fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
1134   interface_only = TREE_INT_CST_LOW (fileinfo);
1135   interface_unknown = TREE_INT_CST_HIGH (fileinfo);
1136 }
1137
1138 /* Return nonzero if S is not considered part of an
1139    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
1140
1141 static int
1142 interface_strcmp (s)
1143      char *s;
1144 {
1145   /* Set the interface/implementation bits for this scope.  */
1146   struct impl_files *ifiles;
1147   char *s1;
1148
1149   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
1150     {
1151       char *t1 = ifiles->filename;
1152       s1 = s;
1153
1154       if (*s1 != *t1 || *s1 == 0)
1155         continue;
1156
1157       while (*s1 == *t1 && *s1 != 0)
1158         s1++, t1++;
1159
1160       /* A match.  */
1161       if (*s1 == *t1)
1162         return 0;
1163
1164       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
1165       if (index (s1, '.') || index (t1, '.'))
1166         continue;
1167
1168       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
1169         continue;
1170
1171       /* A match.  */
1172       return 0;
1173     }
1174
1175   /* No matches.  */
1176   return 1;
1177 }
1178
1179 static void
1180 set_typedecl_interface_info (prev, vars)
1181      tree prev ATTRIBUTE_UNUSED, vars;
1182 {
1183   tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
1184   tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
1185   tree type = TREE_TYPE (vars);
1186
1187   CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
1188     = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars)));
1189 }
1190
1191 static int
1192 set_vardecl_interface_info (prev, vars)
1193      tree prev, vars;
1194 {
1195   tree type = DECL_CONTEXT (vars);
1196
1197   if (CLASSTYPE_INTERFACE_KNOWN (type))
1198     {
1199       if (CLASSTYPE_INTERFACE_ONLY (type))
1200         set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));
1201       else
1202         CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
1203       DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
1204       TREE_PUBLIC (vars) = 1;
1205       return 1;
1206     }
1207   return 0;
1208 }
1209 \f
1210 /* Called from the top level: if there are any pending inlines to
1211    do, set up to process them now.  This function sets up the first function
1212    to be parsed; after it has been, the rule for fndef in parse.y will
1213    call process_next_inline to start working on the next one.  */
1214
1215 void
1216 do_pending_inlines ()
1217 {
1218   struct pending_inline *t;
1219   tree context;
1220
1221   /* Oops, we're still dealing with the last batch.  */
1222   if (yychar == PRE_PARSED_FUNCTION_DECL)
1223     return;
1224
1225   /* Reverse the pending inline functions, since
1226      they were cons'd instead of appended.  */
1227   {
1228     struct pending_inline *prev = 0, *tail;
1229     t = pending_inlines;
1230     pending_inlines = 0;
1231
1232     for (; t; t = tail)
1233       {
1234         tail = t->next;
1235         t->next = prev;
1236         t->deja_vu = 1;
1237         prev = t;
1238       }
1239     t = prev;
1240   }
1241
1242   if (t == 0)
1243     return;
1244             
1245   /* Now start processing the first inline function.  */
1246   context = hack_decl_function_context (t->fndecl);
1247   if (context)
1248     push_cp_function_context (context);
1249   maybe_begin_member_template_processing (t->fndecl);
1250   if (t->len > 0)
1251     {
1252       feed_input (t->buf, t->len);
1253       lineno = t->lineno;
1254 #if 0
1255       if (input_filename != t->filename)
1256         {
1257           input_filename = t->filename;
1258           /* Get interface/implementation back in sync.  */
1259           extract_interface_info ();
1260         }
1261 #else
1262       input_filename = t->filename;
1263       interface_unknown = t->interface == 1;
1264       interface_only = t->interface == 0;
1265 #endif
1266       yychar = PRE_PARSED_FUNCTION_DECL;
1267     }
1268   /* Pass back a handle on the rest of the inline functions, so that they
1269      can be processed later.  */
1270   yylval.ttype = build_tree_list ((tree) t, t->fndecl);
1271   DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
1272 }
1273
1274 static int nextchar = -1;
1275
1276 /* Called from the fndecl rule in the parser when the function just parsed
1277    was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
1278    do_pending_inlines).  */
1279
1280 void
1281 process_next_inline (t)
1282      tree t;
1283 {
1284   tree context;
1285   struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
1286   context = hack_decl_function_context (i->fndecl);  
1287   maybe_end_member_template_processing ();
1288   if (context)
1289     pop_cp_function_context (context);
1290   i = i->next;
1291   if (yychar == YYEMPTY)
1292     yychar = yylex ();
1293   if (yychar != END_OF_SAVED_INPUT)
1294     {
1295       error ("parse error at end of saved function text");
1296
1297       /* restore_pending_input will abort unless yychar is either
1298          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1299          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1300          since that may have gotten set as well.  */
1301       nextchar = -1;
1302     }
1303   yychar = YYEMPTY;
1304   end_input ();
1305   if (i && i->fndecl != NULL_TREE)
1306     {
1307       context = hack_decl_function_context (i->fndecl);
1308       if (context)
1309         push_cp_function_context (context);
1310       maybe_begin_member_template_processing (i->fndecl);
1311       feed_input (i->buf, i->len);
1312       lineno = i->lineno;
1313       input_filename = i->filename;
1314       yychar = PRE_PARSED_FUNCTION_DECL;
1315       yylval.ttype = build_tree_list ((tree) i, i->fndecl);
1316       DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
1317     }
1318   if (i)
1319     {
1320       interface_unknown = i->interface == 1;
1321       interface_only = i->interface == 0;
1322     }
1323   else
1324     extract_interface_info ();
1325 }
1326
1327 /* Since inline methods can refer to text which has not yet been seen,
1328    we store the text of the method in a structure which is placed in the
1329    DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
1330    After parsing the body of the class definition, the FUNCTION_DECL's are
1331    scanned to see which ones have this field set.  Those are then digested
1332    one at a time.
1333
1334    This function's FUNCTION_DECL will have a bit set in its common so
1335    that we know to watch out for it.  */
1336
1337 static void
1338 consume_string (this_obstack, matching_char)
1339      register struct obstack *this_obstack;
1340      int matching_char;
1341 {
1342   register int c;
1343   int starting_lineno = lineno;
1344   do
1345     {
1346       c = getch ();
1347       if (c == EOF)
1348         {
1349           int save_lineno = lineno;
1350           lineno = starting_lineno;
1351           if (matching_char == '"')
1352             error ("end of file encountered inside string constant");
1353           else
1354             error ("end of file encountered inside character constant");
1355           lineno = save_lineno;
1356           return;
1357         }
1358       if (c == '\\')
1359         {
1360           obstack_1grow (this_obstack, c);
1361           c = getch ();
1362           obstack_1grow (this_obstack, c);
1363
1364           /* Make sure we continue the loop */
1365           c = 0;
1366           continue;
1367         }
1368       if (c == '\n')
1369         {
1370           if (pedantic)
1371             pedwarn ("ANSI C++ forbids newline in string constant");
1372           lineno++;
1373         }
1374       obstack_1grow (this_obstack, c);
1375     }
1376   while (c != matching_char);
1377 }
1378
1379 static int nextyychar = YYEMPTY;
1380 static YYSTYPE nextyylval;
1381
1382 struct pending_input {
1383   int nextchar, yychar, nextyychar, eof;
1384   YYSTYPE yylval, nextyylval;
1385   struct obstack token_obstack;
1386   int first_token;
1387 };
1388
1389 struct pending_input *
1390 save_pending_input ()
1391 {
1392   struct pending_input *p;
1393   p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
1394   p->nextchar = nextchar;
1395   p->yychar = yychar;
1396   p->nextyychar = nextyychar;
1397   p->yylval = yylval;
1398   p->nextyylval = nextyylval;
1399   p->eof = end_of_file;
1400   yychar = nextyychar = YYEMPTY;
1401   nextchar = -1;
1402   p->first_token = first_token;
1403   p->token_obstack = token_obstack;
1404
1405   first_token = 0;
1406   gcc_obstack_init (&token_obstack);
1407   end_of_file = 0;
1408   return p;
1409 }
1410
1411 void
1412 restore_pending_input (p)
1413      struct pending_input *p;
1414 {
1415   my_friendly_assert (nextchar == -1, 229);
1416   nextchar = p->nextchar;
1417   my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230);
1418   yychar = p->yychar;
1419   my_friendly_assert (nextyychar == YYEMPTY, 231);
1420   nextyychar = p->nextyychar;
1421   yylval = p->yylval;
1422   nextyylval = p->nextyylval;
1423   first_token = p->first_token;
1424   obstack_free (&token_obstack, (char *) 0);
1425   token_obstack = p->token_obstack;
1426   end_of_file = p->eof;
1427   free (p);
1428 }
1429
1430 /* Unget character CH from the input stream.
1431    If RESCAN is non-zero, then we want to `see' this
1432    character as the next input token.  */
1433
1434 void
1435 yyungetc (ch, rescan)
1436      int ch;
1437      int rescan;
1438 {
1439   /* Unget a character from the input stream.  */
1440   if (yychar == YYEMPTY || rescan == 0)
1441     {
1442       if (nextchar >= 0)
1443         put_back (nextchar);
1444       nextchar = ch;
1445     }
1446   else
1447     {
1448       my_friendly_assert (nextyychar == YYEMPTY, 232);
1449       nextyychar = yychar;
1450       nextyylval = yylval;
1451       yychar = ch;
1452     }
1453 }
1454
1455 void
1456 clear_inline_text_obstack ()
1457 {
1458   obstack_free (&inline_text_obstack, inline_text_firstobj);
1459 }
1460
1461 /* This function stores away the text for an inline function that should
1462    be processed later.  It decides how much later, and may need to move
1463    the info between obstacks; therefore, the caller should not refer to
1464    the T parameter after calling this function.  */
1465
1466 static void
1467 store_pending_inline (decl, t)
1468      tree decl;
1469      struct pending_inline *t;
1470 {
1471   t->fndecl = decl;
1472   DECL_PENDING_INLINE_INFO (decl) = t;
1473
1474   /* Because we use obstacks, we must process these in precise order.  */
1475   t->next = pending_inlines;
1476   pending_inlines = t;
1477 }
1478
1479 void
1480 reinit_parse_for_method (yychar, decl)
1481      int yychar;
1482      tree decl;
1483 {
1484   int len;
1485   int starting_lineno = lineno;
1486   char *starting_filename = input_filename;
1487
1488   reinit_parse_for_block (yychar, &inline_text_obstack);
1489
1490   len = obstack_object_size (&inline_text_obstack);
1491   current_base_init_list = NULL_TREE;
1492   current_member_init_list = NULL_TREE;
1493   if (decl == void_type_node
1494       || (current_class_type && TYPE_REDEFINED (current_class_type)))
1495     {
1496       /* Happens when we get two declarations of the same
1497          function in the same scope.  */
1498       char *buf = obstack_finish (&inline_text_obstack);
1499       obstack_free (&inline_text_obstack, buf);
1500       return;
1501     }
1502   else
1503     {
1504       struct pending_inline *t;
1505       char *buf = obstack_finish (&inline_text_obstack);
1506
1507       t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1508                                                    sizeof (struct pending_inline));
1509       t->lineno = starting_lineno;
1510       t->filename = starting_filename;
1511       t->token = YYEMPTY;
1512       t->token_value = 0;
1513       t->buf = buf;
1514       t->len = len;
1515       t->deja_vu = 0;
1516 #if 0
1517       if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
1518         warn_if_unknown_interface (decl);
1519 #endif
1520       t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
1521       store_pending_inline (decl, t);
1522     }
1523 }
1524
1525 /* Consume a block -- actually, a method beginning
1526    with `:' or `{' -- and save it away on the specified obstack.  */
1527
1528 void
1529 reinit_parse_for_block (pyychar, obstackp)
1530      int pyychar;
1531      struct obstack *obstackp;
1532 {
1533   register int c = 0;
1534   int blev = 1;
1535   int starting_lineno = lineno;
1536   char *starting_filename = input_filename;
1537   int len;
1538   int look_for_semicolon = 0;
1539   int look_for_lbrac = 0;
1540
1541   if (pyychar == '{')
1542     obstack_1grow (obstackp, '{');
1543   else if (pyychar == '=')
1544     look_for_semicolon = 1;
1545   else if (pyychar == ':')
1546     {
1547       obstack_1grow (obstackp, pyychar);
1548       look_for_lbrac = 1;
1549       blev = 0;
1550     }
1551   else if (pyychar == RETURN)
1552     {
1553       obstack_grow (obstackp, "return", 6);
1554       look_for_lbrac = 1;
1555       blev = 0;
1556     }
1557   else if (pyychar == TRY)
1558     {
1559       obstack_grow (obstackp, "try", 3);
1560       look_for_lbrac = 1;
1561       blev = 0;
1562     }
1563   else
1564     {
1565       yyerror ("parse error in method specification");
1566       obstack_1grow (obstackp, '{');
1567     }
1568
1569   if (nextchar != EOF)
1570     {
1571       c = nextchar;
1572       nextchar = EOF;
1573     }
1574   else
1575     c = getch ();
1576   
1577   while (c != EOF)
1578     {
1579       int this_lineno = lineno;
1580
1581       c = skip_white_space (c);
1582
1583       /* Don't lose our cool if there are lots of comments.  */
1584       if (lineno == this_lineno + 1)
1585         obstack_1grow (obstackp, '\n');
1586       else if (lineno == this_lineno)
1587         ;
1588       else if (lineno - this_lineno < 10)
1589         {
1590           int i;
1591           for (i = lineno - this_lineno; i > 0; i--)
1592             obstack_1grow (obstackp, '\n');
1593         }
1594       else
1595         {
1596           char buf[16];
1597           sprintf (buf, "\n# %d \"", lineno);
1598           len = strlen (buf);
1599           obstack_grow (obstackp, buf, len);
1600
1601           len = strlen (input_filename);
1602           obstack_grow (obstackp, input_filename, len);
1603           obstack_1grow (obstackp, '\"');
1604           obstack_1grow (obstackp, '\n');
1605         }
1606
1607       while (c > ' ')           /* ASCII dependent...  */
1608         {
1609           obstack_1grow (obstackp, c);
1610           if (c == '{')
1611             {
1612               look_for_lbrac = 0;
1613               blev++;
1614             }
1615           else if (c == '}')
1616             {
1617               blev--;
1618               if (blev == 0 && !look_for_semicolon)
1619                 {
1620                   if (pyychar == TRY)
1621                     {
1622                       if (peekyylex () == CATCH)
1623                         {
1624                           yylex ();
1625                           obstack_grow (obstackp, " catch ", 7);
1626                           look_for_lbrac = 1;
1627                         }
1628                       else
1629                         {
1630                           yychar = '{';
1631                           goto done;
1632                         }
1633                     }
1634                   else
1635                     {
1636                       goto done;
1637                     }
1638                 }
1639             }
1640           else if (c == '\\')
1641             {
1642               /* Don't act on the next character...e.g, doing an escaped
1643                  double-quote.  */
1644               c = getch ();
1645               if (c == EOF)
1646                 {
1647                   error_with_file_and_line (starting_filename,
1648                                             starting_lineno,
1649                                             "end of file read inside definition");
1650                   goto done;
1651                 }
1652               obstack_1grow (obstackp, c);
1653             }
1654           else if (c == '\"')
1655             consume_string (obstackp, c);
1656           else if (c == '\'')
1657             consume_string (obstackp, c);
1658           else if (c == ';')
1659             {
1660               if (look_for_lbrac)
1661                 {
1662                   error ("function body for constructor missing");
1663                   obstack_1grow (obstackp, '{');
1664                   obstack_1grow (obstackp, '}');
1665                   len += 2;
1666                   goto done;
1667                 }
1668               else if (look_for_semicolon && blev == 0)
1669                 goto done;
1670             }
1671           c = getch ();
1672         }
1673
1674       if (c == EOF)
1675         {
1676           error_with_file_and_line (starting_filename,
1677                                     starting_lineno,
1678                                     "end of file read inside definition");
1679           goto done;
1680         }
1681       else if (c != '\n')
1682         {
1683           obstack_1grow (obstackp, c);
1684           c = getch ();
1685         }
1686     }
1687  done:
1688   obstack_1grow (obstackp, '\0');
1689 }
1690
1691 /* Consume a no-commas expression -- actually, a default argument -- and
1692    save it away on the specified obstack.  */
1693
1694 static void
1695 reinit_parse_for_expr (obstackp)
1696      struct obstack *obstackp;
1697 {
1698   register int c = 0;
1699   int starting_lineno = lineno;
1700   char *starting_filename = input_filename;
1701   int len;
1702   int plev = 0;
1703
1704   if (nextchar != EOF)
1705     {
1706       c = nextchar;
1707       nextchar = EOF;
1708     }
1709   else
1710     c = getch ();
1711   
1712   while (c != EOF)
1713     {
1714       int this_lineno = lineno;
1715
1716       c = skip_white_space (c);
1717
1718       /* Don't lose our cool if there are lots of comments.  */
1719       if (lineno == this_lineno + 1)
1720         obstack_1grow (obstackp, '\n');
1721       else if (lineno == this_lineno)
1722         ;
1723       else if (lineno - this_lineno < 10)
1724         {
1725           int i;
1726           for (i = lineno - this_lineno; i > 0; --i)
1727             obstack_1grow (obstackp, '\n');
1728         }
1729       else
1730         {
1731           char buf[16];
1732           sprintf (buf, "\n# %d \"", lineno);
1733           len = strlen (buf);
1734           obstack_grow (obstackp, buf, len);
1735
1736           len = strlen (input_filename);
1737           obstack_grow (obstackp, input_filename, len);
1738           obstack_1grow (obstackp, '\"');
1739           obstack_1grow (obstackp, '\n');
1740         }
1741
1742       while (c > ' ')           /* ASCII dependent...  */
1743         {
1744           if (plev <= 0 && (c == ')' || c == ','))
1745             {
1746               put_back (c);
1747               goto done;
1748             }
1749           obstack_1grow (obstackp, c);
1750           if (c == '(' || c == '[')
1751             ++plev;
1752           else if (c == ']' || c == ')')
1753             --plev;
1754           else if (c == '\\')
1755             {
1756               /* Don't act on the next character...e.g, doing an escaped
1757                  double-quote.  */
1758               c = getch ();
1759               if (c == EOF)
1760                 {
1761                   error_with_file_and_line (starting_filename,
1762                                             starting_lineno,
1763                                             "end of file read inside definition");
1764                   goto done;
1765                 }
1766               obstack_1grow (obstackp, c);
1767             }
1768           else if (c == '\"')
1769             consume_string (obstackp, c);
1770           else if (c == '\'')
1771             consume_string (obstackp, c);
1772           c = getch ();
1773         }
1774
1775       if (c == EOF)
1776         {
1777           error_with_file_and_line (starting_filename,
1778                                     starting_lineno,
1779                                     "end of file read inside definition");
1780           goto done;
1781         }
1782       else if (c != '\n')
1783         {
1784           obstack_1grow (obstackp, c);
1785           c = getch ();
1786         }
1787     }
1788  done:
1789   obstack_1grow (obstackp, '\0');
1790 }
1791
1792 int do_snarf_defarg;
1793
1794 /* Decide whether the default argument we are about to see should be
1795    gobbled up as text for later parsing.  */
1796
1797 void
1798 maybe_snarf_defarg ()
1799 {
1800   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
1801     do_snarf_defarg = 1;
1802 }
1803
1804 /* When we see a default argument in a method declaration, we snarf it as
1805    text using snarf_defarg.  When we get up to namespace scope, we then go
1806    through and parse all of them using do_pending_defargs.  Since yacc
1807    parsers are not reentrant, we retain defargs state in these two
1808    variables so that subsequent calls to do_pending_defargs can resume
1809    where the previous call left off.  */
1810
1811 tree defarg_fns;
1812 tree defarg_parm;
1813
1814 tree
1815 snarf_defarg ()
1816 {
1817   int len;
1818   char *buf;
1819   tree arg;
1820
1821   reinit_parse_for_expr (&inline_text_obstack);
1822   len = obstack_object_size (&inline_text_obstack);
1823   buf = obstack_finish (&inline_text_obstack);
1824
1825   push_obstacks (&inline_text_obstack, &inline_text_obstack);
1826   arg = make_node (DEFAULT_ARG);
1827   DEFARG_LENGTH (arg) = len - 1;
1828   DEFARG_POINTER (arg) = buf;
1829   pop_obstacks ();
1830
1831   return arg;
1832 }
1833
1834 /* Called from grokfndecl to note a function decl with unparsed default
1835    arguments for later processing.  Also called from grokdeclarator
1836    for function types with unparsed defargs; the call from grokfndecl
1837    will always come second, so we can overwrite the entry from the type.  */
1838
1839 void
1840 add_defarg_fn (decl)
1841      tree decl;
1842 {
1843   if (TREE_CODE (decl) == FUNCTION_DECL)
1844     TREE_VALUE (defarg_fns) = decl;
1845   else
1846     {
1847       push_obstacks (&inline_text_obstack, &inline_text_obstack);
1848       defarg_fns = tree_cons (current_class_type, decl, defarg_fns);  
1849       pop_obstacks ();
1850     }
1851 }
1852
1853 /* Helper for do_pending_defargs.  Starts the parsing of a default arg.  */
1854
1855 static void
1856 feed_defarg (f, p)
1857      tree f, p;
1858 {
1859   tree d = TREE_PURPOSE (p);
1860   feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
1861   if (TREE_CODE (f) == FUNCTION_DECL)
1862     {
1863       lineno = DECL_SOURCE_LINE (f);
1864       input_filename = DECL_SOURCE_FILE (f);
1865     }
1866   yychar = DEFARG_MARKER;
1867   yylval.ttype = p;
1868 }
1869
1870 /* Helper for do_pending_defargs.  Ends the parsing of a default arg.  */
1871
1872 static void
1873 finish_defarg ()
1874 {
1875   if (yychar == YYEMPTY)
1876     yychar = yylex ();
1877   if (yychar != END_OF_SAVED_INPUT)
1878     {
1879       error ("parse error at end of saved function text");
1880
1881       /* restore_pending_input will abort unless yychar is either
1882          END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
1883          hosed, feed back YYEMPTY.  We also need to discard nextchar,
1884          since that may have gotten set as well.  */
1885       nextchar = -1;
1886     }
1887   yychar = YYEMPTY;
1888   end_input ();
1889 }  
1890
1891 /* Main function for deferred parsing of default arguments.  Called from
1892    the parser.  */
1893
1894 void
1895 do_pending_defargs ()
1896 {
1897   if (defarg_parm)
1898     finish_defarg ();
1899
1900   for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
1901     {
1902       tree defarg_fn = TREE_VALUE (defarg_fns);
1903       if (defarg_parm == NULL_TREE)
1904         {
1905           push_nested_class (TREE_PURPOSE (defarg_fns), 1);
1906           pushlevel (0);
1907           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1908             maybe_begin_member_template_processing (defarg_fn);
1909
1910           if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1911             {
1912 #if 0
1913               tree p;
1914               for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
1915                 pushdecl (copy_node (p));
1916 #endif
1917               defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
1918             }
1919           else
1920             defarg_parm = TYPE_ARG_TYPES (defarg_fn);
1921         }
1922       else
1923         defarg_parm = TREE_CHAIN (defarg_parm);
1924
1925       for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
1926         if (TREE_PURPOSE (defarg_parm)
1927             && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG)
1928           {
1929             feed_defarg (defarg_fn, defarg_parm);
1930
1931             /* Return to the parser, which will process this defarg
1932                and call us again.  */
1933             return;
1934           }
1935
1936       if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
1937         {
1938           maybe_end_member_template_processing ();
1939           check_default_args (defarg_fn);
1940         }
1941
1942       poplevel (0, 0, 0);
1943       pop_nested_class (1);
1944     }
1945 }
1946
1947 /* Build a default function named NAME for type TYPE.
1948    KIND says what to build.
1949
1950    When KIND == 0, build default destructor.
1951    When KIND == 1, build virtual destructor.
1952    When KIND == 2, build default constructor.
1953    When KIND == 3, build default X(const X&) constructor.
1954    When KIND == 4, build default X(X&) constructor.
1955    When KIND == 5, build default operator = (const X&).
1956    When KIND == 6, build default operator = (X&).  */
1957
1958 tree
1959 cons_up_default_function (type, full_name, kind)
1960      tree type, full_name;
1961      int kind;
1962 {
1963   extern tree void_list_node;
1964   tree declspecs = NULL_TREE;
1965   tree fn, args = NULL_TREE;
1966   tree argtype;
1967   int retref = 0;
1968   tree name = constructor_name (full_name);
1969
1970   switch (kind)
1971     {
1972       /* Destructors.  */
1973     case 1:
1974       declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
1975       /* Fall through...  */
1976     case 0:
1977       name = build_parse_node (BIT_NOT_EXPR, name);
1978       args = void_list_node;
1979       break;
1980
1981     case 2:
1982       /* Default constructor.  */
1983       args = void_list_node;
1984       break;
1985
1986     case 3:
1987       type = build_type_variant (type, 1, 0);
1988       /* Fall through...  */
1989     case 4:
1990       /* According to ARM $12.8, the default copy ctor will be declared, but
1991          not defined, unless it's needed.  */
1992       argtype = build_reference_type (type);
1993       args = tree_cons (NULL_TREE,
1994                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
1995                                          get_identifier ("_ctor_arg")),
1996                         void_list_node);
1997       break;
1998
1999     case 5:
2000     case 6:
2001       retref = 1;
2002       declspecs = build_decl_list (NULL_TREE, type);
2003
2004       if (kind == 5)
2005         type = build_type_variant (type, 1, 0);
2006
2007       name = ansi_opname [(int) MODIFY_EXPR];
2008
2009       argtype = build_reference_type (type);
2010       args = tree_cons (NULL_TREE,
2011                         build_tree_list (hash_tree_chain (argtype, NULL_TREE),
2012                                          get_identifier ("_ctor_arg")),
2013                         void_list_node);
2014       break;
2015
2016     default:
2017       my_friendly_abort (59);
2018     }
2019
2020   declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
2021                               declspecs);
2022
2023   TREE_PARMLIST (args) = 1;
2024
2025   {
2026     tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
2027     if (retref)
2028       declarator = build_parse_node (ADDR_EXPR, declarator);
2029
2030     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
2031   }
2032   
2033   if (fn == void_type_node)
2034     return fn;
2035
2036   if (kind > 2)
2037     SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
2038
2039 #if 0
2040   if (processing_template_defn)
2041     {
2042       SET_DECL_IMPLICIT_INSTANTIATION (fn);
2043       repo_template_used (fn);
2044     }
2045 #endif
2046
2047 #if 0
2048   if (CLASSTYPE_INTERFACE_KNOWN (type))
2049     {
2050       DECL_INTERFACE_KNOWN (fn) = 1;
2051       DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
2052                                      && flag_implement_inlines);
2053     }
2054   else
2055 #endif
2056     DECL_NOT_REALLY_EXTERN (fn) = 1;
2057
2058   mark_inline_for_output (fn);
2059
2060 #ifdef DEBUG_DEFAULT_FUNCTIONS
2061   { char *fn_type = NULL;
2062     tree t = name;
2063     switch (kind)
2064       {
2065       case 0: fn_type = "default destructor"; break;
2066       case 1: fn_type = "virtual destructor"; break;
2067       case 2: fn_type = "default constructor"; break;
2068       case 3: fn_type = "default X(const X&)"; break;
2069       case 4: fn_type = "default X(X&)"; break;
2070       }
2071     if (fn_type)
2072       {
2073         if (TREE_CODE (name) == BIT_NOT_EXPR)
2074           t = TREE_OPERAND (name, 0);
2075         fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
2076                  IDENTIFIER_POINTER (t), func_buf);
2077       }
2078   }
2079 #endif /* DEBUG_DEFAULT_FUNCTIONS */
2080
2081   /* Show that this function was generated by the compiler.  */
2082   SET_DECL_ARTIFICIAL (fn);
2083   
2084   return fn;
2085 }
2086
2087 /* Heuristic to tell whether the user is missing a semicolon
2088    after a struct or enum declaration.  Emit an error message
2089    if we know the user has blown it.  */
2090
2091 void
2092 check_for_missing_semicolon (type)
2093      tree type;
2094 {
2095   if (yychar < 0)
2096     yychar = yylex ();
2097
2098   if ((yychar > 255
2099        && yychar != SCSPEC
2100        && yychar != IDENTIFIER
2101        && yychar != TYPENAME
2102        && yychar != CV_QUALIFIER
2103        && yychar != SELFNAME)
2104       || end_of_file)
2105     {
2106       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
2107         error ("semicolon missing after %s declaration",
2108                TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
2109       else
2110         cp_error ("semicolon missing after declaration of `%T'", type);
2111       shadow_tag (build_tree_list (0, type));
2112     }
2113   /* Could probably also hack cases where class { ... } f (); appears.  */
2114   clear_anon_tags ();
2115 }
2116
2117 void
2118 note_got_semicolon (type)
2119      tree type;
2120 {
2121   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
2122     my_friendly_abort (60);
2123   if (IS_AGGR_TYPE (type))
2124     CLASSTYPE_GOT_SEMICOLON (type) = 1;
2125 }
2126
2127 void
2128 note_list_got_semicolon (declspecs)
2129      tree declspecs;
2130 {
2131   tree link;
2132
2133   for (link = declspecs; link; link = TREE_CHAIN (link))
2134     {
2135       tree type = TREE_VALUE (link);
2136       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
2137         note_got_semicolon (type);
2138     }
2139   clear_anon_tags ();
2140 }
2141 \f
2142 /* If C is not whitespace, return C.
2143    Otherwise skip whitespace and return first nonwhite char read.  */
2144
2145 static int
2146 skip_white_space (c)
2147      register int c;
2148 {
2149   for (;;)
2150     {
2151       switch (c)
2152         {
2153         case '\n':
2154           c = check_newline ();
2155           break;
2156
2157         case ' ':
2158         case '\t':
2159         case '\f':
2160         case '\r':
2161         case '\v':
2162         case '\b':
2163           do
2164             c = getch ();
2165           while (c == ' ' || c == '\t');
2166           break;
2167
2168         case '\\':
2169           c = getch ();
2170           if (c == '\n')
2171             lineno++;
2172           else
2173             error ("stray '\\' in program");
2174           c = getch ();
2175           break;
2176
2177         default:
2178           return (c);
2179         }
2180     }
2181 }
2182
2183
2184
2185 /* Make the token buffer longer, preserving the data in it.
2186    P should point to just beyond the last valid character in the old buffer.
2187    The value we return is a pointer to the new buffer
2188    at a place corresponding to P.  */
2189
2190 static char *
2191 extend_token_buffer (p)
2192      char *p;
2193 {
2194   int offset = p - token_buffer;
2195
2196   maxtoken = maxtoken * 2 + 10;
2197   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
2198
2199   return token_buffer + offset;
2200 }
2201 \f
2202 static int
2203 get_last_nonwhite_on_line ()
2204 {
2205   register int c;
2206
2207   /* Is this the last nonwhite stuff on the line?  */
2208   if (nextchar >= 0)
2209     c = nextchar, nextchar = -1;
2210   else
2211     c = getch ();
2212
2213   while (c == ' ' || c == '\t')
2214     c = getch ();
2215   return c;
2216 }
2217
2218 #if defined HANDLE_PRAGMA
2219 /* Local versions of these macros, that can be passed as function pointers.  */
2220 static int
2221 pragma_getc ()
2222 {
2223   int c;
2224       
2225   if (nextchar != EOF)
2226     {
2227       c = nextchar;
2228       nextchar = EOF;
2229     }
2230   else
2231     c = getch ();
2232
2233   return c;
2234 }
2235
2236 static void
2237 pragma_ungetc (arg)
2238      int arg;
2239 {
2240   yyungetc (arg, 0);
2241 }
2242 #endif /* HANDLE_PRAGMA */
2243
2244 /* At the beginning of a line, increment the line number
2245    and process any #-directive on this line.
2246    If the line is a #-directive, read the entire line and return a newline.
2247    Otherwise, return the line's first non-whitespace character.  */
2248
2249 int linemode;
2250
2251 static int handle_cp_pragma PROTO((char *));
2252
2253 static int
2254 check_newline ()
2255 {
2256   register int c;
2257   register int token;
2258
2259   /* Read first nonwhite char on the line.  Do this before incrementing the
2260      line number, in case we're at the end of saved text.  */
2261
2262   do
2263     c = getch ();
2264   while (c == ' ' || c == '\t');
2265
2266   lineno++;
2267
2268   if (c != '#')
2269     {
2270       /* If not #, return it so caller will use it.  */
2271       return c;
2272     }
2273
2274   /* Don't read beyond this line.  */
2275   linemode = 1;
2276   
2277   /* Read first nonwhite char after the `#'.  */
2278
2279   do
2280     c = getch ();
2281   while (c == ' ' || c == '\t');
2282
2283   /* If a letter follows, then if the word here is `line', skip
2284      it and ignore it; otherwise, ignore the line, with an error
2285      if the word isn't `pragma'.  */
2286
2287   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
2288     {
2289       if (c == 'p')
2290         {
2291           if (getch () == 'r'
2292               && getch () == 'a'
2293               && getch () == 'g'
2294               && getch () == 'm'
2295               && getch () == 'a')
2296             {
2297               token = real_yylex ();
2298               if (token == IDENTIFIER
2299                   && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
2300                 {
2301                   /* If this is 1, we handled it; if it's -1, it was one we
2302                      wanted but had something wrong with it.  Only if it's
2303                      0 was it not handled.  */
2304                   if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
2305                     goto skipline;
2306                 }
2307               else if (token == END_OF_LINE)
2308                 goto skipline;
2309
2310 #ifdef HANDLE_PRAGMA
2311               /* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA
2312                  (if both are defined), in order to give the back
2313                  end a chance to override the interpretation of
2314                  SYSV style pragmas.  */
2315               if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
2316                                  IDENTIFIER_POINTER (yylval.ttype)))
2317                 goto skipline;
2318 #endif /* HANDLE_PRAGMA */
2319               
2320 #ifdef HANDLE_SYSV_PRAGMA
2321               if (handle_sysv_pragma (token))
2322                 goto skipline;
2323 #endif /* !HANDLE_SYSV_PRAGMA */
2324
2325               /* Issue a warning message if we have been asked to do so.
2326                  Ignoring unknown pragmas in system header file unless
2327                  an explcit -Wunknown-pragmas has been given. */
2328               if (warn_unknown_pragmas > 1
2329                   || (warn_unknown_pragmas && ! in_system_header))
2330                 warning ("ignoring pragma: %s", token_buffer);
2331             }
2332           
2333           goto skipline;
2334         }
2335       else if (c == 'd')
2336         {
2337           if (getch () == 'e'
2338               && getch () == 'f'
2339               && getch () == 'i'
2340               && getch () == 'n'
2341               && getch () == 'e'
2342               && ((c = getch ()) == ' ' || c == '\t'))
2343             {
2344               debug_define (lineno, GET_DIRECTIVE_LINE ());
2345               goto skipline;
2346             }
2347         }
2348       else if (c == 'u')
2349         {
2350           if (getch () == 'n'
2351               && getch () == 'd'
2352               && getch () == 'e'
2353               && getch () == 'f'
2354               && ((c = getch ()) == ' ' || c == '\t'))
2355             {
2356               debug_undef (lineno, GET_DIRECTIVE_LINE ());
2357               goto skipline;
2358             }
2359         }
2360       else if (c == 'l')
2361         {
2362           if (getch () == 'i'
2363               && getch () == 'n'
2364               && getch () == 'e'
2365               && ((c = getch ()) == ' ' || c == '\t'))
2366             goto linenum;
2367         }
2368       else if (c == 'i')
2369         {
2370           if (getch () == 'd'
2371               && getch () == 'e'
2372               && getch () == 'n'
2373               && getch () == 't'
2374               && ((c = getch ()) == ' ' || c == '\t'))
2375             {
2376               /* #ident.  The pedantic warning is now in cccp.c.  */
2377
2378               /* Here we have just seen `#ident '.
2379                  A string constant should follow.  */
2380
2381               token = real_yylex ();
2382               if (token == END_OF_LINE)
2383                 goto skipline;
2384               if (token != STRING
2385                   || TREE_CODE (yylval.ttype) != STRING_CST)
2386                 {
2387                   error ("invalid #ident");
2388                   goto skipline;
2389                 }
2390
2391               if (! flag_no_ident)
2392                 {
2393 #ifdef ASM_OUTPUT_IDENT
2394                   ASM_OUTPUT_IDENT (asm_out_file,
2395                                     TREE_STRING_POINTER (yylval.ttype));
2396 #endif
2397                 }
2398
2399               /* Skip the rest of this line.  */
2400               goto skipline;
2401             }
2402         }
2403       else if (c == 'n')
2404         {
2405           if (getch () == 'e'
2406               && getch () == 'w'
2407               && getch () == 'w'
2408               && getch () == 'o'
2409               && getch () == 'r'
2410               && getch () == 'l'
2411               && getch () == 'd'
2412               && ((c = getch ()) == ' ' || c == '\t'))
2413             {
2414               /* Used to test incremental compilation.  */
2415               sorry ("#pragma newworld");
2416               goto skipline;
2417             }
2418         }
2419       error ("undefined or invalid # directive");
2420       goto skipline;
2421     }
2422
2423 linenum:
2424   /* Here we have either `#line' or `# <nonletter>'.
2425      In either case, it should be a line number; a digit should follow.  */
2426
2427   while (c == ' ' || c == '\t')
2428     c = getch ();
2429
2430   /* If the # is the only nonwhite char on the line,
2431      just ignore it.  Check the new newline.  */
2432   if (c == EOF)
2433     goto skipline;
2434
2435   /* Something follows the #; read a token.  */
2436
2437   put_back (c);
2438   token = real_yylex ();
2439
2440   if (token == CONSTANT
2441       && TREE_CODE (yylval.ttype) == INTEGER_CST)
2442     {
2443       int old_lineno = lineno;
2444       enum { act_none, act_push, act_pop } action = act_none;
2445       int entering_system_header = 0;
2446       int entering_c_header = 0;
2447
2448       /* subtract one, because it is the following line that
2449          gets the specified number */
2450
2451       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2452       c = get_last_nonwhite_on_line ();
2453       if (c == EOF)
2454         {
2455           /* No more: store the line number and check following line.  */
2456           lineno = l;
2457           goto skipline;
2458         }
2459       put_back (c);
2460
2461       /* More follows: it must be a string constant (filename).  */
2462
2463       /* Read the string constant, but don't treat \ as special.  */
2464       ignore_escape_flag = 1;
2465       token = real_yylex ();
2466       ignore_escape_flag = 0;
2467
2468       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2469         {
2470           error ("invalid #line");
2471           goto skipline;
2472         }
2473
2474       /* Changing files again.  This means currently collected time
2475          is charged against header time, and body time starts back
2476          at 0.  */
2477       if (flag_detailed_statistics)
2478         {
2479           int this_time = my_get_run_time ();
2480           tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2481           header_time += this_time - body_time;
2482           TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
2483             += this_time - body_time;
2484           this_filename_time = time_identifier;
2485           body_time = this_time;
2486         }
2487
2488       input_filename
2489         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2490       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2491       lineno = l;
2492       GNU_xref_file (input_filename);
2493       
2494       if (main_input_filename == 0)
2495         {
2496           struct impl_files *ifiles = impl_file_chain;
2497
2498           if (ifiles)
2499             {
2500               while (ifiles->next)
2501                 ifiles = ifiles->next;
2502               ifiles->filename = file_name_nondirectory (input_filename);
2503             }
2504
2505           main_input_filename = input_filename;
2506           if (write_virtuals == 3)
2507             walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2508         }
2509
2510       extract_interface_info ();
2511
2512       c = get_last_nonwhite_on_line ();
2513       if (c == EOF)
2514         {
2515           /* Update the name in the top element of input_file_stack.  */
2516           if (input_file_stack)
2517             input_file_stack->name = input_filename;
2518         }
2519       else
2520         {
2521           put_back (c);
2522
2523           token = real_yylex ();
2524
2525           /* `1' after file name means entering new file.
2526              `2' after file name means just left a file.  */
2527
2528           if (token == CONSTANT
2529               && TREE_CODE (yylval.ttype) == INTEGER_CST)
2530             {
2531               if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2532                 action = act_push;
2533               else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2534                 action = act_pop;
2535
2536               if (action)
2537                 {
2538                   c = get_last_nonwhite_on_line ();
2539                   if (c != EOF)
2540                     {
2541                       put_back (c);
2542                       token = real_yylex ();
2543                     }
2544                 }
2545             }
2546
2547           /* `3' after file name means this is a system header file.  */
2548
2549           if (token == CONSTANT
2550               && TREE_CODE (yylval.ttype) == INTEGER_CST
2551               && TREE_INT_CST_LOW (yylval.ttype) == 3)
2552             {
2553               entering_system_header = 1;
2554
2555               c = get_last_nonwhite_on_line ();
2556               if (c != EOF)
2557                 {
2558                   put_back (c);
2559                   token = real_yylex ();
2560                 }
2561             }
2562
2563           /* `4' after file name means this is a C header file.  */
2564
2565           if (token == CONSTANT
2566               && TREE_CODE (yylval.ttype) == INTEGER_CST
2567               && TREE_INT_CST_LOW (yylval.ttype) == 4)
2568             {
2569               entering_c_header = 1;
2570
2571               c = get_last_nonwhite_on_line ();
2572               if (c != EOF)
2573                 {
2574                   put_back (c);
2575                   token = real_yylex ();
2576                 }
2577             }
2578
2579           /* Do the actions implied by the preceding numbers.  */
2580
2581           if (action == act_push)
2582             {
2583               /* Pushing to a new file.  */
2584               struct file_stack *p;
2585
2586               p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2587               input_file_stack->line = old_lineno;
2588               p->next = input_file_stack;
2589               p->name = input_filename;
2590               input_file_stack = p;
2591               input_file_stack_tick++;
2592               debug_start_source_file (input_filename);
2593               in_system_header = entering_system_header;
2594               if (c_header_level)
2595                 ++c_header_level;
2596               else if (entering_c_header)
2597                 {
2598                   c_header_level = 1;
2599                   ++pending_lang_change;
2600                 }
2601             }
2602           else if (action == act_pop)
2603             {
2604               /* Popping out of a file.  */
2605               if (input_file_stack->next)
2606                 {
2607                   struct file_stack *p;
2608
2609                   if (c_header_level && --c_header_level == 0)
2610                     {
2611                       if (entering_c_header)
2612                         warning ("badly nested C headers from preprocessor");
2613                       --pending_lang_change;
2614                     }
2615                   in_system_header = entering_system_header;
2616
2617                   p = input_file_stack;
2618                   input_file_stack = p->next;
2619                   free (p);
2620                   input_file_stack_tick++;
2621                   debug_end_source_file (input_file_stack->line);
2622                 }
2623               else
2624                 error ("#-lines for entering and leaving files don't match");
2625             }
2626           else
2627             in_system_header = entering_system_header;
2628         }
2629
2630       /* If NEXTCHAR is not end of line, we don't care what it is.  */
2631       if (nextchar == EOF)
2632         c = EOF;
2633     }
2634   else
2635     error ("invalid #-line");
2636
2637   /* skip the rest of this line.  */
2638  skipline:
2639   linemode = 0;
2640   end_of_file = 0;
2641   nextchar = -1;
2642   while ((c = getch ()) != EOF && c != '\n');
2643   return c;
2644 }
2645
2646 void
2647 do_pending_lang_change ()
2648 {
2649   for (; pending_lang_change > 0; --pending_lang_change)
2650     push_lang_context (lang_name_c);
2651   for (; pending_lang_change < 0; ++pending_lang_change)
2652     pop_lang_context ();
2653 }
2654 \f
2655 #define ENDFILE -1  /* token that represents end-of-file */
2656
2657 /* Read an escape sequence, returning its equivalent as a character,
2658    or store 1 in *ignore_ptr if it is backslash-newline.  */
2659
2660 static int
2661 readescape (ignore_ptr)
2662      int *ignore_ptr;
2663 {
2664   register int c = getch ();
2665   register int code;
2666   register unsigned count;
2667   unsigned firstdig = 0;
2668   int nonnull;
2669
2670   switch (c)
2671     {
2672     case 'x':
2673       code = 0;
2674       count = 0;
2675       nonnull = 0;
2676       while (1)
2677         {
2678           c = getch ();
2679           if (! ISXDIGIT (c))
2680             {
2681               put_back (c);
2682               break;
2683             }
2684           code *= 16;
2685           if (c >= 'a' && c <= 'f')
2686             code += c - 'a' + 10;
2687           if (c >= 'A' && c <= 'F')
2688             code += c - 'A' + 10;
2689           if (c >= '0' && c <= '9')
2690             code += c - '0';
2691           if (code != 0 || count != 0)
2692             {
2693               if (count == 0)
2694                 firstdig = code;
2695               count++;
2696             }
2697           nonnull = 1;
2698         }
2699       if (! nonnull)
2700         error ("\\x used with no following hex digits");
2701       else if (count == 0)
2702         /* Digits are all 0's.  Ok.  */
2703         ;
2704       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2705                || (count > 1
2706                    && (((unsigned)1 <<
2707                         (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 >= ((unsigned)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 >= ((unsigned)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 >= (int) 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 */