OSDN Git Service

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