cp-tree.h (struct lang_decl_inlined_fns): New.
[gcc.git] / gcc / cp / decl.c
index ee4571c94e840b09c45c86378419b700b79fa96d..39008956f4af09d8b6d3e3db84b0511c97430be6 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001  Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -37,12 +37,12 @@ Boston, MA 02111-1307, USA.  */
 #include "cp-tree.h"
 #include "decl.h"
 #include "lex.h"
-#include "defaults.h"
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
 #include "../hash.h"
 #include "ggc.h"
+#include "tm_p.h"
 
 extern int current_class_depth;
 
@@ -51,55 +51,12 @@ extern tree global_namespace;
 extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
 
 #ifndef BOOL_TYPE_SIZE
-#ifdef SLOW_BYTE_ACCESS
 /* In the new ABI, `bool' has size and alignment `1', on all
    platforms.  */
-#define BOOL_TYPE_SIZE \
-  ((SLOW_BYTE_ACCESS && !flag_new_abi) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
-#else
 #define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
 #endif
-#endif
-
-/* We let tm.h override the types used here, to handle trivial differences
-   such as the choice of unsigned int or long unsigned int for size_t.
-   When machines start needing nontrivial differences in the size type,
-   it would be best to do something here to figure out automatically
-   from other information what type to use.  */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
 
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-
-#ifndef WINT_TYPE
-#define WINT_TYPE "unsigned int"
-#endif
-
-#ifndef INTMAX_TYPE
-#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
-                    ? "int"                                    \
-                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
-                       ? "long int"                            \
-                       : "long long int"))
-#endif
-
-#ifndef UINTMAX_TYPE
-#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
-                    ? "unsigned int"                           \
-                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
-                       ? "long unsigned int"                   \
-                       : "long long unsigned int"))
-#endif
-
-static tree grokparms                          PARAMS ((tree, int));
+static tree grokparms                          PARAMS ((tree));
 static const char *redeclaration_error_message PARAMS ((tree, tree));
 
 static void push_binding_level PARAMS ((struct binding_level *, int,
@@ -128,7 +85,6 @@ static tree lookup_tag PARAMS ((enum tree_code, tree,
                              struct binding_level *, int));
 static void set_identifier_type_value_with_scope
        PARAMS ((tree, tree, struct binding_level *));
-static void record_builtin_type PARAMS ((enum rid, const char *, tree));
 static void record_unknown_type PARAMS ((tree, const char *));
 static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
 static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
@@ -187,11 +143,12 @@ static tree start_cleanup_fn PARAMS ((void));
 static void end_cleanup_fn PARAMS ((void));
 static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
 static void initialize_predefined_identifiers PARAMS ((void));
-static tree check_special_function_return_type 
-  PARAMS ((special_function_kind, tree, tree, tree));
+static tree check_special_function_return_type
+  PARAMS ((special_function_kind, tree, tree));
 static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
 static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
 static void store_parm_decls PARAMS ((tree));
+static int cp_missing_noreturn_ok_p PARAMS ((tree));
 
 #if defined (DEBUG_CP_BINDING_LEVELS)
 static void indent PARAMS ((void));
@@ -352,10 +309,6 @@ int flag_hosted = 1;
 
 int flag_noniso_default_format_attributes = 1;
 
-/* Nonzero means give `double' the same size as `float'.  */
-
-extern int flag_short_double;
-
 /* Nonzero if we want to conserve space in the .o files.  We do this
    by putting uninitialized data and runtime initialized data into
    .common instead of .data at the expense of not flagging multiple
@@ -432,15 +385,13 @@ struct binding_level
 
     /* If this binding level is the binding level for a class, then
        class_shadowed is a TREE_LIST.  The TREE_PURPOSE of each node
-       is the name of an entity bound in the class; the TREE_VALUE is
-       the IDENTIFIER_CLASS_VALUE before we entered the class.  Thus,
-       when leaving class scope, we can restore the
-       IDENTIFIER_CLASS_VALUE by walking this list.  The TREE_TYPE is
+       is the name of an entity bound in the class.  The TREE_TYPE is
        the DECL bound by this name in the class.  */
     tree class_shadowed;
 
     /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
-       is used for all binding levels.  */
+       is used for all binding levels. In addition the TREE_VALUE is the
+       IDENTIFIER_TYPE_VALUE before we entered the class.  */
     tree type_shadowed;
 
     /* A TREE_LIST.  Each TREE_VALUE is the LABEL_DECL for a local
@@ -490,7 +441,7 @@ struct binding_level
        replaced with a TEMPLATE_DECL.  */
     unsigned template_parms_p : 1;
 
-    /* Nonzero if this scope corresponds to the `<>' in a 
+    /* Nonzero if this scope corresponds to the `<>' in a
        `template <>' clause.  Whenever this flag is set,
        TEMPLATE_PARMS_P will be set as well.  */
     unsigned template_spec_p : 1;
@@ -521,7 +472,7 @@ struct binding_level
 
 #define current_binding_level                  \
   (cfun                                                \
-   ? cp_function_chain->bindings               \
+   ? cp_function_chain->bindings               \
    : scope_chain->bindings)
 
 /* The binding level of the current class, if any.  */
@@ -565,7 +516,7 @@ push_binding_level (newlevel, tag_transparent, keep)
 {
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
-  bzero ((char*) newlevel, sizeof (struct binding_level));
+  memset ((char*) newlevel, 0, sizeof (struct binding_level));
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
   newlevel->tag_transparent = tag_transparent;
@@ -907,6 +858,24 @@ pushlevel (tag_transparent)
   keep_next_level_flag = 0;
 }
 
+/* We're defining an object of type TYPE.  If it needs a cleanup, but
+   we're not allowed to add any more objects with cleanups to the current
+   scope, create a new binding level.  */
+
+void
+maybe_push_cleanup_level (type)
+     tree type;
+{
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      && current_binding_level->more_cleanups_ok == 0)
+    {
+      keep_next_level (2);
+      pushlevel (1);
+      clear_last_expr ();
+      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
+    }
+}
+  
 /* Enter a new scope.  The KIND indicates what kind of scope is being
    created.  */
 
@@ -958,6 +927,11 @@ note_level_for_eh ()
 #define BINDING_LEVEL(NODE) \
    (((struct tree_binding*)NODE)->scope.level)
 
+/* A free list of CPLUS_BINDING nodes, connected by their
+   TREE_CHAINs.  */
+
+static tree free_bindings;
+
 /* Make DECL the innermost binding for ID.  The LEVEL is the binding
    level at which this declaration is being bound.  */
 
@@ -969,7 +943,13 @@ push_binding (id, decl, level)
 {
   tree binding;
 
-  binding = make_node (CPLUS_BINDING);
+  if (free_bindings)
+    {
+      binding = free_bindings;
+      free_bindings = TREE_CHAIN (binding);
+    }
+  else
+    binding = make_node (CPLUS_BINDING);
 
   /* Now, fill in the binding information.  */
   BINDING_VALUE (binding) = decl;
@@ -1157,7 +1137,7 @@ push_class_binding (id, decl)
          else
            {
              my_friendly_assert (DECL_P (decl), 0);
-             context = CP_DECL_CONTEXT (decl);
+             context = context_for_name_lookup (decl);
            }
 
          if (is_properly_derived_from (current_class_type, context))
@@ -1207,9 +1187,19 @@ pop_binding (id, decl)
     my_friendly_abort (0);
 
   if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
-    /* We're completely done with the innermost binding for this
-       identifier.  Unhook it from the list of bindings.  */
-    IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+    {
+      /* We're completely done with the innermost binding for this
+        identifier.  Unhook it from the list of bindings.  */
+      IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+
+      /* Add it to the free list.  */
+      TREE_CHAIN (binding) = free_bindings;
+      free_bindings = binding;
+
+      /* Clear the BINDING_LEVEL so the garbage collector doesn't walk
+        it.  */
+      BINDING_LEVEL (binding) = NULL;
+    }
 }
 
 /* When a label goes out of scope, check to see if that label was used
@@ -1925,20 +1915,8 @@ wrapup_globals_for_namespace (namespace, data)
 
   /* Process the decls in reverse order--earliest first.
      Put them into VEC from back to front, then take out from front.  */
-
   for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
-    {
-      /* Pretend we've output an unused static variable.  This ensures
-         that the toplevel __FUNCTION__ etc won't be emitted, unless
-         needed. */
-      if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)
-         && !TREE_PUBLIC (decl) && !TREE_USED (decl))
-       {
-         TREE_ASM_WRITTEN (decl) = 1;
-         DECL_IGNORED_P (decl) = 1;
-       }
-      vec[len - i - 1] = decl;
-    }
+    vec[len - i - 1] = decl;
 
   if (last_time)
     {
@@ -2456,6 +2434,8 @@ store_bindings (names, old_bindings)
      tree names, old_bindings;
 {
   tree t;
+  tree search_bindings = old_bindings;
+
   for (t = names; t; t = TREE_CHAIN (t))
     {
       tree binding, t1, id;
@@ -2472,22 +2452,18 @@ store_bindings (names, old_bindings)
          || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
        continue;
 
-      for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))
+      for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1))
        if (TREE_VEC_ELT (t1, 0) == id)
          goto skip_it;
 
+      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
       binding = make_tree_vec (4);
-
-      if (id)
-       {
-         my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
-         TREE_VEC_ELT (binding, 0) = id;
-         TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
-         TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
-         TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
-         IDENTIFIER_BINDING (id) = NULL_TREE;
-         IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
-       }
+      TREE_VEC_ELT (binding, 0) = id;
+      TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
+      TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
+      TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
+      IDENTIFIER_BINDING (id) = NULL_TREE;
+      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
       TREE_CHAIN (binding) = old_bindings;
       old_bindings = binding;
     skip_it:
@@ -2581,12 +2557,10 @@ pop_from_top_level ()
   for (t = s->old_bindings; t; t = TREE_CHAIN (t))
     {
       tree id = TREE_VEC_ELT (t, 0);
-      if (id)
-       {
-         SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
-         IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
-         IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
-       }
+
+      SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
+      IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
+      IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
     }
 
   /* If we were in the middle of compiling a function, restore our
@@ -2859,19 +2833,13 @@ pushtag (name, type, globalize)
             all function definitions in a translation unit in a convenient
             way.  (It's otherwise tricky to find a member function definition
             it's only pointed to from within a local class.)  */
-         if (TYPE_CONTEXT (type) 
+         if (TYPE_CONTEXT (type)
              && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
              && !processing_template_decl)
            VARRAY_PUSH_TREE (local_classes, type);
 
-         if (!uses_template_parms (type)) 
-           {
-             if (flag_new_abi)
-               DECL_ASSEMBLER_NAME (d) = mangle_type (type);
-             else
-               DECL_ASSEMBLER_NAME (d)
-                 = get_identifier (build_overload_name (type, 1, 1));
-           }
+         if (!uses_template_parms (type))
+           DECL_ASSEMBLER_NAME (d) = mangle_type (type);
         }
       if (b->parm_flag == 2)
        {
@@ -3431,7 +3399,9 @@ duplicate_decls (newdecl, olddecl)
       DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
       DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
       DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
-      DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
+      if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+       SET_OVERLOADED_OPERATOR_CODE
+         (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
 
       /* Optionally warn about more than one declaration for the same
@@ -3611,6 +3581,8 @@ duplicate_decls (newdecl, olddecl)
       DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
       DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
       DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+      DECL_INITIALIZED_IN_CLASS_P (newdecl)
+        |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
       olddecl_friend = DECL_FRIEND_P (olddecl);
 
       /* Only functions have DECL_BEFRIENDING_CLASSES.  */
@@ -3654,6 +3626,9 @@ duplicate_decls (newdecl, olddecl)
        DECL_INLINE (olddecl) = 1;
       DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
 
+      /* Preserve abstractness on cloned [cd]tors.  */
+      DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
+
       if (! types_match)
        {
          DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
@@ -3850,8 +3825,9 @@ pushdecl (x)
          /* Or in the innermost namespace.  */
          if (! t)
            t = namespace_binding (name, DECL_CONTEXT (x));
-         /* Does it have linkage?  */
-         if (t && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+         /* Does it have linkage?  Note that if this isn't a DECL, it's an
+            OVERLOAD, which is OK.  */
+         if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
            t = NULL_TREE;
          if (t)
            different_binding_level = 1;
@@ -3903,7 +3879,9 @@ pushdecl (x)
          else if (TREE_CODE (t) == PARM_DECL)
            {
              if (DECL_CONTEXT (t) == NULL_TREE)
-               fatal ("parse errors have confused me too much");
+               /* This is probaby caused by too many errors, but calling
+                  abort will say that if errors have occurred.  */
+               abort ();
 
              /* Check for duplicate params.  */
              if (duplicate_decls (x, t))
@@ -4048,7 +4026,7 @@ pushdecl (x)
             warn if we later see static one.  */
          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
-         
+
          /* Bind the mangled name for the entity.  In the future, we
             should not need to do this; mangled names are an
             implementation detail of which the front-end should not
@@ -4443,9 +4421,8 @@ push_class_level_binding (name, x)
       else
        old_decl = BINDING_VALUE (binding);
 
-      /* There was already a binding for X containing fewer
-        functions than are named in X.  Find the previous
-        declaration of X on the class-shadowed list, and update it.  */
+      /* Find the previous binding of name on the class-shadowed
+         list, and update it.  */
       for (shadow = class_binding_level->class_shadowed;
           shadow;
           shadow = TREE_CHAIN (shadow))
@@ -4455,17 +4432,17 @@ push_class_level_binding (name, x)
            BINDING_VALUE (binding) = x;
            INHERITED_VALUE_BINDING_P (binding) = 0;
            TREE_TYPE (shadow) = x;
+           IDENTIFIER_CLASS_VALUE (name) = x;
            return;
          }
     }
 
   /* If we didn't replace an existing binding, put the binding on the
-     stack of bindings for the identifier, and update
-     IDENTIFIER_CLASS_VALUE.  */
+     stack of bindings for the identifier, and update the shadowed list.  */
   if (push_class_binding (name, x))
     {
       class_binding_level->class_shadowed
-       = tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
+       = tree_cons (name, NULL,
                     class_binding_level->class_shadowed);
       /* Record the value we are binding NAME to so that we can know
         what to pop later.  */
@@ -4744,7 +4721,7 @@ redeclaration_error_message (newdecl, olddecl)
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
       if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
-          && (DECL_TEMPLATE_RESULT (newdecl) 
+          && (DECL_TEMPLATE_RESULT (newdecl)
               != DECL_TEMPLATE_RESULT (olddecl))
           && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
           && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
@@ -5097,14 +5074,16 @@ define_label (filename, line, name)
 {
   tree decl = lookup_label (name);
   struct named_label_list *ent;
+  register struct binding_level *p;
 
   for (ent = named_labels; ent; ent = ent->next)
     if (ent->label_decl == decl)
       break;
 
-  /* After labels, make any new cleanups go into their
+  /* After labels, make any new cleanups in the function go into their
      own new (temporary) binding contour.  */
-  current_binding_level->more_cleanups_ok = 0;
+  for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+    p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
     cp_pedwarn ("label named wchar_t");
@@ -5151,7 +5130,7 @@ struct cp_switch
    mark the stack for garbage collection because it is only active
    during the processing of the body of a function, and we never
    collect at that point.  */
-   
+
 static struct cp_switch *switch_stack;
 
 /* Called right after a switch-statement condition is parsed.
@@ -5174,7 +5153,7 @@ void
 pop_switch ()
 {
   struct cp_switch *cs;
-  
+
   cs = switch_stack;
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
@@ -5184,23 +5163,24 @@ pop_switch ()
 /* Note that we've seen a definition of a case label, and complain if this
    is a bad place for one.  */
 
-void
+tree
 finish_case_label (low_value, high_value)
      tree low_value;
      tree high_value;
 {
-  tree cond;
+  tree cond, r;
+  register struct binding_level *p;
 
   if (! switch_stack)
     {
       if (high_value)
        error ("case label not within a switch statement");
       else if (low_value)
-       cp_error ("case label `%E' not within a switch statement", 
+       cp_error ("case label `%E' not within a switch statement",
                  low_value);
       else
        error ("`default' label not within a switch statement");
-      return;
+      return NULL_TREE;
     }
 
   if (processing_template_decl)
@@ -5210,8 +5190,7 @@ finish_case_label (low_value, high_value)
       /* For templates, just add the case label; we'll do semantic
         analysis at instantiation-time.  */
       label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      add_stmt (build_case_label (low_value, high_value, label));
-      return;
+      return add_stmt (build_case_label (low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -5219,14 +5198,19 @@ finish_case_label (low_value, high_value)
   if (cond && TREE_CODE (cond) == TREE_LIST)
     cond = TREE_VALUE (cond);
 
-  c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  if (r == error_mark_node)
+    r = NULL_TREE;
 
   check_switch_goto (switch_stack->level);
 
-  /* After labels, make any new cleanups go into their
+  /* After labels, make any new cleanups in the function go into their
      own new (temporary) binding contour.  */
-  current_binding_level->more_cleanups_ok = 0;
+  for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+    p->more_cleanups_ok = 0;
   current_function_return_value = NULL_TREE;
+
+  return r;
 }
 \f
 /* Return the list of declarations of the current level.
@@ -5468,7 +5452,8 @@ lookup_namespace_name (namespace, name)
                                         TREE_OPERAND (template_id, 1),
                                         /*in_decl=*/NULL_TREE,
                                         /*context=*/NULL_TREE,
-                                        /*entering_scope=*/0);
+                                        /*entering_scope=*/0,
+                                        /*complain=*/1);
          else if (DECL_FUNCTION_TEMPLATE_P (val)
                   || TREE_CODE (val) == OVERLOAD)
            val = lookup_template_function (val,
@@ -5549,16 +5534,15 @@ build_typename_type (context, name, fullname, base_type)
 {
   tree t;
   tree d;
-  struct hash_entrye;
+  struct hash_entry *e;
 
   static struct hash_table ht;
 
   if (!ht.table)
     {
       static struct hash_table *h = &ht;
-      if (!hash_table_init (&ht, &hash_newfunc, &typename_hash,
-                           &typename_compare))
-       fatal ("virtual memory exhausted");
+
+      hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare);
       ggc_add_tree_hash_table_root (&h, 1);
     }
 
@@ -5652,7 +5636,8 @@ make_typename_type (context, name, complain)
          return lookup_template_class (tmpl,
                                        TREE_OPERAND (fullname, 1),
                                        NULL_TREE, context,
-                                       /*entering_scope=*/0);
+                                       /*entering_scope=*/0,
+                                       /*complain=*/1);
        }
       else
        {
@@ -5693,6 +5678,15 @@ select_decl (binding, flags)
 {
   tree val;
   val = BINDING_VALUE (binding);
+
+  /* When we implicitly declare some builtin entity, we mark it
+     DECL_ANTICIPATED, so that we know to ignore it until it is
+     really declared.  */
+  if (val && DECL_P (val)
+      && DECL_LANG_SPECIFIC (val)
+      && DECL_ANTICIPATED (val))
+    return NULL_TREE;
+
   if (LOOKUP_NAMESPACES_ONLY (flags))
     {
       /* We are not interested in types. */
@@ -5937,7 +5931,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
       if (got_scope)
        goto done;
       else if (got_object && val)
-       from_obj = val;
+       {
+         from_obj = val;
+         val = NULL_TREE;
+       }
     }
   else
     {
@@ -6006,13 +6003,11 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
        {
          if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
              && TREE_CODE (val) == TYPE_DECL
-             && TREE_TYPE (from_obj) != TREE_TYPE (val))
-           {
-             cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
-                         name, got_object, TREE_TYPE (from_obj));
-             cp_pedwarn ("  does not match lookup in the current scope (`%#T')",
-                         TREE_TYPE (val));
-           }
+             && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
+           cp_pedwarn ("\
+lookup of `%D' in the scope of `%#T' (`%#D') \
+does not match lookup in the current scope (`%#D')",
+                       name, got_object, from_obj, val);
 
          /* We don't change val to from_obj if got_object depends on
             template parms because that breaks implicit typename for
@@ -6147,7 +6142,7 @@ end_only_namespace_names ()
    in the array RID_POINTERS.  NAME is the name used when looking
    up the builtin type.  TYPE is the _TYPE node for the builtin type.  */
 
-static void
+void
 record_builtin_type (rid_index, name, type)
      enum rid rid_index;
      const char *name;
@@ -6255,7 +6250,7 @@ typedef struct predefined_identifier
 /* Create all the predefined identifiers.  */
 
 static void
-initialize_predefined_identifiers () 
+initialize_predefined_identifiers ()
 {
   struct predefined_identifier *pid;
 
@@ -6303,13 +6298,11 @@ void
 init_decl_processing ()
 {
   tree fields[20];
-  int wchar_type_size;
-  tree array_domain_type;
 
   /* Check to see that the user did not specify an invalid combination
      of command-line options.  */
-  if (flag_new_abi && !flag_vtable_thunks)
-    fatal ("the new ABI requires vtable thunks");
+  if (!flag_vtable_thunks)
+    error ("the ABI requires vtable thunks");
 
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
@@ -6319,6 +6312,8 @@ init_decl_processing ()
   free_lang_status = &pop_cp_function_context;
   mark_lang_status = &mark_cp_function_context;
   lang_safe_from_p = &c_safe_from_p;
+  lang_dump_tree = &cp_dump_tree;
+  lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p;
 
   cp_parse_init ();
   init_decl2 ();
@@ -6373,72 +6368,8 @@ init_decl_processing ()
                                  void_type_node);
       pushdecl (fake_std_node);
     }
-  
-  /* Define `int' and `char' first so that dbx will output them first.  */
-  record_builtin_type (RID_INT, NULL_PTR, integer_type_node);
-  record_builtin_type (RID_CHAR, "char", char_type_node);
-
-  /* `signed' is the same as `int' */
-  record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node);
-  record_builtin_type (RID_LONG, "long int", long_integer_type_node);
-  record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
-  record_builtin_type (RID_MAX, "long unsigned int",
-                      long_unsigned_type_node);
-  record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
-  record_builtin_type (RID_MAX, "long long int",
-                      long_long_integer_type_node);
-  record_builtin_type (RID_MAX, "long long unsigned int",
-                      long_long_unsigned_type_node);
-  record_builtin_type (RID_MAX, "long long unsigned",
-                      long_long_unsigned_type_node);
-  record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
-  record_builtin_type (RID_MAX, "short unsigned int",
-                      short_unsigned_type_node); 
-  record_builtin_type (RID_MAX, "unsigned short",
-                      short_unsigned_type_node);
-
-  ptrdiff_type_node
-    = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
-  unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
-
-  /* Define both `signed char' and `unsigned char'.  */
-  record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
-  record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
-
-  /* `unsigned long' is the standard type for sizeof.
-     Note that stddef.h uses `unsigned long',
-     and this must agree, even if long and int are the same size.  */
-  c_size_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
-  signed_size_type_node = signed_type (c_size_type_node);
-  set_sizetype (c_size_type_node);
-
-  /* Create the widest literal types. */
-  widest_integer_literal_type_node = make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE,
-                       widest_integer_literal_type_node));
-
-  widest_unsigned_literal_type_node = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE,
-                       widest_unsigned_literal_type_node));
-
-  /* These are types that type_for_size and type_for_mode use.  */
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
-#endif
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
-  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
-#endif
 
-  build_common_tree_nodes_2 (flag_short_double);
+  c_common_nodes_and_builtins ();
 
   java_byte_type_node = record_builtin_java_type ("__java_byte", 8);
   java_short_type_node = record_builtin_java_type ("__java_short", 16);
@@ -6466,70 +6397,18 @@ init_decl_processing ()
   TREE_TYPE (boolean_true_node) = boolean_type_node;
 
   signed_size_zero_node = build_int_2 (0, 0);
-  record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
-  record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node);
-  record_builtin_type (RID_MAX, "long double", long_double_type_node);
-
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
-                       complex_integer_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
-                       complex_float_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
-                       complex_double_type_node));
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
-                       complex_long_double_type_node));
-
   TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype));
 
-  record_builtin_type (RID_VOID, NULL_PTR, void_type_node);
-  void_list_node = build_tree_list (NULL_TREE, void_type_node);
-  TREE_PARMLIST (void_list_node) = 1;
-
-  string_type_node = build_pointer_type (char_type_node);
-  const_string_type_node
-    = build_pointer_type (build_qualified_type (char_type_node,
-                                               TYPE_QUAL_CONST));
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
+
 #if 0
   record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
 #endif
 
-  /* Make a type to be the domain of a few array types
-     whose domains don't really matter.
-     200 is small enough that it always fits in size_t.  */
-  array_domain_type = build_index_type (build_int_2 (200, 0));
-
-  /* Make a type for arrays of characters.
-     With luck nothing will ever really depend on the length of this
-     array type.  */
-  char_array_type_node
-    = build_array_type (char_type_node, array_domain_type);
-
-  /* Likewise for arrays of ints.  */
-  int_array_type_node
-    = build_array_type (integer_type_node, array_domain_type);
-
-  if (flag_new_abi)
-    delta_type_node = ptrdiff_type_node;
-  else if (flag_huge_objects)
-    delta_type_node = long_integer_type_node;
-  else
-    delta_type_node = short_integer_type_node;
-
-  if (flag_new_abi)
-    vtable_index_type = ptrdiff_type_node;
-  else
-    vtable_index_type = delta_type_node;
+  delta_type_node = ptrdiff_type_node;
+  vtable_index_type = ptrdiff_type_node;
 
-  default_function_type
-    = build_function_type (integer_type_node, NULL_TREE);
-
-  ptr_type_node = build_pointer_type (void_type_node);
-  const_ptr_type_node
-    = build_pointer_type (build_qualified_type (void_type_node,
-                                               TYPE_QUAL_CONST));
   vtt_parm_type = build_pointer_type (const_ptr_type_node);
-  c_common_nodes_and_builtins ();
   lang_type_promotes_to = convert_type_from_ellipsis;
 
   void_ftype_ptr
@@ -6550,35 +6429,6 @@ init_decl_processing ()
   TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
   TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
 
-  /* This is special for C++ so functions can be overloaded.  */
-  wchar_type_node = get_identifier (flag_short_wchar
-                                   ? "short unsigned int"
-                                   : WCHAR_TYPE);
-  wchar_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (wchar_type_node));
-  wchar_type_size = TYPE_PRECISION (wchar_type_node);
-  if (TREE_UNSIGNED (wchar_type_node))
-    wchar_type_node = make_signed_type (wchar_type_size);
-  else
-    wchar_type_node = make_unsigned_type (wchar_type_size);
-  record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node);
-
-  /* Artificial declaration of wchar_t -- can be bashed */
-  wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"),
-                               wchar_type_node);
-  pushdecl (wchar_decl_node);
-
-  /* This is for wide string constants.  */
-  wchar_array_type_node
-    = build_array_type (wchar_type_node, array_domain_type);
-
-  wint_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
-
-  intmax_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
-  uintmax_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
-
   if (flag_vtable_thunks)
     {
       /* Make sure we get a unique function type, so we can give
@@ -6625,12 +6475,9 @@ init_decl_processing ()
   layout_type (vtbl_ptr_type_node);
   record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
 
-  if (flag_new_abi)
-    {
-      push_namespace (get_identifier ("__cxxabiv1"));
-      abi_node = current_namespace;
-      pop_namespace ();
-    }
+  push_namespace (get_identifier ("__cxxabiv1"));
+  abi_node = current_namespace;
+  pop_namespace ();
 
   global_type_node = make_node (LANG_TYPE);
   record_unknown_type (global_type_node, "global type");
@@ -6656,7 +6503,7 @@ init_decl_processing ()
   }
 
   abort_fndecl
-    = build_library_fn_ptr ("__pure_virtual", void_ftype);
+    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -6725,6 +6572,7 @@ init_decl_processing ()
 
   ggc_add_tree_root (&current_lang_name, 1);
   ggc_add_tree_root (&static_aggregates, 1);
+  ggc_add_tree_root (&free_bindings, 1);
 }
 
 /* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
@@ -6744,11 +6592,11 @@ cp_make_fname_decl (id, name, type_dep)
   tree decl, type, init;
   size_t length = strlen (name);
   tree domain = NULL_TREE;
-  
+
   if (!processing_template_decl)
     type_dep = 0;
   if (!type_dep)
-    domain = build_index_type (build_int_2 (length, 0));
+    domain = build_index_type (size_int (length));
 
   type =  build_cplus_array_type
           (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
@@ -6775,7 +6623,7 @@ cp_make_fname_decl (id, name, type_dep)
     }
   DECL_INITIAL (decl) = init;
   cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
-  
+
   /* We will have to make sure we only emit this, if it is actually used. */
   return decl;
 }
@@ -6807,7 +6655,7 @@ builtin_function (name, type, code, class, libname)
 
   /* All builtins that don't begin with an `_' should go in the `std'
      namespace.  */
-  if (flag_honor_std && name[0] != '_') 
+  if (flag_honor_std && name[0] != '_')
     {
       push_namespace (std_identifier);
       DECL_CONTEXT (decl) = std_node;
@@ -6821,7 +6669,7 @@ builtin_function (name, type, code, class, libname)
      function in the namespace.  */
   if (libname)
     DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
-  make_function_rtl (decl);
+  make_decl_rtl (decl, NULL);
 
   /* Warn if a function in the namespace for users
      is used without an occasion to consider it declared.  */
@@ -6859,7 +6707,7 @@ build_library_fn (name, type)
      tree type;
 {
   tree fn = build_library_fn_1 (name, ERROR_MARK, type);
-  make_function_rtl (fn);
+  make_decl_rtl (fn, NULL);
   return fn;
 }
 
@@ -6875,7 +6723,7 @@ build_cp_library_fn (name, operator_code, type)
   TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
   DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
   set_mangled_name_for_decl (fn);
-  make_function_rtl (fn);
+  make_decl_rtl (fn, NULL);
   return fn;
 }
 
@@ -6921,7 +6769,7 @@ push_cp_library_fn (operator_code, type)
      enum tree_code operator_code;
      tree type;
 {
-  tree fn = build_cp_library_fn (ansi_opname (operator_code), 
+  tree fn = build_cp_library_fn (ansi_opname (operator_code),
                                 operator_code,
                                 type);
   pushdecl (fn);
@@ -6989,7 +6837,7 @@ fixup_anonymous_aggr (t)
 
   /* ISO C++ 9.5.3.  Anonymous unions may not have function members.  */
   if (TYPE_METHODS (t))
-    error ("an anonymous union cannot have function members");
+    cp_error_at ("an anonymous union cannot have function members", t);
 }
 
 /* Make sure that a declaration with no declarator is well-formed, i.e.
@@ -7003,6 +6851,7 @@ check_tag_decl (declspecs)
 {
   int found_type = 0;
   int saw_friend = 0;
+  int saw_typedef = 0;
   tree ob_modifier = NULL_TREE;
   register tree link;
   register tree t = NULL_TREE;
@@ -7012,19 +6861,30 @@ check_tag_decl (declspecs)
       register tree value = TREE_VALUE (link);
 
       if (TYPE_P (value)
+         || TREE_CODE (value) == TYPE_DECL
          || (TREE_CODE (value) == IDENTIFIER_NODE
              && IDENTIFIER_GLOBAL_VALUE (value)
-             && TYPE_P (IDENTIFIER_GLOBAL_VALUE (value))))
+             && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (value)) == TYPE_DECL))
        {
          ++found_type;
 
-         if ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
-             || TREE_CODE (value) == ENUMERAL_TYPE)
+         if (found_type == 2 && TREE_CODE (value) == IDENTIFIER_NODE)
+           {
+             if (! in_system_header)
+               cp_pedwarn ("redeclaration of C++ built-in type `%T'", value);
+             return NULL_TREE;
+           }
+
+         if (TYPE_P (value)
+             && ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
+                 || TREE_CODE (value) == ENUMERAL_TYPE))
            {
              my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
              t = value;
            }
        }
+      else if (value == ridpointers[(int) RID_TYPEDEF])
+        saw_typedef = 1;
       else if (value == ridpointers[(int) RID_FRIEND])
        {
          if (current_class_type == NULL_TREE
@@ -7058,6 +6918,27 @@ check_tag_decl (declspecs)
           && TYPE_NAME (t)
           && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
     {
+      /* 7/3 In a simple-declaration, the optional init-declarator-list
+         can be omitted only when declaring a class (clause 9) or
+         enumeration (7.2), that is, when the decl-specifier-seq contains
+         either a class-specifier, an elaborated-type-specifier with
+         a class-key (9.1), or an enum-specifier.  In these cases and
+         whenever a class-specifier or enum-specifier is present in the
+         decl-specifier-seq, the identifiers in these specifiers are among
+         the names being declared by the declaration (as class-name,
+         enum-names, or enumerators, depending on the syntax).  In such
+         cases, and except for the declaration of an unnamed bit-field (9.6),
+         the decl-specifier-seq shall introduce one or more names into the
+         program, or shall redeclare a name introduced by a previous
+         declaration.  [Example:
+             enum { };            // ill-formed
+             typedef class { };   // ill-formed
+         --end example]  */
+      if (saw_typedef)
+        {
+          error ("Missing type-name in typedef-declaration.");
+          return NULL_TREE;
+        }
       /* Anonymous unions are objects, so they can have specifiers.  */;
       SET_ANON_AGGR_TYPE_P (t);
 
@@ -7342,17 +7223,7 @@ start_decl_1 (decl)
   if (type == error_mark_node)
     return;
 
-  /* If this type of object needs a cleanup, but we're not allowed to
-     add any more objects with cleanups to the current scope, create a
-     new binding level.  */
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
-      && current_binding_level->more_cleanups_ok == 0)
-    {
-      keep_next_level (2);
-      pushlevel (1);
-      clear_last_expr ();
-      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
-    }
+  maybe_push_cleanup_level (type);
 
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
@@ -7383,7 +7254,7 @@ start_decl_1 (decl)
       && TREE_CODE (decl) != TYPE_DECL
       && TREE_CODE (decl) != TEMPLATE_DECL
       && type != error_mark_node
-      && IS_AGGR_TYPE (type) 
+      && IS_AGGR_TYPE (type)
       && ! DECL_EXTERNAL (decl))
     {
       if ((! processing_template_decl || ! uses_template_parms (type))
@@ -7643,6 +7514,7 @@ maybe_commonize_var (decl)
         inlining of such functions.  */
       current_function_cannot_inline
        = "function with static variable cannot be inline";
+      DECL_UNINLINABLE (current_function_decl) = 1;
 
       /* If flag_weak, we don't need to mess with this, as we can just
         make the function weak, and let it refer to its unique local
@@ -7665,8 +7537,7 @@ maybe_commonize_var (decl)
             which we can't if it has been initialized.  */
 
          if (TREE_PUBLIC (decl))
-           DECL_ASSEMBLER_NAME (decl)
-             = build_static_name (current_function_decl, DECL_NAME (decl));
+           DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
          else
            {
              cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
@@ -7754,14 +7625,13 @@ check_initializer (decl, init)
 
       DECL_INITIAL (decl) = init;
 
-      /* This will keep us from needing to worry about our obstacks.  */
       my_friendly_assert (init != NULL_TREE, 149);
       init = NULL_TREE;
     }
   else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
     {
       if (TREE_STATIC (decl))
-       make_decl_rtl (decl, NULL_PTR, toplevel_bindings_p ());
+       make_decl_rtl (decl, NULL_PTR);
       grok_reference_init (decl, type, init);
       init = NULL_TREE;
     }
@@ -7888,7 +7758,7 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
   /* If we're deferring the variable, just make RTL.  Do not actually
      emit the variable.  */
   if (defer_p)
-    make_decl_rtl (decl, asmspec, toplev);
+    make_decl_rtl (decl, asmspec);
   /* If we're not deferring, go ahead and assemble the variable.  */
   else
     rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
@@ -7906,7 +7776,7 @@ maybe_inject_for_scope_var (decl)
 {
   if (!DECL_NAME (decl))
     return;
-  
+
   if (current_binding_level->is_for_scope)
     {
       struct binding_level *outer
@@ -7984,7 +7854,7 @@ initialize_local_var (decl, init, flags)
          saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
          current_stmt_tree ()->stmts_are_full_exprs_p = 1;
          finish_expr_stmt (build_aggr_init (decl, init, flags));
-         current_stmt_tree ()->stmts_are_full_exprs_p = 
+         current_stmt_tree ()->stmts_are_full_exprs_p =
            saved_stmts_are_full_exprs_p;
        }
 
@@ -8082,7 +7952,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
       && CP_DECL_CONTEXT (decl) == current_class_type
       && TYPE_BEING_DEFINED (current_class_type)
       && (DECL_INITIAL (decl) || init))
-    DECL_DEFINED_IN_CLASS_P (decl) = 1;
+    DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
   if (TREE_CODE (decl) == VAR_DECL
       && DECL_CONTEXT (decl)
@@ -8098,9 +7968,9 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
 
   if (type == error_mark_node)
     return;
-  
+
   /* Add this declaration to the statement-tree.  */
-  if (building_stmt_tree () 
+  if (building_stmt_tree ()
       && at_function_scope_p ()
       && TREE_CODE (decl) != RESULT_DECL)
     add_decl_stmt (decl);
@@ -8169,7 +8039,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
         grokclassfn.  Lay this out fresh.  */
       DECL_RTL (TREE_TYPE (decl)) = NULL_RTX;
       DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
-      make_decl_rtl (decl, asmspec, 0);
+      make_decl_rtl (decl, asmspec);
     }
 
   /* Deduce size of array from initialization, if not already known.  */
@@ -8773,7 +8643,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
              object, type);
   if (friendp)
     cp_error_at ("`%D' declared as a friend", object);
-  if (raises)
+  if (raises && !TYPE_PTRFN_P (TREE_TYPE (object))
+      && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))
     cp_error_at ("`%D' declared with an exception specification", object);
 }
 
@@ -8940,6 +8811,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
           orig_declarator);
       else
        {
+         tree fns = TREE_OPERAND (orig_declarator, 0);
+         tree args = TREE_OPERAND (orig_declarator, 1);
+
          if (PROCESSING_REAL_TEMPLATE_DECL_P ())
            {
              /* Something like `template <class T> friend void f<T>()'.  */
@@ -8952,10 +8826,22 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
          /* A friend declaration of the form friend void f<>().  Record
             the information in the TEMPLATE_ID_EXPR.  */
          SET_DECL_IMPLICIT_INSTANTIATION (decl);
-         DECL_TEMPLATE_INFO (decl)
-           = tree_cons (TREE_OPERAND (orig_declarator, 0),
-                        TREE_OPERAND (orig_declarator, 1),
-                        NULL_TREE);
+
+          if (TREE_CODE (fns) == COMPONENT_REF)
+            {
+              /* Due to bison parser ickiness, we will have already looked
+                 up an operator_name or PFUNCNAME within the current class
+                 (see template_id in parse.y). If the current class contains
+                 such a name, we'll get a COMPONENT_REF here. Undo that. */
+
+              my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
+                                  == current_class_type, 20001120);
+              fns = TREE_OPERAND (fns, 1);
+            }
+         my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
+                             || TREE_CODE (fns) == LOOKUP_EXPR
+                             || TREE_CODE (fns) == OVERLOAD, 20001120);
+         DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
 
          if (has_default_arg)
            {
@@ -8978,8 +8864,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
   /* Plain overloading: will not be grok'd by grokclassfn.  */
   if (! ctype && ! processing_template_decl
-      && !DECL_EXTERN_C_P (decl)
-      && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
+      && (! DECL_EXTERN_C_P (decl) || DECL_OVERLOADED_OPERATOR_P (decl))
+      && ! DECL_USE_TEMPLATE (decl))
     set_mangled_name_for_decl (decl);
 
   if (funcdef_flag)
@@ -9059,12 +8945,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
     return decl;
 
   if (virtualp)
-    {
-      DECL_VIRTUAL_P (decl) = 1;
-      if (DECL_VINDEX (decl) == NULL_TREE)
-       DECL_VINDEX (decl) = error_mark_node;
-      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
-    }
+    DECL_VIRTUAL_P (decl) = 1;
 
   return decl;
 }
@@ -9094,13 +8975,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
       /* DECL_ASSEMBLER_NAME is needed only for full-instantiated
         templates.  */
       if (!uses_template_parms (decl))
-       {
-         if (flag_new_abi)
-           DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
-         else
-           DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype,
-                                                           declarator);
-       }
+       DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
     }
   else
     {
@@ -9124,14 +8999,8 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
        set_decl_namespace (decl, context, 0);
 
       context = DECL_CONTEXT (decl);
-      if (declarator && context && current_lang_name != lang_name_c) 
-       {
-         if (flag_new_abi)
-           DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
-         else
-           DECL_ASSEMBLER_NAME (decl) 
-             = build_static_name (context, declarator);
-       }
+      if (declarator && context && current_lang_name != lang_name_c)
+       DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
     }
 
   if (in_namespace)
@@ -9196,9 +9065,11 @@ build_ptrmemfunc_type (type)
 {
   tree fields[4];
   tree t;
-  tree u;
   tree unqualified_variant = NULL_TREE;
 
+  if (type == error_mark_node)
+    return type;
+
   /* If a canonical type already exists for this type, use it.  We use
      this method instead of type_hash_canon, because it only does a
      simple equality check on the list of field members.  */
@@ -9218,30 +9089,10 @@ build_ptrmemfunc_type (type)
   /* ... and not really an aggregate.  */
   SET_IS_AGGR_TYPE (t, 0);
 
-  if (!flag_new_abi)
-    {
-      u = make_aggr_type (UNION_TYPE);
-      SET_IS_AGGR_TYPE (u, 0);
-      fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
-      fields[1] = build_decl (FIELD_DECL, delta2_identifier,
-                             delta_type_node);
-      finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
-      TYPE_NAME (u) = NULL_TREE;
-
-      fields[0] = build_decl (FIELD_DECL, delta_identifier,
-                             delta_type_node);
-      fields[1] = build_decl (FIELD_DECL, index_identifier,
-                             delta_type_node);
-      fields[2] = build_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
-      finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
-    }
-  else
-    {
-      fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
-      fields[1] = build_decl (FIELD_DECL, delta_identifier,
-                             delta_type_node);
-      finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
-    }
+  fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
+  fields[1] = build_decl (FIELD_DECL, delta_identifier,
+                         delta_type_node);
+  finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
 
   /* Zap out the name so that the back-end will give us the debugging
      information for this anonymous RECORD_TYPE.  */
@@ -9513,17 +9364,15 @@ create_array_type_for_decl (name, type, size)
 
 /* Check that it's OK to declare a function with the indicated TYPE.
    SFK indicates the kind of special function (if any) that this
-   function is.  CTYPE is the class of which this function is a
-   member.  OPTYPE is the type given in a conversion operator
+   function is.  OPTYPE is the type given in a conversion operator
    declaration.  Returns the actual return type of the function; that
    may be different than TYPE if an error occurs, or for certain
    special functions.  */
 
 static tree
-check_special_function_return_type (sfk, type, ctype, optype)
+check_special_function_return_type (sfk, type, optype)
      special_function_kind sfk;
      tree type;
-     tree ctype;
      tree optype;
 {
   switch (sfk)
@@ -9531,10 +9380,9 @@ check_special_function_return_type (sfk, type, ctype, optype)
     case sfk_constructor:
       if (type)
        cp_error ("return type specification for constructor invalid");
-       
-      /* In the old ABI, we return `this'; in the new ABI we don't
-        bother.  */
-      type = flag_new_abi ? void_type_node : build_pointer_type        (ctype);
+
+      /* In the new ABI constructors do not return a value.  */
+      type = void_type_node;
       break;
 
     case sfk_destructor:
@@ -9852,7 +9700,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                ctor_return_type = TREE_TYPE (dname);
                sfk = sfk_conversion;
                if (IDENTIFIER_GLOBAL_VALUE (dname)
-                   && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname)) 
+                   && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
                        == TYPE_DECL))
                  name = IDENTIFIER_POINTER (dname);
                else
@@ -10144,7 +9992,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   if (sfk != sfk_none)
     type = check_special_function_return_type (sfk, type,
-                                              ctor_return_type,
                                               ctor_return_type);
   else if (type == NULL_TREE)
     {
@@ -10400,10 +10247,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
        ;
       else if (decl_context == FIELD
-              /* C++ allows static class elements  */
-              && RIDBIT_SETP (RID_STATIC, specbits))
-       /* C++ also allows inlines and signed and unsigned elements,
-          but in those cases we don't come in here.  */
+              /* C++ allows static class elements  */
+              && RIDBIT_SETP (RID_STATIC, specbits))
+       /* C++ also allows inlines and signed and unsigned elements,
+          but in those cases we don't come in here.  */
        ;
       else
        {
@@ -10423,7 +10270,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  if (IDENTIFIER_TYPENAME_P (tmp))
                    {
                      if (IDENTIFIER_GLOBAL_VALUE (tmp)
-                         && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp)) 
+                         && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
                              == TYPE_DECL))
                        name = IDENTIFIER_POINTER (tmp);
                      else
@@ -10566,7 +10413,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            type = create_array_type_for_decl (dname, type, size);
 
            /* VLAs never work as fields. */
-           if (decl_context == FIELD && !processing_template_decl 
+           if (decl_context == FIELD && !processing_template_decl
                && TREE_CODE (type) == ARRAY_TYPE
                && TYPE_DOMAIN (type) != NULL_TREE
                && !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
@@ -10685,10 +10532,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                        cp_error ("constructors may not be `%s'",
                                  IDENTIFIER_POINTER (TREE_VALUE (quals)));
                        quals = NULL_TREE;
-                     }
+                     }
                    {
                      RID_BIT_TYPE tmp_bits;
-                     bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE));
+                     memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));
                      RIDBIT_RESET (RID_INLINE, tmp_bits);
                      RIDBIT_RESET (RID_STATIC, tmp_bits);
                      if (RIDBIT_ANY_SET (tmp_bits))
@@ -10734,7 +10581,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            /* FIXME: This is where default args should be fully
               processed.  */
 
-           arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
+           arg_types = grokparms (inner_parms);
 
            if (declarator && flags == DTOR_FLAG)
              {
@@ -10929,7 +10776,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            t = ctype;
            while (t != NULL_TREE && CLASS_TYPE_P (t))
              {
-               /* You're supposed to have one `template <...>' 
+               /* You're supposed to have one `template <...>'
                   for every template class, but you don't need one
                   for a full specialization.  For example:
 
@@ -10941,14 +10788,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                   the definition of `S<int>::f'.  */
                if (CLASSTYPE_TEMPLATE_INFO (t)
                    && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
-                       || uses_template_parms (CLASSTYPE_TI_ARGS (t))))
+                       || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
+                   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
                  template_count += 1;
 
                t = TYPE_MAIN_DECL (t);
-               if (DECL_LANG_SPECIFIC (t))
-                 t = DECL_CONTEXT (t);
-               else
-                 t = NULL_TREE;
+               t = DECL_CONTEXT (t);
              }
 
            if (sname == NULL_TREE)
@@ -10973,8 +10818,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  }
                else if (TREE_CODE (type) == FUNCTION_TYPE)
                  {
-                   if (current_class_type == NULL_TREE
-                       || friendp)
+                   if (current_class_type == NULL_TREE || friendp)
                      type = build_cplus_method_type (ctype, TREE_TYPE (type),
                                                      TYPE_ARG_TYPES (type));
                    else
@@ -11000,17 +10844,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                      }
                    type = build_offset_type (ctype, type);
                  }
-               else if (uses_template_parms (ctype))
-                 {
-                    if (TREE_CODE (type) == FUNCTION_TYPE)
-                     type
-                       = build_cplus_method_type (ctype, TREE_TYPE (type),
-                                                  TYPE_ARG_TYPES (type));
-                 }
                else
-                 {
-                   cp_error ("structure `%T' not yet defined", ctype);
-                   return error_mark_node;
+                 {
+                   incomplete_type_error (NULL_TREE, ctype);
+                   return error_mark_node;
                  }
 
                declarator = sname;
@@ -11172,24 +11009,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
              = TYPE_IDENTIFIER (type);
 
-         if (flag_new_abi) 
-           DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
-         else
-           {
-             /* XXX Temporarily set the scope.
-                When returning, start_decl expects it as NULL_TREE,
-                and will then then set it using pushdecl. */
-             my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404);
-             if (current_class_type)
-               DECL_CONTEXT (decl) = current_class_type;
-             else
-               DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
-             
-             DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);
-             DECL_ASSEMBLER_NAME (decl)
-               = get_identifier (build_overload_name (type, 1, 1));
-             DECL_CONTEXT (decl) = NULL_TREE;
-           }
+         DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
 
          /* FIXME remangle member functions; member functions of a
             type with external linkage have external linkage.  */
@@ -11263,7 +11083,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            }
 
          /* Until core issue 180 is resolved, allow 'friend typename A::B'.
-            But don't allow implicit typenames.  */
+            But don't allow implicit typenames except with a class-key.  */
          if (!current_aggr && (TREE_CODE (type) != TYPENAME_TYPE
                                || IMPLICIT_TYPENAME_P (type)))
            {
@@ -11283,12 +11103,15 @@ friend declaration requires class-key, i.e. `friend %#T'",
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
            {
+             decl_type_access_control (TYPE_NAME (type));
+
              /* A friendly class?  */
              if (current_class_type)
                make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
              else
                cp_error ("trying to make class `%T' a friend of global scope",
                          type);
+
              type = void_type_node;
            }
        }
@@ -11363,11 +11186,6 @@ friend declaration requires class-key, i.e. `friend %#T'",
        type = build_pointer_type (type);
       else if (TREE_CODE (type) == OFFSET_TYPE)
        type = build_pointer_type (type);
-      else if (TREE_CODE (type) == VOID_TYPE && declarator)
-       {
-         error ("declaration of `%s' as void", name);
-         return NULL_TREE;
-       }
     }
 
   {
@@ -11487,15 +11305,8 @@ friend declaration requires class-key, i.e. `friend %#T'",
                /* The constructor can be called with exactly one
                   parameter if there is at least one parameter, and
                   any subsequent parameters have default arguments.
-                  We don't look at the first parameter, which is
-                  really just the `this' parameter for the new
-                  object.  */
-               tree arg_types =
-                 TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
-
-               /* Skip the `in_chrg' argument too, if present.  */
-               if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-                 arg_types = TREE_CHAIN (arg_types);
+                  Ignore any compiler-added parms.  */
+               tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
 
                if (arg_types == void_list_node
                    || (arg_types
@@ -11833,25 +11644,13 @@ require_complete_types_for_parms (parms)
 {
   for (; parms; parms = TREE_CHAIN (parms))
     {
-      tree type = TREE_TYPE (parms);
-
-      /* Try to complete the TYPE.  */
-      type = complete_type (type);
-
-      if (type == error_mark_node)
-       continue;
-
-      if (!COMPLETE_TYPE_P (type))
-       {
-         if (DECL_NAME (parms))
-           error ("parameter `%s' has incomplete type",
-                  IDENTIFIER_POINTER (DECL_NAME (parms)));
-         else
-           error ("parameter has incomplete type");
-         TREE_TYPE (parms) = error_mark_node;
-       }
-      else
+      if (VOID_TYPE_P (TREE_TYPE (parms)))
+        /* grokparms will have already issued an error */
+        TREE_TYPE (parms) = error_mark_node;
+      else if (complete_type_or_else (TREE_TYPE (parms), parms))
        layout_decl (parms, 0);
+      else
+        TREE_TYPE (parms) = error_mark_node;
     }
 }
 
@@ -11965,7 +11764,7 @@ check_default_argument (decl, arg)
 
      The keyword `this' shall not be used in a default argument of a
      member function.  */
-  var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn, 
+  var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn,
                                      NULL);
   if (var)
     {
@@ -11982,224 +11781,132 @@ check_default_argument (decl, arg)
    Given the list of things declared inside the parens,
    return a list of types.
 
-   The list we receive can have three kinds of elements:
-   an IDENTIFIER_NODE for names given without types,
-   a TREE_LIST node for arguments given as typespecs or names with typespecs,
-   or void_type_node, to mark the end of an argument list
-   when additional arguments are not permitted (... was not used).
-
-   FUNCDEF_FLAG is nonzero for a function definition, 0 for
-   a mere declaration.  A nonempty identifier-list gets an error message
-   when FUNCDEF_FLAG is zero.
-   If FUNCDEF_FLAG is 1, then parameter types must be complete.
-   If FUNCDEF_FLAG is -1, then parameter types may be incomplete.
-
-   If all elements of the input list contain types,
-   we return a list of the types.
-   If all elements contain no type (except perhaps a void_type_node
-   at the end), we return a null list.
-   If some have types and some do not, it is an error, and we
-   return a null list.
-
-   Also set last_function_parms to either
-   a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs.
-   A list of names is converted to a chain of PARM_DECLs
-   by store_parm_decls so that ultimately it is always a chain of decls.
-
-   Note that in C++, parameters can take default values.  These default
-   values are in the TREE_PURPOSE field of the TREE_LIST.  It is
-   an error to specify default values which are followed by parameters
-   that have no default values, or an ELLIPSES.  For simplicities sake,
-   only parameters which are specified with their types can take on
-   default values.  */
+   We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
+   flag. If unset, we append void_list_node. A parmlist declared
+   as `(void)' is accepted as the empty parmlist.
+
+   Also set last_function_parms to the chain of PARM_DECLs.  */
 
 static tree
-grokparms (first_parm, funcdef_flag)
+grokparms (first_parm)
      tree first_parm;
-     int funcdef_flag;
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
+  int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
+  tree parm, chain;
+  int any_error = 0;
 
-  if (first_parm != NULL_TREE
-      && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
-    {
-      if (! funcdef_flag)
-       pedwarn ("parameter names (without types) in function declaration");
-      last_function_parms = first_parm;
-      return NULL_TREE;
-    }
-  else if (first_parm != NULL_TREE
-          && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
-          && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
-    my_friendly_abort (145);
-  else
-    {
-      /* Types were specified.  This is a list of declarators
-        each represented as a TREE_LIST node.  */
-      register tree parm, chain;
-      int any_init = 0, any_error = 0;
-
-      if (first_parm != NULL_TREE)
-       {
-         tree last_result = NULL_TREE;
-         tree last_decl = NULL_TREE;
+  my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
 
-         for (parm = first_parm; parm != NULL_TREE; parm = chain)
-           {
-             tree type = NULL_TREE, list_node = parm;
-             register tree decl = TREE_VALUE (parm);
-             tree init = TREE_PURPOSE (parm);
-
-             chain = TREE_CHAIN (parm);
-             /* @@ weak defense against parse errors.  */
-             if (TREE_CODE (decl) != VOID_TYPE
-                 && TREE_CODE (decl) != TREE_LIST)
-               {
-                 /* Give various messages as the need arises.  */
-                 if (TREE_CODE (decl) == STRING_CST)
-                   cp_error ("invalid string constant `%E'", decl);
-                 else if (TREE_CODE (decl) == INTEGER_CST)
-                   error ("invalid integer constant in parameter list, did you forget to give parameter name?");
-                 continue;
-               }
+  for (parm = first_parm; parm != NULL_TREE; parm = chain)
+    {
+      tree type = NULL_TREE;
+      register tree decl = TREE_VALUE (parm);
+      tree init = TREE_PURPOSE (parm);
+
+      chain = TREE_CHAIN (parm);
+      /* @@ weak defense against parse errors.  */
+      if (TREE_CODE (decl) != VOID_TYPE
+         && TREE_CODE (decl) != TREE_LIST)
+       {
+         /* Give various messages as the need arises.  */
+         if (TREE_CODE (decl) == STRING_CST)
+           cp_error ("invalid string constant `%E'", decl);
+         else if (TREE_CODE (decl) == INTEGER_CST)
+           error ("invalid integer constant in parameter list, did you forget to give parameter name?");
+         continue;
+       }
 
-             if (TREE_CODE (decl) != VOID_TYPE)
-               {
-                 decl = grokdeclarator (TREE_VALUE (decl),
-                                        TREE_PURPOSE (decl),
-                                        PARM, init != NULL_TREE,
-                                        NULL_TREE);
-                 if (! decl || TREE_TYPE (decl) == error_mark_node)
-                   continue;
-
-                 /* Top-level qualifiers on the parameters are
-                    ignored for function types.  */
-                 type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
-
-                 if (TREE_CODE (type) == VOID_TYPE)
-                   decl = void_type_node;
-                 else if (TREE_CODE (type) == METHOD_TYPE)
-                   {
-                     if (DECL_NAME (decl))
-                       /* Cannot use the decl here because
-                          we don't have DECL_CONTEXT set up yet.  */
-                       cp_error ("parameter `%D' invalidly declared method type",
-                                 DECL_NAME (decl));
-                     else
-                       error ("parameter invalidly declared method type");
-                     type = build_pointer_type (type);
-                     TREE_TYPE (decl) = type;
-                   }
-                 else if (TREE_CODE (type) == OFFSET_TYPE)
-                   {
-                     if (DECL_NAME (decl))
-                       cp_error ("parameter `%D' invalidly declared offset type",
-                                 DECL_NAME (decl));
-                     else
-                       error ("parameter invalidly declared offset type");
-                     type = build_pointer_type (type);
-                     TREE_TYPE (decl) = type;
-                   }
-                  else if (abstract_virtuals_error (decl, type))
-                   any_error = 1;  /* Seems like a good idea. */
-                 else if (POINTER_TYPE_P (type))
-                   {
-                     tree t = type;
-                     while (POINTER_TYPE_P (t)
-                            || (TREE_CODE (t) == ARRAY_TYPE
-                                && TYPE_DOMAIN (t) != NULL_TREE))
-                       t = TREE_TYPE (t);
-                     if (TREE_CODE (t) == ARRAY_TYPE)
-                       cp_error ("parameter type `%T' includes %s to array of unknown bound",
-                                 type,
-                                 TYPE_PTR_P (type) ? "pointer" : "reference");
-                   }
-               }
+      if (parm == void_list_node)
+        break;
 
-             if (TREE_CODE (decl) == VOID_TYPE)
-               {
-                 if (result == NULL_TREE)
-                   {
-                     result = void_list_node;
-                     last_result = result;
-                   }
-                 else
-                   {
-                     TREE_CHAIN (last_result) = void_list_node;
-                     last_result = void_list_node;
-                   }
-                 if (chain
-                     && (chain != void_list_node || TREE_CHAIN (chain)))
-                   error ("`void' in parameter list must be entire list");
-                 break;
-               }
+      decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
+                    PARM, init != NULL_TREE, NULL_TREE);
+      if (! decl || TREE_TYPE (decl) == error_mark_node)
+        continue;
 
-             /* Since there is a prototype, args are passed in their own types.  */
-             DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
-             if (PROMOTE_PROTOTYPES
-                 && (TREE_CODE (type) == INTEGER_TYPE
-                     || TREE_CODE (type) == ENUMERAL_TYPE)
-                 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
-               DECL_ARG_TYPE (decl) = integer_type_node;
-             if (!any_error && init)
-               {
-                 any_init++;
-                 init = check_default_argument (decl, init);
-               }
-             else
-               init = NULL_TREE;
+      type = TREE_TYPE (decl);
+      if (VOID_TYPE_P (type))
+        {
+          if (same_type_p (type, void_type_node)
+              && !DECL_NAME (decl) && !result && !chain && !ellipsis)
+            /* this is a parmlist of `(void)', which is ok.  */
+            break;
+          incomplete_type_error (decl, type);
+         /* It's not a good idea to actually create parameters of
+            type `void'; other parts of the compiler assume that a
+            void type terminates the parameter list.  */
+         type = error_mark_node;
+         TREE_TYPE (decl) = error_mark_node;
+        }
 
-             if (decls == NULL_TREE)
-               {
-                 decls = decl;
-                 last_decl = decls;
-               }
-             else
-               {
-                 TREE_CHAIN (last_decl) = decl;
-                 last_decl = decl;
-               }
-             list_node = tree_cons (init, type, NULL_TREE);
-             if (result == NULL_TREE)
-               {
-                 result = list_node;
-                 last_result = result;
-               }
-             else
-               {
-                 TREE_CHAIN (last_result) = list_node;
-                 last_result = list_node;
-               }
+      if (type != error_mark_node)
+       {
+         /* Top-level qualifiers on the parameters are
+            ignored for function types.  */
+         type = TYPE_MAIN_VARIANT (type);
+         if (TREE_CODE (type) == METHOD_TYPE)
+           {
+             cp_error ("parameter `%D' invalidly declared method type", decl);
+             type = build_pointer_type (type);
+             TREE_TYPE (decl) = type;
+           }
+         else if (TREE_CODE (type) == OFFSET_TYPE)
+           {
+             cp_error ("parameter `%D' invalidly declared offset type", decl);
+             type = build_pointer_type (type);
+             TREE_TYPE (decl) = type;
+           }
+         else if (abstract_virtuals_error (decl, type))
+           any_error = 1;  /* Seems like a good idea. */
+         else if (POINTER_TYPE_P (type))
+           {
+             /* [dcl.fct]/6, parameter types cannot contain pointers
+                (references) to arrays of unknown bound.  */
+             tree t = TREE_TYPE (type);
+             int ptr = TYPE_PTR_P (type);
+
+              while (1)
+                {
+                  if (TYPE_PTR_P (t))
+                    ptr = 1;
+                  else if (TREE_CODE (t) != ARRAY_TYPE)
+                    break;
+                  else if (!TYPE_DOMAIN (t))
+                   break;
+                 t = TREE_TYPE (t);
+               }
+             if (TREE_CODE (t) == ARRAY_TYPE)
+               cp_error ("parameter `%D' includes %s to array of unknown bound `%T'",
+                         decl, ptr ? "pointer" : "reference", t);
            }
-         if (last_result)
-           TREE_CHAIN (last_result) = NULL_TREE;
-         /* If there are no parameters, and the function does not end
-            with `...', then last_decl will be NULL_TREE.  */
-         if (last_decl != NULL_TREE)
-           TREE_CHAIN (last_decl) = NULL_TREE;
+
+         DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
+         if (PROMOTE_PROTOTYPES
+             && (TREE_CODE (type) == INTEGER_TYPE
+                 || TREE_CODE (type) == ENUMERAL_TYPE)
+             && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+           DECL_ARG_TYPE (decl) = integer_type_node;
+         if (!any_error && init)
+           init = check_default_argument (decl, init);
+         else
+           init = NULL_TREE;
        }
-    }
 
+      TREE_CHAIN (decl) = decls;
+      decls = decl;
+      result = tree_cons (init, type, result);
+    }
+  decls = nreverse (decls);
+  result = nreverse (result);
+  if (!ellipsis)
+    result = chainon (result, void_list_node);
   last_function_parms = decls;
 
   return result;
 }
 
-/* Called from the parser to update an element of TYPE_ARG_TYPES for some
-   FUNCTION_TYPE with the newly parsed version of its default argument, which
-   was previously digested as text.  See snarf_defarg et al in lex.c.  */
-
-void
-replace_defarg (arg, init)
-     tree arg, init;
-{
-  if (! processing_template_decl
-      && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
-    cp_pedwarn ("invalid type `%T' for default argument to `%T'",
-               TREE_TYPE (init), TREE_VALUE (arg));
-  TREE_PURPOSE (arg) = init;
-}
 \f
 /* D is a constructor or overloaded `operator='.  Returns non-zero if
    D's arguments allow it to be a copy constructor, or copy assignment
@@ -12214,9 +11921,7 @@ copy_args_p (d)
   if (!DECL_FUNCTION_MEMBER_P (d))
     return 0;
 
-  t = FUNCTION_ARG_CHAIN (d);
-  if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
-    t = TREE_CHAIN (t);
+  t = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
       && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
          == DECL_CONTEXT (d))
@@ -12239,22 +11944,9 @@ int
 grok_ctor_properties (ctype, decl)
      tree ctype, decl;
 {
-  tree parmtypes = FUNCTION_ARG_CHAIN (decl);
+  tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
   tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
 
-  /* When a type has virtual baseclasses, a magical first int argument is
-     added to any ctor so we can tell if the class has been initialized
-     yet.  This could screw things up in this function, so we deliberately
-     ignore the leading int if we're in that situation.  */
-  if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-    {
-      my_friendly_assert (parmtypes
-                         && TREE_VALUE (parmtypes) == integer_type_node,
-                         980529);
-      parmtypes = TREE_CHAIN (parmtypes);
-      parmtype = TREE_VALUE (parmtypes);
-    }
-
   /* [class.copy]
 
      A non-template constructor for class X is a copy constructor if
@@ -12263,9 +11955,7 @@ grok_ctor_properties (ctype, decl)
      other parameters have default arguments.  */
   if (TREE_CODE (parmtype) == REFERENCE_TYPE
       && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype
-      && (TREE_CHAIN (parmtypes) == NULL_TREE
-         || TREE_CHAIN (parmtypes) == void_list_node
-         || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+      && sufficient_parms_p (TREE_CHAIN (parmtypes))
       && !(DECL_TEMPLATE_INSTANTIATION (decl)
           && is_member_template (DECL_TI_TEMPLATE (decl))))
     {
@@ -12289,9 +11979,7 @@ grok_ctor_properties (ctype, decl)
      existence.  Theoretically, they should never even be
      instantiated, but that's hard to forestall.  */
   else if (TYPE_MAIN_VARIANT (parmtype) == ctype
-          && (TREE_CHAIN (parmtypes) == NULL_TREE
-              || TREE_CHAIN (parmtypes) == void_list_node
-              || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+          && sufficient_parms_p (TREE_CHAIN (parmtypes))
           && !(DECL_TEMPLATE_INSTANTIATION (decl)
                && is_member_template (DECL_TI_TEMPLATE (decl))))
     {
@@ -12390,7 +12078,7 @@ grok_op_properties (decl, virtualp, friendp)
        case CALL_EXPR:
          TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
          break;
-         
+
        case ARRAY_REF:
          TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
          break;
@@ -12399,19 +12087,19 @@ grok_op_properties (decl, virtualp, friendp)
        case MEMBER_REF:
          TYPE_OVERLOADS_ARROW (current_class_type) = 1;
          break;
-         
+
        case NEW_EXPR:
          TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
          break;
-         
+
        case DELETE_EXPR:
          TYPE_GETS_DELETE (current_class_type) |= 1;
          break;
-         
+
        case VEC_NEW_EXPR:
          TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
          break;
-         
+
        case VEC_DELETE_EXPR:
          TYPE_GETS_DELETE (current_class_type) |= 2;
          break;
@@ -12428,27 +12116,14 @@ grok_op_properties (decl, virtualp, friendp)
       if (methodp)
        revert_static_member_fn (decl);
 
-      /* Take care of function decl if we had syntax errors.  */
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (ptr_type_node,
-                                hash_tree_chain (integer_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
     }
   else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
     {
       if (methodp)
        revert_static_member_fn (decl);
 
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (void_type_node,
-                                hash_tree_chain (ptr_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
     }
   else
     {
@@ -12502,7 +12177,7 @@ grok_op_properties (decl, virtualp, friendp)
            {
              int ref = (TREE_CODE (t) == REFERENCE_TYPE);
              const char *what = 0;
-             
+
              if (ref)
                t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
@@ -12522,7 +12197,7 @@ grok_op_properties (decl, virtualp, friendp)
            }
        }
 
-      if (DECL_ASSIGNMENT_OPERATOR_P (decl) 
+      if (DECL_ASSIGNMENT_OPERATOR_P (decl)
          && operator_code == NOP_EXPR)
        {
          tree parmtype;
@@ -13122,9 +12797,9 @@ xref_basetypes (code_type_node, name, ref, binfo)
 
          if (CLASS_TYPE_P (basetype))
            {
-             TYPE_HAS_NEW_OPERATOR (ref) 
+             TYPE_HAS_NEW_OPERATOR (ref)
                |= TYPE_HAS_NEW_OPERATOR (basetype);
-             TYPE_HAS_ARRAY_NEW_OPERATOR (ref) 
+             TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
                |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
              TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
              /* If the base-class uses multiple inheritance, so do we.  */
@@ -13710,7 +13385,8 @@ start_function (declspecs, declarator, attrs, flags)
   /* Initialize RTL machinery.  We cannot do this until
      CURRENT_FUNCTION_DECL and DECL_RESULT are set up.  We do this
      even when processing a template; this is how we get
-     CFUN set up, and our per-function variables initialized.  */
+     CFUN set up, and our per-function variables initialized.
+     FIXME factor out the non-RTL stuff.  */
   bl = current_binding_level;
   init_function_start (decl1, input_filename, lineno);
   current_binding_level = bl;
@@ -13754,7 +13430,7 @@ start_function (declspecs, declarator, attrs, flags)
 
   /* If we are (erroneously) defining a function that we have already
      defined before, wipe out what we knew before.  */
-  if (!DECL_PENDING_INLINE_P (decl1) 
+  if (!DECL_PENDING_INLINE_P (decl1)
       && DECL_SAVED_FUNCTION_DATA (decl1))
     {
       free (DECL_SAVED_FUNCTION_DATA (decl1));
@@ -13780,8 +13456,18 @@ start_function (declspecs, declarator, attrs, flags)
 
       /* Constructors and destructors need to know whether they're "in
         charge" of initializing virtual base classes.  */
+      t = TREE_CHAIN (t);
       if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
-       current_in_charge_parm = TREE_CHAIN (t);
+       {
+         current_in_charge_parm = t;
+         t = TREE_CHAIN (t);
+       }
+      if (DECL_HAS_VTT_PARM_P (decl1))
+       {
+         if (DECL_NAME (t) != vtt_parm_identifier)
+           abort ();
+         current_vtt_parm = t;
+       }
     }
 
   if (DECL_INTERFACE_KNOWN (decl1))
@@ -13857,7 +13543,7 @@ start_function (declspecs, declarator, attrs, flags)
 
   /* We need to do this even if we aren't expanding yet so that
      assemble_external works.  */
-  make_function_rtl (decl1);
+  make_decl_rtl (decl1, NULL);
 
   /* Promote the value to int before returning it.  */
   if (C_PROMOTING_INTEGER_TYPE_P (restype))
@@ -13883,16 +13569,6 @@ start_function (declspecs, declarator, attrs, flags)
       dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
       DECL_CONTEXT (dtor_label) = current_function_decl;
     }
-  /* Under the old ABI we return `this' from constructors, so we make
-     ordinary `return' statements in constructors jump to CTOR_LABEL;
-     from there we return `this'.  Under the new ABI, we don't bother
-     with any of this.  By not setting CTOR_LABEL the remainder of the
-     machinery is automatically disabled.  */
-  else if (!flag_new_abi && DECL_CONSTRUCTOR_P (decl1))
-    {
-      ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      DECL_CONTEXT (ctor_label) = current_function_decl;
-    }
 
   store_parm_decls (current_function_parms);
 
@@ -13954,7 +13630,7 @@ store_parm_decls (current_function_parms)
              else
                cp_error ("parameter `%D' declared void", parm);
 
-             cleanup = (processing_template_decl 
+             cleanup = (processing_template_decl
                         ? NULL_TREE
                         : maybe_build_cleanup (parm));
 
@@ -14026,8 +13702,7 @@ save_function_data (decl)
   /* Make a copy.  */
   f = ((struct cp_language_function *)
        xmalloc (sizeof (struct cp_language_function)));
-  bcopy ((char *) cp_function_chain, (char *) f,
-        sizeof (struct cp_language_function));
+  memcpy (f, cp_function_chain, sizeof (struct cp_language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
@@ -14073,9 +13748,7 @@ static void
 finish_destructor_body ()
 {
   tree compound_stmt;
-  tree virtual_size;
   tree exprstmt;
-  tree if_stmt;
 
   /* Create a block to contain all the extra code.  */
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
@@ -14129,16 +13802,26 @@ finish_destructor_body ()
               vbases = TREE_CHAIN (vbases))
            {
              tree vbase = TREE_VALUE (vbases);
+             tree base_type = BINFO_TYPE (vbase);
 
-             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbase)))
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
                {
-                 tree vb = get_vbase
-                   (BINFO_TYPE (vbase),
-                    TYPE_BINFO (current_class_type));
-                 finish_expr_stmt
-                   (build_scoped_method_call
-                    (current_class_ref, vb, base_dtor_identifier,
-                     NULL_TREE));
+                  tree base_ptr_type = build_pointer_type (base_type);
+                 tree expr = current_class_ptr;
+                 
+                 /* Convert to the basetype here, as we know the layout is
+                     fixed. What is more, if we let build_method_call do it,
+                     it will use the vtable, which may have been clobbered
+                     by the deletion of our primary base.  */
+                  
+                  expr = build1 (NOP_EXPR, base_ptr_type, expr);
+                 expr = build (PLUS_EXPR, base_ptr_type, expr,
+                               BINFO_OFFSET (vbase));
+                 expr = build_indirect_ref (expr, NULL);
+                 expr = build_method_call (expr, base_dtor_identifier,
+                                           NULL_TREE, vbase,
+                                           LOOKUP_NORMAL);
+                 finish_expr_stmt (expr);
                }
            }
 
@@ -14147,31 +13830,31 @@ finish_destructor_body ()
        }
     }
 
-  virtual_size = c_sizeof (current_class_type);
-
-  /* At the end, call delete if that's what's requested.  */
+  /* In a virtual destructor, we must call delete.  */
+  if (DECL_VIRTUAL_P (current_function_decl))
+    {
+      tree if_stmt;
+      tree virtual_size = c_sizeof (current_class_type);
 
-  /* FDIS sez: At the point of definition of a virtual destructor
-     (including an implicit definition), non-placement operator delete
-     shall be looked up in the scope of the destructor's class and if
-     found shall be accessible and unambiguous.
+      /* [class.dtor]
 
-     This is somewhat unclear, but I take it to mean that if the class
-     only defines placement deletes we don't do anything here.  So we
-     pass LOOKUP_SPECULATIVELY; delete_sanity will complain for us if
-     they ever try to delete one of these.  */
-  exprstmt = build_op_delete_call
-    (DELETE_EXPR, current_class_ptr, virtual_size,
-     LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
+        At the point of definition of a virtual destructor (including
+        an implicit definition), non-placement operator delete shall
+        be looked up in the scope of the destructor's class and if
+        found shall be accessible and unambiguous.  */
+      exprstmt = build_op_delete_call
+       (DELETE_EXPR, current_class_ptr, virtual_size,
+        LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
 
-  if_stmt = begin_if_stmt ();
-  finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
-                             current_in_charge_parm,
-                             integer_one_node),
-                      if_stmt);
-  finish_expr_stmt (exprstmt);
-  finish_then_clause (if_stmt);
-  finish_if_stmt ();
+      if_stmt = begin_if_stmt ();
+      finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
+                                 current_in_charge_parm,
+                                 integer_one_node),
+                          if_stmt);
+      finish_expr_stmt (exprstmt);
+      finish_then_clause (if_stmt);
+      finish_if_stmt ();
+    }
 
   /* Close the block we started above.  */
   finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
@@ -14603,7 +14286,7 @@ revert_static_member_fn (decl)
   if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
       != TYPE_UNQUALIFIED)
     cp_error ("static member function `%#D' declared with type qualifiers",
-             *decl);
+             decl);
 
   args = TREE_CHAIN (args);
   tmp = build_function_type (TREE_TYPE (function), args);
@@ -14649,6 +14332,19 @@ pop_cp_function_context (f)
   f->language = 0;
 }
 
+/* Mark I for GC.  */
+
+static void
+mark_inlined_fns (i)
+     struct lang_decl_inlined_fns *i;
+{
+  int n;
+
+  for (n = i->num_fns - 1; n >= 0; n--)
+    ggc_mark_tree (i->fns [n]);
+  ggc_set_mark (i);
+}
+
 /* Mark P for GC.  */
 
 static void
@@ -14720,7 +14416,7 @@ lang_mark_tree (t)
        {
          ggc_mark (ld);
          c_mark_lang_decl (&ld->decl_flags.base);
-         if (!DECL_GLOBAL_CTOR_P (t) 
+         if (!DECL_GLOBAL_CTOR_P (t)
              && !DECL_GLOBAL_DTOR_P (t)
              && !DECL_THUNK_P (t))
            ggc_mark_tree (ld->decl_flags.u2.access);
@@ -14735,8 +14431,8 @@ lang_mark_tree (t)
              ggc_mark_tree (ld->befriending_classes);
              ggc_mark_tree (ld->context);
              ggc_mark_tree (ld->cloned_function);
-             if (!DECL_OVERLOADED_OPERATOR_P (t))
-               ggc_mark_tree (ld->u2.vtt_parm);
+             if (ld->inlined_fns)
+               mark_inlined_fns (ld->inlined_fns);
              if (TREE_CODE (t) == TYPE_DECL)
                ggc_mark_tree (ld->u.sorted_fields);
              else if (TREE_CODE (t) == FUNCTION_DECL
@@ -14771,3 +14467,30 @@ lang_mark_tree (t)
        ggc_mark_tree ((tree) lt);
     }
 }
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
+
+tree
+identifier_global_value        (t)
+     tree t;
+{
+  return IDENTIFIER_GLOBAL_VALUE (t);
+}
+
+/* Build the void_list_node (void_type_node having been created).  */
+tree
+build_void_list_node ()
+{
+  tree t = build_tree_list (NULL_TREE, void_type_node);
+  TREE_PARMLIST (t) = 1;
+  return t;
+}
+
+static int
+cp_missing_noreturn_ok_p (decl)
+     tree decl;
+{
+  /* A missing noreturn is ok for the `main' function.  */
+  return MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
+}