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