OSDN Git Service

In gcc/:
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 0f7b5d7..5b4dfb7 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -33,28 +33,37 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
-#include "expr.h"
 #include "flags.h"
 #include "cp-tree.h"
+#include "tree-iterator.h"
 #include "tree-inline.h"
 #include "decl.h"
+#include "intl.h"
 #include "output.h"
-#include "except.h"
 #include "toplev.h"
 #include "hashtab.h"
 #include "tm_p.h"
 #include "target.h"
-#include "c-common.h"
-#include "c-pragma.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "c-family/c-pragma.h"
 #include "diagnostic.h"
 #include "intl.h"
 #include "debug.h"
 #include "timevar.h"
-#include "tree-flow.h"
 #include "pointer-set.h"
+#include "splay-tree.h"
+#include "plugin.h"
+
+/* Possible cases of bad specifiers type used by bad_specifiers. */
+enum bad_spec_place {
+  BSP_VAR,    /* variable */
+  BSP_PARM,   /* parameter */
+  BSP_TYPE,   /* type */
+  BSP_FIELD   /* field */
+};
 
-static tree grokparms (cp_parameter_declarator *, tree *);
+static tree grokparms (tree parmlist, tree *);
 static const char *redeclaration_error_message (tree, tree);
 
 static int decl_jump_unsafe (tree);
@@ -69,7 +78,7 @@ static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
 static tree build_library_fn_1 (tree, enum tree_code, tree);
 static int member_function_or_else (tree, tree, enum overload_flags);
-static void bad_specifiers (tree, const char *, int, int, int, int,
+static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
                            int);
 static void check_for_uninitialized_const_var (tree);
 static hashval_t typename_hash (const void *);
@@ -81,20 +90,21 @@ static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
 static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
 static void maybe_deduce_size_from_array_init (tree, tree);
 static void layout_var_decl (tree);
-static void maybe_commonize_var (tree);
 static tree check_initializer (tree, tree, int, tree *);
 static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
 static void save_function_data (tree);
+static void copy_type_enum (tree , tree);
 static void check_function_type (tree, tree);
 static void finish_constructor_body (void);
 static void begin_destructor_body (void);
 static void finish_destructor_body (void);
+static void record_key_method_defined (tree);
 static tree create_array_type_for_decl (tree, tree, tree);
 static tree get_atexit_node (void);
 static tree get_dso_handle_node (void);
 static tree start_cleanup_fn (void);
 static void end_cleanup_fn (void);
-static tree cp_make_fname_decl (tree, int);
+static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
 static tree check_special_function_return_type
        (special_function_kind, tree, tree);
@@ -103,7 +113,6 @@ static tree build_cp_library_fn (tree, enum tree_code, tree);
 static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
-static tree next_initializable_field (tree);
 
 /* The following symbols are subsumed in the cp_global_trees array, and
    listed here individually for documentation purposes.
@@ -162,15 +171,14 @@ tree static_aggregates;
 
 /* -- end of C++ */
 
-/* A node for the integer constants 2, and 3.  */
+/* A node for the integer constant 2.  */
 
-tree integer_two_node, integer_three_node;
+tree integer_two_node;
 
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
-struct named_label_use_entry GTY(())
-{
+struct GTY(()) named_label_use_entry {
   struct named_label_use_entry *next;
   /* The binding level to which this entry is *currently* attached.
      This is initially the binding level in which the goto appeared,
@@ -192,8 +200,7 @@ struct named_label_use_entry GTY(())
    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.  */
 
-struct named_label_entry GTY(())
-{
+struct GTY(()) named_label_entry {
   /* The decl itself.  */
   tree label_decl;
 
@@ -205,9 +212,9 @@ struct named_label_entry GTY(())
      defined, or the inner scope popped.  These are the decls that will
      be skipped when jumping to the label.  */
   tree names_in_scope;
-  /* A tree list of all decls from all binding levels that would be
+  /* A vector of all decls from all binding levels that would be
      crossed by a backward branch to the label.  */
-  tree bad_decls;
+  VEC(tree,gc) *bad_decls;
 
   /* A list of uses of the label, before the label is defined.  */
   struct named_label_use_entry *uses;
@@ -227,24 +234,30 @@ struct named_label_entry GTY(())
    function, two inside the body of a function in a local class, etc.)  */
 int function_depth;
 
+/* To avoid unwanted recursion, finish_function defers all mark_used calls
+   encountered during its execution until it finishes.  */
+bool defer_mark_used_calls;
+VEC(tree, gc) *deferred_mark_used_calls;
+
 /* States indicating how grokdeclarator() should handle declspecs marked
    with __attribute__((deprecated)).  An object declared as
    __attribute__((deprecated)) suppresses warnings of uses of other
    deprecated items.  */
+enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
 
-enum deprecated_states {
-  DEPRECATED_NORMAL,
-  DEPRECATED_SUPPRESS
-};
+\f
+/* A list of VAR_DECLs whose type was incomplete at the time the
+   variable was declared.  */
 
-static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+typedef struct GTY(()) incomplete_var_d {
+  tree decl;
+  tree incomplete_type;
+} incomplete_var;
 
-\f
-/* A TREE_LIST of VAR_DECLs.  The TREE_PURPOSE is a RECORD_TYPE or
-   UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type.  At the
-   time the VAR_DECL was declared, the type was incomplete.  */
+DEF_VEC_O(incomplete_var);
+DEF_VEC_ALLOC_O(incomplete_var,gc);
 
-static GTY(()) tree incomplete_vars;
+static GTY(()) VEC(incomplete_var,gc) *incomplete_vars;
 \f
 /* Returns the kind of template specialization we are currently
    processing, given that it's declaration contained N_CLASS_SCOPES
@@ -382,7 +395,7 @@ pop_labels_1 (void **slot, void *data)
 
   /* Put the labels into the "variables" of the top-level block,
      so debugger can see them.  */
-  TREE_CHAIN (ent->label_decl) = BLOCK_VARS (block);
+  DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
   BLOCK_VARS (block) = ent->label_decl;
 
   htab_clear_slot (named_labels, slot);
@@ -463,9 +476,13 @@ poplevel_named_label_1 (void **slot, void *data)
     {
       tree decl;
 
-      for (decl = ent->names_in_scope; decl; decl = TREE_CHAIN (decl))
+      /* ENT->NAMES_IN_SCOPE may contain a mixture of DECLs and
+        TREE_LISTs representing OVERLOADs, so be careful.  */
+      for (decl = ent->names_in_scope; decl; decl = (DECL_P (decl)
+                                                    ? DECL_CHAIN (decl)
+                                                    : TREE_CHAIN (decl)))
        if (decl_jump_unsafe (decl))
-         ent->bad_decls = tree_cons (NULL, decl, ent->bad_decls);
+         VEC_safe_push (tree, gc, ent->bad_decls, decl);
 
       ent->binding_level = obl;
       ent->names_in_scope = obl->names;
@@ -501,6 +518,10 @@ poplevel_named_label_1 (void **slot, void *data)
   return 1;
 }
 
+/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
+   when errors were reported, except for -Werror-unused-but-set-*.  */
+static int unused_but_set_errorcount;
+
 /* Exit a binding level.
    Pop the level off, and restore the state of the identifier-decl mappings
    that were in effect when this level was entered.
@@ -523,13 +544,13 @@ 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;
   int leaving_for_scope;
   scope_kind kind;
+  unsigned ix;
+  cp_label_binding *label_bind;
 
   timevar_push (TV_NAME_LOOKUP);
  restart:
@@ -538,8 +559,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,
@@ -594,14 +615,28 @@ poplevel (int keep, int reverse, int functionbody)
     = current_binding_level->kind == sk_for && flag_new_for_scope == 1;
 
   /* Before we remove the declarations first check for unused variables.  */
-  if (warn_unused_variable
+  if ((warn_unused_variable || warn_unused_but_set_variable)
       && !processing_template_decl)
     for (decl = getdecls (); decl; decl = TREE_CHAIN (decl))
       if (TREE_CODE (decl) == VAR_DECL
-         && ! TREE_USED (decl)
+         && (! TREE_USED (decl) || !DECL_READ_P (decl))
          && ! DECL_IN_SYSTEM_HEADER (decl)
          && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       warning (OPT_Wunused_variable, "unused variable %q+D", decl);
+       {
+         if (! TREE_USED (decl))
+           warning (OPT_Wunused_variable, "unused variable %q+D", decl);
+         else if (DECL_CONTEXT (decl) == current_function_decl
+                  && TREE_TYPE (decl) != error_mark_node
+                  && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+                  && errorcount == unused_but_set_errorcount
+                  && (!CLASS_TYPE_P (TREE_TYPE (decl))
+                      || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+           {
+             warning (OPT_Wunused_but_set_variable,
+                      "variable %q+D set but not used", decl); 
+             unused_but_set_errorcount = errorcount;
+           }
+       }
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -660,10 +695,9 @@ poplevel (int keep, int reverse, int functionbody)
              /* Add it to the list of dead variables in the next
                 outermost binding to that we can remove these when we
                 leave that binding.  */
-             current_binding_level->level_chain->dead_vars_from_for
-               = tree_cons (NULL_TREE, link,
-                            current_binding_level->level_chain->
-                            dead_vars_from_for);
+             VEC_safe_push (tree, gc,
+                            current_binding_level->level_chain->dead_vars_from_for,
+                            link);
 
              /* Although we don't pop the cxx_binding, we do clear
                 its SCOPE since the scope is going away now.  */
@@ -692,9 +726,9 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* Remove declarations for any `for' variables from inner scopes
      that we kept around.  */
-  for (link = current_binding_level->dead_vars_from_for;
-       link; link = TREE_CHAIN (link))
-    pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link));
+  FOR_EACH_VEC_ELT_REVERSE (tree, current_binding_level->dead_vars_from_for,
+                           ix, decl)
+    pop_binding (DECL_NAME (decl), decl);
 
   /* Restore the IDENTIFIER_TYPE_VALUEs.  */
   for (link = current_binding_level->type_shadowed;
@@ -702,10 +736,10 @@ poplevel (int keep, int reverse, int functionbody)
     SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
 
   /* Restore the IDENTIFIER_LABEL_VALUEs for local labels.  */
-  for (link = current_binding_level->shadowed_labels;
-       link;
-       link = TREE_CHAIN (link))
-    pop_local_label (TREE_VALUE (link), TREE_PURPOSE (link));
+  FOR_EACH_VEC_ELT_REVERSE (cp_label_binding,
+                           current_binding_level->shadowed_labels,
+                           ix, label_bind)
+    pop_local_label (label_bind->label, label_bind->prev_value);
 
   /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
      list if a `using' declaration put them there.  The debugging
@@ -722,7 +756,7 @@ poplevel (int keep, int reverse, int functionbody)
          if (TREE_CODE (*d) == TREE_LIST)
            *d = TREE_CHAIN (*d);
          else
-           d = &TREE_CHAIN (*d);
+           d = &DECL_CHAIN (*d);
        }
     }
 
@@ -746,7 +780,7 @@ poplevel (int keep, int reverse, int functionbody)
         have pushed a statement list level.  Pop that, create a new
         BIND_EXPR for the block, and insert it into the stream.  */
       stmt = pop_stmt_list (current_binding_level->statement_list);
-      stmt = c_build_bind_expr (block, stmt);
+      stmt = c_build_bind_expr (input_location, block, stmt);
       add_stmt (stmt);
     }
 
@@ -784,18 +818,6 @@ poplevel (int keep, int reverse, int functionbody)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
 }
 
-/* Insert BLOCK at the end of the list of subblocks of the
-   current binding level.  This is used when a BIND_EXPR is expanded,
-   to handle the BLOCK node inside the BIND_EXPR.  */
-
-void
-insert_block (tree block)
-{
-  TREE_USED (block) = 1;
-  current_binding_level->blocks
-    = chainon (current_binding_level->blocks, block);
-}
-
 /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
    itself, calling F for each.  The DATA is passed to F as well.  */
 
@@ -807,7 +829,7 @@ walk_namespaces_r (tree name_space, walk_namespaces_fn f, void* data)
 
   result |= (*f) (name_space, data);
 
-  for (; current; current = TREE_CHAIN (current))
+  for (; current; current = DECL_CHAIN (current))
     result |= walk_namespaces_r (current, f, data);
 
   return result;
@@ -857,13 +879,14 @@ create_implicit_typedef (tree name, tree type)
 {
   tree decl;
 
-  decl = build_decl (TYPE_DECL, name, type);
+  decl = build_decl (input_location, TYPE_DECL, name, type);
   DECL_ARTIFICIAL (decl) = 1;
   /* There are other implicit type declarations, like the one *within*
      a class that allows you to write `S::S'.  We must distinguish
      amongst these.  */
   SET_DECL_IMPLICIT_TYPEDEF_P (decl);
   TYPE_NAME (type) = decl;
+  TYPE_STUB_DECL (type) = decl;
 
   return decl;
 }
@@ -888,7 +911,7 @@ push_local_name (tree decl)
        {
          if (!DECL_LANG_SPECIFIC (decl))
            retrofit_lang_decl (decl);
-         DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1;
+         DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
          if (DECL_LANG_SPECIFIC (t))
            DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
          else
@@ -931,11 +954,30 @@ decls_match (tree newdecl, tree olddecl)
       tree p1 = TYPE_ARG_TYPES (f1);
       tree p2 = TYPE_ARG_TYPES (f2);
 
+      /* Specializations of different templates are different functions
+        even if they have the same type.  */
+      tree t1 = (DECL_USE_TEMPLATE (newdecl)
+                ? DECL_TI_TEMPLATE (newdecl)
+                : NULL_TREE);
+      tree t2 = (DECL_USE_TEMPLATE (olddecl)
+                ? DECL_TI_TEMPLATE (olddecl)
+                : NULL_TREE);
+      if (t1 != t2)
+       return 0;
+
       if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
          && ! (DECL_EXTERN_C_P (newdecl)
                && DECL_EXTERN_C_P (olddecl)))
        return 0;
 
+#ifdef NO_IMPLICIT_EXTERN_C
+      /* A new declaration doesn't match a built-in one unless it
+        is also extern "C".  */
+      if (DECL_IS_BUILTIN (olddecl)
+         && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
+       return 0;
+#endif
+
       if (TREE_CODE (f1) != TREE_CODE (f2))
        return 0;
 
@@ -1030,8 +1072,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
@@ -1054,7 +1094,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);
 }
@@ -1086,14 +1125,40 @@ check_redeclaration_exception_specification (tree new_decl,
   if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl))
       && ! DECL_IS_BUILTIN (old_decl)
       && flag_exceptions
-      && !comp_except_specs (new_exceptions, old_exceptions,
-                            /*exact=*/true))
+      && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
     {
-      error ("declaration of %qF throws different exceptions", new_decl);
+      error ("declaration of %qF has a different exception specifier",
+            new_decl);
       error ("from previous declaration %q+F", old_decl);
     }
 }
 
+/* Return true if OLD_DECL and NEW_DECL agree on constexprness.
+   Otherwise issue diagnostics.  */
+
+static bool
+validate_constexpr_redeclaration (tree old_decl, tree new_decl)
+{
+  old_decl = STRIP_TEMPLATE (old_decl);
+  new_decl = STRIP_TEMPLATE (new_decl);
+  if (!VAR_OR_FUNCTION_DECL_P (old_decl)
+      || !VAR_OR_FUNCTION_DECL_P (new_decl))
+    return true;
+  if (DECL_DECLARED_CONSTEXPR_P (old_decl)
+      == DECL_DECLARED_CONSTEXPR_P (new_decl))
+    return true;
+  if (TREE_CODE (old_decl) == FUNCTION_DECL && DECL_BUILT_IN (old_decl))
+    {
+      /* Hide a built-in declaration.  */
+      DECL_DECLARED_CONSTEXPR_P (old_decl)
+       = DECL_DECLARED_CONSTEXPR_P (new_decl);
+      return true;
+    }
+  error ("redeclaration %qD differs in %<constexpr%>", new_decl);
+  error ("from previous declaration %q+D", old_decl);
+  return false;
+}
+
 #define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn)                  \
                          && lookup_attribute ("gnu_inline",            \
                                               DECL_ATTRIBUTES (fn)))
@@ -1113,7 +1178,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
   int new_defines_function = 0;
-  tree new_template;
+  tree new_template_info;
 
   if (newdecl == olddecl)
     return olddecl;
@@ -1179,9 +1244,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;
            }
@@ -1252,9 +1318,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.  */
@@ -1266,7 +1333,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Even if the types match, prefer the new declarations type for
         built-ins which have not been explicitly declared, for
         exception lists, etc...  */
-      else if (DECL_ANTICIPATED (olddecl))
+      else if (DECL_IS_BUILTIN (olddecl))
        {
          tree type = TREE_TYPE (newdecl);
          tree attribs = (*targetm.merge_type_attributes)
@@ -1460,7 +1527,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       const char *errmsg = redeclaration_error_message (newdecl, olddecl);
       if (errmsg)
        {
-         error (errmsg, newdecl);
+         error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
            error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
                         ? "%q+#D previously defined here"
@@ -1473,8 +1540,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
               && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE)
        {
          /* Prototype decl follows defn w/o prototype.  */
-         warning (0, "prototype for %q+#D", newdecl);
-         warning (0, "%Jfollows non-prototype definition here", olddecl);
+         warning_at (input_location, 0, "prototype for %q+#D", newdecl);
+         warning_at (DECL_SOURCE_LOCATION (olddecl), 0,
+                     "follows non-prototype definition here");
        }
       else if ((TREE_CODE (olddecl) == FUNCTION_DECL
                || TREE_CODE (olddecl) == VAR_DECL)
@@ -1570,6 +1638,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
      warn about it.  */
   warn_extern_redeclared_static (newdecl, olddecl);
 
+  if (!validate_constexpr_redeclaration (olddecl, newdecl))
+    return error_mark_node;
+
   /* We have committed to returning 1 at this point.  */
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -1686,8 +1757,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            = DECL_SOURCE_LOCATION (newdecl);
          DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
          if (DECL_FUNCTION_TEMPLATE_P (newdecl))
-           DECL_ARGUMENTS (old_result)
-             = DECL_ARGUMENTS (new_result);
+           {
+             tree parm;
+             DECL_ARGUMENTS (old_result)
+               = DECL_ARGUMENTS (new_result);
+             for (parm = DECL_ARGUMENTS (old_result); parm;
+                  parm = DECL_CHAIN (parm))
+               DECL_CONTEXT (parm) = old_result;
+           }
        }
 
       return olddecl;
@@ -1784,9 +1861,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        {
          DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
          DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
-         if (CAN_HAVE_FULL_LANG_DECL_P (newdecl)
-             && DECL_LANG_SPECIFIC (newdecl)
-             && DECL_LANG_SPECIFIC (olddecl))
+         if (TREE_CODE (newdecl) == FUNCTION_DECL)
            {
              DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
              DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
@@ -1844,14 +1919,16 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   /* Merge the storage class information.  */
   merge_weak (newdecl, olddecl);
 
-  DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl);
+  if (DECL_ONE_ONLY (olddecl))
+    DECL_COMDAT_GROUP (newdecl) = DECL_COMDAT_GROUP (olddecl);
+
   DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
   TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
   TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
   if (! DECL_EXTERNAL (olddecl))
     DECL_EXTERNAL (newdecl) = 0;
 
-  new_template = NULL_TREE;
+  new_template_info = NULL_TREE;
   if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
     {
       bool new_redefines_gnu_inline = false;
@@ -1879,6 +1956,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
@@ -1890,24 +1968,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Don't really know how much of the language-specific
         values we should copy from old to new.  */
       DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
-      DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
-       DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
-      DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
       DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
-      if (DECL_TEMPLATE_INFO (newdecl))
-       new_template = DECL_TI_TEMPLATE (newdecl);
-      DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
       DECL_INITIALIZED_IN_CLASS_P (newdecl)
        |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
-      olddecl_friend = DECL_FRIEND_P (olddecl);
-      hidden_friend = (DECL_ANTICIPATED (olddecl)
-                      && DECL_HIDDEN_FRIEND_P (olddecl)
-                      && newdecl_is_friend);
 
-      /* Only functions have DECL_BEFRIENDING_CLASSES.  */
+      if (LANG_DECL_HAS_MIN (newdecl))
+       {
+         DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
+           DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
+         if (DECL_TEMPLATE_INFO (newdecl))
+           new_template_info = DECL_TEMPLATE_INFO (newdecl);
+         DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+       }
+      /* Only functions have these fields.  */
       if (TREE_CODE (newdecl) == FUNCTION_DECL
          || DECL_FUNCTION_TEMPLATE_P (newdecl))
        {
+         DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
+         olddecl_friend = DECL_FRIEND_P (olddecl);
+         hidden_friend = (DECL_ANTICIPATED (olddecl)
+                          && DECL_HIDDEN_FRIEND_P (olddecl)
+                          && newdecl_is_friend);
          DECL_BEFRIENDING_CLASSES (newdecl)
            = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
                       DECL_BEFRIENDING_CLASSES (olddecl));
@@ -1916,10 +1997,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          if (DECL_VIRTUAL_P (newdecl))
            DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
        }
+      /* Only variables have this field.  */
+      else if (TREE_CODE (newdecl) == VAR_DECL
+              && VAR_HAD_UNKNOWN_BOUND (olddecl))
+       SET_VAR_HAD_UNKNOWN_BOUND (newdecl);
     }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
+      tree parm;
+
+      /* Merge parameter attributes. */
+      tree oldarg, newarg;
+      for (oldarg = DECL_ARGUMENTS(olddecl), 
+               newarg = DECL_ARGUMENTS(newdecl);
+           oldarg && newarg;
+           oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg)) {
+          DECL_ATTRIBUTES (newarg)
+              = (*targetm.merge_decl_attributes) (oldarg, newarg);
+          DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
+      }
+      
       if (DECL_TEMPLATE_INSTANTIATION (olddecl)
          && !DECL_TEMPLATE_INSTANTIATION (newdecl))
        {
@@ -1928,7 +2026,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
@@ -1976,6 +2074,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Preserve abstractness on cloned [cd]tors.  */
       DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
 
+      /* Update newdecl's parms to point at olddecl.  */
+      for (parm = DECL_ARGUMENTS (newdecl); parm;
+          parm = DECL_CHAIN (parm))
+       DECL_CONTEXT (parm) = olddecl;
+
       if (! types_match)
        {
          SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
@@ -2008,7 +2111,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            }
 
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
-         /* Don't clear out the arguments if we're redefining a function.  */
+         /* Don't clear out the arguments if we're just redeclaring a
+            function.  */
          if (DECL_ARGUMENTS (olddecl))
            DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
        }
@@ -2027,10 +2131,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       && DECL_VISIBILITY_SPECIFIED (newdecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
-      warning (OPT_Wattributes, "%q+D: visibility attribute ignored "
-              "because it", newdecl);
-      warning (OPT_Wattributes, "%Jconflicts with previous "
-              "declaration here", olddecl);
+      warning_at (input_location, OPT_Wattributes,
+                 "%q+D: visibility attribute ignored because it", newdecl);
+      warning_at (DECL_SOURCE_LOCATION (olddecl), OPT_Wattributes,
+                 "conflicts with previous declaration here");
     }
   /* Choose the declaration which specified visibility.  */
   if (DECL_VISIBILITY_SPECIFIED (olddecl))
@@ -2045,6 +2149,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
       DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
     }
+  /* Likewise for DECL_USER_ALIGN and DECL_PACKED.  */
+  DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
+  if (TREE_CODE (newdecl) == FIELD_DECL)
+    DECL_PACKED (olddecl) = DECL_PACKED (newdecl);
 
   /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced
      with that from NEWDECL below.  */
@@ -2055,11 +2163,22 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       ggc_free (DECL_LANG_SPECIFIC (olddecl));
     }
 
-   /* Merge the USED information.  */
-   if (TREE_USED (olddecl))
-     TREE_USED (newdecl) = 1;
-   else if (TREE_USED (newdecl))
-     TREE_USED (olddecl) = 1;
+  /* Merge the USED information.  */
+  if (TREE_USED (olddecl))
+    TREE_USED (newdecl) = 1;
+  else if (TREE_USED (newdecl))
+    TREE_USED (olddecl) = 1;
+  if (TREE_CODE (newdecl) == VAR_DECL)
+    {
+      if (DECL_READ_P (olddecl))
+       DECL_READ_P (newdecl) = 1;
+      else if (DECL_READ_P (newdecl))
+       DECL_READ_P (olddecl) = 1;
+    }
+  if (DECL_PRESERVE_P (olddecl))
+    DECL_PRESERVE_P (newdecl) = 1;
+  else if (DECL_PRESERVE_P (newdecl))
+    DECL_PRESERVE_P (olddecl) = 1;
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2074,7 +2193,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
              (char *) newdecl + sizeof (struct tree_decl_common),
              sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
-      if (new_template)
+      if (new_template_info)
        /* If newdecl is a template instantiation, it is possible that
           the following sequence of events has occurred:
 
@@ -2097,7 +2216,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
           instantiations so that if we try to do the instantiation
           again we won't get the clobbered declaration.  */
        reregister_specialization (newdecl,
-                                  new_template,
+                                  new_template_info,
                                   olddecl);
     }
   else
@@ -2177,7 +2296,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)
     {
@@ -2193,7 +2312,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.  */
@@ -2203,10 +2322,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))
@@ -2217,9 +2336,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");
            }
        }
 
@@ -2233,7 +2354,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;
        }
 
@@ -2250,7 +2371,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))
        {
@@ -2260,9 +2381,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");
            }
        }
 
@@ -2277,7 +2400,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;
     }
@@ -2290,11 +2414,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))
     {
@@ -2308,7 +2432,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:
 
@@ -2319,7 +2443,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
     {
@@ -2327,7 +2451,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;
     }
 }
@@ -2358,7 +2482,7 @@ make_label_decl (tree id, int local_p)
   void **slot;
   tree decl;
 
-  decl = build_decl (LABEL_DECL, id, void_type_node);
+  decl = build_decl (input_location, LABEL_DECL, id, void_type_node);
 
   DECL_CONTEXT (decl) = current_function_decl;
   DECL_MODE (decl) = VOIDmode;
@@ -2379,7 +2503,7 @@ make_label_decl (tree id, int local_p)
   /* Record this label on the list of labels used in this function.
      We do this before calling make_label_decl so that we get the
      IDENTIFIER_LABEL_VALUE before the new label is declared.  */
-  ent = GGC_CNEW (struct named_label_entry);
+  ent = ggc_alloc_cleared_named_label_entry ();
   ent->label_decl = decl;
 
   slot = htab_find_slot (named_labels, ent, INSERT);
@@ -2420,16 +2544,17 @@ lookup_label (tree id)
 tree
 declare_local_label (tree id)
 {
-  tree decl, shadow;
+  tree decl;
+  cp_label_binding *bind;
 
   /* Add a new entry to the SHADOWED_LABELS list so that when we leave
      this scope we can restore the old value of IDENTIFIER_TYPE_VALUE.  */
-  shadow = tree_cons (IDENTIFIER_LABEL_VALUE (id), NULL_TREE,
-                     current_binding_level->shadowed_labels);
-  current_binding_level->shadowed_labels = shadow;
+  bind = VEC_safe_push (cp_label_binding, gc,
+                       current_binding_level->shadowed_labels, NULL);
+  bind->prev_value = IDENTIFIER_LABEL_VALUE (id);
 
   decl = make_label_decl (id, /*local_p=*/1);
-  TREE_VALUE (shadow) = decl;
+  bind->label = decl;
 
   return decl;
 }
@@ -2440,20 +2565,28 @@ declare_local_label (tree id)
 static int
 decl_jump_unsafe (tree decl)
 {
+  /* [stmt.dcl]/3: A program that jumps from a point where a local variable
+     with automatic storage duration is not in scope to a point where it is
+     in scope is ill-formed unless the variable has scalar type, class type
+     with a trivial default constructor and a trivial destructor, a
+     cv-qualified version of one of these types, or an array of one of the
+     preceding types and is declared without an initializer (8.5).  */
+  tree type = TREE_TYPE (decl);
+
   if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)
-      || TREE_TYPE (decl) == error_mark_node)
+      || type == error_mark_node)
     return 0;
 
-  if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
+  type = strip_array_types (type);
+
+  if (type_has_nontrivial_default_init (TREE_TYPE (decl))
       || DECL_NONTRIVIALLY_INITIALIZED_P (decl))
     return 2;
 
-  if (pod_type_p (TREE_TYPE (decl)))
-    return 0;
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+    return 1;
 
-  /* The POD stuff is just pedantry; why should it matter if the class
-     contains a field of pointer to member type?  */
-  return 1;
+  return 0;
 }
 
 /* A subroutine of check_previous_goto_1 to identify a branch to the user.  */
@@ -2466,7 +2599,7 @@ identify_goto (tree decl, const location_t *locus)
   else
     permerror (input_location, "jump to case label");
   if (locus)
-    permerror (input_location, "%H  from here", locus);
+    permerror (*locus, "  from here");
 }
 
 /* Check that a single previously seen jump to a newly defined label
@@ -2494,7 +2627,7 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
       tree new_decls, old_decls = (b == level ? names : NULL_TREE);
 
       for (new_decls = b->names; new_decls != old_decls;
-          new_decls = TREE_CHAIN (new_decls))
+          new_decls = DECL_CHAIN (new_decls))
        {
          int problem = decl_jump_unsafe (new_decls);
          if (! problem)
@@ -2508,7 +2641,8 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
          if (problem > 1)
            error ("  crosses initialization of %q+#D", new_decls);
          else
-           permerror (input_location, "  enters scope of non-POD %q+#D", new_decls);
+           permerror (input_location, "  enters scope of %q+#D which has "
+                      "non-trivial destructor", new_decls);
        }
 
       if (b == level)
@@ -2564,6 +2698,7 @@ check_goto (tree decl)
   struct named_label_entry *ent, dummy;
   bool saw_catch = false, identified = false;
   tree bad;
+  unsigned ix;
 
   /* We can't know where a computed goto is jumping.
      So we assume that it's OK.  */
@@ -2590,7 +2725,7 @@ check_goto (tree decl)
          && ent->uses->names_in_scope == current_binding_level->names)
        return;
 
-      new_use = GGC_NEW (struct named_label_use_entry);
+      new_use = ggc_alloc_named_label_use_entry ();
       new_use->binding_level = current_binding_level;
       new_use->names_in_scope = current_binding_level->names;
       new_use->o_goto_locus = input_location;
@@ -2602,28 +2737,28 @@ check_goto (tree decl)
     }
 
   if (ent->in_try_scope || ent->in_catch_scope
-      || ent->in_omp_scope || ent->bad_decls)
+      || ent->in_omp_scope || !VEC_empty (tree, ent->bad_decls))
     {
       permerror (input_location, "jump to label %q+D", decl);
       permerror (input_location, "  from here");
       identified = true;
     }
 
-  for (bad = ent->bad_decls; bad; bad = TREE_CHAIN (bad))
+  FOR_EACH_VEC_ELT (tree, ent->bad_decls, ix, bad)
     {
-      tree b = TREE_VALUE (bad);
-      int u = decl_jump_unsafe (b);
+      int u = decl_jump_unsafe (bad);
 
-      if (u > 1 && DECL_ARTIFICIAL (b))
+      if (u > 1 && DECL_ARTIFICIAL (bad))
        {
          /* Can't skip init of __exception_info.  */
-         error ("%J  enters catch block", b);
+         error_at (DECL_SOURCE_LOCATION (bad), "  enters catch block");
          saw_catch = true;
        }
       else if (u > 1)
-       error ("  skips initialization of %q+#D", b);
+       error ("  skips initialization of %q+#D", bad);
       else
-       permerror (input_location, "  enters scope of non-POD %q+#D", b);
+       permerror (input_location, "  enters scope of %q+#D which has "
+                  "non-trivial destructor", bad);
     }
 
   if (ent->in_try_scope)
@@ -2767,10 +2902,7 @@ pop_switch (void)
   location_t switch_location;
 
   /* Emit warnings as needed.  */
-  if (EXPR_HAS_LOCATION (cs->switch_stmt))
-    switch_location = EXPR_LOCATION (cs->switch_stmt);
-  else
-    switch_location = input_location;
+  switch_location = EXPR_LOC_OR_HERE (cs->switch_stmt);
   if (!processing_template_decl)
     c_do_switch_warnings (cs->cases, switch_location,
                          SWITCH_STMT_TYPE (cs->switch_stmt),
@@ -2785,7 +2917,7 @@ pop_switch (void)
    is a bad place for one.  */
 
 tree
-finish_case_label (tree low_value, tree high_value)
+finish_case_label (location_t loc, tree low_value, tree high_value)
 {
   tree cond, r;
   struct cp_binding_level *p;
@@ -2796,8 +2928,8 @@ finish_case_label (tree low_value, tree high_value)
 
       /* For templates, just add the case label; we'll do semantic
         analysis at instantiation-time.  */
-      label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      return add_stmt (build_case_label (low_value, high_value, label));
+      label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
+      return add_stmt (build_case_label (loc, low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -2808,7 +2940,13 @@ finish_case_label (tree low_value, tree high_value)
   if (!check_switch_goto (switch_stack->level))
     return error_mark_node;
 
-  r = c_add_case_label (switch_stack->cases, cond, TREE_TYPE (cond),
+  if (low_value)
+    low_value = cxx_constant_value (low_value);
+  if (high_value)
+    high_value = cxx_constant_value (high_value);
+
+  r = c_add_case_label (loc, switch_stack->cases, cond,
+                       SWITCH_STMT_TYPE (switch_stack->switch_stmt),
                        low_value, high_value);
 
   /* After labels, make any new cleanups in the function go into their
@@ -2904,7 +3042,7 @@ build_typename_type (tree context, tree name, tree fullname,
       TYPENAME_IS_CLASS_P (t) = ti.class_p;
 
       /* Build the corresponding TYPE_DECL.  */
-      d = build_decl (TYPE_DECL, name, t);
+      d = build_decl (input_location, TYPE_DECL, name, t);
       TYPE_NAME (TREE_TYPE (d)) = d;
       TYPE_STUB_DECL (TREE_TYPE (d)) = d;
       DECL_CONTEXT (d) = FROB_CONTEXT (context);
@@ -2979,12 +3117,6 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
   gcc_assert (TYPE_P (context));
 
-  /* When the CONTEXT is a dependent type,  NAME could refer to a
-     dependent base class of CONTEXT.  So we cannot peek inside it,
-     even if CONTEXT is a currently open scope.  */
-  if (dependent_type_p (context))
-    return build_typename_type (context, name, fullname, tag_type);
-
   if (!MAYBE_CLASS_TYPE_P (context))
     {
       if (complain & tf_error)
@@ -2992,11 +3124,23 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
       return error_mark_node;
     }
   
+  /* When the CONTEXT is a dependent type,  NAME could refer to a
+     dependent base class of CONTEXT.  But look inside it anyway
+     if CONTEXT is a currently open scope, in case it refers to a
+     member of the current instantiation or a non-dependent base;
+     lookup will stop when we hit a dependent base.  */
+  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, 2, /*want_type=*/true);
+  else
+    t = NULL_TREE;
+
+  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;
   
-  /* 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);
   if (!t)
     {
       if (complain & tf_error)
@@ -3005,6 +3149,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)
@@ -3023,6 +3181,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,
@@ -3065,6 +3228,9 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
       if (MAYBE_CLASS_TYPE_P (context))
        tmpl = lookup_field (context, name, 0, false);
 
+      if (tmpl && TREE_CODE (tmpl) == TYPE_DECL)
+       tmpl = maybe_get_template_decl_from_type_decl (tmpl);
+
       if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
        {
          if (complain & tf_error)
@@ -3096,7 +3262,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
   SET_TYPE_STRUCTURAL_EQUALITY (t);
 
   /* Build the corresponding TEMPLATE_DECL.  */
-  d = build_decl (TEMPLATE_DECL, name, t);
+  d = build_decl (input_location, TEMPLATE_DECL, name, t);
   TYPE_NAME (TREE_TYPE (d)) = d;
   TYPE_STUB_DECL (TREE_TYPE (d)) = d;
   DECL_CONTEXT (d) = FROB_CONTEXT (context);
@@ -3133,7 +3299,7 @@ record_builtin_type (enum rid rid_index,
      up built-in types by name.  */
   if (tname)
     {
-      tdecl = build_decl (TYPE_DECL, tname, type);
+      tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, tname, type);
       DECL_ARTIFICIAL (tdecl) = 1;
       SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
     }
@@ -3141,7 +3307,7 @@ record_builtin_type (enum rid rid_index,
     {
       if (!tdecl)
        {
-         tdecl = build_decl (TYPE_DECL, rname, type);
+         tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, rname, type);
          DECL_ARTIFICIAL (tdecl) = 1;
        }
       SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
@@ -3164,10 +3330,18 @@ record_builtin_java_type (const char* name, int size)
 {
   tree type, decl;
   if (size > 0)
-    type = make_signed_type (size);
+    type = build_nonstandard_integer_type (size, 0);
   else if (size > -32)
-    { /* "__java_char" or ""__java_boolean".  */
-      type = make_unsigned_type (-size);
+    {
+      tree stype;
+      /* "__java_char" or ""__java_boolean".  */
+      type = build_nonstandard_integer_type (-size, 1);
+      /* Get the signed type cached and attached to the unsigned type,
+        so it doesn't get garbage-collected at "random" times,
+        causing potential codegen differences out of different UIDs
+        and different alias set numbers.  */
+      stype = build_nonstandard_integer_type (-size, 0);
+      TREE_CHAIN (type) = stype;
       /*if (size == -1)        TREE_SET_CODE (type, BOOLEAN_TYPE);*/
     }
   else
@@ -3193,14 +3367,15 @@ record_builtin_java_type (const char* name, int size)
 static void
 record_unknown_type (tree type, const char* name)
 {
-  tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
+  tree decl = pushdecl (build_decl (UNKNOWN_LOCATION,
+                                   TYPE_DECL, get_identifier (name), type));
   /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
   DECL_IGNORED_P (decl) = 1;
   TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
   TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
   TYPE_ALIGN (type) = 1;
   TYPE_USER_ALIGN (type) = 0;
-  TYPE_MODE (type) = TYPE_MODE (void_type_node);
+  SET_TYPE_MODE (type, TYPE_MODE (void_type_node));
 }
 
 /* A string for which we should create an IDENTIFIER_NODE at
@@ -3268,7 +3443,7 @@ cxx_init_decl_processing (void)
   tree void_ftype;
   tree void_ftype_ptr;
 
-  build_common_tree_nodes (flag_signed_char, false);
+  build_common_tree_nodes (flag_signed_char);
 
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
@@ -3282,6 +3457,7 @@ cxx_init_decl_processing (void)
   gcc_assert (global_namespace == NULL_TREE);
   global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
                                      void_type_node);
+  DECL_CONTEXT (global_namespace) = build_translation_unit_decl (NULL_TREE);
   TREE_PUBLIC (global_namespace) = 1;
   begin_scope (sk_namespace, global_namespace);
 
@@ -3310,7 +3486,6 @@ cxx_init_decl_processing (void)
   java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1);
 
   integer_two_node = build_int_cst (NULL_TREE, 2);
-  integer_three_node = build_int_cst (NULL_TREE, 3);
 
   record_builtin_type (RID_BOOL, "bool", boolean_type_node);
   truthvalue_type_node = boolean_type_node;
@@ -3318,6 +3493,8 @@ cxx_init_decl_processing (void)
   truthvalue_true_node = boolean_true_node;
 
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
+  noexcept_true_spec = build_tree_list (boolean_true_node, NULL_TREE);
+  noexcept_false_spec = build_tree_list (boolean_false_node, NULL_TREE);
 
 #if 0
   record_builtin_type (RID_MAX, NULL, string_type_node);
@@ -3327,17 +3504,15 @@ cxx_init_decl_processing (void)
   vtable_index_type = ptrdiff_type_node;
 
   vtt_parm_type = build_pointer_type (const_ptr_type_node);
-  void_ftype = build_function_type (void_type_node, void_list_node);
-  void_ftype_ptr = build_function_type (void_type_node,
-                                       tree_cons (NULL_TREE,
-                                                  ptr_type_node,
-                                                  void_list_node));
+  void_ftype = build_function_type_list (void_type_node, NULL_TREE);
+  void_ftype_ptr = build_function_type_list (void_type_node,
+                                            ptr_type_node, NULL_TREE);
   void_ftype_ptr
     = build_exception_variant (void_ftype_ptr, empty_except_spec);
 
   /* C++ extensions */
 
-  unknown_type_node = make_node (UNKNOWN_TYPE);
+  unknown_type_node = make_node (LANG_TYPE);
   record_unknown_type (unknown_type_node, "unknown type");
 
   /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
@@ -3348,7 +3523,7 @@ cxx_init_decl_processing (void)
   TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
   TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
 
-  init_list_type_node = make_node (UNKNOWN_TYPE);
+  init_list_type_node = make_node (LANG_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
   {
@@ -3366,7 +3541,7 @@ cxx_init_decl_processing (void)
   vtbl_type_node
     = build_cplus_array_type (vtable_entry_type, NULL_TREE);
   layout_type (vtbl_type_node);
-  vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
+  vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
   record_builtin_type (RID_MAX, NULL, vtbl_type_node);
   vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
   layout_type (vtbl_ptr_type_node);
@@ -3383,35 +3558,48 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
-    tree bad_alloc_id;
-    tree bad_alloc_type_node;
-    tree bad_alloc_decl;
     tree newtype, deltype;
     tree ptr_ftype_sizetype;
-
-    push_namespace (std_identifier);
-    bad_alloc_id = get_identifier ("bad_alloc");
-    bad_alloc_type_node = make_class_type (RECORD_TYPE);
-    TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
-    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 ();
+    tree new_eh_spec;
 
     ptr_ftype_sizetype
-      = build_function_type (ptr_type_node,
-                            tree_cons (NULL_TREE,
-                                       size_type_node,
-                                       void_list_node));
-    newtype = build_exception_variant
-      (ptr_ftype_sizetype, add_exception_specifier
-       (NULL_TREE, bad_alloc_type_node, -1));
+      = build_function_type_list (ptr_type_node, size_type_node, NULL_TREE);
+    if (cxx_dialect == cxx98)
+      {
+       tree bad_alloc_id;
+       tree bad_alloc_type_node;
+       tree bad_alloc_decl;
+
+       push_namespace (std_identifier);
+       bad_alloc_id = get_identifier ("bad_alloc");
+       bad_alloc_type_node = make_class_type (RECORD_TYPE);
+       TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
+       bad_alloc_decl
+         = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
+       DECL_CONTEXT (bad_alloc_decl) = current_namespace;
+       pop_namespace ();
+
+       new_eh_spec
+         = add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1);
+      }
+    else
+      new_eh_spec = noexcept_false_spec;
+
+    newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
     deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
     push_cp_library_fn (NEW_EXPR, newtype);
     push_cp_library_fn (VEC_NEW_EXPR, newtype);
     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
     push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+
+    nullptr_type_node = make_node (NULLPTR_TYPE);
+    TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
+    TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
+    TYPE_UNSIGNED (nullptr_type_node) = 1;
+    TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
+    SET_TYPE_MODE (nullptr_type_node, Pmode);
+    record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
+    nullptr_node = build_int_cst (nullptr_type_node, 0);
   }
 
   abort_fndecl
@@ -3420,6 +3608,7 @@ cxx_init_decl_processing (void)
   /* Perform other language dependent initializations.  */
   init_class_processing ();
   init_rtti_processing ();
+  init_template_processing ();
 
   if (flag_exceptions)
     init_exception_processing ();
@@ -3454,7 +3643,7 @@ cp_fname_init (const char* name, tree *type_p)
       init = build_string (length + 1, name);
     }
 
-  type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+  type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
   type = build_cplus_array_type (type, domain);
 
   *type_p = type;
@@ -3467,20 +3656,21 @@ cp_fname_init (const char* name, tree *type_p)
   return init;
 }
 
-/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
-   decl, NAME is the initialization string and TYPE_DEP indicates whether
-   NAME depended on the type of the function. We make use of that to detect
-   __PRETTY_FUNCTION__ inside a template fn. This is being done
-   lazily at the point of first use, so we mustn't push the decl now.  */
+/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give
+   the decl, LOC is the location to give the decl, NAME is the
+   initialization string and TYPE_DEP indicates whether NAME depended
+   on the type of the function. We make use of that to detect
+   __PRETTY_FUNCTION__ inside a template fn. This is being done 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)
+cp_make_fname_decl (location_t loc, tree id, int type_dep)
 {
   const char *const name = (type_dep && processing_template_decl
                            ? NULL : fname_as_string (type_dep));
   tree type;
   tree init = cp_fname_init (name, &type);
-  tree decl = build_decl (VAR_DECL, id, type);
+  tree decl = build_decl (loc, VAR_DECL, id, type);
 
   if (name)
     free (CONST_CAST (char *, name));
@@ -3498,6 +3688,8 @@ cp_make_fname_decl (tree id, int type_dep)
   if (current_function_decl)
     {
       struct cp_binding_level *b = current_binding_level;
+      if (b->kind == sk_function_parms)
+       return error_mark_node;
       while (b->level_chain->kind != sk_function_parms)
        b = b->level_chain;
       pushdecl_with_scope (decl, b, /*is_friend=*/false);
@@ -3518,10 +3710,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);
@@ -3731,10 +3919,10 @@ fixup_anonymous_aggr (tree t)
   /* Wipe out memory of synthesized methods.  */
   TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
   TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
-  TYPE_HAS_INIT_REF (t) = 0;
-  TYPE_HAS_CONST_INIT_REF (t) = 0;
-  TYPE_HAS_ASSIGN_REF (t) = 0;
-  TYPE_HAS_CONST_ASSIGN_REF (t) = 0;
+  TYPE_HAS_COPY_CTOR (t) = 0;
+  TYPE_HAS_CONST_COPY_CTOR (t) = 0;
+  TYPE_HAS_COPY_ASSIGN (t) = 0;
+  TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;
 
   /* Splice the implicitly generated functions out of the TYPE_METHODS
      list.  */
@@ -3744,7 +3932,7 @@ fixup_anonymous_aggr (tree t)
       if (DECL_ARTIFICIAL (*q))
        *q = TREE_CHAIN (*q);
       else
-       q = &TREE_CHAIN (*q);
+       q = &DECL_CHAIN (*q);
     }
 
   /* ISO C++ 9.5.3.  Anonymous unions may not have function members.  */
@@ -3753,9 +3941,11 @@ fixup_anonymous_aggr (tree t)
       tree decl = TYPE_MAIN_DECL (t);
 
       if (TREE_CODE (t) != UNION_TYPE)
-       error ("%Jan anonymous struct cannot have function members", decl);
+       error_at (DECL_SOURCE_LOCATION (decl), 
+                 "an anonymous struct cannot have function members");
       else
-       error ("%Jan anonymous union cannot have function members", decl);
+       error_at (DECL_SOURCE_LOCATION (decl),
+                 "an anonymous union cannot have function members");
     }
 
   /* Anonymous aggregates cannot have fields with ctors, dtors or complex
@@ -3766,7 +3956,7 @@ fixup_anonymous_aggr (tree t)
     {
       tree field, type;
 
-      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
        if (TREE_CODE (field) == FIELD_DECL)
          {
            type = TREE_TYPE (field);
@@ -3778,7 +3968,7 @@ fixup_anonymous_aggr (tree t)
                if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
                  error ("member %q+#D with destructor not allowed "
                         "in anonymous aggregate", field);
-               if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+               if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
                  error ("member %q+#D with copy assignment operator "
                         "not allowed in anonymous aggregate", field);
              }
@@ -3879,6 +4069,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;
@@ -3940,13 +4132,16 @@ shadow_tag (cp_decl_specifier_seq *declspecs)
 
 tree
 groktypename (cp_decl_specifier_seq *type_specifiers,
-             const cp_declarator *declarator)
+             const cp_declarator *declarator,
+             bool is_template_arg)
 {
   tree attrs;
   tree type;
+  enum decl_context context
+    = is_template_arg ? TEMPLATE_TYPE_ARG : TYPENAME;
   attrs = type_specifiers->attributes;
   type_specifiers->attributes = NULL_TREE;
-  type = grokdeclarator (declarator, type_specifiers, TYPENAME, 0, &attrs);
+  type = grokdeclarator (declarator, type_specifiers, context, 0, &attrs);
   if (attrs && type != error_mark_node)
     {
       if (CLASS_TYPE_P (type))
@@ -3987,10 +4182,10 @@ start_decl (const cp_declarator *declarator,
            tree *pushed_scope_p)
 {
   tree decl;
-  tree type;
   tree context;
   bool was_public;
   int flags;
+  bool alias;
 
   *pushed_scope_p = NULL_TREE;
 
@@ -4010,18 +4205,9 @@ start_decl (const cp_declarator *declarator,
       || decl == error_mark_node)
     return error_mark_node;
 
-  type = TREE_TYPE (decl);
-
-  context = DECL_CONTEXT (decl);
-
-  if (context)
-    {
-      *pushed_scope_p = push_scope (context);
-
-      /* We are only interested in class contexts, later.  */
-      if (TREE_CODE (context) == NAMESPACE_DECL)
-       context = NULL_TREE;
-    }
+  context = CP_DECL_CONTEXT (decl);
+  if (context != global_namespace)
+    *pushed_scope_p = push_scope (context);
 
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
@@ -4054,6 +4240,10 @@ start_decl (const cp_declarator *declarator,
       if (toplevel_bindings_p ())
        TREE_STATIC (decl) = 1;
     }
+  alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
+  
+  if (alias && TREE_CODE (decl) == FUNCTION_DECL)
+    record_key_method_defined (decl);
 
   /* If this is a typedef that names the class for linkage purposes
      (7.1.3p8), apply any attributes directly to the type.  */
@@ -4086,7 +4276,7 @@ start_decl (const cp_declarator *declarator,
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
     warning (0, "inline function %q+D given attribute noinline", decl);
 
-  if (context && COMPLETE_TYPE_P (complete_type (context)))
+  if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
     {
       if (TREE_CODE (decl) == VAR_DECL)
        {
@@ -4118,6 +4308,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
@@ -4153,7 +4346,9 @@ start_decl (const cp_declarator *declarator,
            DECL_EXTERNAL (decl) = 1;
        }
 
-      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
+      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
+         /* Aliases are definitions. */
+         && !alias)
        permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
     }
@@ -4187,7 +4382,7 @@ start_decl (const cp_declarator *declarator,
       /* This is a const variable with implicit 'static'.  Set
         DECL_THIS_STATIC so we can tell it from variables that are
         !TREE_PUBLIC because of the anonymous namespace.  */
-      gcc_assert (cp_type_readonly (TREE_TYPE (decl)));
+      gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)) || errorcount);
       DECL_THIS_STATIC (decl) = 1;
     }
 
@@ -4304,15 +4499,9 @@ 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");
+    init = build_x_compound_expr_from_list (init, ELK_INIT,
+                                           tf_warning_or_error);
 
   if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
@@ -4326,7 +4515,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;
@@ -4351,13 +4540,15 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
    grok_reference_init.  */
 
 static tree
-build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
+build_init_list_var_init (tree decl, tree type, tree init, tree *array_init,
+                         tree *cleanup)
 {
   tree aggr_init, array, arrtype;
   init = perform_implicit_conversion (type, init, tf_warning_or_error);
-  aggr_init = TARGET_EXPR_INITIAL (init);
-  init = build2 (INIT_EXPR, type, decl, init);
+  if (error_operand_p (init))
+    return error_mark_node;
 
+  aggr_init = TARGET_EXPR_INITIAL (init);
   array = AGGR_INIT_EXPR_ARG (aggr_init, 1);
   arrtype = TREE_TYPE (array);
   STRIP_NOPS (array);
@@ -4367,12 +4558,10 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
      static variable and we don't need to do anything here.  */
   if (decl && TREE_CODE (array) == TARGET_EXPR)
     {
-      tree subinit;
-      tree var = set_up_extended_ref_temp (decl, array, cleanup, &subinit);
+      tree var = set_up_extended_ref_temp (decl, array, cleanup, array_init);
       var = build_address (var);
       var = convert (arrtype, var);
       AGGR_INIT_EXPR_ARG (aggr_init, 1) = var;
-      init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init);
     }
   return init;
 }
@@ -4392,9 +4581,15 @@ check_array_designated_initializer (const constructor_elt *ce)
     {
       /* The parser only allows identifiers as designated
         initializers.  */
-      gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
-      error ("name %qD used in a GNU-style designated "
-            "initializer for an array", ce->index);
+      if (ce->index == error_mark_node)
+       error ("name used in a GNU-style designated "
+              "initializer for an array");
+      else
+       {
+         gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
+         error ("name %qD used in a GNU-style designated "
+                "initializer for an array", ce->index);
+       }
       return false;
     }
 
@@ -4429,9 +4624,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initializer);
          constructor_elt *ce;
          HOST_WIDE_INT i;
-         for (i = 0; 
-              VEC_iterate (constructor_elt, v, i, ce);
-              ++i) 
+         FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
            if (!check_array_designated_initializer (ce))
              failure = 1;
        }
@@ -4468,7 +4661,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
 
       cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
 
-      layout_decl (decl, 0);
+      relayout_decl (decl);
     }
 }
 
@@ -4504,7 +4697,7 @@ layout_var_decl (tree decl)
       /* An automatic variable with an incomplete type: that is an error.
         Don't talk about array types here, since we took care of that
         message in grokdeclarator.  */
-      error ("storage size of %qD isn't known", decl);
+      error ("storage size of %qD isn%'t known", decl);
       TREE_TYPE (decl) = error_mark_node;
     }
 #if 0
@@ -4527,7 +4720,7 @@ layout_var_decl (tree decl)
        constant_expression_warning (DECL_SIZE (decl));
       else
        {
-         error ("storage size of %qD isn't constant", decl);
+         error ("storage size of %qD isn%'t constant", decl);
          TREE_TYPE (decl) = error_mark_node;
        }
     }
@@ -4537,7 +4730,7 @@ layout_var_decl (tree decl)
    we have a weak definition, we must endeavor to create only one
    instance of the variable at link-time.  */
 
-static void
+void
 maybe_commonize_var (tree decl)
 {
   /* Static data in a function with comdat linkage also has comdat
@@ -4546,13 +4739,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_p (DECL_CONTEXT (decl)))
     {
       if (flag_weak)
        {
@@ -4578,12 +4765,13 @@ maybe_commonize_var (tree decl)
                 be merged.  */
              TREE_PUBLIC (decl) = 0;
              DECL_COMMON (decl) = 0;
-             warning (0, "sorry: semantics of inline function static "
-                      "data %q+#D are wrong (you'll wind up "
-                      "with multiple copies)", decl);
-             warning (0, "%J  you can work around this by removing "
-                      "the initializer",
-                      decl);
+             warning_at (input_location, 0,
+                         "sorry: semantics of inline function static "
+                         "data %q+#D are wrong (you%'ll wind up "
+                         "with multiple copies)", decl);
+             warning_at (DECL_SOURCE_LOCATION (decl), 0, 
+                         "  you can work around this by removing "
+                         "the initializer");
            }
        }
     }
@@ -4598,7 +4786,7 @@ maybe_commonize_var (tree decl)
 static void
 check_for_uninitialized_const_var (tree decl)
 {
-  tree type = TREE_TYPE (decl);
+  tree type = strip_array_types (TREE_TYPE (decl));
 
   /* ``Unless explicitly declared extern, a const object does not have
      external linkage and must be initialized. ($8.4; $12.1)'' ARM
@@ -4606,11 +4794,28 @@ check_for_uninitialized_const_var (tree decl)
   if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
-      && !TYPE_NEEDS_CONSTRUCTING (type)
+      && (!TYPE_NEEDS_CONSTRUCTING (type)
+         || !type_has_user_provided_default_constructor (type))
       && !DECL_INITIAL (decl))
-    error ("uninitialized const %qD", decl);
-}
+    {
+      permerror (DECL_SOURCE_LOCATION (decl),
+                "uninitialized const %qD", decl);
+
+      if (CLASS_TYPE_P (type)
+         && !type_has_user_provided_default_constructor (type))
+       {
+         tree defaulted_ctor;
 
+         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+                 "%q#T has no user-provided default constructor", type);
+         defaulted_ctor = in_class_defaulted_default_constructor (type);
+         if (defaulted_ctor)
+           inform (DECL_SOURCE_LOCATION (defaulted_ctor),
+                   "constructor is not user-provided because it is "
+                   "explicitly defaulted in the class body");
+       }
+    }
+}
 \f
 /* Structure holding the current initializer being processed by reshape_init.
    CUR is a pointer to the current element being processed, END is a pointer
@@ -4628,14 +4833,14 @@ static tree reshape_init_r (tree, reshape_iter *, bool);
    initialized.  If there are no more such fields, the return value
    will be NULL.  */
 
-static tree
+tree
 next_initializable_field (tree field)
 {
   while (field
         && (TREE_CODE (field) != FIELD_DECL
             || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
             || DECL_ARTIFICIAL (field)))
-    field = TREE_CHAIN (field);
+    field = DECL_CHAIN (field);
 
   return field;
 }
@@ -4711,7 +4916,6 @@ static tree
 reshape_init_vector (tree type, reshape_iter *d)
 {
   tree max_index = NULL_TREE;
-  tree rtype;
 
   gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
 
@@ -4728,12 +4932,9 @@ reshape_init_vector (tree type, reshape_iter *d)
       return value;
     }
 
-  /* For a vector, the representation type is a struct
-      containing a single member which is an array of the
-      appropriate size.  */
-  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)));
+  /* For a vector, we initialize it as an array of the appropriate size.  */
+  if (TREE_CODE (type) == VECTOR_TYPE)
+    max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);
 
   return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
 }
@@ -4792,6 +4993,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]
@@ -4802,7 +5006,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
       if (TREE_CODE (type) == UNION_TYPE)
        break;
 
-      field = next_initializable_field (TREE_CHAIN (field));
+      field = next_initializable_field (DECL_CHAIN (field));
     }
 
   return new_init;
@@ -4812,7 +5016,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)
@@ -4840,7 +5044,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++;
@@ -4857,7 +5061,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;
@@ -5048,6 +5257,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
 {
   tree type = TREE_TYPE (decl);
   tree init_code = NULL;
+  tree extra_init = NULL_TREE;
+  tree core_type;
 
   /* Things that are going to be initialized need to have complete
      type.  */
@@ -5079,7 +5290,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)
@@ -5101,16 +5312,21 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
       gcc_assert (init != NULL_TREE);
       init = NULL_TREE;
     }
-  else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
+  else if (!init && DECL_REALLY_EXTERN (decl))
+    ;
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
     init = grok_reference_init (decl, type, init, cleanup);
-  else if (init)
+  else if (init || TYPE_NEEDS_CONSTRUCTING (type))
     {
+      if (!init)
+       check_for_uninitialized_const_var (decl);
       /* Do not reshape constructors of vectors (they don't need to be
         reshaped.  */
-      if (BRACE_ENCLOSED_INITIALIZER_P (init))
+      else if (BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          if (is_std_init_list (type))
-           return build_init_list_var_init (decl, type, init, cleanup);
+           init = build_init_list_var_init (decl, type, init,
+                                            &extra_init, cleanup);
          else if (TYPE_NON_AGGREGATE_CLASS (type))
            {
              /* Don't reshape if the class has constructors.  */
@@ -5118,9 +5334,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
                error ("in C++98 %qD must be initialized by constructor, "
                       "not by %<{...}%>",
                       decl);
-             init = build_tree_list (NULL_TREE, init);
            }
-         else if ((*targetm.vector_opaque_p) (type))
+         else if (TREE_CODE (type) == VECTOR_TYPE && TYPE_VECTOR_OPAQUE (type))
            {
              error ("opaque vector types cannot be initialized");
              init = error_mark_node;
@@ -5138,11 +5353,48 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
 
       if (TYPE_NEEDS_CONSTRUCTING (type)
          || (CLASS_TYPE_P (type)
-             && !BRACE_ENCLOSED_INITIALIZER_P (init)))
-       return build_aggr_init_full_exprs (decl, init, flags);
-      else if (TREE_CODE (init) != TREE_VEC)
+             && !(init && BRACE_ENCLOSED_INITIALIZER_P (init))))
+       {
+         init_code = build_aggr_init_full_exprs (decl, init, flags);
+
+         /* If this is a constexpr initializer, expand_default_init will
+            have returned an INIT_EXPR rather than a CALL_EXPR.  In that
+            case, pull the initializer back out and pass it down into
+            store_init_value.  */
+         while (TREE_CODE (init_code) == EXPR_STMT
+                || TREE_CODE (init_code) == CONVERT_EXPR)
+           init_code = TREE_OPERAND (init_code, 0);
+         if (TREE_CODE (init_code) == INIT_EXPR)
+           {
+             init = TREE_OPERAND (init_code, 1);
+             init_code = NULL_TREE;
+             /* Don't call digest_init; it's unnecessary and will complain
+                about aggregate initialization of non-aggregate classes.  */
+             flags |= LOOKUP_ALREADY_DIGESTED;
+           }
+         else if (DECL_DECLARED_CONSTEXPR_P (decl))
+           {
+             /* Declared constexpr, but no suitable initializer; massage
+                init appropriately so we can pass it into store_init_value
+                for the error.  */
+             if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
+               init = finish_compound_literal (type, init);
+             else if (CLASS_TYPE_P (type)
+                      && (!init || TREE_CODE (init) == TREE_LIST))
+               {
+                 init = build_functional_cast (type, init, tf_none);
+                 if (init != error_mark_node)
+                   TARGET_EXPR_DIRECT_INIT_P (init) = true;
+               }
+             init_code = NULL_TREE;
+           }
+         else
+           init = NULL_TREE;
+       }
+
+      if (init && TREE_CODE (init) != TREE_VEC)
        {
-         init_code = store_init_value (decl, init);
+         init_code = store_init_value (decl, init, flags);
          if (pedantic && TREE_CODE (type) == ARRAY_TYPE
              && DECL_INITIAL (decl)
              && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
@@ -5152,27 +5404,39 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
          init = NULL;
        }
     }
-  else if (DECL_EXTERNAL (decl))
-    ;
-  else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
-    return build_aggr_init_full_exprs (decl, init, flags);
-  else if (MAYBE_CLASS_TYPE_P (type))
+  else
     {
-      tree core_type = strip_array_types (type);
-
-      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type))
-       error ("structure %qD with uninitialized const members", decl);
-      if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
-       error ("structure %qD with uninitialized reference members", decl);
+      if (CLASS_TYPE_P (core_type = strip_array_types (type))
+         && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
+             || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
+       diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false,
+                                                 /*complain=*/true);
 
       check_for_uninitialized_const_var (decl);
     }
-  else
-    check_for_uninitialized_const_var (decl);
 
   if (init && init != error_mark_node)
     init_code = build2 (INIT_EXPR, type, decl, init);
 
+  if (extra_init)
+    init_code = add_stmt_to_compound (extra_init, init_code);
+
+  if (init_code && DECL_IN_AGGR_P (decl))
+    {
+      static int explained = 0;
+
+      if (cxx_dialect < cxx0x)
+       error ("initializer invalid for static member with constructor");
+      else
+       error ("non-constant in-class initialization invalid for static "
+              "member %qD", decl);
+      if (!explained)
+       {
+         error ("(an out of class initialization is required)");
+         explained = 1;
+       }
+    }
+
   return init_code;
 }
 
@@ -5339,6 +5603,8 @@ initialize_local_var (tree decl, tree init)
 
   /* Compute and store the initial value.  */
   already_used = TREE_USED (decl) || TREE_USED (type);
+  if (TREE_USED (type))
+    DECL_READ_P (decl) = 1;
 
   /* Generate a cleanup, if necessary.  */
   cleanup = cxx_maybe_build_cleanup (decl);
@@ -5383,16 +5649,15 @@ initialize_local_var (tree decl, tree init)
 
 /* DECL is a VAR_DECL for a compiler-generated variable with static
    storage duration (like a virtual table) whose initializer is a
-   compile-time constant.  INIT must be either a TREE_LIST of values,
-   or a CONSTRUCTOR.  Initialize the variable and provide it to the
+   compile-time constant.  Initialize the variable and provide it to the
    back end.  */
 
 void
-initialize_artificial_var (tree decl, tree init)
+initialize_artificial_var (tree decl, VEC(constructor_elt,gc) *v)
 {
+  tree init;
   gcc_assert (DECL_ARTIFICIAL (decl));
-  if (TREE_CODE (init) == TREE_LIST)
-    init = build_constructor_from_list (TREE_TYPE (decl), init);
+  init = build_constructor (TREE_TYPE (decl), v);
   gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
   DECL_INITIAL (decl) = init;
   DECL_INITIALIZED_P (decl) = 1;
@@ -5489,11 +5754,74 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
   auto_node = type_uses_auto (type);
-  if (auto_node && !type_dependent_expression_p (init))
+  if (auto_node)
     {
-      type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node);
-      if (type == error_mark_node)
-       return;
+      tree d_init;
+      if (init == NULL_TREE)
+       {
+         error ("declaration of %q#D has no initializer", decl);
+         TREE_TYPE (decl) = error_mark_node;
+         return;
+       }
+      d_init = init;
+      if (TREE_CODE (d_init) == TREE_LIST)
+       d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
+                                                 tf_warning_or_error);
+      d_init = resolve_nondeduced_context (d_init);
+      if (describable_type (d_init))
+       {
+         type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+                                                      auto_node);
+         if (type == error_mark_node)
+           return;
+       }
+    }
+
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    validate_constexpr_fundecl (decl);
+
+  else if (!ensure_literal_type_for_constexpr_object (decl))
+    DECL_DECLARED_CONSTEXPR_P (decl) = 0;
+
+  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_check (decl))
+           DECL_DEFAULTED_FN (decl) = 1;
+         else
+           DECL_INITIAL (decl) = NULL_TREE;
+       }
+    }
+
+  if (init && TREE_CODE (decl) == VAR_DECL)
+    {
+      DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+      /* FIXME we rely on TREE_CONSTANT below; basing that on
+        init_const_expr_p is probably wrong for C++0x.  */
+      if (init_const_expr_p)
+       {
+         /* Set these flags now for C++98 templates.  We'll update the
+            flags in store_init_value for instantiations and C++0x.  */
+         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+         if (decl_maybe_constant_var_p (decl))
+           TREE_CONSTANT (decl) = 1;
+       }
     }
 
   if (processing_template_decl)
@@ -5512,22 +5840,16 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          DECL_INITIAL (decl) = NULL_TREE;
        }
 
-      if (init && init_const_expr_p)
-       {
-         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-         if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
-           TREE_CONSTANT (decl) = 1;
-       }
-
       /* Generally, initializers in templates are expanded when the
-        template is instantiated.  But, if DECL is an integral
-        constant static data member, then it can be used in future
-        integral constant expressions, and its value must be
-        available. */
+        template is instantiated.  But, if DECL is a variable constant
+        then it can be used in future constant expressions, so its value
+        must be available. */
       if (!(init
            && DECL_CLASS_SCOPE_P (decl)
-           && DECL_INTEGRAL_CONSTANT_VAR_P (decl)
+           /* We just set TREE_CONSTANT appropriately; see above.  */
+           && TREE_CONSTANT (decl)
            && !type_dependent_p
+           /* FIXME non-value-dependent constant expression  */
            && !value_dependent_init_p (init)))
        {
          if (init)
@@ -5575,7 +5897,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
        TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
 
-      rest_of_decl_compilation (decl, DECL_CONTEXT (decl) == NULL_TREE,
+      rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl),
                                at_eof);
       goto finish_end;
     }
@@ -5591,11 +5913,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
-      /* Only PODs can have thread-local storage.  Other types may require
-        various kinds of non-trivial initialization.  */
-      if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
-       error ("%qD cannot be thread-local because it has non-POD type %qT",
-              decl, TREE_TYPE (decl));
+      /* Only variables with trivial initialization and destruction can
+        have thread-local storage.  */
+      if (DECL_THREAD_LOCAL_P (decl)
+         && (type_has_nontrivial_default_init (TREE_TYPE (decl))
+             || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+       error ("%qD cannot be thread-local because it has non-trivial "
+              "type %qT", decl, TREE_TYPE (decl));
       /* If this is a local variable that will need a mangled name,
         register it now.  We must do this before processing the
         initializer for the variable, since the initialization might
@@ -5605,7 +5929,17 @@ 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.  */
+           add_local_decl (cfun, decl);
+       }
+
       /* Convert the initializer to the type of DECL, if we have not
         already initialized DECL.  */
       if (!DECL_INITIALIZED_P (decl)
@@ -5629,16 +5963,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
                error ("Java object %qD not allocated with %<new%>", decl);
              init = NULL_TREE;
            }
-         if (init)
-           {
-             DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
-             if (init_const_expr_p)
-               {
-                 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-                 if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
-                   TREE_CONSTANT (decl) = 1;
-               }
-           }
          init = check_initializer (decl, init, flags, &cleanup);
          /* Thread-local storage cannot be dynamically initialized.  */
          if (DECL_THREAD_LOCAL_P (decl) && init)
@@ -5698,6 +6022,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))
@@ -5757,25 +6090,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        {
          if (init)
            {
-             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;
-               }
-             else if (init == ridpointers[(int)RID_DEFAULT])
+             if (init == ridpointers[(int)RID_DEFAULT])
                {
-                 if (!defaultable_fn_p (decl))
-                   error ("%qD cannot be defaulted", decl);
-                 else
-                   {
-                     /* An out-of-class default definition is defined at
-                        the point where it is explicitly defaulted.  */
-                     DECL_DEFAULTED_FN (decl) = 1;
-                     if (DECL_INITIAL (decl) == error_mark_node)
-                       synthesize_method (decl);
-                   }
+                 /* An out-of-class default definition is defined at
+                    the point where it is explicitly defaulted.  */
+                 if (DECL_INITIAL (decl) == error_mark_node)
+                   synthesize_method (decl);
                }
              else
                error ("function %q#D is initialized like a variable", decl);
@@ -5816,18 +6136,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (was_readonly)
     TREE_READONLY (decl) = 1;
-
-  /* If this was marked 'used', be sure it will be output.  */
-  if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
-    mark_decl_referenced (decl);
-}
-
-/* This is here for a midend callback from c-common.c.  */
-
-void
-finish_decl (tree decl, tree init, tree asmspec_tree)
-{
-  cp_finish_decl (decl, init, /*init_const_expr_p=*/false, asmspec_tree, 0);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -5843,7 +6151,7 @@ declare_global_var (tree name, tree type)
   tree decl;
 
   push_to_top_level ();
-  decl = build_decl (VAR_DECL, name, type);
+  decl = build_decl (input_location, VAR_DECL, name, type);
   TREE_PUBLIC (decl) = 1;
   DECL_EXTERNAL (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
@@ -5852,7 +6160,7 @@ declare_global_var (tree name, tree type)
      library), then it is possible that our declaration will be merged
      with theirs by pushdecl.  */
   decl = pushdecl (decl);
-  finish_decl (decl, NULL_TREE, NULL_TREE);
+  cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
   pop_from_top_level ();
 
   return decl;
@@ -5865,20 +6173,21 @@ declare_global_var (tree name, tree type)
 static tree
 get_atexit_fn_ptr_type (void)
 {
-  tree arg_types;
   tree fn_type;
 
   if (!atexit_fn_ptr_type_node)
     {
+      tree arg_type;
       if (flag_use_cxa_atexit 
          && !targetm.cxx.use_atexit_for_cxa_atexit ())
        /* The parameter to "__cxa_atexit" is "void (*)(void *)".  */
-       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+       arg_type = ptr_type_node;
       else
        /* The parameter to "atexit" is "void (*)(void)".  */
-       arg_types = void_list_node;
+       arg_type = NULL_TREE;
       
-      fn_type = build_function_type (void_type_node, arg_types);
+      fn_type = build_function_type_list (void_type_node,
+                                         arg_type, NULL_TREE);
       atexit_fn_ptr_type_node = build_pointer_type (fn_type);
     }
 
@@ -5893,7 +6202,6 @@ static tree
 get_atexit_node (void)
 {
   tree atexit_fndecl;
-  tree arg_types;
   tree fn_type;
   tree fn_ptr_type;
   const char *name;
@@ -5908,27 +6216,30 @@ get_atexit_node (void)
 
           int __cxa_atexit (void (*)(void *), void *, void *)
 
-        We build up the argument types and then then function type
+        We build up the argument types and then the function type
         itself.  */
+      tree argtype0, argtype1, argtype2;
 
       use_aeabi_atexit = targetm.cxx.use_aeabi_atexit ();
       /* First, build the pointer-to-function type for the first
         argument.  */
       fn_ptr_type = get_atexit_fn_ptr_type ();
       /* Then, build the rest of the argument types.  */
-      arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+      argtype2 = ptr_type_node;
       if (use_aeabi_atexit)
        {
-         arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types);
-         arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
+         argtype1 = fn_ptr_type;
+         argtype0 = ptr_type_node;
        }
       else
        {
-         arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
-         arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types);
+         argtype1 = ptr_type_node;
+         argtype0 = fn_ptr_type;
        }
       /* And the final __cxa_atexit type.  */
-      fn_type = build_function_type (integer_type_node, arg_types);
+      fn_type = build_function_type_list (integer_type_node,
+                                         argtype0, argtype1, argtype2,
+                                         NULL_TREE);
       fn_ptr_type = build_pointer_type (fn_type);
       if (use_aeabi_atexit)
        name = "__aeabi_atexit";
@@ -5941,12 +6252,12 @@ get_atexit_node (void)
 
           int atexit (void (*)());
 
-        We build up the argument types and then then function type
+        We build up the argument types and then the function type
         itself.  */
       fn_ptr_type = get_atexit_fn_ptr_type ();
-      arg_types = tree_cons (NULL_TREE, fn_ptr_type, void_list_node);
       /* Build the final atexit type.  */
-      fn_type = build_function_type (integer_type_node, arg_types);
+      fn_type = build_function_type_list (integer_type_node,
+                                         fn_ptr_type, NULL_TREE);
       name = "atexit";
     }
 
@@ -6007,6 +6318,7 @@ start_cleanup_fn (void)
      actually needed.  It is unlikely that it will be inlined, since
      it is only called via a function pointer, but we avoid unnecessary
      emissions this way.  */
+  DECL_DECLARED_INLINE_P (fndecl) = 1;
   DECL_INTERFACE_KNOWN (fndecl) = 1;
   /* Build the parameter.  */
   if (use_cxa_atexit)
@@ -6016,6 +6328,7 @@ start_cleanup_fn (void)
       parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
       DECL_CONTEXT (parmdecl) = fndecl;
       TREE_USED (parmdecl) = 1;
+      DECL_READ_P (parmdecl) = 1;
       DECL_ARGUMENTS (fndecl) = parmdecl;
     }
 
@@ -6045,10 +6358,10 @@ register_dtor_fn (tree decl)
 {
   tree cleanup;
   tree compound_stmt;
-  tree args;
   tree fcall;
   tree type;
   bool use_dtor;
+  tree arg0, arg1 = NULL_TREE, arg2 = NULL_TREE;
 
   type = TREE_TYPE (decl);
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
@@ -6126,25 +6439,23 @@ register_dtor_fn (tree decl)
           in, and, in general, it's cheaper to pass NULL than any
           other value.  */
        addr = null_pointer_node;
-      args = tree_cons (NULL_TREE,
-                       cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
-                                        tf_warning_or_error),
-                       NULL_TREE);
+      arg2 = cp_build_addr_expr (get_dso_handle_node (),
+                                tf_warning_or_error);
       if (targetm.cxx.use_aeabi_atexit ())
        {
-         args = tree_cons (NULL_TREE, cleanup, args);
-         args = tree_cons (NULL_TREE, addr, args);
+         arg1 = cleanup;
+         arg0 = addr;
        }
       else
        {
-         args = tree_cons (NULL_TREE, addr, args);
-         args = tree_cons (NULL_TREE, cleanup, args);
+         arg1 = addr;
+         arg0 = cleanup;
        }
     }
   else
-    args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
-  return cp_build_function_call (get_atexit_node (), args, 
-                                tf_warning_or_error);
+    arg0 = cleanup;
+  return cp_build_function_call_nary (get_atexit_node (), tf_warning_or_error,
+                                     arg0, arg1, arg2, NULL_TREE);
 }
 
 /* DECL is a VAR_DECL with static storage duration.  INIT, if present,
@@ -6157,9 +6468,8 @@ expand_static_init (tree decl, tree init)
   gcc_assert (TREE_CODE (decl) == VAR_DECL);
   gcc_assert (TREE_STATIC (decl));
 
-  /* Some variables require no initialization.  */
+  /* Some variables require no dynamic initialization.  */
   if (!init
-      && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
       && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     return;
 
@@ -6226,11 +6536,13 @@ expand_static_init (tree decl, tree init)
          abort_fn = get_identifier ("__cxa_guard_abort");
          if (!get_global_value_if_present (acquire_fn, &acquire_fn))
            {
-             tree argtypes = tree_cons (NULL_TREE, TREE_TYPE (guard_addr),
-                                        void_list_node);
-             tree vfntype = build_function_type (void_type_node, argtypes);
+             tree vfntype = build_function_type_list (void_type_node,
+                                                      TREE_TYPE (guard_addr),
+                                                      NULL_TREE);
              acquire_fn = push_library_fn
-               (acquire_fn, build_function_type (integer_type_node, argtypes),
+               (acquire_fn, build_function_type_list (integer_type_node,
+                                                      TREE_TYPE (guard_addr),
+                                                      NULL_TREE),
                 NULL_TREE);
              release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
              abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
@@ -6380,21 +6692,54 @@ member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
 
 static void
 bad_specifiers (tree object,
-               const char* type,
+               enum bad_spec_place type,
                int virtualp,
                int quals,
                int inlinep,
                int friendp,
                int raises)
 {
-  if (virtualp)
-    error ("%qD declared as a %<virtual%> %s", object, type);
-  if (inlinep)
-    error ("%qD declared as an %<inline%> %s", object, type);
-  if (quals)
-    error ("%<const%> and %<volatile%> function specifiers on "
-          "%qD invalid in %s declaration",
-          object, type);
+  switch (type)
+    {
+      case BSP_VAR:
+       if (virtualp)
+         error ("%qD declared as a %<virtual%> variable", object);
+       if (inlinep)
+         error ("%qD declared as an %<inline%> variable", object);
+       if (quals)
+         error ("%<const%> and %<volatile%> function specifiers on "
+                "%qD invalid in variable declaration", object);
+       break;
+      case BSP_PARM:
+       if (virtualp)
+         error ("%qD declared as a %<virtual%> parameter", object);
+       if (inlinep)
+         error ("%qD declared as an %<inline%> parameter", object);
+       if (quals)
+         error ("%<const%> and %<volatile%> function specifiers on "
+                "%qD invalid in parameter declaration", object);
+       break;
+      case BSP_TYPE:
+       if (virtualp)
+         error ("%qD declared as a %<virtual%> type", object);
+       if (inlinep)
+         error ("%qD declared as an %<inline%> type", object);
+       if (quals)
+         error ("%<const%> and %<volatile%> function specifiers on "
+                "%qD invalid in type declaration", object);
+       break;
+      case BSP_FIELD:
+       if (virtualp)
+         error ("%qD declared as a %<virtual%> field", object);
+       if (inlinep)
+         error ("%qD declared as an %<inline%> field", object);
+       if (quals)
+         error ("%<const%> and %<volatile%> function specifiers on "
+                "%qD invalid in field declaration", object);
+       break;
+      default:
+        gcc_unreachable();
+    }
   if (friendp)
     error ("%q+D declared as a friend", object);
   if (raises
@@ -6498,7 +6843,8 @@ grokfndecl (tree ctype,
            bool funcdef_flag,
            int template_count,
            tree in_namespace,
-           tree* attrlist)
+           tree* attrlist,
+           location_t location)
 {
   tree decl;
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
@@ -6508,14 +6854,22 @@ grokfndecl (tree ctype,
     type = build_exception_variant (type, raises);
 
   decl = build_lang_decl (FUNCTION_DECL, declarator, type);
+
+  /* If we have an explicit location, use it, otherwise use whatever
+     build_lang_decl used (probably input_location).  */
+  if (location != UNKNOWN_LOCATION)
+    DECL_SOURCE_LOCATION (decl) = location;
+
   if (TREE_CODE (type) == METHOD_TYPE)
     {
       tree parm;
       parm = build_this_parm (type, quals);
-      TREE_CHAIN (parm) = parms;
+      DECL_CHAIN (parm) = parms;
       parms = parm;
     }
   DECL_ARGUMENTS (decl) = parms;
+  for (t = parms; t; t = DECL_CHAIN (t))
+    DECL_CONTEXT (t) = decl;
   /* Propagate volatile out from type to decl.  */
   if (TYPE_VOLATILE (type))
     TREE_THIS_VOLATILE (decl) = 1;
@@ -6525,6 +6879,7 @@ grokfndecl (tree ctype,
     {
     case sfk_constructor:
     case sfk_copy_constructor:
+    case sfk_move_constructor:
       DECL_CONSTRUCTOR_P (decl) = 1;
       break;
     case sfk_destructor:
@@ -6581,7 +6936,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)
@@ -6607,7 +6962,7 @@ grokfndecl (tree ctype,
   if (in_namespace)
     set_decl_namespace (decl, in_namespace, friendp);
   else if (!ctype)
-    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+    DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());
 
   /* `main' and builtins have implicit 'C' linkage.  */
   if ((MAIN_NAME_P (declarator)
@@ -6617,8 +6972,7 @@ grokfndecl (tree ctype,
           && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
       && current_lang_name == lang_name_cplusplus
       && ctype == NULL_TREE
-      /* NULL_TREE means global namespace.  */
-      && DECL_CONTEXT (decl) == NULL_TREE)
+      && DECL_FILE_SCOPE_P (decl))
     SET_DECL_LANGUAGE (decl, lang_c);
 
   /* Should probably propagate const out from type to decl I bet (mrs).  */
@@ -6653,13 +7007,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)
@@ -6670,8 +7024,9 @@ grokfndecl (tree ctype,
                /* Allow this; it's pretty common in C.  */;
              else
                {
-                 permerror (input_location, "non-local function %q#D uses anonymous type",
-                             decl);
+                 permerror (input_location, "anonymous type with no linkage "
+                            "used to declare function %q#D with linkage",
+                            decl);
                  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
                    permerror (input_location, "%q+#D does not refer to the unqualified "
                               "type, so it is not used for linkage",
@@ -6679,7 +7034,8 @@ grokfndecl (tree ctype,
                }
            }
          else
-           permerror (input_location, "non-local function %q#D uses local type %qT", decl, t);
+           permerror (input_location, "type %qT with no linkage used to "
+                      "declare function %q#D with linkage", t, decl);
        }
     }
 
@@ -6693,6 +7049,8 @@ grokfndecl (tree ctype,
   /* If the declaration was declared inline, mark it as such.  */
   if (inlinep)
     DECL_DECLARED_INLINE_P (decl) = 1;
+  if (inlinep & 2)
+    DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
   DECL_EXTERNAL (decl) = 1;
   if (quals && TREE_CODE (type) == FUNCTION_TYPE)
@@ -6708,9 +7066,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.  */
@@ -6870,7 +7225,7 @@ grokvardecl (tree type,
       /* An explicit "extern" specifier indicates a namespace-scope
         variable.  */
       if (declspecs->storage_class == sc_extern)
-       scope = current_namespace;
+       scope = current_decl_namespace ();
       else if (!at_function_scope_p ())
        scope = current_scope ();
     }
@@ -6887,7 +7242,7 @@ grokvardecl (tree type,
          || TYPE_P (scope)))
     decl = build_lang_decl (VAR_DECL, name, type);
   else
-    decl = build_decl (VAR_DECL, name, type);
+    decl = build_decl (input_location, VAR_DECL, name, type);
 
   if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL)
     set_decl_namespace (decl, explicit_scope, 0);
@@ -6925,29 +7280,39 @@ 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
                     no linkage can only be used to declare extern "C"
                     entities.  Since it's not always an error in the
                     ISO C++ 90 Standard, we only issue a warning.  */
-                 warning (0, "non-local variable %q#D uses anonymous type",
-                          decl);
+                 warning (0, "anonymous type with no linkage used to declare "
+                          "variable %q#D with linkage", decl);
                  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
                    warning (0, "%q+#D does not refer to the unqualified "
                             "type, so it is not used for linkage",
@@ -6955,7 +7320,8 @@ grokvardecl (tree type,
                }
            }
          else
-           warning (0, "non-local variable %q#D uses local type %qT", decl, t);
+           warning (0, "type %qT with no linkage used to declare variable "
+                    "%q#D with linkage", t, decl);
        }
     }
   else
@@ -6998,11 +7364,12 @@ build_ptrmemfunc_type (tree type)
   /* ... and not really a class type.  */
   SET_CLASS_TYPE_P (t, 0);
 
-  field = build_decl (FIELD_DECL, pfn_identifier, type);
+  field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
   fields = field;
 
-  field = build_decl (FIELD_DECL, delta_identifier, delta_type_node);
-  TREE_CHAIN (field) = fields;
+  field = build_decl (input_location, FIELD_DECL, delta_identifier, 
+                     delta_type_node);
+  DECL_CHAIN (field) = fields;
   fields = field;
 
   finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node);
@@ -7014,10 +7381,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;
@@ -7043,16 +7414,8 @@ 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));
+      cp_cv_quals quals = type_memfn_quals (member_type);
+      member_type = build_memfn_type (member_type, class_type, quals);
       return build_ptrmemfunc_type (build_pointer_type (member_type));
     }
   else
@@ -7070,6 +7433,21 @@ build_ptrmem_type (tree class_type, tree member_type)
 int
 check_static_variable_definition (tree decl, tree type)
 {
+  /* If DECL is declared constexpr, we'll do the appropriate checks
+     in check_initializer.  */
+  if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
+    return 0;
+  else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+    {
+      if (literal_type_p (type))
+       error ("%<constexpr%> needed for in-class initialization of static "
+              "data member %q#D of non-integral type", decl);
+      else
+       error ("in-class initialization of static data member %q#D of "
+              "non-literal type", decl);
+      return 1;
+    }
+
   /* Motion 10 at San Diego: If a static const integral data member is
      initialized with an integral constant expression, the initializer
      may appear either in the declaration (within the class), or in
@@ -7081,17 +7459,13 @@ check_static_variable_definition (tree decl, tree type)
       error ("invalid in-class initialization of static data member "
             "of non-integral type %qT",
             type);
-      /* If we just return the declaration, crashes will sometimes
-        occur.  We therefore return void_type_node, as if this were a
-        friend declaration, to cause callers to completely ignore
-        this declaration.  */
       return 1;
     }
   else if (!CP_TYPE_CONST_P (type))
     error ("ISO C++ forbids in-class initialization of non-const "
           "static member %qD",
           decl);
-  else if (!INTEGRAL_TYPE_P (type))
+  else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     pedwarn (input_location, OPT_pedantic, "ISO C++ forbids initialization of member constant "
             "%qD of non-integral type %qT", decl, type);
 
@@ -7103,34 +7477,75 @@ check_static_variable_definition (tree decl, tree type)
    name of the thing being declared.  */
 
 tree
-compute_array_index_type (tree name, tree size)
+compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
 {
   tree type;
   tree itype;
+  tree osize = size;
   tree abi_1_itype = NULL_TREE;
 
   if (error_operand_p (size))
     return error_mark_node;
 
   type = TREE_TYPE (size);
-  /* The array bound must be an integer type.  */
-  if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
+  /* type_dependent_expression_p? */
+  if (!dependent_type_p (type))
     {
-      if (name)
-       error ("size of array %qD has non-integral type %qT", name, type);
+      mark_rvalue_use (size);
+
+      if (cxx_dialect < cxx0x && TREE_CODE (size) == NOP_EXPR
+         && TREE_SIDE_EFFECTS (size))
+       /* In C++98, we mark a non-constant array bound with a magic
+          NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case.  */;
       else
-       error ("size of array has non-integral type %qT", type);
-      size = integer_one_node;
-      type = TREE_TYPE (size);
+       {
+         size = fold_non_dependent_expr (size);
+
+         if (CLASS_TYPE_P (type)
+             && CLASSTYPE_LITERAL_P (type))
+           {
+             size = build_expr_type_conversion (WANT_INT, size, true);
+             if (size == error_mark_node)
+               return error_mark_node;
+             type = TREE_TYPE (size);
+           }
+
+         size = maybe_constant_value (size);
+       }
+
+      if (error_operand_p (size))
+       return error_mark_node;
+
+      /* The array bound must be an integer type.  */
+      if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+       {
+         if (!(complain & tf_error))
+           return error_mark_node;
+         if (name)
+           error ("size of array %qD has non-integral type %qT", name, type);
+         else
+           error ("size of array has non-integral type %qT", type);
+         size = integer_one_node;
+         type = TREE_TYPE (size);
+       }
     }
 
-  if (value_dependent_expression_p (size))
+  /* A type is dependent if it is...an array type constructed from any
+     dependent type or whose size is specified by a constant expression
+     that is value-dependent.  */
+  /* We can only call value_dependent_expression_p on integral constant
+     expressions; treat non-constant expressions as dependent, too.  */
+  if (processing_template_decl
+      && (dependent_type_p (type)
+         || !TREE_CONSTANT (size) || value_dependent_expression_p (size)))
     {
-      /* We cannot do any checking for a value-dependent SIZE. Just
-        build the index type and mark that it requires structural
-        equality checks.  */
+      /* We cannot do any checking for a SIZE that isn't known to be
+        constant. Just build the index type and mark that it requires
+        structural equality checks.  */
       itype = build_index_type (build_min (MINUS_EXPR, sizetype,
                                           size, integer_one_node));
+      TYPE_DEPENDENT_P (itype) = 1;
+      TYPE_DEPENDENT_P_VALID (itype) = 1;
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
       return itype;
     }
@@ -7143,13 +7558,7 @@ compute_array_index_type (tree name, tree size)
        would have, but with TYPE_CANONICAL set to the "right"
        value that the current ABI would provide. */
     abi_1_itype = build_index_type (build_min (MINUS_EXPR, sizetype,
-                                              size, integer_one_node));
-
-  /* The size might be the result of a cast.  */
-  STRIP_TYPE_NOPS (size);
-
-  /* It might be a const variable or enumeration constant.  */
-  size = integral_constant_value (size);
+                                              osize, integer_one_node));
 
   /* Normally, the array-bound will be a constant.  */
   if (TREE_CODE (size) == INTEGER_CST)
@@ -7161,24 +7570,37 @@ compute_array_index_type (tree name, tree size)
       /* An array must have a positive number of elements.  */
       if (INT_CST_LT (size, integer_zero_node))
        {
+         if (!(complain & tf_error))
+           return error_mark_node;
          if (name)
            error ("size of array %qD is negative", name);
          else
            error ("size of array is negative");
          size = integer_one_node;
        }
-      /* As an extension we allow zero-sized arrays.  We always allow
-        them in system headers because glibc uses them.  */
-      else if (integer_zerop (size) && !in_system_header)
+      /* As an extension we allow zero-sized arrays.  */
+      else if (integer_zerop (size))
        {
-         if (name)
+         if (!(complain & tf_error))
+           /* We must fail if performing argument deduction (as
+              indicated by the state of complain), so that
+              another substitution can be found.  */
+           return error_mark_node;
+         else if (in_system_header)
+           /* Allow them in system headers because glibc uses them.  */;
+         else if (name)
            pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
          else
            pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array");
        }
     }
-  else if (TREE_CONSTANT (size))
+  else if (TREE_CONSTANT (size)
+          /* We don't allow VLAs at non-function scopes, or during
+             tentative template substitution.  */
+          || !at_function_scope_p () || !(complain & tf_error))
     {
+      if (!(complain & tf_error))
+       return error_mark_node;
       /* `(int) &fn' is not a valid array bound.  */
       if (name)
        error ("size of array %qD is not an integral constant-expression",
@@ -7217,7 +7639,8 @@ compute_array_index_type (tree name, tree size)
         cp_build_binary_op will be appropriately folded.  */
       saved_processing_template_decl = processing_template_decl;
       processing_template_decl = 0;
-      itype = cp_build_binary_op (MINUS_EXPR,
+      itype = cp_build_binary_op (input_location,
+                                 MINUS_EXPR,
                                  cp_convert (ssizetype, size),
                                  cp_convert (ssizetype, integer_one_node),
                                  tf_warning_or_error);
@@ -7233,6 +7656,8 @@ compute_array_index_type (tree name, tree size)
       else if (TREE_CODE (itype) == INTEGER_CST
               && TREE_OVERFLOW (itype))
        {
+         if (!(complain & tf_error))
+           return error_mark_node;
          error ("overflow in array dimension");
          TREE_OVERFLOW (itype) = 0;
        }
@@ -7243,10 +7668,16 @@ compute_array_index_type (tree name, tree size)
     {
       tree t = build_index_type (itype);
       TYPE_CANONICAL (abi_1_itype) = TYPE_CANONICAL (t);
-      return abi_1_itype;
+      itype = abi_1_itype;
     }
   else
-    return build_index_type (itype);
+    itype = build_index_type (itype);
+
+  /* If the index type were dependent, we would have returned early, so
+     remember that it isn't.  */
+  TYPE_DEPENDENT_P (itype) = 0;
+  TYPE_DEPENDENT_P_VALID (itype) = 1;
+  return itype;
 }
 
 /* Returns the scope (if any) in which the entity declared by
@@ -7278,47 +7709,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]
@@ -7340,7 +7769,7 @@ create_array_type_for_decl (tree name, tree type, tree size)
 
   /* Figure out the index type for the array.  */
   if (size)
-    itype = compute_array_index_type (name, size);
+    itype = compute_array_index_type (name, size, tf_warning_or_error);
 
   /* [dcl.array]
      T is called the array element type; this type shall not be [...] an
@@ -7444,11 +7873,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
@@ -7478,6 +7909,7 @@ grokdeclarator (const cp_declarator *declarator,
 {
   tree type = NULL_TREE;
   int longlong = 0;
+  int explicit_int128 = 0;
   int virtualp, explicitp, friendp, inlinep, staticp;
   int explicit_int = 0;
   int explicit_char = 0;
@@ -7531,13 +7963,17 @@ 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];
   unsigned_p = declspecs->specs[(int)ds_unsigned];
   short_p = declspecs->specs[(int)ds_short];
   long_p = declspecs->specs[(int)ds_long];
   longlong = declspecs->specs[(int)ds_long] >= 2;
+  explicit_int128 = declspecs->explicit_int128_p;
   thread_p = declspecs->specs[(int)ds_thread];
 
   if (decl_context == FUNCDEF)
@@ -7546,6 +7982,10 @@ grokdeclarator (const cp_declarator *declarator,
     funcdef_flag = true, decl_context = FIELD;
   else if (decl_context == BITFIELD)
     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;
@@ -7634,7 +8074,9 @@ grokdeclarator (const cp_declarator *declarator,
                    }
 
                  type = TREE_OPERAND (decl, 0);
-                 name = IDENTIFIER_POINTER (constructor_name (type));
+                 if (TYPE_P (type))
+                   type = constructor_name (type);
+                 name = identifier_to_locale (IDENTIFIER_POINTER (type));
                  dname = decl;
                }
                break;
@@ -7660,10 +8102,10 @@ grokdeclarator (const cp_declarator *declarator,
                  {
                    error ("declarator-id missing; using reserved word %qD",
                           dname);
-                   name = IDENTIFIER_POINTER (dname);
+                   name = identifier_to_locale (IDENTIFIER_POINTER (dname));
                  }
                else if (!IDENTIFIER_TYPENAME_P (dname))
-                 name = IDENTIFIER_POINTER (dname);
+                 name = identifier_to_locale (IDENTIFIER_POINTER (dname));
                else
                  {
                    gcc_assert (flags == NO_SPECIAL);
@@ -7671,7 +8113,7 @@ grokdeclarator (const cp_declarator *declarator,
                    ctor_return_type = TREE_TYPE (dname);
                    sfk = sfk_conversion;
                    if (is_typename_at_global_scope (dname))
-                     name = IDENTIFIER_POINTER (dname);
+                     name = identifier_to_locale (IDENTIFIER_POINTER (dname));
                    else
                      name = "<invalid operator>";
                  }
@@ -7743,6 +8185,12 @@ grokdeclarator (const cp_declarator *declarator,
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
 
+  if (constexpr_p && declspecs->specs[(int)ds_typedef])
+    {
+      error ("%<constexpr%> cannot appear in a typedef declaration");
+      return error_mark_node;
+    }
+
   /* If there were multiple types specified in the decl-specifier-seq,
      issue an error message.  */
   if (declspecs->multiple_types_p)
@@ -7768,7 +8216,7 @@ grokdeclarator (const cp_declarator *declarator,
      suppress reports of deprecated items.  */
   if (type && TREE_DEPRECATED (type)
       && deprecated_state != DEPRECATED_SUPPRESS)
-    warn_deprecated_use (type);
+    warn_deprecated_use (type, NULL_TREE);
   if (type && TREE_CODE (type) == TYPE_DECL)
     {
       typedef_decl = type;
@@ -7776,7 +8224,7 @@ grokdeclarator (const cp_declarator *declarator,
       if (TREE_DEPRECATED (type)
          && DECL_ARTIFICIAL (typedef_decl)
          && deprecated_state != DEPRECATED_SUPPRESS)
-       warn_deprecated_use (type);
+       warn_deprecated_use (type, NULL_TREE);
     }
   /* No type at all: default to `int', and set DEFAULTED_INT
      because it was not a user-defined typedef.  */
@@ -7814,7 +8262,8 @@ grokdeclarator (const cp_declarator *declarator,
         common.  With no options, it is allowed.  With -Wreturn-type,
         it is a warning.  It is only an error with -pedantic-errors.  */
       is_main = (funcdef_flag
-                && dname && MAIN_NAME_P (dname)
+                && dname && TREE_CODE (dname) == IDENTIFIER_NODE
+                && MAIN_NAME_P (dname)
                 && ctype == NULL_TREE
                 && in_namespace == NULL_TREE
                 && current_namespace == global_namespace);
@@ -7844,8 +8293,8 @@ grokdeclarator (const cp_declarator *declarator,
   if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
       long_p = false;
-      type = build_qualified_type (long_double_type_node,
-                                  cp_type_quals (type));
+      type = cp_build_qualified_type (long_double_type_node,
+                                     cp_type_quals (type));
     }
 
   /* Check all other uses of type modifiers.  */
@@ -7860,12 +8309,16 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<signed%> and %<unsigned%> specified together for %qs", name);
       else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long long%> invalid for %qs", name);
+      else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE)
+       error ("%<__int128%> invalid for %qs", name);
       else if (long_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<long%> invalid for %qs", name);
       else if (short_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<short%> invalid for %qs", name);
       else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long%> or %<short%> invalid for %qs", name);
+      else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128)
+       error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
       else if ((long_p || short_p) && explicit_char)
        error ("%<long%> or %<short%> specified with char for %qs", name);
       else if (long_p && short_p)
@@ -7880,7 +8333,7 @@ grokdeclarator (const cp_declarator *declarator,
       else
        {
          ok = 1;
-         if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
+         if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic)
            {
              pedwarn (input_location, OPT_pedantic, 
                       "long, short, signed or unsigned used invalidly for %qs",
@@ -7888,6 +8341,22 @@ grokdeclarator (const cp_declarator *declarator,
              if (flag_pedantic_errors)
                ok = 0;
            }
+         if (explicit_int128)
+           {
+             if (int128_integer_type_node == NULL_TREE)
+               {
+                 error ("%<__int128%> is not supported by this target");
+                 ok = 0;
+               }
+             else if (pedantic)
+               {
+                 pedwarn (input_location, OPT_pedantic,
+                          "ISO C++ does not support %<__int128%> for %qs",
+                          name);
+                 if (flag_pedantic_errors)
+                   ok = 0;
+               }
+           }
        }
 
       /* Discard the type modifiers if they are invalid.  */
@@ -7898,6 +8367,7 @@ grokdeclarator (const cp_declarator *declarator,
          long_p = false;
          short_p = false;
          longlong = 0;
+         explicit_int128 = false;
        }
     }
 
@@ -7922,7 +8392,9 @@ grokdeclarator (const cp_declarator *declarator,
          && TREE_CODE (type) == INTEGER_TYPE
          && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
     {
-      if (longlong)
+      if (explicit_int128)
+       type = int128_unsigned_type_node;
+      else if (longlong)
        type = long_long_unsigned_type_node;
       else if (long_p)
        type = long_unsigned_type_node;
@@ -7937,6 +8409,8 @@ grokdeclarator (const cp_declarator *declarator,
     }
   else if (signed_p && type == char_type_node)
     type = signed_char_type_node;
+  else if (explicit_int128)
+    type = int128_integer_type_node;
   else if (longlong)
     type = long_long_integer_type_node;
   else if (long_p)
@@ -7952,8 +8426,7 @@ grokdeclarator (const cp_declarator *declarator,
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
         "complex short int".  */
-
-      else if (defaulted_int && ! longlong
+      else if (defaulted_int && ! longlong && ! explicit_int128
               && ! (long_p || short_p || signed_p || unsigned_p))
        type = complex_double_type_node;
       else if (type == integer_type_node)
@@ -7979,21 +8452,6 @@ grokdeclarator (const cp_declarator *declarator,
     error ("qualifiers are not allowed on declaration of %<operator %T%>",
           ctor_return_type);
 
-  if (TREE_CODE (type) == FUNCTION_TYPE
-      && type_quals != TYPE_UNQUALIFIED)
-    {
-      /* 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)
-       {
-         tree bad_type = build_qualified_type (type, type_quals);
-         pedwarn (input_location, OPT_pedantic, 
-                  "ignoring %qV qualifiers added to function type %qT",
-                  bad_type, type);
-       }
-      type_quals = TYPE_UNQUALIFIED;
-    }
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
@@ -8032,10 +8490,29 @@ 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)
        error ("storage class specifiers invalid in parameter declarations");
+
+      if (type_uses_auto (type))
+       {
+         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.  */
@@ -8130,8 +8607,9 @@ grokdeclarator (const cp_declarator *declarator,
       switch (TREE_CODE (unqualified_id))
        {
        case BIT_NOT_EXPR:
-         unqualified_id
-           = constructor_name (TREE_OPERAND (unqualified_id, 0));
+         unqualified_id = TREE_OPERAND (unqualified_id, 0);
+         if (TYPE_P (unqualified_id))
+           unqualified_id = constructor_name (unqualified_id);
          break;
 
        case IDENTIFIER_NODE:
@@ -8198,7 +8676,12 @@ 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)
+             {
+               error (errmsg);
+               type = integer_type_node;
              }
 
            /* Error about some types functions can't return.  */
@@ -8220,16 +8703,41 @@ grokdeclarator (const cp_declarator *declarator,
            /* Pick up the exception specifications.  */
            raises = declarator->u.function.exception_specification;
 
+           /* Say it's a definition only for the CALL_EXPR
+              closest to the identifier.  */
+           funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
+
            /* Handle a late-specified return type.  */
+           if (funcdecl_p)
+             {
+               if (type_uses_auto (type))
+                 {
+                   if (!declarator->u.function.late_return_type)
+                     {
+                       error ("%qs function uses %<auto%> type specifier without"
+                              " late return type", name);
+                       return error_mark_node;
+                     }
+                   else if (!is_auto (type))
+                     {
+                       error ("%qs function with late return type has"
+                              " %qT as its type rather than plain %<auto%>",
+                              name, type);
+                       return error_mark_node;
+                     }
+                 }
+               else if (declarator->u.function.late_return_type)
+                 {
+                   error ("%qs function with late return type not declared"
+                          " with %<auto%> type specifier", name);
+                   return error_mark_node;
+                 }
+             }
            type = splice_late_return_type
              (type, declarator->u.function.late_return_type);
            if (type == error_mark_node)
              return error_mark_node;
 
-           /* Say it's a definition only for the CALL_EXPR
-              closest to the identifier.  */
-           funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
-
            if (ctype == NULL_TREE
                && decl_context == FIELD
                && funcdecl_p
@@ -8289,7 +8797,7 @@ grokdeclarator (const cp_declarator *declarator,
            else if (friendp)
              {
                if (initialized)
-                 error ("can't initialize friend function %qs", name);
+                 error ("can%'t initialize friend function %qs", name);
                if (virtualp)
                  {
                    /* Cannot be both friend and virtual.  */
@@ -8299,10 +8807,18 @@ grokdeclarator (const cp_declarator *declarator,
                if (decl_context == NORMAL)
                  error ("friend declaration not in class definition");
                if (current_function_decl && funcdef_flag)
-                 error ("can't define friend function %qs in a local "
+                 error ("can%'t define friend function %qs in a local "
                         "class definition",
                         name);
              }
+           else if (ctype && sfk == sfk_conversion)
+             {
+               if (explicitp == 1)
+                 {
+                   maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
+                   explicitp = 2;
+                 }
+             }
 
            arg_types = grokparms (declarator->u.function.parameters,
                                   &parms);
@@ -8364,13 +8880,50 @@ grokdeclarator (const cp_declarator *declarator,
              && (TREE_CODE (type) == FUNCTION_TYPE
                  || (memfn_quals && TREE_CODE (type) == METHOD_TYPE)))
            {
-             memfn_quals |= cp_type_quals (type);
+             memfn_quals |= type_memfn_quals (type);
              type = build_memfn_type (type,
                                       declarator->u.pointer.class_type,
                                       memfn_quals);
+             if (type == error_mark_node)
+               return error_mark_node;
              memfn_quals = TYPE_UNQUALIFIED;
            }
 
+         if (TREE_CODE (type) == FUNCTION_TYPE
+             && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+            error (declarator->kind == cdk_reference
+                   ? G_("cannot declare reference to qualified function type %qT")
+                   : G_("cannot declare pointer to qualified function type %qT"),
+                  type);
+
+         /* When the pointed-to type involves components of variable size,
+            care must be taken to ensure that the size evaluation code is
+            emitted early enough to dominate all the possible later uses
+            and late enough for the variables on which it depends to have
+            been assigned.
+
+            This is expected to happen automatically when the pointed-to
+            type has a name/declaration of it's own, but special attention
+            is required if the type is anonymous.
+
+            We handle the NORMAL and FIELD contexts here by inserting a
+            dummy statement that just evaluates the size at a safe point
+            and ensures it is not deferred until e.g. within a deeper
+            conditional context (c++/43555).
+
+            We expect nothing to be needed here for PARM or TYPENAME.
+            Evaluating the size at this point for TYPENAME would
+            actually be incorrect, as we might be in the middle of an
+            expression with side effects on the pointed-to type size
+            "arguments" prior to the pointer declaration point and the
+            size evaluation could end up prior to the side effects.  */
+
+         if (!TYPE_NAME (type)
+             && (decl_context == NORMAL || decl_context == FIELD)
+             && at_function_scope_p ()
+             && variably_modified_type_p (type, NULL_TREE))
+           finish_expr_stmt (TYPE_SIZE (type));
+
          if (declarator->kind == cdk_reference)
            {
              /* In C++0x, the type we are creating a reference to might be
@@ -8444,6 +8997,18 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
+  /* A `constexpr' specifier used in an object declaration declares
+     the object as `const'.  */
+  if (constexpr_p && innermost_code != cdk_function)
+    {
+      if (type_quals & TYPE_QUAL_CONST)
+        error ("both %<const%> and %<constexpr%> cannot be used here");
+      if (type_quals & TYPE_QUAL_VOLATILE)
+        error ("both %<volatile%> and %<constexpr%> cannot be used here");
+      type_quals |= TYPE_QUAL_CONST;
+      type = cp_build_qualified_type (type, type_quals);
+    }
+
   if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
       && TREE_CODE (type) != FUNCTION_TYPE
       && TREE_CODE (type) != METHOD_TYPE)
@@ -8530,8 +9095,6 @@ grokdeclarator (const cp_declarator *declarator,
        return error_mark_node;
       else if (TREE_CODE (type) == FUNCTION_TYPE)
        {
-         tree sname = declarator->u.id.unqualified_name;
-
          if (current_class_type
              && (!friendp || funcdef_flag))
            {
@@ -8541,14 +9104,6 @@ grokdeclarator (const cp_declarator *declarator,
                     ctype, name, current_class_type);
              return error_mark_node;
            }
-
-         if (TREE_CODE (sname) == IDENTIFIER_NODE
-             && NEW_DELETE_OPNAME_P (sname))
-           /* Overloaded operator new and operator delete
-              are always static functions.  */
-           ;
-         else
-           type = build_memfn_type (type, ctype, memfn_quals);
        }
       else if (declspecs->specs[(int)ds_typedef]
               && current_class_type)
@@ -8559,6 +9114,15 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
+  if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
+    ctype = current_class_type;
+
+  /* A constexpr non-static member function is implicitly const.  */
+  if (constexpr_p && ctype && staticp == 0
+      && TREE_CODE (type) == FUNCTION_TYPE
+      && sfk != sfk_constructor && sfk != sfk_destructor)
+    memfn_quals |= TYPE_QUAL_CONST;
+
   /* Now TYPE has the actual type.  */
 
   if (returned_attrs)
@@ -8662,7 +9226,7 @@ grokdeclarator (const cp_declarator *declarator,
         function type.  */
       if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
         {
-          type = cp_build_qualified_type (type, memfn_quals);
+          type = apply_memfn_quals (type, memfn_quals);
           
           /* We have now dealt with these qualifiers.  */
           memfn_quals = TYPE_UNQUALIFIED;
@@ -8671,9 +9235,12 @@ grokdeclarator (const cp_declarator *declarator,
       if (decl_context == FIELD)
        decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
-       decl = build_decl (TYPE_DECL, unqualified_id, type);
-      if (id_declarator && declarator->u.id.qualifying_scope)
-       error ("%Jtypedef name may not be a nested-name-specifier", decl);
+       decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
+      if (id_declarator && declarator->u.id.qualifying_scope) {
+       error_at (DECL_SOURCE_LOCATION (decl), 
+                 "typedef name may not be a nested-name-specifier");
+       TREE_TYPE (decl) = error_mark_node;
+      }
 
       if (decl_context != FIELD)
        {
@@ -8704,13 +9271,19 @@ grokdeclarator (const cp_declarator *declarator,
          && TYPE_ANONYMOUS_P (type)
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
-         tree oldname = TYPE_NAME (type);
          tree t;
 
          /* Replace the anonymous name with the real name everywhere.  */
          for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-           if (TYPE_NAME (t) == oldname)
-             TYPE_NAME (t) = decl;
+           {
+             if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+               /* We do not rename the debug info representing the
+                  anonymous tagged type because the standard says in
+                  [dcl.typedef] that the naming applies only for
+                  linkage purposes.  */
+               /*debug_hooks->set_name (t, decl);*/
+               TYPE_NAME (t) = decl;
+           }
 
          if (TYPE_LANG_SPECIFIC (type))
            TYPE_WAS_ANONYMOUS (type) = 1;
@@ -8722,6 +9295,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.  */
        }
@@ -8730,7 +9307,7 @@ grokdeclarator (const cp_declarator *declarator,
          || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
        C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
 
-      bad_specifiers (decl, "type", virtualp,
+      bad_specifiers (decl, BSP_TYPE, virtualp,
                      memfn_quals != TYPE_UNQUALIFIED,
                      inlinep, friendp, raises != NULL_TREE);
 
@@ -8755,11 +9332,13 @@ 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));
 
-         TREE_CHAIN (decl) = decls;
+         DECL_CHAIN (decl) = decls;
          decls = decl;
        }
 
@@ -8769,7 +9348,7 @@ grokdeclarator (const cp_declarator *declarator,
        {
          /* A cv-qualifier-seq shall only be part of the function type
             for a non-static member function. [8.3.5/4 dcl.fct] */
-         if (cp_type_quals (type) != TYPE_UNQUALIFIED
+         if (type_memfn_quals (type) != TYPE_UNQUALIFIED
              && (current_class_type == NULL_TREE || staticp) )
            {
              error (staticp
@@ -8782,7 +9361,8 @@ 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);
+         memfn_quals |= type_memfn_quals (type);
+         type_quals = TYPE_UNQUALIFIED;
        }
     }
 
@@ -8841,15 +9421,17 @@ grokdeclarator (const cp_declarator *declarator,
        }
       else if (memfn_quals)
        {
-         if (ctype == NULL_TREE)
-           {
-             if (TREE_CODE (type) != METHOD_TYPE)
-               error ("invalid qualifiers on non-member function type");
-             else
-               ctype = TYPE_METHOD_BASETYPE (type);
-           }
+         if (ctype == NULL_TREE
+             && TREE_CODE (type) == METHOD_TYPE)
+           ctype = TYPE_METHOD_BASETYPE (type);
+
          if (ctype)
            type = build_memfn_type (type, ctype, memfn_quals);
+         /* Core issue #547: need to allow this in template type args.  */
+         else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE)
+           type = apply_memfn_quals (type, memfn_quals);
+         else
+           error ("invalid qualifiers on non-member function type");
        }
 
       return type;
@@ -8904,6 +9486,10 @@ grokdeclarator (const cp_declarator *declarator,
        type = build_pointer_type (type);
     }
 
+  if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+      && !NEW_DELETE_OPNAME_P (unqualified_id))
+    type = build_memfn_type (type, ctype, memfn_quals);
+
   {
     tree decl;
 
@@ -8911,7 +9497,7 @@ grokdeclarator (const cp_declarator *declarator,
       {
        decl = cp_build_parm_decl (unqualified_id, type);
 
-       bad_specifiers (decl, "parameter", virtualp,
+       bad_specifiers (decl, BSP_PARM, virtualp,
                        memfn_quals != TYPE_UNQUALIFIED,
                        inlinep, friendp, raises != NULL_TREE);
       }
@@ -8921,7 +9507,8 @@ grokdeclarator (const cp_declarator *declarator,
        if (!staticp && TREE_CODE (type) == ARRAY_TYPE
            && TYPE_DOMAIN (type) == NULL_TREE)
          {
-           tree itype = compute_array_index_type (dname, integer_zero_node);
+           tree itype = compute_array_index_type (dname, integer_zero_node,
+                                                  tf_warning_or_error);
            type = build_cplus_array_type (TREE_TYPE (type), itype);
          }
 
@@ -8937,19 +9524,26 @@ grokdeclarator (const cp_declarator *declarator,
            error ("invalid use of %<::%>");
            return error_mark_node;
          }
-       else if (TREE_CODE (type) == FUNCTION_TYPE)
+       else if (TREE_CODE (type) == FUNCTION_TYPE
+                || TREE_CODE (type) == METHOD_TYPE)
          {
            int publicp = 0;
            tree function_context;
 
            if (friendp == 0)
              {
-               if (ctype == NULL_TREE)
-                 ctype = current_class_type;
-
-               if (ctype == NULL_TREE)
+               /* This should never happen in pure C++ (the check
+                  could be an assert).  It could happen in
+                  Objective-C++ if someone writes invalid code that
+                  uses a function declaration for an instance
+                  variable or property (instance variables and
+                  properties are parsed as FIELD_DECLs, but they are
+                  part of an Objective-C class, not a C++ class).
+                  That code is invalid and is caught by this
+                  check.  */
+               if (!ctype)
                  {
-                   error ("can't make %qD into a method -- not in a class",
+                   error ("declaration of function %qD in invalid context",
                           unqualified_id);
                    return error_mark_node;
                  }
@@ -8973,32 +9567,34 @@ grokdeclarator (const cp_declarator *declarator,
                        virtualp = 0;
                      }
                  }
-               else if (staticp < 2)
-                 type = build_memfn_type (type, ctype, memfn_quals);
              }
 
            /* Check that the name used for a destructor makes sense.  */
            if (sfk == sfk_destructor)
              {
+               tree uqname = id_declarator->u.id.unqualified_name;
+
                if (!ctype)
                  {
                    gcc_assert (friendp);
                    error ("expected qualified name in friend declaration "
-                          "for destructor %qD",
-                          id_declarator->u.id.unqualified_name);
+                          "for destructor %qD", uqname);
                    return error_mark_node;
                  }
 
-               if (!same_type_p (TREE_OPERAND
-                                 (id_declarator->u.id.unqualified_name, 0),
-                                 ctype))
+               if (!check_dtor_name (ctype, TREE_OPERAND (uqname, 0)))
                  {
                    error ("declaration of %qD as member of %qT",
-                          id_declarator->u.id.unqualified_name, ctype);
+                          uqname, ctype);
                    return error_mark_node;
                  }
+                if (constexpr_p)
+                  {
+                    error ("a destructor cannot be %<constexpr%>");
+                    return error_mark_node;
+                  }
              }
-           else if (sfk == sfk_constructor && friendp)
+           else if (sfk == sfk_constructor && friendp && !ctype)
              {
                error ("expected qualified name in friend declaration "
                       "for constructor %qD",
@@ -9017,9 +9613,11 @@ 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 | (2 * constexpr_p),
                               sfk,
-                              funcdef_flag, template_count, in_namespace, attrlist);
+                              funcdef_flag, template_count, in_namespace,
+                              attrlist, declarator->id_loc);
            if (decl == NULL_TREE)
              return error_mark_node;
 #if 0
@@ -9037,33 +9635,6 @@ grokdeclarator (const cp_declarator *declarator,
               is called a converting constructor.  */
            if (explicitp == 2)
              DECL_NONCONVERTING_P (decl) = 1;
-           else if (DECL_CONSTRUCTOR_P (decl))
-             {
-               /* A constructor with no parms is not a conversion.
-                  Ignore any compiler-added parms.  */
-               tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
-
-               if (arg_types == void_list_node)
-                 DECL_NONCONVERTING_P (decl) = 1;
-             }
-         }
-       else if (TREE_CODE (type) == METHOD_TYPE)
-         {
-           /* We only get here for friend declarations of
-              members of other classes.  */
-           /* All method decls are public, so tell grokfndecl to set
-              TREE_PUBLIC, also.  */
-           decl = grokfndecl (ctype, type,
-                              TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
-                              ? unqualified_id : dname,
-                              parms,
-                              unqualified_id,
-                              virtualp, flags, memfn_quals, raises,
-                              friendp ? -1 : 0, friendp, 1, 0, sfk,
-                              funcdef_flag, template_count, in_namespace,
-                              attrlist);
-           if (decl == NULL_TREE)
-             return error_mark_node;
          }
        else if (!staticp && !dependent_type_p (type)
                 && !COMPLETE_TYPE_P (complete_type (type))
@@ -9113,6 +9684,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);
@@ -9142,15 +9714,25 @@ grokdeclarator (const cp_declarator *declarator,
                       the rest of the compiler does not correctly
                       handle the initialization unless the member is
                       static so we make it static below.  */
-                   permerror (input_location, "ISO C++ forbids initialization of member %qD",
-                              unqualified_id);
-                   permerror (input_location, "making %qD static", unqualified_id);
-                   staticp = 1;
+                   if (cxx_dialect >= cxx0x)
+                     {
+                       sorry ("non-static data member initializers");
+                     }
+                   else
+                     {
+                       permerror (input_location, "ISO C++ forbids initialization of member %qD",
+                                  unqualified_id);
+                       permerror (input_location, "making %qD static", unqualified_id);
+                       staticp = 1;
+                     }
                  }
 
                if (uses_template_parms (type))
                  /* We'll check at instantiation time.  */
                  ;
+               else if (constexpr_p)
+                 /* constexpr has the same requirements.  */
+                 ;
                else if (check_static_variable_definition (unqualified_id,
                                                           type))
                  /* If we just return the declaration, crashes
@@ -9177,7 +9759,14 @@ grokdeclarator (const cp_declarator *declarator,
              }
            else
              {
-               decl = build_decl (FIELD_DECL, unqualified_id, type);
+                if (constexpr_p)
+                 {
+                   error ("non-static data member %qE declared %<constexpr%>",
+                          unqualified_id);
+                   constexpr_p = false;
+                 }
+               decl = build_decl (input_location,
+                                  FIELD_DECL, unqualified_id, type);
                DECL_NONADDRESSABLE_P (decl) = bitfield;
                if (bitfield && !unqualified_id)
                  TREE_NO_WARNING (decl) = 1;
@@ -9189,7 +9778,7 @@ grokdeclarator (const cp_declarator *declarator,
                  }
              }
 
-           bad_specifiers (decl, "field", virtualp,
+           bad_specifiers (decl, BSP_FIELD, virtualp,
                            memfn_quals != TYPE_UNQUALIFIED,
                            inlinep, friendp, raises != NULL_TREE);
          }
@@ -9233,6 +9822,13 @@ grokdeclarator (const cp_declarator *declarator,
                       "declared out of global scope", name);
          }
 
+       if (ctype != NULL_TREE
+           && TREE_CODE (ctype) != NAMESPACE_DECL && !MAYBE_CLASS_TYPE_P (ctype))
+         {
+           error ("%q#T is not a class or a namespace", ctype);
+           ctype = NULL_TREE;
+         }
+
        if (ctype == NULL_TREE)
          {
            if (virtualp)
@@ -9240,12 +9836,15 @@ grokdeclarator (const cp_declarator *declarator,
                error ("virtual non-class function %qs", name);
                virtualp = 0;
              }
+           else if (sfk == sfk_constructor
+                    || sfk == sfk_destructor)
+             {
+               error (funcdef_flag
+                      ? "%qs defined in a non-class scope"
+                      : "%qs declared in a non-class scope", name);
+               sfk = sfk_none;
+             }
          }
-       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));
 
        /* Record presence of `static'.  */
        publicp = (ctype != NULL_TREE
@@ -9255,8 +9854,10 @@ 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,
-                          template_count, in_namespace, attrlist);
+                          publicp, inlinep | (2 * constexpr_p), sfk,
+                           funcdef_flag,
+                          template_count, in_namespace, attrlist,
+                          declarator->id_loc);
        if (decl == NULL_TREE)
          return error_mark_node;
 
@@ -9296,7 +9897,7 @@ grokdeclarator (const cp_declarator *declarator,
                            initialized,
                            (type_quals & TYPE_QUAL_CONST) != 0,
                            ctype ? ctype : in_namespace);
-       bad_specifiers (decl, "variable", virtualp,
+       bad_specifiers (decl, BSP_VAR, virtualp,
                        memfn_quals != TYPE_UNQUALIFIED,
                        inlinep, friendp, raises != NULL_TREE);
 
@@ -9323,6 +9924,9 @@ grokdeclarator (const cp_declarator *declarator,
                storage_class = sc_none;
              }
          }
+       else if (constexpr_p && DECL_EXTERNAL (decl))
+         error ("declaration of constexpr variable %qD is not a definition",
+                decl);
       }
 
     if (storage_class == sc_extern && initialized && !funcdef_flag)
@@ -9351,15 +9955,16 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
+    /* Don't forget constexprness.  */
+    if (constexpr_p)
+      DECL_DECLARED_CONSTEXPR_P (decl) = true;
+
     /* 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;
   }
 }
@@ -9371,7 +9976,7 @@ grokdeclarator (const cp_declarator *declarator,
 static void
 require_complete_types_for_parms (tree parms)
 {
-  for (; parms; parms = TREE_CHAIN (parms))
+  for (; parms; parms = DECL_CHAIN (parms))
     {
       if (dependent_type_p (TREE_TYPE (parms)))
        continue;
@@ -9489,6 +10094,36 @@ check_default_argument (tree decl, tree arg)
   return arg;
 }
 
+/* Returns a deprecated type used within TYPE, or NULL_TREE if none.  */
+
+static tree
+type_is_deprecated (tree type)
+{
+  enum tree_code code;
+  if (TREE_DEPRECATED (type))
+    return type;
+  if (TYPE_NAME (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
+      || code == OFFSET_TYPE || code == FUNCTION_TYPE
+      || code == METHOD_TYPE || code == ARRAY_TYPE)
+    return type_is_deprecated (TREE_TYPE (type));
+
+  if (TYPE_PTRMEMFUNC_P (type))
+    return type_is_deprecated
+      (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type))));
+
+  return NULL_TREE;
+}
+
 /* Decode the list of parameter types for a function type.
    Given the list of things declared inside the parens,
    return a list of types.
@@ -9499,41 +10134,32 @@ check_default_argument (tree decl, tree arg)
    *PARMS is set to the chain of PARM_DECLs created.  */
 
 static tree
-grokparms (cp_parameter_declarator *first_parm, tree *parms)
+grokparms (tree parmlist, tree *parms)
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
-  int ellipsis = !first_parm || first_parm->ellipsis_p;
-  cp_parameter_declarator *parm;
+  tree parm;
   int any_error = 0;
-  struct pointer_set_t *unique_decls = pointer_set_create ();
 
-  for (parm = first_parm; parm != NULL; parm = parm->next)
+  for (parm = parmlist; parm != NULL_TREE; parm = TREE_CHAIN (parm))
     {
       tree type = NULL_TREE;
-      tree init = parm->default_argument;
-      tree attrs;
-      tree decl;
+      tree init = TREE_PURPOSE (parm);
+      tree decl = TREE_VALUE (parm);
+      const char *errmsg;
 
-      if (parm == no_parameters)
+      if (parm == void_list_node)
        break;
 
-      attrs = parm->decl_specifiers.attributes;
-      parm->decl_specifiers.attributes = NULL_TREE;
-      decl = grokdeclarator (parm->declarator, &parm->decl_specifiers,
-                            PARM, init != NULL_TREE, &attrs);
       if (! decl || TREE_TYPE (decl) == error_mark_node)
        continue;
 
-      if (attrs)
-       cplus_decl_attributes (&decl, attrs, 0);
-
       type = TREE_TYPE (decl);
       if (VOID_TYPE_P (type))
        {
          if (same_type_p (type, void_type_node)
              && DECL_SELF_REFERENCE_P (type)
-             && !DECL_NAME (decl) && !result && !parm->next && !ellipsis)
+             && !DECL_NAME (decl) && !result && TREE_CHAIN (parm) == void_list_node)
            /* this is a parmlist of `(void)', which is ok.  */
            break;
          cxx_incomplete_type_error (decl, type);
@@ -9554,8 +10180,23 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
          init = NULL_TREE;
        }
 
+      if (type != error_mark_node
+         && (errmsg = targetm.invalid_parameter_type (type)))
+       {
+         error (errmsg);
+         type = error_mark_node;
+         TREE_TYPE (decl) = error_mark_node;
+       }
+
       if (type != error_mark_node)
        {
+         if (deprecated_state != DEPRECATED_SUPPRESS)
+           {
+             tree deptype = type_is_deprecated (type);
+             if (deptype)
+               warn_deprecated_use (deptype, NULL_TREE);
+           }
+
          /* Top-level qualifiers on the parameters are
             ignored for function types.  */
          type = cp_build_qualified_type (type, 0);
@@ -9585,9 +10226,12 @@ grokparms (cp_parameter_declarator *first_parm, 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)
@@ -9598,28 +10242,20 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
 
       if (TREE_CODE (decl) == PARM_DECL
           && FUNCTION_PARAMETER_PACK_P (decl)
-          && parm->next)
+          && TREE_CHAIN (parm)
+          && TREE_CHAIN (parm) != void_list_node)
         error ("parameter packs must be at the end of the parameter list");
 
-      if (DECL_NAME (decl))
-        {
-          if (pointer_set_contains (unique_decls, DECL_NAME (decl)))
-            error ("multiple parameters named %qE", DECL_NAME (decl));
-          else
-            pointer_set_insert (unique_decls, DECL_NAME (decl));
-        }
-
-      TREE_CHAIN (decl) = decls;
+      DECL_CHAIN (decl) = decls;
       decls = decl;
       result = tree_cons (init, type, result);
     }
   decls = nreverse (decls);
   result = nreverse (result);
-  if (!ellipsis)
+  if (parm)
     result = chainon (result, void_list_node);
   *parms = decls;
 
-  pointer_set_destroy (unique_decls);
   return result;
 }
 
@@ -9634,9 +10270,9 @@ grokparms (cp_parameter_declarator *first_parm, 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
@@ -9770,16 +10406,26 @@ grok_special_member_properties (tree decl)
             X&, volatile X& or const volatile X&, and either there
             are no other parameters or else all other parameters have
             default arguments.  */
-         TYPE_HAS_INIT_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
-           TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
+         TYPE_HAS_COPY_CTOR (class_type) = 1;
+         if (user_provided_p (decl))
+           TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1;
          if (ctor > 1)
-           TYPE_HAS_CONST_INIT_REF (class_type) = 1;
+           TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
        }
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
-       TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
+       {
+         TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
+         if (user_provided_p (decl))
+           TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
+       }
+      else if (move_fn_p (decl) && user_provided_p (decl))
+       TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
       else if (is_list_ctor (decl))
        TYPE_HAS_LIST_CTOR (class_type) = 1;
+
+      if (DECL_DECLARED_CONSTEXPR_P (decl)
+         && !copy_fn_p (decl) && !move_fn_p (decl))
+       TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
     }
   else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
     {
@@ -9793,13 +10439,16 @@ grok_special_member_properties (tree decl)
 
       if (assop)
        {
-         TYPE_HAS_ASSIGN_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
-           TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
+         TYPE_HAS_COPY_ASSIGN (class_type) = 1;
+         if (user_provided_p (decl))
+           TYPE_HAS_COMPLEX_COPY_ASSIGN (class_type) = 1;
          if (assop != 1)
-           TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
+           TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1;
        }
+      else if (move_fn_p (decl) && user_provided_p (decl))
+       TYPE_HAS_COMPLEX_MOVE_ASSIGN (class_type) = 1;
     }
+  /* Destructors are handled in check_methods.  */
 }
 
 /* Check a constructor DECL has the correct form.  Complains
@@ -10033,28 +10682,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)
@@ -10289,6 +10948,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));
@@ -10630,7 +11290,12 @@ xref_basetypes (tree ref, tree base_list)
 
   /* The binfo slot should be empty, unless this is an (ill-formed)
      redefinition.  */
-  gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));
+  if (TYPE_BINFO (ref) && !TYPE_SIZE (ref))
+    {
+      error ("redefinition of %q#T", ref);
+      return false;
+    }
+
   gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
 
   binfo = make_tree_binfo (max_bases);
@@ -10639,6 +11304,9 @@ xref_basetypes (tree ref, tree base_list)
   BINFO_OFFSET (binfo) = size_zero_node;
   BINFO_TYPE (binfo) = ref;
 
+  /* Apply base-class info set up to the variants of this type.  */
+  fixup_type_variants (ref);
+
   if (max_bases)
     {
       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases);
@@ -10776,108 +11444,172 @@ xref_basetypes (tree ref, tree base_list)
 }
 
 \f
+/* Copies the enum-related properties from type SRC to type DST.
+   Used with the underlying type of an enum and the enum itself.  */
+static void
+copy_type_enum (tree dst, tree src)
+{
+  TYPE_MIN_VALUE (dst) = TYPE_MIN_VALUE (src);
+  TYPE_MAX_VALUE (dst) = TYPE_MAX_VALUE (src);
+  TYPE_SIZE (dst) = TYPE_SIZE (src);
+  TYPE_SIZE_UNIT (dst) = TYPE_SIZE_UNIT (src);
+  SET_TYPE_MODE (dst, TYPE_MODE (src));
+  TYPE_PRECISION (dst) = TYPE_PRECISION (src);
+  TYPE_ALIGN (dst) = TYPE_ALIGN (src);
+  TYPE_USER_ALIGN (dst) = TYPE_USER_ALIGN (src);
+  TYPE_UNSIGNED (dst) = TYPE_UNSIGNED (src);
+}
+
 /* Begin compiling the definition of an enumeration type.
    NAME is its name, 
 
+   if ENUMTYPE is not NULL_TREE then the type has alredy been found.
+
    UNDERLYING_TYPE is the type that will be used as the storage for
    the enumeration type. This should be NULL_TREE if no storage type
    was specified.
 
    SCOPED_ENUM_P is true if this is a scoped enumeration type.
 
+   if IS_NEW is not NULL, gets TRUE iff a new type is created.
+
    Returns the type object, as yet incomplete.
    Also records info about it so that build_enumerator
    may be used to declare the individual values as they are read.  */
 
 tree
-start_enum (tree name, tree underlying_type, bool scoped_enum_p)
+start_enum (tree name, tree enumtype, tree underlying_type,
+           bool scoped_enum_p, bool *is_new)
 {
-  tree enumtype;
-
+  tree prevtype = NULL_TREE;
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
+  if (is_new)
+    *is_new = false;
+  /* [C++0x dcl.enum]p5:
+
+    If not explicitly specified, the underlying type of a scoped
+    enumeration type is int.  */
+  if (!underlying_type && scoped_enum_p)
+    underlying_type = integer_type_node;
+
+  if (underlying_type)
+    underlying_type = cv_unqualified (underlying_type);
+
   /* If this is the real definition for a previous forward reference,
      fill in the contents in the same object that used to be the
      forward reference.  */
+  if (!enumtype)
+    enumtype = lookup_and_check_tag (enum_type, name,
+                                    /*tag_scope=*/ts_current,
+                                    /*template_header_p=*/false);
 
-  enumtype = lookup_and_check_tag (enum_type, name,
-                                  /*tag_scope=*/ts_current,
-                                  /*template_header_p=*/false);
-
-  if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
+  /* In case of a template_decl, the only check that should be deferred
+     to instantiation time is the comparison of underlying types.  */
+  if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
     {
-      error ("multiple definition of %q#T", enumtype);
-      error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
-      /* Clear out TYPE_VALUES, and start again.  */
-      TYPE_VALUES (enumtype) = NULL_TREE;
+      if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
+       {
+         error_at (input_location, "scoped/unscoped mismatch "
+                   "in enum %q#T", enumtype);
+         error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+                   "previous definition here");
+         enumtype = error_mark_node;
+       }
+      else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
+       {
+         error_at (input_location, "underlying type mismatch "
+                   "in enum %q#T", enumtype);
+         error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+                   "previous definition here");
+         enumtype = error_mark_node;
+       }
+      else if (underlying_type && ENUM_UNDERLYING_TYPE (enumtype)
+              && !dependent_type_p (underlying_type)
+              && !dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))
+              && !same_type_p (underlying_type,
+                               ENUM_UNDERLYING_TYPE (enumtype)))
+       {
+         error_at (input_location, "different underlying type "
+                   "in enum %q#T", enumtype);
+         error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+                   "previous definition here");
+         underlying_type = NULL_TREE;
+       }
     }
-  else
+
+  if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
+      || processing_template_decl)
     {
       /* In case of error, make a dummy enum to allow parsing to
         continue.  */
       if (enumtype == error_mark_node)
-       name = make_anon_name ();
+       {
+         name = make_anon_name ();
+         enumtype = NULL_TREE;
+       }
 
-      enumtype = make_node (ENUMERAL_TYPE);
+      /* enumtype may be an ENUMERAL_TYPE if this is a redefinition
+         of an opaque enum, or an opaque enum of an already defined
+        enumeration (C++0x only).
+        In any other case, it'll be NULL_TREE. */
+      if (!enumtype)
+       {
+         if (is_new)
+           *is_new = true;
+       }
+      prevtype = enumtype;
+      enumtype = cxx_make_type (ENUMERAL_TYPE);
       enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
-    }
-
-  if (scoped_enum_p)
-    {
-      SET_SCOPED_ENUM_P (enumtype, 1);
-      begin_scope (sk_scoped_enum, enumtype);
-
-      /* [C++0x dcl.enum]p5: 
+      if (enumtype == error_mark_node)
+       return error_mark_node;
 
-          If not explicitly specified, the underlying type of a scoped
-          enumeration type is int.  */
-      if (!underlying_type)
-        underlying_type = integer_type_node;
+      /* The enum is considered opaque until the opening '{' of the
+        enumerator list.  */
+      SET_OPAQUE_ENUM_P (enumtype, true);
+      ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = !! underlying_type;
     }
 
+  SET_SCOPED_ENUM_P (enumtype, scoped_enum_p);
+
   if (underlying_type)
     {
       if (CP_INTEGRAL_TYPE_P (underlying_type))
         {
-          TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (underlying_type);
-          TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (underlying_type);
-          TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
-          TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
-          TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
-          TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
-          TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
-          TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
-          TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
+         copy_type_enum (enumtype, underlying_type);
           ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
         }
+      else if (dependent_type_p (underlying_type))
+       ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
       else
         error ("underlying type %<%T%> of %<%T%> must be an integral type", 
                underlying_type, enumtype);
     }
 
-  return enumtype;
+  /* If into a template class, the returned enum is always the first
+     declaration (opaque or not) seen. This way all the references to
+     this type will be to the same declaration. The following ones are used
+     only to check for definition errors.  */
+  if (prevtype && processing_template_decl)
+    return prevtype;
+  else
+    return enumtype;
 }
 
 /* After processing and defining all the values of an enumeration type,
-   install their decls in the enumeration type and finish it off.
-   ENUMTYPE is the type object and VALUES a list of name-value pairs.  */
+   install their decls in the enumeration type.
+   ENUMTYPE is the type object.  */
 
 void
-finish_enum (tree enumtype)
+finish_enum_value_list (tree enumtype)
 {
   tree values;
+  tree underlying_type;
   tree decl;
-  tree minnode;
-  tree maxnode;
   tree value;
+  tree minnode, maxnode;
   tree t;
-  bool unsignedp;
-  bool use_short_enum;
-  int lowprec;
-  int highprec;
-  int precision;
-  integer_type_kind itk;
-  tree underlying_type = NULL_TREE;
+
   bool fixed_underlying_type_p 
     = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
 
@@ -10894,8 +11626,6 @@ finish_enum (tree enumtype)
           values;
           values = TREE_CHAIN (values))
        TREE_TYPE (TREE_VALUE (values)) = enumtype;
-      if (at_function_scope_p ())
-       add_stmt (build_min (TAG_DEFN, enumtype));
       return;
     }
 
@@ -10905,49 +11635,51 @@ finish_enum (tree enumtype)
       minnode = maxnode = NULL_TREE;
 
       for (values = TYPE_VALUES (enumtype);
-           values;
-           values = TREE_CHAIN (values))
-        {
-          decl = TREE_VALUE (values);
-
-          /* [dcl.enum]: Following the closing brace of an enum-specifier,
-             each enumerator has the type of its enumeration.  Prior to the
-             closing brace, the type of each enumerator is the type of its
-             initializing value.  */
-          TREE_TYPE (decl) = enumtype;
-
-          /* Update the minimum and maximum values, if appropriate.  */
-          value = DECL_INITIAL (decl);
-          if (value == error_mark_node)
-            value = integer_zero_node;
-          /* Figure out what the minimum and maximum values of the
-             enumerators are.  */
-          if (!minnode)
-            minnode = maxnode = value;
-          else if (tree_int_cst_lt (maxnode, value))
-            maxnode = value;
-          else if (tree_int_cst_lt (value, minnode))
-            minnode = value;
-        }
+          values;
+          values = TREE_CHAIN (values))
+       {
+         decl = TREE_VALUE (values);
+
+         /* [dcl.enum]: Following the closing brace of an enum-specifier,
+            each enumerator has the type of its enumeration.  Prior to the
+            closing brace, the type of each enumerator is the type of its
+            initializing value.  */
+         TREE_TYPE (decl) = enumtype;
+
+         /* Update the minimum and maximum values, if appropriate.  */
+         value = DECL_INITIAL (decl);
+         if (value == error_mark_node)
+           value = integer_zero_node;
+         /* Figure out what the minimum and maximum values of the
+            enumerators are.  */
+         if (!minnode)
+           minnode = maxnode = value;
+         else if (tree_int_cst_lt (maxnode, value))
+           maxnode = value;
+         else if (tree_int_cst_lt (value, minnode))
+           minnode = value;
+       }
     }
   else
     /* [dcl.enum]
-       
+
        If the enumerator-list is empty, the underlying type is as if
        the enumeration had a single enumerator with value 0.  */
     minnode = maxnode = integer_zero_node;
 
-  /* Compute the number of bits require to represent all values of the
-     enumeration.  We must do this before the type of MINNODE and
-     MAXNODE are transformed, since min_precision relies on the
-     TREE_TYPE of the value it is passed.  */
-  unsignedp = tree_int_cst_sgn (minnode) >= 0;
-  lowprec = min_precision (minnode, unsignedp);
-  highprec = min_precision (maxnode, unsignedp);
-  precision = MAX (lowprec, highprec);
-
   if (!fixed_underlying_type_p)
     {
+      /* Compute the number of bits require to represent all values of the
+        enumeration.  We must do this before the type of MINNODE and
+        MAXNODE are transformed, since tree_int_cst_min_precision relies
+        on the TREE_TYPE of the value it is passed.  */
+      bool unsignedp = tree_int_cst_sgn (minnode) >= 0;
+      int lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+      int highprec = tree_int_cst_min_precision (maxnode, unsignedp);
+      int precision = MAX (lowprec, highprec);
+      unsigned int itk;
+      bool use_short_enum;
+
       /* Determine the underlying type of the enumeration.
 
          [dcl.enum]
@@ -10973,7 +11705,8 @@ finish_enum (tree enumtype)
            itk++)
         {
           underlying_type = integer_types[itk];
-          if (TYPE_PRECISION (underlying_type) >= precision
+          if (underlying_type != NULL_TREE
+             && TYPE_PRECISION (underlying_type) >= precision
               && TYPE_UNSIGNED (underlying_type) == unsignedp)
             break;
         }
@@ -10994,42 +11727,43 @@ finish_enum (tree enumtype)
          The value of sizeof() applied to an enumeration type, an object
          of an enumeration type, or an enumerator, is the value of sizeof()
          applied to the underlying type.  */
-      TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
-      TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
-      TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
-      TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
-      TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
-      TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
-
-      /* 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);
-      set_min_and_max_values_for_integral_type 
+      copy_type_enum (enumtype, underlying_type);
+
+      /* Compute the minimum and maximum values for the type.
+
+        [dcl.enum]
+
+        For an enumeration where emin is the smallest enumerator and emax
+        is the largest, the values of the enumeration are the values of the
+        underlying type in the range bmin to bmax, where bmin and bmax are,
+        respectively, the smallest and largest values of the smallest bit-
+        field that can store emin and emax.  */
+
+      /* The middle-end currently assumes that types with TYPE_PRECISION
+        narrower than their underlying type are suitably zero or sign
+        extended to fill their mode.  Similarly, it assumes that the front
+        end assures that a value of a particular type must be within
+        TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+
+        We used to set these fields based on bmin and bmax, but that led
+        to invalid assumptions like optimizing away bounds checking.  So
+        now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and
+        TYPE_MAX_VALUE to the values for the mode above and only restrict
+        the ENUM_UNDERLYING_TYPE for the benefit of diagnostics.  */
+      ENUM_UNDERLYING_TYPE (enumtype)
+       = build_distinct_type_copy (underlying_type);
+      TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
+      set_min_and_max_values_for_integral_type
         (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
+
+      /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE.  */
+      if (flag_strict_enums)
+       set_min_and_max_values_for_integral_type (enumtype, precision,
+                                                 unsignedp);
     }
   else
     underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
 
-  /* Compute the minimum and maximum values for the type.
-
-     [dcl.enum]
-
-     For an enumeration where emin is the smallest enumerator and emax
-     is the largest, the values of the enumeration are the values of the
-     underlying type in the range bmin to bmax, where bmin and bmax are,
-     respectively, the smallest and largest values of the smallest bit-
-     field that can store emin and emax.  */
-  
-  /* The middle-end currently assumes that types with TYPE_PRECISION
-     narrower than their underlying type are suitably zero or sign
-     extended to fill their mode.  g++ doesn't make these guarantees.
-     Until the middle-end can represent such paradoxical types, we
-     set the TYPE_PRECISION to the width of the underlying type.  */
-  TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
-  
-  set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
-  
   /* Convert each of the enumerators to the type of the underlying
      type of the enumeration.  */
   for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
@@ -11058,34 +11792,38 @@ finish_enum (tree enumtype)
 
   /* Fix up all variant types of this enum type.  */
   for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
-    {
-      TYPE_VALUES (t) = TYPE_VALUES (enumtype);
-      TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (enumtype);
-      TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (enumtype);
-      TYPE_SIZE (t) = TYPE_SIZE (enumtype);
-      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (enumtype);
-      TYPE_MODE (t) = TYPE_MODE (enumtype);
-      TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
-      TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
-      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
-      TYPE_UNSIGNED (t) = TYPE_UNSIGNED (enumtype);
-      ENUM_UNDERLYING_TYPE (t) = ENUM_UNDERLYING_TYPE (enumtype);
-    }
-
-  /* Finish up the scope of a scoped enumeration.  */
-  if (SCOPED_ENUM_P (enumtype))
-    finish_scope ();
+    TYPE_VALUES (t) = TYPE_VALUES (enumtype);
 
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (enumtype, namespace_bindings_p ());
 }
 
+/* Finishes the enum type. This is called only the first time an
+   enumeration is seen, be it opaque or odinary.
+   ENUMTYPE is the type object.  */
+
+void
+finish_enum (tree enumtype)
+{
+  if (processing_template_decl)
+    {
+      if (at_function_scope_p ())
+       add_stmt (build_min (TAG_DEFN, enumtype));
+      return;
+    }
+
+  /* Here there should not be any variants of this type.  */
+  gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype)
+             && !TYPE_NEXT_VARIANT (enumtype));
+}
+
 /* Build and install a CONST_DECL for an enumeration constant of the
    enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
+   LOC is the location of NAME.
    Assignment of sequential values by default is handled here.  */
 
 void
-build_enumerator (tree name, tree value, tree enumtype)
+build_enumerator (tree name, tree value, tree enumtype, location_t loc)
 {
   tree decl;
   tree context;
@@ -11105,12 +11843,11 @@ build_enumerator (tree name, tree value, tree enumtype)
       /* Validate and default VALUE.  */
       if (value != NULL_TREE)
        {
-         value = integral_constant_value (value);
+         value = cxx_constant_value (value);
 
          if (TREE_CODE (value) == INTEGER_CST)
            {
              value = perform_integral_promotions (value);
-             constant_expression_warning (value);
            }
          else
            {
@@ -11129,21 +11866,26 @@ build_enumerator (tree name, tree value, tree enumtype)
              tree prev_value;
              bool overflowed;
 
-             /* The next value is the previous value plus one.  We can
-                safely assume that the previous value is an INTEGER_CST.
+             /* The next value is the previous value plus one.
                 add_double doesn't know the type of the target expression,
                 so we must check with int_fits_type_p as well.  */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
-             overflowed = add_double (TREE_INT_CST_LOW (prev_value),
-                                      TREE_INT_CST_HIGH (prev_value),
-                                      1, 0, &lo, &hi);
-             value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
-             overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value));
-
-             if (overflowed)
+             if (error_operand_p (prev_value))
+               value = error_mark_node;
+             else
                {
-                 error ("overflow in enumeration values at %qD", name);
-                 value = error_mark_node;
+                 overflowed = add_double (TREE_INT_CST_LOW (prev_value),
+                                          TREE_INT_CST_HIGH (prev_value),
+                                          1, 0, &lo, &hi);
+                 value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
+                 overflowed
+                   |= !int_fits_type_p (value, TREE_TYPE (prev_value));
+
+                 if (overflowed)
+                   {
+                     error ("overflow in enumeration values at %qD", name);
+                     value = error_mark_node;
+                   }
                }
            }
          else
@@ -11167,8 +11909,6 @@ build_enumerator (tree name, tree value, tree enumtype)
           /* Silently convert the value so that we can continue.  */
           value = perform_implicit_conversion (ENUM_UNDERLYING_TYPE (enumtype),
                                                value, tf_none);
-          if (value == error_mark_node)
-            value = NULL_TREE;
         }
     }
 
@@ -11197,18 +11937,18 @@ build_enumerator (tree name, tree value, tree enumtype)
   if (context && context == current_class_type)
     /* This enum declaration is local to the class.  We need the full
        lang_decl so that we can record DECL_CLASS_CONTEXT, for example.  */
-    decl = build_lang_decl (CONST_DECL, name, type);
+    decl = build_lang_decl_loc (loc, CONST_DECL, name, type);
   else
     /* It's a global enum, or it's local to a function.  (Note local to
-      a function could mean local to a class method.  */
-    decl = build_decl (CONST_DECL, name, type);
-
+       a function could mean local to a class method.  */
+    decl = build_decl (loc, CONST_DECL, name, type);
+  
   DECL_CONTEXT (decl) = FROB_CONTEXT (context);
   TREE_CONSTANT (decl) = 1;
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
-  if (context && context == current_class_type)
+  if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
     /* In something like `struct S { enum E { i = 7 }; };' we put `i'
        on the TYPE_FIELDS list for `S'.  (That's so that you can say
        things like `S::i' later.)  */
@@ -11241,7 +11981,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)
@@ -11271,9 +12011,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));
@@ -11428,7 +12171,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
     {
       tree resdecl;
 
-      resdecl = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));
+      resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
       DECL_ARTIFICIAL (resdecl) = 1;
       DECL_IGNORED_P (resdecl) = 1;
       DECL_RESULT (decl1) = resdecl;
@@ -11504,10 +12247,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
         with any previous declarations; if the original declaration
         has a linkage specification, that specification applies to
         the definition as well, and may affect the mangled name.  */
-      if (!DECL_CONTEXT (decl1))
+      if (DECL_FILE_SCOPE_P (decl1))
        maybe_apply_pragma_weak (decl1);
     }
 
+  /* constexpr functions must have literal argument types and
+     literal return type.  */
+  validate_constexpr_fundecl (decl1);
+
   /* Reset this in case the call to pushdecl changed it.  */
   current_function_decl = decl1;
 
@@ -11528,7 +12275,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   /* Initialize the language data structures.  Whenever we start
      a new function, we destroy temporaries in the usual way.  */
-  cfun->language = GGC_CNEW (struct language_function);
+  cfun->language = ggc_alloc_cleared_language_function ();
   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   current_binding_level = bl;
 
@@ -11558,16 +12305,16 @@ 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
         charge" of initializing virtual base classes.  */
-      t = TREE_CHAIN (t);
+      t = DECL_CHAIN (t);
       if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
        {
          current_in_charge_parm = t;
-         t = TREE_CHAIN (t);
+         t = DECL_CHAIN (t);
        }
       if (DECL_HAS_VTT_PARM_P (decl1))
        {
@@ -11648,9 +12395,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
       if ((DECL_DECLARED_INLINE_P (decl1)
           || DECL_TEMPLATE_INSTANTIATION (decl1))
-         && ! DECL_INTERFACE_KNOWN (decl1)
-         /* Don't try to defer nested functions for now.  */
-         && ! decl_function_context (decl1))
+         && ! DECL_INTERFACE_KNOWN (decl1))
        DECL_DEFER_OUTPUT (decl1) = 1;
       else
        DECL_INTERFACE_KNOWN (decl1) = 1;
@@ -11671,7 +12416,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       || (DECL_CONSTRUCTOR_P (decl1)
          && targetm.cxx.cdtor_returns_this ()))
     {
-      cdtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+      cdtor_label = build_decl (input_location, 
+                               LABEL_DECL, NULL_TREE, NULL_TREE);
       DECL_CONTEXT (cdtor_label) = current_function_decl;
     }
 
@@ -11696,10 +12442,15 @@ start_function (cp_decl_specifier_seq *declspecs,
   tree decl1;
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
+  if (decl1 == error_mark_node)
+    return 0;
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
-    return 0;
+    {
+      error ("invalid function declaration");
+      return 0;
+    }
 
   if (DECL_MAIN_P (decl1))
     /* main must return int.  grokfndecl should have corrected it
@@ -11720,7 +12471,7 @@ use_eh_spec_block (tree fn)
 {
   return (flag_exceptions && flag_enforce_eh_specs
          && !processing_template_decl
-         && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
+         && !type_throw_all_p (TREE_TYPE (fn))
          /* We insert the EH_SPEC_BLOCK only in the original
             function; then, it is copied automatically to the
             clones.  */
@@ -11774,7 +12525,7 @@ store_parm_decls (tree current_function_parms)
 
       for (parm = specparms; parm; parm = next)
        {
-         next = TREE_CHAIN (parm);
+         next = DECL_CHAIN (parm);
          if (TREE_CODE (parm) == PARM_DECL)
            {
              if (DECL_NAME (parm) == NULL_TREE
@@ -11825,7 +12576,7 @@ save_function_data (tree decl)
   gcc_assert (!DECL_PENDING_INLINE_P (decl));
 
   /* Make a copy.  */
-  f = GGC_NEW (struct language_function);
+  f = ggc_alloc_language_function ();
   memcpy (f, cp_function_chain, sizeof (struct language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
@@ -11848,13 +12599,13 @@ finish_constructor_body (void)
       && (! TYPE_FOR_JAVA (current_class_type)))
     {
       /* Any return from a constructor will end up here.  */
-      add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+      add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
 
       val = DECL_ARGUMENTS (current_function_decl);
       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
                    DECL_RESULT (current_function_decl), val);
       /* Return the address of the object.  */
-      exprstmt = build_stmt (RETURN_EXPR, val);
+      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
       add_stmt (exprstmt);
     }
 }
@@ -11896,7 +12647,7 @@ finish_destructor_body (void)
 
   /* Any return from a destructor will end up here; that way all base
      and member cleanups will be run when the function returns.  */
-  add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+  add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
 
   /* In a virtual destructor, we must call delete.  */
   if (DECL_VIRTUAL_P (current_function_decl))
@@ -11934,7 +12685,7 @@ finish_destructor_body (void)
       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
                    DECL_RESULT (current_function_decl), val);
       /* Return the address of the object.  */
-      exprstmt = build_stmt (RETURN_EXPR, val);
+      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
       add_stmt (exprstmt);
     }
 }
@@ -12010,6 +12761,35 @@ outer_curly_brace_block (tree fndecl)
   return block;
 }
 
+/* If FNDECL is a class's key method, add the class to the list of
+   keyed classes that should be emitted.  */
+
+static void
+record_key_method_defined (tree fndecl)
+{
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+      && DECL_VIRTUAL_P (fndecl)
+      && !processing_template_decl)
+    {
+      tree fnclass = DECL_CONTEXT (fndecl);
+      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+    }
+}
+
+/* Subroutine of finish_function.
+   Save the body of constexpr functions for possible
+   future compile time evaluation.  */
+
+static void
+maybe_save_function_definition (tree fun)
+{
+  if (!processing_template_decl
+      && DECL_DECLARED_CONSTEXPR_P (fun)
+      && !DECL_CLONED_FUNCTION_P (fun))
+    register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
+}
+
 /* Finish up a function declaration and compile that function
    all the way to assembler language output.  The free the storage
    for the function definition.
@@ -12026,23 +12806,20 @@ finish_function (int flags)
   tree fndecl = current_function_decl;
   tree fntype, ctype = NULL_TREE;
   int inclass_inline = (flags & 2) != 0;
-  int nested;
 
   /* When we get some parse errors, we can end up without a
      current_function_decl, so cope.  */
   if (fndecl == NULL_TREE)
     return error_mark_node;
 
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
-      && DECL_VIRTUAL_P (fndecl)
-      && !processing_template_decl)
-    {
-      tree fnclass = DECL_CONTEXT (fndecl);
-      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
-       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
-    }
+  if (c_dialect_objc ())
+    objc_finish_function ();
+
+  gcc_assert (!defer_mark_used_calls);
+  defer_mark_used_calls = true;
+
+  record_key_method_defined (fndecl);
 
-  nested = function_depth > 1;
   fntype = TREE_TYPE (fndecl);
 
   /*  TREE_READONLY (fndecl) = 1;
@@ -12094,7 +12871,7 @@ finish_function (int flags)
   if (!processing_template_decl
       && !cp_function_chain->can_throw
       && !flag_non_call_exceptions
-      && !DECL_REPLACEABLE_P (fndecl))
+      && !decl_replaceable_p (fndecl))
     TREE_NOTHROW (fndecl) = 1;
 
   /* This must come after expand_function_end because cleanups might
@@ -12127,6 +12904,10 @@ finish_function (int flags)
      of curly braces for a function.  */
   gcc_assert (stmts_are_full_exprs_p ());
 
+  /* Save constexpr function body before it gets munged by
+     the NRV transformation.   */
+  maybe_save_function_definition (fndecl);
+
   /* Set up the named return value optimization, if we can.  Candidate
      variables are selected in check_return_expr.  */
   if (current_function_return_value)
@@ -12171,6 +12952,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.  */
@@ -12186,10 +12969,38 @@ finish_function (int flags)
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
 
+  /* Complain about parameters that are only set, but never otherwise used.  */
+  if (warn_unused_but_set_parameter
+      && !processing_template_decl
+      && errorcount == unused_but_set_errorcount
+      && !DECL_CLONED_FUNCTION_P (fndecl))
+    {
+      tree decl;
+
+      for (decl = DECL_ARGUMENTS (fndecl);
+          decl;
+          decl = DECL_CHAIN (decl))
+       if (TREE_USED (decl)
+           && TREE_CODE (decl) == PARM_DECL
+           && !DECL_READ_P (decl)
+           && DECL_NAME (decl)
+           && !DECL_ARTIFICIAL (decl)
+           && !TREE_NO_WARNING (decl)
+           && !DECL_IN_SYSTEM_HEADER (decl)
+           && TREE_TYPE (decl) != error_mark_node
+           && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
+           && (!CLASS_TYPE_P (TREE_TYPE (decl))
+               || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+         warning (OPT_Wunused_but_set_parameter,
+                  "parameter %q+D set but not used", decl);
+      unused_but_set_errorcount = errorcount;
+    }
+
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
       struct language_function *f = DECL_SAVED_FUNCTION_DATA (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;
@@ -12200,9 +13011,6 @@ finish_function (int flags)
       f->x_return_value = NULL;
       f->bindings = NULL;
       f->extern_decl_map = NULL;
-
-      /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-      c_warn_unused_result (gimple_body (fndecl));
     }
   /* Clear out the bits we don't need.  */
   local_names = NULL;
@@ -12226,11 +13034,18 @@ finish_function (int flags)
   --function_depth;
 
   /* Clean up.  */
-  if (! nested)
-    /* Let the error reporting routines know that we're outside a
-       function.  For a nested function, this value is used in
-       cxx_pop_function_context and then reset via pop_function_context.  */
-    current_function_decl = NULL_TREE;
+  current_function_decl = NULL_TREE;
+
+  defer_mark_used_calls = false;
+  if (deferred_mark_used_calls)
+    {
+      unsigned int i;
+      tree decl;
+
+      FOR_EACH_VEC_ELT (tree, deferred_mark_used_calls, i, decl)
+       mark_used (decl);
+      VEC_free (tree, gc, deferred_mark_used_calls);
+    }
 
   return fndecl;
 }
@@ -12257,8 +13072,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);
@@ -12291,6 +13106,7 @@ start_method (cp_decl_specifier_seq *declspecs,
   check_template_shadow (fndecl);
 
   DECL_DECLARED_INLINE_P (fndecl) = 1;
+  DECL_NO_INLINE_WARNING_P (fndecl) = 1;
 
   /* We process method specializations in finish_struct_1.  */
   if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
@@ -12302,81 +13118,18 @@ start_method (cp_decl_specifier_seq *declspecs,
 
   if (! DECL_FRIEND_P (fndecl))
     {
-      if (TREE_CHAIN (fndecl))
+      if (DECL_CHAIN (fndecl))
        {
          fndecl = copy_node (fndecl);
          TREE_CHAIN (fndecl) = NULL_TREE;
        }
     }
 
-  finish_decl (fndecl, NULL_TREE, NULL_TREE);
-
-  /* Make a place for the parms.  */
-  begin_scope (sk_function_parms, fndecl);
+  cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);
 
   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;
-
-  /* We used to check if the context of FNDECL was different from
-     current_class_type as another way to get inside here.  This didn't work
-     for String.cc in libg++.  */
-  if (DECL_FRIEND_P (fndecl))
-    {
-      VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type),
-                    fndecl);
-      decl = void_type_node;
-    }
-
-  return decl;
-}
 \f
 
 /* VAR is a VAR_DECL.  If its type is incomplete, remember VAR so that
@@ -12401,7 +13154,12 @@ maybe_register_incomplete_var (tree var)
          /* RTTI TD entries are created while defining the type_info.  */
          || (TYPE_LANG_SPECIFIC (inner_type)
              && TYPE_BEING_DEFINED (inner_type)))
-       incomplete_vars = tree_cons (inner_type, var, incomplete_vars);
+       {
+         incomplete_var *iv
+           = VEC_safe_push (incomplete_var, gc, incomplete_vars, NULL);
+         iv->decl = var;
+         iv->incomplete_type = inner_type;
+       }
     }
 }
 
@@ -12412,24 +13170,24 @@ maybe_register_incomplete_var (tree var)
 void
 complete_vars (tree type)
 {
-  tree *list = &incomplete_vars;
+  unsigned ix;
+  incomplete_var *iv;
 
-  gcc_assert (CLASS_TYPE_P (type));
-  while (*list)
+  for (ix = 0; VEC_iterate (incomplete_var, incomplete_vars, ix, iv); )
     {
-      if (same_type_p (type, TREE_PURPOSE (*list)))
+      if (same_type_p (type, iv->incomplete_type))
        {
-         tree var = TREE_VALUE (*list);
+         tree var = iv->decl;
          tree type = TREE_TYPE (var);
          /* Complete the type of the variable.  The VAR_DECL itself
             will be laid out in expand_expr.  */
          complete_type (type);
          cp_apply_type_quals_to_decl (cp_type_quals (type), var);
          /* Remove this entry from the list.  */
-         *list = TREE_CHAIN (*list);
+         VEC_unordered_remove (incomplete_var, incomplete_vars, ix);
        }
       else
-       list = &TREE_CHAIN (*list);
+       ix++;
     }
 
   /* Check for pending declarations which may have abstract type.  */
@@ -12476,9 +13234,8 @@ cxx_maybe_build_cleanup (tree decl)
       fn = lookup_name (id);
       arg = build_address (decl);
       mark_used (decl);
-      cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE,
-                                                            arg),
-                                       tf_warning_or_error);
+      cleanup = cp_build_function_call_nary (fn, tf_warning_or_error,
+                                            arg, NULL_TREE);
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
@@ -12502,7 +13259,7 @@ cxx_maybe_build_cleanup (tree decl)
       call = build_delete (TREE_TYPE (addr), addr,
                           sfk_complete_destructor, flags, 0);
       if (cleanup)
-       cleanup = build_compound_expr (cleanup, call);
+       cleanup = build_compound_expr (input_location, cleanup, call);
       else
        cleanup = call;
     }
@@ -12517,28 +13274,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;
+
+  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));
+  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+  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_ARGUMENTS (decl) = DECL_CHAIN (DECL_ARGUMENTS (decl));
   DECL_STATIC_FUNCTION_P (decl) = 1;
 }
 
@@ -12559,6 +13335,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;
     }
 }
@@ -12580,7 +13358,7 @@ cp_missing_noreturn_ok_p (tree decl)
 
 /* Return the COMDAT group into which DECL should be placed.  */
 
-const char *
+tree
 cxx_comdat_group (tree decl)
 {
   tree name;
@@ -12610,7 +13388,7 @@ cxx_comdat_group (tree decl)
       name = DECL_ASSEMBLER_NAME (decl);
     }
 
-  return IDENTIFIER_POINTER (name);
+  return name;
 }
 
 #include "gt-cp-decl.h"