OSDN Git Service

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