cp-tree.h (struct lang_decl_inlined_fns): New.
[gcc.git] / gcc / cp / decl.c
index 924447f402dbcc10f80becb9a7a234af09c298c9..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,7 +37,6 @@ 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"
@@ -52,33 +51,10 @@ 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
 
 static tree grokparms                          PARAMS ((tree));
 static const char *redeclaration_error_message PARAMS ((tree, tree));
@@ -109,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));
@@ -169,10 +144,11 @@ 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));
+  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));
@@ -333,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
@@ -413,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
@@ -502,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.  */
@@ -888,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.  */
 
@@ -939,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.  */
 
@@ -950,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;
@@ -1138,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))
@@ -1188,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
@@ -2447,18 +2456,14 @@ store_bindings (names, old_bindings)
        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:
@@ -2552,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
@@ -2836,13 +2839,7 @@ pushtag (name, type, globalize)
            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));
-           }
+           DECL_ASSEMBLER_NAME (d) = mangle_type (type);
         }
       if (b->parm_flag == 2)
        {
@@ -3402,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
@@ -3582,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.  */
@@ -3625,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);
@@ -3875,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))
@@ -4415,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))
@@ -4427,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.  */
@@ -5158,12 +5163,12 @@ 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)
@@ -5175,7 +5180,7 @@ finish_case_label (low_value, high_value)
                  low_value);
       else
        error ("`default' label not within a switch statement");
-      return;
+      return NULL_TREE;
     }
 
   if (processing_template_decl)
@@ -5185,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.  */
@@ -5194,7 +5198,9 @@ 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);
 
@@ -5203,6 +5209,8 @@ finish_case_label (low_value, high_value)
   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.
@@ -5444,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,
@@ -5525,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);
     }
 
@@ -5628,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
        {
@@ -5996,10 +6005,9 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
              && TREE_CODE (val) == TYPE_DECL
              && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
            cp_pedwarn ("\
-lookup of `%D' in the scope of `%#T' (`%#T') \
-does not match lookup in the current scope (`%#T')",
-                       name, got_object, TREE_TYPE (from_obj),
-                       TREE_TYPE (val));
+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
@@ -6134,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;
@@ -6290,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 ();
@@ -6307,6 +6313,7 @@ init_decl_processing ()
   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 ();
@@ -6362,67 +6369,7 @@ init_decl_processing ()
       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);
-
-  /* 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);
@@ -6450,58 +6397,16 @@ 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;
-
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
-  /* 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);
-
-  c_common_nodes_and_builtins ();
 
 #if 0
   record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
 #endif
 
-  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;
 
   vtt_parm_type = build_pointer_type (const_ptr_type_node);
   lang_type_promotes_to = convert_type_from_ellipsis;
@@ -6509,10 +6414,6 @@ init_decl_processing ()
   void_ftype_ptr
     = build_exception_variant (void_ftype_ptr, empty_except_spec);
 
-#ifdef MD_INIT_BUILTINS
-  MD_INIT_BUILTINS;
-#endif
-
   /* C++ extensions */
 
   unknown_type_node = make_node (UNKNOWN_TYPE);
@@ -6528,22 +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);
-
-  /* This is for wide string constants.  */
-  wchar_array_type_node
-    = build_array_type (wchar_type_node, array_domain_type);
-
   if (flag_vtable_thunks)
     {
       /* Make sure we get a unique function type, so we can give
@@ -6590,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");
@@ -6621,10 +6503,7 @@ init_decl_processing ()
   }
 
   abort_fndecl
-    = build_library_fn_ptr ((flag_new_abi 
-                            ? "__cxa_pure_virtual"
-                            : "__pure_virtual"),
-                           void_ftype);
+    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -6693,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
@@ -6716,7 +6596,7 @@ cp_make_fname_decl (id, name, type_dep)
   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),
@@ -6789,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.  */
@@ -6827,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;
 }
 
@@ -6843,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;
 }
 
@@ -6957,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.
@@ -6971,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;
@@ -6980,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
@@ -7026,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);
 
@@ -7310,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?
@@ -7634,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);
@@ -7723,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;
     }
@@ -7857,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);
@@ -8051,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)
@@ -8138,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.  */
@@ -8742,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);
 }
 
@@ -8911,7 +8813,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        {
          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>()'.  */
@@ -8931,7 +8833,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
                  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);
@@ -8962,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)
@@ -9073,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
     {
@@ -9104,13 +9000,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
 
       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);
-       }
+       DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
     }
 
   if (in_namespace)
@@ -9175,12 +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.  */
@@ -9200,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.  */
@@ -9495,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)
@@ -9514,9 +9381,8 @@ check_special_function_return_type (sfk, type, ctype, optype)
       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:
@@ -10126,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)
     {
@@ -10382,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
        {
@@ -10667,7 +10532,7 @@ 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;
                      memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));
@@ -10923,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)
@@ -10985,7 +10848,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  {
                    incomplete_type_error (NULL_TREE, ctype);
                    return error_mark_node;
-                 }
+                 }
 
                declarator = sname;
              }
@@ -11146,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.  */
@@ -11258,14 +11104,14 @@ friend declaration requires class-key, i.e. `friend %#T'",
          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;
            }
        }
@@ -11459,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
@@ -11983,10 +11822,10 @@ grokparms (first_parm)
         break;
 
       decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
-                            PARM, init != NULL_TREE, NULL_TREE);
+                    PARM, init != NULL_TREE, NULL_TREE);
       if (! decl || TREE_TYPE (decl) == error_mark_node)
         continue;
-    
+
       type = TREE_TYPE (decl);
       if (VOID_TYPE_P (type))
         {
@@ -12002,7 +11841,7 @@ grokparms (first_parm)
          TREE_TYPE (decl) = error_mark_node;
         }
 
-      if (type != error_mark_node) 
+      if (type != error_mark_node)
        {
          /* Top-level qualifiers on the parameters are
             ignored for function types.  */
@@ -12025,15 +11864,22 @@ grokparms (first_parm)
            {
              /* [dcl.fct]/6, parameter types cannot contain pointers
                 (references) to arrays of unknown bound.  */
-             tree t = type;
-
-             while (POINTER_TYPE_P (t)
-                    || (TREE_CODE (t) == ARRAY_TYPE
-                        && TYPE_DOMAIN (t) != NULL_TREE))
-               t = TREE_TYPE (t);
+             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, TYPE_PTR_P (type) ? "pointer" : "reference", t);
+                         decl, ptr ? "pointer" : "reference", t);
            }
 
          DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
@@ -12061,20 +11907,6 @@ grokparms (first_parm)
   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
@@ -12089,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))
@@ -12114,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
@@ -13639,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))
@@ -13716,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))
@@ -13742,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);
 
@@ -13931,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);
@@ -13987,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);
                }
            }
 
@@ -14005,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);
@@ -14507,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
@@ -14593,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
@@ -14639,3 +14477,20 @@ identifier_global_value        (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));
+}