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