OSDN Git Service

tweak formatting
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 215a5fb..20a6aba 100644 (file)
@@ -1,5 +1,6 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988, 92-98, 1999, 2000 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.
@@ -112,7 +113,6 @@ 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 void push_overloaded_decl_1 PARAMS ((tree));
 static int ambi_op_p PARAMS ((tree));
 static int unary_op_p PARAMS ((tree));
 static tree store_bindings PARAMS ((tree, tree));
@@ -132,6 +132,7 @@ static void set_identifier_type_value_with_scope
        PARAMS ((tree, tree, struct binding_level *));
 static void record_builtin_type PARAMS ((enum rid, const char *, tree));
 static void record_unknown_type PARAMS ((tree, const char *));
+static tree build_library_fn_1                 PARAMS ((tree, 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));
@@ -181,6 +182,7 @@ 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 PARAMS ((void));
@@ -221,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;
 
@@ -313,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
@@ -324,9 +321,9 @@ tree current_function_decl;
 
 tree current_function_return_value;
 
-/* Nonzero means use the ISO C9x dialect of C.  */
+/* Nonzero means use the ISO C99 dialect of C.  */
 
-int flag_isoc9x;
+int flag_isoc99;
 
 /* Nonzero means give `double' the same size as `float'.  */
 
@@ -442,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;
 
@@ -450,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;
@@ -481,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.  */
@@ -1002,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))
@@ -1524,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.  */
@@ -1784,7 +1785,18 @@ wrapup_globals_for_namespace (namespace, data)
      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)
     {
@@ -1837,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);
 
@@ -2278,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);
@@ -2655,7 +2670,7 @@ pushtag (name, type, globalize)
                /* 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;
@@ -2798,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)))
        {
@@ -3063,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;
@@ -3248,10 +3243,10 @@ 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);
@@ -3634,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))
@@ -4033,8 +4026,14 @@ 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)
@@ -4498,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);
@@ -4574,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.  */
@@ -5602,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;
@@ -5641,6 +5643,11 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
       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)))
        {
@@ -5933,26 +5940,6 @@ record_unknown_type (type, name)
   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,
    and some nodes representing standard constants (0, 1, (void *)0).
    Initialize the global binding level.
@@ -6139,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);
 
@@ -6173,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.
@@ -6187,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);
 
@@ -6276,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,
@@ -6314,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 ();
@@ -6341,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.  */
@@ -6391,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
@@ -6401,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) PARAMS ((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 (*) PARAMS ((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
@@ -6488,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");
 }
@@ -6692,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)
@@ -6771,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);
@@ -6849,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);
@@ -6941,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;
     }
 
@@ -7092,7 +7230,7 @@ layout_var_decl (decl)
      `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)
@@ -7138,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)
@@ -7173,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);
@@ -7495,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;
     }
@@ -7527,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)
@@ -7549,7 +7687,7 @@ destroy_local_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 &&
@@ -7603,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
@@ -7629,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)
@@ -7637,39 +7770,19 @@ 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;
@@ -7825,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:
@@ -7834,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
@@ -7852,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;
 }
@@ -7967,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);
@@ -8077,7 +8172,7 @@ register_dtor_fn (decl)
 
   int saved_flag_access_control;
 
-  if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
+  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     return;
 
   /* Call build_cleanup before we enter the anonymous function so that
@@ -8263,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);
        }
@@ -8444,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;
     }
@@ -8461,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)
@@ -8509,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))
@@ -8532,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;
            }
@@ -8576,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;
@@ -8698,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
@@ -8805,27 +8903,36 @@ build_ptrmemfunc_type (type)
     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.  */
@@ -8871,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
@@ -8880,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;
 }
@@ -8967,9 +9074,9 @@ compute_array_index_type (name, size)
       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");
        }
     }
 
@@ -8988,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.  */
@@ -9074,9 +9181,8 @@ create_array_type_for_decl (name, type, size)
      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;
     }
@@ -9118,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.
 
@@ -9308,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 */
@@ -9605,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
@@ -9695,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;
@@ -10176,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)
@@ -10199,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)
@@ -10467,7 +10575,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  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;
              }
@@ -10656,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);
        }
@@ -10727,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);
            }
@@ -10798,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;
@@ -10954,7 +11067,7 @@ 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;
+             decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
            publicp = (! friendp || ! staticp)
              && function_context == NULL_TREE;
            decl = grokfndecl (ctype, type,
@@ -11043,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;
              }
@@ -11101,7 +11214,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                       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;
@@ -11126,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)
@@ -11697,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))))
@@ -11855,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;
     }
@@ -11893,14 +12015,7 @@ grok_op_properties (decl, virtualp, friendp)
                                 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
     {
@@ -11950,16 +12065,17 @@ grok_op_properties (decl, virtualp, friendp)
       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)
@@ -11996,7 +12112,7 @@ 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))
        {
@@ -12330,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);
     }
@@ -12485,7 +12593,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
             the `accessibility' of that particular inheritance is.)  */
 
          base_binfo
-           = make_binfo (integer_zero_node, basetype,
+           = make_binfo (size_zero_node, basetype,
                          CLASS_TYPE_P (basetype)
                          ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
                          CLASS_TYPE_P (basetype)
@@ -12515,7 +12623,10 @@ xref_basetypes (code_type_node, name, ref, binfo)
 
          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)
@@ -12778,10 +12889,9 @@ 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);
@@ -12954,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
@@ -13203,7 +13312,7 @@ 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;
@@ -13260,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;
@@ -13388,13 +13497,15 @@ store_parm_decls ()
                  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
@@ -13459,6 +13570,7 @@ store_parm_decls ()
 
   /* Do the starting of the exception specifications, if we have any.  */
   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 ();
@@ -13610,7 +13722,7 @@ finish_destructor_body ()
 
          while (vbases)
            {
-             if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbases)))
                {
                  tree vb = get_vbase
                    (BINFO_TYPE (vbases),
@@ -13736,6 +13848,7 @@ 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
                            (TREE_TYPE (current_function_decl)),
@@ -13899,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;
@@ -13950,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
@@ -14222,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;
     }
 }
 
@@ -14271,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;