OSDN Git Service

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