78th 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           tree access = compute_access (TYPE_BINFO (current_class_type), id);
3022           if (access == access_private_node)
3023             cp_error ("enum `%D' is private", id);
3024           /* protected is OK, since it's an enum of `this'.  */
3025         }
3026       id = DECL_INITIAL (id);
3027     }
3028   else
3029     id = hack_identifier (id, token, yychar);
3030   return id;
3031 }
3032
3033 tree
3034 identifier_typedecl_value (node)
3035      tree node;
3036 {
3037   tree t, type;
3038   type = IDENTIFIER_TYPE_VALUE (node);
3039   if (type == NULL_TREE)
3040     return NULL_TREE;
3041 #define do(X) \
3042   { \
3043     t = (X); \
3044     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
3045       return t; \
3046   }
3047   do (IDENTIFIER_LOCAL_VALUE (node));
3048   do (IDENTIFIER_CLASS_VALUE (node));
3049   do (IDENTIFIER_GLOBAL_VALUE (node));
3050 #undef do
3051   /* Will this one ever happen?  */
3052   if (TYPE_NAME (type))
3053     return TYPE_NAME (type);
3054
3055   /* We used to do an internal error of 62 here, but instead we will
3056      handle the return of a null appropriately in the callers.  */
3057   return NULL_TREE;
3058 }
3059
3060 struct try_type
3061 {
3062   tree *node_var;
3063   char unsigned_flag;
3064   char long_flag;
3065   char long_long_flag;
3066 };
3067
3068 struct try_type type_sequence[] = 
3069 {
3070   { &integer_type_node, 0, 0, 0},
3071   { &unsigned_type_node, 1, 0, 0},
3072   { &long_integer_type_node, 0, 1, 0},
3073   { &long_unsigned_type_node, 1, 1, 0},
3074   { &long_long_integer_type_node, 0, 1, 1},
3075   { &long_long_unsigned_type_node, 1, 1, 1}
3076 };
3077
3078 int
3079 real_yylex ()
3080 {
3081   register int c;
3082   register int value;
3083   int wide_flag = 0;
3084   int dollar_seen = 0;
3085   int i;
3086
3087   if (nextchar >= 0)
3088     c = nextchar, nextchar = -1;
3089   else
3090     c = getch ();
3091
3092   /* Effectively do c = skip_white_space (c)
3093      but do it faster in the usual cases.  */
3094   while (1)
3095     switch (c)
3096       {
3097       case ' ':
3098       case '\t':
3099       case '\f':
3100       case '\v':
3101       case '\b':
3102         c = getch ();
3103         break;
3104
3105       case '\r':
3106         /* Call skip_white_space so we can warn if appropriate.  */
3107
3108       case '\n':
3109       case '/':
3110       case '\\':
3111         c = skip_white_space (c);
3112       default:
3113         goto found_nonwhite;
3114       }
3115  found_nonwhite:
3116
3117   token_buffer[0] = c;
3118   token_buffer[1] = 0;
3119
3120 /*  yylloc.first_line = lineno; */
3121
3122   switch (c)
3123     {
3124     case EOF:
3125       token_buffer[0] = '\0';
3126       end_of_file = 1;
3127       if (input_redirected ())
3128         value = END_OF_SAVED_INPUT;
3129       else if (linemode)
3130         value = END_OF_LINE;
3131       else if (do_pending_expansions ())
3132         /* this will set yychar for us */
3133         return yychar;
3134       else
3135         value = ENDFILE;
3136       break;
3137
3138     case '$':
3139       if (dollars_in_ident)
3140         {
3141           dollar_seen = 1;
3142           goto letter;
3143         }
3144       value = '$';
3145       goto done;
3146
3147     case 'L':
3148       /* Capital L may start a wide-string or wide-character constant.  */
3149       {
3150         register int c = getch ();
3151         if (c == '\'')
3152           {
3153             wide_flag = 1;
3154             goto char_constant;
3155           }
3156         if (c == '"')
3157           {
3158             wide_flag = 1;
3159             goto string_constant;
3160           }
3161         put_back (c);
3162       }
3163
3164     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
3165     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
3166     case 'K':             case 'M':  case 'N':  case 'O':
3167     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
3168     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
3169     case 'Z':
3170     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
3171     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
3172     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
3173     case 'p':  case 'q':  case 'r':  case 's':  case 't':
3174     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
3175     case 'z':
3176     case '_':
3177     letter:
3178       {
3179         register char *p;
3180
3181         p = token_buffer;
3182         if (input == 0)
3183           {
3184             /* We know that `token_buffer' can hold at least on char,
3185                so we install C immediately.
3186                We may have to read the value in `putback_char', so call
3187                `getch' once.  */
3188             *p++ = c;
3189             c = getch ();
3190
3191             /* Make this run fast.  We know that we are reading straight
3192                from FINPUT in this case (since identifiers cannot straddle
3193                input sources.  */
3194             while (isalnum (c) || (c == '_') || c == '$')
3195               {
3196                 if (c == '$' && ! dollars_in_ident)
3197                   break;
3198                 if (p >= token_buffer + maxtoken)
3199                   p = extend_token_buffer (p);
3200
3201                 *p++ = c;
3202                 c = getc (finput);
3203               }
3204
3205             if (linemode && c == '\n')
3206               {
3207                 put_back (c);
3208                 c = EOF;
3209               }
3210           }
3211         else
3212           {
3213             /* We know that `token_buffer' can hold at least on char,
3214                so we install C immediately.  */
3215             *p++ = c;
3216             c = getch ();
3217
3218             while (isalnum (c) || (c == '_') || c == '$')
3219               {
3220                 if (c == '$' && ! dollars_in_ident)
3221                   break;
3222                 if (p >= token_buffer + maxtoken)
3223                   p = extend_token_buffer (p);
3224
3225                 *p++ = c;
3226                 c = getch ();
3227               }
3228           }
3229
3230         *p = 0;
3231         nextchar = c;
3232
3233         value = IDENTIFIER;
3234         yylval.itype = 0;
3235
3236       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
3237
3238         {
3239           register struct resword *ptr;
3240
3241           if (ptr = is_reserved_word (token_buffer, p - token_buffer))
3242             {
3243               if (ptr->rid)
3244                 {
3245                   tree old_ttype = ridpointers[(int) ptr->rid];
3246
3247                   /* If this provides a type for us, then revert lexical
3248                      state to standard state.  */
3249                   if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
3250                       && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
3251                       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
3252                     looking_for_typename = 0;
3253                   else if (ptr->token == AGGR || ptr->token == ENUM)
3254                     looking_for_typename = 1;
3255
3256                   /* Check if this is a language-type declaration.
3257                      Just glimpse the next non-white character.  */
3258                   nextchar = skip_white_space (nextchar);
3259                   if (nextchar == '"')
3260                     {
3261                       /* We are looking at a string.  Complain
3262                          if the token before the string is no `extern'.
3263                          
3264                          Could cheat some memory by placing this string
3265                          on the temporary_, instead of the saveable_
3266                          obstack.  */
3267
3268                       if (ptr->rid != RID_EXTERN)
3269                         error ("invalid modifier `%s' for language string",
3270                                ptr->name);
3271                       real_yylex ();
3272                       value = EXTERN_LANG_STRING;
3273                       yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
3274                       break;
3275                     }
3276                   if (ptr->token == VISSPEC)
3277                     {
3278                       switch (ptr->rid)
3279                         {
3280                         case RID_PUBLIC:
3281                           yylval.ttype = access_public_node;
3282                           break;
3283                         case RID_PRIVATE:
3284                           yylval.ttype = access_private_node;
3285                           break;
3286                         case RID_PROTECTED:
3287                           yylval.ttype = access_protected_node;
3288                           break;
3289                         default:
3290                           my_friendly_abort (63);
3291                         }
3292                     }
3293                   else
3294                     yylval.ttype = old_ttype;
3295                 }
3296               else if (ptr->token == EQCOMPARE)
3297                 {
3298                   yylval.code = NE_EXPR;
3299                   token_buffer[0] = '!';
3300                   token_buffer[1] = '=';
3301                   token_buffer[2] = 0;
3302                 }
3303               else if (ptr->token == ASSIGN)
3304                 {
3305                   if (strcmp ("and_eq", token_buffer) == 0)
3306                     {
3307                       yylval.code = BIT_AND_EXPR;
3308                       token_buffer[0] = '&';
3309                     }
3310                   else if (strcmp ("or_eq", token_buffer) == 0)
3311                     {
3312                       yylval.code = BIT_IOR_EXPR;
3313                       token_buffer[0] = '|';
3314                     }
3315                   else if (strcmp ("xor_eq", token_buffer) == 0)
3316                     {
3317                       yylval.code = BIT_XOR_EXPR;
3318                       token_buffer[0] = '^';
3319                     }
3320                   token_buffer[1] = '=';
3321                   token_buffer[2] = 0;
3322                 }
3323               else if (ptr->token == '&')
3324                 {
3325                   yylval.code = BIT_AND_EXPR;
3326                   token_buffer[0] = '&';
3327                   token_buffer[1] = 0;
3328                 }
3329               else if (ptr->token == '|')
3330                 {
3331                   yylval.code = BIT_IOR_EXPR;
3332                   token_buffer[0] = '|';
3333                   token_buffer[1] = 0;
3334                 }
3335               else if (ptr->token == '^')
3336                 {
3337                   yylval.code = BIT_XOR_EXPR;
3338                   token_buffer[0] = '^';
3339                   token_buffer[1] = 0;
3340                 }
3341
3342               value = (int) ptr->token;
3343             }
3344         }
3345
3346         /* If we did not find a keyword, look for an identifier
3347            (or a typename).  */
3348
3349         if (strcmp ("catch", token_buffer) == 0
3350             || strcmp ("throw", token_buffer) == 0
3351             || strcmp ("try", token_buffer) == 0)
3352           {
3353             static int did_warn = 0;
3354             if (! did_warn  && ! flag_handle_exceptions)
3355               {
3356                 pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
3357                 did_warn = 1;
3358               }
3359           }
3360
3361         if (value == IDENTIFIER || value == TYPESPEC)
3362           GNU_xref_ref (current_function_decl, token_buffer);
3363
3364         if (value == IDENTIFIER)
3365           {
3366             register tree tmp = get_identifier (token_buffer);
3367
3368 #if !defined(VMS) && defined(JOINER)
3369             /* Make sure that user does not collide with our internal
3370                naming scheme.  */
3371             if (JOINER == '$'
3372                 && dollar_seen
3373                 && (THIS_NAME_P (tmp)
3374                     || VPTR_NAME_P (tmp)
3375                     || DESTRUCTOR_NAME_P (tmp)
3376                     || VTABLE_NAME_P (tmp)
3377                     || TEMP_NAME_P (tmp)
3378                     || ANON_AGGRNAME_P (tmp)
3379                     || ANON_PARMNAME_P (tmp)))
3380               warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
3381                        token_buffer);
3382 #endif
3383
3384             yylval.ttype = tmp;
3385
3386             /* A user-invisible read-only initialized variable
3387                should be replaced by its value.  We only handle strings
3388                since that's the only case used in C (and C++).  */
3389             /* Note we go right after the local value for the identifier
3390                (e.g., __FUNCTION__ or __PRETTY_FUNCTION__).  We used to
3391                call lookup_name, but that could result in an error about
3392                ambiguities.  */
3393             tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype);
3394             if (tmp != NULL_TREE
3395                 && TREE_CODE (tmp) == VAR_DECL
3396                 && DECL_IGNORED_P (tmp)
3397                 && TREE_READONLY (tmp)
3398                 && DECL_INITIAL (tmp) != NULL_TREE
3399                 && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
3400               {
3401                 yylval.ttype = DECL_INITIAL (tmp);
3402                 value = STRING;
3403               }
3404           }
3405         if (value == NEW && ! global_bindings_p ())
3406           {
3407             value = NEW;
3408             goto done;
3409           }
3410       }
3411       break;
3412
3413     case '.':
3414       {
3415         register int c1 = getch ();
3416         token_buffer[0] = c;
3417         token_buffer[1] = c1;
3418         if (c1 == '*')
3419           {
3420             value = DOT_STAR;
3421             token_buffer[2] = 0;
3422             goto done;
3423           }
3424         if (c1 == '.')
3425           {
3426             c1 = getch ();
3427             if (c1 == '.')
3428               {
3429                 token_buffer[2] = c1;
3430                 token_buffer[3] = 0;
3431                 value = ELLIPSIS;
3432                 goto done;
3433               }
3434             error ("parse error at `..'");
3435           }
3436         if (isdigit (c1))
3437           {
3438             put_back (c1);
3439             goto resume_numerical_scan;
3440           }
3441         nextchar = c1;
3442         value = '.';
3443         token_buffer[1] = 0;
3444         goto done;
3445       }
3446     case '0':  case '1':
3447         /* Optimize for most frequent case.  */
3448       {
3449         register int c1 = getch ();
3450         if (! isalnum (c1) && c1 != '.')
3451           {
3452             /* Terminate string.  */
3453             token_buffer[0] = c;
3454             token_buffer[1] = 0;
3455             if (c == '0')
3456               yylval.ttype = integer_zero_node;
3457             else
3458               yylval.ttype = integer_one_node;
3459             nextchar = c1;
3460             value = CONSTANT;
3461             goto done;
3462           }
3463         put_back (c1);
3464       }
3465       /* fall through... */
3466                           case '2':  case '3':  case '4':
3467     case '5':  case '6':  case '7':  case '8':  case '9':
3468     resume_numerical_scan:
3469       {
3470         register char *p;
3471         int base = 10;
3472         int count = 0;
3473         int largest_digit = 0;
3474         int numdigits = 0;
3475         /* for multi-precision arithmetic,
3476            we actually store only HOST_BITS_PER_CHAR bits in each part.
3477            The number of parts is chosen so as to be sufficient to hold
3478            the enough bits to fit into the two HOST_WIDE_INTs that contain
3479            the integer value (this is always at least as many bits as are
3480            in a target `long long' value, but may be wider).  */
3481 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3482         int parts[TOTAL_PARTS];
3483         int overflow = 0;
3484
3485         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3486           = NOT_FLOAT;
3487
3488         p = token_buffer;
3489         *p++ = c;
3490
3491         for (count = 0; count < TOTAL_PARTS; count++)
3492           parts[count] = 0;
3493
3494         if (c == '0')
3495           {
3496             *p++ = (c = getch ());
3497             if ((c == 'x') || (c == 'X'))
3498               {
3499                 base = 16;
3500                 *p++ = (c = getch ());
3501               }
3502             /* Leading 0 forces octal unless the 0 is the only digit.  */
3503             else if (c >= '0' && c <= '9')
3504               {
3505                 base = 8;
3506                 numdigits++;
3507               }
3508             else
3509               numdigits++;
3510           }
3511
3512         /* Read all the digits-and-decimal-points.  */
3513
3514         while (c == '.'
3515                || (isalnum (c) && (c != 'l') && (c != 'L')
3516                    && (c != 'u') && (c != 'U')
3517                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3518           {
3519             if (c == '.')
3520               {
3521                 if (base == 16)
3522                   error ("floating constant may not be in radix 16");
3523                 if (floatflag == AFTER_POINT)
3524                   {
3525                     error ("malformed floating constant");
3526                     floatflag = TOO_MANY_POINTS;
3527                   }
3528                 else
3529                   floatflag = AFTER_POINT;
3530
3531                 base = 10;
3532                 *p++ = c = getch ();
3533                 /* Accept '.' as the start of a floating-point number
3534                    only when it is followed by a digit.
3535                    Otherwise, unread the following non-digit
3536                    and use the '.' as a structural token.  */
3537                 if (p == token_buffer + 2 && !isdigit (c))
3538                   {
3539                     if (c == '.')
3540                       {
3541                         c = getch ();
3542                         if (c == '.')
3543                           {
3544                             *p++ = '.';
3545                             *p = '\0';
3546                             value = ELLIPSIS;
3547                             goto done;
3548                           }
3549                         error ("parse error at `..'");
3550                       }
3551                     nextchar = c;
3552                     token_buffer[1] = '\0';
3553                     value = '.';
3554                     goto done;
3555                   }
3556               }
3557             else
3558               {
3559                 /* It is not a decimal point.
3560                    It should be a digit (perhaps a hex digit).  */
3561
3562                 if (isdigit (c))
3563                   {
3564                     c = c - '0';
3565                   }
3566                 else if (base <= 10)
3567                   {
3568                     if (c == 'e' || c == 'E')
3569                       {
3570                         base = 10;
3571                         floatflag = AFTER_POINT;
3572                         break;   /* start of exponent */
3573                       }
3574                     error ("nondigits in number and not hexadecimal");
3575                     c = 0;
3576                   }
3577                 else if (c >= 'a')
3578                   {
3579                     c = c - 'a' + 10;
3580                   }
3581                 else
3582                   {
3583                     c = c - 'A' + 10;
3584                   }
3585                 if (c >= largest_digit)
3586                   largest_digit = c;
3587                 numdigits++;
3588
3589                 for (count = 0; count < TOTAL_PARTS; count++)
3590                   {
3591                     parts[count] *= base;
3592                     if (count)
3593                       {
3594                         parts[count]
3595                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
3596                         parts[count-1]
3597                           &= (1 << HOST_BITS_PER_CHAR) - 1;
3598                       }
3599                     else
3600                       parts[0] += c;
3601                   }
3602
3603                 /* If the extra highest-order part ever gets anything in it,
3604                    the number is certainly too big.  */
3605                 if (parts[TOTAL_PARTS - 1] != 0)
3606                   overflow = 1;
3607
3608                 if (p >= token_buffer + maxtoken - 3)
3609                   p = extend_token_buffer (p);
3610                 *p++ = (c = getch ());
3611               }
3612           }
3613
3614         if (numdigits == 0)
3615           error ("numeric constant with no digits");
3616
3617         if (largest_digit >= base)
3618           error ("numeric constant contains digits beyond the radix");
3619
3620         /* Remove terminating char from the token buffer and delimit the string */
3621         *--p = 0;
3622
3623         if (floatflag != NOT_FLOAT)
3624           {
3625             tree type = double_type_node;
3626             char f_seen = 0;
3627             char l_seen = 0;
3628             int garbage_chars = 0;
3629             REAL_VALUE_TYPE value;
3630             jmp_buf handler;
3631
3632             /* Read explicit exponent if any, and put it in tokenbuf.  */
3633
3634             if ((c == 'e') || (c == 'E'))
3635               {
3636                 if (p >= token_buffer + maxtoken - 3)
3637                   p = extend_token_buffer (p);
3638                 *p++ = c;
3639                 c = getch ();
3640                 if ((c == '+') || (c == '-'))
3641                   {
3642                     *p++ = c;
3643                     c = getch ();
3644                   }
3645                 if (! isdigit (c))
3646                   error ("floating constant exponent has no digits");
3647                 while (isdigit (c))
3648                   {
3649                     if (p >= token_buffer + maxtoken - 3)
3650                       p = extend_token_buffer (p);
3651                     *p++ = c;
3652                     c = getch ();
3653                   }
3654               }
3655
3656             *p = 0;
3657             errno = 0;
3658
3659             /* Convert string to a double, checking for overflow.  */
3660             if (setjmp (handler))
3661               {
3662                 error ("floating constant out of range");
3663                 value = dconst0;
3664               }
3665             else
3666               {
3667                 set_float_handler (handler);
3668                 /*  The second argument, machine_mode, of REAL_VALUE_ATOF
3669                     tells the desired precision of the binary result of
3670                     decimal-to-binary conversion. */
3671
3672                 /* Read the suffixes to choose a data type.  */
3673                 switch (c)
3674                   {
3675                   case 'f': case 'F':
3676                     type = float_type_node;
3677                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3678                     garbage_chars = -1;
3679                     break;
3680
3681                   case 'l': case 'L':
3682                     type = long_double_type_node;
3683                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3684                     garbage_chars = -1;
3685                     break;
3686
3687                   default:
3688                     value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3689                   }
3690                 set_float_handler (NULL_PTR);
3691               }
3692             if (pedantic
3693                 && (REAL_VALUE_ISINF (value)
3694 #ifdef ERANGE
3695                     || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3696                         && errno == ERANGE
3697                         /* ERANGE is also reported for underflow, so test the
3698                            value to distinguish overflow from that.  */
3699                         && (REAL_VALUES_LESS (dconst1, value)
3700                             || REAL_VALUES_LESS (value, dconstm1)))
3701 #endif
3702                     ))
3703               {
3704                 pedwarn ("floating point number exceeds range of `%s'",
3705                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
3706               }
3707             /* Note: garbage_chars is -1 if first char is *not* garbage.  */
3708             while (isalnum (c))
3709               {
3710                 if (c == 'f' || c == 'F')
3711                   {
3712                     if (f_seen)
3713                       error ("two `f's in floating constant");
3714                     f_seen = 1;
3715                   }
3716                 if (c == 'l' || c == 'L')
3717                   {
3718                     if (l_seen)
3719                       error ("two `l's in floating constant");
3720                     l_seen = 1;
3721                   }
3722                 if (p >= token_buffer + maxtoken - 3)
3723                   p = extend_token_buffer (p);
3724                 *p++ = c;
3725                 c = getch ();
3726                 garbage_chars++;
3727               }
3728
3729             if (garbage_chars > 0)
3730               error ("garbage at end of number");
3731
3732             /* Create a node with determined type and value.  */
3733             yylval.ttype = build_real (type, value);
3734
3735             put_back (c);
3736             *p = 0;
3737           }
3738         else
3739           {
3740             tree type;
3741             HOST_WIDE_INT high, low;
3742             int spec_unsigned = 0;
3743             int spec_long = 0;
3744             int spec_long_long = 0;
3745             int bytes, warn;
3746
3747             while (1)
3748               {
3749                 if (c == 'u' || c == 'U')
3750                   {
3751                     if (spec_unsigned)
3752                       error ("two `u's in integer constant");
3753                     spec_unsigned = 1;
3754                   }
3755                 else if (c == 'l' || c == 'L')
3756                   {
3757                     if (spec_long)
3758                       {
3759                         if (spec_long_long)
3760                           error ("three `l's in integer constant");
3761                         else if (pedantic)
3762                           pedwarn ("ANSI C++ forbids long long integer constants");
3763                         spec_long_long = 1;
3764                       }
3765                     spec_long = 1;
3766                   }
3767                 else
3768                   {
3769                     if (isalnum (c))
3770                       {
3771                         error ("garbage at end of number");
3772                         while (isalnum (c))
3773                           {
3774                             if (p >= token_buffer + maxtoken - 3)
3775                               p = extend_token_buffer (p);
3776                             *p++ = c;
3777                             c = getch ();
3778                           }
3779                       }
3780                     break;
3781                   }
3782                 if (p >= token_buffer + maxtoken - 3)
3783                   p = extend_token_buffer (p);
3784                 *p++ = c;
3785                 c = getch ();
3786               }
3787
3788             put_back (c);
3789
3790             /* If the constant is not long long and it won't fit in an
3791                unsigned long, or if the constant is long long and won't fit
3792                in an unsigned long long, then warn that the constant is out
3793                of range.  */
3794
3795             /* ??? This assumes that long long and long integer types are
3796                a multiple of 8 bits.  This better than the original code
3797                though which assumed that long was exactly 32 bits and long
3798                long was exactly 64 bits.  */
3799
3800             if (spec_long_long)
3801               bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3802             else
3803               bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3804
3805             warn = overflow;
3806             for (i = bytes; i < TOTAL_PARTS; i++)
3807               if (parts[i])
3808                 warn = 1;
3809             if (warn)
3810               pedwarn ("integer constant out of range");
3811
3812             /* This is simplified by the fact that our constant
3813                is always positive.  */
3814             high = low = 0;
3815
3816             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3817               {
3818                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3819                                                     / HOST_BITS_PER_CHAR)]
3820                          << (i * HOST_BITS_PER_CHAR));
3821                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3822               }
3823             
3824             
3825             yylval.ttype = build_int_2 (low, high);
3826             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3827
3828 #if 0
3829             /* Find the first allowable type that the value fits in.  */
3830             type = 0;
3831             for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
3832                  i++)
3833               if (!(spec_long && !type_sequence[i].long_flag)
3834                   && !(spec_long_long && !type_sequence[i].long_long_flag)
3835                   && !(spec_unsigned && !type_sequence[i].unsigned_flag)
3836                   /* A hex or octal constant traditionally is unsigned.  */
3837                   && !(base != 10 && flag_traditional
3838                        && !type_sequence[i].unsigned_flag)
3839                   /* A decimal constant can't be unsigned int
3840                      unless explicitly specified.  */
3841                   && !(base == 10 && !spec_unsigned
3842                        && *type_sequence[i].node_var == unsigned_type_node))
3843                 if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
3844                   {
3845                     type = *type_sequence[i].node_var;
3846                     break;
3847                   }
3848             if (flag_traditional && type == long_unsigned_type_node
3849                 && !spec_unsigned)
3850               type = long_integer_type_node;
3851               
3852             if (type == 0)
3853               {
3854                 type = long_long_integer_type_node;
3855                 warning ("integer constant out of range");
3856               }
3857
3858             /* Warn about some cases where the type of a given constant
3859                changes from traditional C to ANSI C.  */
3860             if (warn_traditional)
3861               {
3862                 tree other_type = 0;
3863
3864                 /* This computation is the same as the previous one
3865                    except that flag_traditional is used backwards.  */
3866                 for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
3867                      i++)
3868                   if (!(spec_long && !type_sequence[i].long_flag)
3869                       && !(spec_long_long && !type_sequence[i].long_long_flag)
3870                       && !(spec_unsigned && !type_sequence[i].unsigned_flag)
3871                       /* A hex or octal constant traditionally is unsigned.  */
3872                       && !(base != 10 && !flag_traditional
3873                            && !type_sequence[i].unsigned_flag)
3874                       /* A decimal constant can't be unsigned int
3875                          unless explicitly specified.  */
3876                       && !(base == 10 && !spec_unsigned
3877                            && *type_sequence[i].node_var == unsigned_type_node))
3878                     if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
3879                       {
3880                         other_type = *type_sequence[i].node_var;
3881                         break;
3882                       }
3883                 if (!flag_traditional && type == long_unsigned_type_node
3884                     && !spec_unsigned)
3885                   type = long_integer_type_node;
3886               
3887                 if (other_type != 0 && other_type != type)
3888                   {
3889                     if (flag_traditional)
3890                       warning ("type of integer constant would be different without -traditional");
3891                     else
3892                       warning ("type of integer constant would be different with -traditional");
3893                   }
3894               }
3895
3896 #else /* 1 */
3897             if (!spec_long && !spec_unsigned
3898                 && !(flag_traditional && base != 10)
3899                 && int_fits_type_p (yylval.ttype, integer_type_node))
3900               {
3901 #if 0
3902                 if (warn_traditional && base != 10)
3903                   warning ("small nondecimal constant becomes signed in ANSI C++");
3904 #endif
3905                 type = integer_type_node;
3906               }
3907             else if (!spec_long && (base != 10 || spec_unsigned)
3908                      && int_fits_type_p (yylval.ttype, unsigned_type_node))
3909               {
3910                 /* Nondecimal constants try unsigned even in traditional C.  */
3911                 type = unsigned_type_node;
3912               }
3913
3914             else if (!spec_unsigned && !spec_long_long
3915                      && int_fits_type_p (yylval.ttype, long_integer_type_node))
3916               type = long_integer_type_node;
3917
3918             else if (! spec_long_long
3919                      && int_fits_type_p (yylval.ttype,
3920                                          long_unsigned_type_node))
3921               {
3922 #if 0
3923                 if (warn_traditional && !spec_unsigned)
3924                   warning ("large integer constant becomes unsigned in ANSI C++");
3925 #endif
3926                 if (flag_traditional && !spec_unsigned)
3927                   type = long_integer_type_node;
3928                 else
3929                   type = long_unsigned_type_node;
3930               }
3931
3932             else if (! spec_unsigned
3933                      /* Verify value does not overflow into sign bit.  */
3934                      && TREE_INT_CST_HIGH (yylval.ttype) >= 0
3935                      && int_fits_type_p (yylval.ttype,
3936                                          long_long_integer_type_node))
3937               type = long_long_integer_type_node;
3938
3939             else if (int_fits_type_p (yylval.ttype,
3940                                       long_long_unsigned_type_node))
3941               {
3942 #if 0
3943                 if (warn_traditional && !spec_unsigned)
3944                   warning ("large nondecimal constant is unsigned in ANSI C++");
3945 #endif
3946
3947                 if (flag_traditional && !spec_unsigned)
3948                   type = long_long_integer_type_node;
3949                 else
3950                   type = long_long_unsigned_type_node;
3951               }
3952
3953             else
3954               {
3955                 type = long_long_integer_type_node;
3956                 warning ("integer constant out of range");
3957
3958                 if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
3959                   warning ("decimal integer constant is so large that it is unsigned");
3960               }
3961 #endif
3962
3963             TREE_TYPE (yylval.ttype) = type;
3964             *p = 0;
3965           }
3966
3967         value = CONSTANT; break;
3968       }
3969
3970     case '\'':
3971     char_constant:
3972       {
3973         register int result = 0;
3974         register int num_chars = 0;
3975         unsigned width = TYPE_PRECISION (char_type_node);
3976         int max_chars;
3977
3978         if (wide_flag)
3979           {
3980             width = WCHAR_TYPE_SIZE;
3981 #ifdef MULTIBYTE_CHARS
3982             max_chars = MB_CUR_MAX;
3983 #else
3984             max_chars = 1;
3985 #endif
3986           }
3987         else
3988           max_chars = TYPE_PRECISION (integer_type_node) / width;
3989
3990         while (1)
3991           {
3992           tryagain:
3993
3994             c = getch ();
3995
3996             if (c == '\'' || c == EOF)
3997               break;
3998
3999             if (c == '\\')
4000               {
4001                 int ignore = 0;
4002                 c = readescape (&ignore);
4003                 if (ignore)
4004                   goto tryagain;
4005                 if (width < HOST_BITS_PER_INT
4006                     && (unsigned) c >= (1 << width))
4007                   warning ("escape sequence out of range for character");
4008 #ifdef MAP_CHARACTER
4009                 if (isprint (c))
4010                   c = MAP_CHARACTER (c);
4011 #endif
4012               }
4013             else if (c == '\n')
4014               {
4015                 if (pedantic)
4016                   pedwarn ("ANSI C++ forbids newline in character constant");
4017                 lineno++;
4018               }
4019 #ifdef MAP_CHARACTER
4020             else
4021               c = MAP_CHARACTER (c);
4022 #endif
4023
4024             num_chars++;
4025             if (num_chars > maxtoken - 4)
4026               extend_token_buffer (token_buffer);
4027
4028             token_buffer[num_chars] = c;
4029
4030             /* Merge character into result; ignore excess chars.  */
4031             if (num_chars < max_chars + 1)
4032               {
4033                 if (width < HOST_BITS_PER_INT)
4034                   result = (result << width) | (c & ((1 << width) - 1));
4035                 else
4036                   result = c;
4037               }
4038           }
4039
4040         token_buffer[num_chars + 1] = '\'';
4041         token_buffer[num_chars + 2] = 0;
4042
4043         if (c != '\'')
4044           error ("malformatted character constant");
4045         else if (num_chars == 0)
4046           error ("empty character constant");
4047         else if (num_chars > max_chars)
4048           {
4049             num_chars = max_chars;
4050             error ("character constant too long");
4051           }
4052         else if (num_chars != 1 && ! flag_traditional)
4053           warning ("multi-character character constant");
4054
4055         /* If char type is signed, sign-extend the constant.  */
4056         if (! wide_flag)
4057           {
4058             int num_bits = num_chars * width;
4059             if (num_bits == 0)
4060               /* We already got an error; avoid invalid shift.  */
4061               yylval.ttype = build_int_2 (0, 0);
4062             else if (TREE_UNSIGNED (char_type_node)
4063                      || ((result >> (num_bits - 1)) & 1) == 0)
4064               yylval.ttype
4065                 = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
4066                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4067                                0);
4068             else
4069               yylval.ttype
4070                 = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
4071                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
4072                                -1);
4073             if (num_chars<=1)
4074               TREE_TYPE (yylval.ttype) = char_type_node;
4075             else
4076               TREE_TYPE (yylval.ttype) = integer_type_node;
4077           }
4078         else
4079           {
4080 #ifdef MULTIBYTE_CHARS
4081             /* Set the initial shift state and convert the next sequence.  */
4082             result = 0;
4083             /* In all locales L'\0' is zero and mbtowc will return zero,
4084                so don't use it.  */
4085             if (num_chars > 1
4086                 || (num_chars == 1 && token_buffer[1] != '\0'))
4087               {
4088                 wchar_t wc;
4089                 (void) mbtowc (NULL, NULL, 0);
4090                 if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
4091                   result = wc;
4092                 else
4093                   warning ("Ignoring invalid multibyte character");
4094               }
4095 #endif
4096             yylval.ttype = build_int_2 (result, 0);
4097             TREE_TYPE (yylval.ttype) = wchar_type_node;
4098           }
4099
4100         value = CONSTANT;
4101         break;
4102       }
4103
4104     case '"':
4105     string_constant:
4106       {
4107         register char *p;
4108
4109         c = getch ();
4110         p = token_buffer + 1;
4111
4112         while (c != '"' && c >= 0)
4113           {
4114             /* ignore_escape_flag is set for reading the filename in #line.  */
4115             if (!ignore_escape_flag && c == '\\')
4116               {
4117                 int ignore = 0;
4118                 c = readescape (&ignore);
4119                 if (ignore)
4120                   goto skipnewline;
4121                 if (!wide_flag
4122                     && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
4123                     && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node)))
4124                   warning ("escape sequence out of range for character");
4125               }
4126             else if (c == '\n')
4127               {
4128                 if (pedantic)
4129                   pedwarn ("ANSI C++ forbids newline in string constant");
4130                 lineno++;
4131               }
4132
4133             if (p == token_buffer + maxtoken)
4134               p = extend_token_buffer (p);
4135             *p++ = c;
4136
4137           skipnewline:
4138             c = getch ();
4139             if (c == EOF) {
4140                 error("Unterminated string");
4141                 break;
4142             }
4143           }
4144         *p = 0;
4145
4146         /* We have read the entire constant.
4147            Construct a STRING_CST for the result.  */
4148
4149         if (wide_flag)
4150           {
4151             /* If this is a L"..." wide-string, convert the multibyte string
4152                to a wide character string.  */
4153             char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
4154             int len;
4155
4156 #ifdef MULTIBYTE_CHARS
4157             len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
4158             if (len < 0 || len >= (p - token_buffer))
4159               {
4160                 warning ("Ignoring invalid multibyte string");
4161                 len = 0;
4162               }
4163             bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
4164 #else
4165             {
4166               union { long l; char c[sizeof (long)]; } u;
4167               int big_endian;
4168               char *wp, *cp;
4169
4170               /* Determine whether host is little or big endian.  */
4171               u.l = 1;
4172               big_endian = u.c[sizeof (long) - 1];
4173               wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
4174
4175               bzero (widep, (p - token_buffer) * WCHAR_BYTES);
4176               for (cp = token_buffer + 1; cp < p; cp++)
4177                 *wp = *cp, wp += WCHAR_BYTES;
4178               len = p - token_buffer - 1;
4179             }
4180 #endif
4181             yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
4182             TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4183           }
4184         else
4185           {
4186             yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
4187             TREE_TYPE (yylval.ttype) = char_array_type_node;
4188           }
4189
4190         *p++ = '"';
4191         *p = 0;
4192
4193         value = STRING; break;
4194       }
4195
4196     case '+':
4197     case '-':
4198     case '&':
4199     case '|':
4200     case '<':
4201     case '>':
4202     case '*':
4203     case '/':
4204     case '%':
4205     case '^':
4206     case '!':
4207     case '=':
4208       {
4209         register int c1;
4210
4211       combine:
4212
4213         switch (c)
4214           {
4215           case '+':
4216             yylval.code = PLUS_EXPR; break;
4217           case '-':
4218             yylval.code = MINUS_EXPR; break;
4219           case '&':
4220             yylval.code = BIT_AND_EXPR; break;
4221           case '|':
4222             yylval.code = BIT_IOR_EXPR; break;
4223           case '*':
4224             yylval.code = MULT_EXPR; break;
4225           case '/':
4226             yylval.code = TRUNC_DIV_EXPR; break;
4227           case '%':
4228             yylval.code = TRUNC_MOD_EXPR; break;
4229           case '^':
4230             yylval.code = BIT_XOR_EXPR; break;
4231           case LSHIFT:
4232             yylval.code = LSHIFT_EXPR; break;
4233           case RSHIFT:
4234             yylval.code = RSHIFT_EXPR; break;
4235           case '<':
4236             yylval.code = LT_EXPR; break;
4237           case '>':
4238             yylval.code = GT_EXPR; break;
4239           }
4240
4241         token_buffer[1] = c1 = getch ();
4242         token_buffer[2] = 0;
4243
4244         if (c1 == '=')
4245           {
4246             switch (c)
4247               {
4248               case '<':
4249                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4250               case '>':
4251                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4252               case '!':
4253                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4254               case '=':
4255                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4256               }
4257             value = ASSIGN; goto done;
4258           }
4259         else if (c == c1)
4260           switch (c)
4261             {
4262             case '+':
4263               value = PLUSPLUS; goto done;
4264             case '-':
4265               value = MINUSMINUS; goto done;
4266             case '&':
4267               value = ANDAND; goto done;
4268             case '|':
4269               value = OROR; goto done;
4270             case '<':
4271               c = LSHIFT;
4272               goto combine;
4273             case '>':
4274               c = RSHIFT;
4275               goto combine;
4276             }
4277         else if ((c == '-') && (c1 == '>'))
4278           {
4279             nextchar = getch ();
4280             if (nextchar == '*')
4281               {
4282                 nextchar = -1;
4283                 value = POINTSAT_STAR;
4284               }
4285             else
4286               value = POINTSAT;
4287             goto done;
4288           }
4289         else if (c1 == '?' && (c == '<' || c == '>'))
4290           {
4291             token_buffer[3] = 0;
4292
4293             c1 = getch ();
4294             yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4295             if (c1 == '=')
4296               {
4297                 /* <?= or >?= expression.  */
4298                 token_buffer[2] = c1;
4299                 value = ASSIGN;
4300               }
4301             else
4302               {
4303                 value = MIN_MAX;
4304                 nextchar = c1;
4305               }
4306             if (pedantic)
4307               pedwarn ("use of `operator %s' is not standard C++",
4308                        token_buffer);
4309             goto done;
4310           }
4311         /* digraphs */
4312         else if (c == '<' && c1 == '%')
4313           { value = '{'; goto done; }
4314         else if (c == '<' && c1 == ':')
4315           { value = '['; goto done; }
4316         else if (c == '%' && c1 == '>')
4317           { value = '}'; goto done; }
4318         else if (c == '%' && c1 == ':')
4319           { value = '#'; goto done; }
4320
4321         nextchar = c1;
4322         token_buffer[1] = 0;
4323
4324         value = c;
4325         goto done;
4326       }
4327
4328     case ':':
4329       c = getch ();
4330       if (c == ':')
4331         {
4332           token_buffer[1] = ':';
4333           token_buffer[2] = '\0';
4334           value = SCOPE;
4335           yylval.itype = 1;
4336         }
4337       else if (c == '>')
4338         {
4339           value = ']';
4340           goto done;
4341         }
4342       else
4343         {
4344           nextchar = c;
4345           value = ':';
4346         }
4347       break;
4348
4349     case 0:
4350       /* Don't make yyparse think this is eof.  */
4351       value = 1;
4352       break;
4353
4354     case '(':
4355       /* try, weakly, to handle casts to pointers to functions.  */
4356       nextchar = skip_white_space (getch ());
4357       if (nextchar == '*')
4358         {
4359           int next_c = skip_white_space (getch ());
4360           if (next_c == ')')
4361             {
4362               nextchar = -1;
4363               yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4364               value = PAREN_STAR_PAREN;
4365             }
4366           else
4367             {
4368               put_back (next_c);
4369               value = c;
4370             }
4371         }
4372       else if (nextchar == ')')
4373         {
4374           nextchar = -1;
4375           yylval.ttype = NULL_TREE;
4376           value = LEFT_RIGHT;
4377         }
4378       else value = c;
4379       break;
4380
4381     default:
4382       value = c;
4383     }
4384
4385 done:
4386 /*  yylloc.last_line = lineno; */
4387 #ifdef GATHER_STATISTICS
4388 #ifdef REDUCE_LENGTH
4389   token_count[value] += 1;
4390 #endif
4391 #endif
4392
4393   return value;
4394 }
4395
4396 int
4397 is_rid (t)
4398      tree t;
4399 {
4400   return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
4401 }
4402
4403 typedef enum
4404 {
4405   d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
4406   id_kind, op_id_kind, perm_list_kind, temp_list_kind,
4407   vec_kind, x_kind, lang_decl, lang_type, all_kinds
4408 } tree_node_kind;
4409 extern int tree_node_counts[];
4410 extern int tree_node_sizes[];
4411 extern char *tree_node_kind_names[];
4412
4413 /* Place to save freed lang_decls which were allocated on the
4414    permanent_obstack.  @@ Not currently used.  */
4415 tree free_lang_decl_chain;
4416
4417 tree
4418 build_lang_decl (code, name, type)
4419      enum tree_code code;
4420      tree name;
4421      tree type;
4422 {
4423   register tree t = build_decl (code, name, type);
4424   struct obstack *obstack = current_obstack;
4425   register int i = sizeof (struct lang_decl) / sizeof (int);
4426   register int *pi;
4427
4428   if (! TREE_PERMANENT (t))
4429     obstack = saveable_obstack;
4430   else
4431     /* Could be that saveable is permanent and current is not.  */
4432     obstack = &permanent_obstack;
4433
4434   if (free_lang_decl_chain && obstack == &permanent_obstack)
4435     {
4436       pi = (int *)free_lang_decl_chain;
4437       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4438     }
4439   else
4440     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4441
4442   while (i > 0)
4443     pi[--i] = 0;
4444
4445   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4446   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4447     = obstack == &permanent_obstack;
4448   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4449           == TREE_PERMANENT  (t), 234);
4450   DECL_MAIN_VARIANT (t) = t;
4451   if (current_lang_name == lang_name_cplusplus)
4452     {
4453       DECL_LANGUAGE (t) = lang_cplusplus;
4454 #if 0
4455 #ifndef NO_AUTO_OVERLOAD
4456       if (code == FUNCTION_DECL && name != 0
4457           && ! (IDENTIFIER_LENGTH (name) == 4
4458                 && IDENTIFIER_POINTER (name)[0] == 'm'
4459                 && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
4460           && ! (IDENTIFIER_LENGTH (name) > 10
4461                 && IDENTIFIER_POINTER (name)[0] == '_'
4462                 && IDENTIFIER_POINTER (name)[1] == '_'
4463                 && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
4464         TREE_OVERLOADED (name) = 1;
4465 #endif
4466 #endif
4467     }
4468   else if (current_lang_name == lang_name_c)
4469     DECL_LANGUAGE (t) = lang_c;
4470   else my_friendly_abort (64);
4471
4472 #if 0 /* not yet, should get fixed properly later */
4473   if (code == TYPE_DECL)
4474     {
4475       tree id;
4476       id = get_identifier (build_overload_name (type, 1, 1));
4477       DECL_ASSEMBLER_NAME (t) = id;
4478     }
4479
4480 #endif
4481 #ifdef GATHER_STATISTICS
4482   tree_node_counts[(int)lang_decl] += 1;
4483   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4484 #endif
4485
4486   return t;
4487 }
4488
4489 tree
4490 build_lang_field_decl (code, name, type)
4491      enum tree_code code;
4492      tree name;
4493      tree type;
4494 {
4495   extern struct obstack *current_obstack, *saveable_obstack;
4496   register tree t = build_decl (code, name, type);
4497   struct obstack *obstack = current_obstack;
4498   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4499   register int *pi;
4500 #if 0 /* not yet, should get fixed properly later */
4501
4502   if (code == TYPE_DECL)
4503     {
4504       tree id;
4505       id = get_identifier (build_overload_name (type, 1, 1));
4506       DECL_ASSEMBLER_NAME (t) = id;
4507     }
4508 #endif
4509
4510   if (! TREE_PERMANENT (t))
4511     obstack = saveable_obstack;
4512   else
4513     my_friendly_assert (obstack == &permanent_obstack, 235);
4514
4515   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4516   while (i > 0)
4517     pi[--i] = 0;
4518
4519   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4520   return t;
4521 }
4522
4523 void
4524 copy_lang_decl (node)
4525      tree node;
4526 {
4527   int size;
4528   int *pi;
4529
4530   if (TREE_CODE (node) == FIELD_DECL)
4531     size = sizeof (struct lang_decl_flags);
4532   else
4533     size = sizeof (struct lang_decl);
4534   pi = (int *)obstack_alloc (&permanent_obstack, size);
4535   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4536   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4537 }
4538
4539 tree
4540 make_lang_type (code)
4541      enum tree_code code;
4542 {
4543   extern struct obstack *current_obstack, *saveable_obstack;
4544   register tree t = make_node (code);
4545   struct obstack *obstack = current_obstack;
4546   register int i = sizeof (struct lang_type) / sizeof (int);
4547   register int *pi;
4548
4549   /* Set up some flags that give proper default behavior.  */
4550   IS_AGGR_TYPE (t) = 1;
4551
4552   if (! TREE_PERMANENT (t))
4553     obstack = saveable_obstack;
4554   else
4555     my_friendly_assert (obstack == &permanent_obstack, 236);
4556
4557   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
4558   while (i > 0)
4559     pi[--i] = 0;
4560
4561   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
4562   CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
4563   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4564   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4565   CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
4566   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
4567                                NULL_TREE);
4568   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4569
4570   /* Make sure this is laid out, for ease of use later.
4571      In the presence of parse errors, the normal was of assuring
4572      this might not ever get executed, so we lay it out *immediately*.  */
4573   build_pointer_type (t);
4574
4575 #ifdef GATHER_STATISTICS
4576   tree_node_counts[(int)lang_type] += 1;
4577   tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
4578 #endif
4579
4580   return t;
4581 }
4582
4583 void
4584 copy_decl_lang_specific (decl)
4585      tree decl;
4586 {
4587   extern struct obstack *current_obstack, *saveable_obstack;
4588   register int *old = (int *)DECL_LANG_SPECIFIC (decl);
4589   struct obstack *obstack = current_obstack;
4590   register int i = sizeof (struct lang_decl) / sizeof (int);
4591   register int *pi;
4592
4593   if (! TREE_PERMANENT (decl))
4594     obstack = saveable_obstack;
4595   else
4596     my_friendly_assert (obstack == &permanent_obstack, 237);
4597
4598   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4599   while (i-- > 0)
4600     pi[i] = old[i];
4601
4602   DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
4603
4604 #ifdef GATHER_STATISTICS
4605   tree_node_counts[(int)lang_decl] += 1;
4606   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4607 #endif
4608 }
4609
4610 void
4611 dump_time_statistics ()
4612 {
4613   register tree prev = 0, decl, next;
4614   int this_time = my_get_run_time ();
4615   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
4616     += this_time - body_time;
4617
4618   fprintf (stderr, "\n******\n");
4619   print_time ("header files (total)", header_time);
4620   print_time ("main file (total)", this_time - body_time);
4621   fprintf (stderr, "ratio = %g : 1\n",
4622            (double)header_time / (double)(this_time - body_time));
4623   fprintf (stderr, "\n******\n");
4624
4625   for (decl = filename_times; decl; decl = next)
4626     {
4627       next = IDENTIFIER_GLOBAL_VALUE (decl);
4628       IDENTIFIER_GLOBAL_VALUE (decl) = prev;
4629       prev = decl;
4630     }
4631
4632   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4633     print_time (IDENTIFIER_POINTER (decl),
4634                 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4635 }
4636
4637 void
4638 compiler_error (s, v, v2)
4639      char *s;
4640      HOST_WIDE_INT v, v2;                       /* @@also used as pointer */
4641 {
4642   char buf[1024];
4643   sprintf (buf, s, v, v2);
4644   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4645 }
4646
4647 void
4648 compiler_error_with_decl (decl, s)
4649      tree decl;
4650      char *s;
4651 {
4652   char *name;
4653   count_error (0);
4654
4655   report_error_function (0);
4656
4657   if (TREE_CODE (decl) == PARM_DECL)
4658     fprintf (stderr, "%s:%d: ",
4659              DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
4660              DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
4661   else
4662     fprintf (stderr, "%s:%d: ",
4663              DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4664
4665   name = lang_printable_name (decl);
4666   if (name)
4667     fprintf (stderr, s, name);
4668   else
4669     fprintf (stderr, s, "((anonymous))");
4670   fprintf (stderr, " (compiler error)\n");
4671 }
4672 \f
4673 void
4674 yyerror (string)
4675      char *string;
4676 {
4677   extern int end_of_file;
4678   char buf[200];
4679
4680   strcpy (buf, string);
4681
4682   /* We can't print string and character constants well
4683      because the token_buffer contains the result of processing escapes.  */
4684   if (end_of_file)
4685     strcat (buf, input_redirected ()
4686             ? " at end of saved text"
4687             : " at end of input");
4688   else if (token_buffer[0] == 0)
4689     strcat (buf, " at null character");
4690   else if (token_buffer[0] == '"')
4691     strcat (buf, " before string constant");
4692   else if (token_buffer[0] == '\'')
4693     strcat (buf, " before character constant");
4694   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
4695     sprintf (buf + strlen (buf), " before character 0%o",
4696              (unsigned char) token_buffer[0]);
4697   else
4698     strcat (buf, " before `%s'");
4699
4700   error (buf, token_buffer);
4701 }
4702 \f
4703 #ifdef HANDLE_SYSV_PRAGMA
4704
4705 /* Handle a #pragma directive.  INPUT is the current input stream,
4706    and C is a character to reread.  Processes the entire input line
4707    and returns a character for the caller to reread: either \n or EOF.  */
4708
4709 /* This function has to be in this file, in order to get at
4710    the token types.  */
4711
4712 handle_sysv_pragma ()
4713 {
4714   for (;;)
4715     {
4716       switch (yylex ())
4717         {
4718         case IDENTIFIER:
4719         case TYPENAME:
4720         case STRING:
4721         case CONSTANT:
4722           handle_pragma_token ("ignored", yylval.ttype);
4723           break;
4724         case '(':
4725           handle_pragma_token ("(", NULL_TREE);
4726           break;
4727         case ')':
4728           handle_pragma_token (")", NULL_TREE);
4729           break;
4730         case ',':
4731           handle_pragma_token (",", NULL_TREE);
4732           break;
4733         case '=':
4734           handle_pragma_token ("=", NULL_TREE);
4735           break;
4736         case LEFT_RIGHT:
4737           handle_pragma_token ("(", NULL_TREE);
4738           handle_pragma_token (")", NULL_TREE);
4739           break;
4740         case END_OF_LINE:
4741           handle_pragma_token (NULL_PTR, NULL_TREE);
4742           return;
4743         default:
4744           handle_pragma_token (NULL_PTR, NULL_TREE);
4745           while (yylex () != END_OF_LINE)
4746             /* continue */;
4747           return;
4748         }
4749     }
4750 }
4751 #endif /* HANDLE_SYSV_PRAGMA */