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