OSDN Git Service

tweak formatting
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 8ef1d4f..20a6aba 100644 (file)
@@ -1,5 +1,6 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+   Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -56,7 +57,7 @@ extern tree static_ctors, static_dtors;
 
 extern tree global_namespace;
 
-extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree));
+extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
 
 /* Use garbage collection.  */
 
@@ -72,7 +73,10 @@ int ggc_p = 1;
 
 #ifndef BOOL_TYPE_SIZE
 #ifdef SLOW_BYTE_ACCESS
-#define BOOL_TYPE_SIZE ((SLOW_BYTE_ACCESS) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
+/* 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
@@ -96,99 +100,99 @@ int ggc_p = 1;
 #define WCHAR_TYPE "int"
 #endif
 
-static tree grokparms                          PROTO((tree, int));
-static const char *redeclaration_error_message PROTO((tree, tree));
+static tree grokparms                          PARAMS ((tree, int));
+static const char *redeclaration_error_message PARAMS ((tree, tree));
 
-static void push_binding_level PROTO((struct binding_level *, int,
+static void push_binding_level PARAMS ((struct binding_level *, int,
                                      int));
-static void pop_binding_level PROTO((void));
-static void suspend_binding_level PROTO((void));
-static void resume_binding_level PROTO((struct binding_level *));
-static struct binding_level *make_binding_level PROTO((void));
-static void declare_namespace_level PROTO((void));
-static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN;
-static void storedecls PROTO((tree));
-static void require_complete_types_for_parms PROTO((tree));
-static void push_overloaded_decl_1 PROTO((tree));
-static int ambi_op_p PROTO((tree));
-static int unary_op_p PROTO((tree));
-static tree store_bindings PROTO((tree, tree));
-static tree lookup_tag_reverse PROTO((tree, tree));
-static tree obscure_complex_init PROTO((tree, tree));
-static tree maybe_build_cleanup_1 PROTO((tree, tree));
-static tree lookup_name_real PROTO((tree, int, int, int));
-static void warn_extern_redeclared_static PROTO((tree, tree));
-static void grok_reference_init PROTO((tree, tree, tree));
-static tree grokfndecl PROTO((tree, tree, tree, tree, int,
+static void pop_binding_level PARAMS ((void));
+static void suspend_binding_level PARAMS ((void));
+static void resume_binding_level PARAMS ((struct binding_level *));
+static struct binding_level *make_binding_level PARAMS ((void));
+static void declare_namespace_level PARAMS ((void));
+static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void storedecls PARAMS ((tree));
+static void require_complete_types_for_parms PARAMS ((tree));
+static int ambi_op_p PARAMS ((tree));
+static int unary_op_p PARAMS ((tree));
+static tree store_bindings PARAMS ((tree, tree));
+static tree lookup_tag_reverse PARAMS ((tree, tree));
+static tree obscure_complex_init PARAMS ((tree, tree));
+static tree maybe_build_cleanup_1 PARAMS ((tree, tree));
+static tree lookup_name_real PARAMS ((tree, int, int, int));
+static void warn_extern_redeclared_static PARAMS ((tree, tree));
+static void grok_reference_init PARAMS ((tree, tree, tree));
+static tree grokfndecl PARAMS ((tree, tree, tree, tree, int,
                              enum overload_flags, tree,
                              tree, int, int, int, int, int, int, tree));
-static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree));
-static tree lookup_tag PROTO((enum tree_code, tree,
+static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree));
+static tree lookup_tag PARAMS ((enum tree_code, tree,
                              struct binding_level *, int));
 static void set_identifier_type_value_with_scope
-       PROTO((tree, tree, struct binding_level *));
-static void record_builtin_type PROTO((enum rid, const char *, tree));
-static void record_unknown_type PROTO((tree, const char *));
-static int member_function_or_else PROTO((tree, tree, const char *));
-static void bad_specifiers PROTO((tree, const char *, int, int, int, int,
+       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, tree));
+static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
+static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
                                  int));
-static void lang_print_error_function PROTO((const char *));
-static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
-static void check_for_uninitialized_const_var PROTO((tree));
-static unsigned long typename_hash PROTO((hash_table_key));
-static boolean typename_compare PROTO((hash_table_key, hash_table_key));
-static void push_binding PROTO((tree, tree, struct binding_level*));
-static int add_binding PROTO((tree, tree));
-static void pop_binding PROTO((tree, tree));
-static tree local_variable_p_walkfn PROTO((tree *, int *, void *));
-static tree find_binding PROTO((tree, tree));
-static tree select_decl PROTO((tree, int));
-static int lookup_flags PROTO((int, int));
-static tree qualify_lookup PROTO((tree, int));
-static tree record_builtin_java_type PROTO((const char *, int));
-static const char *tag_name PROTO((enum tag_types code));
-static void find_class_binding_level PROTO((void));
-static struct binding_level *innermost_nonclass_level PROTO((void));
-static void warn_about_implicit_typename_lookup PROTO((tree, tree));
-static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *));
-static int walk_globals_r PROTO((tree, void *));
-static void add_decl_to_level PROTO((tree, struct binding_level *));
-static tree make_label_decl PROTO((tree, int));
-static void pop_label PROTO((tree));
-static void pop_labels PROTO((tree));
-static void maybe_deduce_size_from_array_init PROTO((tree, tree));
-static void layout_var_decl PROTO((tree));
-static void maybe_commonize_var PROTO((tree));
-static tree check_initializer PROTO((tree, tree));
-static void make_rtl_for_nonlocal_decl PROTO((tree, tree, const char *));
-static void push_cp_function_context PROTO((struct function *));
-static void pop_cp_function_context PROTO((struct function *));
-static void mark_binding_level PROTO((void *));
-static void mark_cp_function_context PROTO((struct function *));
-static void mark_saved_scope PROTO((void *));
-static void mark_lang_function PROTO((struct language_function *));
-static void mark_stmt_tree PROTO((struct stmt_tree *));
-static void save_function_data PROTO((tree));
-static void check_function_type PROTO((tree));
-static void destroy_local_static PROTO((tree));
-static void destroy_local_var PROTO((tree));
-static void finish_constructor_body PROTO((void));
-static void finish_destructor_body PROTO((void));
-static tree create_array_type_for_decl PROTO((tree, tree, tree));
-static tree get_atexit_node PROTO((void));
-static tree get_dso_handle_node PROTO((void));
-static tree start_cleanup_fn PROTO((void));
-static void end_cleanup_fn PROTO((void));
+static void lang_print_error_function PARAMS ((const char *));
+static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct binding_level*));
+static void check_for_uninitialized_const_var PARAMS ((tree));
+static unsigned long typename_hash PARAMS ((hash_table_key));
+static boolean typename_compare PARAMS ((hash_table_key, hash_table_key));
+static void push_binding PARAMS ((tree, tree, struct binding_level*));
+static int add_binding PARAMS ((tree, tree));
+static void pop_binding PARAMS ((tree, tree));
+static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *));
+static tree find_binding PARAMS ((tree, tree));
+static tree select_decl PARAMS ((tree, int));
+static int lookup_flags PARAMS ((int, int));
+static tree qualify_lookup PARAMS ((tree, int));
+static tree record_builtin_java_type PARAMS ((const char *, int));
+static const char *tag_name PARAMS ((enum tag_types code));
+static void find_class_binding_level PARAMS ((void));
+static struct binding_level *innermost_nonclass_level PARAMS ((void));
+static void warn_about_implicit_typename_lookup PARAMS ((tree, tree));
+static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *));
+static int walk_globals_r PARAMS ((tree, void *));
+static void add_decl_to_level PARAMS ((tree, struct binding_level *));
+static tree make_label_decl PARAMS ((tree, int));
+static void pop_label PARAMS ((tree));
+static void pop_labels PARAMS ((tree));
+static void maybe_deduce_size_from_array_init PARAMS ((tree, tree));
+static void layout_var_decl PARAMS ((tree));
+static void maybe_commonize_var PARAMS ((tree));
+static tree check_initializer PARAMS ((tree, tree));
+static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *));
+static void push_cp_function_context PARAMS ((struct function *));
+static void pop_cp_function_context PARAMS ((struct function *));
+static void mark_binding_level PARAMS ((void *));
+static void mark_cp_function_context PARAMS ((struct function *));
+static void mark_saved_scope PARAMS ((void *));
+static void mark_lang_function PARAMS ((struct language_function *));
+static void mark_stmt_tree PARAMS ((struct stmt_tree *));
+static void save_function_data PARAMS ((tree));
+static void check_function_type PARAMS ((tree));
+static void destroy_local_var PARAMS ((tree));
+static void finish_constructor_body PARAMS ((void));
+static void finish_destructor_body PARAMS ((void));
+static tree create_array_type_for_decl PARAMS ((tree, tree, tree));
+static tree get_atexit_node PARAMS ((void));
+static tree get_dso_handle_node PARAMS ((void));
+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));
 
 #if defined (DEBUG_CP_BINDING_LEVELS)
-static void indent PROTO((void));
+static void indent PARAMS ((void));
 #endif
 
 /* Erroneous argument lists can use this *IFF* they do not modify it.  */
 tree error_mark_list;
 
 /* The following symbols are subsumed in the cp_global_trees array, and
-   listed here individually for documentation purposes. 
+   listed here individually for documentation purposes.
 
    C++ extensions
        tree wchar_decl_node;
@@ -206,10 +210,12 @@ tree error_mark_list;
 #if 0
        tree __tp_desc_type_node;
 #endif
-       tree __access_mode_type_node;
-       tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node;
-       tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node;
-       tree __ptmf_desc_type_node, __ptmd_desc_type_node;
+        tree ti_desc_type_node;
+       tree bltn_desc_type_node, ptr_desc_type_node, ref_desc_type_node;
+       tree ary_desc_type_node, func_desc_type_node, enum_desc_type_node;
+       tree class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node;
+       tree ptmd_desc_type_node;
+       tree base_desc_type_node;
 #if 0
    Not needed yet?  May be needed one day?
        tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
@@ -217,7 +223,6 @@ tree error_mark_list;
        tree __ptmf_desc_array_type, __ptmd_desc_array_type;
 #endif
 
-       tree class_star_type_node;
        tree class_type_node, record_type_node, union_type_node, enum_type_node;
        tree unknown_type_node;
 
@@ -241,7 +246,8 @@ tree error_mark_list;
        tree global_delete_fndecl;
 
    Used by RTTI
-       tree type_info_type_node, tinfo_fn_id, tinfo_fn_type;
+       tree type_info_type_node, tinfo_decl_id, tinfo_decl_type;
+       tree tinfo_var_id;
 
 */
 
@@ -308,10 +314,6 @@ static tree current_function_parm_tags;
 
 #define named_labels cp_function_chain->x_named_labels
 
-/* The FUNCTION_DECL for the function currently being compiled,
-   or 0 if between functions.  */
-tree current_function_decl;
-
 /* Set to 0 at beginning of a function definition, and whenever
    a label (case or named) is defined.  Set to value of expression
    returned from function when that value can be transformed into
@@ -319,6 +321,10 @@ tree current_function_decl;
 
 tree current_function_return_value;
 
+/* Nonzero means use the ISO C99 dialect of C.  */
+
+int flag_isoc99;
+
 /* Nonzero means give `double' the same size as `float'.  */
 
 extern int flag_short_double;
@@ -433,6 +439,9 @@ struct binding_level
        If 0, the BLOCK is allocated (if needed) when the level is popped.  */
     tree this_block;
 
+    /* The _TYPE node for this level, if parm_flag == 2.  */
+    tree this_class;
+
     /* The binding level which this one is contained in (inherits from).  */
     struct binding_level *level_chain;
 
@@ -441,7 +450,7 @@ struct binding_level
     tree incomplete;
 
     /* List of VAR_DECLS saved from a previous for statement.
-       These would be dead in ANSI-conforming code, but might
+       These would be dead in ISO-conforming code, but might
        be referenced in ARM-era code.  These are stored in a
        TREE_LIST; the TREE_VALUE is the actual declaration.  */
     tree dead_vars_from_for;
@@ -472,7 +481,7 @@ struct binding_level
     unsigned namespace_p : 1;
 
     /* True if this level is that of a for-statement where we need to
-       worry about ambiguous (ARM or ANSI) scope rules.  */
+       worry about ambiguous (ARM or ISO) scope rules.  */
     unsigned is_for_scope : 1;
 
     /* True if this level corresponds to an EH region, as for a try block.  */
@@ -487,7 +496,7 @@ struct binding_level
   };
 
 #define NULL_BINDING_LEVEL ((struct binding_level *) NULL)
-  
+
 /* The binding level currently in effect.  */
 
 #define current_binding_level                  \
@@ -527,7 +536,7 @@ indent ()
 }
 #endif /* defined(DEBUG_CP_BINDING_LEVELS) */
 
-static tree pushdecl_with_scope        PROTO((tree, struct binding_level *));
+static tree pushdecl_with_scope        PARAMS ((tree, struct binding_level *));
 
 static void
 push_binding_level (newlevel, tag_transparent, keep)
@@ -993,12 +1002,12 @@ push_class_binding (id, decl)
       else
        {
          if (TREE_CODE (decl) == OVERLOAD)
-           context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
+           context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
          else
            {
              my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd',
                                  0);
-             context = DECL_REAL_CONTEXT (decl);
+             context = CP_DECL_CONTEXT (decl);
            }
 
          if (is_properly_derived_from (current_class_type, context))
@@ -1019,13 +1028,13 @@ push_class_binding (id, decl)
 /* Remove the binding for DECL which should be the innermost binding
    for ID.  */
 
-static void 
-pop_binding (id, decl) 
+static void
+pop_binding (id, decl)
      tree id;
      tree decl;
 {
   tree binding;
-    
+
   if (id == NULL_TREE)
     /* It's easiest to write the loops that call this function without
        checking whether or not the entities involved have names.  We
@@ -1078,7 +1087,7 @@ pop_label (link)
 }
 
 /* At the end of a function, all labels declared within the fucntion
-   go out of scope.  BLOCK is the top-level block for the 
+   go out of scope.  BLOCK is the top-level block for the
    function.  */
 
 static void
@@ -1245,7 +1254,7 @@ poplevel (keep, reverse, functionbody)
      in a for-init statement were in scope after the for-statement
      ended.  We only use the new rules in flag_new_for_scope is
      nonzero.  */
-  leaving_for_scope 
+  leaving_for_scope
     = current_binding_level->is_for_scope && flag_new_for_scope == 1;
 
   /* Remove declarations for all the DECLs in this level.  */
@@ -1253,7 +1262,7 @@ poplevel (keep, reverse, functionbody)
     {
       if (leaving_for_scope && TREE_CODE (link) == VAR_DECL)
        {
-         tree outer_binding 
+         tree outer_binding
            = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link)));
          tree ns_binding;
 
@@ -1262,21 +1271,21 @@ poplevel (keep, reverse, functionbody)
          else
            ns_binding = NULL_TREE;
 
-         if (outer_binding 
-             && (BINDING_LEVEL (outer_binding) 
+         if (outer_binding
+             && (BINDING_LEVEL (outer_binding)
                  == current_binding_level->level_chain))
            /* We have something like:
-              
+
                 int i;
                 for (int i; ;);
-                
+
               and we are leaving the `for' scope.  There's no reason to
               keep the binding of the inner `i' in this case.  */
            pop_binding (DECL_NAME (link), link);
-         else if ((outer_binding 
-                   && (TREE_CODE (BINDING_VALUE (outer_binding)) 
+         else if ((outer_binding
+                   && (TREE_CODE (BINDING_VALUE (outer_binding))
                        == TYPE_DECL))
-                  || (ns_binding 
+                  || (ns_binding
                       && TREE_CODE (ns_binding) == TYPE_DECL))
            /* Here, we have something like:
 
@@ -1294,11 +1303,11 @@ poplevel (keep, reverse, functionbody)
              /* Mark this VAR_DECL as dead so that we can tell we left it
                 there only for backward compatibility.  */
              DECL_DEAD_FOR_LOCAL (link) = 1;
-             
+
              /* Keep track of what should of have happenned when we
                 popped the binding.  */
              if (outer_binding && BINDING_VALUE (outer_binding))
-               DECL_SHADOWED_FOR_VAR (link) 
+               DECL_SHADOWED_FOR_VAR (link)
                  = BINDING_VALUE (outer_binding);
 
              /* Add it to the list of dead variables in the next
@@ -1315,7 +1324,7 @@ poplevel (keep, reverse, functionbody)
                = 0;
            }
        }
-      else 
+      else
        {
          /* Remove the binding.  */
          decl = link;
@@ -1325,7 +1334,7 @@ poplevel (keep, reverse, functionbody)
            pop_binding (DECL_NAME (decl), decl);
          else if (TREE_CODE (decl) == OVERLOAD)
            pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl);
-         else 
+         else
            my_friendly_abort (0);
        }
     }
@@ -1343,7 +1352,7 @@ poplevel (keep, reverse, functionbody)
 
   /* Restore the IDENTIFIER_LABEL_VALUEs for local labels.  */
   for (link = current_binding_level->shadowed_labels;
-       link; 
+       link;
        link = TREE_CHAIN (link))
     pop_label (link);
 
@@ -1426,7 +1435,7 @@ poplevel (keep, reverse, functionbody)
     {
       tree scope_stmts;
 
-      scope_stmts 
+      scope_stmts
        = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
       if (block)
        {
@@ -1515,6 +1524,7 @@ pushlevel_class ()
 
   class_binding_level = current_binding_level;
   class_binding_level->parm_flag = 2;
+  class_binding_level->this_class = current_class_type;
 }
 
 /* ...and a poplevel for class declarations.  */
@@ -1526,7 +1536,7 @@ poplevel_class ()
   tree shadowed;
 
   my_friendly_assert (level != 0, 354);
-  
+
   /* If we're leaving a toplevel class, don't bother to do the setting
      of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
      shouldn't even be used when current_class_type isn't set, and second,
@@ -1541,7 +1551,7 @@ poplevel_class ()
           shadowed;
           shadowed = TREE_CHAIN (shadowed))
        IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
-       
+
       /* Find the next enclosing class, and recreate
         IDENTIFIER_CLASS_VALUEs appropriate for that class.  */
       b = level->level_chain;
@@ -1549,8 +1559,8 @@ poplevel_class ()
        b = b->level_chain;
 
       if (b)
-       for (shadowed = b->class_shadowed; 
-            shadowed; 
+       for (shadowed = b->class_shadowed;
+            shadowed;
             shadowed = TREE_CHAIN (shadowed))
          {
            tree t;
@@ -1558,9 +1568,9 @@ poplevel_class ()
            t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
            while (t && BINDING_LEVEL (t) != b)
              t = TREE_CHAIN (t);
-      
+
            if (t)
-             IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) 
+             IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
                = BINDING_VALUE (t);
          }
     }
@@ -1577,8 +1587,8 @@ poplevel_class ()
     SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
 
   /* Remove the bindings for all of the class-level declarations.  */
-  for (shadowed = level->class_shadowed; 
-       shadowed; 
+  for (shadowed = level->class_shadowed;
+       shadowed;
        shadowed = TREE_CHAIN (shadowed))
     pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
 
@@ -1702,7 +1712,7 @@ struct walk_globals_data {
    for which P returns non-zero, call F with its address.  If any call
    to F returns a non-zero value, return a non-zero value.  */
 
-static int 
+static int
 walk_globals_r (namespace, data)
      tree namespace;
      void *data;
@@ -1773,10 +1783,21 @@ 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))
-    vec[len - i - 1] = 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;
+    }
+
   if (last_time)
     {
       check_global_declarations (vec, len);
@@ -1828,6 +1849,7 @@ mark_binding_level (arg)
       ggc_mark_tree (lvl->shadowed_labels);
       ggc_mark_tree (lvl->blocks);
       ggc_mark_tree (lvl->this_block);
+      ggc_mark_tree (lvl->this_class);
       ggc_mark_tree (lvl->incomplete);
       ggc_mark_tree (lvl->dead_vars_from_for);
 
@@ -1862,7 +1884,7 @@ print_binding_level (lvl)
       /* We can probably fit 3 names to a line?  */
       for (t = lvl->names; t; t = TREE_CHAIN (t))
        {
-         if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) 
+         if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
            continue;
          if (no_print_builtins
              && (TREE_CODE (t) == TYPE_DECL)
@@ -2001,7 +2023,7 @@ find_binding (name, scope)
   tree iter, prev = NULL_TREE;
 
   scope = ORIGINAL_NAMESPACE (scope);
-  
+
   for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
        iter = TREE_CHAIN (iter))
     {
@@ -2036,7 +2058,7 @@ binding_for_name (name, scope)
   tree result;
 
   scope = ORIGINAL_NAMESPACE (scope);
-  
+
   if (b && TREE_CODE (b) != CPLUS_BINDING)
     {
       /* Get rid of optimization for global scope. */
@@ -2090,7 +2112,7 @@ set_namespace_binding (name, scope, val)
 
   if (scope == NULL_TREE)
     scope = global_namespace;
-  
+
   if (scope == global_namespace)
     {
       b = IDENTIFIER_NAMESPACE_BINDINGS (name);
@@ -2155,7 +2177,7 @@ push_namespace (name)
             }
         }
     }
-  
+
   if (need_new)
     {
       /* Make a new namespace, binding the name to it. */
@@ -2213,7 +2235,7 @@ push_nested_namespace (ns)
 
 /* Pop back from the scope of the namespace NS, which was previously
    entered with push_nested_namespace.  */
-     
+
 void
 pop_nested_namespace (ns)
      tree ns;
@@ -2269,6 +2291,8 @@ mark_saved_scope (arg)
       ggc_mark_tree (t->x_previous_class_type);
       ggc_mark_tree (t->x_previous_class_values);
       ggc_mark_tree (t->x_saved_tree);
+      ggc_mark_tree (t->incomplete);
+      ggc_mark_tree (t->lookups);
 
       mark_stmt_tree (&t->x_stmt_tree);
       mark_binding_level (&t->bindings);
@@ -2290,7 +2314,7 @@ store_bindings (names, old_bindings)
       else
        id = DECL_NAME (t);
 
-      if (!id 
+      if (!id
          /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
             we have no IDENTIFIER_BINDING if we have left the class
             scope, but cached the class-level declarations.  */
@@ -2430,7 +2454,7 @@ pop_from_top_level ()
 }
 \f
 /* Push a definition of struct, union or enum tag "name".
-   into binding_level "b".   "type" should be the type node, 
+   into binding_level "b".   "type" should be the type node,
    We assume that the tag "name" is not already defined.
 
    Note that the definition may really be just a forward reference.
@@ -2527,30 +2551,30 @@ pop_everything ()
    Returns the TYPE_DECL for TYPE, which may have been altered by this
    processing.  */
 
-static tree 
+static tree
 maybe_process_template_type_declaration (type, globalize, b)
      tree type;
      int globalize;
      struct binding_level* b;
 {
   tree decl = TYPE_NAME (type);
+
   if (processing_template_parmlist)
     /* You can't declare a new template type in a template parameter
        list.  But, you can declare a non-template type:
-       
+
          template <class A*> struct S;
-       
+
        is a forward-declaration of `A'.  */
     ;
-  else 
+  else
     {
       maybe_check_template_type (type);
 
-      my_friendly_assert (IS_AGGR_TYPE (type) 
+      my_friendly_assert (IS_AGGR_TYPE (type)
                          || TREE_CODE (type) == ENUMERAL_TYPE, 0);
-                         
-                         
+
+
       if (processing_template_decl)
        {
          /* This may change after the call to
@@ -2573,7 +2597,7 @@ maybe_process_template_type_declaration (type, globalize, b)
              /* Put this tag on the list of tags for the class, since
                 that won't happen below because B is not the class
                 binding level, but is instead the pseudo-global level.  */
-             b->level_chain->tags = 
+             b->level_chain->tags =
                tree_cons (name, type, b->level_chain->tags);
              if (TYPE_SIZE (current_class_type) == NULL_TREE)
                CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
@@ -2641,12 +2665,12 @@ pushtag (name, type, globalize)
 
              if (! globalize)
                context = cs;
-             else if (cs != NULL_TREE 
+             else if (cs != NULL_TREE
                       && TREE_CODE_CLASS (TREE_CODE (cs)) == 't')
                /* When declaring a friend class of a local class, we want
                   to inject the newly named class into the scope
                   containing the local class, not the namespace scope.  */
-               context = hack_decl_function_context (get_type_decl (cs));
+               context = decl_function_context (get_type_decl (cs));
            }
          if (!context)
            context = current_namespace;
@@ -2789,33 +2813,13 @@ decls_match (newdecl, olddecl)
       tree p1 = TYPE_ARG_TYPES (f1);
       tree p2 = TYPE_ARG_TYPES (f2);
 
-      if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)
+      if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
          && ! (DECL_LANGUAGE (newdecl) == lang_c
                && DECL_LANGUAGE (olddecl) == lang_c))
        return 0;
 
-      /* When we parse a static member function definition,
-        we put together a FUNCTION_DECL which thinks its type
-        is METHOD_TYPE.  Change that to FUNCTION_TYPE, and
-        proceed.  */
-      if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))
-       revert_static_member_fn (&newdecl, &f1, &p1);
-      else if (TREE_CODE (f2) == METHOD_TYPE
-              && DECL_STATIC_FUNCTION_P (newdecl))
-       revert_static_member_fn (&olddecl, &f2, &p2);
-
-      /* Here we must take care of the case where new default
-        parameters are specified.  Also, warn if an old
-        declaration becomes ambiguous because default
-        parameters may cause the two to be ambiguous.  */
       if (TREE_CODE (f1) != TREE_CODE (f2))
-       {
-         if (TREE_CODE (f1) == OFFSET_TYPE)
-           cp_compiler_error ("`%D' redeclared as member function", newdecl);
-         else
-           cp_compiler_error ("`%D' redeclared as non-member function", newdecl);
-         return 0;
-       }
+        return 0;
 
       if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
        {
@@ -2843,7 +2847,7 @@ decls_match (newdecl, olddecl)
       if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
                                DECL_TEMPLATE_PARMS (olddecl)))
        return 0;
-      
+
       if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
        types_match = 1;
       else
@@ -2887,10 +2891,10 @@ warn_extern_redeclared_static (newdecl, olddecl)
 
   tree name;
 
-  if (TREE_CODE (newdecl) == TYPE_DECL 
+  if (TREE_CODE (newdecl) == TYPE_DECL
       || TREE_CODE (newdecl) == TEMPLATE_DECL)
     return;
-  
+
   /* Don't get confused by static member functions; that's a different
      use of `static'.  */
   if (TREE_CODE (newdecl) == FUNCTION_DECL
@@ -2942,7 +2946,7 @@ duplicate_decls (newdecl, olddecl)
   if (TREE_TYPE (newdecl) == error_mark_node
       || TREE_TYPE (olddecl) == error_mark_node)
     types_match = 1;
+
   /* Check for redeclaration and other discrepancies. */
   if (TREE_CODE (olddecl) == FUNCTION_DECL
       && DECL_ARTIFICIAL (olddecl))
@@ -2998,7 +3002,7 @@ duplicate_decls (newdecl, olddecl)
            /* Discard the old built-in function.  */
            return 0;
        }
-      
+
       if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
        {
          /* If a builtin function is redeclared as `static', merge
@@ -3054,7 +3058,7 @@ duplicate_decls (newdecl, olddecl)
     }
   else if (!types_match)
     {
-      if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl))
+      if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
        /* These are certainly not duplicate declarations; they're
           from different scopes.  */
        return 0;
@@ -3110,14 +3114,14 @@ duplicate_decls (newdecl, olddecl)
          cp_error_at ("previous declaration as `%#D'", olddecl);
        }
     }
-  else if (TREE_CODE (newdecl) == FUNCTION_DECL 
+  else if (TREE_CODE (newdecl) == FUNCTION_DECL
            && ((DECL_TEMPLATE_SPECIALIZATION (olddecl)
                 && (!DECL_TEMPLATE_INFO (newdecl)
-                    || (DECL_TI_TEMPLATE (newdecl) 
+                    || (DECL_TI_TEMPLATE (newdecl)
                         != DECL_TI_TEMPLATE (olddecl))))
                || (DECL_TEMPLATE_SPECIALIZATION (newdecl)
                    && (!DECL_TEMPLATE_INFO (olddecl)
-                       || (DECL_TI_TEMPLATE (olddecl) 
+                       || (DECL_TI_TEMPLATE (olddecl)
                            != DECL_TI_TEMPLATE (newdecl))))))
     /* It's OK to have a template specialization and a non-template
        with the same type, or to have specializations of two
@@ -3128,8 +3132,8 @@ duplicate_decls (newdecl, olddecl)
        specialize one of its methods.  This situation is legal, but
        the declarations must be merged in the usual way.  */
     return 0;
-  else if (TREE_CODE (newdecl) == FUNCTION_DECL 
-          && ((DECL_TEMPLATE_INSTANTIATION (olddecl) 
+  else if (TREE_CODE (newdecl) == FUNCTION_DECL
+          && ((DECL_TEMPLATE_INSTANTIATION (olddecl)
                && !DECL_USE_TEMPLATE (newdecl))
               || (DECL_TEMPLATE_INSTANTIATION (newdecl)
                   && !DECL_USE_TEMPLATE (olddecl))))
@@ -3190,7 +3194,7 @@ duplicate_decls (newdecl, olddecl)
 
          if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
            t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
-       
+
          for (; t1 && t1 != void_list_node;
               t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
            if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
@@ -3239,20 +3243,20 @@ duplicate_decls (newdecl, olddecl)
         definition.  */
       if (DECL_VINDEX (olddecl))
        DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);
+      if (DECL_VIRTUAL_CONTEXT (olddecl))
+       DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl);
       if (DECL_CONTEXT (olddecl))
        DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
-      if (DECL_CLASS_CONTEXT (olddecl))
-       DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl);
       if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0)
        DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
       DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
       DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
-      DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
+      DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (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);
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
-      
+
       /* Optionally warn about more than one declaration for the same
          name, but don't warn about a function declaration followed by a
          definition.  */
@@ -3285,7 +3289,7 @@ duplicate_decls (newdecl, olddecl)
 
   /* Copy all the DECL_... slots specified in the new decl
      except for any that we copy here from the old type.  */
-  DECL_MACHINE_ATTRIBUTES (newdecl) 
+  DECL_MACHINE_ATTRIBUTES (newdecl)
     = merge_machine_decl_attributes (olddecl, newdecl);
 
   if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -3294,13 +3298,13 @@ duplicate_decls (newdecl, olddecl)
                             DECL_TEMPLATE_RESULT (olddecl)))
        cp_error ("invalid redeclaration of %D", newdecl);
       TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl));
-      DECL_TEMPLATE_SPECIALIZATIONS (olddecl) 
+      DECL_TEMPLATE_SPECIALIZATIONS (olddecl)
        = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl),
                   DECL_TEMPLATE_SPECIALIZATIONS (newdecl));
+
       return 1;
     }
-    
+
   if (types_match)
     {
       /* Automatically handles default parameters.  */
@@ -3412,13 +3416,13 @@ duplicate_decls (newdecl, olddecl)
   TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
   if (! DECL_EXTERNAL (olddecl))
     DECL_EXTERNAL (newdecl) = 0;
-  
+
   if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
     {
       DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
       DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
       DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
-      DECL_TEMPLATE_INSTANTIATED (newdecl) 
+      DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
       /* Don't really know how much of the language-specific
         values we should copy from old to new.  */
@@ -3438,8 +3442,8 @@ duplicate_decls (newdecl, olddecl)
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
-      if (DECL_TEMPLATE_INSTANTIATION (olddecl) 
-         && !DECL_TEMPLATE_INSTANTIATION (newdecl)) 
+      if (DECL_TEMPLATE_INSTANTIATION (olddecl)
+         && !DECL_TEMPLATE_INSTANTIATION (newdecl))
        {
          /* If newdecl is not a specialization, then it is not a
             template-related function at all.  And that means that we
@@ -3447,16 +3451,16 @@ duplicate_decls (newdecl, olddecl)
          my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl),
                              0);
 
-         if (TREE_USED (olddecl)) 
+         if (TREE_USED (olddecl))
            /* From [temp.expl.spec]:
-              
+
               If a template, a member template or the member of a class
               template is explicitly specialized then that
               specialization shall be declared before the first use of
               that specialization that would cause an implicit
               instantiation to take place, in every translation unit in
               which such a use occurs.  */
-           cp_error ("explicit specialization of %D after first use", 
+           cp_error ("explicit specialization of %D after first use",
                      olddecl);
 
          SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
@@ -3542,16 +3546,16 @@ duplicate_decls (newdecl, olddecl)
             the following sequence of events has occurred:
 
             o A friend function was declared in a class template.  The
-            class template was instantiated.  
+            class template was instantiated.
 
-            o The instantiation of the friend declaration was 
-            recorded on the instantiation list, and is newdecl.  
+            o The instantiation of the friend declaration was
+            recorded on the instantiation list, and is newdecl.
 
             o Later, however, instantiate_class_template called pushdecl
             on the newdecl to perform name injection.  But, pushdecl in
             turn called duplicate_decls when it discovered that another
             declaration of a global function with the same name already
-            existed. 
+            existed.
 
             o Here, in duplicate_decls, we decided to clobber newdecl.
 
@@ -3560,8 +3564,8 @@ duplicate_decls (newdecl, olddecl)
             instantiations so that if we try to do the instantiation
             again we won't get the clobbered declaration.  */
 
-         tree tmpl = DECL_TI_TEMPLATE (newdecl); 
-         tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); 
+         tree tmpl = DECL_TI_TEMPLATE (newdecl);
+         tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
 
          for (; decls; decls = TREE_CHAIN (decls))
            if (TREE_VALUE (decls) == newdecl)
@@ -3625,8 +3629,6 @@ pushdecl (x)
             scoped of the current namespace, not the current
             function.  */
          && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
-         /* Don't change DECL_CONTEXT of virtual methods.  */
-         && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
          && !DECL_CONTEXT (x))
        DECL_CONTEXT (x) = current_function_decl;
       if (!DECL_CONTEXT (x))
@@ -3635,7 +3637,7 @@ pushdecl (x)
       /* If this is the declaration for a namespace-scope function,
         but the declaration itself is in a local scope, mark the
         declaration.  */
-      if (TREE_CODE (x) == FUNCTION_DECL 
+      if (TREE_CODE (x) == FUNCTION_DECL
          && DECL_NAMESPACE_SCOPE_P (x)
          && current_function_decl
          && x != current_function_decl)
@@ -3657,7 +3659,7 @@ pushdecl (x)
 #endif
       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
-      
+
       /* Namespace-scoped variables are not found in the current level. */
       if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x))
        t = namespace_binding (name, DECL_CONTEXT (x));
@@ -3746,7 +3748,7 @@ pushdecl (x)
          else if (DECL_MAIN_P (x))
            {
              /* A redeclaration of main, but not a duplicate of the
-                previous one. 
+                previous one.
 
                 [basic.start.main]
 
@@ -3804,7 +3806,7 @@ pushdecl (x)
                   /* We don't want to copy the type when all we're
                      doing is making a TYPE_DECL for the purposes of
                      inlining.  */
-                  && (!TYPE_NAME (type) 
+                  && (!TYPE_NAME (type)
                       || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
             {
              DECL_ORIGINAL_TYPE (x) = type;
@@ -3817,7 +3819,7 @@ pushdecl (x)
          if (type != error_mark_node
              && TYPE_NAME (type)
              && TYPE_IDENTIFIER (type))
-            set_identifier_type_value_with_scope (DECL_NAME (x), type, 
+            set_identifier_type_value_with_scope (DECL_NAME (x), type,
                                                  current_binding_level);
 
        }
@@ -3826,7 +3828,7 @@ pushdecl (x)
 
         We get warnings about inline functions where they are defined.
         We get warnings about other functions from push_overloaded_decl.
-        
+
         Avoid duplicate warnings where they are used.  */
       if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
        {
@@ -3866,11 +3868,11 @@ pushdecl (x)
                 the mangled name (i.e., NAME) to the DECL.  But, for
                 an `extern "C"' function, the mangled name and the
                 ordinary name are the same so we need not do this.  */
-             && !(TREE_CODE (x) == FUNCTION_DECL && 
+             && !(TREE_CODE (x) == FUNCTION_DECL &&
                   DECL_LANGUAGE (x) == lang_c))
            {
              if (TREE_CODE (x) == FUNCTION_DECL)
-               my_friendly_assert 
+               my_friendly_assert
                  ((IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE)
                  || (IDENTIFIER_GLOBAL_VALUE (name) == x), 378);
              SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
@@ -3916,16 +3918,29 @@ pushdecl (x)
 
          /* If this is a TYPE_DECL, push it into the type value slot.  */
          if (TREE_CODE (x) == TYPE_DECL)
-           set_identifier_type_value_with_scope (name, TREE_TYPE (x), 
+           set_identifier_type_value_with_scope (name, TREE_TYPE (x),
                                                  current_binding_level);
 
          /* Clear out any TYPE_DECL shadowed by a namespace so that
             we won't think this is a type.  The C struct hack doesn't
             go through namespaces.  */
          if (TREE_CODE (x) == NAMESPACE_DECL)
-           set_identifier_type_value_with_scope (name, NULL_TREE, 
+           set_identifier_type_value_with_scope (name, NULL_TREE,
                                                  current_binding_level);
 
+         if (oldlocal)
+           {
+             tree d = oldlocal;
+             while (oldlocal
+                    && TREE_CODE (oldlocal) == VAR_DECL
+                    && DECL_DEAD_FOR_LOCAL (oldlocal))
+               {
+                 oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
+               }
+             if (oldlocal == NULL_TREE)
+               oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
+           }
+
          /* If this is an extern function declaration, see if we
             have a global definition or declaration for the function.  */
          if (oldlocal == NULL_TREE
@@ -3952,15 +3967,14 @@ pushdecl (x)
              && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
 
-         if (DECL_FROM_INLINE (x))
-           /* Inline decls shadow nothing.  */;
-
          /* Warn if shadowing an argument at the top level of the body.  */
-         else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
-                  && TREE_CODE (oldlocal) == PARM_DECL
-                  /* Don't complain if it's from an enclosing function.  */
-                  && DECL_CONTEXT (oldlocal) == current_function_decl
-                  && TREE_CODE (x) != PARM_DECL)
+         if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
+             /* Inline decls shadow nothing.  */
+             && !DECL_FROM_INLINE (x)
+             && TREE_CODE (oldlocal) == PARM_DECL
+             /* Don't complain if it's from an enclosing function.  */
+             && DECL_CONTEXT (oldlocal) == current_function_decl
+             && TREE_CODE (x) != PARM_DECL)
            {
              /* Go to where the parms should be and see if we
                 find them there.  */
@@ -3973,20 +3987,15 @@ pushdecl (x)
              if (b->parm_flag == 1)
                cp_error ("declaration of `%#D' shadows a parameter", name);
            }
-         else if (warn_shadow && oldlocal != NULL_TREE
-                  && current_binding_level->is_for_scope
-                  && !DECL_DEAD_FOR_LOCAL (oldlocal))
-           {
-             warning ("variable `%s' shadows local",
-                      IDENTIFIER_POINTER (name));
-             cp_warning_at ("  this is the shadowed declaration", oldlocal);
-           }              
+
          /* Maybe warn if shadowing something else.  */
-         else if (warn_shadow && !DECL_EXTERNAL (x)
-                  /* No shadow warnings for internally generated vars.  */
-                  && ! DECL_ARTIFICIAL (x)
-                  /* No shadow warnings for vars made for inlining.  */
-                  && ! DECL_FROM_INLINE (x))
+         if (warn_shadow && !DECL_EXTERNAL (x)
+             /* Inline decls shadow nothing.  */
+             && !DECL_FROM_INLINE (x)
+             /* No shadow warnings for internally generated vars.  */
+             && ! DECL_ARTIFICIAL (x)
+             /* No shadow warnings for vars made for inlining.  */
+             && ! DECL_FROM_INLINE (x))
            {
              if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL)
                warning ("declaration of `%s' shadows a parameter",
@@ -4017,12 +4026,18 @@ pushdecl (x)
              /* RTTI TD entries are created while defining the type_info.  */
              || (TYPE_LANG_SPECIFIC (TREE_TYPE (x))
                  && TYPE_BEING_DEFINED (TREE_TYPE (x)))))
-       current_binding_level->incomplete 
-         = tree_cons (NULL_TREE, x, current_binding_level->incomplete);
+       {
+         if (namespace_bindings_p ())
+           namespace_scope_incomplete
+             = tree_cons (NULL_TREE, x, namespace_scope_incomplete);
+         else
+           current_binding_level->incomplete
+             = tree_cons (NULL_TREE, x, current_binding_level->incomplete);
+       }
     }
 
   if (need_new_binding)
-    add_decl_to_level (x, 
+    add_decl_to_level (x,
                       DECL_NAMESPACE_SCOPE_P (x)
                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
                       : current_binding_level);
@@ -4162,11 +4177,12 @@ maybe_push_decl (decl)
   /* Add this decl to the current binding level, but not if it comes
      from another scope, e.g. a static member variable.  TEM may equal
      DECL or it may be a previous decl of the same name.  */
-  if ((TREE_CODE (decl) != PARM_DECL 
-       && DECL_CONTEXT (decl) != NULL_TREE 
-       /* Definitions of namespace members outside their namespace are
-         possible. */
-       && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+  if (decl == error_mark_node
+      || (TREE_CODE (decl) != PARM_DECL
+         && DECL_CONTEXT (decl) != NULL_TREE
+         /* Definitions of namespace members outside their namespace are
+            possible. */
+         && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
       || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
       || TREE_CODE (type) == UNKNOWN_TYPE
       /* The declaration of a template specialization does not affect
@@ -4211,7 +4227,7 @@ push_class_level_binding (name, x)
      tree x;
 {
   tree binding;
-  /* The class_binding_level will be NULL if x is a template 
+  /* The class_binding_level will be NULL if x is a template
      parameter name in a member template.  */
   if (!class_binding_level)
     return;
@@ -4225,7 +4241,7 @@ push_class_level_binding (name, x)
      class, then we will need to restore IDENTIFIER_CLASS_VALUE when
      we leave this class.  Record the shadowed declaration here.  */
   binding = IDENTIFIER_BINDING (name);
-  if (binding 
+  if (binding
       && ((TREE_CODE (x) == OVERLOAD
           && BINDING_VALUE (binding)
           && is_overloaded_fn (BINDING_VALUE (binding)))
@@ -4292,7 +4308,7 @@ push_using_decl (scope, name)
      tree name;
 {
   tree decl;
-  
+
   my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
   for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
@@ -4317,7 +4333,7 @@ push_using_directive (used)
 {
   tree ud = current_binding_level->using_directives;
   tree iter, ancestor;
-  
+
   /* Check if we already have this. */
   if (purpose_member (used, ud) != NULL_TREE)
     return NULL_TREE;
@@ -4346,7 +4362,7 @@ push_using_directive (used)
      PUSH_LOCAL: Bind DECL in the current scope, rather than at
                  namespace scope.
      PUSH_USING: DECL is being pushed as the result of a using
-                 declaration. 
+                 declaration.
 
    The value returned may be a previous declaration if we guessed wrong
    about what language DECL should belong to (C or C++).  Otherwise,
@@ -4381,7 +4397,7 @@ push_overloaded_decl (decl, flags)
       else if (is_overloaded_fn (old))
         {
           tree tmp;
-         
+
          for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
            {
              tree fn = OVL_CURRENT (tmp);
@@ -4392,7 +4408,7 @@ push_overloaded_decl (decl, flags)
                                TYPE_ARG_TYPES (TREE_TYPE (decl))))
                cp_error ("`%#D' conflicts with previous using declaration `%#D'",
                          decl, fn);
-             
+
              if (duplicate_decls (decl, fn))
                return fn;
            }
@@ -4431,7 +4447,7 @@ push_overloaded_decl (decl, flags)
       if (TREE_CODE (new_binding) == OVERLOAD && old)
        {
          tree *d;
-         
+
          for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names;
               *d;
               d = &TREE_CHAIN (*d))
@@ -4444,7 +4460,7 @@ push_overloaded_decl (decl, flags)
                  TREE_VALUE (*d) = new_binding;
                else
                  /* Build a TREE_LIST to wrap the OVERLOAD.  */
-                 *d = tree_cons (NULL_TREE, new_binding, 
+                 *d = tree_cons (NULL_TREE, new_binding,
                                  TREE_CHAIN (*d));
 
                /* And update the CPLUS_BINDING node.  */
@@ -4481,7 +4497,7 @@ implicitly_declare (functionid)
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
 
-  /* ANSI standard says implicit declarations are in the innermost block.
+  /* ISO standard says implicit declarations are in the innermost block.
      So we record the decl in the standard fashion.  */
   pushdecl (decl);
   rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
@@ -4523,7 +4539,7 @@ redeclaration_error_message (newdecl, olddecl)
       /* If this is a pure function, its olddecl will actually be
         the original initialization to `0' (which we force to call
         abort()).  Don't complain about redefinition in this case.  */
-      if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl))
+      if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl))
        return 0;
 
       /* If both functions come from different namespaces, this is not
@@ -4557,7 +4573,7 @@ redeclaration_error_message (newdecl, olddecl)
        return "redefinition of `%#D'";
       return 0;
     }
-  else if (toplevel_bindings_p ())
+  else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
     {
       /* Objects declared at top level:  */
       /* If at least one is a reference, it's ok.  */
@@ -4630,7 +4646,7 @@ make_label_decl (id, local_p)
    be found, create one.  (We keep track of used, but undefined,
    labels, and complain about them at the end of a function.)  */
 
-tree 
+tree
 lookup_label (id)
      tree id;
 {
@@ -4643,7 +4659,7 @@ lookup_label (id)
             IDENTIFIER_POINTER (id));
       return NULL_TREE;
     }
-  
+
   /* See if we've already got this label.  */
   decl = IDENTIFIER_LABEL_VALUE (id);
   if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl)
@@ -4673,14 +4689,14 @@ declare_local_label (id)
   /* Add a new entry to the SHADOWED_LABELS list so that when we leave
      this scope we can restore the old value of
      IDENTIFIER_TYPE_VALUE.  */
-  current_binding_level->shadowed_labels 
+  current_binding_level->shadowed_labels
     = tree_cons (IDENTIFIER_LABEL_VALUE (id), NULL_TREE,
                 current_binding_level->shadowed_labels);
   /* Look for the label.  */
   decl = make_label_decl (id, /*local_p=*/1);
   /* Now fill in the information we didn't have before.  */
   TREE_VALUE (current_binding_level->shadowed_labels) = decl;
-  
+
   return decl;
 }
 
@@ -4850,7 +4866,7 @@ define_case_label ()
   if (! switch_stack)
     /* Don't crash; we'll complain in do_case.  */
     return;
-  
+
   if (cleanup)
     {
       static int explained = 0;
@@ -4979,10 +4995,10 @@ lookup_tag (form, name, binding_level, thislevel_only)
               declaration, then we use the _TYPE node for the
               template.  See the example below.  */
            if (thislevel_only && !allow_pseudo_global
-               && old && BINDING_VALUE (old) 
+               && old && BINDING_VALUE (old)
                && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old)))
              old = TREE_TYPE (BINDING_VALUE (old));
-           else 
+           else
              old = BINDING_TYPE (old);
 
            /* If it has an original type, it is a typedef, and we
@@ -5024,10 +5040,10 @@ lookup_tag (form, name, binding_level, thislevel_only)
          if (level->pseudo_global && allow_pseudo_global)
            {
              /* We must deal with cases like this:
-                
+
                   template <class T> struct S;
                   template <class T> struct S {};
-                  
+
                 When looking up `S', for the second declaration, we
                 would like to find the first declaration.  But, we
                 are in the pseudo-global level created for the
@@ -5118,7 +5134,7 @@ lookup_namespace_name (namespace, name)
     }
 
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
-  
+
   val = make_node (CPLUS_BINDING);
   if (!qualified_lookup_using_namespace (name, namespace, val, 0))
     return error_mark_node;
@@ -5130,14 +5146,14 @@ lookup_namespace_name (namespace, name)
       if (template_id)
        {
          if (DECL_CLASS_TEMPLATE_P (val))
-           val = lookup_template_class (val, 
+           val = lookup_template_class (val,
                                         TREE_OPERAND (template_id, 1),
                                         /*in_decl=*/NULL_TREE,
                                         /*context=*/NULL_TREE,
                                         /*entering_scope=*/0);
          else if (DECL_FUNCTION_TEMPLATE_P (val)
                   || TREE_CODE (val) == OVERLOAD)
-           val = lookup_template_function (val, 
+           val = lookup_template_function (val,
                                            TREE_OPERAND (template_id, 1));
          else
            {
@@ -5189,10 +5205,10 @@ typename_compare (k1, k2)
   t2 = (tree) k2;
   d1 = TYPE_NAME (t1);
   d2 = TYPE_NAME (t2);
-  
+
   return (DECL_NAME (d1) == DECL_NAME (d2)
          && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2))
-         && ((TREE_TYPE (t1) != NULL_TREE) 
+         && ((TREE_TYPE (t1) != NULL_TREE)
              == (TREE_TYPE (t2) != NULL_TREE))
          && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
          && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2));
@@ -5202,7 +5218,7 @@ typename_compare (k1, k2)
    the type of `T', NAME is the IDENTIFIER_NODE for `t'.  If BASE_TYPE
    is non-NULL, this type is being created by the implicit typename
    extension, and BASE_TYPE is a type named `t' in some base class of
-   `T' which depends on template parameters.  
+   `T' which depends on template parameters.
 
    Returns the new TYPENAME_TYPE.  */
 
@@ -5222,7 +5238,7 @@ build_typename_type (context, name, fullname, base_type)
   if (!ht.table)
     {
       static struct hash_table *h = &ht;
-      if (!hash_table_init (&ht, &hash_newfunc, &typename_hash, 
+      if (!hash_table_init (&ht, &hash_newfunc, &typename_hash,
                            &typename_compare))
        fatal ("virtual memory exhausted");
       ggc_add_tree_hash_table_root (&h, 1);
@@ -5265,8 +5281,8 @@ make_typename_type (context, name, complain)
 
   if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
     {
-      if (!(TYPE_LANG_SPECIFIC (name) 
-           && (CLASSTYPE_IS_TEMPLATE (name) 
+      if (!(TYPE_LANG_SPECIFIC (name)
+           && (CLASSTYPE_IS_TEMPLATE (name)
                || CLASSTYPE_USE_TEMPLATE (name))))
        name = TYPE_IDENTIFIER (name);
       else
@@ -5315,15 +5331,15 @@ make_typename_type (context, name, complain)
              return error_mark_node;
            }
 
-         return lookup_template_class (tmpl, 
+         return lookup_template_class (tmpl,
                                        TREE_OPERAND (fullname, 1),
-                                       NULL_TREE, context, 
+                                       NULL_TREE, context,
                                        /*entering_scope=*/0);
        }
       else
        {
           tree t;
-          
+
          if (!IS_AGGR_TYPE (context))
            {
              if (complain)
@@ -5345,8 +5361,8 @@ make_typename_type (context, name, complain)
        cp_error ("no type named `%#T' in `%#T'", name, context);
       return error_mark_node;
     }
-    
-  
+
+
   return build_typename_type (context, name, fullname,  NULL_TREE);
 }
 
@@ -5366,7 +5382,7 @@ select_decl (binding, flags)
         return val;
       return NULL_TREE;
     }
-  
+
   /* If we could have a type and
      we have nothing or we need a type and have none.  */
   if (BINDING_TYPE (binding)
@@ -5413,7 +5429,7 @@ unqualified_namespace_lookup (name, flags, spacesp)
       BINDING_TYPE (b) = BINDING_TYPE (val);
 
       /* Add all _DECLs seen through local using-directives. */
-      for (level = current_binding_level; 
+      for (level = current_binding_level;
           !level->namespace_p;
           level = level->level_chain)
        if (!lookup_using_namespace (name, b, level->using_directives,
@@ -5426,7 +5442,7 @@ unqualified_namespace_lookup (name, flags, spacesp)
       siter = initial;
       while (1)
        {
-         if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), 
+         if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter),
                                       scope, flags, spacesp))
            /* Give up because of error. */
            return error_mark_node;
@@ -5495,7 +5511,7 @@ warn_about_implicit_typename_lookup (typename, binding)
       && ! (TREE_CODE (binding) == TYPE_DECL
            && same_type_p (TREE_TYPE (binding), subtype)))
     {
-      cp_warning ("lookup of `%D' finds `%#D'", 
+      cp_warning ("lookup of `%D' finds `%#D'",
                  name, binding);
       cp_warning ("  instead of `%D' from dependent base class",
                  typename);
@@ -5513,7 +5529,7 @@ warn_about_implicit_typename_lookup (typename, binding)
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
    If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
    If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
-   Otherwise we prefer non-TYPE_DECLs.  
+   Otherwise we prefer non-TYPE_DECLs.
 
    If NONCLASS is non-zero, we don't look for the NAME in class scope,
    using IDENTIFIER_CLASS_VALUE.  */
@@ -5555,7 +5571,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
        type = got_scope;
       else if (got_object != error_mark_node)
        type = got_object;
-      
+
       if (type)
        {
          if (type == error_mark_node)
@@ -5585,7 +5601,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
          else if (type == current_class_type)
            val = IDENTIFIER_CLASS_VALUE (name);
          else
-           val = lookup_member (type, name, 0, prefer_type);
+           {
+             val = lookup_member (type, name, 0, prefer_type);
+             type_access_control (type, val);
+           }
        }
       else
        val = NULL_TREE;
@@ -5614,23 +5633,28 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
       if (!LOCAL_BINDING_P (t) && nonclass)
        /* We're not looking for class-scoped bindings, so keep going.  */
        continue;
-      
+
       /* If this is the kind of thing we're looking for, we're done.  */
       if (qualify_lookup (BINDING_VALUE (t), flags))
        binding = BINDING_VALUE (t);
-      else if ((flags & LOOKUP_PREFER_TYPES) 
+      else if ((flags & LOOKUP_PREFER_TYPES)
               && qualify_lookup (BINDING_TYPE (t), flags))
        binding = BINDING_TYPE (t);
       else
        binding = NULL_TREE;
 
+      /* Handle access control on types from enclosing or base classes.  */
+      if (binding && ! yylex
+         && BINDING_LEVEL (t) && BINDING_LEVEL (t)->parm_flag == 2)
+       type_access_control (BINDING_LEVEL (t)->this_class, binding);
+
       if (binding
          && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
        {
          if (val_is_implicit_typename && !yylex)
            warn_about_implicit_typename_lookup (val, binding);
          val = binding;
-         val_is_implicit_typename 
+         val_is_implicit_typename
            = IMPLICIT_TYPENAME_TYPE_DECL_P (val);
          if (!val_is_implicit_typename)
            break;
@@ -5735,14 +5759,14 @@ lookup_name_current_level (name)
       if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
        t = TREE_VALUE (t);
     }
-  else if (IDENTIFIER_BINDING (name) 
+  else if (IDENTIFIER_BINDING (name)
           && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
     {
       while (1)
        {
          if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
            return IDENTIFIER_VALUE (name);
-         
+
          if (b->keep == 2)
            b = b->level_chain;
          else
@@ -5840,7 +5864,7 @@ record_builtin_type (rid_index, name, type)
     tname = get_identifier (name);
 
   TYPE_BUILT_IN (type) = 1;
-  
+
   if (tname)
     {
       tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
@@ -5914,26 +5938,6 @@ record_unknown_type (type, name)
   TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
   TYPE_ALIGN (type) = 1;
   TYPE_MODE (type) = TYPE_MODE (void_type_node);
-} 
-
-/* Push overloaded decl, in global scope, with one argument so it
-   can be used as a callback from define_function.  */
-
-static void
-push_overloaded_decl_1 (x)
-     tree x;
-{
-  pushdecl (x);
-}
-
-inline tree
-auto_function (name, type)
-     tree name, type;
-{
-  return define_function
-    (IDENTIFIER_POINTER (name), type, push_overloaded_decl_1,
-     IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type),
-                                             0)));
 }
 
 /* Create the predefined scalar types of C,
@@ -5948,6 +5952,11 @@ init_decl_processing ()
   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");
+
   /* Have to make these distinct before we try using them.  */
   lang_name_cplusplus = get_identifier ("C++");
   lang_name_c = get_identifier ("C");
@@ -6067,11 +6076,11 @@ init_decl_processing ()
 
   /* 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, 
+  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, 
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE,
                        widest_unsigned_literal_type_node));
 
   /* These are types that type_for_size and type_for_mode use.  */
@@ -6117,7 +6126,8 @@ init_decl_processing ()
   boolean_true_node = build_int_2 (1, 0);
   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);
+  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);
 
@@ -6142,7 +6152,7 @@ init_decl_processing ()
 
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
-    = build_pointer_type (build_qualified_type (char_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
@@ -6151,9 +6161,7 @@ init_decl_processing ()
 
   /* 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
-     and large enough that it can hold most function names for the
-     initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
+     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.
@@ -6165,15 +6173,18 @@ init_decl_processing ()
   int_array_type_node
     = build_array_type (integer_type_node, array_domain_type);
 
-  /* This is just some anonymous class type.  Nobody should ever
-     need to look inside this envelope.  */
-  class_star_type_node = build_pointer_type (make_aggr_type (RECORD_TYPE));
-
-  if (flag_huge_objects)
+  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;
+
   default_function_type
     = build_function_type (integer_type_node, NULL_TREE);
 
@@ -6254,6 +6265,7 @@ init_decl_processing ()
       DECL_NAME (fields[3]) = delta2_identifier;
       DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
       DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
+      DECL_SIZE_UNIT (fields[3]) = TYPE_SIZE_UNIT (delta_type_node);
       TREE_UNSIGNED (fields[3]) = 0;
       TREE_CHAIN (fields[2]) = fields[3];
       vtable_entry_type = build_qualified_type (vtable_entry_type,
@@ -6270,7 +6282,7 @@ init_decl_processing ()
   layout_type (vtbl_ptr_type_node);
   record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
 
-  std_node = build_decl (NAMESPACE_DECL, 
+  std_node = build_decl (NAMESPACE_DECL,
                         get_identifier (flag_honor_std ? "fake std":"std"),
                         void_type_node);
   pushdecl (std_node);
@@ -6292,15 +6304,15 @@ init_decl_processing ()
     newtype = build_exception_variant
       (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
     deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
-    auto_function (ansi_opname[(int) NEW_EXPR], newtype);
-    auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype);
-    global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR],
-                                         deltype);
-    auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
+    push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
+    push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
+    global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
+                                              deltype);
+    push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
   }
 
   abort_fndecl
-    = define_function ("__pure_virtual", void_ftype, 0, 0);
+    = build_library_fn_ptr ("__pure_virtual", void_ftype);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -6319,6 +6331,7 @@ init_decl_processing ()
     flag_weak = 0;
 
   /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
+  make_fname_decl = cp_make_fname_decl;
   declare_function_name ();
 
   /* Prepare to check format strings against argument lists.  */
@@ -6369,6 +6382,59 @@ init_decl_processing ()
   ggc_add_tree_root (&static_aggregates, 1);
 }
 
+/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
+   decl, NAME is the initialization string and TYPE_DEP indicates whether
+   NAME depended on the type of the function. We make use of that to detect
+   __PRETTY_FUNCTION__ inside a template fn.  Because we build a tree for
+   the function before emitting any of it, we don't need to treat the
+   VAR_DECL specially. We can decide whether to emit it later, if it was
+   used.  */
+
+static tree
+cp_make_fname_decl (id, name, type_dep)
+     tree id;
+     const char *name;
+     int 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));
+
+  type =  build_cplus_array_type
+          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
+          domain);
+
+  decl = build_lang_decl (VAR_DECL, id, type);
+  TREE_STATIC (decl) = 1;
+  TREE_READONLY (decl) = 1;
+  DECL_SOURCE_LINE (decl) = 0;
+  DECL_ARTIFICIAL (decl) = 1;
+  DECL_IN_SYSTEM_HEADER (decl) = 1;
+  pushdecl (decl);
+  if (processing_template_decl)
+    decl = push_template_decl (decl);
+  if (type_dep)
+    {
+      init = build (FUNCTION_NAME, type);
+      DECL_PRETTY_FUNCTION_P (decl) = 1;
+    }
+  else
+    {
+      init = build_string (length + 1, name);
+      TREE_TYPE (init) = type;
+    }
+  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;
+}
+
 /* Function to print any language-specific context for an error message.  */
 
 static void
@@ -6379,56 +6445,154 @@ lang_print_error_function (file)
   maybe_print_template_context ();
 }
 
-/* Make a definition for a builtin function named NAME and whose data type
+/* Entry point for the benefit of c_common_nodes_and_builtins.
+
+   Make a definition for a builtin function named NAME and whose data type
    is TYPE.  TYPE should be a function type with argument types.
 
-   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
+   CLASS and CODE tell later passes how to compile calls to this function.
+   See tree.h for possible values.
+
+   If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
    the name to be called if we can't opencode the function.  */
 
 tree
-define_function (name, type, pfn, library_name)
+builtin_function (name, type, code, class, libname)
      const char *name;
      tree type;
-     void (*pfn) PROTO((tree));
-     const char *library_name;
+     int code;
+     enum built_in_class class;
+     const char *libname;
 {
-  tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
-  DECL_EXTERNAL (decl) = 1;
-  TREE_PUBLIC (decl) = 1;
-  DECL_ARTIFICIAL (decl) = 1;
+  tree decl = build_library_fn_1 (get_identifier (name), type);
+  DECL_BUILT_IN_CLASS (decl) = class;
+  DECL_FUNCTION_CODE (decl) = code;
 
   my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
-  DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
 
   /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
      we cannot change DECL_ASSEMBLER_NAME until we have installed this
      function in the namespace.  */
-  if (pfn) (*pfn) (decl);
-  if (library_name)
-    DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
+  pushdecl (decl);
+  if (libname)
+    DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
   make_function_rtl (decl);
   return decl;
 }
 
+/* Generate a FUNCTION_DECL with the typical flags for a runtime library
+   function.  Not called directly.  */
+
+static tree
+build_library_fn_1 (name, type)
+     tree name;
+     tree type;
+{
+  tree fn = build_lang_decl (FUNCTION_DECL, name, type);
+  DECL_EXTERNAL (fn) = 1;
+  TREE_PUBLIC (fn) = 1;
+  DECL_ARTIFICIAL (fn) = 1;
+  TREE_NOTHROW (fn) = 1;
+  return fn;
+}
 
-/* Wrapper around define_function, for the benefit of 
-   c_common_nodes_and_builtins.
-   FUNCTION_CODE tells later passes how to compile calls to this function.
-   See tree.h for its possible values.  */
+/* Returns the _DECL for a library function with C linkage.
+   We assume that such functions never throw; if this is incorrect,
+   callers should unset TREE_NOTHROW.  */
 
 tree
-builtin_function (name, type, code, class, libname)
+build_library_fn (name, type)
+     tree name;
+     tree type;
+{
+  tree fn = build_library_fn_1 (name, type);
+  make_function_rtl (fn);
+  return fn;
+}
+
+/* Returns the _DECL for a library function with C++ linkage.  */
+
+tree
+build_cp_library_fn (name, type)
+     tree name;
+     tree type;
+{
+  tree fn = build_library_fn_1 (name, type);
+  TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+  set_mangled_name_for_decl (fn);
+  make_function_rtl (fn);
+  return fn;
+}
+
+/* Like build_library_fn, but takes a C string instead of an
+   IDENTIFIER_NODE.  */
+
+tree
+build_library_fn_ptr (name, type)
      const char *name;
      tree type;
-     int code;
-     enum built_in_class class;
-     const char *libname;
 {
-  tree decl = define_function (name, type, (void (*) PROTO((tree)))pushdecl,
-                              libname);
-  DECL_BUILT_IN_CLASS (decl) = class;
-  DECL_FUNCTION_CODE (decl) = code;
-  return decl;
+  return build_library_fn (get_identifier (name), type);
+}
+
+/* Like build_cp_library_fn, but takes a C string instead of an
+   IDENTIFIER_NODE.  */
+
+tree
+build_cp_library_fn_ptr (name, type)
+     const char *name;
+     tree type;
+{
+  return build_cp_library_fn (get_identifier (name), type);
+}
+
+/* Like build_library_fn, but also pushes the function so that we will
+   be able to find it via IDENTIFIER_GLOBAL_VALUE.  */
+
+tree
+push_library_fn (name, type)
+     tree name, type;
+{
+  tree fn = build_library_fn (name, type);
+  pushdecl_top_level (fn);
+  return fn;
+}
+
+/* Like build_cp_library_fn, but also pushes the function so that it
+   will be found by normal lookup.  */
+
+tree
+push_cp_library_fn (name, type)
+     tree name;
+     tree type;
+{
+  tree fn = build_cp_library_fn (name, type);
+  pushdecl (fn);
+  return fn;
+}
+
+/* Like push_library_fn, but takes a TREE_LIST of parm types rather than
+   a FUNCTION_TYPE.  */
+
+tree
+push_void_library_fn (name, parmtypes)
+     tree name, parmtypes;
+{
+  tree type = build_function_type (void_type_node, parmtypes);
+  return push_library_fn (name, type);
+}
+
+/* Like push_library_fn, but also note that this function throws
+   and does not return.  Used for __throw_foo and the like.  */
+
+tree
+push_throw_library_fn (name, type)
+     tree name, type;
+{
+  tree fn = push_library_fn (name, type);
+  TREE_THIS_VOLATILE (fn) = 1;
+  TREE_NOTHROW (fn) = 0;
+  return fn;
 }
 \f
 /* When we call finish_struct for an anonymous union, we create
@@ -6466,8 +6630,7 @@ fixup_anonymous_aggr (t)
        q = &TREE_CHAIN (*q);
     }
 
-  /* ANSI C++ June 5 1992 WP 9.5.3.  Anonymous unions may not have
-     function members.  */
+  /* ISO C++ 9.5.3.  Anonymous unions may not have function members.  */
   if (TYPE_METHODS (t))
     error ("an anonymous union cannot have function members");
 }
@@ -6655,13 +6818,13 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
     }
 
   if (attributes || prefix_attributes)
-    attrlist = build_scratch_list (attributes, prefix_attributes);
+    attrlist = build_tree_list (attributes, prefix_attributes);
   else
     attrlist = NULL_TREE;
 
   decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
                         attrlist);
-                        
+
   if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
     return NULL_TREE;
 
@@ -6670,10 +6833,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
   if (type == error_mark_node)
     return NULL_TREE;
 
-  context
-    = (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
-      ? DECL_CLASS_CONTEXT (decl)
-      : DECL_CONTEXT (decl);
+  context = DECL_CONTEXT (decl);
 
   if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL
       && context != current_namespace && TREE_CODE (decl) == VAR_DECL)
@@ -6732,7 +6892,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
 #ifdef SET_DEFAULT_DECL_ATTRIBUTES
   SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
 #endif
-  
+
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   cplus_decl_attributes (decl, attributes, prefix_attributes);
 
@@ -6749,7 +6909,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
            {
              if (DECL_CONTEXT (field) != context)
                {
-                 cp_pedwarn ("ANSI C++ does not permit `%T::%D' to be defined as `%T::%D'",
+                 cp_pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
                              DECL_CONTEXT (field), DECL_NAME (decl),
                              context, DECL_NAME (decl));
                  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
@@ -6774,7 +6934,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
 
       /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set.  */
       DECL_IN_AGGR_P (decl) = 0;
-      if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) 
+      if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
          || CLASSTYPE_USE_TEMPLATE (context))
        {
          SET_DECL_TEMPLATE_SPECIALIZATION (decl);
@@ -6807,7 +6967,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
      data segment.  */
   DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
 #endif
-  
+
   if (! processing_template_decl)
     start_decl_1 (tem);
 
@@ -6827,7 +6987,7 @@ start_decl_1 (decl)
   /* 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_NEEDS_DESTRUCTOR (type)
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
       && current_binding_level->more_cleanups_ok == 0)
     {
       keep_next_level (2);
@@ -6864,7 +7024,9 @@ start_decl_1 (decl)
   if (!initialized
       && TREE_CODE (decl) != TYPE_DECL
       && TREE_CODE (decl) != TEMPLATE_DECL
-      && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl))
+      && type != error_mark_node
+      && IS_AGGR_TYPE (type) 
+      && ! DECL_EXTERNAL (decl))
     {
       if ((! processing_template_decl || ! uses_template_parms (type))
          && TYPE_SIZE (complete_type (type)) == NULL_TREE)
@@ -6917,7 +7079,7 @@ grok_reference_init (decl, type, init)
 
   if (TREE_CODE (init) == CONSTRUCTOR)
     {
-      cp_error ("ANSI C++ forbids use of initializer list to initialize reference `%D'", decl);
+      cp_error ("ISO C++ forbids use of initializer list to initialize reference `%D'", decl);
       return;
     }
 
@@ -6933,7 +7095,7 @@ grok_reference_init (decl, type, init)
       /* Note: default conversion is only called in very special cases.  */
       init = default_conversion (init);
     }
-  
+
   /* Convert INIT to the reference type TYPE.  This may involve the
      creation of a temporary, whose lifetime must be the same as that
      of the reference.  If so, a DECL_STMT for the temporary will be
@@ -7064,11 +7226,11 @@ layout_var_decl (decl)
   /* If we haven't already layed out this declaration, do so now.
      Note that we must not call complete type for an external object
      because it's type might involve templates that we are not
-     supposed to isntantiate yet.  (And it's perfectly legal to say 
+     supposed to isntantiate yet.  (And it's perfectly legal to say
      `extern X x' for some incomplete type `X'.)  */
   if (!DECL_EXTERNAL (decl))
     complete_type (type);
-  if (!DECL_SIZE (decl)&& TYPE_SIZE (type))
+  if (!DECL_SIZE (decl) && TYPE_SIZE (type))
     layout_decl (decl, 0);
 
   if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
@@ -7114,7 +7276,7 @@ maybe_commonize_var (decl)
      linkage.  */
   if (TREE_STATIC (decl)
       /* Don't mess with __FUNCTION__.  */
-      && ! TREE_ASM_WRITTEN (decl)
+      && ! DECL_ARTIFICIAL (decl)
       && current_function_decl
       && DECL_CONTEXT (decl) == current_function_decl
       && (DECL_THIS_INLINE (current_function_decl)
@@ -7149,7 +7311,7 @@ maybe_commonize_var (decl)
          if (TREE_PUBLIC (decl))
            DECL_ASSEMBLER_NAME (decl)
              = build_static_name (current_function_decl, DECL_NAME (decl));
-         else if (! DECL_ARTIFICIAL (decl))
+         else
            {
              cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
              cp_warning_at ("  you can work around this by removing the initializer", decl);
@@ -7303,7 +7465,7 @@ check_initializer (decl, init)
     }
   else
     check_for_uninitialized_const_var (decl);
-  
+
   return init;
 }
 
@@ -7416,7 +7578,7 @@ maybe_inject_for_scope_var (decl)
 {
   if (current_binding_level->is_for_scope)
     {
-      struct binding_level *outer 
+      struct binding_level *outer
        = current_binding_level->level_chain;
 
       /* Check to see if the same name is already bound at the outer
@@ -7428,11 +7590,11 @@ maybe_inject_for_scope_var (decl)
         Otherwise, we need to preserve the temp slot for decl to last
         into the outer binding level.  */
 
-      tree outer_binding 
+      tree outer_binding
        = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl)));
-             
+
       if (outer_binding && BINDING_LEVEL (outer_binding) == outer
-         && (TREE_CODE (BINDING_VALUE (outer_binding)) 
+         && (TREE_CODE (BINDING_VALUE (outer_binding))
              == VAR_DECL)
          && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
        {
@@ -7471,7 +7633,7 @@ initialize_local_var (decl, init, flags)
   if (TREE_STATIC (decl))
     {
       if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE
-         || TYPE_NEEDS_DESTRUCTOR (type))
+         || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
        expand_static_init (decl, init);
       return;
     }
@@ -7479,7 +7641,7 @@ initialize_local_var (decl, init, flags)
   if (DECL_SIZE (decl) && type != error_mark_node)
     {
       int already_used;
-  
+
       /* Compute and store the initial value.  */
       already_used = TREE_USED (decl) || TREE_USED (type);
 
@@ -7503,7 +7665,7 @@ initialize_local_var (decl, init, flags)
         marked used. (see TREE_USED, above.)  */
       if (TYPE_NEEDS_CONSTRUCTING (type)
          && ! already_used
-         && !TYPE_NEEDS_DESTRUCTOR (type) 
+         && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
          && DECL_NAME (decl))
        TREE_USED (decl) = 0;
       else if (already_used)
@@ -7513,7 +7675,7 @@ initialize_local_var (decl, init, flags)
 
 /* Generate code to destroy DECL (a local variable).  */
 
-static void 
+static void
 destroy_local_var (decl)
      tree decl;
 {
@@ -7523,9 +7685,9 @@ destroy_local_var (decl)
   /* Only variables get cleaned up.  */
   if (TREE_CODE (decl) != VAR_DECL)
     return;
-  
+
   /* And only things with destructors need cleaning up.  */
-  if (!TYPE_NEEDS_DESTRUCTOR (type))
+  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     return;
 
   if (TREE_CODE (decl) == VAR_DECL &&
@@ -7534,7 +7696,7 @@ destroy_local_var (decl)
        translation unit, or that need a static cleanup.  The latter
        are handled by finish_file.  */
     return;
-  
+
   /* Compute the cleanup.  */
   cleanup = maybe_build_cleanup (decl);
 
@@ -7554,14 +7716,14 @@ emit_local_var (decl)
   if (DECL_RTL (decl))
     /* Only a RESULT_DECL should have non-NULL RTL when arriving here.
        All other local variables are assigned RTL in this function.  */
-    my_friendly_assert (TREE_CODE (decl) == RESULT_DECL, 
+    my_friendly_assert (TREE_CODE (decl) == RESULT_DECL,
                        19990828);
   else
     {
       if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
        /* The user must have specified an assembler name for this
           variable.  Set that up now.  */
-       rest_of_decl_compilation 
+       rest_of_decl_compilation
          (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
           /*top_level=*/0, /*at_end=*/0);
       else
@@ -7579,14 +7741,10 @@ emit_local_var (decl)
    If the length of an array type is not known before,
    it must be determined now, from the initial value, or it is an error.
 
-   For C++, `cp_finish_decl' must be fairly evasive:  it must keep initializers
-   for aggregates that have constructors alive on the permanent obstack,
-   so that the global initializing functions can be written at the end.
-
    INIT0 holds the value of an initializer that should be allowed to escape
    the normal rules.
 
-   FLAGS is LOOKUP_ONLYCONVERTING is the = init syntax was used, else 0
+   FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
    if the (init) syntax was used.
 
    For functions that take default parameters, DECL points to its
@@ -7605,7 +7763,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
   const char *asmspec = NULL;
   int was_readonly = 0;
 
-  /* If this is 0, then we did not change obstacks.  */
   if (! decl)
     {
       if (init)
@@ -7613,44 +7770,24 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
       return;
     }
 
-  /* Handling __FUNCTION__ and its ilk in a template-function requires
-     some special processing because we are called from
-     language-independent code.  */
-  if (cfun && processing_template_decl 
-      && current_function_name_declared == 2)
-    {
-      /* Since we're in a template function, we need to
-        push_template_decl.  The language-independent code in
-        declare_hidden_char_array doesn't know to do this.  */
-      retrofit_lang_decl (decl);
-      decl = push_template_decl (decl);
-
-      if (strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), 
-                 "__PRETTY_FUNCTION__") == 0)
-       {
-         init = build (FUNCTION_NAME, const_string_type_node);
-         DECL_PRETTY_FUNCTION_P (decl) = 1;
-       }
-    }
-
   /* If a name was specified, get the string.  */
   if (asmspec_tree)
       asmspec = TREE_STRING_POINTER (asmspec_tree);
 
   if (init && TREE_CODE (init) == NAMESPACE_DECL)
     {
-      cp_error ("Cannot initialize `%D' to namespace `%D'",
+      cp_error ("cannot initialize `%D' to namespace `%D'",
                decl, init);
       init = NULL_TREE;
     }
 
   if (current_class_type
-      && DECL_REAL_CONTEXT (decl) == current_class_type
+      && CP_DECL_CONTEXT (decl) == current_class_type
       && TYPE_BEING_DEFINED (current_class_type)
       && (DECL_INITIAL (decl) || init))
     DECL_DEFINED_IN_CLASS_P (decl) = 1;
 
-  if (TREE_CODE (decl) == VAR_DECL 
+  if (TREE_CODE (decl) == VAR_DECL
       && DECL_CONTEXT (decl)
       && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL
       && DECL_CONTEXT (decl) != current_namespace
@@ -7756,11 +7893,11 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
 
       make_rtl_for_nonlocal_decl (decl, init, asmspec);
 
-      if (TREE_CODE (type) == FUNCTION_TYPE 
+      if (TREE_CODE (type) == FUNCTION_TYPE
          || TREE_CODE (type) == METHOD_TYPE)
-       abstract_virtuals_error (decl, 
+       abstract_virtuals_error (decl,
                                 strip_array_types (TREE_TYPE (type)));
-      else 
+      else
        abstract_virtuals_error (decl, strip_array_types (type));
 
       if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -7801,7 +7938,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
        {
          /* Cleanups for static variables are handled by `finish_file'.  */
          if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE
-             || TYPE_NEEDS_DESTRUCTOR (type))
+             || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
            expand_static_init (decl, init);
        }
     finish_end0:
@@ -7810,7 +7947,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
         due to initialization of qualified member variable.
         I.e., Foo::x = 10;  */
       {
-       tree context = DECL_REAL_CONTEXT (decl);
+       tree context = CP_DECL_CONTEXT (decl);
        if (context
            && TREE_CODE_CLASS (TREE_CODE (context)) == 't'
            && (TREE_CODE (decl) == VAR_DECL
@@ -7828,24 +7965,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
 
  finish_end:
 
-  /* If requested, warn about definitions of large data objects.  */
-
-  if (warn_larger_than
-      && ! processing_template_decl
-      && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
-      && !DECL_EXTERNAL (decl))
-    {
-      register tree decl_size = DECL_SIZE (decl);
-
-      if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
-       {
-         unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
-
-         if (units > larger_than_size)
-           warning_with_decl (decl, "size of `%s' is %u bytes", units);
-       }
-    }
-
   if (was_readonly)
     TREE_READONLY (decl) = 1;
 }
@@ -7910,7 +8029,7 @@ get_atexit_node ()
 
         We build up the argument types and then then function type
         itself.  */
-      
+
       /* First, build the pointer-to-function type for the first
         argument.  */
       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
@@ -7928,7 +8047,7 @@ get_atexit_node ()
   else
     {
       /* The declaration for `atexit' is:
-         
+
            int atexit (void (*)());
 
         We build up the argument types and then then function type
@@ -7943,7 +8062,7 @@ get_atexit_node ()
 
   /* Now, build the function declaration.  */
   push_lang_context (lang_name_c);
-  atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR);
+  atexit_fndecl = build_library_fn_ptr (name, fn_type);
   mark_used (atexit_fndecl);
   pop_lang_context ();
   atexit_node = default_conversion (atexit_fndecl);
@@ -8016,6 +8135,7 @@ start_cleanup_fn ()
       DECL_ARGUMENTS (fndecl) = parmdecl;
     }
 
+  pushdecl (fndecl);
   start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED);
   do_pushlevel ();
 
@@ -8038,11 +8158,11 @@ end_cleanup_fn ()
   pop_from_top_level ();
 }
 
-/* Generate code to handle the destruction of the function-scoped
-   static variable DECL.  */
+/* Generate code to handle the destruction of DECL, an object with
+   static storage duration.  */
 
-static void
-destroy_local_static (decl)
+void
+register_dtor_fn (decl)
      tree decl;
 {
   tree cleanup;
@@ -8052,6 +8172,9 @@ destroy_local_static (decl)
 
   int saved_flag_access_control;
 
+  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+    return;
+
   /* Call build_cleanup before we enter the anonymous function so that
      any access checks will be done relative to the current scope,
      rather than the scope of the anonymous function.  */
@@ -8124,7 +8247,7 @@ expand_static_init (decl, init)
         initialization is complete.  This ensures that an exception,
         thrown during the construction, will cause the variable to
         reinitialized when we pass through this code again, as per:
-        
+
           [stmt.dcl]
 
           If the initialization exits by throwing an exception, the
@@ -8140,7 +8263,7 @@ expand_static_init (decl, init)
       /* Begin the conditional initialization.  */
       if_stmt = begin_if_stmt ();
       finish_if_stmt_cond (build_binary_op (EQ_EXPR, temp,
-                                           integer_zero_node), 
+                                           integer_zero_node),
                           if_stmt);
       then_clause = begin_compound_stmt (/*has_no_scope=*/0);
 
@@ -8167,7 +8290,7 @@ expand_static_init (decl, init)
       if (assignment)
        {
          assignment = tree_cons (NULL_TREE, assignment,
-                                 build_tree_list (NULL_TREE, 
+                                 build_tree_list (NULL_TREE,
                                                   temp_init));
          assignment = build_compound_expr (assignment);
        }
@@ -8177,23 +8300,14 @@ expand_static_init (decl, init)
 
       /* Use atexit to register a function for destroying this static
         variable.  */
-      if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
-       destroy_local_static (decl);
+      register_dtor_fn (decl);
 
       finish_compound_stmt (/*has_no_scope=*/0, then_clause);
       finish_then_clause (if_stmt);
       finish_if_stmt ();
     }
   else
-    {
-      /* This code takes into account memory allocation policy of
-        `start_decl'.  Namely, if TYPE_NEEDS_CONSTRUCTING does not
-        hold for this object, then we must make permanent the storage
-        currently in the temporary obstack.  */
-      if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
-       preserve_initializer ();
-      static_aggregates = tree_cons (init, decl, static_aggregates);
-    }
+    static_aggregates = tree_cons (init, decl, static_aggregates);
 }
 
 /* Finish the declaration of a catch-parameter.  */
@@ -8229,7 +8343,7 @@ complete_array_type (type, initial_value, do_default)
 {
   register tree maxindex = NULL_TREE;
   int value = 0;
-  
+
   if (initial_value)
     {
       /* Note MAXINDEX  is really the maximum index,
@@ -8244,13 +8358,14 @@ complete_array_type (type, initial_value, do_default)
       else if (TREE_CODE (initial_value) == CONSTRUCTOR)
        {
          tree elts = CONSTRUCTOR_ELTS (initial_value);
-         maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node);
+
+         maxindex = ssize_int (-1);
          for (; elts; elts = TREE_CHAIN (elts))
            {
              if (TREE_PURPOSE (elts))
                maxindex = TREE_PURPOSE (elts);
              else
-               maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node);
+               maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1));
            }
          maxindex = copy_node (maxindex);
        }
@@ -8309,13 +8424,18 @@ complete_array_type (type, initial_value, do_default)
    message to print in that case.  Otherwise, quietly return 1.  */
 
 static int
-member_function_or_else (ctype, cur_type, string)
+member_function_or_else (ctype, cur_type, flags)
      tree ctype, cur_type;
-     const char *string;
+     enum overload_flags flags;
 {
   if (ctype && ctype != cur_type)
     {
-      error (string, TYPE_NAME_STRING (ctype));
+      if (flags == DTOR_FLAG)
+       error ("destructor for alien class `%s' cannot be a member",
+              TYPE_NAME_STRING (ctype));
+      else
+       error ("constructor for alien class `%s' cannot be a member",
+              TYPE_NAME_STRING (ctype));
       return 0;
     }
   return 1;
@@ -8355,7 +8475,7 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
    or `volatile'.
    RAISES is a list of exceptions that this function can raise.
    CHECK is 1 if we must find this method in CTYPE, 0 if we should
-   not look, and -1 if we should not call `grokclassfn' at all.  
+   not look, and -1 if we should not call `grokclassfn' at all.
 
    Returns `NULL_TREE' if something goes wrong, after issuing
    applicable error messages.  */
@@ -8420,16 +8540,16 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
     }
 
   if (ctype)
-    DECL_CLASS_CONTEXT (decl) = ctype;
+    DECL_CONTEXT (decl) = ctype;
 
   if (ctype == NULL_TREE && DECL_MAIN_P (decl))
     {
       if (processing_template_decl)
-       error ("cannot declare `main' to be a template");
+       error ("cannot declare `::main' to be a template");
       if (inlinep)
-       error ("cannot declare `main' to be inline");
+       error ("cannot declare `::main' to be inline");
       else if (! publicp)
-       error ("cannot declare `main' to be static");
+       error ("cannot declare `::main' to be static");
       inlinep = 0;
       publicp = 1;
     }
@@ -8437,7 +8557,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   /* Members of anonymous types and local classes have no linkage; make
      them internal.  */
   if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype))
-               || hack_decl_function_context (TYPE_MAIN_DECL (ctype))))
+               || decl_function_context (TYPE_MAIN_DECL (ctype))))
     publicp = 0;
 
   if (publicp)
@@ -8485,7 +8605,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
     grok_op_properties (decl, virtualp, check < 0);
 
-  if (ctype && hack_decl_function_context (decl))
+  if (ctype && decl_function_context (decl))
     DECL_NO_STATIC_CHAIN (decl) = 1;
 
   for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
@@ -8508,7 +8628,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
          if (PROCESSING_REAL_TEMPLATE_DECL_P ())
            {
              /* Something like `template <class T> friend void f<T>()'.  */
-             cp_error ("template-id `%D' in declaration of primary template", 
+             cp_error ("invalid use of template-id `%D' in declaration of primary template",
                        orig_declarator);
              return NULL_TREE;
            }
@@ -8531,7 +8651,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
          if (inlinep)
            {
-             cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'", 
+             cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'",
                        decl);
              return NULL_TREE;
            }
@@ -8552,6 +8672,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        tentative.  error_mark_node is replaced later with the BLOCK.  */
     DECL_INITIAL (decl) = error_mark_node;
 
+  if (nothrow_libfn_p (decl))
+    TREE_NOTHROW (decl) = 1;
+
   /* Caller will do the rest of this.  */
   if (check < 0)
     return decl;
@@ -8569,8 +8692,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
       grokclassfn (ctype, decl, flags, quals);
 
       decl = check_explicit_specialization (orig_declarator, decl,
-                                           template_count, 
-                                           2 * (funcdef_flag != 0) + 
+                                           template_count,
+                                           2 * (funcdef_flag != 0) +
                                            4 * (friendp != 0));
       if (decl == error_mark_node)
        return NULL_TREE;
@@ -8602,8 +8725,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        grokclassfn (ctype, decl, flags, quals);
 
       decl = check_explicit_specialization (orig_declarator, decl,
-                                           template_count, 
-                                           2 * (funcdef_flag != 0) + 
+                                           template_count,
+                                           2 * (funcdef_flag != 0) +
                                            4 * (friendp != 0));
       if (decl == error_mark_node)
        return NULL_TREE;
@@ -8616,7 +8739,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
          if (tmp && TREE_CODE (tmp) == TEMPLATE_DECL)
            tmp = DECL_TEMPLATE_RESULT (tmp);
-             
+
          if (tmp && DECL_STATIC_FUNCTION_P (tmp)
              && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
            {
@@ -8674,7 +8797,6 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
       type = TREE_TYPE (type);
       decl = build_lang_decl (VAR_DECL, declarator, type);
       DECL_CONTEXT (decl) = basetype;
-      DECL_CLASS_CONTEXT (decl) = basetype;
       DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
     }
   else
@@ -8688,7 +8810,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
       else
        context = NULL_TREE;
 
-      if (processing_template_decl) 
+      if (processing_template_decl)
        /* If we're in a template, we need DECL_LANG_SPECIFIC so that
           we can call push_template_decl.  */
        decl = build_lang_decl (VAR_DECL, declarator, type);
@@ -8778,30 +8900,39 @@ build_ptrmemfunc_type (type)
   /* Make sure that we always have the unqualified pointer-to-member
      type first.  */
   if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)
-    unqualified_variant 
+    unqualified_variant
       = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
 
-  u = make_aggr_type (UNION_TYPE);
-  SET_IS_AGGR_TYPE (u, 0);
-  fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
-  fields[1] = build_lang_decl (FIELD_DECL, delta2_identifier,
-                              delta_type_node);
-  finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
-  TYPE_NAME (u) = NULL_TREE;
-
   t = make_aggr_type (RECORD_TYPE);
-
   /* Let the front-end know this is a pointer to member function...  */
   TYPE_PTRMEMFUNC_FLAG (t) = 1;
   /* ... and not really an aggregate.  */
   SET_IS_AGGR_TYPE (t, 0);
 
-  fields[0] = build_lang_decl (FIELD_DECL, delta_identifier,
-                              delta_type_node);
-  fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
-                              delta_type_node);
-  fields[2] = build_lang_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
-  finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
+  if (!flag_new_abi)
+    {
+      u = make_aggr_type (UNION_TYPE);
+      SET_IS_AGGR_TYPE (u, 0);
+      fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
+      fields[1] = build_lang_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_lang_decl (FIELD_DECL, delta_identifier,
+                                  delta_type_node);
+      fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
+                                  delta_type_node);
+      fields[2] = build_lang_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
+      finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
+    }
+  else
+    {
+      fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
+      fields[1] = build_lang_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.  */
@@ -8847,7 +8978,7 @@ check_static_variable_definition (decl, type)
      required.  */
   if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
     {
-      cp_error ("in-class initialization of static data member of non-integral type `%T'", 
+      cp_error ("invalid in-class initialization of static data member of non-integral type `%T'",
                type);
       /* If we just return the declaration, crashes will sometimes
         occur.  We therefore return void_type_node, as if this was a
@@ -8856,10 +8987,10 @@ check_static_variable_definition (decl, type)
       return 1;
     }
   else if (!CP_TYPE_CONST_P (type))
-    cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
+    cp_error ("ISO C++ forbids in-class initialization of non-const static member `%D'",
              decl);
   else if (pedantic && !INTEGRAL_TYPE_P (type))
-    cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
+    cp_pedwarn ("ISO C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
 
   return 0;
 }
@@ -8938,14 +9069,14 @@ compute_array_index_type (name, size)
          size = integer_one_node;
        }
       /* Except that an extension we allow zero-sized arrays.  We
-        always allow them in system headers because glibc uses 
+        always allow them in system headers because glibc uses
         them.  */
       else if (integer_zerop (size) && pedantic && !in_system_header)
        {
          if (name)
-           cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", name);
+           cp_pedwarn ("ISO C++ forbids zero-size array `%D'", name);
          else
-           cp_pedwarn ("ANSI C++ forbids zero-size array");
+           cp_pedwarn ("ISO C++ forbids zero-size array");
        }
     }
 
@@ -8956,7 +9087,7 @@ compute_array_index_type (name, size)
                             cp_convert (ssizetype, size),
                             cp_convert (ssizetype,
                                         integer_one_node)));
-  
+
   /* Check for variable-sized arrays.  We allow such things as an
      extension, even though they are not allowed in ANSI/ISO C++.  */
   if (!TREE_CONSTANT (itype))
@@ -8964,10 +9095,10 @@ compute_array_index_type (name, size)
       if (pedantic)
        {
          if (name)
-           cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
+           cp_pedwarn ("ISO C++ forbids variable-size array `%D'",
                        name);
          else
-           cp_pedwarn ("ANSI C++ forbids variable-size array");
+           cp_pedwarn ("ISO C++ forbids variable-size array");
        }
 
       /* Create a variable-sized array index type.  */
@@ -8981,7 +9112,7 @@ compute_array_index_type (name, size)
       error ("overflow in array dimension");
       TREE_OVERFLOW (itype) = 0;
     }
-  
+
   /* Create and return the appropriate index type.  */
   return build_index_type (itype);
 }
@@ -9045,14 +9176,13 @@ create_array_type_for_decl (name, type, size)
     }
 
   /* [dcl.array]
-     
+
      The constant expressions that specify the bounds of the arrays
      can be omitted only for the first member of the sequence.  */
   if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
     {
-      cp_error ("declaration of `%D' as multidimensional array",
+      cp_error ("declaration of `%D' as multidimensional array must have bounds for all dimensions except the first",
                name);
-      cp_error ("must have bounds for all dimensions except the first");
 
       return error_mark_node;
     }
@@ -9094,7 +9224,7 @@ create_array_type_for_decl (name, type, size)
    ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and
    normal attributes in TREE_PURPOSE, or NULL_TREE.
 
-   In the TYPENAME case, DECLARATOR is really an absolute declarator.
+   In the TYPENAME case, DECLARATOR is really an abstract declarator.
    It may also be so in the PARM case, for a prototype where the
    argument type is specified but not the name.
 
@@ -9284,6 +9414,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
                decl = start_decl (declarator, declspecs, 1,
                                   attributes, prefix_attributes);
+               decl_type_access_control (decl);
                if (decl)
                  {
                    /* Look for __unused__ attribute */
@@ -9317,7 +9448,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              }
            ctype = NULL_TREE;
            break;
-           
+
          case TEMPLATE_ID_EXPR:
              {
                tree fns = TREE_OPERAND (decl, 0);
@@ -9510,7 +9641,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
-  
+
   /* Look through the decl specs and record which ones appear.
      Some typespecs are defined as built-in typenames.
      Others, the ones that are modifiers of other types,
@@ -9581,7 +9712,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))
                    {
                      if (pedantic && ! in_system_header && warn_long_long)
-                       pedwarn ("ANSI C++ does not support `long long'");
+                       pedwarn ("ISO C++ does not support `long long'");
                      if (longlong)
                        error ("`long long long' is too long for GCC");
                      else
@@ -9671,10 +9802,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          if (in_system_header || flag_ms_extensions)
            /* Allow it, sigh.  */;
          else if (pedantic || ! is_main)
-           cp_pedwarn ("ANSI C++ forbids declaration of `%s' with no type",
+           cp_pedwarn ("ISO C++ forbids declaration of `%s' with no type",
                        name);
          else if (warn_return_type)
-           cp_warning ("ANSI C++ forbids declaration of `%s' with no type",
+           cp_warning ("ISO C++ forbids declaration of `%s' with no type",
                        name);
 
          type = integer_type_node;
@@ -9713,7 +9844,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
       RIDBIT_RESET (RID_LONG, specbits);
-      type = build_qualified_type (long_double_type_node, 
+      type = build_qualified_type (long_double_type_node,
                                   CP_TYPE_QUALS (type));
     }
 
@@ -9782,7 +9913,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
         It is implementation-defined whether a plain (neither
         explicitly signed or unsigned) char, short, int, or long
         bit-field is signed or unsigned.
-            
+
         Naturally, we extend this to long long as well.  Note that
         this does not include wchar_t.  */
       || (bitfield && !flag_signed_bitfields
@@ -9790,7 +9921,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          /* A typedef for plain `int' without `signed' can be
             controlled just like plain `int', but a typedef for
             `signed int' cannot be so controlled.  */
-         && !(typedef_decl 
+         && !(typedef_decl
               && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
          && (TREE_CODE (type) == INTEGER_TYPE
              || TREE_CODE (type) == CHAR_TYPE)
@@ -9844,7 +9975,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        type = build_complex_type (type);
     }
 
-  if (return_type == return_conversion 
+  if (return_type == return_conversion
       && (RIDBIT_SETP (RID_CONST, specbits)
          || RIDBIT_SETP (RID_VOLATILE, specbits)
          || RIDBIT_SETP (RID_RESTRICT, specbits)))
@@ -9856,9 +9987,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
      Likewise for VOLATILEP.  */
 
   constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type);
-  restrictp = 
+  restrictp =
     !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type);
-  volatilep = 
+  volatilep =
     !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
                | (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -9943,7 +10074,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
              if (declarator)
                {
-                 /* Avoid trying to get an operand off an identifier node.  */ 
+                 /* Avoid trying to get an operand off an identifier node.  */
                  if (TREE_CODE (declarator) == IDENTIFIER_NODE)
                    tmp = declarator;
                  else
@@ -9995,7 +10126,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
      the declared identifier (or NULL_TREE, in an absolute declarator).  */
 
   inner_attrs = NULL_TREE;
-  ignore_attrs = 0;  
+  ignore_attrs = 0;
 
   while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
         && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
@@ -10118,7 +10249,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF)
              inner_decl = TREE_OPERAND (inner_decl, 1);
 
-           if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR) 
+           if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR)
              inner_decl = dname;
 
            /* Pick up type qualifiers which should be applied to `this'.  */
@@ -10130,11 +10261,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            /* Say it's a definition only for the CALL_EXPR
               closest to the identifier.  */
            funcdecl_p
-             = inner_decl 
+             = inner_decl
              && (TREE_CODE (inner_decl) == IDENTIFIER_NODE
-                 || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR 
+                 || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR
                  || TREE_CODE (inner_decl) == BIT_NOT_EXPR);
-           
+
            if (ctype == NULL_TREE
                && decl_context == FIELD
                && funcdecl_p
@@ -10152,9 +10283,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
                if (flags == DTOR_FLAG)
                  {
-                   /* ANSI C++ June 5 1992 WP 12.4.1.  A destructor may
-                      not be declared const or volatile.  A destructor
-                      may not be static.  */
+                   /* ISO C++ 12.4/2.  A destructor may not be
+                      declared const or volatile.  A destructor may
+                      not be static.  */
                    if (staticp == 2)
                      error ("destructor cannot be static member function");
                    if (quals)
@@ -10165,8 +10296,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                      }
                    if (decl_context == FIELD)
                      {
-                       if (! member_function_or_else (ctype, current_class_type,
-                                                      "destructor for alien class `%s' cannot be a member"))
+                       if (! member_function_or_else (ctype,
+                                                      current_class_type,
+                                                      flags))
                          return void_type_node;
                      }
                  }
@@ -10174,9 +10306,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  {
                    if (explicitp == 1)
                      explicitp = 2;
-                   /* ANSI C++ June 5 1992 WP 12.1.2.  A constructor may
-                      not be declared const or volatile.  A constructor may
-                      not be virtual.  A constructor may not be static.  */
+                   /* ISO C++ 12.1.  A constructor may not be
+                      declared const or volatile.  A constructor may
+                      not be virtual.  A constructor may not be
+                      static.  */
                    if (staticp == 2)
                      error ("constructor cannot be static member function");
                    if (virtualp)
@@ -10201,8 +10334,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                    type = build_pointer_type (ctype);
                    if (decl_context == FIELD)
                      {
-                       if (! member_function_or_else (ctype, current_class_type,
-                                                      "constructor for alien class `%s' cannot be member"))
+                       if (! member_function_or_else (ctype,
+                                                      current_class_type,
+                                                      flags))
                          return void_type_node;
                        TYPE_HAS_CONSTRUCTOR (ctype) = 1;
                        if (return_type != return_ctor)
@@ -10247,7 +10381,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                   want the underlying IDENTIFIER.  */
                if (TREE_CODE (declarator) == BIT_NOT_EXPR)
                  declarator = TREE_OPERAND (declarator, 0);
-               
+
                if (strict_prototype == 0 && arg_types == NULL_TREE)
                  arg_types = void_list_node;
                else if (arg_types == NULL_TREE
@@ -10434,14 +10568,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            ctype = TREE_OPERAND (declarator, 0);
 
            t = ctype;
-           while (t != NULL_TREE && CLASS_TYPE_P (t)) 
+           while (t != NULL_TREE && CLASS_TYPE_P (t))
              {
                if (CLASSTYPE_TEMPLATE_INFO (t) &&
                    !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
                  template_count += 1;
                t = TYPE_MAIN_DECL (t);
                if (DECL_LANG_SPECIFIC (t))
-                 t = DECL_CLASS_CONTEXT (t);
+                 t = DECL_CONTEXT (t);
                else
                  t = NULL_TREE;
              }
@@ -10630,7 +10764,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       if (decl_context == FIELD)
        {
          if (declarator == constructor_name (current_class_type))
-           cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",
+           cp_pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
                        declarator);
          decl = build_lang_decl (TYPE_DECL, declarator, type);
        }
@@ -10670,10 +10804,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
             type is a (non-primary) template.  The name for the
             template needs updating as well.  */
          if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
-           DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) 
+           DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
              = TYPE_IDENTIFIER (type);
 
-         /* XXX Temporarily set the scope. 
+         /* 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);
@@ -10701,7 +10835,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          if (ctype == NULL_TREE)
            {
              if (TREE_CODE (type) != METHOD_TYPE)
-               cp_error_at ("invalid type qualifier for non-method type", decl);
+               cp_error_at ("invalid type qualifier for non-member function type", decl);
              else
                ctype = TYPE_METHOD_BASETYPE (type);
            }
@@ -10772,14 +10906,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        }
       else if (quals)
        {
-         tree dummy = build_decl (TYPE_DECL, declarator, type);
          if (ctype == NULL_TREE)
            {
-             my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159);
-             ctype = TYPE_METHOD_BASETYPE (type);
+             if (TREE_CODE (type) != METHOD_TYPE)
+               cp_error ("invalid qualifiers on non-member function type");
+             else
+               ctype = TYPE_METHOD_BASETYPE (type);
+           }
+         if (ctype)
+           {
+             tree dummy = build_decl (TYPE_DECL, declarator, type);
+             grok_method_quals (ctype, dummy, quals);
+             type = TREE_TYPE (dummy);
            }
-         grok_method_quals (ctype, dummy, quals);
-         type = TREE_TYPE (dummy);
        }
 
       return type;
@@ -10842,7 +10981,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          return NULL_TREE;
        }
     }
-  
+
   {
     register tree decl;
 
@@ -10927,11 +11066,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              }
 
            /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
-           function_context = (ctype != NULL_TREE) ? 
-             hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
+           function_context = (ctype != NULL_TREE) ?
+             decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
            publicp = (! friendp || ! staticp)
              && function_context == NULL_TREE;
-           decl = grokfndecl (ctype, type, 
+           decl = grokfndecl (ctype, type,
                               TREE_CODE (declarator) != TEMPLATE_ID_EXPR
                               ? declarator : dname,
                               declarator,
@@ -10963,7 +11102,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                   We don't look at the first parameter, which is
                   really just the `this' parameter for the new
                   object.  */
-               tree arg_types = 
+               tree arg_types =
                  TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
 
                /* Skip the `in_chrg' argument too, if present.  */
@@ -10971,8 +11110,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  arg_types = TREE_CHAIN (arg_types);
 
                if (arg_types == void_list_node
-                   || (arg_types 
-                       && TREE_CHAIN (arg_types) 
+                   || (arg_types
+                       && TREE_CHAIN (arg_types)
                        && TREE_CHAIN (arg_types) != void_list_node
                        && !TREE_PURPOSE (TREE_CHAIN (arg_types))))
                  DECL_NONCONVERTING_P (decl) = 1;
@@ -11017,7 +11156,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          {
            if (friendp)
              {
-               error ("`%s' is neither function nor method; cannot be declared friend",
+               error ("`%s' is neither function nor member function; cannot be declared friend",
                       IDENTIFIER_POINTER (declarator));
                friendp = 0;
              }
@@ -11036,8 +11175,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  {
                    if (template_class_depth (current_class_type) == 0)
                      {
-                       decl 
-                         = check_explicit_specialization 
+                       decl
+                         = check_explicit_specialization
                          (declarator, decl,
                           template_count, 2 * (funcdef_flag != 0) + 4);
                        if (decl == error_mark_node)
@@ -11050,7 +11189,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  }
                if (t && funcdef_flag)
                  return t;
-               
+
                return void_type_node;
              }
          }
@@ -11065,17 +11204,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  {
                    /* An attempt is being made to initialize a non-static
                       member.  But, from [class.mem]:
-                      
+
                       4 A member-declarator can contain a
                       constant-initializer only if it declares a static
                       member (_class.static_) of integral or enumeration
-                      type, see _class.static.data_.  
+                      type, see _class.static.data_.
 
                       This used to be relatively common practice, but
                       the rest of the compiler does not correctly
                       handle the initialization unless the member is
                       static so we make it static below.  */
-                   cp_pedwarn ("ANSI C++ forbids initialization of member `%D'",
+                   cp_pedwarn ("ISO C++ forbids initialization of member `%D'",
                                declarator);
                    cp_pedwarn ("making `%D' static", declarator);
                    staticp = 1;
@@ -11100,7 +11239,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                   allow non-static data members here, because C does
                   and /usr/include/netinet/in.h uses that.  */
                && (staticp || ! in_system_header))
-             cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class",
+             cp_pedwarn ("ISO C++ forbids data member `%D' with same name as enclosing class",
                          declarator);
 
            if (staticp)
@@ -11157,7 +11296,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            else
              pedwarn ("storage class `inline' invalid for function `%s' declared out of global scope", name);
          }
-       
+
        if (ctype == NULL_TREE)
          {
            if (virtualp)
@@ -11178,7 +11317,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        decl = grokfndecl (ctype, type, original_name, declarator,
                           virtualp, flags, quals, raises,
                           1, friendp,
-                          publicp, inlinep, funcdef_flag, 
+                          publicp, inlinep, funcdef_flag,
                           template_count, in_namespace);
        if (decl == NULL_TREE)
          return NULL_TREE;
@@ -11213,9 +11352,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        /* It's a variable.  */
 
        /* An uninitialized decl with `extern' is a reference.  */
-       decl = grokvardecl (type, declarator, &specbits, 
-                           initialized, 
-                           (type_quals & TYPE_QUAL_CONST) != 0, 
+       decl = grokvardecl (type, declarator, &specbits,
+                           initialized,
+                           (type_quals & TYPE_QUAL_CONST) != 0,
                            in_namespace);
        bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
                        inlinep, friendp, raises != NULL_TREE);
@@ -11302,10 +11441,17 @@ static void
 require_complete_types_for_parms (parms)
      tree parms;
 {
-  while (parms)
+  for (; parms; parms = TREE_CHAIN (parms))
     {
       tree type = TREE_TYPE (parms);
-      if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
+
+      /* Try to complete the TYPE.  */
+      type = complete_type (type);
+
+      if (type == error_mark_node)
+       continue;
+
+      if (TYPE_SIZE (type) == NULL_TREE)
        {
          if (DECL_NAME (parms))
            error ("parameter `%s' has incomplete type",
@@ -11316,8 +11462,6 @@ require_complete_types_for_parms (parms)
        }
       else
        layout_decl (parms, 0);
-
-      parms = TREE_CHAIN (parms);
     }
 }
 
@@ -11327,7 +11471,7 @@ int
 local_variable_p (t)
      tree t;
 {
-  if ((TREE_CODE (t) == VAR_DECL 
+  if ((TREE_CODE (t) == VAR_DECL
        /* A VAR_DECL with a context that is a _TYPE is a static data
          member.  */
        && !TYPE_P (CP_DECL_CONTEXT (t))
@@ -11361,7 +11505,7 @@ local_variable_p_walkfn (tp, walk_subtrees, data)
      int *walk_subtrees ATTRIBUTE_UNUSED;
      void *data ATTRIBUTE_UNUSED;
 {
-  return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp)) 
+  return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
          ? *tp : NULL_TREE);
 }
 
@@ -11399,7 +11543,7 @@ check_default_argument (decl, arg)
   else
     decl_type = TREE_TYPE (decl);
 
-  if (arg == error_mark_node 
+  if (arg == error_mark_node
       || decl == error_mark_node
       || TREE_TYPE (arg) == error_mark_node
       || decl_type == error_mark_node)
@@ -11408,14 +11552,14 @@ check_default_argument (decl, arg)
     return error_mark_node;
 
   /* [dcl.fct.default]
-     
+
      A default argument expression is implicitly converted to the
      parameter type.  */
   if (!TREE_TYPE (arg)
       || !can_convert_arg (decl_type, TREE_TYPE (arg), arg))
     {
       if (decl)
-       cp_error ("default argument for `%#D' has type `%T'", 
+       cp_error ("default argument for `%#D' has type `%T'",
                  decl, TREE_TYPE (arg));
       else
        cp_error ("default argument for parameter of type `%T' has type `%T'",
@@ -11427,7 +11571,7 @@ check_default_argument (decl, arg)
   /* [dcl.fct.default]
 
      Local variables shall not be used in default argument
-     expressions. 
+     expressions.
 
      The keyword `this' shall not be used in a default argument of a
      member function.  */
@@ -11518,7 +11662,7 @@ grokparms (first_parm, funcdef_flag)
 
              chain = TREE_CHAIN (parm);
              /* @@ weak defense against parse errors.  */
-             if (TREE_CODE (decl) != VOID_TYPE 
+             if (TREE_CODE (decl) != VOID_TYPE
                  && TREE_CODE (decl) != TREE_LIST)
                {
                  /* Give various messages as the need arises.  */
@@ -11666,17 +11810,26 @@ replace_defarg (arg, init)
   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
+   operator.  */
+
 int
 copy_args_p (d)
      tree d;
 {
-  tree t = FUNCTION_ARG_CHAIN (d);
+  tree t;
+
+  if (!DECL_FUNCTION_MEMBER_P (d))
+    return 0;
+
+  t = FUNCTION_ARG_CHAIN (d);
   if (DECL_CONSTRUCTOR_P (d)
       && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d)))
     t = TREE_CHAIN (t);
   if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
       && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
-         == DECL_CLASS_CONTEXT (d))
+         == DECL_CONTEXT (d))
       && (TREE_CHAIN (t) == NULL_TREE
          || TREE_CHAIN (t) == void_list_node
          || TREE_PURPOSE (TREE_CHAIN (t))))
@@ -11735,7 +11888,7 @@ grok_ctor_properties (ctype, decl)
      A declaration of a constructor for a class X is ill-formed if its
      first parameter is of type (optionally cv-qualified) X and either
      there are no other parameters or else all other parameters have
-     default arguments.  
+     default arguments.
 
      We *don't* complain about member template instantiations that
      have this form, though; they can occur as we try to decide what
@@ -11824,11 +11977,11 @@ grok_op_properties (decl, virtualp, friendp)
               || name == ansi_opname[(int) MEMBER_REF])
        TYPE_OVERLOADS_ARROW (current_class_type) = 1;
       else if (name == ansi_opname[(int) NEW_EXPR])
-       TYPE_GETS_NEW (current_class_type) |= 1;
+       TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
       else if (name == ansi_opname[(int) DELETE_EXPR])
        TYPE_GETS_DELETE (current_class_type) |= 1;
       else if (name == ansi_opname[(int) VEC_NEW_EXPR])
-       TYPE_GETS_NEW (current_class_type) |= 2;
+       TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
       else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
        TYPE_GETS_DELETE (current_class_type) |= 2;
     }
@@ -11840,7 +11993,7 @@ grok_op_properties (decl, virtualp, friendp)
         doesn't look at the class declaration to find out if it's static.  */
       if (methodp)
        revert_static_member_fn (&decl, NULL, NULL);
-     
+
       /* Take care of function decl if we had syntax errors.  */
       if (argtypes == NULL_TREE)
        TREE_TYPE (decl)
@@ -11855,21 +12008,14 @@ grok_op_properties (decl, virtualp, friendp)
     {
       if (methodp)
        revert_static_member_fn (&decl, NULL, NULL);
-     
+
       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));
-
-         if (! friendp && name == ansi_opname[(int) VEC_DELETE_EXPR]
-             && (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
-                 != void_list_node))
-           TYPE_VEC_DELETE_TAKES_SIZE (current_class_type) = 1;
-       }
+       TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
     }
   else
     {
@@ -11912,23 +12058,24 @@ grok_op_properties (decl, virtualp, friendp)
              ;
            }
        }
-      
+
       if (name == ansi_opname[(int) CALL_EXPR])
        return;                 /* No restrictions on args. */
 
       if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
        {
          tree t = TREE_TYPE (name);
-         if (TREE_CODE (t) == VOID_TYPE)
-           pedwarn ("void is not a valid type conversion operator");
-         else if (! friendp)
+         if (! friendp)
            {
              int ref = (TREE_CODE (t) == REFERENCE_TYPE);
              const char *what = 0;
+             
              if (ref)
                t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
-             if (t == current_class_type)
+             if (TREE_CODE (t) == VOID_TYPE)
+               what = "void";
+             else if (t == current_class_type)
                what = "the same type";
              /* Don't force t to be complete here.  */
              else if (IS_AGGR_TYPE (t)
@@ -11965,8 +12112,8 @@ grok_op_properties (decl, virtualp, friendp)
       else if (name == ansi_opname[(int) COND_EXPR])
        {
          /* 13.4.0.3 */
-         cp_error ("ANSI C++ prohibits overloading operator ?:");
-       }         
+         cp_error ("ISO C++ prohibits overloading operator ?:");
+       }
       else if (ambi_op_p (name))
        {
          if (list_length (argtypes) == 2)
@@ -12187,11 +12334,11 @@ xref_tag (code_type_node, name, globalize)
        }
       else
        ref = lookup_tag (code, name, b, 0);
-         
+
       if (! ref)
        {
          /* Try finding it as a type declaration.  If that wins,
-            use it.  */ 
+            use it.  */
          ref = lookup_name (name, 1);
 
          if (ref != NULL_TREE
@@ -12209,9 +12356,9 @@ xref_tag (code_type_node, name, globalize)
            ref = NULL_TREE;
        }
 
-      if (ref && current_class_type 
-         && template_class_depth (current_class_type) 
-         && PROCESSING_REAL_TEMPLATE_DECL_P ()) 
+      if (ref && current_class_type
+         && template_class_depth (current_class_type)
+         && PROCESSING_REAL_TEMPLATE_DECL_P ())
        {
          /* Since GLOBALIZE is non-zero, we are not looking at a
             definition of this tag.  Since, in addition, we are currently
@@ -12299,14 +12446,6 @@ xref_tag (code_type_node, name, globalize)
     }
   else
     {
-      /* If it no longer looks like a nested type, make sure it's
-        in global scope.  
-         If it is not an IDENTIFIER, this is not a declaration */
-      if (b->namespace_p && !class_binding_level
-         && TREE_CODE (name) == IDENTIFIER_NODE
-         && IDENTIFIER_NAMESPACE_VALUE (name) == NULL_TREE)
-       SET_IDENTIFIER_NAMESPACE_VALUE (name, TYPE_NAME (ref));
-
       if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
        redeclare_class_template (ref, current_template_parms);
     }
@@ -12441,7 +12580,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
            }
 
          if (TYPE_FOR_JAVA (basetype)
-             && (current_lang_stack 
+             && (current_lang_stack
                  == &VARRAY_TREE (current_lang_base, 0)))
            TYPE_FOR_JAVA (ref) = 1;
 
@@ -12452,14 +12591,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
             derived classes.  (Each BINFO record describing an
             individual inheritance contains flags which say what
             the `accessibility' of that particular inheritance is.)  */
-  
-         base_binfo 
-           = make_binfo (integer_zero_node, basetype,
+
+         base_binfo
+           = make_binfo (size_zero_node, basetype,
                          CLASS_TYPE_P (basetype)
                          ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
                          CLASS_TYPE_P (basetype)
                          ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE);
+
          TREE_VEC_ELT (binfos, i) = base_binfo;
          TREE_VIA_PUBLIC (base_binfo) = via_public;
          TREE_VIA_PROTECTED (base_binfo) = via_protected;
@@ -12477,13 +12616,26 @@ xref_basetypes (code_type_node, name, ref, binfo)
          if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype))
            {
              TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1;
-             TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
+             /* Converting to a virtual base class requires looking
+                up the offset of the virtual base.  */
+             TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
            }
 
          if (CLASS_TYPE_P (basetype))
            {
-             TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
+             TYPE_HAS_NEW_OPERATOR (ref) 
+               |= TYPE_HAS_NEW_OPERATOR (basetype);
+             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.  */
+             TYPE_USES_MULTIPLE_INHERITANCE (ref)
+               |= TYPE_USES_MULTIPLE_INHERITANCE (basetype);
+             /* Likewise, if converting to a base of the base may require
+                code, then we may need to generate code to convert to a
+                base as well.  */
+             TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)
+               |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);
            }
 
          i += 1;
@@ -12495,19 +12647,13 @@ xref_basetypes (code_type_node, name, ref, binfo)
     BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE;
 
   if (i > 1)
-    TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
-  else if (i == 1)
     {
-      tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
-      
-      if (CLASS_TYPE_P (basetype))
-       TYPE_USES_MULTIPLE_INHERITANCE (ref)
-         = TYPE_USES_MULTIPLE_INHERITANCE (basetype);
+      TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
+      /* If there is more than one non-empty they cannot be at the same
+        address.  */
+      TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
     }
 
-  if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
-    TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
-
   /* Unmark all the types.  */
   while (--i >= 0)
     CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
@@ -12515,9 +12661,9 @@ xref_basetypes (code_type_node, name, ref, binfo)
 
   /* Now that we know all the base-classes, set up the list of virtual
      bases.  */
-  CLASSTYPE_VBASECLASSES (ref) = get_vbase_types (ref);
+  get_vbase_types (ref);
 }
-  
+
 \f
 /* Begin compiling the definition of an enumeration type.
    NAME is its name (or null if anonymous).
@@ -12607,7 +12753,7 @@ finish_enum (enumtype)
                 reason to do that when processing_template_decl.
                 And, if the expression is something like a
                 TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will
-                wreak havoc on the intended type of the expression.  
+                wreak havoc on the intended type of the expression.
 
                 Of course, there's also no point in trying to compute
                 minimum or maximum values if we're in a template.  */
@@ -12621,7 +12767,7 @@ finish_enum (enumtype)
                minnode = value;
            }
 
-         if (processing_template_decl) 
+         if (processing_template_decl)
            /* If this is just a template, leave the CONST_DECL
               alone.  That way tsubst_copy will find CONST_DECLs for
               CONST_DECLs, and not INTEGER_CSTs.  */
@@ -12663,7 +12809,7 @@ finish_enum (enumtype)
 
       if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
        /* Use the width of the narrowest normal C type which is wide
-          enough.  */ 
+          enough.  */
        TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size
                                                    (precision, 1));
       else
@@ -12671,7 +12817,7 @@ finish_enum (enumtype)
 
       TYPE_SIZE (enumtype) = 0;
       layout_type (enumtype);
-    
+
       /* Fix up all variant types of this enum type.  */
       for (tem = TYPE_MAIN_VARIANT (enumtype); tem;
           tem = TYPE_NEXT_VARIANT (tem))
@@ -12743,11 +12889,10 @@ build_enumerator (name, value, enumtype)
              /* The next value is the previous value ... */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
              /* ... plus one.  */
-             value = build_binary_op_nodefault (PLUS_EXPR,
-                                                prev_value,
-                                                integer_one_node,
-                                                PLUS_EXPR);
-             
+             value = build_binary_op (PLUS_EXPR,
+                                      prev_value,
+                                      integer_one_node);
+
              if (tree_int_cst_lt (value, prev_value))
                cp_error ("overflow in enumeration values at `%D'", name);
            }
@@ -12854,7 +12999,7 @@ check_function_type (decl)
        TREE_TYPE (decl)
          = build_function_type (void_type_node,
                                 TYPE_ARG_TYPES (TREE_TYPE (decl)));
-      TREE_TYPE (decl) 
+      TREE_TYPE (decl)
        = build_exception_variant (fntype,
                                   TYPE_RAISES_EXCEPTIONS (fntype));
     }
@@ -12872,8 +13017,8 @@ check_function_type (decl)
    process and that DECLSPECS should be ignored), SF_INCLASS_INLINE
    indicating that the function is an inline defined in-class, and
    SF_EXPAND indicating that we should generate RTL for this
-   function.  
-   
+   function.
+
    This function creates a binding context for the function body
    as well as setting up the FUNCTION_DECL in current_function_decl.
 
@@ -12919,12 +13064,11 @@ start_function (declspecs, declarator, attrs, flags)
       if (TREE_CODE (fntype) == METHOD_TYPE)
        ctype = TYPE_METHOD_BASETYPE (fntype);
 
-      /* ANSI C++ June 5 1992 WP 11.4.5.  A friend function defined in a
-        class is in the (lexical) scope of the class in which it is
-        defined.  */
+      /* ISO C++ 11.4/5.  A friend function defined in a class is in
+        the (lexical) scope of the class in which it is defined.  */
       if (!ctype && DECL_FRIEND_P (decl1))
        {
-         ctype = DECL_CLASS_CONTEXT (decl1);
+         ctype = DECL_FRIEND_CONTEXT (decl1);
 
          /* CTYPE could be null here if we're dealing with a template;
             for example, `inline friend float foo()' inside a template
@@ -12951,7 +13095,7 @@ start_function (declspecs, declarator, attrs, flags)
       if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
        {
          cp_error ("semicolon missing after declaration of `%#T'", restype);
-         shadow_tag (build_expr_list (NULL_TREE, restype));
+         shadow_tag (build_tree_list (NULL_TREE, restype));
          CLASSTYPE_GOT_SEMICOLON (restype) = 1;
          if (TREE_CODE (fntype) == FUNCTION_TYPE)
            fntype = build_function_type (integer_type_node,
@@ -12976,7 +13120,7 @@ start_function (declspecs, declarator, attrs, flags)
            }
        }
     }
-  
+
   /* Sometimes we don't notice that a function is a static member, and
      build a METHOD_TYPE for it.  Fix that up now.  */
   if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
@@ -13023,7 +13167,7 @@ start_function (declspecs, declarator, attrs, flags)
 #ifdef SET_DEFAULT_DECL_ATTRIBUTES
   SET_DEFAULT_DECL_ATTRIBUTES (decl1, attrs);
 #endif
-  
+
   /* This function exists in static storage.
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
@@ -13057,8 +13201,8 @@ start_function (declspecs, declarator, attrs, flags)
        {
          DECL_RESULT (decl1)
            = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));
-         c_apply_type_quals_to_decl (CP_TYPE_QUALS (restype), 
-                                     DECL_RESULT (decl1)); 
+         c_apply_type_quals_to_decl (CP_TYPE_QUALS (restype),
+                                     DECL_RESULT (decl1));
        }
     }
   else
@@ -13095,7 +13239,7 @@ start_function (declspecs, declarator, attrs, flags)
   if (!processing_template_decl && !(flags & SF_PRE_PARSED))
     {
       /* A specialization is not used to guide overload resolution.  */
-      if ((flag_guiding_decls 
+      if ((flag_guiding_decls
           || !DECL_TEMPLATE_SPECIALIZATION (decl1))
          && ! DECL_FUNCTION_MEMBER_P (decl1))
        decl1 = pushdecl (decl1);
@@ -13144,13 +13288,13 @@ start_function (declspecs, declarator, attrs, flags)
         never get us to that point.  Here we keep the consistency
         between `current_class_type' and `current_class_ptr'.  */
       tree t = DECL_ARGUMENTS (decl1);
-             
-      my_friendly_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL, 
+
+      my_friendly_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL,
                          162);
       my_friendly_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE,
                          19990811);
-         
-      cp_function_chain->x_current_class_ref 
+
+      cp_function_chain->x_current_class_ref
        = build_indirect_ref (t, NULL_PTR);
       cp_function_chain->x_current_class_ptr = t;
 
@@ -13168,12 +13312,12 @@ start_function (declspecs, declarator, attrs, flags)
 
   if (DECL_INTERFACE_KNOWN (decl1))
     {
-      tree ctx = hack_decl_function_context (decl1);
+      tree ctx = decl_function_context (decl1);
 
       if (DECL_NOT_REALLY_EXTERN (decl1))
        DECL_EXTERNAL (decl1) = 0;
 
-      if (ctx != NULL_TREE && DECL_THIS_INLINE (ctx) 
+      if (ctx != NULL_TREE && DECL_THIS_INLINE (ctx)
          && TREE_PUBLIC (ctx))
        /* This is a function in a local class in an extern inline
           function.  */
@@ -13225,7 +13369,7 @@ start_function (declspecs, declarator, attrs, flags)
       if ((DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1))
          && ! DECL_INTERFACE_KNOWN (decl1)
          /* Don't try to defer nested functions for now.  */
-         && ! hack_decl_function_context (decl1))
+         && ! decl_function_context (decl1))
        DECL_DEFER_OUTPUT (decl1) = 1;
       else
        DECL_INTERFACE_KNOWN (decl1) = 1;
@@ -13239,7 +13383,7 @@ start_function (declspecs, declarator, attrs, flags)
 
   if (attrs)
     cplus_decl_attributes (decl1, NULL_TREE, attrs);
-  
+
   if (!building_stmt_tree ())
     {
       GNU_xref_function (decl1, current_function_parms);
@@ -13346,20 +13490,22 @@ store_parm_decls ()
              if (doing_semantic_analysis_p ())
                {
                  tree cleanup;
-             
+
                  if (DECL_NAME (parm) == NULL_TREE
                      || TREE_CODE (parm) != VOID_TYPE)
                    pushdecl (parm);
                  else
                    cp_error ("parameter `%D' declared void", parm);
 
-                 cleanup = maybe_build_cleanup (parm);
-                 
+                 cleanup = (processing_template_decl 
+                            ? NULL_TREE
+                            : maybe_build_cleanup (parm));
+
                  if (cleanup)
                    cleanups = tree_cons (parm, cleanup, cleanups);
                }
              else if (type != error_mark_node
-                      && TYPE_NEEDS_DESTRUCTOR (type))
+                      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
                parms_have_cleanups = 1;
            }
          else
@@ -13407,7 +13553,7 @@ store_parm_decls ()
      should not be called before the parm can be used.  */
   while (cleanups)
     {
-      finish_decl_cleanup (TREE_PURPOSE (cleanups), 
+      finish_decl_cleanup (TREE_PURPOSE (cleanups),
                           TREE_VALUE (cleanups));
       cleanups = TREE_CHAIN (cleanups);
     }
@@ -13423,8 +13569,9 @@ store_parm_decls ()
     }
 
   /* Do the starting of the exception specifications, if we have any.  */
-  if (flag_exceptions && !processing_template_decl 
-      && building_stmt_tree () 
+  if (flag_exceptions && !processing_template_decl
+      && flag_enforce_eh_specs
+      && building_stmt_tree ()
       && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
     current_eh_spec_try_block = expand_start_eh_spec ();
 }
@@ -13441,7 +13588,14 @@ store_return_init (decl)
   if (DECL_REGISTER (decl))
     {
       original_result_rtx = DECL_RTL (decl);
-      DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
+      /* Note that the mode of the old DECL_RTL may be wider than the
+        mode of DECL_RESULT, depending on the calling conventions for
+        the processor.  For example, on the Alpha, a 32-bit integer
+        is returned in a DImode register -- the DECL_RESULT has
+        SImode but the DECL_RTL for the DECL_RESULT has DImode.  So,
+        here, we use the mode the back-end has already assigned for
+        the return value.  */
+      DECL_RTL (decl) = gen_reg_rtx (GET_MODE (original_result_rtx));
     }
 }
 
@@ -13460,9 +13614,9 @@ save_function_data (decl)
      get it back when we really expand this function.  */
   my_friendly_assert (!DECL_PENDING_INLINE_P (decl),
                      19990908);
-      
+
   /* Make a copy.  */
-  f = ((struct language_function *) 
+  f = ((struct language_function *)
        xmalloc (sizeof (struct language_function)));
   bcopy ((char *) cp_function_chain, (char *) f,
         sizeof (struct language_function));
@@ -13541,9 +13695,9 @@ finish_destructor_body ()
     in_charge = current_in_charge_parm;
 
   exprstmt = build_delete (current_class_type,
-                          current_class_ref, 
+                          current_class_ref,
                           in_charge,
-                          LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 
+                          LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
                           0);
 
   if (exprstmt != error_mark_node
@@ -13562,13 +13716,13 @@ finish_destructor_body ()
          tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type)));
          tree if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
-                                     current_in_charge_parm, 
+                                     current_in_charge_parm,
                                      integer_two_node),
                               if_stmt);
 
          while (vbases)
            {
-             if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbases)))
                {
                  tree vb = get_vbase
                    (BINFO_TYPE (vbases),
@@ -13576,7 +13730,7 @@ finish_destructor_body ()
                  finish_expr_stmt
                    (build_scoped_method_call
                     (current_class_ref, vb, dtor_identifier,
-                     build_expr_list (NULL_TREE, integer_zero_node)));
+                     build_tree_list (NULL_TREE, integer_zero_node)));
                }
              vbases = TREE_CHAIN (vbases);
            }
@@ -13585,16 +13739,16 @@ finish_destructor_body ()
          finish_if_stmt ();
        }
     }
-  
+
   virtual_size = c_sizeof (current_class_type);
 
   /* At the end, call delete if that's what's requested.  */
-  
+
   /* 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.
-     
+
      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
@@ -13629,8 +13783,8 @@ finish_destructor_body ()
    This is called after parsing the body of the function definition.
    LINENO is the current line number.
 
-   FLAGS is a bitwise or of the following values: 
-     1 - CALL_POPLEVEL 
+   FLAGS is a bitwise or of the following values:
+     1 - CALL_POPLEVEL
        An extra call to poplevel (and expand_end_bindings) must be
        made to take care of the binding contour for the base
        initializers.  This is only relevant for constructors.
@@ -13694,8 +13848,9 @@ finish_function (lineno, flags)
 
       /* Finish dealing with exception specifiers.  */
       if (flag_exceptions && !processing_template_decl
+         && flag_enforce_eh_specs
          && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
-       expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS 
+       expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS
                            (TREE_TYPE (current_function_decl)),
                            current_eh_spec_try_block);
     }
@@ -13746,7 +13901,7 @@ finish_function (lineno, flags)
       /* If this function is supposed to return a value, ensure that
         we do not fall into the cleanups by mistake.  The end of our
         function will look like this:
-        
+
         user code (may have return stmt somewhere)
         goto no_return_label
         cleanup_label:
@@ -13756,7 +13911,7 @@ finish_function (lineno, flags)
         NOTE_INSN_FUNCTION_END
         return_label:
         things for return
-        
+
         If the user omits a return stmt in the USER CODE section, we
         will have a control path which reaches NOTE_INSN_FUNCTION_END.
         Otherwise, we won't.  */
@@ -13811,7 +13966,7 @@ finish_function (lineno, flags)
      maybe_end_member_template_processing decides to pop all the
      template parameters.  */
   expand_p = !building_stmt_tree ();
-  
+
   /* If we're saving up tree structure, tie off the function now.  */
   if (!expand_p)
     finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
@@ -13857,21 +14012,10 @@ finish_function (lineno, flags)
     {
       int returns_null;
       int returns_value;
-      int saved_flag_keep_inline_functions =
-       flag_keep_inline_functions;
 
       /* So we can tell if jump_optimize sets it to 1.  */
       can_reach_end = 0;
 
-      if (DECL_CONTEXT (fndecl) != NULL_TREE
-         && hack_decl_function_context (fndecl))
-       /* Trick rest_of_compilation into not deferring output of this
-          function, even if it is inline, since the rtl_obstack for
-          this function is the function_obstack of the enclosing
-          function and will be deallocated when the enclosing
-          function is gone.  See save_tree_status.  */
-       flag_keep_inline_functions = 1;
-
       /* Before we call rest_of_compilation (which will pop the
         CURRENT_FUNCTION), we must save these values.  */
       returns_null = current_function_returns_null;
@@ -13908,8 +14052,6 @@ finish_function (lineno, flags)
       if (function_depth > 1)
        ggc_pop_context ();
 
-      flag_keep_inline_functions = saved_flag_keep_inline_functions;
-
       if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
        {
          /* Set DECL_EXTERNAL so that assemble_external will be called as
@@ -14053,7 +14195,7 @@ start_method (declspecs, declarator, attrlist)
     {
       if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
        {
-         if (DECL_CONTEXT (fndecl) 
+         if (DECL_CONTEXT (fndecl)
              && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
            cp_error ("`%D' is already defined in class %s", fndecl,
                             TYPE_NAME_STRING (DECL_CONTEXT (fndecl)));
@@ -14100,7 +14242,7 @@ start_method (declspecs, declarator, attrlist)
   /* Make a place for the parms */
   pushlevel (0);
   current_binding_level->parm_flag = 1;
-  
+
   DECL_IN_AGGR_P (fndecl) = 1;
   return fndecl;
 }
@@ -14180,41 +14322,63 @@ hack_incomplete_structures (type)
      tree type;
 {
   tree *list;
-
-  if (current_binding_level->incomplete == NULL_TREE)
-    return;
+  struct binding_level *level;
 
   if (!type) /* Don't do this for class templates.  */
     return;
 
-  for (list = &current_binding_level->incomplete; *list; )
-    {
-      tree decl = TREE_VALUE (*list);
-      if ((decl && TREE_TYPE (decl) == type)
-         || (TREE_TYPE (decl)
-             && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
-             && TREE_TYPE (TREE_TYPE (decl)) == type))
-       {
-         int toplevel = toplevel_bindings_p ();
-         if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
-             && TREE_TYPE (TREE_TYPE (decl)) == type)
-           layout_type (TREE_TYPE (decl));
-         layout_decl (decl, 0);
-         rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0);
-         if (! toplevel)
+  if (namespace_bindings_p ())
+    {
+      level = 0;
+      list = &namespace_scope_incomplete;
+    }
+  else
+    {
+      level = innermost_nonclass_level ();
+      list = &level->incomplete;
+    }
+
+  while (1)
+    {
+      while (*list)
+       {
+         tree decl = TREE_VALUE (*list);
+         if ((decl && TREE_TYPE (decl) == type)
+             || (TREE_TYPE (decl)
+                 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+                 && TREE_TYPE (TREE_TYPE (decl)) == type))
            {
-             tree cleanup;
-             expand_decl (decl);
-             cleanup = maybe_build_cleanup (decl);
-             expand_decl_init (decl);
-             if (! expand_decl_cleanup (decl, cleanup))
-               cp_error ("parser lost in parsing declaration of `%D'",
-                         decl);
+             int toplevel = toplevel_bindings_p ();
+             if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+                 && TREE_TYPE (TREE_TYPE (decl)) == type)
+               layout_type (TREE_TYPE (decl));
+             layout_decl (decl, 0);
+             rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0);
+             if (! toplevel)
+               {
+                 tree cleanup;
+                 expand_decl (decl);
+                 cleanup = maybe_build_cleanup (decl);
+                 expand_decl_init (decl);
+                 if (! expand_decl_cleanup (decl, cleanup))
+                   cp_error ("parser lost in parsing declaration of `%D'",
+                             decl);
+               }
+             *list = TREE_CHAIN (*list);
            }
-         *list = TREE_CHAIN (*list);
+         else
+           list = &TREE_CHAIN (*list);
+       }
+
+      /* Keep looking through artificial binding levels generated
+        for local variables.  */
+      if (level && level->keep == 2)
+       {
+         level = level->level_chain;
+         list = &level->incomplete;
        }
       else
-       list = &TREE_CHAIN (*list);
+       break;
     }
 }
 
@@ -14229,7 +14393,7 @@ maybe_build_cleanup_1 (decl, auto_delete)
      tree decl, auto_delete;
 {
   tree type = TREE_TYPE (decl);
-  if (type != error_mark_node && TYPE_NEEDS_DESTRUCTOR (type))
+  if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
     {
       int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
       tree rval;
@@ -14252,7 +14416,7 @@ maybe_build_cleanup_1 (decl, auto_delete)
       if (TYPE_USES_VIRTUAL_BASECLASSES (type)
          && ! TYPE_HAS_DESTRUCTOR (type))
        rval = build_compound_expr (tree_cons (NULL_TREE, rval,
-                                              build_expr_list (NULL_TREE, build_vbase_delete (type, decl))));
+                                              build_tree_list (NULL_TREE, build_vbase_delete (type, decl))));
 
       return rval;
     }
@@ -14293,7 +14457,7 @@ cplus_expand_expr_stmt (exp)
 {
   if (stmts_are_full_exprs_p)
     exp = convert_to_void (exp, "statement");
-  
+
 #if 0
   /* We should do this eventually, but right now this causes regex.o from
      libg++ to miscompile, and tString to core dump.  */
@@ -14333,9 +14497,9 @@ revert_static_member_fn (decl, fn, argtypes)
   tree function = fn ? *fn : TREE_TYPE (*decl);
   tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function);
 
-  if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args))) 
+  if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
       != TYPE_UNQUALIFIED)
-    cp_error ("static member function `%#D' declared with type qualifiers", 
+    cp_error ("static member function `%#D' declared with type qualifiers",
              *decl);
 
   args = TREE_CHAIN (args);
@@ -14353,15 +14517,15 @@ revert_static_member_fn (decl, fn, argtypes)
     *argtypes = args;
 }
 
-/* Initialize the variables used during compilation of a C++ 
-   function.  */ 
+/* Initialize the variables used during compilation of a C++
+   function.  */
 
 static void
 push_cp_function_context (f)
      struct function *f;
 {
-  struct language_function *p 
-    = ((struct language_function *) 
+  struct language_function *p
+    = ((struct language_function *)
        xcalloc (1, sizeof (struct language_function)));
   f->language = p;
 
@@ -14499,7 +14663,7 @@ lang_mark_tree (t)
     {
       struct lang_type *lt = TYPE_LANG_SPECIFIC (t);
 
-      if (lt && !(TREE_CODE (t) == POINTER_TYPE 
+      if (lt && !(TREE_CODE (t) == POINTER_TYPE
                  && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))
        {
          ggc_mark (lt);
@@ -14508,7 +14672,7 @@ lang_mark_tree (t)
          ggc_mark_tree (lt->tags);
          ggc_mark_tree (lt->search_slot);
          ggc_mark_tree (lt->size);
-         ggc_mark_tree (lt->abstract_virtuals);
+         ggc_mark_tree (lt->pure_virtuals);
          ggc_mark_tree (lt->friend_classes);
          ggc_mark_tree (lt->rtti);
          ggc_mark_tree (lt->methods);
@@ -14521,4 +14685,3 @@ lang_mark_tree (t)
        ggc_mark_tree ((tree) lt);
     }
 }
-