]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/lex.c
Remove erroneously-installed change.
[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)
2878 warning ("Badly nested C headers from preprocessor");
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 }
3574 nextchar = c1;
3575 token_buffer[2] = '\0';
3576 value = RANGE;
3577 goto done;
3578 }
3579 if (isdigit (c1))
3580 {
3581 put_back (c1);
3582 goto resume_numerical_scan;
3583 }
3584 nextchar = c1;
3585 value = '.';
3586 token_buffer[1] = 0;
3587 goto done;
3588 }
3589 case '0': case '1':
3590 /* Optimize for most frequent case. */
3591 {
3592 register int c1 = getch ();
3593 if (! isalnum (c1) && c1 != '.')
3594 {
3595 /* Terminate string. */
3596 token_buffer[0] = c;
3597 token_buffer[1] = 0;
3598 if (c == '0')
3599 yylval.ttype = integer_zero_node;
3600 else
3601 yylval.ttype = integer_one_node;
3602 nextchar = c1;
3603 value = CONSTANT;
3604 goto done;
3605 }
3606 put_back (c1);
3607 }
3608 /* fall through... */
3609 case '2': case '3': case '4':
3610 case '5': case '6': case '7': case '8': case '9':
3611 resume_numerical_scan:
3612 {
3613 register char *p;
3614 int base = 10;
3615 int count = 0;
3616 int largest_digit = 0;
3617 int numdigits = 0;
3618 /* for multi-precision arithmetic,
3619 we actually store only HOST_BITS_PER_CHAR bits in each part.
3620 The number of parts is chosen so as to be sufficient to hold
3621 the enough bits to fit into the two HOST_WIDE_INTs that contain
3622 the integer value (this is always at least as many bits as are
3623 in a target `long long' value, but may be wider). */
3624#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
3625 int parts[TOTAL_PARTS];
3626 int overflow = 0;
3627
3628 enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3629 = NOT_FLOAT;
3630
3631 p = token_buffer;
3632 *p++ = c;
3633
3634 for (count = 0; count < TOTAL_PARTS; count++)
3635 parts[count] = 0;
3636
3637 if (c == '0')
3638 {
3639 *p++ = (c = getch ());
3640 if ((c == 'x') || (c == 'X'))
3641 {
3642 base = 16;
3643 *p++ = (c = getch ());
3644 }
3645 /* Leading 0 forces octal unless the 0 is the only digit. */
3646 else if (c >= '0' && c <= '9')
3647 {
3648 base = 8;
3649 numdigits++;
3650 }
3651 else
3652 numdigits++;
3653 }
3654
3655 /* Read all the digits-and-decimal-points. */
3656
3657 while (c == '.'
3658 || (isalnum (c) && (c != 'l') && (c != 'L')
3659 && (c != 'u') && (c != 'U')
3660 && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3661 {
3662 if (c == '.')
3663 {
3664 if (base == 16)
3665 error ("floating constant may not be in radix 16");
3666 if (floatflag == AFTER_POINT)
3667 {
3668 error ("malformed floating constant");
3669 floatflag = TOO_MANY_POINTS;
3670 }
3671 else
3672 floatflag = AFTER_POINT;
3673
3674 base = 10;
3675 *p++ = c = getch ();
3676 /* Accept '.' as the start of a floating-point number
3677 only when it is followed by a digit.
3678 Otherwise, unread the following non-digit
3679 and use the '.' as a structural token. */
3680 if (p == token_buffer + 2 && !isdigit (c))
3681 {
3682 if (c == '.')
3683 {
3684 c = getch ();
3685 if (c == '.')
3686 {
3687 *p++ = '.';
3688 *p = '\0';
3689 value = ELLIPSIS;
3690 goto done;
3691 }
3692 nextchar = c;
3693 token_buffer[2] = '\0';
3694 value = RANGE;
3695 goto done;
3696 }
3697 nextchar = c;
3698 token_buffer[1] = '\0';
3699 value = '.';
3700 goto done;
3701 }
3702 }
3703 else
3704 {
3705 /* It is not a decimal point.
3706 It should be a digit (perhaps a hex digit). */
3707
3708 if (isdigit (c))
3709 {
3710 c = c - '0';
3711 }
3712 else if (base <= 10)
3713 {
3714 if (c == 'e' || c == 'E')
3715 {
3716 base = 10;
3717 floatflag = AFTER_POINT;
3718 break; /* start of exponent */
3719 }
3720 error ("nondigits in number and not hexadecimal");
3721 c = 0;
3722 }
3723 else if (c >= 'a')
3724 {
3725 c = c - 'a' + 10;
3726 }
3727 else
3728 {
3729 c = c - 'A' + 10;
3730 }
3731 if (c >= largest_digit)
3732 largest_digit = c;
3733 numdigits++;
3734
3735 for (count = 0; count < TOTAL_PARTS; count++)
3736 {
3737 parts[count] *= base;
3738 if (count)
3739 {
3740 parts[count]
3741 += (parts[count-1] >> HOST_BITS_PER_CHAR);
3742 parts[count-1]
3743 &= (1 << HOST_BITS_PER_CHAR) - 1;
3744 }
3745 else
3746 parts[0] += c;
3747 }
3748
3749 /* If the extra highest-order part ever gets anything in it,
3750 the number is certainly too big. */
3751 if (parts[TOTAL_PARTS - 1] != 0)
3752 overflow = 1;
3753
3754 if (p >= token_buffer + maxtoken - 3)
3755 p = extend_token_buffer (p);
3756 *p++ = (c = getch ());
3757 }
3758 }
3759
3760 if (numdigits == 0)
3761 error ("numeric constant with no digits");
3762
3763 if (largest_digit >= base)
3764 error ("numeric constant contains digits beyond the radix");
3765
3766 /* Remove terminating char from the token buffer and delimit the string */
3767 *--p = 0;
3768
3769 if (floatflag != NOT_FLOAT)
3770 {
3771 tree type = double_type_node;
3772 char f_seen = 0;
3773 char l_seen = 0;
3774 int garbage_chars = 0;
3775 REAL_VALUE_TYPE value;
3776 jmp_buf handler;
3777
3778 /* Read explicit exponent if any, and put it in tokenbuf. */
3779
3780 if ((c == 'e') || (c == 'E'))
3781 {
3782 if (p >= token_buffer + maxtoken - 3)
3783 p = extend_token_buffer (p);
3784 *p++ = c;
3785 c = getch ();
3786 if ((c == '+') || (c == '-'))
3787 {
3788 *p++ = c;
3789 c = getch ();
3790 }
3791 if (! isdigit (c))
3792 error ("floating constant exponent has no digits");
3793 while (isdigit (c))
3794 {
3795 if (p >= token_buffer + maxtoken - 3)
3796 p = extend_token_buffer (p);
3797 *p++ = c;
3798 c = getch ();
3799 }
3800 }
3801
3802 *p = 0;
3803 errno = 0;
3804
3805 /* Convert string to a double, checking for overflow. */
3806 if (setjmp (handler))
3807 {
3808 error ("floating constant out of range");
3809 value = dconst0;
3810 }
3811 else
3812 {
3813 set_float_handler (handler);
3814 /* The second argument, machine_mode, of REAL_VALUE_ATOF
3815 tells the desired precision of the binary result of
3816 decimal-to-binary conversion. */
3817
3818 /* Read the suffixes to choose a data type. */
3819 switch (c)
3820 {
3821 case 'f': case 'F':
3822 type = float_type_node;
3823 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3824 garbage_chars = -1;
3825 break;
3826
3827 case 'l': case 'L':
3828 type = long_double_type_node;
3829 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3830 garbage_chars = -1;
3831 break;
3832
3833 default:
3834 value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
3835 }
3836 set_float_handler (NULL_PTR);
3837 }
3838 if (pedantic
3839 && (REAL_VALUE_ISINF (value)
3840#ifdef ERANGE
3841 || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3842 && errno == ERANGE
3843 /* ERANGE is also reported for underflow, so test the
3844 value to distinguish overflow from that. */
3845 && (REAL_VALUES_LESS (dconst1, value)
3846 || REAL_VALUES_LESS (value, dconstm1)))
3847#endif
3848 ))
3849 {
3850 pedwarn ("floating point number exceeds range of `%s'",
3851 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
3852 }
3853 /* Note: garbage_chars is -1 if first char is *not* garbage. */
3854 while (isalnum (c))
3855 {
3856 if (c == 'f' || c == 'F')
3857 {
3858 if (f_seen)
3859 error ("two `f's in floating constant");
3860 f_seen = 1;
3861 }
3862 if (c == 'l' || c == 'L')
3863 {
3864 if (l_seen)
3865 error ("two `l's in floating constant");
3866 l_seen = 1;
3867 }
3868 if (p >= token_buffer + maxtoken - 3)
3869 p = extend_token_buffer (p);
3870 *p++ = c;
3871 c = getch ();
3872 garbage_chars++;
3873 }
3874
3875 if (garbage_chars > 0)
3876 error ("garbage at end of number");
3877
3878 /* Create a node with determined type and value. */
3879 yylval.ttype = build_real (type, value);
3880
3881 put_back (c);
3882 *p = 0;
3883 }
3884 else
3885 {
3886 tree type;
3887 HOST_WIDE_INT high, low;
3888 int spec_unsigned = 0;
3889 int spec_long = 0;
3890 int spec_long_long = 0;
3891 int bytes, warn;
3892
3893 while (1)
3894 {
3895 if (c == 'u' || c == 'U')
3896 {
3897 if (spec_unsigned)
3898 error ("two `u's in integer constant");
3899 spec_unsigned = 1;
3900 }
3901 else if (c == 'l' || c == 'L')
3902 {
3903 if (spec_long)
3904 {
3905 if (spec_long_long)
3906 error ("three `l's in integer constant");
3907 else if (pedantic)
3908 pedwarn ("ANSI C++ forbids long long integer constants");
3909 spec_long_long = 1;
3910 }
3911 spec_long = 1;
3912 }
3913 else
3914 {
3915 if (isalnum (c))
3916 {
3917 error ("garbage at end of number");
3918 while (isalnum (c))
3919 {
3920 if (p >= token_buffer + maxtoken - 3)
3921 p = extend_token_buffer (p);
3922 *p++ = c;
3923 c = getch ();
3924 }
3925 }
3926 break;
3927 }
3928 if (p >= token_buffer + maxtoken - 3)
3929 p = extend_token_buffer (p);
3930 *p++ = c;
3931 c = getch ();
3932 }
3933
3934 put_back (c);
3935
3936 /* If the constant is not long long and it won't fit in an
3937 unsigned long, or if the constant is long long and won't fit
3938 in an unsigned long long, then warn that the constant is out
3939 of range. */
3940
3941 /* ??? This assumes that long long and long integer types are
3942 a multiple of 8 bits. This better than the original code
3943 though which assumed that long was exactly 32 bits and long
3944 long was exactly 64 bits. */
3945
3946 if (spec_long_long)
3947 bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
3948 else
3949 bytes = TYPE_PRECISION (long_integer_type_node) / 8;
3950
3951 warn = overflow;
3952 for (i = bytes; i < TOTAL_PARTS; i++)
3953 if (parts[i])
3954 warn = 1;
3955 if (warn)
3956 pedwarn ("integer constant out of range");
3957
3958 /* This is simplified by the fact that our constant
3959 is always positive. */
3960 high = low = 0;
3961
3962 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
3963 {
3964 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
3965 / HOST_BITS_PER_CHAR)]
3966 << (i * HOST_BITS_PER_CHAR));
3967 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
3968 }
3969
3970
3971 yylval.ttype = build_int_2 (low, high);
3972 TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
3973
3974#if 0
3975 /* Find the first allowable type that the value fits in. */
3976 type = 0;
3977 for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
3978 i++)
3979 if (!(spec_long && !type_sequence[i].long_flag)
3980 && !(spec_long_long && !type_sequence[i].long_long_flag)
3981 && !(spec_unsigned && !type_sequence[i].unsigned_flag)
3982 /* A hex or octal constant traditionally is unsigned. */
3983 && !(base != 10 && flag_traditional
3984 && !type_sequence[i].unsigned_flag)
3985 /* A decimal constant can't be unsigned int
3986 unless explicitly specified. */
3987 && !(base == 10 && !spec_unsigned
3988 && *type_sequence[i].node_var == unsigned_type_node))
3989 if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
3990 {
3991 type = *type_sequence[i].node_var;
3992 break;
3993 }
3994 if (flag_traditional && type == long_unsigned_type_node
3995 && !spec_unsigned)
3996 type = long_integer_type_node;
3997
3998 if (type == 0)
3999 {
4000 type = long_long_integer_type_node;
4001 warning ("integer constant out of range");
4002 }
4003
4004 /* Warn about some cases where the type of a given constant
4005 changes from traditional C to ANSI C. */
4006 if (warn_traditional)
4007 {
4008 tree other_type = 0;
4009
4010 /* This computation is the same as the previous one
4011 except that flag_traditional is used backwards. */
4012 for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
4013 i++)
4014 if (!(spec_long && !type_sequence[i].long_flag)
4015 && !(spec_long_long && !type_sequence[i].long_long_flag)
4016 && !(spec_unsigned && !type_sequence[i].unsigned_flag)
4017 /* A hex or octal constant traditionally is unsigned. */
4018 && !(base != 10 && !flag_traditional
4019 && !type_sequence[i].unsigned_flag)
4020 /* A decimal constant can't be unsigned int
4021 unless explicitly specified. */
4022 && !(base == 10 && !spec_unsigned
4023 && *type_sequence[i].node_var == unsigned_type_node))
4024 if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
4025 {
4026 other_type = *type_sequence[i].node_var;
4027 break;
4028 }
4029 if (!flag_traditional && type == long_unsigned_type_node
4030 && !spec_unsigned)
4031 type = long_integer_type_node;
4032
4033 if (other_type != 0 && other_type != type)
4034 {
4035 if (flag_traditional)
4036 warning ("type of integer constant would be different without -traditional");
4037 else
4038 warning ("type of integer constant would be different with -traditional");
4039 }
4040 }
4041
4042#else /* 1 */
4043 if (!spec_long && !spec_unsigned
4044 && !(flag_traditional && base != 10)
4045 && int_fits_type_p (yylval.ttype, integer_type_node))
4046 {
4047#if 0
4048 if (warn_traditional && base != 10)
4049 warning ("small nondecimal constant becomes signed in ANSI C++");
4050#endif
4051 type = integer_type_node;
4052 }
4053 else if (!spec_long && (base != 10 || spec_unsigned)
4054 && int_fits_type_p (yylval.ttype, unsigned_type_node))
4055 {
4056 /* Nondecimal constants try unsigned even in traditional C. */
4057 type = unsigned_type_node;
4058 }
4059
4060 else if (!spec_unsigned && !spec_long_long
4061 && int_fits_type_p (yylval.ttype, long_integer_type_node))
4062 type = long_integer_type_node;
4063
4064 else if (! spec_long_long
4065 && int_fits_type_p (yylval.ttype,
4066 long_unsigned_type_node))
4067 {
4068#if 0
4069 if (warn_traditional && !spec_unsigned)
4070 warning ("large integer constant becomes unsigned in ANSI C++");
4071#endif
4072 if (flag_traditional && !spec_unsigned)
4073 type = long_integer_type_node;
4074 else
4075 type = long_unsigned_type_node;
4076 }
4077
4078 else if (! spec_unsigned
4079 /* Verify value does not overflow into sign bit. */
4080 && TREE_INT_CST_HIGH (yylval.ttype) >= 0
4081 && int_fits_type_p (yylval.ttype,
4082 long_long_integer_type_node))
4083 type = long_long_integer_type_node;
4084
4085 else if (int_fits_type_p (yylval.ttype,
4086 long_long_unsigned_type_node))
4087 {
4088#if 0
4089 if (warn_traditional && !spec_unsigned)
4090 warning ("large nondecimal constant is unsigned in ANSI C++");
4091#endif
4092
4093 if (flag_traditional && !spec_unsigned)
4094 type = long_long_integer_type_node;
4095 else
4096 type = long_long_unsigned_type_node;
4097 }
4098
4099 else
4100 {
4101 type = long_long_integer_type_node;
4102 warning ("integer constant out of range");
4103
4104 if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
4105 warning ("decimal integer constant is so large that it is unsigned");
4106 }
4107#endif
4108
4109 TREE_TYPE (yylval.ttype) = type;
4110 *p = 0;
4111 }
4112
4113 value = CONSTANT; break;
4114 }
4115
4116 case '\'':
4117 char_constant:
4118 {
4119 register int result = 0;
4120 register int num_chars = 0;
4121 unsigned width = TYPE_PRECISION (char_type_node);
4122 int max_chars;
4123
4124 if (wide_flag)
4125 {
4126 width = WCHAR_TYPE_SIZE;
4127#ifdef MULTIBYTE_CHARS
4128 max_chars = MB_CUR_MAX;
4129#else
4130 max_chars = 1;
4131#endif
4132 }
4133 else
4134 max_chars = TYPE_PRECISION (integer_type_node) / width;
4135
4136 while (1)
4137 {
4138 tryagain:
4139
4140 c = getch ();
4141
4142 if (c == '\'' || c == EOF)
4143 break;
4144
4145 if (c == '\\')
4146 {
4147 int ignore = 0;
4148 c = readescape (&ignore);
4149 if (ignore)
4150 goto tryagain;
4151 if (width < HOST_BITS_PER_INT
4152 && (unsigned) c >= (1 << width))
4153 pedwarn ("escape sequence out of range for character");
4154#ifdef MAP_CHARACTER
4155 if (isprint (c))
4156 c = MAP_CHARACTER (c);
4157#endif
4158 }
4159 else if (c == '\n')
4160 {
4161 if (pedantic)
4162 pedwarn ("ANSI C++ forbids newline in character constant");
4163 lineno++;
4164 }
4165#ifdef MAP_CHARACTER
4166 else
4167 c = MAP_CHARACTER (c);
4168#endif
4169
4170 num_chars++;
4171 if (num_chars > maxtoken - 4)
4172 extend_token_buffer (token_buffer);
4173
4174 token_buffer[num_chars] = c;
4175
4176 /* Merge character into result; ignore excess chars. */
4177 if (num_chars < max_chars + 1)
4178 {
4179 if (width < HOST_BITS_PER_INT)
4180 result = (result << width) | (c & ((1 << width) - 1));
4181 else
4182 result = c;
4183 }
4184 }
4185
4186 token_buffer[num_chars + 1] = '\'';
4187 token_buffer[num_chars + 2] = 0;
4188
4189 if (c != '\'')
4190 error ("malformatted character constant");
4191 else if (num_chars == 0)
4192 error ("empty character constant");
4193 else if (num_chars > max_chars)
4194 {
4195 num_chars = max_chars;
4196 error ("character constant too long");
4197 }
4198 else if (num_chars != 1 && ! flag_traditional)
4199 warning ("multi-character character constant");
4200
4201 /* If char type is signed, sign-extend the constant. */
4202 if (! wide_flag)
4203 {
4204 int num_bits = num_chars * width;
4205 if (num_bits == 0)
4206 /* We already got an error; avoid invalid shift. */
4207 yylval.ttype = build_int_2 (0, 0);
4208 else if (TREE_UNSIGNED (char_type_node)
4209 || ((result >> (num_bits - 1)) & 1) == 0)
4210 yylval.ttype
4211 = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
4212 >> (HOST_BITS_PER_INT - num_bits)),
4213 0);
4214 else
4215 yylval.ttype
4216 = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
4217 >> (HOST_BITS_PER_INT - num_bits)),
4218 -1);
4219 if (num_chars<=1)
4220 TREE_TYPE (yylval.ttype) = char_type_node;
4221 else
4222 TREE_TYPE (yylval.ttype) = integer_type_node;
4223 }
4224 else
4225 {
4226#ifdef MULTIBYTE_CHARS
4227 /* Set the initial shift state and convert the next sequence. */
4228 result = 0;
4229 /* In all locales L'\0' is zero and mbtowc will return zero,
4230 so don't use it. */
4231 if (num_chars > 1
4232 || (num_chars == 1 && token_buffer[1] != '\0'))
4233 {
4234 wchar_t wc;
4235 (void) mbtowc (NULL, NULL, 0);
4236 if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
4237 result = wc;
4238 else
4239 warning ("Ignoring invalid multibyte character");
4240 }
4241#endif
4242 yylval.ttype = build_int_2 (result, 0);
4243 TREE_TYPE (yylval.ttype) = wchar_type_node;
4244 }
4245
4246 value = CONSTANT;
4247 break;
4248 }
4249
4250 case '"':
4251 string_constant:
4252 {
4253 register char *p;
4254
4255 c = getch ();
4256 p = token_buffer + 1;
4257
4258 while (c != '"' && c >= 0)
4259 {
4260 /* ignore_escape_flag is set for reading the filename in #line. */
4261 if (!ignore_escape_flag && c == '\\')
4262 {
4263 int ignore = 0;
4264 c = readescape (&ignore);
4265 if (ignore)
4266 goto skipnewline;
4267 if (!wide_flag
4268 && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
4269 && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node)))
4270 pedwarn ("escape sequence out of range for character");
4271 }
4272 else if (c == '\n')
4273 {
4274 if (pedantic)
4275 pedwarn ("ANSI C++ forbids newline in string constant");
4276 lineno++;
4277 }
4278
4279 if (p == token_buffer + maxtoken)
4280 p = extend_token_buffer (p);
4281 *p++ = c;
4282
4283 skipnewline:
4284 c = getch ();
4285 if (c == EOF) {
4286 error("Unterminated string");
4287 break;
4288 }
4289 }
4290 *p = 0;
4291
4292 /* We have read the entire constant.
4293 Construct a STRING_CST for the result. */
4294
4295 if (wide_flag)
4296 {
4297 /* If this is a L"..." wide-string, convert the multibyte string
4298 to a wide character string. */
4299 char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
4300 int len;
4301
4302#ifdef MULTIBYTE_CHARS
4303 len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
4304 if (len < 0 || len >= (p - token_buffer))
4305 {
4306 warning ("Ignoring invalid multibyte string");
4307 len = 0;
4308 }
4309 bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
4310#else
4311 {
4312 union { long l; char c[sizeof (long)]; } u;
4313 int big_endian;
4314 char *wp, *cp;
4315
4316 /* Determine whether host is little or big endian. */
4317 u.l = 1;
4318 big_endian = u.c[sizeof (long) - 1];
4319 wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
4320
4321 bzero (widep, (p - token_buffer) * WCHAR_BYTES);
4322 for (cp = token_buffer + 1; cp < p; cp++)
4323 *wp = *cp, wp += WCHAR_BYTES;
4324 len = p - token_buffer - 1;
4325 }
4326#endif
4327 yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
4328 TREE_TYPE (yylval.ttype) = wchar_array_type_node;
4329 }
4330 else
4331 {
4332 yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
4333 TREE_TYPE (yylval.ttype) = char_array_type_node;
4334 }
4335
4336 *p++ = '"';
4337 *p = 0;
4338
4339 value = STRING; break;
4340 }
4341
4342 case '+':
4343 case '-':
4344 case '&':
4345 case '|':
4346 case '<':
4347 case '>':
4348 case '*':
4349 case '/':
4350 case '%':
4351 case '^':
4352 case '!':
4353 case '=':
4354 {
4355 register int c1;
4356
4357 combine:
4358
4359 switch (c)
4360 {
4361 case '+':
4362 yylval.code = PLUS_EXPR; break;
4363 case '-':
4364 yylval.code = MINUS_EXPR; break;
4365 case '&':
4366 yylval.code = BIT_AND_EXPR; break;
4367 case '|':
4368 yylval.code = BIT_IOR_EXPR; break;
4369 case '*':
4370 yylval.code = MULT_EXPR; break;
4371 case '/':
4372 yylval.code = TRUNC_DIV_EXPR; break;
4373 case '%':
4374 yylval.code = TRUNC_MOD_EXPR; break;
4375 case '^':
4376 yylval.code = BIT_XOR_EXPR; break;
4377 case LSHIFT:
4378 yylval.code = LSHIFT_EXPR; break;
4379 case RSHIFT:
4380 yylval.code = RSHIFT_EXPR; break;
4381 case '<':
4382 yylval.code = LT_EXPR; break;
4383 case '>':
4384 yylval.code = GT_EXPR; break;
4385 }
4386
4387 token_buffer[1] = c1 = getch ();
4388 token_buffer[2] = 0;
4389
4390 if (c1 == '=')
4391 {
4392 switch (c)
4393 {
4394 case '<':
4395 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
4396 case '>':
4397 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
4398 case '!':
4399 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
4400 case '=':
4401 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
4402 }
4403 value = ASSIGN; goto done;
4404 }
4405 else if (c == c1)
4406 switch (c)
4407 {
4408 case '+':
4409 value = PLUSPLUS; goto done;
4410 case '-':
4411 value = MINUSMINUS; goto done;
4412 case '&':
4413 value = ANDAND; goto done;
4414 case '|':
4415 value = OROR; goto done;
4416 case '<':
4417 c = LSHIFT;
4418 goto combine;
4419 case '>':
4420 c = RSHIFT;
4421 goto combine;
4422 }
4423 else if ((c == '-') && (c1 == '>'))
4424 {
4425 nextchar = skip_white_space (getch ());
4426 if (nextchar == '*')
4427 {
4428 nextchar = -1;
4429 value = POINTSAT_STAR;
4430 }
4431 else
4432 value = POINTSAT;
4433 goto done;
4434 }
4435 else if (c1 == '?' && (c == '<' || c == '>'))
4436 {
4437 token_buffer[3] = 0;
4438
4439 c1 = getch ();
4440 yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
4441 if (c1 == '=')
4442 {
4443 /* <?= or >?= expression. */
4444 token_buffer[2] = c1;
4445 value = ASSIGN;
4446 }
4447 else
4448 {
4449 value = MIN_MAX;
4450 nextchar = c1;
4451 }
2986ae00
MS
4452 if (flag_ansi)
4453 pedwarn ("use of `operator %s' is not standard C++",
4454 token_buffer);
8d08fdba
MS
4455 goto done;
4456 }
4457
4458 nextchar = c1;
4459 token_buffer[1] = 0;
4460
4461 value = c;
4462 goto done;
4463 }
4464
4465 case ':':
4466 c = getch ();
4467 if (c == ':')
4468 {
4469 token_buffer[1] = ':';
4470 token_buffer[2] = '\0';
4471 value = SCOPE;
4472 yylval.itype = 1;
4473 }
4474 else
4475 {
4476 nextchar = c;
4477 value = ':';
4478 }
4479 break;
4480
4481 case 0:
4482 /* Don't make yyparse think this is eof. */
4483 value = 1;
4484 break;
4485
4486 case '(':
4487 /* try, weakly, to handle casts to pointers to functions. */
4488 nextchar = skip_white_space (getch ());
4489 if (nextchar == '*')
4490 {
4491 int next_c = skip_white_space (getch ());
4492 if (next_c == ')')
4493 {
4494 nextchar = -1;
4495 yylval.ttype = build1 (INDIRECT_REF, 0, 0);
4496 value = PAREN_STAR_PAREN;
4497 }
4498 else
4499 {
4500 put_back (next_c);
4501 value = c;
4502 }
4503 }
4504 else if (nextchar == ')')
4505 {
4506 nextchar = -1;
4507 yylval.ttype = NULL_TREE;
4508 value = LEFT_RIGHT;
4509 }
4510 else value = c;
4511 break;
4512
4513 default:
4514 value = c;
4515 }
4516
4517done:
4518/* yylloc.last_line = lineno; */
4519#ifdef GATHER_STATISTICS
4520 token_count[value] += 1;
4521#endif
4522
4523 return value;
4524}
4525
4526typedef enum
4527{
4528 d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
4529 id_kind, op_id_kind, perm_list_kind, temp_list_kind,
4530 vec_kind, x_kind, lang_decl, lang_type, all_kinds
4531} tree_node_kind;
4532extern int tree_node_counts[];
4533extern int tree_node_sizes[];
4534extern char *tree_node_kind_names[];
4535
4536/* Place to save freed lang_decls which were allocated on the
4537 permanent_obstack. @@ Not currently used. */
4538tree free_lang_decl_chain;
4539
4540tree
4541build_lang_decl (code, name, type)
4542 enum tree_code code;
4543 tree name;
4544 tree type;
4545{
4546 register tree t = build_decl (code, name, type);
4547 struct obstack *obstack = current_obstack;
4548 register int i = sizeof (struct lang_decl) / sizeof (int);
4549 register int *pi;
4550
4551 if (! TREE_PERMANENT (t))
4552 obstack = saveable_obstack;
4553 else
4554 /* Could be that saveable is permanent and current is not. */
4555 obstack = &permanent_obstack;
4556
4557 if (free_lang_decl_chain && obstack == &permanent_obstack)
4558 {
4559 pi = (int *)free_lang_decl_chain;
4560 free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
4561 }
4562 else
4563 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4564
4565 while (i > 0)
4566 pi[--i] = 0;
4567
4568 DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4569 LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4570 = obstack == &permanent_obstack;
4571 my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
4572 == TREE_PERMANENT (t), 234);
4573 DECL_MAIN_VARIANT (t) = t;
4574 if (current_lang_name == lang_name_cplusplus)
4575 {
4576 DECL_LANGUAGE (t) = lang_cplusplus;
7177d104 4577#if 0
8d08fdba
MS
4578#ifndef NO_AUTO_OVERLOAD
4579 if (code == FUNCTION_DECL && name != 0
4580 && ! (IDENTIFIER_LENGTH (name) == 4
4581 && IDENTIFIER_POINTER (name)[0] == 'm'
4582 && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
4583 && ! (IDENTIFIER_LENGTH (name) > 10
4584 && IDENTIFIER_POINTER (name)[0] == '_'
4585 && IDENTIFIER_POINTER (name)[1] == '_'
4586 && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
4587 TREE_OVERLOADED (name) = 1;
7177d104 4588#endif
8d08fdba
MS
4589#endif
4590 }
4591 else if (current_lang_name == lang_name_c)
4592 DECL_LANGUAGE (t) = lang_c;
4593 else my_friendly_abort (64);
4594
4595#if 0 /* not yet, should get fixed properly later */
4596 if (code == TYPE_DECL)
4597 {
4598 tree id;
4599 id = get_identifier (build_overload_name (type, 1, 1));
4600 DECL_ASSEMBLER_NAME (t) = id;
4601 }
4602
4603#endif
4604#ifdef GATHER_STATISTICS
4605 tree_node_counts[(int)lang_decl] += 1;
4606 tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4607#endif
4608
4609 return t;
4610}
4611
4612tree
4613build_lang_field_decl (code, name, type)
4614 enum tree_code code;
4615 tree name;
4616 tree type;
4617{
4618 extern struct obstack *current_obstack, *saveable_obstack;
4619 register tree t = build_decl (code, name, type);
4620 struct obstack *obstack = current_obstack;
4621 register int i = sizeof (struct lang_decl_flags) / sizeof (int);
4622 register int *pi;
4623#if 0 /* not yet, should get fixed properly later */
4624
4625 if (code == TYPE_DECL)
4626 {
4627 tree id;
4628 id = get_identifier (build_overload_name (type, 1, 1));
4629 DECL_ASSEMBLER_NAME (t) = id;
4630 }
4631#endif
4632
4633 if (! TREE_PERMANENT (t))
4634 obstack = saveable_obstack;
4635 else
4636 my_friendly_assert (obstack == &permanent_obstack, 235);
4637
4638 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
4639 while (i > 0)
4640 pi[--i] = 0;
4641
4642 DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
4643 return t;
4644}
4645
4646void
4647copy_lang_decl (node)
4648 tree node;
4649{
4650 int size;
4651 int *pi;
4652
4653 if (TREE_CODE (node) == FIELD_DECL)
4654 size = sizeof (struct lang_decl_flags);
4655 else
4656 size = sizeof (struct lang_decl);
4657 pi = (int *)obstack_alloc (&permanent_obstack, size);
4658 bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
4659 DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
4660}
4661
4662tree
4663make_lang_type (code)
4664 enum tree_code code;
4665{
4666 extern struct obstack *current_obstack, *saveable_obstack;
4667 register tree t = make_node (code);
4668 struct obstack *obstack = current_obstack;
4669 register int i = sizeof (struct lang_type) / sizeof (int);
4670 register int *pi;
4671
4672 /* Set up some flags that give proper default behavior. */
4673 IS_AGGR_TYPE (t) = 1;
4674
4675 if (! TREE_PERMANENT (t))
4676 obstack = saveable_obstack;
4677 else
4678 my_friendly_assert (obstack == &permanent_obstack, 236);
4679
4680 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
4681 while (i > 0)
4682 pi[--i] = 0;
4683
4684 TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
4685 CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
4686 SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
4687 CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
4688 CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
8926095f
MS
4689 TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
4690 NULL_TREE);
8d08fdba
MS
4691 CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
4692
4693 /* Make sure this is laid out, for ease of use later.
4694 In the presence of parse errors, the normal was of assuring
4695 this might not ever get executed, so we lay it out *immediately*. */
4696 build_pointer_type (t);
4697
4698#ifdef GATHER_STATISTICS
4699 tree_node_counts[(int)lang_type] += 1;
4700 tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
4701#endif
4702
4703 return t;
4704}
4705
4706void
4707copy_decl_lang_specific (decl)
4708 tree decl;
4709{
4710 extern struct obstack *current_obstack, *saveable_obstack;
4711 register int *old = (int *)DECL_LANG_SPECIFIC (decl);
4712 struct obstack *obstack = current_obstack;
4713 register int i = sizeof (struct lang_decl) / sizeof (int);
4714 register int *pi;
4715
4716 if (! TREE_PERMANENT (decl))
4717 obstack = saveable_obstack;
4718 else
4719 my_friendly_assert (obstack == &permanent_obstack, 237);
4720
4721 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
4722 while (i-- > 0)
4723 pi[i] = old[i];
4724
4725 DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
4726
4727#ifdef GATHER_STATISTICS
4728 tree_node_counts[(int)lang_decl] += 1;
4729 tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
4730#endif
4731}
4732
4733void
4734dump_time_statistics ()
4735{
4736 register tree prev = 0, decl, next;
4737 int this_time = my_get_run_time ();
4738 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
4739 += this_time - body_time;
4740
4741 fprintf (stderr, "\n******\n");
4742 print_time ("header files (total)", header_time);
4743 print_time ("main file (total)", this_time - body_time);
4744 fprintf (stderr, "ratio = %g : 1\n",
4745 (double)header_time / (double)(this_time - body_time));
4746 fprintf (stderr, "\n******\n");
4747
4748 for (decl = filename_times; decl; decl = next)
4749 {
4750 next = IDENTIFIER_GLOBAL_VALUE (decl);
4751 IDENTIFIER_GLOBAL_VALUE (decl) = prev;
4752 prev = decl;
4753 }
4754
4755 for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
4756 print_time (IDENTIFIER_POINTER (decl),
4757 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4758}
4759
4760void
4761compiler_error (s, v, v2)
4762 char *s;
4763 HOST_WIDE_INT v, v2; /* @@also used as pointer */
4764{
4765 char buf[1024];
4766 sprintf (buf, s, v, v2);
4767 error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4768}
4769
4770void
4771compiler_error_with_decl (decl, s)
4772 tree decl;
4773 char *s;
4774{
4775 char *name;
4776 count_error (0);
4777
4778 report_error_function (0);
4779
4780 if (TREE_CODE (decl) == PARM_DECL)
4781 fprintf (stderr, "%s:%d: ",
4782 DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
4783 DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
4784 else
4785 fprintf (stderr, "%s:%d: ",
4786 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4787
4788 name = lang_printable_name (decl);
4789 if (name)
4790 fprintf (stderr, s, name);
4791 else
4792 fprintf (stderr, s, "((anonymous))");
4793 fprintf (stderr, " (compiler error)\n");
4794}
4795\f
4796void
4797yyerror (string)
4798 char *string;
4799{
4800 extern int end_of_file;
4801 char buf[200];
4802
4803 strcpy (buf, string);
4804
4805 /* We can't print string and character constants well
4806 because the token_buffer contains the result of processing escapes. */
4807 if (end_of_file)
4808 strcat (buf, input_redirected ()
4809 ? " at end of saved text"
4810 : " at end of input");
4811 else if (token_buffer[0] == 0)
4812 strcat (buf, " at null character");
4813 else if (token_buffer[0] == '"')
4814 strcat (buf, " before string constant");
4815 else if (token_buffer[0] == '\'')
4816 strcat (buf, " before character constant");
4817 else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
4818 sprintf (buf + strlen (buf), " before character 0%o",
4819 (unsigned char) token_buffer[0]);
4820 else
4821 strcat (buf, " before `%s'");
4822
4823 error (buf, token_buffer);
4824}
This page took 0.492153 seconds and 5 git commands to generate.