OSDN Git Service

tweak formatting
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 0575e48..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
@@ -453,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;
@@ -484,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.  */
@@ -1005,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))
@@ -1788,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)
     {
@@ -2662,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;
@@ -2805,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)))
        {
@@ -3070,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;
@@ -3255,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);
@@ -3641,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))
@@ -4511,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);
@@ -4587,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.  */
@@ -5954,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.
@@ -6160,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);
 
@@ -6194,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.
@@ -6208,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);
 
@@ -6297,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,
@@ -6335,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 ();
@@ -6362,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.  */
@@ -6412,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
@@ -6422,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;
+}
+
+/* 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
+build_library_fn (name, type)
+     tree name;
+     tree type;
+{
+  tree fn = build_library_fn_1 (name, type);
+  make_function_rtl (fn);
+  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.  */
 
 tree
-builtin_function (name, type, code, class, libname)
+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
@@ -6509,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");
 }
@@ -6713,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)
@@ -6792,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);
@@ -6870,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);
@@ -6962,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;
     }
 
@@ -7113,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)
@@ -7159,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)
@@ -7194,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);
@@ -7516,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;
     }
@@ -7548,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)
@@ -7570,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 &&
@@ -7624,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
@@ -7650,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)
@@ -7658,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;
@@ -7846,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:
@@ -7855,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
@@ -7873,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;
 }
@@ -7988,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);
@@ -8098,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
@@ -8284,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);
        }
@@ -8465,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;
     }
@@ -8482,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)
@@ -8530,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))
@@ -8553,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;
            }
@@ -8597,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;
@@ -8719,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
@@ -8826,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.  */
@@ -8892,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
@@ -8901,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;
 }
@@ -8988,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");
        }
     }
 
@@ -9009,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.  */
@@ -9095,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;
     }
@@ -9329,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 */
@@ -9626,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
@@ -9716,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;
@@ -10197,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)
@@ -10220,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)
@@ -10488,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;
              }
@@ -10677,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);
        }
@@ -10748,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);
            }
@@ -10819,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;
@@ -10975,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,
@@ -11064,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;
              }
@@ -11122,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;
@@ -11147,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)
@@ -11718,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))))
@@ -11876,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;
     }
@@ -11914,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
     {
@@ -11971,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)
@@ -12017,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))
        {
@@ -12351,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);
     }
@@ -12506,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)
@@ -12536,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)
@@ -12799,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);
@@ -12975,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
@@ -13224,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;
@@ -13281,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;
@@ -13409,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
@@ -13480,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 ();
@@ -13631,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),
@@ -13757,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)),
@@ -13920,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;
@@ -13971,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
@@ -14314,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;