OSDN Git Service

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