OSDN Git Service

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