OSDN Git Service

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