OSDN Git Service

* decl.c (record_builtin_java_type): Undo unintended change.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 6537c50..5d3ff9d 100644 (file)
@@ -53,6 +53,7 @@ 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 (tree parmlist, tree *);
 static const char *redeclaration_error_message (tree, tree);
@@ -93,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);
@@ -168,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,
@@ -191,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;
 
@@ -744,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);
     }
 
@@ -782,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.  */
 
@@ -855,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
@@ -886,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
@@ -929,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;
 
@@ -1111,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;
@@ -1471,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)
@@ -1788,9 +1795,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        {
          DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
          DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
-         if (CAN_HAVE_FULL_LANG_DECL_P (newdecl)
-             && DECL_LANG_SPECIFIC (newdecl)
-             && DECL_LANG_SPECIFIC (olddecl))
+         if (TREE_CODE (newdecl) == FUNCTION_DECL)
            {
              DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
              DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
@@ -1848,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;
@@ -1883,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
@@ -1894,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));
@@ -1926,6 +1937,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
     {
       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))
        {
@@ -1934,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
@@ -2039,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))
@@ -2067,11 +2089,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       ggc_free (DECL_LANG_SPECIFIC (olddecl));
     }
 
-   /* Merge the USED information.  */
-   if (TREE_USED (olddecl))
-     TREE_USED (newdecl) = 1;
-   else if (TREE_USED (newdecl))
-     TREE_USED (olddecl) = 1;
+  /* Merge the USED information.  */
+  if (TREE_USED (olddecl))
+    TREE_USED (newdecl) = 1;
+  else if (TREE_USED (newdecl))
+    TREE_USED (olddecl) = 1;
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2086,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:
 
@@ -2109,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
@@ -2370,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;
@@ -2452,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.  */
@@ -2478,7 +2508,7 @@ identify_goto (tree decl, const location_t *locus)
   else
     permerror (input_location, "jump to case label");
   if (locus)
-    permerror (input_location, "%H  from here", locus);
+    permerror (*locus, "  from here");
 }
 
 /* Check that a single previously seen jump to a newly defined label
@@ -2520,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 (input_location, "  enters scope of non-POD %q+#D", new_decls);
+           permerror (input_location, "  enters scope of %q+#D which has "
+                      "non-trivial destructor", new_decls);
        }
 
       if (b == level)
@@ -2629,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 (input_location, "  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)
@@ -2797,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;
@@ -2808,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.  */
@@ -2820,7 +2852,7 @@ 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,
+  r = c_add_case_label (loc, switch_stack->cases, cond,
                        SWITCH_STMT_TYPE (switch_stack->switch_stmt),
                        low_value, high_value);
 
@@ -2917,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);
@@ -3115,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);
@@ -3152,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);
     }
@@ -3160,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);
@@ -3220,7 +3252,8 @@ 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;
@@ -3447,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 ();
@@ -3494,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));
@@ -3545,10 +3580,6 @@ builtin_function_1 (tree decl, tree context, bool is_global)
 
   retrofit_lang_decl (decl);
 
-  /* All nesting of C++ functions is lexical; there is never a "static
-     chain" in the sense of GNU C nested functions.  */
-  DECL_NO_STATIC_CHAIN (decl) = 1;
-
   DECL_ARTIFICIAL (decl) = 1;
   SET_OVERLOADED_OPERATOR_CODE (decl, ERROR_MARK);
   SET_DECL_LANGUAGE (decl, lang_c);
@@ -3780,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
@@ -3906,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;
@@ -4148,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
@@ -4186,6 +4224,9 @@ start_decl (const cp_declarator *declarator,
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
        permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
+
+      if (!ensure_literal_type_for_constexpr_object (decl))
+        return error_mark_node;
     }
 
   was_public = TREE_PUBLIC (decl);
@@ -4334,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");
 
@@ -4385,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);
 
@@ -4504,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);
     }
 }
 
@@ -4582,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)
        {
@@ -4614,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");
            }
        }
     }
@@ -4636,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)
@@ -4848,7 +4884,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
    a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
    iterator within the CONSTRUCTOR which points to the initializer to process.
    FIRST_INITIALIZER_P is true if this is the first initializer of the
-   CONSTRUCTOR node.  */
+   outermost CONSTRUCTOR node.  */
 
 static tree
 reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
@@ -4893,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;
@@ -5156,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;
@@ -5178,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
@@ -5533,7 +5574,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          TREE_TYPE (decl) = error_mark_node;
          return;
        }
-      else if (describable_type (init))
+      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)
@@ -5543,12 +5586,19 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (init && TREE_CODE (decl) == FUNCTION_DECL)
     {
+      tree clone;
       if (init == ridpointers[(int)RID_DELETE])
        {
          /* FIXME check this is 1st decl.  */
          DECL_DELETED_FN (decl) = 1;
          DECL_DECLARED_INLINE_P (decl) = 1;
          DECL_INITIAL (decl) = error_mark_node;
+         FOR_EACH_CLONE (clone, decl)
+           {
+             DECL_DELETED_FN (clone) = 1;
+             DECL_DECLARED_INLINE_P (clone) = 1;
+             DECL_INITIAL (clone) = error_mark_node;
+           }
          init = NULL_TREE;
        }
       else if (init == ridpointers[(int)RID_DEFAULT])
@@ -5559,7 +5609,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
              DECL_INITIAL (decl) = NULL_TREE;
            }
          else
-           DECL_DEFAULTED_FN (decl) = 1;
+           {
+             DECL_DEFAULTED_FN (decl) = 1;
+             FOR_EACH_CLONE (clone, decl)
+               DECL_DEFAULTED_FN (clone) = 1;
+           }
        }
     }
     
@@ -5658,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
@@ -5765,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))
@@ -5876,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;
@@ -5897,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;
@@ -5906,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;
@@ -6589,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:
@@ -6717,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 (input_location, "non-local function %q#D uses anonymous type",
-                             decl);
-                 if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-                   permerror (input_location, "%q+#D does not refer to the unqualified "
-                              "type, so it is not used for linkage",
-                              TYPE_NAME (t));
-               }
-           }
-         else
-           permerror (input_location, "non-local function %q#D uses local type %qT", decl, t);
-       }
-    }
-
   TREE_PUBLIC (decl) = publicp;
   if (! publicp)
     {
@@ -6772,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.  */
@@ -6951,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);
@@ -6991,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;
@@ -7062,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;
 
@@ -7078,10 +7081,14 @@ build_ptrmemfunc_type (tree type)
   /* If this is not the unqualified form of this pointer-to-member
      type, set the TYPE_MAIN_VARIANT for this type to be the
      unqualified type.  Since they are actually RECORD_TYPEs that are
-     not variants of each other, we must do this manually.  */
+     not variants of each other, we must do this manually.
+     As we just built a new type there is no need to do yet another copy.  */
   if (cp_type_quals (type) != TYPE_UNQUALIFIED)
     {
-      t = build_qualified_type (t, cp_type_quals (type));
+      int type_quals = cp_type_quals (type);
+      TYPE_READONLY (t) = (type_quals & TYPE_QUAL_CONST) != 0;
+      TYPE_VOLATILE (t) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
+      TYPE_RESTRICT (t) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
       TYPE_MAIN_VARIANT (t) = unqualified_variant;
       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
       TYPE_NEXT_VARIANT (unqualified_variant) = t;
@@ -7155,7 +7162,7 @@ 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))
+  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);
 
@@ -7178,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);
@@ -7605,8 +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];
@@ -7713,7 +7721,7 @@ grokdeclarator (const cp_declarator *declarator,
                  type = TREE_OPERAND (decl, 0);
                  if (TYPE_P (type))
                    type = constructor_name (type);
-                 name = IDENTIFIER_POINTER (type);
+                 name = identifier_to_locale (IDENTIFIER_POINTER (type));
                  dname = decl;
                }
                break;
@@ -7739,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);
@@ -7750,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>";
                  }
@@ -7847,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;
@@ -7855,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.  */
@@ -8050,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])
@@ -8121,6 +8140,14 @@ grokdeclarator (const cp_declarator *declarator,
          error ("parameter declared %<auto%>");
          type = error_mark_node;
        }
+
+      /* Function parameters cannot be constexpr.  If we saw one, moan
+         and pretend it wasn't there.  */
+      if (constexpr_p)
+        {
+          error ("a parameter cannot be declared %<constexpr%>");
+          constexpr_p = 0;
+        }
     }
 
   /* Give error if `virtual' is used outside of class declaration.  */
@@ -8284,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.  */
@@ -8414,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);
@@ -8659,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
@@ -8788,9 +8849,10 @@ 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);
+       decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
       if (id_declarator && declarator->u.id.qualifying_scope) {
-       error ("%Jtypedef name may not be a nested-name-specifier", decl);
+       error_at (DECL_SOURCE_LOCATION (decl), 
+                 "typedef name may not be a nested-name-specifier");
        TREE_TYPE (decl) = error_mark_node;
       }
 
@@ -8823,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;
@@ -8841,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.  */
        }
@@ -9117,6 +9187,8 @@ grokdeclarator (const cp_declarator *declarator,
                           uqname, ctype);
                    return error_mark_node;
                  }
+                if (constexpr_p)
+                  error ("a destructor cannot be %<constexpr%>");
              }
            else if (sfk == sfk_constructor && friendp)
              {
@@ -9137,7 +9209,8 @@ grokdeclarator (const cp_declarator *declarator,
                               parms,
                               unqualified_id,
                               virtualp, flags, memfn_quals, raises,
-                              friendp ? -1 : 0, friendp, publicp, inlinep,
+                              friendp ? -1 : 0, friendp, publicp,
+                               inlinep || constexpr_p,
                               sfk,
                               funcdef_flag, template_count, in_namespace,
                               attrlist, declarator->id_loc);
@@ -9229,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
@@ -9290,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;
@@ -9383,7 +9461,7 @@ grokdeclarator (const cp_declarator *declarator,
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, memfn_quals, raises,
                           1, friendp,
-                          publicp, inlinep, sfk, funcdef_flag,
+                          publicp, inlinep || constexpr_p, sfk, funcdef_flag,
                           template_count, in_namespace, attrlist,
                           declarator->id_loc);
        if (decl == NULL_TREE)
@@ -9480,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;
   }
 }
@@ -9666,6 +9745,7 @@ grokparms (tree parmlist, tree *parms)
       tree type = NULL_TREE;
       tree init = TREE_PURPOSE (parm);
       tree decl = TREE_VALUE (parm);
+      const char *errmsg;
 
       if (parm == void_list_node)
        break;
@@ -9699,13 +9779,21 @@ grokparms (tree parmlist, 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);
+               warn_deprecated_use (deptype, NULL_TREE);
            }
 
          /* Top-level qualifiers on the parameters are
@@ -9889,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)
 {
@@ -9915,7 +10007,7 @@ grok_special_member_properties (tree decl)
             are no other parameters or else all other parameters have
             default arguments.  */
          TYPE_HAS_INIT_REF (class_type) = 1;
-         if (!DECL_DEFAULTED_FN (decl))
+         if (!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;
@@ -9923,7 +10015,8 @@ grok_special_member_properties (tree decl)
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
        {
          TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
-         if (TREE_CODE (decl) == TEMPLATE_DECL || !DECL_DEFAULTED_FN (decl))
+         if (TREE_CODE (decl) == TEMPLATE_DECL
+             || !DECL_DEFAULTED_IN_CLASS_P (decl))
            TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
        }
       else if (is_list_ctor (decl))
@@ -9942,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;
@@ -10787,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);
@@ -10954,8 +11050,9 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
 
   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;
     }
@@ -10966,7 +11063,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
       if (enumtype == error_mark_node)
        name = make_anon_name ();
 
-      enumtype = make_node (ENUMERAL_TYPE);
+      enumtype = cxx_make_type (ENUMERAL_TYPE);
       enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
@@ -11001,7 +11098,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
           TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
           ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
         }
-      else
+      else if (!dependent_type_p (underlying_type))
         error ("underlying type %<%T%> of %<%T%> must be an integral type", 
                underlying_type, enumtype);
     }
@@ -11027,7 +11124,7 @@ finish_enum (tree enumtype)
   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;
@@ -11047,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;
     }
 
@@ -11155,7 +11254,8 @@ finish_enum (tree enumtype)
       /* Set the underlying type of the enumeration type to the
          computed enumeration type, restricted to the enumerator
          values. */
-      ENUM_UNDERLYING_TYPE (enumtype) = copy_node (underlying_type);
+      ENUM_UNDERLYING_TYPE (enumtype)
+       = build_distinct_type_copy (underlying_type);
       set_min_and_max_values_for_integral_type 
         (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
     }
@@ -11355,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.)  */
@@ -11406,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)
@@ -11582,7 +11686,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
     {
       tree resdecl;
 
-      resdecl = build_decl (RESULT_DECL, 0, restype);
+      resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
       DECL_ARTIFICIAL (resdecl) = 1;
       DECL_IGNORED_P (resdecl) = 1;
       DECL_RESULT (decl1) = resdecl;
@@ -11825,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;
     }
 
@@ -12007,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);
     }
 }
@@ -12055,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))
@@ -12093,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);
     }
 }
@@ -12352,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;
@@ -12362,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;
@@ -12430,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);
@@ -12483,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
@@ -12676,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;
     }
@@ -12733,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;
     }
 }
@@ -12754,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;
@@ -12784,7 +12825,7 @@ cxx_comdat_group (tree decl)
       name = DECL_ASSEMBLER_NAME (decl);
     }
 
-  return IDENTIFIER_POINTER (name);
+  return name;
 }
 
 #include "gt-cp-decl.h"