OSDN Git Service

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