OSDN Git Service

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