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