OSDN Git Service

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