OSDN Git Service

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