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