OSDN Git Service

* pt.c (register_specialization): Push DECL_SOURCE_LOCATION to the
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 630faac..9f5ca30 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
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -53,8 +53,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "tree-flow.h"
 #include "pointer-set.h"
+#include "plugin.h"
 
-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);
@@ -66,7 +67,7 @@ static tree grok_reference_init (tree, tree, tree, tree *);
 static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
                         int, int, tree);
 static void record_unknown_type (tree, const char *);
-static tree builtin_function_1 (tree, tree);
+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,
@@ -81,7 +82,6 @@ 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);
@@ -94,7 +94,7 @@ 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);
@@ -169,8 +169,7 @@ tree integer_two_node, integer_three_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 +191,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;
 
@@ -227,17 +225,16 @@ 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_NORMAL,
-  DEPRECATED_SUPPRESS
-};
-
-static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
+enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
 
 \f
 /* A TREE_LIST of VAR_DECLs.  The TREE_PURPOSE is a RECORD_TYPE or
@@ -746,7 +743,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 +781,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.  */
 
@@ -857,7 +842,7 @@ 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
@@ -888,7 +873,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 +916,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_BUILT_IN (olddecl)
+         && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
+       return 0;
+#endif
+
       if (TREE_CODE (f1) != TREE_CODE (f2))
        return 0;
 
@@ -1055,8 +1059,8 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  permerror ("%qD was declared %<extern%> and later %<static%>", newdecl);
-  permerror ("previous declaration of %q+D", olddecl);
+  permerror (input_location, "%qD was declared %<extern%> and later %<static%>", newdecl);
+  permerror (input_location, "previous declaration of %q+D", olddecl);
 }
 
 /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
@@ -1113,7 +1117,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;
@@ -1460,7 +1464,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 +1477,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)
@@ -1539,9 +1544,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                if (1 == simple_cst_equal (TREE_PURPOSE (t1),
                                           TREE_PURPOSE (t2)))
                  {
-                   permerror ("default argument given for parameter %d of %q#D",
+                   permerror (input_location, "default argument given for parameter %d of %q#D",
                               i, newdecl);
-                   permerror ("after previous specification in %q+#D", olddecl);
+                   permerror (input_location, "after previous specification in %q+#D", olddecl);
                  }
                else
                  {
@@ -1652,15 +1657,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
              && DECL_INITIAL (new_result))
            {
              if (DECL_INITIAL (old_result))
-               {
-                 DECL_INLINE (old_result) = 0;
-                 DECL_UNINLINABLE (old_result) = 1;
-               }
+               DECL_UNINLINABLE (old_result) = 1;
              else
-               {
-                 DECL_INLINE (old_result) = DECL_INLINE (new_result);
-                 DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
-               }
+               DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
              DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
              DECL_NOT_REALLY_EXTERN (old_result)
                = DECL_NOT_REALLY_EXTERN (new_result);
@@ -1674,8 +1673,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            }
          else
            {
-             DECL_INLINE (old_result)
-               |= DECL_INLINE (new_result);
              DECL_DECLARED_INLINE_P (old_result)
                |= DECL_DECLARED_INLINE_P (new_result);
              DECL_DISREGARD_INLINE_LIMITS (old_result)
@@ -1694,8 +1691,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 = TREE_CHAIN (parm))
+               DECL_CONTEXT (parm) = old_result;
+           }
        }
 
       return olddecl;
@@ -1772,15 +1775,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       if (TREE_DEPRECATED (newdecl))
        TREE_DEPRECATED (olddecl) = 1;
 
+      /* Preserve function specific target and optimization options */
+      if (TREE_CODE (newdecl) == FUNCTION_DECL)
+       {
+         if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
+             && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
+           DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
+             = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
+
+         if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
+             && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
+           DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
+             = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+       }
+
       /* Merge the initialization information.  */
       if (DECL_INITIAL (newdecl) == NULL_TREE
          && DECL_INITIAL (olddecl) != NULL_TREE)
        {
          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);
@@ -1838,14 +1853,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;
@@ -1873,6 +1890,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
@@ -1884,24 +1902,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));
@@ -1914,6 +1935,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 
   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 = TREE_CHAIN(oldarg), newarg = TREE_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))
        {
@@ -1922,7 +1956,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
@@ -1949,7 +1983,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          /* Never inline re-defined extern inline functions.
             FIXME: this could be better handled by keeping both
             function as separate declarations.  */
-         DECL_INLINE (newdecl) = 0;
          DECL_UNINLINABLE (newdecl) = 1;
        }
       else
@@ -1959,12 +1992,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 
          DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
 
-         /* If either decl says `inline', this fn is inline, unless
-            its definition was passed already.  */
-         if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
-           DECL_INLINE (olddecl) = 1;
-         DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
-
          DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
            = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
 
@@ -1977,6 +2004,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 = TREE_CHAIN (parm))
+       DECL_CONTEXT (parm) = olddecl;
+
       if (! types_match)
        {
          SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
@@ -2009,7 +2041,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);
        }
@@ -2028,10 +2061,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))
@@ -2056,6 +2089,12 @@ 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;
+
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       int function_size;
@@ -2069,7 +2108,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:
 
@@ -2092,7 +2131,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
@@ -2353,7 +2392,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;
@@ -2435,20 +2474,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.  */
@@ -2457,11 +2504,11 @@ static void
 identify_goto (tree decl, const location_t *locus)
 {
   if (decl)
-    permerror ("jump to label %qD", decl);
+    permerror (input_location, "jump to label %qD", decl);
   else
-    permerror ("jump to case label");
+    permerror (input_location, "jump to case label");
   if (locus)
-    permerror ("%H  from here", locus);
+    permerror (*locus, "  from here");
 }
 
 /* Check that a single previously seen jump to a newly defined label
@@ -2503,7 +2550,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 ("  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)
@@ -2599,8 +2647,8 @@ check_goto (tree decl)
   if (ent->in_try_scope || ent->in_catch_scope
       || ent->in_omp_scope || ent->bad_decls)
     {
-      permerror ("jump to label %q+D", decl);
-      permerror ("  from here");
+      permerror (input_location, "jump to label %q+D", decl);
+      permerror (input_location, "  from here");
       identified = true;
     }
 
@@ -2612,13 +2660,14 @@ check_goto (tree decl)
       if (u > 1 && DECL_ARTIFICIAL (b))
        {
          /* Can't skip init of __exception_info.  */
-         error ("%J  enters catch block", b);
+         error_at (DECL_SOURCE_LOCATION (b), "  enters catch block");
          saw_catch = true;
        }
       else if (u > 1)
        error ("  skips initialization of %q+#D", b);
       else
-       permerror ("  enters scope of non-POD %q+#D", b);
+       permerror (input_location, "  enters scope of %q+#D which has "
+                  "non-trivial destructor", b);
     }
 
   if (ent->in_try_scope)
@@ -2639,8 +2688,8 @@ check_goto (tree decl)
            {
              if (!identified)
                {
-                 permerror ("jump to label %q+D", decl);
-                 permerror ("  from here");
+                 permerror (input_location, "jump to label %q+D", decl);
+                 permerror (input_location, "  from here");
                  identified = true;
                }
              error ("  exits OpenMP structured block");
@@ -2692,7 +2741,7 @@ define_label (location_t location, tree name)
     p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
-    permerror ("label named wchar_t");
+    permerror (input_location, "label named wchar_t");
 
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
@@ -2780,7 +2829,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;
@@ -2791,8 +2840,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.  */
@@ -2803,7 +2852,8 @@ 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),
+  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
@@ -2899,7 +2949,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);
@@ -2974,12 +3024,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)
@@ -2987,11 +3031,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, 0, /*want_type=*/true);
+  else
+    t = NULL_TREE;
+
+  if (!t && 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)
@@ -3091,7 +3147,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);
@@ -3128,7 +3184,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);
     }
@@ -3136,7 +3192,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);
@@ -3159,15 +3215,23 @@ 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
     { /* "__java_float" or ""__java_double".  */
-      type = make_node (REAL_TYPE);
+      type = cxx_make_type (REAL_TYPE);
       TYPE_PRECISION (type) = - size;
       layout_type (type);
     }
@@ -3188,14 +3252,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
@@ -3332,7 +3397,7 @@ cxx_init_decl_processing (void)
 
   /* C++ extensions */
 
-  unknown_type_node = make_node (UNKNOWN_TYPE);
+  unknown_type_node = cxx_make_type (UNKNOWN_TYPE);
   record_unknown_type (unknown_type_node, "unknown type");
 
   /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
@@ -3343,13 +3408,13 @@ 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 = cxx_make_type (UNKNOWN_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
   {
     /* Make sure we get a unique function type, so we can give
        its pointer type a name.  (This wins for gdb.) */
-    tree vfunc_type = make_node (FUNCTION_TYPE);
+    tree vfunc_type = cxx_make_type (FUNCTION_TYPE);
     TREE_TYPE (vfunc_type) = integer_type_node;
     TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
     layout_type (vfunc_type);
@@ -3371,7 +3436,7 @@ cxx_init_decl_processing (void)
   abi_node = current_namespace;
   pop_namespace ();
 
-  global_type_node = make_node (LANG_TYPE);
+  global_type_node = cxx_make_type (LANG_TYPE);
   record_unknown_type (global_type_node, "global type");
 
   /* Now, C++.  */
@@ -3415,6 +3480,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 ();
@@ -3462,20 +3528,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));
@@ -3506,17 +3573,13 @@ cp_make_fname_decl (tree id, int type_dep)
 }
 
 static tree
-builtin_function_1 (tree decl, tree context)
+builtin_function_1 (tree decl, tree context, bool is_global)
 {
   tree          id = DECL_NAME (decl);
   const char *name = IDENTIFIER_POINTER (id);
 
   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);
@@ -3527,7 +3590,10 @@ builtin_function_1 (tree decl, tree context)
 
   DECL_CONTEXT (decl) = context;
 
-  pushdecl (decl);
+  if (is_global)
+    pushdecl_top_level (decl);
+  else
+    pushdecl (decl);
 
   /* A function in the user's namespace should have an explicit
      declaration before it is used.  Mark the built-in function as
@@ -3560,11 +3626,36 @@ cxx_builtin_function (tree decl)
     {
       tree decl2 = copy_node(decl);
       push_namespace (std_identifier);
-      builtin_function_1 (decl2, std_node);
+      builtin_function_1 (decl2, std_node, false);
+      pop_namespace ();
+    }
+
+  return builtin_function_1 (decl, NULL_TREE, false);
+}
+
+/* Like cxx_builtin_function, but guarantee the function is added to the global
+   scope.  This is to allow function specific options to add new machine
+   dependent builtins when the target ISA changes via attribute((target(...)))
+   which saves space on program startup if the program does not use non-generic
+   ISAs.  */
+
+tree
+cxx_builtin_function_ext_scope (tree decl)
+{
+
+  tree          id = DECL_NAME (decl);
+  const char *name = IDENTIFIER_POINTER (id);
+  /* All builtins that don't begin with an '_' should additionally
+     go in the 'std' namespace.  */
+  if (name[0] != '_')
+    {
+      tree decl2 = copy_node(decl);
+      push_namespace (std_identifier);
+      builtin_function_1 (decl2, std_node, true);
       pop_namespace ();
     }
 
-  return builtin_function_1 (decl, NULL_TREE);
+  return builtin_function_1 (decl, NULL_TREE, true);
 }
 
 /* Generate a FUNCTION_DECL with the typical flags for a runtime library
@@ -3720,9 +3811,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
@@ -3775,7 +3868,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
   else if (declspecs->redefined_builtin_type)
     {
       if (!in_system_header)
-       permerror ("redeclaration of C++ built-in type %qT",
+       permerror (input_location, "redeclaration of C++ built-in type %qT",
                   declspecs->redefined_builtin_type);
       return NULL_TREE;
     }
@@ -3789,7 +3882,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
   else if (declspecs->type == error_mark_node)
     error_p = true;
   if (declared_type == NULL_TREE && ! saw_friend && !error_p)
-    permerror ("declaration does not declare anything");
+    permerror (input_location, "declaration does not declare anything");
   /* Check for an anonymous union.  */
   else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
           && TYPE_ANONYMOUS_P (declared_type))
@@ -3819,7 +3912,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
       SET_ANON_AGGR_TYPE_P (declared_type);
 
       if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
-       pedwarn (OPT_pedantic, "ISO C++ prohibits anonymous structs");
+       pedwarn (input_location, OPT_pedantic, "ISO C++ prohibits anonymous structs");
     }
 
   else
@@ -3846,6 +3939,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;
@@ -3907,13 +4002,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))
@@ -3936,14 +4034,14 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
    grokfield.)  The DECL corresponding to the DECLARATOR is returned.
    If an error occurs, the error_mark_node is returned instead.
    
-   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED is 1
-   if an explicit initializer is present, or 2 for an explicitly defaulted
-   function, or 3 for an explicitly deleted function, but 0 if this is a
-   variable implicitly initialized via a default constructor.  ATTRIBUTES
-   and PREFIX_ATTRIBUTES are GNU attributes associated with this
-   declaration.  *PUSHED_SCOPE_P is set to the scope entered in this
-   function, if any; if set, the caller is responsible for calling
-   pop_scope.  */
+   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED is
+   SD_INITIALIZED if an explicit initializer is present, or SD_DEFAULTED
+   for an explicitly defaulted function, or SD_DELETED for an explicitly
+   deleted function, but 0 (SD_UNINITIALIZED) if this is a variable
+   implicitly initialized via a default constructor.  ATTRIBUTES and
+   PREFIX_ATTRIBUTES are GNU attributes associated with this declaration.
+   *PUSHED_SCOPE_P is set to the scope entered in this function, if any; if
+   set, the caller is responsible for calling pop_scope.  */
 
 tree
 start_decl (const cp_declarator *declarator,
@@ -4001,7 +4099,7 @@ start_decl (const cp_declarator *declarator,
        return error_mark_node;
 
       case FUNCTION_DECL:
-       if (initialized == 3)
+       if (initialized == SD_DELETED)
          /* We'll handle the rest of the semantics later, but we need to
             set this now so it's visible to duplicate_decls.  */
          DECL_DELETED_FN (decl) = 1;
@@ -4065,7 +4163,7 @@ start_decl (const cp_declarator *declarator,
              if (DECL_CONTEXT (field) != context)
                {
                  if (!same_type_p (DECL_CONTEXT (field), context))
-                   permerror ("ISO C++ does not permit %<%T::%D%> "
+                   permerror (input_location, "ISO C++ does not permit %<%T::%D%> "
                               "to be defined as %<%T::%D%>",
                               DECL_CONTEXT (field), DECL_NAME (decl),
                               context, DECL_NAME (decl));
@@ -4085,6 +4183,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
@@ -4121,8 +4222,11 @@ start_decl (const cp_declarator *declarator,
        }
 
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
-       permerror ("declaration of %q#D outside of class is not definition",
+       permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
+
+      if (!ensure_literal_type_for_constexpr_object (decl))
+        return error_mark_node;
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -4212,6 +4316,8 @@ start_decl_1 (tree decl, bool initialized)
         arrays which might be completed by the initialization.  */
       if (complete_p)
        ;                       /* A complete type is ok.  */
+      else if (type_uses_auto (type))
+       ;                       /* An auto type is ok.  */
       else if (TREE_CODE (type) != ARRAY_TYPE)
        {
          error ("variable %q#D has initializer but incomplete type", decl);
@@ -4226,8 +4332,11 @@ start_decl_1 (tree decl, bool initialized)
     }
   else if (aggregate_definition_p && !complete_p)
     {
-      error ("aggregate %q#D has incomplete type and cannot be defined",
-            decl);
+      if (type_uses_auto (type))
+       error ("declaration of %q#D has no initializer", decl);
+      else
+       error ("aggregate %q#D has incomplete type and cannot be defined",
+              decl);
       /* Change the type so that assemble_variable will give
         DECL an rtl we can live with: (mem (const_int 0)).  */
       type = TREE_TYPE (decl) = error_mark_node;
@@ -4266,13 +4375,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
       return NULL_TREE;
     }
 
-  if (TREE_CODE (init) == CONSTRUCTOR)
-    {
-      error ("ISO C++ forbids use of initializer list to "
-            "initialize reference %qD", decl);
-      return NULL_TREE;
-    }
-
   if (TREE_CODE (init) == TREE_LIST)
     init = build_x_compound_expr_from_list (init, "initializer");
 
@@ -4317,6 +4419,9 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
 {
   tree aggr_init, array, arrtype;
   init = perform_implicit_conversion (type, init, tf_warning_or_error);
+  if (error_operand_p (init))
+    return error_mark_node;
+
   aggr_init = TARGET_EXPR_INITIAL (init);
   init = build2 (INIT_EXPR, type, decl, init);
 
@@ -4354,9 +4459,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;
     }
 
@@ -4430,7 +4541,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);
     }
 }
 
@@ -4499,7 +4610,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
@@ -4508,13 +4619,7 @@ maybe_commonize_var (tree decl)
       /* Don't mess with __FUNCTION__.  */
       && ! DECL_ARTIFICIAL (decl)
       && DECL_FUNCTION_SCOPE_P (decl)
-      /* Unfortunately, import_export_decl has not always been called
-        before the function is processed, so we cannot simply check
-        DECL_COMDAT.  */
-      && (DECL_COMDAT (DECL_CONTEXT (decl))
-         || ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl))
-              || DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl)))
-             && TREE_PUBLIC (DECL_CONTEXT (decl)))))
+      && vague_linkage_fn_p (DECL_CONTEXT (decl)))
     {
       if (flag_weak)
        {
@@ -4540,12 +4645,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");
            }
        }
     }
@@ -4562,10 +4668,14 @@ check_for_uninitialized_const_var (tree decl)
 {
   tree type = TREE_TYPE (decl);
 
+  if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl)
+      && DECL_INITIAL (decl) == NULL)
+    error ("missing initializer for constexpr %qD", decl);
+
   /* ``Unless explicitly declared extern, a const object does not have
      external linkage and must be initialized. ($8.4; $12.1)'' ARM
      7.1.6 */
-  if (TREE_CODE (decl) == VAR_DECL
+  else if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
       && !TYPE_NEEDS_CONSTRUCTING (type)
@@ -4774,27 +4884,35 @@ 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)
 {
   tree init = d->cur->value;
 
+  if (error_operand_p (init))
+    return error_mark_node;
+
   /* A non-aggregate type is always initialized with a single
      initializer.  */
   if (!CP_AGGREGATE_TYPE_P (type))
     {
       /* It is invalid to initialize a non-aggregate type with a
-        brace-enclosed initializer.
+        brace-enclosed initializer before C++0x.
         We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
         of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
         a CONSTRUCTOR (with a record type).  */
       if (TREE_CODE (init) == CONSTRUCTOR
          && BRACE_ENCLOSED_INITIALIZER_P (init))  /* p7626.C */
        {
-         error ("braces around scalar initializer for type %qT", type);
-         init = error_mark_node;
+         if (SCALAR_TYPE_P (type))
+           {
+             error ("braces around scalar initializer for type %qT", type);
+             init = error_mark_node;
+           }
+         else
+           maybe_warn_cpp0x ("extended initializer lists");
        }
 
       d->cur++;
@@ -4811,7 +4929,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;
@@ -5074,7 +5197,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
                       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;
@@ -5096,7 +5219,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
        return build_aggr_init_full_exprs (decl, init, flags);
       else if (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
@@ -5407,6 +5530,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   int was_readonly = 0;
   bool var_definition_p = false;
   int saved_processing_template_decl;
+  tree auto_node;
 
   if (decl == error_mark_node)
     return;
@@ -5441,6 +5565,58 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
+  auto_node = type_uses_auto (type);
+  if (auto_node)
+    {
+      if (init == NULL_TREE)
+       {
+         error ("declaration of %q#D has no initializer", decl);
+         TREE_TYPE (decl) = error_mark_node;
+         return;
+       }
+      if (TREE_CODE (init) == TREE_LIST)
+       init = build_x_compound_expr_from_list (init, "initializer");
+      if (describable_type (init))
+       {
+         type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node);
+         if (type == error_mark_node)
+           return;
+       }
+    }
+
+  if (init && TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      tree clone;
+      if (init == ridpointers[(int)RID_DELETE])
+       {
+         /* FIXME check this is 1st decl.  */
+         DECL_DELETED_FN (decl) = 1;
+         DECL_DECLARED_INLINE_P (decl) = 1;
+         DECL_INITIAL (decl) = error_mark_node;
+         FOR_EACH_CLONE (clone, decl)
+           {
+             DECL_DELETED_FN (clone) = 1;
+             DECL_DECLARED_INLINE_P (clone) = 1;
+             DECL_INITIAL (clone) = error_mark_node;
+           }
+         init = NULL_TREE;
+       }
+      else if (init == ridpointers[(int)RID_DEFAULT])
+       {
+         if (!defaultable_fn_p (decl))
+           {
+             error ("%qD cannot be defaulted", decl);
+             DECL_INITIAL (decl) = NULL_TREE;
+           }
+         else
+           {
+             DECL_DEFAULTED_FN (decl) = 1;
+             FOR_EACH_CLONE (clone, decl)
+               DECL_DEFAULTED_FN (clone) = 1;
+           }
+       }
+    }
+    
   if (processing_template_decl)
     {
       bool type_dependent_p;
@@ -5457,7 +5633,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          DECL_INITIAL (decl) = NULL_TREE;
        }
 
-      if (init && init_const_expr_p)
+      if (init && init_const_expr_p && TREE_CODE (decl) == VAR_DECL)
        {
          DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
          if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
@@ -5536,11 +5712,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
@@ -5643,6 +5821,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))
@@ -5702,25 +5889,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        {
          if (init)
            {
-             if (init == ridpointers[(int)RID_DELETE])
+             if (init == ridpointers[(int)RID_DEFAULT])
                {
-                 /* 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 (!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);
@@ -5767,14 +5941,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
     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:
 
      extern "C" TYPE NAME;
@@ -5788,7 +5954,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;
@@ -5797,7 +5963,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;
@@ -5952,6 +6118,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)
@@ -6381,7 +6548,7 @@ check_class_member_definition_namespace (tree decl)
      The definition for a static data member shall appear in a
      namespace scope enclosing the member's class definition.  */
   if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
-    permerror ("definition of %qD is not in namespace enclosing %qT",
+    permerror (input_location, "definition of %qD is not in namespace enclosing %qT",
               decl, DECL_CONTEXT (decl));
 }
 
@@ -6443,7 +6610,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;
@@ -6453,6 +6621,12 @@ 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;
@@ -6461,6 +6635,8 @@ grokfndecl (tree ctype,
       parms = parm;
     }
   DECL_ARGUMENTS (decl) = parms;
+  for (t = parms; t; t = TREE_CHAIN (t))
+    DECL_CONTEXT (t) = decl;
   /* Propagate volatile out from type to decl.  */
   if (TYPE_VOLATILE (type))
     TREE_THIS_VOLATILE (decl) = 1;
@@ -6470,6 +6646,7 @@ grokfndecl (tree ctype,
     {
     case sfk_constructor:
     case sfk_copy_constructor:
+    case sfk_move_constructor:
       DECL_CONSTRUCTOR_P (decl) = 1;
       break;
     case sfk_destructor:
@@ -6598,36 +6775,6 @@ grokfndecl (tree ctype,
                || decl_function_context (TYPE_MAIN_DECL (ctype))))
     publicp = 0;
 
-  if (publicp)
-    {
-      /* [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.  */
-      t = 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
-               {
-                 permerror ("non-local function %q#D uses anonymous type",
-                             decl);
-                 if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-                   permerror ("%q+#D does not refer to the unqualified "
-                              "type, so it is not used for linkage",
-                              TYPE_NAME (t));
-               }
-           }
-         else
-           permerror ("non-local function %q#D uses local type %qT", decl, t);
-       }
-    }
-
   TREE_PUBLIC (decl) = publicp;
   if (! publicp)
     {
@@ -6638,11 +6785,6 @@ grokfndecl (tree ctype,
   /* If the declaration was declared inline, mark it as such.  */
   if (inlinep)
     DECL_DECLARED_INLINE_P (decl) = 1;
-  /* We inline functions that are explicitly declared inline, or, when
-     the user explicitly asks us to, all functions.  */
-  if (DECL_DECLARED_INLINE_P (decl)
-      || (!DECL_INLINE (decl) && funcdef_flag))
-    DECL_INLINE (decl) = 1;
 
   DECL_EXTERNAL (decl) = 1;
   if (quals && TREE_CODE (type) == FUNCTION_TYPE)
@@ -6658,9 +6800,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.  */
@@ -6701,7 +6840,8 @@ grokfndecl (tree ctype,
          newtype = build_function_type (integer_type_node, oldtypeargs);
          TREE_TYPE (decl) = newtype;
        }
-      check_main_parameter_types (decl);
+      if (warn_main)
+       check_main_parameter_types (decl);
     }
 
   if (ctype != NULL_TREE
@@ -6836,7 +6976,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);
@@ -6876,36 +7016,13 @@ grokvardecl (tree type,
 
   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);
-      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);
-                 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",
-                            TYPE_NAME (t));
-               }
-           }
-         else
-           warning (0, "non-local variable %q#D uses local type %qT", decl, t);
-       }
+      /* If the type of the decl has no linkage, make sure that we'll
+        notice that in mark_used.  */
+      if (DECL_LANG_SPECIFIC (decl) == NULL
+         && TREE_PUBLIC (decl)
+         && !DECL_EXTERN_C_P (decl)
+         && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+       retrofit_lang_decl (decl);
     }
   else
     DECL_INTERFACE_KNOWN (decl) = 1;
@@ -6947,10 +7064,11 @@ 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);
+  field = build_decl (input_location, FIELD_DECL, delta_identifier, 
+                     delta_type_node);
   TREE_CHAIN (field) = fields;
   fields = field;
 
@@ -6963,23 +7081,28 @@ 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;
+      TREE_TYPE (TYPE_BINFO (t)) = t;
     }
 
   /* Cache this pointer-to-member type so that we can find it again
      later.  */
   TYPE_SET_PTRMEMFUNC_TYPE (type, t);
 
-  /* Managing canonical types for the RECORD_TYPE behind a
-     pointer-to-member function is a nightmare, so use structural
-     equality for now.  */
-  SET_TYPE_STRUCTURAL_EQUALITY (t);
+  if (TYPE_STRUCTURAL_EQUALITY_P (type))
+    SET_TYPE_STRUCTURAL_EQUALITY (t);
+  else if (TYPE_CANONICAL (type) != type)
+    TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));
 
   return t;
 }
@@ -7039,8 +7162,8 @@ check_static_variable_definition (tree decl, tree type)
     error ("ISO C++ forbids in-class initialization of non-const "
           "static member %qD",
           decl);
-  else if (!INTEGRAL_TYPE_P (type))
-    pedwarn (OPT_pedantic, "ISO C++ forbids initialization of member constant "
+  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);
 
   return 0;
@@ -7062,7 +7185,7 @@ compute_array_index_type (tree name, tree size)
 
   type = TREE_TYPE (size);
   /* The array bound must be an integer type.  */
-  if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
+  if (!dependent_type_p (type) && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
     {
       if (name)
        error ("size of array %qD has non-integral type %qT", name, type);
@@ -7072,13 +7195,22 @@ compute_array_index_type (tree name, tree size)
       type = TREE_TYPE (size);
     }
 
-  if (value_dependent_expression_p (size))
+  /* We can only call value_dependent_expression_p on integral constant
+     expressions; the parser adds a dummy NOP_EXPR with TREE_SIDE_EFFECTS
+     set if this isn't one.  */
+  if (processing_template_decl
+      && (TREE_SIDE_EFFECTS (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));
+      if (!TREE_SIDE_EFFECTS (size))
+       {
+         TYPE_DEPENDENT_P (itype) = 1;
+         TYPE_DEPENDENT_P_VALID (itype) = 1;
+       }
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
       return itype;
     }
@@ -7120,9 +7252,9 @@ compute_array_index_type (tree name, tree size)
       else if (integer_zerop (size) && !in_system_header)
        {
          if (name)
-           pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
+           pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
          else
-           pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array");
+           pedwarn (input_location, OPT_pedantic, "ISO C++ forbids zero-size array");
        }
     }
   else if (TREE_CONSTANT (size))
@@ -7138,9 +7270,9 @@ compute_array_index_type (tree name, tree size)
   else if (pedantic && warn_vla != 0)
     {
       if (name)
-       pedwarn (OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
+       pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
       else
-       pedwarn (OPT_Wvla, "ISO C++ forbids variable length array");
+       pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array");
     }
   else if (warn_vla > 0)
     {
@@ -7165,7 +7297,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);
@@ -7479,7 +7612,9 @@ grokdeclarator (const cp_declarator *declarator,
   bool unsigned_p, signed_p, short_p, long_p, thread_p;
   bool type_was_error_mark_node = false;
   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
-  bool set_no_warning = false;
+  bool template_type_arg = false;
+  bool constexpr_p = declspecs->specs[(int) ds_constexpr];
+  const char *errmsg;
 
   signed_p = declspecs->specs[(int)ds_signed];
   unsigned_p = declspecs->specs[(int)ds_unsigned];
@@ -7494,6 +7629,8 @@ 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;
 
   if (initialized > 1)
     funcdef_flag = true;
@@ -7582,7 +7719,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;
@@ -7608,10 +7747,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);
@@ -7619,7 +7758,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>";
                  }
@@ -7716,7 +7855,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;
@@ -7724,7 +7863,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.  */
@@ -7772,9 +7911,9 @@ grokdeclarator (const cp_declarator *declarator,
       else if (in_system_header || flag_ms_extensions)
        /* Allow it, sigh.  */;
       else if (! is_main)
-       permerror ("ISO C++ forbids declaration of %qs with no type", name);
+       permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name);
       else if (pedantic)
-       pedwarn (OPT_pedantic,
+       pedwarn (input_location, OPT_pedantic,
                 "ISO C++ forbids declaration of %qs with no type", name);
       else
        warning (OPT_Wreturn_type,
@@ -7830,7 +7969,7 @@ grokdeclarator (const cp_declarator *declarator,
          ok = 1;
          if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
            {
-             pedwarn (OPT_pedantic, 
+             pedwarn (input_location, OPT_pedantic, 
                       "long, short, signed or unsigned used invalidly for %qs",
                       name);
              if (flag_pedantic_errors)
@@ -7919,6 +8058,17 @@ grokdeclarator (const cp_declarator *declarator,
   type_quals = TYPE_UNQUALIFIED;
   if (declspecs->specs[(int)ds_const])
     type_quals |= TYPE_QUAL_CONST;
+  /* A `constexpr' specifier used in an object declaration declares
+     the object as `const'.  */
+  if (constexpr_p)
+    {
+      if (innermost_code == cdk_function)
+        ;
+      else if (declspecs->specs[(int)ds_const] != 0)
+        error ("both %<const%> and %<constexpr%> cannot be used here");
+      else
+        type_quals |= TYPE_QUAL_CONST;
+    }
   if (declspecs->specs[(int)ds_volatile])
     type_quals |= TYPE_QUAL_VOLATILE;
   if (declspecs->specs[(int)ds_restrict])
@@ -7936,7 +8086,7 @@ grokdeclarator (const cp_declarator *declarator,
       if (pedantic)
        {
          tree bad_type = build_qualified_type (type, type_quals);
-         pedwarn (OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic, 
                   "ignoring %qV qualifiers added to function type %qT",
                   bad_type, type);
        }
@@ -7984,6 +8134,20 @@ grokdeclarator (const cp_declarator *declarator,
               || 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.  */
@@ -8078,8 +8242,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:
@@ -8146,7 +8311,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.  */
@@ -8172,6 +8342,37 @@ grokdeclarator (const cp_declarator *declarator,
               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;
+
            if (ctype == NULL_TREE
                && decl_context == FIELD
                && funcdecl_p
@@ -8218,7 +8419,7 @@ grokdeclarator (const cp_declarator *declarator,
                      explicitp = 2;
                    if (virtualp)
                      {
-                       permerror ("constructors cannot be declared virtual");
+                       permerror (input_location, "constructors cannot be declared virtual");
                        virtualp = 0;
                      }
                    if (decl_context == FIELD
@@ -8245,6 +8446,29 @@ grokdeclarator (const cp_declarator *declarator,
                         "class definition",
                         name);
              }
+           else if (ctype && sfk == sfk_conversion)
+             {
+               if (explicitp == 1)
+                 {
+                   maybe_warn_cpp0x ("explicit conversion operators");
+                   explicitp = 2;
+                 }
+             }
+
+            /* It is not allowed to use `constexpr' in a function
+               declaration that is not a definition.
+               That is too strict, though.  */
+            if (constexpr_p && !funcdef_flag)
+              {
+                error ("the %<constexpr%> specifier cannot be used in "
+                       "a function declaration that is not a definition");
+                constexpr_p = false;
+              }
+
+            /* A constexpr non-static member function is implicitly const.  */
+            if (constexpr_p && decl_context == FIELD && staticp == 0
+                && sfk != sfk_constructor && sfk != sfk_destructor)
+              memfn_quals |= TYPE_QUAL_CONST;
 
            arg_types = grokparms (declarator->u.function.parameters,
                                   &parms);
@@ -8313,6 +8537,12 @@ grokdeclarator (const cp_declarator *declarator,
              memfn_quals = TYPE_UNQUALIFIED;
            }
 
+         if (TREE_CODE (type) == FUNCTION_TYPE
+             && cp_type_quals (type) != TYPE_UNQUALIFIED)
+           error ("cannot declare %s to qualified function type %qT",
+                  declarator->kind == cdk_reference ? "reference" : "pointer",
+                  type);
+
          if (declarator->kind == cdk_reference)
            {
              /* In C++0x, the type we are creating a reference to might be
@@ -8441,12 +8671,13 @@ grokdeclarator (const cp_declarator *declarator,
        {
          if (friendp)
            {
-             permerror ("member functions are implicitly friends of their class");
+             permerror (input_location, "member functions are implicitly friends of their class");
              friendp = 0;
            }
          else
-           permerror ("extra qualification %<%T::%> on member %qs",
-                      ctype, name);
+           permerror (declarator->id_loc, 
+                         "extra qualification %<%T::%> on member %qs",
+                         ctype, name);
        }
       else if (/* If the qualifying type is already complete, then we
                  can skip the following checks.  */
@@ -8483,6 +8714,12 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
 
+          /* It is not permitted to define a member function outside ist
+             membership class as `constexpr'.  */
+          if (constexpr_p)
+            error ("a constexpr function cannot be defined "
+                   "outside of its class.");
+
          if (TREE_CODE (sname) == IDENTIFIER_NODE
              && NEW_DELETE_OPNAME_P (sname))
            /* Overloaded operator new and operator delete
@@ -8612,9 +8849,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)
        {
@@ -8630,7 +8870,7 @@ grokdeclarator (const cp_declarator *declarator,
            DECL_ABSTRACT (decl) = 1;
        }
       else if (constructor_name_p (unqualified_id, current_class_type))
-       permerror ("ISO C++ forbids nested type %qD with same name "
+       permerror (input_location, "ISO C++ forbids nested type %qD with same name "
                   "as enclosing class",
                   unqualified_id);
 
@@ -8645,13 +8885,17 @@ 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)))
+               {
+                 debug_hooks->set_name (t, decl);
+                 TYPE_NAME (t) = decl;
+               }
+           }
 
          if (TYPE_LANG_SPECIFIC (type))
            TYPE_WAS_ANONYMOUS (type) = 1;
@@ -8663,6 +8907,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.  */
        }
@@ -8755,13 +9003,13 @@ grokdeclarator (const cp_declarator *declarator,
            {
              /* Don't allow friend declaration without a class-key.  */
              if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-               permerror ("template parameters cannot be friends");
+               permerror (input_location, "template parameters cannot be friends");
              else if (TREE_CODE (type) == TYPENAME_TYPE)
-               permerror ("friend declaration requires class-key, "
+               permerror (input_location, "friend declaration requires class-key, "
                           "i.e. %<friend class %T::%D%>",
                           TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
              else
-               permerror ("friend declaration requires class-key, "
+               permerror (input_location, "friend declaration requires class-key, "
                           "i.e. %<friend %#T%>",
                           type);
            }
@@ -8782,15 +9030,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 = cp_build_qualified_type (type, memfn_quals);
+         else
+           error ("invalid qualifiers on non-member function type");
        }
 
       return type;
@@ -8921,23 +9171,24 @@ grokdeclarator (const cp_declarator *declarator,
            /* 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%>");
              }
            else if (sfk == sfk_constructor && friendp)
              {
@@ -8958,9 +9209,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 || 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
@@ -8978,15 +9231,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)
          {
@@ -9002,7 +9246,8 @@ grokdeclarator (const cp_declarator *declarator,
                               virtualp, flags, memfn_quals, raises,
                               friendp ? -1 : 0, friendp, 1, 0, sfk,
                               funcdef_flag, template_count, in_namespace,
-                              attrlist);
+                              attrlist,
+                              declarator->id_loc);
            if (decl == NULL_TREE)
              return error_mark_node;
          }
@@ -9057,6 +9302,7 @@ grokdeclarator (const cp_declarator *declarator,
                decl = do_friend (ctype, unqualified_id, decl,
                                  *attrlist, flags,
                                  funcdef_flag);
+                DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
                return decl;
              }
            else
@@ -9083,9 +9329,9 @@ 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 ("ISO C++ forbids initialization of member %qD",
+                   permerror (input_location, "ISO C++ forbids initialization of member %qD",
                               unqualified_id);
-                   permerror ("making %qD static", unqualified_id);
+                   permerror (input_location, "making %qD static", unqualified_id);
                    staticp = 1;
                  }
 
@@ -9118,7 +9364,11 @@ 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);
+               decl = build_decl (input_location,
+                                  FIELD_DECL, unqualified_id, type);
                DECL_NONADDRESSABLE_P (decl) = bitfield;
                if (bitfield && !unqualified_id)
                  TREE_NO_WARNING (decl) = 1;
@@ -9165,15 +9415,22 @@ grokdeclarator (const cp_declarator *declarator,
            && pedantic)
          {
            if (storage_class == sc_static)
-             pedwarn (OPT_pedantic, 
+             pedwarn (input_location, OPT_pedantic, 
                       "%<static%> specified invalid for function %qs "
                       "declared out of global scope", name);
            else
-             pedwarn (OPT_pedantic, 
+             pedwarn (input_location, OPT_pedantic, 
                       "%<inline%> specifier invalid for function %qs "
                       "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)
@@ -9181,6 +9438,14 @@ 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))
@@ -9196,8 +9461,9 @@ 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 || constexpr_p, sfk, funcdef_flag,
+                          template_count, in_namespace, attrlist,
+                          declarator->id_loc);
        if (decl == NULL_TREE)
          return error_mark_node;
 
@@ -9209,7 +9475,7 @@ grokdeclarator (const cp_declarator *declarator,
               declaring main to be static.  */
            if (TREE_CODE (type) == METHOD_TYPE)
              {
-               permerror ("cannot declare member function %qD to have "
+               permerror (input_location, "cannot declare member function %qD to have "
                           "static linkage", decl);
                invalid_static = 1;
              }
@@ -9246,7 +9512,7 @@ grokdeclarator (const cp_declarator *declarator,
            DECL_CONTEXT (decl) = ctype;
            if (staticp == 1)
              {
-               permerror ("%<static%> may not be used when defining "
+               permerror (input_location, "%<static%> may not be used when defining "
                           "(as opposed to declaring) a static data member");
                staticp = 0;
                storage_class = sc_none;
@@ -9258,7 +9524,7 @@ grokdeclarator (const cp_declarator *declarator,
              }
            if (storage_class == sc_extern && pedantic)
              {
-               pedwarn (OPT_pedantic, 
+               pedwarn (input_location, OPT_pedantic, 
                         "cannot explicitly declare member %q#D to have "
                         "extern linkage", decl);
                storage_class = sc_none;
@@ -9276,7 +9542,10 @@ grokdeclarator (const cp_declarator *declarator,
              warning (0, "%qs initialized and declared %<extern%>", name);
          }
        else
-         error ("%qs has both %<extern%> and initializer", name);
+         {
+           error ("%qs has both %<extern%> and initializer", name);
+           return error_mark_node;
+         }
       }
 
     /* Record `register' declaration for warnings on &
@@ -9289,15 +9558,16 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
+    /* Don't forget constexprness.  */
+    if (VAR_OR_FUNCTION_DECL_P (decl))
+      DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
+
     /* Record constancy and volatility on the DECL itself .  There's
        no need to do this when processing a template; we'll do this
        for the instantiated declaration based on the type of DECL.  */
     if (!processing_template_decl)
       cp_apply_type_quals_to_decl (type_quals, decl);
 
-    if (set_no_warning)
-        TREE_NO_WARNING (decl) = 1;
-
     return decl;
   }
 }
@@ -9427,6 +9697,32 @@ 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;
+
+  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.
@@ -9437,41 +9733,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);
@@ -9492,8 +9779,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);
@@ -9536,28 +9838,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;
       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;
 }
 
@@ -9683,6 +9977,10 @@ move_fn_p (const_tree d)
 
 /* Remember any special properties of member function DECL.  */
 
+#define DECL_DEFAULTED_IN_CLASS_P(DECL)                                        \
+ (DECL_DEFAULTED_FN (DECL)                                             \
+  && (DECL_ARTIFICIAL (DECL) || DECL_INITIALIZED_IN_CLASS_P (DECL)))
+
 void
 grok_special_member_properties (tree decl)
 {
@@ -9709,13 +10007,18 @@ grok_special_member_properties (tree decl)
             are no other parameters or else all other parameters have
             default arguments.  */
          TYPE_HAS_INIT_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (!DECL_DEFAULTED_IN_CLASS_P (decl))
            TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
          if (ctor > 1)
            TYPE_HAS_CONST_INIT_REF (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 (TREE_CODE (decl) == TEMPLATE_DECL
+             || !DECL_DEFAULTED_IN_CLASS_P (decl))
+           TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
+       }
       else if (is_list_ctor (decl))
        TYPE_HAS_LIST_CTOR (class_type) = 1;
     }
@@ -9732,7 +10035,7 @@ grok_special_member_properties (tree decl)
       if (assop)
        {
          TYPE_HAS_ASSIGN_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (!DECL_DEFAULTED_IN_CLASS_P (decl))
            TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
          if (assop != 1)
            TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
@@ -10151,7 +10454,7 @@ grok_op_properties (tree decl, bool complain)
            if (operator_code == POSTINCREMENT_EXPR
                || operator_code == POSTDECREMENT_EXPR)
              {
-               pedwarn (OPT_pedantic, "%qD cannot have default arguments", 
+               pedwarn (input_location, OPT_pedantic, "%qD cannot have default arguments", 
                         decl);
              }
            else
@@ -10577,6 +10880,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);
@@ -10623,10 +10929,7 @@ xref_basetypes (tree ref, tree base_list)
         basetype = PACK_EXPANSION_PATTERN (basetype);
       if (TREE_CODE (basetype) == TYPE_DECL)
        basetype = TREE_TYPE (basetype);
-      if (TREE_CODE (basetype) != RECORD_TYPE
-         && TREE_CODE (basetype) != TYPENAME_TYPE
-         && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
-         && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM)
+      if (!MAYBE_CLASS_TYPE_P (basetype) || TREE_CODE (basetype) == UNION_TYPE)
        {
          error ("base type %qT fails to be a struct or class type",
                 basetype);
@@ -10718,13 +11021,20 @@ xref_basetypes (tree ref, tree base_list)
 
 \f
 /* Begin compiling the definition of an enumeration type.
-   NAME is its name.
+   NAME is its name, 
+
+   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.
+
    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)
+start_enum (tree name, tree underlying_type, bool scoped_enum_p)
 {
   tree enumtype;
 
@@ -10740,8 +11050,9 @@ start_enum (tree name)
 
   if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
     {
-      error ("multiple definition of %q#T", enumtype);
-      error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
+      error_at (input_location, "multiple definition of %q#T", enumtype);
+      error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+               "previous definition here");
       /* Clear out TYPE_VALUES, and start again.  */
       TYPE_VALUES (enumtype) = NULL_TREE;
     }
@@ -10752,10 +11063,46 @@ start_enum (tree name)
       if (enumtype == error_mark_node)
        name = make_anon_name ();
 
-      enumtype = make_node (ENUMERAL_TYPE);
+      enumtype = cxx_make_type (ENUMERAL_TYPE);
       enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
+  if (enumtype == error_mark_node)
+    return enumtype;
+
+  if (scoped_enum_p)
+    {
+      SET_SCOPED_ENUM_P (enumtype, 1);
+      begin_scope (sk_scoped_enum, enumtype);
+
+      /* [C++0x dcl.enum]p5: 
+
+          If not explicitly specified, the underlying type of a scoped
+          enumeration type is int.  */
+      if (!underlying_type)
+        underlying_type = integer_type_node;
+    }
+
+  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);
+          SET_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);
+          ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
+        }
+      else if (!dependent_type_p (underlying_type))
+        error ("underlying type %<%T%> of %<%T%> must be an integral type", 
+               underlying_type, enumtype);
+    }
+
   return enumtype;
 }
 
@@ -10768,17 +11115,19 @@ finish_enum (tree enumtype)
 {
   tree values;
   tree decl;
-  tree value;
   tree minnode;
   tree maxnode;
+  tree value;
   tree t;
   bool unsignedp;
   bool use_short_enum;
   int lowprec;
   int highprec;
   int precision;
-  integer_type_kind itk;
+  unsigned int itk;
   tree underlying_type = NULL_TREE;
+  bool fixed_underlying_type_p 
+    = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
 
   /* We built up the VALUES in reverse order.  */
   TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
@@ -10795,6 +11144,8 @@ finish_enum (tree enumtype)
        TREE_TYPE (TREE_VALUE (values)) = enumtype;
       if (at_function_scope_p ())
        add_stmt (build_min (TAG_DEFN, enumtype));
+      if (SCOPED_ENUM_P (enumtype))
+       finish_scope ();
       return;
     }
 
@@ -10804,87 +11155,112 @@ 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.  */
+     MAXNODE are transformed, since tree_int_cst_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);
+  lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+  highprec = tree_int_cst_min_precision (maxnode, unsignedp);
   precision = MAX (lowprec, highprec);
 
-  /* Determine the underlying type of the enumeration.
+  if (!fixed_underlying_type_p)
+    {
+      /* Determine the underlying type of the enumeration.
 
-       [dcl.enum]
+         [dcl.enum]
 
-       The underlying type of an enumeration is an integral type that
-       can represent all the enumerator values defined in the
-       enumeration.  It is implementation-defined which integral type is
-       used as the underlying type for an enumeration except that the
-       underlying type shall not be larger than int unless the value of
-       an enumerator cannot fit in an int or unsigned int.
+         The underlying type of an enumeration is an integral type that
+         can represent all the enumerator values defined in the
+         enumeration.  It is implementation-defined which integral type is
+         used as the underlying type for an enumeration except that the
+         underlying type shall not be larger than int unless the value of
+         an enumerator cannot fit in an int or unsigned int.
 
-     We use "int" or an "unsigned int" as the underlying type, even if
-     a smaller integral type would work, unless the user has
-     explicitly requested that we use the smallest possible type.  The
-     user can request that for all enumerations with a command line
-     flag, or for just one enumeration with an attribute.  */
+         We use "int" or an "unsigned int" as the underlying type, even if
+         a smaller integral type would work, unless the user has
+         explicitly requested that we use the smallest possible type.  The
+         user can request that for all enumerations with a command line
+         flag, or for just one enumeration with an attribute.  */
 
-  use_short_enum = flag_short_enums
-    || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
+      use_short_enum = flag_short_enums
+        || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
 
-  for (itk = (use_short_enum ? itk_char : itk_int);
-       itk != itk_none;
-       itk++)
-    {
-      underlying_type = integer_types[itk];
-      if (TYPE_PRECISION (underlying_type) >= precision
-         && TYPE_UNSIGNED (underlying_type) == unsignedp)
-       break;
-    }
-  if (itk == itk_none)
-    {
-      /* DR 377
+      for (itk = (use_short_enum ? itk_char : itk_int);
+           itk != itk_none;
+           itk++)
+        {
+          underlying_type = integer_types[itk];
+          if (TYPE_PRECISION (underlying_type) >= precision
+              && TYPE_UNSIGNED (underlying_type) == unsignedp)
+            break;
+        }
+      if (itk == itk_none)
+        {
+          /* DR 377
+
+             IF no integral type can represent all the enumerator values, the
+             enumeration is ill-formed.  */
+          error ("no integral type can represent all of the enumerator values "
+                 "for %qT", enumtype);
+          precision = TYPE_PRECISION (long_long_integer_type_node);
+          underlying_type = integer_types[itk_unsigned_long_long];
+        }
 
-        IF no integral type can represent all the enumerator values, the
-        enumeration is ill-formed.  */
-      error ("no integral type can represent all of the enumerator values "
-            "for %qT", enumtype);
-      precision = TYPE_PRECISION (long_long_integer_type_node);
-      underlying_type = integer_types[itk_unsigned_long_long];
+      /* [dcl.enum]
+
+         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);
+      SET_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)
+       = build_distinct_type_copy (underlying_type);
+      set_min_and_max_values_for_integral_type 
+        (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
     }
+  else
+    underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
 
   /* Compute the minimum and maximum values for the type.
 
@@ -10895,28 +11271,16 @@ finish_enum (tree enumtype)
      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);
-
-  /* [dcl.enum]
-
-     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);
-
+  
   /* 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))
@@ -10926,9 +11290,14 @@ finish_enum (tree enumtype)
       decl = TREE_VALUE (values);
       saved_location = input_location;
       input_location = DECL_SOURCE_LOCATION (decl);
-      value = perform_implicit_conversion (underlying_type,
-                                          DECL_INITIAL (decl),
-                                          tf_warning_or_error);
+      if (fixed_underlying_type_p)
+        /* If the enumeration type has a fixed underlying type, we
+           already checked all of the enumerator values.  */
+        value = DECL_INITIAL (decl);
+      else
+        value = perform_implicit_conversion (underlying_type,
+                                             DECL_INITIAL (decl),
+                                             tf_warning_or_error);
       input_location = saved_location;
 
       /* Do not clobber shared ints.  */
@@ -10936,7 +11305,6 @@ finish_enum (tree enumtype)
 
       TREE_TYPE (value) = enumtype;
       DECL_INITIAL (decl) = value;
-      TREE_VALUE (values) = value;
     }
 
   /* Fix up all variant types of this enum type.  */
@@ -10947,13 +11315,18 @@ finish_enum (tree 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);
+      SET_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 ();
+
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (enumtype, namespace_bindings_p ());
 }
@@ -11007,21 +11380,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
@@ -11030,24 +11408,44 @@ build_enumerator (tree name, tree value, tree enumtype)
 
       /* Remove no-op casts from the value.  */
       STRIP_TYPE_NOPS (value);
+
+      /* If the underlying type of the enum is fixed, check whether
+         the enumerator values fits in the underlying type.  If it
+         does not fit, the program is ill-formed [C++0x dcl.enum].  */
+      if (ENUM_UNDERLYING_TYPE (enumtype)
+          && value
+          && TREE_CODE (value) == INTEGER_CST
+          && !int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
+        {
+          error ("enumerator value %E is too large for underlying type %<%T%>",
+                 value, ENUM_UNDERLYING_TYPE (enumtype));
+
+          /* Silently convert the value so that we can continue.  */
+          value = perform_implicit_conversion (ENUM_UNDERLYING_TYPE (enumtype),
+                                               value, tf_none);
+        }
     }
 
   /* C++ associates enums with global, function, or class declarations.  */
   context = current_scope ();
 
   /* Build the actual enumeration constant.  Note that the enumeration
-    constants have the type of their initializers until the
-    enumeration is complete:
-
-      [ dcl.enum ]
-
-      Following the closing brace of an enum-specifier, each enumer-
-      ator has the type of its enumeration.  Prior to the closing
-      brace, the type of each enumerator is the type of its
-      initializing value.
-
-    In finish_enum we will reset the type.  Of course, if we're
-    processing a template, there may be no value.  */
+     constants have the underlying type of the enum (if it is fixed)
+     or the type of their initializer (if the underlying type of the
+     enum is not fixed):
+
+      [ C++0x dcl.enum ]
+
+        If the underlying type is fixed, the type of each enumerator
+        prior to the closing brace is the underlying type; if the
+        initializing value of an enumerator cannot be represented by
+        the underlying type, the program is ill-formed. If the
+        underlying type is not fixed, the type of each enumerator is
+        the type of its initializing value.
+
+    If the underlying type is not fixed, it will be computed by
+    finish_enum and we will reset the type of this enumerator.  Of
+    course, if we're processing a template, there may be no value.  */
   type = value ? TREE_TYPE (value) : NULL_TREE;
 
   if (context && context == current_class_type)
@@ -11057,14 +11455,14 @@ build_enumerator (tree name, tree value, tree enumtype)
   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);
+    decl = build_decl (input_location, 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.)  */
@@ -11076,6 +11474,26 @@ build_enumerator (tree name, tree value, tree enumtype)
   TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
 }
 
+/* Look for an enumerator with the given NAME within the enumeration
+   type ENUMTYPE.  This routine is used primarily for qualified name
+   lookup into an enumerator in C++0x, e.g.,
+
+     enum class Color { Red, Green, Blue };
+
+     Color color = Color::Red;
+
+   Returns the value corresponding to the enumerator, or
+   NULL_TREE if no such enumerator was found.  */
+tree
+lookup_enumerator (tree enumtype, tree name)
+{
+  tree e;
+  gcc_assert (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE);
+
+  e = purpose_member (name, TYPE_VALUES (enumtype));
+  return e? TREE_VALUE (e) : NULL_TREE;
+}
+
 \f
 /* We're defining DECL.  Make sure that it's type is OK.  */
 
@@ -11088,6 +11506,10 @@ check_function_type (tree decl, tree current_function_parms)
   /* In a function definition, arg types must be complete.  */
   require_complete_types_for_parms (current_function_parms);
 
+  /* constexpr functions must have literal argument types and
+     literal return type.  */
+  validate_constexpr_fundecl (decl);
+
   if (dependent_type_p (return_type))
     return;
   if (!COMPLETE_OR_VOID_TYPE_P (return_type)
@@ -11264,7 +11686,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;
@@ -11507,7 +11929,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;
     }
 
@@ -11532,10 +11955,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
@@ -11684,13 +12112,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);
     }
 }
@@ -11732,7 +12160,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))
@@ -11770,7 +12198,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);
     }
 }
@@ -11869,6 +12297,9 @@ finish_function (int flags)
   if (fndecl == NULL_TREE)
     return error_mark_node;
 
+  gcc_assert (!defer_mark_used_calls);
+  defer_mark_used_calls = true;
+
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
       && DECL_VIRTUAL_P (fndecl)
       && !processing_template_decl)
@@ -12026,6 +12457,7 @@ finish_function (int flags)
   if (!processing_template_decl)
     {
       struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
+      invoke_plugin_callbacks (PLUGIN_CXX_CP_PRE_GENERICIZE, fndecl);
       cp_genericize (fndecl);
       /* Clear out the bits we don't need.  */
       f->x_current_class_ptr = NULL;
@@ -12036,9 +12468,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;
@@ -12068,6 +12497,17 @@ finish_function (int flags)
        cxx_pop_function_context and then reset via pop_function_context.  */
     current_function_decl = NULL_TREE;
 
+  defer_mark_used_calls = false;
+  if (deferred_mark_used_calls)
+    {
+      unsigned int i;
+      tree decl;
+
+      for (i = 0; VEC_iterate (tree, deferred_mark_used_calls, i, decl); i++)
+       mark_used (decl);
+      VEC_free (tree, gc, deferred_mark_used_calls);
+    }
+
   return fndecl;
 }
 \f
@@ -12093,8 +12533,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);
@@ -12127,8 +12567,7 @@ start_method (cp_decl_specifier_seq *declspecs,
   check_template_shadow (fndecl);
 
   DECL_DECLARED_INLINE_P (fndecl) = 1;
-  if (flag_default_inline)
-    DECL_INLINE (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))
@@ -12147,74 +12586,11 @@ start_method (cp_decl_specifier_seq *declspecs,
        }
     }
 
-  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
@@ -12340,7 +12716,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;
     }
@@ -12397,6 +12773,7 @@ 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;
     default:                   return TS_CP_GENERIC;
     }
 }
@@ -12418,7 +12795,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;
@@ -12448,7 +12825,7 @@ cxx_comdat_group (tree decl)
       name = DECL_ASSEMBLER_NAME (decl);
     }
 
-  return IDENTIFIER_POINTER (name);
+  return name;
 }
 
 #include "gt-cp-decl.h"