OSDN Git Service

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