OSDN Git Service

PR c++/41090
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 251d0a3..a22cf01 100644 (file)
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "tree-inline.h"
 #include "decl.h"
+#include "intl.h"
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
@@ -520,8 +521,6 @@ poplevel (int keep, int reverse, int functionbody)
   /* The chain of decls was accumulated in reverse order.
      Put it into forward order, just for cleanliness.  */
   tree decls;
-  int tmp = functionbody;
-  int real_functionbody;
   tree subblocks;
   tree block;
   tree decl;
@@ -535,8 +534,8 @@ poplevel (int keep, int reverse, int functionbody)
 
   gcc_assert (current_binding_level->kind != sk_class);
 
-  real_functionbody = (current_binding_level->kind == sk_cleanup
-                      ? ((functionbody = 0), tmp) : functionbody);
+  if (current_binding_level->kind == sk_cleanup)
+    functionbody = 0;
   subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
 
   gcc_assert (!VEC_length(cp_class_binding,
@@ -849,6 +848,7 @@ create_implicit_typedef (tree name, tree type)
      amongst these.  */
   SET_DECL_IMPLICIT_TYPEDEF_P (decl);
   TYPE_NAME (type) = decl;
+  TYPE_STUB_DECL (type) = decl;
 
   return decl;
 }
@@ -935,7 +935,7 @@ decls_match (tree newdecl, tree olddecl)
 #ifdef NO_IMPLICIT_EXTERN_C
       /* A new declaration doesn't match a built-in one unless it
         is also extern "C".  */
-      if (DECL_BUILT_IN (olddecl)
+      if (DECL_IS_BUILTIN (olddecl)
          && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
        return 0;
 #endif
@@ -1034,8 +1034,6 @@ decls_match (tree newdecl, tree olddecl)
 void
 warn_extern_redeclared_static (tree newdecl, tree olddecl)
 {
-  tree name;
-
   if (TREE_CODE (newdecl) == TYPE_DECL
       || TREE_CODE (newdecl) == TEMPLATE_DECL
       || TREE_CODE (newdecl) == CONST_DECL
@@ -1058,7 +1056,6 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
       && DECL_ARTIFICIAL (olddecl))
     return;
 
-  name = DECL_ASSEMBLER_NAME (newdecl);
   permerror (input_location, "%qD was declared %<extern%> and later %<static%>", newdecl);
   permerror (input_location, "previous declaration of %q+D", olddecl);
 }
@@ -1183,9 +1180,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
             bad choice of name.  */
          if (! TREE_PUBLIC (newdecl))
            {
-             warning (OPT_Wshadow, "shadowing %s function %q#D",
-                      DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                      olddecl);
+             warning (OPT_Wshadow, 
+                       DECL_BUILT_IN (olddecl)
+                       ? G_("shadowing built-in function %q#D")
+                       : G_("shadowing library function %q#D"), olddecl);
              /* Discard the old built-in function.  */
              return NULL_TREE;
            }
@@ -1256,9 +1254,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                           olddecl);
                }
              else
-               warning (OPT_Wshadow, "shadowing %s function %q#D",
-                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                        olddecl);
+               warning (OPT_Wshadow, 
+                         DECL_BUILT_IN (olddecl)
+                         ? G_("shadowing built-in function %q#D")
+                         : G_("shadowing library function %q#D"), olddecl);
            }
          else
            /* Discard the old built-in function.  */
@@ -1890,6 +1889,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        }
       DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
+      DECL_ODR_USED (newdecl) |= DECL_ODR_USED (olddecl);
 
       /* If the OLDDECL is an instantiation and/or specialization,
         then the NEWDECL must be too.  But, it may not yet be marked
@@ -1955,7 +1955,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
             should have exited above, returning 0.  */
          gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));
 
-         if (TREE_USED (olddecl))
+         if (DECL_ODR_USED (olddecl))
            /* From [temp.expl.spec]:
 
               If a template, a member template or the member of a class
@@ -2210,7 +2210,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
        return NULL;
       else
-       return "redefinition of %q#D";
+       return G_("redefinition of %q#D");
     }
   else if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2226,7 +2226,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (DECL_NAMESPACE_SCOPE_P (olddecl)
          && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
          && ! decls_match (olddecl, newdecl))
-       return "%qD conflicts with used function";
+       return G_("%qD conflicts with used function");
 
       /* We'll complain about linkage mismatches in
         warn_extern_redeclared_static.  */
@@ -2236,10 +2236,10 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          && DECL_INITIAL (newdecl) != NULL_TREE)
        {
          if (DECL_NAME (olddecl) == NULL_TREE)
-           return "%q#D not declared in class";
+           return G_("%q#D not declared in class");
          else if (!GNU_INLINE_P (olddecl)
                   || GNU_INLINE_P (newdecl))
-           return "redefinition of %q#D";
+           return G_("redefinition of %q#D");
        }
 
       if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl))
@@ -2250,9 +2250,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          if (olda != newa)
            {
              if (newa)
-               return "%q+D redeclared inline with %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline with "
+                         "%<gnu_inline%> attribute");
              else
-               return "%q+D redeclared inline without %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline without "
+                         "%<gnu_inline%> attribute");
            }
        }
 
@@ -2266,7 +2268,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
        {
          if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
              && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
-           return "redefinition of %q#D";
+           return G_("redefinition of %q#D");
          return NULL;
        }
 
@@ -2283,7 +2285,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
        ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
       if (DECL_INITIAL (nt) && DECL_INITIAL (ot)
          && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt)))
-       return "redefinition of %q#D";
+       return G_("redefinition of %q#D");
 
       if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt))
        {
@@ -2293,9 +2295,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          if (olda != newa)
            {
              if (newa)
-               return "%q+D redeclared inline with %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline with "
+                         "%<gnu_inline%> attribute");
              else
-               return "%q+D redeclared inline without %<gnu_inline%> attribute";
+               return G_("%q+D redeclared inline without "
+                         "%<gnu_inline%> attribute");
            }
        }
 
@@ -2310,7 +2314,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
           && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), 
                                        /*is_primary=*/1, /*is_partial=*/0,
                                        /*is_friend_decl=*/2))
-        return "redeclaration of friend %q#D may not have default template arguments";
+        return G_("redeclaration of friend %q#D "
+                 "may not have default template arguments");
 
       return NULL;
     }
@@ -2323,11 +2328,11 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* Only variables can be thread-local, and all declarations must
         agree on this property.  */
       if (DECL_THREAD_LOCAL_P (newdecl))
-       return "thread-local declaration of %q#D follows "
-              "non-thread-local declaration";
+       return G_("thread-local declaration of %q#D follows "
+                 "non-thread-local declaration");
       else
-       return "non-thread-local declaration of %q#D follows "
-              "thread-local declaration";
+       return G_("non-thread-local declaration of %q#D follows "
+                 "thread-local declaration");
     }
   else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
     {
@@ -2341,7 +2346,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
           is invalid.  */
       if ((TREE_CODE (newdecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (newdecl))
          || (TREE_CODE (olddecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (olddecl)))
-       return "redeclaration of %q#D";
+       return G_("redeclaration of %q#D");
       /* If at least one declaration is a reference, there is no
         conflict.  For example:
 
@@ -2352,7 +2357,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
        return NULL;
       /* Reject two definitions.  */
-      return "redefinition of %q#D";
+      return G_("redefinition of %q#D");
     }
   else
     {
@@ -2360,7 +2365,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* Reject two definitions, and reject a definition
         together with an external reference.  */
       if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
-       return "redeclaration of %q#D";
+       return G_("redeclaration of %q#D");
       return NULL;
     }
 }
@@ -3038,11 +3043,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (!dependent_scope_p (context))
     /* We should only set WANT_TYPE when we're a nested typename type.
        Then we can give better diagnostics if we find a non-type.  */
-    t = lookup_field (context, name, 0, /*want_type=*/true);
+    t = lookup_field (context, name, 2, /*want_type=*/true);
   else
     t = NULL_TREE;
 
-  if (!t && dependent_type_p (context)) 
+  if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context))
     return build_typename_type (context, name, fullname, tag_type);
 
   want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR;
@@ -3055,6 +3060,20 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
       return error_mark_node;
     }
   
+  /* Pull out the template from an injected-class-name (or multiple).  */
+  if (want_template)
+    t = maybe_get_template_decl_from_type_decl (t);
+
+  if (TREE_CODE (t) == TREE_LIST)
+    {
+      if (complain & tf_error)
+       {
+         error ("lookup of %qT in %qT is ambiguous", name, context);
+         print_candidates (t);
+       }
+      return error_mark_node;
+    }
+
   if (want_template && !DECL_CLASS_TEMPLATE_P (t))
     {
       if (complain & tf_error)
@@ -3073,6 +3092,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (complain & tf_error)
     perform_or_defer_access_check (TYPE_BINFO (context), t, t);
 
+  /* If we are currently parsing a template and if T is a typedef accessed
+     through CONTEXT then we need to remember and check access of T at
+     template instantiation time.  */
+  add_typedef_to_current_template_for_access_check (t, context, input_location);
+
   if (want_template)
     return lookup_template_class (t, TREE_OPERAND (fullname, 1),
                                  NULL_TREE, context,
@@ -3455,7 +3479,6 @@ cxx_init_decl_processing (void)
     bad_alloc_decl
       = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
     DECL_CONTEXT (bad_alloc_decl) = current_namespace;
-    TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl;
     pop_namespace ();
 
     ptr_ftype_sizetype
@@ -3579,10 +3602,6 @@ builtin_function_1 (tree decl, tree context, bool is_global)
 
   retrofit_lang_decl (decl);
 
-  /* All nesting of C++ functions is lexical; there is never a "static
-     chain" in the sense of GNU C nested functions.  */
-  DECL_NO_STATIC_CHAIN (decl) = 1;
-
   DECL_ARTIFICIAL (decl) = 1;
   SET_OVERLOADED_OPERATOR_CODE (decl, ERROR_MARK);
   SET_DECL_LANGUAGE (decl, lang_c);
@@ -3942,6 +3961,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
               "and functions");
       else if (saw_typedef)
        warning (0, "%<typedef%> was ignored in this declaration");
+      else if (declspecs->specs[(int) ds_constexpr])
+        error ("%<constexpr> cannot be used for type declarations");
     }
 
   return declared_type;
@@ -4053,7 +4074,6 @@ start_decl (const cp_declarator *declarator,
            tree *pushed_scope_p)
 {
   tree decl;
-  tree type;
   tree context;
   bool was_public;
   int flags;
@@ -4076,8 +4096,6 @@ start_decl (const cp_declarator *declarator,
       || decl == error_mark_node)
     return error_mark_node;
 
-  type = TREE_TYPE (decl);
-
   context = DECL_CONTEXT (decl);
 
   if (context)
@@ -4184,6 +4202,9 @@ start_decl (const cp_declarator *declarator,
                error ("duplicate initialization of %qD", decl);
              if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false))
                decl = field;
+              if (declspecs->specs[(int) ds_constexpr]
+                  && !DECL_DECLARED_CONSTEXPR_P (field))
+                error ("%qD declared %<constexpr%> outside its class", field);
            }
        }
       else
@@ -4222,6 +4243,9 @@ start_decl (const cp_declarator *declarator,
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
        permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
+
+      if (!ensure_literal_type_for_constexpr_object (decl))
+        return error_mark_node;
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -4370,13 +4394,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
       return NULL_TREE;
     }
 
-  if (TREE_CODE (init) == CONSTRUCTOR)
-    {
-      error ("ISO C++ forbids use of initializer list to "
-            "initialize reference %qD", decl);
-      return NULL_TREE;
-    }
-
   if (TREE_CODE (init) == TREE_LIST)
     init = build_x_compound_expr_from_list (init, "initializer");
 
@@ -4392,7 +4409,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = initialize_reference (type, init, decl, cleanup);
+  tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
 
   if (tmp == error_mark_node)
     return NULL_TREE;
@@ -4421,6 +4438,9 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
 {
   tree aggr_init, array, arrtype;
   init = perform_implicit_conversion (type, init, tf_warning_or_error);
+  if (error_operand_p (init))
+    return error_mark_node;
+
   aggr_init = TARGET_EXPR_INITIAL (init);
   init = build2 (INIT_EXPR, type, decl, init);
 
@@ -4618,13 +4638,7 @@ maybe_commonize_var (tree decl)
       /* Don't mess with __FUNCTION__.  */
       && ! DECL_ARTIFICIAL (decl)
       && DECL_FUNCTION_SCOPE_P (decl)
-      /* Unfortunately, import_export_decl has not always been called
-        before the function is processed, so we cannot simply check
-        DECL_COMDAT.  */
-      && (DECL_COMDAT (DECL_CONTEXT (decl))
-         || ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl))
-              || DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl)))
-             && TREE_PUBLIC (DECL_CONTEXT (decl)))))
+      && vague_linkage_fn_p (DECL_CONTEXT (decl)))
     {
       if (flag_weak)
        {
@@ -4673,10 +4687,14 @@ check_for_uninitialized_const_var (tree decl)
 {
   tree type = TREE_TYPE (decl);
 
+  if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl)
+      && DECL_INITIAL (decl) == NULL)
+    error ("missing initializer for constexpr %qD", decl);
+
   /* ``Unless explicitly declared extern, a const object does not have
      external linkage and must be initialized. ($8.4; $12.1)'' ARM
      7.1.6 */
-  if (TREE_CODE (decl) == VAR_DECL
+  else if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
       && !TYPE_NEEDS_CONSTRUCTING (type)
@@ -4865,6 +4883,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
 
       field_init = reshape_init_r (TREE_TYPE (field), d,
                                   /*first_initializer_p=*/false);
+      if (field_init == error_mark_node)
+       return error_mark_node;
+
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
 
       /* [dcl.init.aggr]
@@ -4885,7 +4906,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
    a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
    iterator within the CONSTRUCTOR which points to the initializer to process.
    FIRST_INITIALIZER_P is true if this is the first initializer of the
-   CONSTRUCTOR node.  */
+   outermost CONSTRUCTOR node.  */
 
 static tree
 reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
@@ -4913,7 +4934,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
              init = error_mark_node;
            }
          else
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
        }
 
       d->cur++;
@@ -4930,7 +4951,12 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
      initializer is considered for the initialization of the first
      member of the subaggregate.  */
   if (TREE_CODE (init) != CONSTRUCTOR
-      && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))
+      /* But don't try this for the first initializer, since that would be
+        looking through the outermost braces; A a2 = { a1 }; is not a
+        valid aggregate initialization.  */
+      && !first_initializer_p
+      && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
+         || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
     {
       d->cur++;
       return init;
@@ -5152,7 +5178,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
        {
          if (init_len == 0)
            {
-             maybe_warn_cpp0x ("extended initializer lists");
+             maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
              init = build_zero_init (type, NULL_TREE, false);
            }
          else if (init_len != 1)
@@ -5582,23 +5608,27 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (init && TREE_CODE (decl) == FUNCTION_DECL)
     {
+      tree clone;
       if (init == ridpointers[(int)RID_DELETE])
        {
          /* FIXME check this is 1st decl.  */
          DECL_DELETED_FN (decl) = 1;
          DECL_DECLARED_INLINE_P (decl) = 1;
          DECL_INITIAL (decl) = error_mark_node;
+         FOR_EACH_CLONE (clone, decl)
+           {
+             DECL_DELETED_FN (clone) = 1;
+             DECL_DECLARED_INLINE_P (clone) = 1;
+             DECL_INITIAL (clone) = error_mark_node;
+           }
          init = NULL_TREE;
        }
       else if (init == ridpointers[(int)RID_DEFAULT])
        {
-         if (!defaultable_fn_p (decl))
-           {
-             error ("%qD cannot be defaulted", decl);
-             DECL_INITIAL (decl) = NULL_TREE;
-           }
-         else
+         if (defaultable_fn_check (decl))
            DECL_DEFAULTED_FN (decl) = 1;
+         else
+           DECL_INITIAL (decl) = NULL_TREE;
        }
     }
     
@@ -5713,7 +5743,18 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       if (DECL_FUNCTION_SCOPE_P (decl)
          && TREE_STATIC (decl)
          && !DECL_ARTIFICIAL (decl))
-       push_local_name (decl);
+       {
+         push_local_name (decl);
+         if (DECL_CONSTRUCTOR_P (current_function_decl)
+             || DECL_DESTRUCTOR_P (current_function_decl))
+           /* Normally local_decls is populated during GIMPLE lowering,
+              but [cd]tors are never actually compiled directly.  We need
+              to put statics on the list so we can deal with the label
+              address extension.  */
+           cfun->local_decls = tree_cons (NULL_TREE, decl,
+                                          cfun->local_decls);
+       }
+
       /* Convert the initializer to the type of DECL, if we have not
         already initialized DECL.  */
       if (!DECL_INITIALIZED_P (decl)
@@ -5806,6 +5847,15 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
         type.  */
       else if (TREE_CODE (type) == ARRAY_TYPE)
        layout_type (type);
+
+      if (!processing_template_decl
+         && TREE_STATIC (decl)
+         && !at_function_scope_p ()
+         && current_function_decl == NULL)
+       /* So decl is a global variable or a static member of a
+          non local class. Record the types it uses
+          so that we can decide later to emit debug info for them.  */
+       record_types_used_by_current_var_decl (decl);
     }
   else if (TREE_CODE (decl) == FIELD_DECL
           && TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
@@ -6622,6 +6672,7 @@ grokfndecl (tree ctype,
     {
     case sfk_constructor:
     case sfk_copy_constructor:
+    case sfk_move_constructor:
       DECL_CONSTRUCTOR_P (decl) = 1;
       break;
     case sfk_destructor:
@@ -6678,7 +6729,7 @@ grokfndecl (tree ctype,
            }
          gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
                      || TREE_CODE (fns) == OVERLOAD);
-         DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
+         DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
 
          for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
            if (TREE_PURPOSE (t)
@@ -6750,13 +6801,13 @@ grokfndecl (tree ctype,
                || decl_function_context (TYPE_MAIN_DECL (ctype))))
     publicp = 0;
 
-  if (publicp)
+  if (publicp && cxx_dialect == cxx98)
     {
       /* [basic.link]: A name with no linkage (notably, the name of a class
         or enumeration declared in a local scope) shall not be used to
         declare an entity with linkage.
 
-        Only check this for public decls for now.  See core 319, 389.  */
+        DR 757 relaxes this restriction for C++0x.  */
       t = no_linkage_check (TREE_TYPE (decl),
                            /*relaxed_p=*/false);
       if (t)
@@ -6805,9 +6856,6 @@ grokfndecl (tree ctype,
       && !grok_op_properties (decl, /*complain=*/true))
     return NULL_TREE;
 
-  if (ctype && decl_function_context (decl))
-    DECL_NO_STATIC_CHAIN (decl) = 1;
-
   if (funcdef_flag)
     /* Make the init_value nonzero so pushdecl knows this is not
        tentative.  error_mark_node is replaced later with the BLOCK.  */
@@ -7022,21 +7070,31 @@ grokvardecl (tree type,
   if (declspecs->specs[(int)ds_thread])
     DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
 
+  /* If the type of the decl has no linkage, make sure that we'll
+     notice that in mark_used.  */
+  if (cxx_dialect > cxx98
+      && decl_linkage (decl) != lk_none
+      && DECL_LANG_SPECIFIC (decl) == NULL
+      && !DECL_EXTERN_C_P (decl)
+      && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+    retrofit_lang_decl (decl);
+
   if (TREE_PUBLIC (decl))
     {
       /* [basic.link]: A name with no linkage (notably, the name of a class
         or enumeration declared in a local scope) shall not be used to
         declare an entity with linkage.
 
-        Only check this for public decls for now.  */
-      tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
+        DR 757 relaxes this restriction for C++0x.  */
+      tree t = (cxx_dialect > cxx98 ? NULL_TREE
+               : no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false));
       if (t)
        {
          if (TYPE_ANONYMOUS_P (t))
            {
              if (DECL_EXTERN_C_P (decl))
                /* Allow this; it's pretty common in C.  */
-                 ;
+               ;
              else
                {
                  /* DRs 132, 319 and 389 seem to indicate types with
@@ -7112,10 +7170,14 @@ build_ptrmemfunc_type (tree type)
   /* If this is not the unqualified form of this pointer-to-member
      type, set the TYPE_MAIN_VARIANT for this type to be the
      unqualified type.  Since they are actually RECORD_TYPEs that are
-     not variants of each other, we must do this manually.  */
+     not variants of each other, we must do this manually.
+     As we just built a new type there is no need to do yet another copy.  */
   if (cp_type_quals (type) != TYPE_UNQUALIFIED)
     {
-      t = build_qualified_type (t, cp_type_quals (type));
+      int type_quals = cp_type_quals (type);
+      TYPE_READONLY (t) = (type_quals & TYPE_QUAL_CONST) != 0;
+      TYPE_VOLATILE (t) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
+      TYPE_RESTRICT (t) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
       TYPE_MAIN_VARIANT (t) = unqualified_variant;
       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
       TYPE_NEXT_VARIANT (unqualified_variant) = t;
@@ -7141,16 +7203,9 @@ build_ptrmem_type (tree class_type, tree member_type)
 {
   if (TREE_CODE (member_type) == METHOD_TYPE)
     {
-      tree arg_types;
-
-      arg_types = TYPE_ARG_TYPES (member_type);
-      class_type = (cp_build_qualified_type
-                   (class_type,
-                    cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
-      member_type
-       = build_method_type_directly (class_type,
-                                     TREE_TYPE (member_type),
-                                     TREE_CHAIN (arg_types));
+      tree arg_types = TYPE_ARG_TYPES (member_type);
+      cp_cv_quals quals = cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)));
+      member_type = build_memfn_type (member_type, class_type, quals);
       return build_ptrmemfunc_type (build_pointer_type (member_type));
     }
   else
@@ -7233,11 +7288,8 @@ compute_array_index_type (tree name, tree size)
         structural equality checks.  */
       itype = build_index_type (build_min (MINUS_EXPR, sizetype,
                                           size, integer_one_node));
-      if (!TREE_SIDE_EFFECTS (size))
-       {
-         TYPE_DEPENDENT_P (itype) = 1;
-         TYPE_DEPENDENT_P_VALID (itype) = 1;
-       }
+      TYPE_DEPENDENT_P (itype) = 1;
+      TYPE_DEPENDENT_P_VALID (itype) = 1;
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
       return itype;
     }
@@ -7386,47 +7438,45 @@ static tree
 create_array_type_for_decl (tree name, tree type, tree size)
 {
   tree itype = NULL_TREE;
-  const char* error_msg;
 
   /* If things have already gone awry, bail now.  */
   if (type == error_mark_node || size == error_mark_node)
     return error_mark_node;
 
-  /* Assume that everything will go OK.  */
-  error_msg = NULL;
-
-  /* There are some types which cannot be array elements.  */
+  /* If there are some types which cannot be array elements,
+     issue an error-message and return.  */
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
-      error_msg = "array of void";
-      break;
+      if (name)
+        error ("declaration of %qD as array of void", name);
+      else
+        error ("creating array of void");
+      return error_mark_node;
 
     case FUNCTION_TYPE:
-      error_msg = "array of functions";
-      break;
+      if (name)
+        error ("declaration of %qD as array of functions", name);
+      else
+        error ("creating array of functions");
+      return error_mark_node;
 
     case REFERENCE_TYPE:
-      error_msg = "array of references";
-      break;
+      if (name)
+        error ("declaration of %qD as array of references", name);
+      else
+        error ("creating array of references");
+      return error_mark_node;
 
     case METHOD_TYPE:
-      error_msg = "array of function members";
-      break;
-
-    default:
-      break;
-    }
-
-  /* If something went wrong, issue an error-message and return.  */
-  if (error_msg)
-    {
       if (name)
-       error ("declaration of %qD as %s", name, error_msg);
+        error ("declaration of %qD as array of function members", name);
       else
-       error ("creating %s", error_msg);
-
+        error ("creating array of function members");
       return error_mark_node;
+
+    default:
+      break;
     }
 
   /* [dcl.array]
@@ -7552,11 +7602,13 @@ check_var_type (tree identifier, tree type)
       try to parse.
      PARM for a parameter declaration (either within a function prototype
       or before a function body).  Make a PARM_DECL, or return void_type_node.
+     TPARM for a template parameter declaration.
      CATCHPARM for a parameter declaration before a catch clause.
      TYPENAME if for a typename (in a cast or sizeof).
       Don't make a DECL node; just return the ..._TYPE node.
      FIELD for a struct or union field; make a FIELD_DECL.
      BITFIELD for a field with specified width.
+
    INITIALIZED is as for start_decl.
 
    ATTRLIST is a pointer to the list of attributes, which may be NULL
@@ -7639,8 +7691,9 @@ grokdeclarator (const cp_declarator *declarator,
   bool unsigned_p, signed_p, short_p, long_p, thread_p;
   bool type_was_error_mark_node = false;
   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
-  bool set_no_warning = false;
   bool template_type_arg = false;
+  bool template_parm_flag = false;
+  bool constexpr_p = declspecs->specs[(int) ds_constexpr];
   const char *errmsg;
 
   signed_p = declspecs->specs[(int)ds_signed];
@@ -7658,6 +7711,8 @@ grokdeclarator (const cp_declarator *declarator,
     bitfield = 1, decl_context = FIELD;
   else if (decl_context == TEMPLATE_TYPE_ARG)
     template_type_arg = true, decl_context = TYPENAME;
+  else if (decl_context == TPARM)
+    template_parm_flag = true, decl_context = PARM;
 
   if (initialized > 1)
     funcdef_flag = true;
@@ -8085,6 +8140,17 @@ grokdeclarator (const cp_declarator *declarator,
   type_quals = TYPE_UNQUALIFIED;
   if (declspecs->specs[(int)ds_const])
     type_quals |= TYPE_QUAL_CONST;
+  /* A `constexpr' specifier used in an object declaration declares
+     the object as `const'.  */
+  if (constexpr_p)
+    {
+      if (innermost_code == cdk_function)
+        ;
+      else if (declspecs->specs[(int)ds_const] != 0)
+        error ("both %<const%> and %<constexpr%> cannot be used here");
+      else
+        type_quals |= TYPE_QUAL_CONST;
+    }
   if (declspecs->specs[(int)ds_volatile])
     type_quals |= TYPE_QUAL_VOLATILE;
   if (declspecs->specs[(int)ds_restrict])
@@ -8099,7 +8165,7 @@ grokdeclarator (const cp_declarator *declarator,
       /* This was an error in C++98 (cv-qualifiers cannot be added to
         a function type), but DR 295 makes the code well-formed by
         dropping the extra qualifiers. */
-      if (pedantic)
+      if (pedantic && cxx_dialect == cxx98)
        {
          tree bad_type = build_qualified_type (type, type_quals);
          pedwarn (input_location, OPT_pedantic, 
@@ -8146,6 +8212,11 @@ grokdeclarator (const cp_declarator *declarator,
          error ("typedef declaration invalid in parameter declaration");
          return error_mark_node;
        }
+      else if (template_parm_flag && storage_class != sc_none)
+       {
+         error ("storage class specified for template parameter %qs", name);
+         return error_mark_node;
+       }
       else if (storage_class == sc_static
               || storage_class == sc_extern
               || thread_p)
@@ -8156,6 +8227,14 @@ grokdeclarator (const cp_declarator *declarator,
          error ("parameter declared %<auto%>");
          type = error_mark_node;
        }
+
+      /* Function parameters cannot be constexpr.  If we saw one, moan
+         and pretend it wasn't there.  */
+      if (constexpr_p)
+        {
+          error ("a parameter cannot be declared %<constexpr%>");
+          constexpr_p = 0;
+        }
     }
 
   /* Give error if `virtual' is used outside of class declaration.  */
@@ -8319,7 +8398,6 @@ grokdeclarator (const cp_declarator *declarator,
                /* We now know that the TYPE_QUALS don't apply to the
                   decl, but to its return type.  */
                type_quals = TYPE_UNQUALIFIED;
-               set_no_warning = true;
              }
            errmsg = targetm.invalid_return_type (type);
            if (errmsg)
@@ -8459,11 +8537,26 @@ grokdeclarator (const cp_declarator *declarator,
              {
                if (explicitp == 1)
                  {
-                   maybe_warn_cpp0x ("explicit conversion operators");
+                   maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
                    explicitp = 2;
                  }
              }
 
+            /* It is not allowed to use `constexpr' in a function
+               declaration that is not a definition.
+               That is too strict, though.  */
+            if (constexpr_p && !funcdef_flag)
+              {
+                error ("the %<constexpr%> specifier cannot be used in "
+                       "a function declaration that is not a definition");
+                constexpr_p = false;
+              }
+
+            /* A constexpr non-static member function is implicitly const.  */
+            if (constexpr_p && decl_context == FIELD && staticp == 0
+                && sfk != sfk_constructor && sfk != sfk_destructor)
+              memfn_quals |= TYPE_QUAL_CONST;
+
            arg_types = grokparms (declarator->u.function.parameters,
                                   &parms);
 
@@ -8533,8 +8626,9 @@ grokdeclarator (const cp_declarator *declarator,
 
          if (TREE_CODE (type) == FUNCTION_TYPE
              && cp_type_quals (type) != TYPE_UNQUALIFIED)
-           error ("cannot declare %s to qualified function type %qT",
-                  declarator->kind == cdk_reference ? "reference" : "pointer",
+            error (declarator->kind == cdk_reference
+                   ? G_("cannot declare reference to qualified function type %qT")
+                   : G_("cannot declare pointer to qualified function type %qT"),
                   type);
 
          if (declarator->kind == cdk_reference)
@@ -8708,6 +8802,12 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
 
+          /* It is not permitted to define a member function outside ist
+             membership class as `constexpr'.  */
+          if (constexpr_p)
+            error ("a constexpr function cannot be defined "
+                   "outside of its class");
+
          if (TREE_CODE (sname) == IDENTIFIER_NODE
              && NEW_DELETE_OPNAME_P (sname))
            /* Overloaded operator new and operator delete
@@ -8895,6 +8995,10 @@ grokdeclarator (const cp_declarator *declarator,
            DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
              = TYPE_IDENTIFIER (type);
 
+         /* Adjust linkage now that we aren't anonymous anymore.  */
+         set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+         determine_visibility (TYPE_MAIN_DECL (type));
+
          /* FIXME remangle member functions; member functions of a
             type with external linkage have external linkage.  */
        }
@@ -8928,7 +9032,9 @@ grokdeclarator (const cp_declarator *declarator,
       tree decls = NULL_TREE;
       tree args;
 
-      for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
+      for (args = TYPE_ARG_TYPES (type);
+          args && args != void_list_node;
+          args = TREE_CHAIN (args))
        {
          tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
 
@@ -8956,6 +9062,7 @@ grokdeclarator (const cp_declarator *declarator,
          /* The qualifiers on the function type become the qualifiers on
             the non-static member function. */
          memfn_quals |= cp_type_quals (type);
+         type_quals = TYPE_UNQUALIFIED;
        }
     }
 
@@ -9171,6 +9278,8 @@ grokdeclarator (const cp_declarator *declarator,
                           uqname, ctype);
                    return error_mark_node;
                  }
+                if (constexpr_p)
+                  error ("a destructor cannot be %<constexpr%>");
              }
            else if (sfk == sfk_constructor && friendp)
              {
@@ -9191,7 +9300,8 @@ grokdeclarator (const cp_declarator *declarator,
                               parms,
                               unqualified_id,
                               virtualp, flags, memfn_quals, raises,
-                              friendp ? -1 : 0, friendp, publicp, inlinep,
+                              friendp ? -1 : 0, friendp, publicp,
+                               inlinep || constexpr_p,
                               sfk,
                               funcdef_flag, template_count, in_namespace,
                               attrlist, declarator->id_loc);
@@ -9280,6 +9390,7 @@ grokdeclarator (const cp_declarator *declarator,
                      return error_mark_node;
                  }
 
+                DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
                decl = do_friend (ctype, unqualified_id, decl,
                                  *attrlist, flags,
                                  funcdef_flag);
@@ -9344,6 +9455,9 @@ grokdeclarator (const cp_declarator *declarator,
              }
            else
              {
+                if (constexpr_p)
+                  error ("non-static data member %qE declared %<constexpr%>",
+                         unqualified_id);
                decl = build_decl (input_location,
                                   FIELD_DECL, unqualified_id, type);
                DECL_NONADDRESSABLE_P (decl) = bitfield;
@@ -9438,7 +9552,7 @@ grokdeclarator (const cp_declarator *declarator,
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, memfn_quals, raises,
                           1, friendp,
-                          publicp, inlinep, sfk, funcdef_flag,
+                          publicp, inlinep || constexpr_p, sfk, funcdef_flag,
                           template_count, in_namespace, attrlist,
                           declarator->id_loc);
        if (decl == NULL_TREE)
@@ -9535,15 +9649,16 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
+    /* Don't forget constexprness.  */
+    if (VAR_OR_FUNCTION_DECL_P (decl))
+      DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
+
     /* Record constancy and volatility on the DECL itself .  There's
        no need to do this when processing a template; we'll do this
        for the instantiated declaration based on the type of DECL.  */
     if (!processing_template_decl)
       cp_apply_type_quals_to_decl (type_quals, decl);
 
-    if (set_no_warning)
-        TREE_NO_WARNING (decl) = 1;
-
     return decl;
   }
 }
@@ -9685,6 +9800,10 @@ type_is_deprecated (tree type)
       && TREE_DEPRECATED (TYPE_NAME (type)))
     return type;
 
+  /* Do warn about using typedefs to a deprecated class.  */
+  if (TAGGED_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
+    return type_is_deprecated (TYPE_MAIN_VARIANT (type));
+
   code = TREE_CODE (type);
 
   if (code == POINTER_TYPE || code == REFERENCE_TYPE
@@ -9801,9 +9920,12 @@ grokparms (tree parmlist, tree *parms)
                  t = TREE_TYPE (t);
                }
              if (TREE_CODE (t) == ARRAY_TYPE)
-               error ("parameter %qD includes %s to array of unknown "
-                      "bound %qT",
-                      decl, ptr ? "pointer" : "reference", t);
+               error (ptr
+                       ? G_("parameter %qD includes pointer to array of "
+                            "unknown bound %qT")
+                       : G_("parameter %qD includes reference to array of "
+                            "unknown bound %qT"),
+                       decl, t);
            }
 
          if (any_error)
@@ -9842,9 +9964,9 @@ grokparms (tree parmlist, tree *parms)
    0  if D is not a copy constructor or copy assignment
       operator.
    1  if D is a copy constructor or copy assignment operator whose
-      first parameter is a reference to const qualified T.
-   2  if D is a copy constructor or copy assignment operator whose
       first parameter is a reference to non-const qualified T.
+   2  if D is a copy constructor or copy assignment operator whose
+      first parameter is a reference to const qualified T.
 
    This function can be used as a predicate. Positive values indicate
    a copy constructor and nonzero values indicate a copy assignment
@@ -9979,7 +10101,7 @@ grok_special_member_properties (tree decl)
             are no other parameters or else all other parameters have
             default arguments.  */
          TYPE_HAS_INIT_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
          if (ctor > 1)
            TYPE_HAS_CONST_INIT_REF (class_type) = 1;
@@ -9987,7 +10109,7 @@ grok_special_member_properties (tree decl)
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
        {
          TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
-         if (TREE_CODE (decl) == TEMPLATE_DECL || !DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
        }
       else if (is_list_ctor (decl))
@@ -10006,7 +10128,7 @@ grok_special_member_properties (tree decl)
       if (assop)
        {
          TYPE_HAS_ASSIGN_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (user_provided_p (decl))
            TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
          if (assop != 1)
            TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
@@ -10192,8 +10314,13 @@ grok_op_properties (tree decl, bool complain)
              || operator_code == ARRAY_REF
              || operator_code == NOP_EXPR)
            {
-             error ("%qD must be a nonstatic member function", decl);
-             return false;
+             if (class_type && LAMBDA_TYPE_P (class_type))
+               /* Lambdas can have static op() and conv ops.  */;
+             else
+               {
+                 error ("%qD must be a nonstatic member function", decl);
+                 return false;
+               }
            }
          else
            {
@@ -10245,28 +10372,38 @@ grok_op_properties (tree decl, bool complain)
        {
          tree t = TREE_TYPE (name);
          int ref = (TREE_CODE (t) == REFERENCE_TYPE);
-         const char *what = 0;
 
          if (ref)
            t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
          if (TREE_CODE (t) == VOID_TYPE)
-           what = "void";
+            warning (OPT_Wconversion,
+                     ref
+                     ? G_("conversion to a reference to void "
+                          "will never use a type conversion operator")
+                     : G_("conversion to void "
+                          "will never use a type conversion operator"));
          else if (class_type)
            {
              if (t == class_type)
-               what = "the same type";
+                warning (OPT_Wconversion,
+                     ref
+                     ? G_("conversion to a reference to the same type "
+                          "will never use a type conversion operator")
+                     : G_("conversion to the same type "
+                          "will never use a type conversion operator"));               
              /* Don't force t to be complete here.  */
              else if (MAYBE_CLASS_TYPE_P (t)
                       && COMPLETE_TYPE_P (t)
                       && DERIVED_FROM_P (t, class_type))
-               what = "a base class";
+                 warning (OPT_Wconversion,
+                          ref
+                          ? G_("conversion to a reference to a base class "
+                               "will never use a type conversion operator")
+                          : G_("conversion to a base class "
+                               "will never use a type conversion operator"));          
            }
 
-         if (what)
-           warning (OPT_Wconversion, "conversion to %s%s will never use a type "
-                    "conversion operator",
-                    ref ? "a reference to " : "", what);
        }
 
       if (operator_code == COND_EXPR)
@@ -10501,6 +10638,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
      elaborated type specifier is the implicit typedef created when
      the type is declared.  */
   else if (!DECL_IMPLICIT_TYPEDEF_P (decl)
+          && !DECL_SELF_REFERENCE_P (decl)
           && tag_code != typename_type)
     {
       error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
@@ -11034,7 +11172,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
       if (enumtype == error_mark_node)
        name = make_anon_name ();
 
-      enumtype = make_node (ENUMERAL_TYPE);
+      enumtype = cxx_make_type (ENUMERAL_TYPE);
       enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
@@ -11225,7 +11363,8 @@ finish_enum (tree enumtype)
       /* Set the underlying type of the enumeration type to the
          computed enumeration type, restricted to the enumerator
          values. */
-      ENUM_UNDERLYING_TYPE (enumtype) = copy_node (underlying_type);
+      ENUM_UNDERLYING_TYPE (enumtype)
+       = build_distinct_type_copy (underlying_type);
       set_min_and_max_values_for_integral_type 
         (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
     }
@@ -11465,7 +11604,7 @@ lookup_enumerator (tree enumtype, tree name)
 }
 
 \f
-/* We're defining DECL.  Make sure that it's type is OK.  */
+/* We're defining DECL.  Make sure that its type is OK.  */
 
 static void
 check_function_type (tree decl, tree current_function_parms)
@@ -11476,6 +11615,10 @@ check_function_type (tree decl, tree current_function_parms)
   /* In a function definition, arg types must be complete.  */
   require_complete_types_for_parms (current_function_parms);
 
+  /* constexpr functions must have literal argument types and
+     literal return type.  */
+  validate_constexpr_fundecl (decl);
+
   if (dependent_type_p (return_type))
     return;
   if (!COMPLETE_OR_VOID_TYPE_P (return_type)
@@ -11495,9 +11638,12 @@ check_function_type (tree decl, tree current_function_parms)
                                             TREE_CHAIN (args));
       else
        fntype = build_function_type (void_type_node, args);
-      TREE_TYPE (decl)
+      fntype
        = build_exception_variant (fntype,
                                   TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)));
+      fntype = (cp_build_type_attribute_variant
+               (fntype, TYPE_ATTRIBUTES (TREE_TYPE (decl))));
+      TREE_TYPE (decl) = fntype;
     }
   else
     abstract_virtuals_error (decl, TREE_TYPE (fntype));
@@ -11782,7 +11928,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE);
 
       cp_function_chain->x_current_class_ref
-       = cp_build_indirect_ref (t, NULL, tf_warning_or_error);
+       = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
       cp_function_chain->x_current_class_ptr = t;
 
       /* Constructors and destructors need to know whether they're "in
@@ -12404,6 +12550,8 @@ finish_function (int flags)
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we abort or throw.  */
       && !current_function_returns_abnormally
+      /* Don't complain if we are declared noreturn.  */
+      && !TREE_THIS_VOLATILE (fndecl)
       && !DECL_NAME (DECL_RESULT (fndecl))
       && !TREE_NO_WARNING (fndecl)
       /* Structor return values (if any) are set by the compiler.  */
@@ -12423,7 +12571,7 @@ finish_function (int flags)
   if (!processing_template_decl)
     {
       struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
-      invoke_plugin_callbacks (PLUGIN_CXX_CP_PRE_GENERICIZE, fndecl);
+      invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
       cp_genericize (fndecl);
       /* Clear out the bits we don't need.  */
       f->x_current_class_ptr = NULL;
@@ -12499,8 +12647,8 @@ finish_function (int flags)
    CHANGES TO CODE IN `grokfield'.  */
 
 tree
-start_method (cp_decl_specifier_seq *declspecs,
-             const cp_declarator *declarator, tree attrlist)
+grokmethod (cp_decl_specifier_seq *declspecs,
+           const cp_declarator *declarator, tree attrlist)
 {
   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
                                &attrlist);
@@ -12554,62 +12702,9 @@ start_method (cp_decl_specifier_seq *declspecs,
 
   cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);
 
-  /* Make a place for the parms.  */
-  begin_scope (sk_function_parms, fndecl);
-
   DECL_IN_AGGR_P (fndecl) = 1;
   return fndecl;
 }
-
-/* Go through the motions of finishing a function definition.
-   We don't compile this method until after the whole class has
-   been processed.
-
-   FINISH_METHOD must return something that looks as though it
-   came from GROKFIELD (since we are defining a method, after all).
-
-   This is called after parsing the body of the function definition.
-   STMTS is the chain of statements that makes up the function body.
-
-   DECL is the ..._DECL that `start_method' provided.  */
-
-tree
-finish_method (tree decl)
-{
-  tree fndecl = decl;
-  tree old_initial;
-
-  tree link;
-
-  if (decl == void_type_node)
-    return decl;
-
-  old_initial = DECL_INITIAL (fndecl);
-
-  /* Undo the level for the parms (from start_method).
-     This is like poplevel, but it causes nothing to be
-     saved.  Saving information here confuses symbol-table
-     output routines.  Besides, this information will
-     be correctly output when this method is actually
-     compiled.  */
-
-  /* Clear out the meanings of the local variables of this level;
-     also record in each decl which block it belongs to.  */
-
-  for (link = current_binding_level->names; link; link = TREE_CHAIN (link))
-    {
-      if (DECL_NAME (link) != NULL_TREE)
-       pop_binding (DECL_NAME (link), link);
-      gcc_assert (TREE_CODE (link) != FUNCTION_DECL);
-      DECL_CONTEXT (link) = NULL_TREE;
-    }
-
-  poplevel (0, 0, 0);
-
-  DECL_INITIAL (fndecl) = old_initial;
-
-  return decl;
-}
 \f
 
 /* VAR is a VAR_DECL.  If its type is incomplete, remember VAR so that
@@ -12750,26 +12845,47 @@ finish_stmt (void)
 {
 }
 
+/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a
+   FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to
+   METHOD_TYPE or FUNCTION_TYPE, or pointer to member function.  */
+
+tree
+static_fn_type (tree memfntype)
+{
+  tree fntype;
+  tree args;
+  int quals;
+
+  if (TYPE_PTRMEMFUNC_P (memfntype))
+    memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype);
+  if (POINTER_TYPE_P (memfntype)
+      || TREE_CODE (memfntype) == FUNCTION_DECL)
+    memfntype = TREE_TYPE (memfntype);
+  if (TREE_CODE (memfntype) == FUNCTION_TYPE)
+    return memfntype;
+  gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
+  args = TYPE_ARG_TYPES (memfntype);
+  fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
+  quals = cp_type_quals (TREE_TYPE (TREE_VALUE (args)));
+  fntype = build_qualified_type (fntype, quals);
+  fntype = (cp_build_type_attribute_variant
+           (fntype, TYPE_ATTRIBUTES (memfntype)));
+  fntype = (build_exception_variant
+           (fntype, TYPE_RAISES_EXCEPTIONS (memfntype)));
+  return fntype;
+}
+
 /* DECL was originally constructed as a non-static member function,
    but turned out to be static.  Update it accordingly.  */
 
 void
 revert_static_member_fn (tree decl)
 {
-  tree tmp;
-  tree function = TREE_TYPE (decl);
-  tree args = TYPE_ARG_TYPES (function);
+  TREE_TYPE (decl) = static_fn_type (decl);
 
-  if (cp_type_quals (TREE_TYPE (TREE_VALUE (args)))
-      != TYPE_UNQUALIFIED)
+  if (cp_type_quals (TREE_TYPE (decl)) != TYPE_UNQUALIFIED)
     error ("static member function %q#D declared with type qualifiers", decl);
 
-  args = TREE_CHAIN (args);
-  tmp = build_function_type (TREE_TYPE (function), args);
-  tmp = build_qualified_type (tmp, cp_type_quals (function));
-  tmp = build_exception_variant (tmp,
-                                TYPE_RAISES_EXCEPTIONS (function));
-  TREE_TYPE (decl) = tmp;
   if (DECL_ARGUMENTS (decl))
     DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl));
   DECL_STATIC_FUNCTION_P (decl) = 1;
@@ -12792,6 +12908,8 @@ cp_tree_node_structure (union lang_tree_node * t)
     case STATIC_ASSERT:                return TS_CP_STATIC_ASSERT;
     case ARGUMENT_PACK_SELECT:  return TS_CP_ARGUMENT_PACK_SELECT;
     case TRAIT_EXPR:           return TS_CP_TRAIT_EXPR;
+    case LAMBDA_EXPR:          return TS_CP_LAMBDA_EXPR;
+    case TEMPLATE_INFO:                return TS_CP_TEMPLATE_INFO;
     default:                   return TS_CP_GENERIC;
     }
 }