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