OSDN Git Service

91th Cygnus<->FSF merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / lex.c
index d59932d..befb5a1 100644 (file)
@@ -33,8 +33,8 @@ Boston, MA 02111-1307, USA.  */
 #include "input.h"
 #include "tree.h"
 #include "lex.h"
-#include "parse.h"
 #include "cp-tree.h"
+#include "parse.h"
 #include "flags.h"
 #include "obstack.h"
 #include "c-pragma.h"
@@ -131,35 +131,35 @@ extern int *token_count;
 \f
 /* Return something to represent absolute declarators containing a *.
    TARGET is the absolute declarator that the * contains.
-   TYPE_QUALS is a list of modifiers such as const or volatile
+   CV_QUALIFIERS is a list of modifiers such as const or volatile
    to apply to the pointer type, represented as identifiers.
 
    We return an INDIRECT_REF whose "contents" are TARGET
    and whose type is the modifier list.  */
 
 tree
-make_pointer_declarator (type_quals, target)
-     tree type_quals, target;
+make_pointer_declarator (cv_qualifiers, target)
+     tree cv_qualifiers, target;
 {
   if (target && TREE_CODE (target) == IDENTIFIER_NODE
       && ANON_AGGRNAME_P (target))
     error ("type name expected before `*'");
   target = build_parse_node (INDIRECT_REF, target);
-  TREE_TYPE (target) = type_quals;
+  TREE_TYPE (target) = cv_qualifiers;
   return target;
 }
 
 /* Return something to represent absolute declarators containing a &.
    TARGET is the absolute declarator that the & contains.
-   TYPE_QUALS is a list of modifiers such as const or volatile
+   CV_QUALIFIERS is a list of modifiers such as const or volatile
    to apply to the reference type, represented as identifiers.
 
    We return an ADDR_EXPR whose "contents" are TARGET
    and whose type is the modifier list.  */
    
 tree
-make_reference_declarator (type_quals, target)
-     tree type_quals, target;
+make_reference_declarator (cv_qualifiers, target)
+     tree cv_qualifiers, target;
 {
   if (target)
     {
@@ -177,9 +177,26 @@ make_reference_declarator (type_quals, target)
          error ("type name expected before `&'");
     }
   target = build_parse_node (ADDR_EXPR, target);
-  TREE_TYPE (target) = type_quals;
+  TREE_TYPE (target) = cv_qualifiers;
+  return target;
+}
+
+tree
+make_call_declarator (target, parms, cv_qualifiers, exception_specification)
+     tree target, parms, cv_qualifiers, exception_specification;
+{
+  target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
+  TREE_TYPE (target) = exception_specification;
   return target;
 }
+
+void
+set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
+     tree call_declarator, cv_qualifiers, exception_specification;
+{
+  TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
+  TREE_TYPE (call_declarator) = exception_specification;
+}
 \f
 /* Build names and nodes for overloaded operators.  */
 
@@ -254,7 +271,7 @@ char *token_buffer;         /* Pointer to token buffer.
 
 #include "hash.h"
 \f
-int check_newline ();
+static int check_newline ();
 
 /* Nonzero tells yylex to ignore \ in string constants.  */
 static int ignore_escape_flag = 0;
@@ -301,13 +318,13 @@ my_get_run_time ()
 \f
 /* Table indexed by tree code giving a string containing a character
    classifying the tree code.  Possibilities are
-   t, d, s, c, r, <, 1 and 2.  See cp/tree.def for details.  */
+   t, d, s, c, r, <, 1 and 2.  See cp/cp-tree.def for details.  */
 
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
 
 char *cplus_tree_code_type[] = {
   "x",
-#include "tree.def"
+#include "cp-tree.def"
 };
 #undef DEFTREECODE
 
@@ -319,7 +336,7 @@ char *cplus_tree_code_type[] = {
 
 int cplus_tree_code_length[] = {
   0,
-#include "tree.def"
+#include "cp-tree.def"
 };
 #undef DEFTREECODE
 
@@ -329,7 +346,7 @@ int cplus_tree_code_length[] = {
 
 char *cplus_tree_code_name[] = {
   "@@dummy",
-#include "tree.def"
+#include "cp-tree.def"
 };
 #undef DEFTREECODE
 \f
@@ -374,12 +391,15 @@ init_filename_times ()
 /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
    Stuck this hack in to get the files open correctly; this is called
    in place of init_lex if we are an unexec'd binary.    */
+
+#if 0
 void
 reinit_lang_specific ()
 {
   init_filename_times ();
   reinit_search_statistics ();
 }
+#endif
 
 int *init_parse ();
 
@@ -620,7 +640,7 @@ init_lex ()
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
 
-  /* C++ extensions. These are probably not correctly named. */
+  /* C++ extensions. These are probably not correctly named.  */
   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
@@ -662,7 +682,7 @@ init_lex ()
   ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
-  /* This is for ANSI C++. */
+  /* This is for ANSI C++.  */
   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
@@ -672,17 +692,20 @@ init_lex ()
   TREE_TYPE (signature_type_node) = signature_type_node;
   ridpointers[(int) RID_SIGNATURE] = signature_type_node;
 
+  null_node = build_int_2 (0, 0);
+  ridpointers[RID_NULL] = null_node;
+
   opname_tab[(int) COMPONENT_REF] = "->";
   opname_tab[(int) MEMBER_REF] = "->*";
   opname_tab[(int) METHOD_CALL_EXPR] = "->()";
-  opname_tab[(int) INDIRECT_REF] = "(unary *)";
+  opname_tab[(int) INDIRECT_REF] = "*";
   opname_tab[(int) ARRAY_REF] = "[]";
   opname_tab[(int) MODIFY_EXPR] = "=";
   opname_tab[(int) NEW_EXPR] = "new";
   opname_tab[(int) DELETE_EXPR] = "delete";
   opname_tab[(int) VEC_NEW_EXPR] = "new []";
   opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
-  opname_tab[(int) COND_EXPR] = "... ? ... : ...";
+  opname_tab[(int) COND_EXPR] = "?:";
   opname_tab[(int) CALL_EXPR] = "()";
   opname_tab[(int) PLUS_EXPR] = "+";
   opname_tab[(int) MINUS_EXPR] = "-";
@@ -719,9 +742,9 @@ init_lex ()
   opname_tab[(int) EQ_EXPR] = "==";
   opname_tab[(int) NE_EXPR] = "!=";
   opname_tab[(int) IN_EXPR] = "in";
-  opname_tab[(int) RANGE_EXPR] = "..";
-  opname_tab[(int) CONVERT_EXPR] = "(unary +)";
-  opname_tab[(int) ADDR_EXPR] = "(unary &)";
+  opname_tab[(int) RANGE_EXPR] = "...";
+  opname_tab[(int) CONVERT_EXPR] = "+";
+  opname_tab[(int) ADDR_EXPR] = "&";
   opname_tab[(int) PREDECREMENT_EXPR] = "--";
   opname_tab[(int) PREINCREMENT_EXPR] = "++";
   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
@@ -763,7 +786,7 @@ init_lex ()
 
 #if 0
   /* let's parse things, and if they use it, then give them an error.  */
-  if (!flag_handle_exceptions)
+  if (!flag_exceptions)
     {
       UNSET_RESERVED_WORD ("throw");
       UNSET_RESERVED_WORD ("try");
@@ -800,8 +823,6 @@ init_lex ()
       UNSET_RESERVED_WORD ("xor");
       UNSET_RESERVED_WORD ("xor_eq");
     }
-  if (! flag_traditional)
-    UNSET_RESERVED_WORD ("overload");
 
   token_count = init_parse ();
   interface_unknown = 1;
@@ -937,13 +958,13 @@ print_parse_statistics ()
   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
   for (i = 0; i < TOKEN_LENGTH; i++)
     {
-      int index = sorted[i];
-      if (token_count[index] == 0)
+      int idx = sorted[i];
+      if (token_count[idx] == 0)
        break;
-      if (token_count[index] < token_count[-1])
+      if (token_count[idx] < token_count[-1])
        break;
       fprintf (stderr, "token %d, `%s', count = %d\n",
-              index, yytname[YYTRANSLATE (index)], token_count[index]);
+              idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
     }
   fprintf (stderr, "\n");
   for (i = 0; i < REDUCE_LENGTH; i++)
@@ -951,13 +972,13 @@ print_parse_statistics ()
   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
   for (i = 0; i < REDUCE_LENGTH; i++)
     {
-      int index = sorted[i];
-      if (reduce_count[index] == 0)
+      int idx = sorted[i];
+      if (reduce_count[idx] == 0)
        break;
-      if (reduce_count[index] < reduce_count[-1])
+      if (reduce_count[idx] < reduce_count[-1])
        break;
       fprintf (stderr, "rule %d, line %d, count = %d\n",
-              index, yyrline[index], reduce_count[index]);
+              idx, yyrline[idx], reduce_count[idx]);
     }
   fprintf (stderr, "\n");
 #endif
@@ -968,6 +989,7 @@ print_parse_statistics ()
 /* Sets the value of the 'yydebug' variable to VALUE.
    This is a function so we don't have to have YYDEBUG defined
    in order to build the compiler.  */
+
 void
 set_yydebug (value)
      int value;
@@ -1010,6 +1032,7 @@ static struct impl_files *impl_file_chain;
 
 /* Helper function to load global variables with interface
    information.  */
+
 void
 extract_interface_info ()
 {
@@ -1031,6 +1054,7 @@ extract_interface_info ()
 
 /* Return nonzero if S is not considered part of an
    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
+
 static int
 interface_strcmp (s)
      char *s;
@@ -1069,7 +1093,7 @@ interface_strcmp (s)
   return 1;
 }
 
-void
+static void
 set_typedecl_interface_info (prev, vars)
      tree prev, vars;
 {
@@ -1081,7 +1105,7 @@ set_typedecl_interface_info (prev, vars)
     = interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
 }
 
-int
+static int
 set_vardecl_interface_info (prev, vars)
      tree prev, vars;
 {
@@ -1090,7 +1114,7 @@ set_vardecl_interface_info (prev, vars)
   if (CLASSTYPE_INTERFACE_KNOWN (type))
     {
       if (CLASSTYPE_INTERFACE_ONLY (type))
-       set_typedecl_interface_info (prev, TYPE_NAME (type));
+       set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));
       else
        CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
       DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
@@ -1104,6 +1128,7 @@ set_vardecl_interface_info (prev, vars)
    do, set up to process them now.  This function sets up the first function
    to be parsed; after it has been, the rule for fndef in parse.y will
    call process_next_inline to start working on the next one.  */
+
 void
 do_pending_inlines ()
 {
@@ -1168,6 +1193,7 @@ static int nextchar = -1;
 /* Called from the fndecl rule in the parser when the function just parsed
    was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
    do_pending_inlines).  */
+
 void
 process_next_inline (t)
      tree t;
@@ -1183,12 +1209,11 @@ process_next_inline (t)
   if (yychar != END_OF_SAVED_INPUT)
     {
       error ("parse error at end of saved function text");
+
       /* restore_pending_input will abort unless yychar is either
-       * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
-       * hosed, feed back YYEMPTY.
-       *  We also need to discard nextchar, since that may have gotten
-       * set as well.
-       */
+         END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
+         hosed, feed back YYEMPTY.  We also need to discard nextchar,
+         since that may have gotten set as well.  */
       nextchar = -1;
     }
   yychar = YYEMPTY;
@@ -1322,6 +1347,7 @@ restore_pending_input (p)
 
 /* Return next non-whitespace input character, which may come
    from `finput', or from `nextchar'.  */
+
 static int
 yynextch ()
 {
@@ -1339,6 +1365,7 @@ yynextch ()
 /* Unget character CH from the input stream.
    If RESCAN is non-zero, then we want to `see' this
    character as the next input token.  */
+
 void
 yyungetc (ch, rescan)
      int ch;
@@ -1378,7 +1405,7 @@ store_pending_inline (decl, t)
   pending_inlines = t;
 }
 
-void reinit_parse_for_block ();
+static void reinit_parse_for_block PROTO((int, struct obstack *));
 
 void
 reinit_parse_for_method (yychar, decl)
@@ -1430,7 +1457,7 @@ reinit_parse_for_method (yychar, decl)
 /* Consume a block -- actually, a method beginning
    with `:' or `{' -- and save it away on the specified obstack.  */
 
-void
+static void
 reinit_parse_for_block (pyychar, obstackp)
      int pyychar;
      struct obstack *obstackp;
@@ -1646,12 +1673,13 @@ cons_up_default_function (type, full_name, kind)
       break;
 
     case 5:
-      type = build_type_variant (type, 1, 0);
-      /* Fall through...  */
     case 6:
       retref = 1;
       declspecs = build_decl_list (NULL_TREE, type);
 
+      if (kind == 5)
+       type = build_type_variant (type, 1, 0);
+
       name = ansi_opname [(int) MODIFY_EXPR];
 
       argtype = build_reference_type (type);
@@ -1671,17 +1699,19 @@ cons_up_default_function (type, full_name, kind)
   TREE_PARMLIST (args) = 1;
 
   {
-    tree declarator = build_parse_node (CALL_EXPR, name, args, NULL_TREE);
+    tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
     if (retref)
       declarator = build_parse_node (ADDR_EXPR, declarator);
     
-    fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE,
-                   NULL_TREE, NULL_TREE);
+    fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
   }
   
   if (fn == void_type_node)
     return fn;
 
+  if (kind > 2)
+    SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
+
 #if 0
   if (processing_template_defn)
     {
@@ -1733,6 +1763,7 @@ cons_up_default_function (type, full_name, kind)
 /* Heuristic to tell whether the user is missing a semicolon
    after a struct or enum declaration.  Emit an error message
    if we know the user has blown it.  */
+
 void
 check_for_missing_semicolon (type)
      tree type;
@@ -1743,7 +1774,8 @@ check_for_missing_semicolon (type)
   if ((yychar > 255
        && yychar != SCSPEC
        && yychar != IDENTIFIER
-       && yychar != TYPENAME)
+       && yychar != TYPENAME
+       && yychar != SELFNAME)
       || end_of_file)
     {
       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
@@ -1865,9 +1897,12 @@ get_last_nonwhite_on_line ()
 
 int linemode;
 
-int handle_cp_pragma ();
+#ifdef HANDLE_SYSV_PRAGMA
+static int handle_sysv_pragma ();
+#endif
+static int handle_cp_pragma ();
 
-int
+static int
 check_newline ()
 {
   register int c;
@@ -1911,12 +1946,6 @@ check_newline ()
              && getch () == 'm'
              && getch () == 'a')
            {
-             c = getch ();
-             while (c == ' ' || c == '\t')
-               c = getch ();
-             put_back (c);
-             if (c == '\n' || c == EOF)
-               goto skipline;
              token = real_yylex ();
              if (token == IDENTIFIER
                  && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
@@ -1951,11 +1980,7 @@ check_newline ()
              && getch () == 'e'
              && ((c = getch ()) == ' ' || c == '\t'))
            {
-#ifdef DWARF_DEBUGGING_INFO
-             if ((debug_info_level == DINFO_LEVEL_VERBOSE)
-                 && (write_symbols == DWARF_DEBUG))
-               dwarfout_define (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+             debug_define (lineno, get_directive_line (finput));
              goto skipline;
            }
        }
@@ -1967,11 +1992,7 @@ check_newline ()
              && getch () == 'f'
              && ((c = getch ()) == ' ' || c == '\t'))
            {
-#ifdef DWARF_DEBUGGING_INFO
-             if ((debug_info_level == DINFO_LEVEL_VERBOSE)
-                 && (write_symbols == DWARF_DEBUG))
-               dwarfout_undef (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+             debug_undef (lineno, get_directive_line (finput));
              goto skipline;
            }
        }
@@ -1999,15 +2020,9 @@ check_newline ()
              /* Here we have just seen `#ident '.
                 A string constant should follow.  */
 
-             while (c == ' ' || c == '\t')
-               c = getch ();
-
-             /* If no argument, ignore the line.  */
-             if (c == EOF)
-               goto skipline;
-
-             put_back (c);
              token = real_yylex ();
+             if (token == END_OF_LINE)
+               goto skipline;
              if (token != STRING
                  || TREE_CODE (yylval.ttype) != STRING_CST)
                {
@@ -2216,15 +2231,7 @@ linenum:
              p->name = input_filename;
              input_file_stack = p;
              input_file_stack_tick++;
-#ifdef DBX_DEBUGGING_INFO
-             if (write_symbols == DBX_DEBUG)
-               dbxout_start_new_source_file (input_filename);
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-             if (debug_info_level == DINFO_LEVEL_VERBOSE
-                 && write_symbols == DWARF_DEBUG)
-               dwarfout_start_new_source_file (input_filename);
-#endif /* DWARF_DEBUGGING_INFO */
+             debug_start_source_file (input_filename);
              in_system_header = entering_system_header;
              if (c_header_level)
                ++c_header_level;
@@ -2253,15 +2260,7 @@ linenum:
                  input_file_stack = p->next;
                  free (p);
                  input_file_stack_tick++;
-#ifdef DBX_DEBUGGING_INFO
-                 if (write_symbols == DBX_DEBUG)
-                   dbxout_resume_previous_source_file ();
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-                 if (debug_info_level == DINFO_LEVEL_VERBOSE
-                     && write_symbols == DWARF_DEBUG)
-                   dwarfout_resume_previous_source_file (input_file_stack->line);
-#endif /* DWARF_DEBUGGING_INFO */
+                 debug_end_source_file (input_file_stack->line);
                }
              else
                error ("#-lines for entering and leaving files don't match");
@@ -2281,6 +2280,7 @@ linenum:
  skipline:
   linemode = 0;
   end_of_file = 0;
+  nextchar = -1;
   while ((c = getch ()) != EOF && c != '\n');
   return c;
 }
@@ -2319,12 +2319,6 @@ readescape (ignore_ptr)
   switch (c)
     {
     case 'x':
-      if (warn_traditional)
-       warning ("the meaning of `\\x' varies with -traditional");
-
-      if (flag_traditional)
-       return c;
-
       code = 0;
       count = 0;
       nonnull = 0;
@@ -2399,11 +2393,6 @@ readescape (ignore_ptr)
       return TARGET_BS;
 
     case 'a':
-      if (warn_traditional)
-       warning ("the meaning of `\\a' varies with -traditional");
-
-      if (flag_traditional)
-       return c;
       return TARGET_BELL;
 
     case 'v':
@@ -2440,20 +2429,6 @@ readescape (ignore_ptr)
    Value is 0 if we treat this name in a default fashion.  */
 int looking_for_typename = 0;
 
-#if 0
-/* NO LONGER USED: Value is -1 if we must not see a type name.  */
-void
-dont_see_typename ()
-{
-  looking_for_typename = -1;
-  if (yychar == TYPENAME || yychar == PTYPENAME)
-    {
-      yychar = IDENTIFIER;
-      lastiddecl = 0;
-    }
-}
-#endif
-
 #ifdef __GNUC__
 extern __inline int identifier_type ();
 __inline
@@ -2471,6 +2446,10 @@ identifier_type (decl)
     return NSNAME;
   if (TREE_CODE (decl) != TYPE_DECL)
     return IDENTIFIER;
+  if (((got_scope && TREE_TYPE (decl) == got_scope)
+       || TREE_TYPE (decl) == current_class_type)
+      && DECL_ARTIFICIAL (decl))
+    return SELFNAME;
   return TYPENAME;
 }
 
@@ -2540,7 +2519,12 @@ do_identifier (token, parsing)
      [class.scope0] */
   if (id && current_class_type && parsing
       && TYPE_BEING_DEFINED (current_class_type)
-      && ! IDENTIFIER_CLASS_VALUE (token))
+      && ! IDENTIFIER_CLASS_VALUE (token)
+      /* Avoid breaking if we get called for a default argument that
+        refers to an overloaded method.  Eventually this will not be
+        necessary, since default arguments shouldn't be parsed until
+        after the class is complete.  (jason 3/12/97) */
+      && TREE_CODE (id) != TREE_LIST)
     pushdecl_class_level (id);
     
   if (!id || id == error_mark_node)
@@ -2559,7 +2543,7 @@ do_identifier (token, parsing)
       else if (IDENTIFIER_OPNAME_P (token))
        {
          if (token != ansi_opname[ERROR_MARK])
-           cp_error ("operator %O not defined", token);
+           cp_error ("`%D' not defined", token);
          id = error_mark_node;
        }
       else if (parsing && (yychar == '(' || yychar == LEFT_RIGHT))
@@ -2644,7 +2628,7 @@ do_identifier (token, parsing)
            cp_error ("enum `%D' is private", id);
          /* protected is OK, since it's an enum of `this'.  */
        }
-      if (! current_template_parms
+      if (! processing_template_decl
          || (DECL_INITIAL (id)
              && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
        id = DECL_INITIAL (id);
@@ -2681,7 +2665,7 @@ do_scoped_id (token, parsing)
     yychar = yylex ();
   if (! id)
     {
-      if (current_template_parms)
+      if (processing_template_decl)
        {
          id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
          LOOKUP_EXPR_GLOBAL (id) = 1;
@@ -2706,7 +2690,7 @@ do_scoped_id (token, parsing)
       else if (TREE_CODE (id) != TREE_LIST)
        mark_used (id);
     }
-  if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
+  if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
     {
       /* XXX CHS - should we set TREE_USED of the constant? */
       id = DECL_INITIAL (id);
@@ -2716,7 +2700,7 @@ do_scoped_id (token, parsing)
       TREE_CONSTANT (id) = 1;
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (is_overloaded_fn (id))
        {
@@ -2748,32 +2732,14 @@ identifier_typedecl_value (node)
   do (IDENTIFIER_GLOBAL_VALUE (node));
 #undef do
   /* Will this one ever happen?  */
-  if (TYPE_NAME (type))
-    return TYPE_NAME (type);
+  if (TYPE_MAIN_DECL (type))
+    return TYPE_MAIN_DECL (type);
 
   /* We used to do an internal error of 62 here, but instead we will
      handle the return of a null appropriately in the callers.  */
   return NULL_TREE;
 }
 
-struct try_type
-{
-  tree *node_var;
-  char unsigned_flag;
-  char long_flag;
-  char long_long_flag;
-};
-
-struct try_type type_sequence[] = 
-{
-  { &integer_type_node, 0, 0, 0},
-  { &unsigned_type_node, 1, 0, 0},
-  { &long_integer_type_node, 0, 1, 0},
-  { &long_unsigned_type_node, 1, 1, 0},
-  { &long_long_integer_type_node, 0, 1, 1},
-  { &long_long_unsigned_type_node, 1, 1, 1}
-};
-
 int
 real_yylex ()
 {
@@ -3050,18 +3016,6 @@ real_yylex ()
        /* If we did not find a keyword, look for an identifier
           (or a typename).  */
 
-       if (strcmp ("catch", token_buffer) == 0
-           || strcmp ("throw", token_buffer) == 0
-           || strcmp ("try", token_buffer) == 0)
-         {
-           static int did_warn = 0;
-           if (! did_warn  && ! flag_handle_exceptions)
-             {
-               pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
-               did_warn = 1;
-             }
-         }
-
        if (value == IDENTIFIER || value == TYPESPEC)
          GNU_xref_ref (current_function_decl, token_buffer);
 
@@ -3102,7 +3056,12 @@ real_yylex ()
                && DECL_INITIAL (tmp) != NULL_TREE
                && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
              {
-               yylval.ttype = DECL_INITIAL (tmp);
+               tree stringval = DECL_INITIAL (tmp);
+             
+               /* Copy the string value so that we won't clobber anything
+                  if we put something in the TREE_CHAIN of this one.  */
+               yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
+                                            TREE_STRING_POINTER (stringval));
                value = STRING;
              }
          }
@@ -3166,7 +3125,7 @@ real_yylex ()
          }
        put_back (c1);
       }
-      /* fall through... */
+      /* fall through...  */
                          case '2':  case '3':  case '4':
     case '5':  case '6':  case '7':  case '8':  case '9':
     resume_numerical_scan:
@@ -3371,7 +3330,7 @@ real_yylex ()
                set_float_handler (handler);
                /*  The second argument, machine_mode, of REAL_VALUE_ATOF
                    tells the desired precision of the binary result of
-                   decimal-to-binary conversion. */
+                   decimal-to-binary conversion.  */
 
                /* Read the suffixes to choose a data type.  */
                switch (c)
@@ -3406,7 +3365,7 @@ real_yylex ()
                    ))
              {
                pedwarn ("floating point number exceeds range of `%s'",
-                        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+                        IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
              }
            /* Note: garbage_chars is -1 if first char is *not* garbage.  */
            while (isalnum (c))
@@ -3529,83 +3488,9 @@ real_yylex ()
            yylval.ttype = build_int_2 (low, high);
            TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
 
-#if 0
-           /* Find the first allowable type that the value fits in.  */
-           type = 0;
-           for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
-                i++)
-             if (!(spec_long && !type_sequence[i].long_flag)
-                 && !(spec_long_long && !type_sequence[i].long_long_flag)
-                 && !(spec_unsigned && !type_sequence[i].unsigned_flag)
-                 /* A hex or octal constant traditionally is unsigned.  */
-                 && !(base != 10 && flag_traditional
-                      && !type_sequence[i].unsigned_flag)
-                 /* A decimal constant can't be unsigned int
-                    unless explicitly specified.  */
-                 && !(base == 10 && !spec_unsigned
-                      && *type_sequence[i].node_var == unsigned_type_node))
-               if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
-                 {
-                   type = *type_sequence[i].node_var;
-                   break;
-                 }
-           if (flag_traditional && type == long_unsigned_type_node
-               && !spec_unsigned)
-             type = long_integer_type_node;
-             
-           if (type == 0)
-             {
-               type = long_long_integer_type_node;
-               warning ("integer constant out of range");
-             }
-
-           /* Warn about some cases where the type of a given constant
-              changes from traditional C to ANSI C.  */
-           if (warn_traditional)
-             {
-               tree other_type = 0;
-
-               /* This computation is the same as the previous one
-                  except that flag_traditional is used backwards.  */
-               for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
-                    i++)
-                 if (!(spec_long && !type_sequence[i].long_flag)
-                     && !(spec_long_long && !type_sequence[i].long_long_flag)
-                     && !(spec_unsigned && !type_sequence[i].unsigned_flag)
-                     /* A hex or octal constant traditionally is unsigned.  */
-                     && !(base != 10 && !flag_traditional
-                          && !type_sequence[i].unsigned_flag)
-                     /* A decimal constant can't be unsigned int
-                        unless explicitly specified.  */
-                     && !(base == 10 && !spec_unsigned
-                          && *type_sequence[i].node_var == unsigned_type_node))
-                   if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
-                     {
-                       other_type = *type_sequence[i].node_var;
-                       break;
-                     }
-               if (!flag_traditional && type == long_unsigned_type_node
-                   && !spec_unsigned)
-                 type = long_integer_type_node;
-             
-               if (other_type != 0 && other_type != type)
-                 {
-                   if (flag_traditional)
-                     warning ("type of integer constant would be different without -traditional");
-                   else
-                     warning ("type of integer constant would be different with -traditional");
-                 }
-             }
-
-#else /* 1 */
            if (!spec_long && !spec_unsigned
-               && !(flag_traditional && base != 10)
                && int_fits_type_p (yylval.ttype, integer_type_node))
              {
-#if 0
-               if (warn_traditional && base != 10)
-                 warning ("small nondecimal constant becomes signed in ANSI C++");
-#endif
                type = integer_type_node;
              }
            else if (!spec_long && (base != 10 || spec_unsigned)
@@ -3622,16 +3507,7 @@ real_yylex ()
            else if (! spec_long_long
                     && int_fits_type_p (yylval.ttype,
                                         long_unsigned_type_node))
-             {
-#if 0
-               if (warn_traditional && !spec_unsigned)
-                 warning ("large integer constant becomes unsigned in ANSI C++");
-#endif
-               if (flag_traditional && !spec_unsigned)
-                 type = long_integer_type_node;
-               else
-                 type = long_unsigned_type_node;
-             }
+             type = long_unsigned_type_node;
 
            else if (! spec_unsigned
                     /* Verify value does not overflow into sign bit.  */
@@ -3642,17 +3518,7 @@ real_yylex ()
 
            else if (int_fits_type_p (yylval.ttype,
                                      long_long_unsigned_type_node))
-             {
-#if 0
-               if (warn_traditional && !spec_unsigned)
-                 warning ("large nondecimal constant is unsigned in ANSI C++");
-#endif
-
-               if (flag_traditional && !spec_unsigned)
-                 type = long_long_integer_type_node;
-               else
-                 type = long_long_unsigned_type_node;
-             }
+             type = long_long_unsigned_type_node;
 
            else
              {
@@ -3662,7 +3528,6 @@ real_yylex ()
                if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
                  warning ("decimal integer constant is so large that it is unsigned");
              }
-#endif
 
            TREE_TYPE (yylval.ttype) = type;
            *p = 0;
@@ -3753,7 +3618,7 @@ real_yylex ()
            num_chars = max_chars;
            error ("character constant too long");
          }
-       else if (num_chars != 1 && ! flag_traditional)
+       else if (num_chars != 1)
          warning ("multi-character character constant");
 
        /* If char type is signed, sign-extend the constant.  */
@@ -3882,19 +3747,19 @@ real_yylex ()
              len = p - token_buffer - 1;
            }
 #endif
-           if (current_template_parms)
+           if (processing_template_decl)
              push_obstacks (&permanent_obstack, &permanent_obstack);
            yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
-           if (current_template_parms)
+           if (processing_template_decl)
              pop_obstacks ();
            TREE_TYPE (yylval.ttype) = wchar_array_type_node;
          }
        else
          {
-           if (current_template_parms)
+           if (processing_template_decl)
              push_obstacks (&permanent_obstack, &permanent_obstack);
            yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
-           if (current_template_parms)
+           if (processing_template_decl)
              pop_obstacks ();
            TREE_TYPE (yylval.ttype) = char_array_type_node;
          }
@@ -4113,6 +3978,30 @@ is_rid (t)
 }
 
 #ifdef GATHER_STATISTICS
+/* The original for tree_node_kind is in the toplevel tree.c; changes there
+   need to be brought into here, unless this were actually put into a header
+   instead.  */
+/* Statistics-gathering stuff.  */
+typedef enum
+{
+  d_kind,
+  t_kind,
+  b_kind,
+  s_kind,
+  r_kind,
+  e_kind,
+  c_kind,
+  id_kind,
+  op_id_kind,
+  perm_list_kind,
+  temp_list_kind,
+  vec_kind,
+  x_kind,
+  lang_decl,
+  lang_type,
+  all_kinds
+} tree_node_kind;
+
 extern int tree_node_counts[];
 extern int tree_node_sizes[];
 #endif
@@ -4156,22 +4045,7 @@ build_lang_decl (code, name, type)
          == TREE_PERMANENT  (t), 234);
   DECL_MAIN_VARIANT (t) = t;
   if (current_lang_name == lang_name_cplusplus)
-    {
-      DECL_LANGUAGE (t) = lang_cplusplus;
-#if 0
-#ifndef NO_AUTO_OVERLOAD
-      if (code == FUNCTION_DECL && name != 0
-         && ! (IDENTIFIER_LENGTH (name) == 4
-               && IDENTIFIER_POINTER (name)[0] == 'm'
-               && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
-         && ! (IDENTIFIER_LENGTH (name) > 10
-               && IDENTIFIER_POINTER (name)[0] == '_'
-               && IDENTIFIER_POINTER (name)[1] == '_'
-               && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
-       TREE_OVERLOADED (name) = 1;
-#endif
-#endif
-    }
+    DECL_LANGUAGE (t) = lang_cplusplus;
   else if (current_lang_name == lang_name_c)
     DECL_LANGUAGE (t) = lang_c;
   else my_friendly_abort (64);
@@ -4291,33 +4165,6 @@ make_lang_type (code)
 }
 
 void
-copy_decl_lang_specific (decl)
-     tree decl;
-{
-  extern struct obstack *current_obstack, *saveable_obstack;
-  register int *old = (int *)DECL_LANG_SPECIFIC (decl);
-  struct obstack *obstack = current_obstack;
-  register int i = sizeof (struct lang_decl) / sizeof (int);
-  register int *pi;
-
-  if (! TREE_PERMANENT (decl))
-    obstack = saveable_obstack;
-  else
-    my_friendly_assert (obstack == &permanent_obstack, 237);
-
-  pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
-  while (i-- > 0)
-    pi[i] = old[i];
-
-  DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
-
-#ifdef GATHER_STATISTICS
-  tree_node_counts[(int)lang_decl] += 1;
-  tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
-#endif
-}
-
-void
 dump_time_statistics ()
 {
   register tree prev = 0, decl, next;
@@ -4384,12 +4231,11 @@ yyerror (string)
   error (buf, token_buffer);
 }
 \f
-int
+static int
 handle_cp_pragma (pname)
      char *pname;
 {
   register int token;
-  register int c;
 
   if (! strcmp (pname, "vtable"))
     {
@@ -4412,10 +4258,8 @@ handle_cp_pragma (pname)
        = perm_tree_cons (NULL_TREE,
                          get_identifier (TREE_STRING_POINTER (yylval.ttype)),
                          pending_vtables);
-      if (nextchar < 0)
-       nextchar = getch ();
-      c = nextchar;
-      if (c != EOF)
+      token = real_yylex ();
+      if (token != END_OF_LINE)
        warning ("trailing characters ignored");
       return 1;
     }
@@ -4428,30 +4272,22 @@ handle_cp_pragma (pname)
          error ("invalid #pragma unit");
          return -1;
        }
-      if (nextchar < 0)
-       nextchar = getch ();
-      c = nextchar;
-      if (c != EOF)
+      token = real_yylex ();
+      if (token != END_OF_LINE)
        warning ("trailing characters ignored");
       return 1;
     }
   else if (! strcmp (pname, "interface"))
     {
       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
-      int warned_already = 0;
       char *main_filename = input_filename;
 
       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
 
-      do
-       {
-         c = getch ();
-       } while (c == ' ' || c == '\t');
-
-      if (c != EOF)
+      token = real_yylex ();
+      
+      if (token != END_OF_LINE)
        {
-         put_back (c);
-         token = real_yylex ();
          if (token != STRING
              || TREE_CODE (yylval.ttype) != STRING_CST)
            {
@@ -4459,85 +4295,66 @@ handle_cp_pragma (pname)
              return -1;
            }
          main_filename = TREE_STRING_POINTER (yylval.ttype);
-         c = getch();
-         put_back (c);
-
-         while (c == ' ' || c == '\t')
-           c = getch ();
+         token = real_yylex ();
+       }
 
-         while (c != EOF)
-           {
-             if (!warned_already && extra_warnings
-                 && c != ' ' && c != '\t')
-               {
-                 warning ("garbage after `#pragma interface' ignored");
-                 warned_already = 1;
-               }
-             c = getch ();
-           }
+      if (token != END_OF_LINE)
+       warning ("garbage after `#pragma interface' ignored");
 
-         write_virtuals = 3;
+#ifndef NO_LINKAGE_HEURISTICS
+      write_virtuals = 3;
 
-         if (impl_file_chain == 0)
-           {
-             /* If this is zero at this point, then we are
-                auto-implementing.  */
-             if (main_input_filename == 0)
-               main_input_filename = input_filename;
+      if (impl_file_chain == 0)
+       {
+         /* If this is zero at this point, then we are
+            auto-implementing.  */
+         if (main_input_filename == 0)
+           main_input_filename = input_filename;
 
 #ifdef AUTO_IMPLEMENT
-             filename = FILE_NAME_NONDIRECTORY (main_input_filename);
-             fi = get_time_identifier (filename);
-             fi = IDENTIFIER_CLASS_VALUE (fi);
-             TREE_INT_CST_LOW (fi) = 0;
-             TREE_INT_CST_HIGH (fi) = 1;
-             /* Get default.  */
-             impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
-             impl_file_chain->filename = filename;
-             impl_file_chain->next = 0;
+         filename = FILE_NAME_NONDIRECTORY (main_input_filename);
+         fi = get_time_identifier (filename);
+         fi = IDENTIFIER_CLASS_VALUE (fi);
+         TREE_INT_CST_LOW (fi) = 0;
+         TREE_INT_CST_HIGH (fi) = 1;
+         /* Get default.  */
+         impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
+         impl_file_chain->filename = filename;
+         impl_file_chain->next = 0;
 #endif
-           }
        }
 
       interface_only = interface_strcmp (main_filename);
       interface_unknown = 0;
       TREE_INT_CST_LOW (fileinfo) = interface_only;
       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
+#endif /* NO_LINKAGE_HEURISTICS */
 
       return 1;
     }
   else if (! strcmp (pname, "implementation"))
     {
       tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
-      int warned_already = 0;
       char *main_filename = main_input_filename ? main_input_filename : input_filename;
 
       main_filename = FILE_NAME_NONDIRECTORY (main_filename);
       token = real_yylex ();
-      if (token != STRING
-         || TREE_CODE (yylval.ttype) != STRING_CST)
-       {
-         error ("invalid `#pragma implementation'");
-         return -1;
-       }
-      main_filename = TREE_STRING_POINTER (yylval.ttype);
-      c = getch();
-      put_back (c);
-
-      while (c == ' ' || c == '\t')
-       c = getch ();
-
-      while (c != EOF)
+      if (token != END_OF_LINE)
        {
-         if (!warned_already && extra_warnings
-             && c != ' ' && c != '\t')
+         if (token != STRING
+             || TREE_CODE (yylval.ttype) != STRING_CST)
            {
-             warning ("garbage after `#pragma implementation' ignored");
-             warned_already = 1;
+             error ("invalid `#pragma implementation'");
+             return -1;
            }
-         c = getch ();
+         main_filename = TREE_STRING_POINTER (yylval.ttype);
+         token = real_yylex ();
        }
 
+      if (token != END_OF_LINE)
+       warning ("garbage after `#pragma implementation' ignored");
+
+#ifndef NO_LINKAGE_HEURISTICS
       if (write_virtuals == 3)
        {
          struct impl_files *ifiles = impl_file_chain;
@@ -4577,11 +4394,13 @@ handle_cp_pragma (pname)
       interface_unknown = 1;
 #else
       /* We make this zero so that templates in the impl
-        file will be emitted properly. */
+        file will be emitted properly.  */
       interface_unknown = 0;
 #endif
       TREE_INT_CST_LOW (fileinfo) = interface_only;
       TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
+#endif /* NO_LINKAGE_HEURISTICS */
+
       return 1;
     }
 
@@ -4596,7 +4415,8 @@ handle_cp_pragma (pname)
 
 /* This function has to be in this file, in order to get at
    the token types.  */
-int
+
+static int
 handle_sysv_pragma (finput, token)
      FILE *finput;
      register int token;
@@ -4610,38 +4430,29 @@ handle_sysv_pragma (finput, token)
        case STRING:
        case CONSTANT:
          handle_pragma_token ("ignored", yylval.ttype);
-         token = yylex ();
          break;
        case '(':
          handle_pragma_token ("(", NULL_TREE);
-         token = yylex ();
          break;
        case ')':
          handle_pragma_token (")", NULL_TREE);
-         token = yylex ();
          break;
        case ',':
          handle_pragma_token (",", NULL_TREE);
-         token = yylex ();
          break;
        case '=':
          handle_pragma_token ("=", NULL_TREE);
-         token = yylex ();
          break;
        case LEFT_RIGHT:
          handle_pragma_token ("(", NULL_TREE);
          handle_pragma_token (")", NULL_TREE);
-         token = yylex ();
          break;
        case END_OF_LINE:
-         handle_pragma_token (NULL_PTR, NULL_TREE);
-         return 1;
        default:
          handle_pragma_token (NULL_PTR, NULL_TREE);
-         while (yylex () != END_OF_LINE)
-           /* continue */;
          return 1;
        }
+      token = real_yylex ();
     }
 }
 #endif /* HANDLE_SYSV_PRAGMA */