OSDN Git Service

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