OSDN Git Service

When a class template is explicitly instantiated, its member should be too.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index c949c74..92f6d14 100644 (file)
@@ -51,8 +51,9 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "debug.h"
 #include "timevar.h"
+#include "tree-flow.h"
 
-static tree grokparms (tree);
+static tree grokparms (tree, tree *);
 static const char *redeclaration_error_message (tree, tree);
 
 static int decl_jump_unsafe (tree);
@@ -61,7 +62,7 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, tree *);
-static tree grokfndecl (tree, tree, tree, tree, int,
+static tree grokfndecl (tree, tree, tree, tree, tree, int,
                        enum overload_flags, tree,
                        tree, int, int, int, int, int, int, tree);
 static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree);
@@ -114,7 +115,6 @@ static tree check_special_function_return_type
 static tree push_cp_library_fn (enum tree_code, tree);
 static tree build_cp_library_fn (tree, enum tree_code, tree);
 static void store_parm_decls (tree);
-static int cp_missing_noreturn_ok_p (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
 static tree next_initializable_field (tree);
@@ -207,9 +207,6 @@ tree static_aggregates;
 
 tree integer_two_node, integer_three_node;
 
-/* Similar, for last_function_parm_tags.  */
-tree last_function_parms;
-
 /* A list of all LABEL_DECLs in the function that have names.  Here so
    we can clear out their names' definitions at the end of the
    function, and so we can check the validity of jumps to these labels.  */
@@ -502,28 +499,6 @@ poplevel (int keep, int reverse, int functionbody)
   else
     decls = current_binding_level->names;
 
-  /* Output any nested inline functions within this block
-     if they weren't already output.  */
-  for (decl = decls; decl; decl = TREE_CHAIN (decl))
-    if (TREE_CODE (decl) == FUNCTION_DECL
-       && ! TREE_ASM_WRITTEN (decl)
-       && DECL_INITIAL (decl) != NULL_TREE
-       && TREE_ADDRESSABLE (decl)
-       && decl_function_context (decl) == current_function_decl)
-      {
-       /* If this decl was copied from a file-scope decl
-          on account of a block-scope extern decl,
-          propagate TREE_ADDRESSABLE to the file-scope decl.  */
-       if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE)
-         TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
-       else
-         {
-           push_function_context ();
-           output_inline_function (decl);
-           pop_function_context ();
-         }
-      }
-
   /* When not in function-at-a-time mode, expand_end_bindings will
      warn about unused variables.  But, in function-at-a-time mode
      expand_end_bindings is not passed the list of variables in the
@@ -1097,11 +1072,6 @@ decls_match (tree newdecl, tree olddecl)
 void
 warn_extern_redeclared_static (tree newdecl, tree olddecl)
 {
-  static const char *const explicit_extern_static_warning
-    = "`%D' was declared `extern' and later `static'";
-  static const char *const implicit_extern_static_warning
-    = "`%D' was declared implicitly `extern' and later `static'";
-
   tree name;
 
   if (TREE_CODE (newdecl) == TYPE_DECL
@@ -1127,9 +1097,7 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  pedwarn (IDENTIFIER_IMPLICIT_DECL (name)
-             ? implicit_extern_static_warning
-             : explicit_extern_static_warning, newdecl);
+  pedwarn ("`%D' was declared `extern' and later `static'", newdecl);
   cp_pedwarn_at ("previous declaration of `%D'", olddecl);
 }
 
@@ -1319,10 +1287,7 @@ duplicate_decls (tree newdecl, tree olddecl)
        olddecl = TREE_VALUE (olddecl);
       cp_error_at ("previous declaration of `%#D'", olddecl);
 
-      /* New decl is completely inconsistent with the old one =>
-        tell caller to replace the old one.  */
-
-      return NULL_TREE;
+      return error_mark_node;
     }
   else if (!types_match)
     {
@@ -1376,10 +1341,7 @@ duplicate_decls (tree newdecl, tree olddecl)
          else
            return NULL_TREE;
        }
-
-      /* Already complained about this, so don't do so again.  */
-      else if (current_class_type == NULL_TREE
-         || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
+      else
        {
          error ("conflicting declaration '%#D'", newdecl);
          cp_error_at ("'%D' has a previous declaration as `%#D'",
@@ -1594,6 +1556,9 @@ duplicate_decls (tree newdecl, tree olddecl)
          DECL_SOURCE_LOCATION (olddecl) 
            = DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl))
            = DECL_SOURCE_LOCATION (newdecl);
+         if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+           DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (olddecl))
+             = DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (newdecl));
        }
 
       if (DECL_FUNCTION_TEMPLATE_P (newdecl))
@@ -1684,7 +1649,7 @@ duplicate_decls (tree newdecl, tree olddecl)
              && DECL_LANG_SPECIFIC (olddecl))
            {
              DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
-             DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
+             DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
            }
        }
 
@@ -1853,8 +1818,6 @@ duplicate_decls (tree newdecl, tree olddecl)
                 regardless of declaration matches.  */
              SET_DECL_RTL (newdecl, DECL_RTL (olddecl));
            }
-         else
-           DECL_ESTIMATED_INSNS (newdecl) = DECL_ESTIMATED_INSNS (olddecl);
 
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
          /* Don't clear out the arguments if we're redefining a function.  */
@@ -1948,39 +1911,6 @@ duplicate_decls (tree newdecl, tree olddecl)
   return olddecl;
 }
 \f
-/* Generate an implicit declaration for identifier FUNCTIONID
-   as a function of type int ().  Print a warning if appropriate.  */
-
-tree
-implicitly_declare (tree functionid)
-{
-  tree decl;
-
-  /* We used to reuse an old implicit decl here,
-     but this loses with inline functions because it can clobber
-     the saved decl chains.  */
-  decl = build_lang_decl (FUNCTION_DECL, functionid, default_function_type);
-
-  DECL_EXTERNAL (decl) = 1;
-  TREE_PUBLIC (decl) = 1;
-
-  /* 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, 0, 0);
-
-  if (warn_implicit
-      /* Only one warning per identifier.  */
-      && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE)
-    {
-      pedwarn ("implicit declaration of function `%#D'", decl);
-    }
-
-  SET_IDENTIFIER_IMPLICIT_DECL (functionid, decl);
-
-  return decl;
-}
-
 /* Return zero if the declaration NEWDECL is valid
    when the declaration OLDDECL (assumed to be for the same name)
    has already been seen.
@@ -2030,16 +1960,31 @@ redeclaration_error_message (tree newdecl, tree olddecl)
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
-      if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
-          && (DECL_TEMPLATE_RESULT (newdecl)
-              != DECL_TEMPLATE_RESULT (olddecl))
-          && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
-          && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
-         || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
-             && COMPLETE_TYPE_P (TREE_TYPE (newdecl))
-             && COMPLETE_TYPE_P (TREE_TYPE (olddecl))))
+      tree nt, ot;
+
+      if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
+       {
+         if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
+             && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
+           return "redefinition of `%#D'";
+         return NULL;
+       }
+
+      if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != FUNCTION_DECL
+         || (DECL_TEMPLATE_RESULT (newdecl) 
+             == DECL_TEMPLATE_RESULT (olddecl)))
+       return NULL;
+
+      nt = DECL_TEMPLATE_RESULT (newdecl);
+      if (DECL_TEMPLATE_INFO (nt))
+       nt = DECL_TEMPLATE_RESULT (template_for_substitution (nt));
+      ot = DECL_TEMPLATE_RESULT (olddecl);
+      if (DECL_TEMPLATE_INFO (ot))
+       ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
+      if (DECL_INITIAL (nt) && DECL_INITIAL (ot))
        return "redefinition of `%#D'";
-      return 0;
+
+      return NULL;
     }
   else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
     {
@@ -2121,8 +2066,7 @@ lookup_label (tree id)
   /* You can't use labels at global scope.  */
   if (current_function_decl == NULL_TREE)
     {
-      error ("label `%s' referenced outside of any function",
-            IDENTIFIER_POINTER (id));
+      error ("label `%E' referenced outside of any function", id);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
 
@@ -2439,9 +2383,11 @@ push_switch (tree switch_stmt)
 void
 pop_switch (void)
 {
-  struct cp_switch *cs;
+  struct cp_switch *cs = switch_stack;
+
+  /* Emit warnings as needed.  */
+  c_do_switch_warnings (cs->cases, cs->switch_stmt);
 
-  cs = switch_stack;
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
   free (cs);
@@ -2750,18 +2696,6 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
 
 \f
 
-/* A chain of TYPE_DECLs for the builtin types.  */
-
-static GTY(()) tree builtin_type_decls;
-
-/* Return a chain of TYPE_DECLs for the builtin types.  */
-
-tree
-cxx_builtin_type_decls (void)
-{
-  return builtin_type_decls;
-}
-
 /* Push the declarations of builtin types into the namespace.
    RID_INDEX is the index of the builtin type in the array
    RID_POINTERS.  NAME is the name used when looking up the builtin
@@ -2805,10 +2739,7 @@ record_builtin_type (enum rid rid_index,
     TYPE_NAME (type) = tdecl;
 
   if (tdecl)
-    {
-      TREE_CHAIN (tdecl) = builtin_type_decls;
-      builtin_type_decls = tdecl;
-    }
+    debug_hooks->type_decl (tdecl, 0);
 }
 
 /* Record one of the standard Java types.
@@ -2926,9 +2857,6 @@ cxx_init_decl_processing (void)
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
 
-  /* Fill in back-end hooks.  */
-  lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p;
-
   /* Create the global variables.  */
   push_to_top_level ();
 
@@ -3108,12 +3036,8 @@ cxx_init_decl_processing (void)
   start_fname_decls ();
 
   /* Show we use EH for cleanups.  */
-  using_eh_for_cleanups ();
-
-  /* Maintain consistency.  Perhaps we should just complain if they
-     say -fwritable-strings?  */
-  if (flag_writable_strings)
-    flag_const_strings = 0;
+  if (flag_exceptions)
+    using_eh_for_cleanups ();
 }
 
 /* Generate an initializer for a function naming variable from
@@ -3152,7 +3076,7 @@ cp_fname_init (const char* name, tree *type_p)
    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. This is being done
-   lazily at the point of first use, so we musn't push the decl now.  */
+   lazily at the point of first use, so we mustn't push the decl now.  */
 
 static tree
 cp_make_fname_decl (tree id, int type_dep)
@@ -3163,6 +3087,9 @@ cp_make_fname_decl (tree id, int type_dep)
   tree init = cp_fname_init (name, &type);
   tree decl = build_decl (VAR_DECL, id, type);
 
+  if (name)
+    free ((char *) name);
+
   /* As we're using pushdecl_with_scope, we must set the context.  */
   DECL_CONTEXT (decl) = current_function_decl;
   DECL_PRETTY_FUNCTION_P (decl) = type_dep;
@@ -3780,8 +3707,10 @@ start_decl (tree declarator,
       else
        {
          tree field = check_classfn (context, decl,
-                                     processing_template_decl
-                                     > template_class_depth (context));
+                                     (processing_template_decl
+                                      > template_class_depth (context))
+                                     ? current_template_parms
+                                     : NULL_TREE);
          if (field && duplicate_decls (decl, field))
            decl = field;
        }
@@ -3841,8 +3770,6 @@ start_decl_1 (tree decl)
   if (type == error_mark_node)
     return;
 
-  maybe_push_cleanup_level (type);
-
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
        If not, set INITIALIZED to zero, which will indirectly
@@ -3898,6 +3825,14 @@ start_decl_1 (tree decl)
 
   if (! initialized)
     DECL_INITIAL (decl) = NULL_TREE;
+
+  /* Create a new scope to hold this declaration if necessary.
+     Whether or not a new scope is necessary cannot be determined
+     until after the type has been completed; if the type is a
+     specialization of a class template it is not until after
+     instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+     will be set correctly.  */
+  maybe_push_cleanup_level (type);
 }
 
 /* Handle initialization of references.  DECL, TYPE, and INIT have the
@@ -4198,8 +4133,7 @@ reshape_init (tree type, tree *initp)
      enclosed elements.  Advance past the brace-enclosed initializer
      now.  */
   if (TREE_CODE (old_init_value) == CONSTRUCTOR
-      && TREE_TYPE (old_init_value) == NULL_TREE
-      && TREE_HAS_CONSTRUCTOR (old_init_value))
+      && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
     {
       *initp = TREE_CHAIN (old_init);
       TREE_CHAIN (old_init) = NULL_TREE;
@@ -4269,8 +4203,7 @@ reshape_init (tree type, tree *initp)
   else
     {
       /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */  
-      new_init = build_constructor (type, NULL_TREE);
-      TREE_HAS_CONSTRUCTOR (new_init) = 1;
+      new_init = build_constructor (NULL_TREE, NULL_TREE);
 
       if (CLASS_TYPE_P (type))
        {
@@ -4330,15 +4263,30 @@ reshape_init (tree type, tree *initp)
                }
            }
        }
-      else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
+      else if (TREE_CODE (type) == ARRAY_TYPE
+              || TREE_CODE (type) == VECTOR_TYPE)
        {
          tree index;
          tree max_index;
 
          /* If the bound of the array is known, take no more initializers
             than are allowed.  */
-         max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
-                      ? array_type_nelts (type) : NULL_TREE);
+         max_index = NULL_TREE;
+         if (TREE_CODE (type) == ARRAY_TYPE)
+           {
+             if (TYPE_DOMAIN (type))
+               max_index = array_type_nelts (type);
+           }
+         else
+           {
+             /* For a vector, the representation type is a struct
+                containing a single member which is an array of the
+                appropriate size.  */
+             tree rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
+             if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
+               max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype)));
+           }
+
          /* Loop through the array elements, gathering initializers.  */
          for (index = size_zero_node;
               *initp && (!max_index || !tree_int_cst_lt (max_index, index));
@@ -4446,7 +4394,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
     init = grok_reference_init (decl, type, init, cleanup);
   else if (init)
     {
-      if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
+      if (TREE_CODE (init) == CONSTRUCTOR 
+         && BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          /* [dcl.init] paragraph 13,
             If T is a scalar type, then a declaration of the form
@@ -4471,15 +4420,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
         array size from the initializer.  */
       maybe_deduce_size_from_array_init (decl, init);
       type = TREE_TYPE (decl);
-      if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
-       TREE_TYPE (init) = type;
 
       if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
        {
          if (TREE_CODE (type) == ARRAY_TYPE)
            goto initialize_aggr;
          else if (TREE_CODE (init) == CONSTRUCTOR
-                  && TREE_HAS_CONSTRUCTOR (init))
+                  && BRACE_ENCLOSED_INITIALIZER_P (init))
            {
              if (TYPE_NON_AGGREGATE_CLASS (type))
                {
@@ -4577,7 +4524,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
         asm-specification, indicates that the variable should be
         placed in a particular register.  */
       if (DECL_REGISTER (decl))
-       DECL_C_HARD_REGISTER (decl) = 1;
+       DECL_HARD_REGISTER (decl) = 1;
     }
 
   /* We don't create any RTL for local variables.  */
@@ -4764,6 +4711,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 
       if (init && DECL_INITIAL (decl))
        DECL_INITIAL (decl) = init;
+      if (TREE_CODE (decl) == VAR_DECL
+         && !DECL_PRETTY_FUNCTION_P (decl)
+         && !dependent_type_p (TREE_TYPE (decl)))
+       maybe_deduce_size_from_array_init (decl, init);
       goto finish_end0;
     }
 
@@ -4796,16 +4747,17 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   if (TREE_CODE (decl) != FUNCTION_DECL)
     ttype = target_type (type);
 
-  if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)
-      && (TYPE_NEEDS_CONSTRUCTING (type) 
-         || TREE_CODE (type) == REFERENCE_TYPE))
+  
+  /* Currently, GNU C++ puts constants in text space, making them
+     impossible to initialize.  In the future, one would hope for
+     an operating system which understood the difference between
+     initialization and the running of a program.  */
+  if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
     {
-      /* Currently, GNU C++ puts constants in text space, making them
-        impossible to initialize.  In the future, one would hope for
-        an operating system which understood the difference between
-        initialization and the running of a program.  */
       was_readonly = 1;
-      TREE_READONLY (decl) = 0;
+      if (TYPE_NEEDS_CONSTRUCTING (type) 
+         || TREE_CODE (type) == REFERENCE_TYPE)
+       TREE_READONLY (decl) = 0;
     }
 
   if (TREE_CODE (decl) == VAR_DECL)
@@ -4962,7 +4914,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 
   /* If this was marked 'used', be sure it will be output.  */
   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
-    mark_referenced (DECL_ASSEMBLER_NAME (decl));
+    mark_decl_referenced (decl);
 }
 
 /* This is here for a midend callback from c-common.c.  */
@@ -5388,6 +5340,7 @@ complete_array_type (tree type, tree initial_value, int do_default)
     {
       tree itype;
       tree domain;
+      tree elt_type;
 
       domain = build_index_type (maxindex);
       TYPE_DOMAIN (type) = domain;
@@ -5405,6 +5358,12 @@ complete_array_type (tree type, tree initial_value, int do_default)
         size of the array.  */
       if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
        TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
+
+      elt_type = TREE_TYPE (type);
+      TYPE_NEEDS_CONSTRUCTING (type)
+       = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
+      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+       = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));      
     }
 
   /* Lay out the type now that we can get the real answer.  */
@@ -5469,6 +5428,7 @@ bad_specifiers (tree object,
    TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
    or METHOD_TYPE.
    DECLARATOR is the function's name.
+   PARMS is a chain of PARM_DECLs for the function.
    VIRTUALP is truthvalue of whether the function is virtual or not.
    FLAGS are to be passed through to `grokclassfn'.
    QUALS are qualifiers indicating whether the function is `const'
@@ -5484,6 +5444,7 @@ static tree
 grokfndecl (tree ctype, 
             tree type,
             tree declarator,
+           tree parms,
             tree orig_declarator,
             int virtualp,
             enum overload_flags flags,
@@ -5506,6 +5467,7 @@ grokfndecl (tree ctype,
     type = build_exception_variant (type, raises);
 
   decl = build_lang_decl (FUNCTION_DECL, declarator, type);
+  DECL_ARGUMENTS (decl) = parms;
   /* Propagate volatile out from type to decl.  */
   if (TYPE_VOLATILE (type))
     TREE_THIS_VOLATILE (decl) = 1;
@@ -5554,8 +5516,7 @@ grokfndecl (tree ctype,
     }
 
   /* Members of anonymous types and local classes have no linkage; make
-     them internal.  */
-  /* FIXME what if it gets a name from typedef?  */
+     them internal.  If a typedef is made later, this will be changed.  */
   if (ctype && (TYPE_ANONYMOUS_P (ctype)
                || decl_function_context (TYPE_MAIN_DECL (ctype))))
     publicp = 0;
@@ -5719,8 +5680,10 @@ grokfndecl (tree ctype,
       tree old_decl;
 
       old_decl = check_classfn (ctype, decl,
-                               processing_template_decl
-                               > template_class_depth (ctype));
+                               (processing_template_decl
+                                > template_class_depth (ctype))
+                               ? current_template_parms
+                               : NULL_TREE);
 
       if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
        /* Because grokfndecl is always supposed to return a
@@ -5731,18 +5694,16 @@ grokfndecl (tree ctype,
 
       if (old_decl && DECL_STATIC_FUNCTION_P (old_decl)
          && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
-       {
-         /* Remove the `this' parm added by grokclassfn.
-            XXX Isn't this done in start_function, too?  */
-         revert_static_member_fn (decl);
-         last_function_parms = TREE_CHAIN (last_function_parms);
-       }
+       /* Remove the `this' parm added by grokclassfn.
+          XXX Isn't this done in start_function, too?  */
+       revert_static_member_fn (decl);
       if (old_decl && DECL_ARTIFICIAL (old_decl))
        error ("definition of implicitly-declared `%D'", old_decl);
 
       if (old_decl)
        {
          tree ok;
+         bool pop_p;
 
          /* Since we've smashed OLD_DECL to its
             DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
@@ -5751,9 +5712,10 @@ grokfndecl (tree ctype,
 
          /* Attempt to merge the declarations.  This can fail, in
             the case of some invalid specialization declarations.  */
-         push_scope (ctype);
+         pop_p = push_scope (ctype);
          ok = duplicate_decls (decl, old_decl);
-         pop_scope (ctype);
+         if (pop_p)
+           pop_scope (ctype);
          if (!ok)
            {
              error ("no `%#D' member function declared in class `%T'",
@@ -5888,7 +5850,19 @@ grokvardecl (tree type,
       if (t)
        {
          if (TYPE_ANONYMOUS_P (t))
-           /* Ignore for now; `enum { foo } e' is pretty common.  */;
+           {
+             if (DECL_EXTERN_C_P (decl))
+               /* Allow this; it's pretty common in C.  */;
+             else
+               {
+                 pedwarn ("non-local variable `%#D' uses anonymous type",
+                          decl);
+                 if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+                   cp_pedwarn_at ("\
+`%#D' does not refer to the unqualified type, so it is not used for linkage",
+                                  TYPE_NAME (t));
+               }
+           }
          else
            pedwarn ("non-local variable `%#D' uses local type `%T'",
                        decl, t);
@@ -6376,6 +6350,7 @@ grokdeclarator (tree declarator,
   tree in_namespace = NULL_TREE;
   tree returned_attrs = NULL_TREE;
   tree scope = NULL_TREE;
+  tree parms = NULL_TREE;
 
   RIDBIT_RESET_ALL (specbits);
   if (decl_context == FUNCDEF)
@@ -6780,7 +6755,7 @@ grokdeclarator (tree declarator,
                        longlong = 1;
                    }
                  else if (RIDBIT_SETP (i, specbits))
-                   pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
+                   pedwarn ("duplicate `%E'", id);
 
                  /* Diagnose "__thread extern" or "__thread static".  */
                  if (RIDBIT_SETP (RID_THREAD, specbits))
@@ -6820,8 +6795,7 @@ grokdeclarator (tree declarator,
        {
          tree t = lookup_name (id, 1);
          if (!t || TREE_CODE (t) != TYPE_DECL)
-           error ("`%s' fails to be a typedef or built in type",
-                  IDENTIFIER_POINTER (id));
+           error ("`%E' fails to be a typedef or built in type", id);
          else
            {
              type = TREE_TYPE (t);
@@ -7295,6 +7269,13 @@ grokdeclarator (tree declarator,
 
            type = create_array_type_for_decl (dname, type, size);
 
+           if (declarator
+               && (TREE_CODE (declarator) == INDIRECT_REF
+                   || TREE_CODE (declarator) == ADDR_EXPR))
+             /* We can never complete an array type which is the target of a
+                pointer, so go ahead and lay it out.  */
+             layout_type (type);
+
            ctype = NULL_TREE;
          }
          break;
@@ -7370,8 +7351,8 @@ grokdeclarator (tree declarator,
                      error ("destructor cannot be static member function");
                    if (quals)
                      {
-                       error ("destructors may not be `%s'",
-                                 IDENTIFIER_POINTER (TREE_VALUE (quals)));
+                       error ("destructors may not be `%E'",
+                                 TREE_VALUE (quals));
                        quals = NULL_TREE;
                      }
                    if (decl_context == FIELD)
@@ -7399,8 +7380,8 @@ grokdeclarator (tree declarator,
                      }
                    if (quals)
                      {
-                       error ("constructors may not be `%s'",
-                                 IDENTIFIER_POINTER (TREE_VALUE (quals)));
+                       error ("constructors may not be `%E'",
+                               TREE_VALUE (quals));
                        quals = NULL_TREE;
                      }
                    {
@@ -7448,7 +7429,7 @@ grokdeclarator (tree declarator,
 
            declarator = TREE_OPERAND (declarator, 0);
 
-           arg_types = grokparms (inner_parms);
+           arg_types = grokparms (inner_parms, &parms);
 
            if (declarator && flags == DTOR_FLAG)
              {
@@ -7462,7 +7443,7 @@ grokdeclarator (tree declarator,
                  {
                    error ("destructors may not have parameters");
                    arg_types = void_list_node;
-                   last_function_parms = NULL_TREE;
+                   parms = NULL_TREE;
                  }
              }
 
@@ -7629,7 +7610,11 @@ grokdeclarator (tree declarator,
                  }
                else if (TREE_CODE (type) == FUNCTION_TYPE)
                  {
-                   if (current_class_type == NULL_TREE || friendp)
+                   if (NEW_DELETE_OPNAME_P (sname))
+                     /* Overloaded operator new and operator delete
+                        are always static functions.  */
+                     ;
+                   else if (current_class_type == NULL_TREE || friendp)
                      type 
                        = build_method_type_directly (ctype, 
                                                      TREE_TYPE (type),
@@ -7776,6 +7761,7 @@ grokdeclarator (tree declarator,
     }
 
   if (declarator == NULL_TREE
+      || TREE_CODE (declarator) == ERROR_MARK
       || TREE_CODE (declarator) == IDENTIFIER_NODE
       || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR
          && (TREE_CODE (type) == FUNCTION_TYPE
@@ -7888,8 +7874,7 @@ grokdeclarator (tree declarator,
     type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
 
   /* Detect where we're using a typedef of function type to declare a
-     function. last_function_parms will not be set, so we must create
-     it now.  */
+     function. PARMS will not be set, so we must create it now.  */
   
   if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
     {
@@ -7904,7 +7889,7 @@ grokdeclarator (tree declarator,
          decls = decl;
        }
       
-      last_function_parms = nreverse (decls);
+      parms = nreverse (decls);
     }
 
   /* If this is a type name (such as, in a cast or sizeof),
@@ -8098,10 +8083,7 @@ grokdeclarator (tree declarator,
                    return void_type_node;
                  }
 
-               if (declarator == ansi_opname (NEW_EXPR)
-                   || declarator == ansi_opname (VEC_NEW_EXPR)
-                   || declarator == ansi_opname (DELETE_EXPR)
-                   || declarator == ansi_opname (VEC_DELETE_EXPR))
+               if (NEW_DELETE_OPNAME_P (declarator))
                  {
                    if (virtualp)
                      {
@@ -8124,6 +8106,7 @@ grokdeclarator (tree declarator,
            decl = grokfndecl (ctype, type,
                               TREE_CODE (declarator) != TEMPLATE_ID_EXPR
                               ? declarator : dname,
+                              parms,
                               declarator,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, publicp, inlinep,
@@ -8170,6 +8153,7 @@ grokdeclarator (tree declarator,
            decl = grokfndecl (ctype, type,
                               TREE_CODE (declarator) != TEMPLATE_ID_EXPR
                               ? declarator : dname,
+                              parms,
                               declarator,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
@@ -8203,8 +8187,8 @@ grokdeclarator (tree declarator,
          {
            if (friendp)
              {
-               error ("`%s' is neither function nor member function; cannot be declared friend",
-                      IDENTIFIER_POINTER (declarator));
+               error ("`%E' is neither function nor member function; "
+                       "cannot be declared friend", declarator);
                friendp = 0;
              }
            decl = NULL_TREE;
@@ -8227,8 +8211,7 @@ grokdeclarator (tree declarator,
                  }
                
                decl = do_friend (ctype, declarator, decl,
-                                 last_function_parms, *attrlist,
-                                 flags, quals, funcdef_flag);
+                                 *attrlist, flags, quals, funcdef_flag);
                return decl;
              }
            else
@@ -8276,13 +8259,6 @@ grokdeclarator (tree declarator,
 
            if (staticp)
              {
-               /* [class.mem] forbids static data members with the
-                  same name as the enclosing class.  Non-static data
-                  members are checked in check_field_decls.  */
-               if (constructor_name_p (declarator, current_class_type))
-                 pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
-                          declarator);
-                 
                /* C++ allows static class members.  All other work
                   for this is done by grokfield.  */
                decl = build_lang_decl (VAR_DECL, declarator, type);
@@ -8348,7 +8324,8 @@ grokdeclarator (tree declarator,
                virtualp = 0;
              }
          }
-       else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)
+       else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+                && !NEW_DELETE_OPNAME_P (original_name))
          type = build_method_type_directly (ctype, 
                                             TREE_TYPE (type),
                                             TYPE_ARG_TYPES (type));
@@ -8358,7 +8335,7 @@ grokdeclarator (tree declarator,
                   || RIDBIT_SETP (RID_EXTERN, specbits)
                   || !RIDBIT_SETP (RID_STATIC, specbits));
 
-       decl = grokfndecl (ctype, type, original_name, declarator,
+       decl = grokfndecl (ctype, type, original_name, parms, declarator,
                           virtualp, flags, quals, raises,
                           1, friendp,
                           publicp, inlinep, funcdef_flag,
@@ -8467,8 +8444,6 @@ require_complete_types_for_parms (tree parms)
          layout_decl (parms, 0);
          DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
        }
-      else
-        TREE_TYPE (parms) = error_mark_node;
     }
 }
 
@@ -8598,10 +8573,10 @@ check_default_argument (tree decl, tree arg)
    flag. If unset, we append void_list_node. A parmlist declared
    as `(void)' is accepted as the empty parmlist.
 
-   Also set last_function_parms to the chain of PARM_DECLs.  */
+   *PARMS is set to the chain of PARM_DECLs created.  */
 
 static tree
-grokparms (tree first_parm)
+grokparms (tree first_parm, tree *parms)
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
@@ -8707,7 +8682,7 @@ grokparms (tree first_parm)
   result = nreverse (result);
   if (!ellipsis)
     result = chainon (result, void_list_node);
-  last_function_parms = decls;
+  *parms = decls;
 
   return result;
 }
@@ -8850,7 +8825,6 @@ grok_ctor_properties (tree ctype, tree decl)
         instantiated, but that's hard to forestall.  */
       error ("invalid constructor; you probably meant `%T (const %T&)'",
                ctype, ctype);
-      SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
       return 0;
     }
   
@@ -8961,21 +8935,9 @@ grok_op_properties (tree decl, int friendp, bool complain)
     }
 
   if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
-    {
-      /* When the compiler encounters the definition of A::operator new, it
-        doesn't look at the class declaration to find out if it's static.  */
-      if (methodp)
-       revert_static_member_fn (decl);
-
-      TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
-    }
+    TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
   else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
-    {
-      if (methodp)
-       revert_static_member_fn (decl);
-
-      TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
-    }
+    TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
   else
     {
       /* An operator function must either be a non-static member function
@@ -9309,8 +9271,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
    Define the tag as a forward-reference if it is not defined.
 
    If a declaration is given, process it here, and report an error if
-   multiple declarations are not identical.  ATTRIBUTE is the attribute
-   appeared in this declaration.
+   multiple declarations are not identical.
 
    GLOBALIZE is false when this is also a definition.  Only look in
    the current frame for the name (since C++ allows new names in any
@@ -9320,7 +9281,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
    a set of template parameters.  */
 
 tree
-xref_tag (enum tag_types tag_code, tree name, tree attributes, 
+xref_tag (enum tag_types tag_code, tree name,
          bool globalize, bool template_header_p)
 {
   enum tree_code code;
@@ -9356,7 +9317,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
     }
   else
     {
-      tree decl = lookup_name (name, 1);
+      tree decl = lookup_name (name, 2);
 
       if (decl && DECL_CLASS_TEMPLATE_P (decl))
        decl = DECL_TEMPLATE_RESULT (decl);
@@ -9443,25 +9404,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
       if (code == ENUMERAL_TYPE)
        {
          error ("use of enum `%#D' without previous declaration", name);
-
-         t = make_node (ENUMERAL_TYPE);
-
-         /* Give the type a default layout like unsigned int
-            to avoid crashing if it does not get defined.  */
-         TYPE_MODE (t) = TYPE_MODE (unsigned_type_node);
-         TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node);
-         TYPE_USER_ALIGN (t) = 0;
-         TREE_UNSIGNED (t) = 1;
-         TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node);
-         TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node);
-         TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node);
-
-         /* Enable us to recognize when a type is created in class context.
-            To do nested classes correctly, this should probably be cleared
-            out when we leave this classes scope.  Currently this in only
-            done in `start_enum'.  */
-
-         pushtag (name, t, globalize);
+         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
        }
       else
        {
@@ -9474,16 +9417,13 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
     {
       if (!globalize && processing_template_decl && IS_AGGR_TYPE (t))
        redeclare_class_template (t, current_template_parms);
-    }
-
-  /* Add attributes only when defining a class. */
-  if (attributes)
-    {
-      /* The only place that xref_tag is called with non-null
-        attributes is in cp_parser_class_head(), when defining a
-        class.  */ 
-      my_friendly_assert (TYPE_ATTRIBUTES (t) == NULL_TREE, 20040113);
-      TYPE_ATTRIBUTES (t) = attributes;
+      else if (!processing_template_decl 
+              && CLASS_TYPE_P (t)
+              && CLASSTYPE_IS_TEMPLATE (t))
+       {
+         error ("redeclaration of `%T' as a non-template", t);
+         t = error_mark_node;
+       }
     }
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
@@ -9502,7 +9442,7 @@ xref_tag_from_type (tree old, tree id, int globalize)
   if (id == NULL_TREE)
     id = TYPE_IDENTIFIER (old);
 
-  return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
+  return xref_tag (tag_kind, id, globalize, false);
 }
 
 /* REF is a type (named NAME), for which we have just seen some
@@ -9837,7 +9777,7 @@ finish_enum (tree enumtype)
     {
       underlying_type = integer_types[itk];
       if (TYPE_PRECISION (underlying_type) >= precision
-         && TREE_UNSIGNED (underlying_type) == unsignedp)
+         && TYPE_UNSIGNED (underlying_type) == unsignedp)
        break;
     }
   if (itk == itk_none)
@@ -9874,7 +9814,7 @@ finish_enum (tree enumtype)
   TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
   TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
   TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
-  TREE_UNSIGNED (enumtype) = TREE_UNSIGNED (underlying_type);
+  TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
 
   /* Convert each of the enumerators to the type of the underlying
      type of the enumeration.  */
@@ -9900,7 +9840,7 @@ finish_enum (tree enumtype)
       TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
       TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
-      TREE_UNSIGNED (t) = TREE_UNSIGNED (enumtype);
+      TYPE_UNSIGNED (t) = TYPE_UNSIGNED (enumtype);
     }
 
   /* Finish debugging output for this type.  */
@@ -9996,7 +9936,9 @@ build_enumerator (tree name, tree value, tree enumtype)
     decl = build_decl (CONST_DECL, name, type);
 
   DECL_CONTEXT (decl) = FROB_CONTEXT (context);
-  TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
+  TREE_CONSTANT (decl) = 1;
+  TREE_INVARIANT (decl) = 1;
+  TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
   if (context && context == current_class_type)
@@ -10115,8 +10057,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
          else
            doing_friend = 1;
        }
-
-      last_function_parms = DECL_ARGUMENTS (decl1);
     }
   else
     {
@@ -10167,16 +10107,9 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
       && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
     {
       revert_static_member_fn (decl1);
-      last_function_parms = TREE_CHAIN (last_function_parms);
       ctype = NULL_TREE;
     }
 
-  /* Warn if function was previously implicitly declared
-     (but not if we warned then).  */
-  if (! warn_implicit
-      && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE)
-    cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)));
-
   /* Set up current_class_type, and enter the scope of the class, if
      appropriate.  */
   if (ctype)
@@ -10220,7 +10153,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
 
   /* Save the parm names or decls from this function's declarator
      where store_parm_decls will find them.  */
-  current_function_parms = last_function_parms;
+  current_function_parms = DECL_ARGUMENTS (decl1);
 
   /* Make sure the parameter and return types are reasonable.  When
      you declare a function, these types can be incomplete, but they
@@ -10260,9 +10193,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
   /* Start the statement-tree, start the tree now.  */
   begin_stmt_tree (&DECL_SAVED_TREE (decl1));
 
-  /* Don't double-count statements in templates.  */
-  DECL_ESTIMATED_INSNS (decl1) = 0;
-
   /* Let the user know we're compiling this function.  */
   announce_function (decl1);
 
@@ -10272,8 +10202,9 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
   if (!processing_template_decl && !(flags & SF_PRE_PARSED))
     {
       /* A specialization is not used to guide overload resolution.  */
-      if (!DECL_TEMPLATE_SPECIALIZATION (decl1)
-         && ! DECL_FUNCTION_MEMBER_P (decl1))
+      if (!DECL_FUNCTION_MEMBER_P (decl1)
+         && !(DECL_USE_TEMPLATE (decl1) && 
+              PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl1))))
        {
          tree olddecl = pushdecl (decl1);
 
@@ -10627,8 +10558,8 @@ finish_destructor_body (void)
       be looked up in the scope of the destructor's class and if
       found shall be accessible and unambiguous.  */
       exprstmt = build_op_delete_call
-       (DELETE_EXPR, current_class_ptr, virtual_size,
-        LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
+       (DELETE_EXPR, current_class_ptr, virtual_size, 
+        /*global_p=*/false, NULL_TREE);
 
       if_stmt = begin_if_stmt ();
       finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
@@ -10802,10 +10733,8 @@ finish_function (int flags)
      of curly braces for a function.  */
   my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
 
-  /* Set up the named return value optimization, if we can.  Here, we
-     eliminate the copy from the nrv into the RESULT_DECL and any cleanup
-     for the nrv.  genrtl_start_function and declare_return_variable
-     handle making the nrv and RESULT_DECL share space.  */
+  /* Set up the named return value optimization, if we can.  Candidate
+     variables are selected in check_return_value.  */
   if (current_function_return_value)
     {
       tree r = current_function_return_value;
@@ -10822,16 +10751,9 @@ finish_function (int flags)
          /* Skip the artificial function body block.  */
          && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
              chain_member (r, BLOCK_VARS (outer))))
-       {
-         
-         DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
-         walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
-                                       nullify_returns_r, r);
-       }
-      else
-       /* Clear it so genrtl_start_function and declare_return_variable
-          know we're not optimizing.  */
-       current_function_return_value = NULL_TREE;
+       finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
+
+      current_function_return_value = NULL_TREE;
     }
 
   /* Remember that we were in class scope.  */
@@ -10849,18 +10771,6 @@ finish_function (int flags)
   if (!processing_template_decl)
     save_function_data (fndecl);
 
-  /* If this function calls `setjmp' it cannot be inlined.  When
-     `longjmp' is called it is not guaranteed to restore the value of
-     local variables that have been modified since the call to
-     `setjmp'.  So, if were to inline this function into some caller
-     `c', then when we `longjmp', we might not restore all variables
-     in `c'.  (It might seem, at first blush, that there's no way for
-     this function to modify local variables in `c', but their
-     addresses may have been stored somewhere accessible to this
-     function.)  */
-  if (!processing_template_decl && calls_setjmp_p (fndecl))
-    DECL_UNINLINABLE (fndecl) = 1;
-
   /* Complain if there's just no return statement.  */
   if (warn_return_type
       && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
@@ -10874,8 +10784,21 @@ finish_function (int flags)
       && (DECL_INLINE (fndecl) || processing_template_decl))
     warning ("no return statement in function returning non-void");
 
+  /* Store the end of the function, so that we get good line number
+     info for the epilogue.  */
+  cfun->function_end_locus = input_location;
+
+  /* Genericize before inlining.  */
+  if (!processing_template_decl)
+    {
+      c_genericize (fndecl);
+
+      /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
+      c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+    }
+
   /* We're leaving the context of this function, so zap cfun.  It's still in
-     DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation.  */
+     DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation.  */
   cfun = NULL;
   current_function_decl = NULL;
 
@@ -10947,13 +10870,10 @@ start_method (tree declspecs, tree declarator, tree attrlist)
 
   if (DECL_IN_AGGR_P (fndecl))
     {
-      if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
-       {
-         if (DECL_CONTEXT (fndecl)
-             && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
-           error ("`%D' is already defined in class `%T'", fndecl,
-                     DECL_CONTEXT (fndecl));
-       }
+      if (DECL_CONTEXT (fndecl)
+         && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
+       error ("`%D' is already defined in class `%T'", fndecl,
+              DECL_CONTEXT (fndecl));
       return void_type_node;
     }
 
@@ -11196,8 +11116,6 @@ cxx_push_function_context (struct function * f)
     {
       tree fn = f->decl;
 
-      current_function_is_thunk = DECL_THUNK_P (fn);
-
       if (DECL_SAVED_FUNCTION_DATA (fn))
        {
          /* If we already parsed this function, and we're just expanding it
@@ -11241,7 +11159,6 @@ cp_tree_node_structure (union lang_tree_node * t)
     case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;
     case PTRMEM_CST:           return TS_CP_PTRMEM;
     case BASELINK:              return TS_CP_BASELINK;
-    case WRAPPER:              return TS_CP_WRAPPER;
     default:                   return TS_CP_GENERIC;
     }
 }
@@ -11255,7 +11172,7 @@ build_void_list_node (void)
   return t;
 }
 
-static int
+bool
 cp_missing_noreturn_ok_p (tree decl)
 {
   /* A missing noreturn is ok for the `main' function.  */