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