OSDN Git Service

Implement C++11 user-defined literals.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index ccc5fd0..5ba5008 100644 (file)
@@ -71,9 +71,10 @@ static void require_complete_types_for_parms (tree);
 static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
-static tree grok_reference_init (tree, tree, tree, tree *);
+static tree grok_reference_init (tree, tree, tree, tree *, int);
 static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
                         int, int, tree);
+static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
 static tree build_library_fn_1 (tree, enum tree_code, tree);
@@ -183,7 +184,7 @@ struct GTY((chain_next ("%h.next"))) named_label_use_entry {
   /* The binding level to which this entry is *currently* attached.
      This is initially the binding level in which the goto appeared,
      but is modified as scopes are closed.  */
-  struct cp_binding_level *binding_level;
+  cp_binding_level *binding_level;
   /* The head of the names list that was current when the goto appeared,
      or the inner scope popped.  These are the decls that will *not* be
      skipped when jumping to the label.  */
@@ -207,7 +208,7 @@ struct GTY(()) named_label_entry {
   /* The binding level to which the label is *currently* attached.
      This is initially set to the binding level in which the label
      is defined, but is modified as scopes are closed.  */
-  struct cp_binding_level *binding_level;
+  cp_binding_level *binding_level;
   /* The head of the names list that was current when the label was
      defined, or the inner scope popped.  These are the decls that will
      be skipped when jumping to the label.  */
@@ -269,7 +270,7 @@ current_tmpl_spec_kind (int n_class_scopes)
   int n_template_parm_scopes = 0;
   int seen_specialization_p = 0;
   int innermost_specialization_p = 0;
-  struct cp_binding_level *b;
+  cp_binding_level *b;
 
   /* Scan through the template parameter scopes.  */
   for (b = current_binding_level;
@@ -446,7 +447,7 @@ objc_get_current_scope (void)
 void
 objc_mark_locals_volatile (void *enclosing_blk)
 {
-  struct cp_binding_level *scope;
+  cp_binding_level *scope;
 
   for (scope = current_binding_level;
        scope && scope != enclosing_blk;
@@ -469,8 +470,8 @@ static int
 poplevel_named_label_1 (void **slot, void *data)
 {
   struct named_label_entry *ent = (struct named_label_entry *) *slot;
-  struct cp_binding_level *bl = (struct cp_binding_level *) data;
-  struct cp_binding_level *obl = bl->level_chain;
+  cp_binding_level *bl = (cp_binding_level *) data;
+  cp_binding_level *obl = bl->level_chain;
 
   if (ent->binding_level == bl)
     {
@@ -552,7 +553,7 @@ poplevel (int keep, int reverse, int functionbody)
   unsigned ix;
   cp_label_binding *label_bind;
 
-  timevar_push (TV_NAME_LOOKUP);
+  timevar_start (TV_NAME_LOOKUP);
  restart:
 
   block = NULL_TREE;
@@ -642,6 +643,9 @@ poplevel (int keep, int reverse, int functionbody)
   for (link = decls; link; link = TREE_CHAIN (link))
     {
       if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
+         /* It's hard to make this ARM compatibility hack play nicely with
+            lambdas, and it really isn't necessary in C++11 mode.  */
+         && cxx_dialect < cxx0x
          && DECL_NAME (link))
        {
          tree name = DECL_NAME (link);
@@ -815,7 +819,8 @@ poplevel (int keep, int reverse, int functionbody)
   if (kind == sk_cleanup)
     goto restart;
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
+  timevar_stop (TV_NAME_LOOKUP);
+  return block;
 }
 
 /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
@@ -851,7 +856,7 @@ walk_namespaces (walk_namespaces_fn f, void* data)
 int
 wrapup_globals_for_namespace (tree name_space, void* data)
 {
-  struct cp_binding_level *level = NAMESPACE_LEVEL (name_space);
+  cp_binding_level *level = NAMESPACE_LEVEL (name_space);
   VEC(tree,gc) *statics = level->static_decls;
   tree *vec = VEC_address (tree, statics);
   int len = VEC_length (tree, statics);
@@ -899,7 +904,7 @@ push_local_name (tree decl)
   size_t i, nelts;
   tree t, name;
 
-  timevar_push (TV_NAME_LOOKUP);
+  timevar_start (TV_NAME_LOOKUP);
 
   name = DECL_NAME (decl);
 
@@ -918,13 +923,13 @@ push_local_name (tree decl)
            DECL_DISCRIMINATOR (decl) = 1;
 
          VEC_replace (tree, local_names, i, decl);
-         timevar_pop (TV_NAME_LOOKUP);
+         timevar_stop (TV_NAME_LOOKUP);
          return;
        }
     }
 
   VEC_safe_push (tree, gc, local_names, decl);
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_stop (TV_NAME_LOOKUP);
 }
 \f
 /* Subroutine of duplicate_decls: return truthvalue of whether
@@ -1198,6 +1203,21 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       || TREE_TYPE (olddecl) == error_mark_node)
     return error_mark_node;
 
+  if (UDLIT_OPER_P (DECL_NAME (newdecl))
+      && UDLIT_OPER_P (DECL_NAME (olddecl)))
+    {
+      if (TREE_CODE (newdecl) == TEMPLATE_DECL
+         && TREE_CODE (olddecl) != TEMPLATE_DECL
+         && check_raw_literal_operator (olddecl))
+       error ("literal operator template %q+D conflicts with"
+              " raw literal operator %qD", newdecl, olddecl);
+      else if (TREE_CODE (newdecl) != TEMPLATE_DECL
+              && TREE_CODE (olddecl) == TEMPLATE_DECL
+              && check_raw_literal_operator (newdecl))
+       error ("raw literal operator %q+D conflicts with"
+              " literal operator template %qD", newdecl, olddecl);
+    }
+
   if (DECL_P (olddecl)
       && TREE_CODE (newdecl) == FUNCTION_DECL
       && TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1352,11 +1372,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
          && DECL_ANTICIPATED (olddecl)
          && TREE_NOTHROW (newdecl)
-         && !TREE_NOTHROW (olddecl)
-         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE
-         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl
-         && types_match)
-       TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1;
+         && !TREE_NOTHROW (olddecl))
+       {
+         enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl);
+         tree tmpdecl = builtin_decl_explicit (fncode);
+         if (tmpdecl && tmpdecl != olddecl && types_match)
+           TREE_NOTHROW (tmpdecl)  = 1;
+       }
 
       /* Whether or not the builtin can throw exceptions has no
         bearing on this declarator.  */
@@ -1535,8 +1557,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          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"
-                        : "%q+#D previously declared here", olddecl);
+                  ? G_("%q+#D previously defined here")
+                  : G_("%q+#D previously declared here"), olddecl);
          return error_mark_node;
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1687,6 +1709,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          error ("deleted definition of %qD", newdecl);
          error ("after previous declaration %q+D", olddecl);
        }
+      DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
     }
 
   /* Deal with C++: must preserve virtual function table size.  */
@@ -1781,6 +1804,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       tree oldtype = TREE_TYPE (olddecl);
       tree newtype;
 
+      if (TREE_CODE (newdecl) == FUNCTION_DECL)
+       maybe_instantiate_noexcept (olddecl);
+
       /* Merge the data types specified in the two decls.  */
       newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
 
@@ -2126,6 +2152,22 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
              /* If we're keeping the built-in definition, keep the rtl,
                 regardless of declaration matches.  */
              COPY_DECL_RTL (olddecl, newdecl);
+             if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+               {
+                 enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+                 switch (fncode)
+                   {
+                     /* If a compatible prototype of these builtin functions
+                        is seen, assume the runtime implements it with the
+                        expected semantics.  */
+                   case BUILT_IN_STPCPY:
+                     if (builtin_decl_explicit_p (fncode))
+                       set_builtin_decl_implicit_p (fncode, true);
+                     break;
+                   default:
+                     break;
+                   }
+               }
            }
 
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
@@ -2535,26 +2577,37 @@ make_label_decl (tree id, int local_p)
    be found, create one.  (We keep track of used, but undefined,
    labels, and complain about them at the end of a function.)  */
 
-tree
-lookup_label (tree id)
+static tree
+lookup_label_1 (tree id)
 {
   tree decl;
 
-  timevar_push (TV_NAME_LOOKUP);
   /* You can't use labels at global scope.  */
   if (current_function_decl == NULL_TREE)
     {
       error ("label %qE referenced outside of any function", id);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+      return NULL_TREE;
     }
 
   /* See if we've already got this label.  */
   decl = IDENTIFIER_LABEL_VALUE (id);
   if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+    return decl;
 
   decl = make_label_decl (id, /*local_p=*/0);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+  return decl;
+}
+
+/* Wrapper for lookup_label_1.  */
+
+tree
+lookup_label (tree id)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = lookup_label_1 (id);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Declare a local label named ID.  */
@@ -2627,10 +2680,10 @@ identify_goto (tree decl, const location_t *locus)
    true if all is well.  */
 
 static bool
-check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
+check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
                       bool exited_omp, const location_t *locus)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   bool identified = false, saw_eh = false, saw_omp = false;
 
   if (exited_omp)
@@ -2645,7 +2698,8 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
       tree new_decls, old_decls = (b == level ? names : NULL_TREE);
 
       for (new_decls = b->names; new_decls != old_decls;
-          new_decls = DECL_CHAIN (new_decls))
+          new_decls = (DECL_P (new_decls) ? DECL_CHAIN (new_decls)
+                       : TREE_CHAIN (new_decls)))
        {
          int problem = decl_jump_unsafe (new_decls);
          if (! problem)
@@ -2702,7 +2756,7 @@ check_previous_goto (tree decl, struct named_label_use_entry *use)
 }
 
 static bool
-check_switch_goto (struct cp_binding_level* level)
+check_switch_goto (cp_binding_level* level)
 {
   return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL);
 }
@@ -2788,7 +2842,7 @@ check_goto (tree decl)
     error ("  enters OpenMP structured block");
   else if (flag_openmp)
     {
-      struct cp_binding_level *b;
+      cp_binding_level *b;
       for (b = current_binding_level; b ; b = b->level_chain)
        {
          if (b == ent->binding_level)
@@ -2814,28 +2868,28 @@ check_goto (tree decl)
 bool
 check_omp_return (void)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   for (b = current_binding_level; b ; b = b->level_chain)
     if (b->kind == sk_omp)
       {
        error ("invalid exit from OpenMP structured block");
        return false;
       }
+    else if (b->kind == sk_function_parms)
+      break;
   return true;
 }
 
 /* Define a label, specifying the location in the source file.
    Return the LABEL_DECL node for the label.  */
 
-tree
-define_label (location_t location, tree name)
+static tree
+define_label_1 (location_t location, tree name)
 {
   struct named_label_entry *ent, dummy;
-  struct cp_binding_level *p;
+  cp_binding_level *p;
   tree decl;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   decl = lookup_label (name);
 
   dummy.label_decl = decl;
@@ -2855,7 +2909,7 @@ define_label (location_t location, tree name)
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
       error ("duplicate label %qD", decl);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+      return error_mark_node;
     }
   else
     {
@@ -2874,12 +2928,25 @@ define_label (location_t location, tree name)
       ent->uses = NULL;
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+  return decl;
 }
 
+/* Wrapper for define_label_1.  */
+
+tree
+define_label (location_t location, tree name)
+{
+  tree ret;
+  timevar_start (TV_NAME_LOOKUP);
+  ret = define_label_1 (location, name);
+  timevar_stop (TV_NAME_LOOKUP);
+  return ret;
+}
+
+
 struct cp_switch
 {
-  struct cp_binding_level *level;
+  cp_binding_level *level;
   struct cp_switch *next;
   /* The SWITCH_STMT being built.  */
   tree switch_stmt;
@@ -2931,6 +2998,28 @@ pop_switch (void)
   free (cs);
 }
 
+/* Convert a case constant VALUE in a switch to the type TYPE of the switch
+   condition.  Note that if TYPE and VALUE are already integral we don't
+   really do the conversion because the language-independent
+   warning/optimization code will work better that way.  */
+
+static tree
+case_conversion (tree type, tree value)
+{
+  if (value == NULL_TREE)
+    return value;
+
+  if (cxx_dialect >= cxx0x
+      && (SCOPED_ENUM_P (type)
+         || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
+    {
+      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+       type = type_promotes_to (type);
+      value = perform_implicit_conversion (type, value, tf_warning_or_error);
+    }
+  return cxx_constant_value (value);
+}
+
 /* Note that we've seen a definition of a case label, and complain if this
    is a bad place for one.  */
 
@@ -2938,7 +3027,8 @@ tree
 finish_case_label (location_t loc, tree low_value, tree high_value)
 {
   tree cond, r;
-  struct cp_binding_level *p;
+  cp_binding_level *p;
+  tree type;
 
   if (processing_template_decl)
     {
@@ -2947,7 +3037,7 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
       /* For templates, just add the case label; we'll do semantic
         analysis at instantiation-time.  */
       label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
-      return add_stmt (build_case_label (loc, low_value, high_value, label));
+      return add_stmt (build_case_label (low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -2958,13 +3048,12 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
   if (!check_switch_goto (switch_stack->level))
     return error_mark_node;
 
-  if (low_value)
-    low_value = cxx_constant_value (low_value);
-  if (high_value)
-    high_value = cxx_constant_value (high_value);
+  type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
+
+  low_value = case_conversion (type, low_value);
+  high_value = case_conversion (type, high_value);
 
-  r = c_add_case_label (loc, switch_stack->cases, cond,
-                       SWITCH_STMT_TYPE (switch_stack->switch_stmt),
+  r = c_add_case_label (loc, switch_stack->cases, cond, type,
                        low_value, high_value);
 
   /* After labels, make any new cleanups in the function go into their
@@ -3162,8 +3251,8 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (!t)
     {
       if (complain & tf_error)
-       error (want_template ? "no class template named %q#T in %q#T"
-              : "no type named %q#T in %q#T", name, context);
+       error (want_template ? G_("no class template named %q#T in %q#T")
+              : G_("no type named %q#T in %q#T"), name, context);
       return error_mark_node;
     }
   
@@ -3466,8 +3555,6 @@ cxx_init_decl_processing (void)
   tree void_ftype;
   tree void_ftype_ptr;
 
-  build_common_tree_nodes (flag_signed_char);
-
   /* Create all the identifiers we need.  */
   initialize_predefined_identifiers ();
 
@@ -3484,8 +3571,6 @@ cxx_init_decl_processing (void)
   TREE_PUBLIC (global_namespace) = 1;
   begin_scope (sk_namespace, global_namespace);
 
-  current_lang_name = NULL_TREE;
-
   if (flag_visibility_ms_compat)
     default_visibility = VISIBILITY_HIDDEN;
 
@@ -3549,6 +3634,10 @@ cxx_init_decl_processing (void)
   init_list_type_node = make_node (LANG_TYPE);
   record_unknown_type (init_list_type_node, "init list");
 
+  dependent_lambda_return_type_node = make_node (LANG_TYPE);
+  record_unknown_type (dependent_lambda_return_type_node,
+                      "undeduced lambda return type");
+
   {
     /* Make sure we get a unique function type, so we can give
        its pointer type a name.  (This wins for gdb.) */
@@ -3581,6 +3670,7 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
+    tree newattrs, extvisattr;
     tree newtype, deltype;
     tree ptr_ftype_sizetype;
     tree new_eh_spec;
@@ -3608,8 +3698,17 @@ cxx_init_decl_processing (void)
     else
       new_eh_spec = noexcept_false_spec;
 
-    newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
-    deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
+    /* Ensure attribs.c is initialized.  */
+    init_attributes ();
+    extvisattr = build_tree_list (get_identifier ("externally_visible"),
+                                 NULL_TREE);
+    newattrs = tree_cons (get_identifier ("alloc_size"),
+                         build_tree_list (NULL_TREE, integer_one_node),
+                         extvisattr);
+    newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
+    newtype = build_exception_variant (newtype, new_eh_spec);
+    deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
+    deltype = build_exception_variant (deltype, empty_except_spec);
     push_cp_library_fn (NEW_EXPR, newtype);
     push_cp_library_fn (VEC_NEW_EXPR, newtype);
     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
@@ -3620,7 +3719,7 @@ cxx_init_decl_processing (void)
     TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
     TYPE_UNSIGNED (nullptr_type_node) = 1;
     TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
-    SET_TYPE_MODE (nullptr_type_node, Pmode);
+    SET_TYPE_MODE (nullptr_type_node, ptr_mode);
     record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
     nullptr_node = build_int_cst (nullptr_type_node, 0);
   }
@@ -3710,7 +3809,7 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
 
   if (current_function_decl)
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       if (b->kind == sk_function_parms)
        return error_mark_node;
       while (b->level_chain->kind != sk_function_parms)
@@ -4512,7 +4611,8 @@ start_decl_1 (tree decl, bool initialized)
    Quotes on semantics can be found in ARM 8.4.3.  */
 
 static tree
-grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
+grok_reference_init (tree decl, tree type, tree init, tree *cleanup,
+                    int flags)
 {
   tree tmp;
 
@@ -4541,7 +4641,14 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
+  tmp = initialize_reference (type, init, decl, cleanup, flags,
+                             tf_warning_or_error);
+  if (DECL_DECLARED_CONSTEXPR_P (decl))
+    {
+      tmp = cxx_constant_value (tmp);
+      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+       = reduced_constant_expression_p (tmp);
+    }
 
   if (tmp == error_mark_node)
     return NULL_TREE;
@@ -4600,7 +4707,8 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *array_init,
    is valid, i.e., does not have a designated initializer.  */
 
 static bool
-check_array_designated_initializer (const constructor_elt *ce)
+check_array_designated_initializer (const constructor_elt *ce,
+                                   unsigned HOST_WIDE_INT index)
 {
   /* Designated initializers for array elements are not supported.  */
   if (ce->index)
@@ -4611,8 +4719,13 @@ check_array_designated_initializer (const constructor_elt *ce)
        error ("name used in a GNU-style designated "
               "initializer for an array");
       else if (TREE_CODE (ce->index) == INTEGER_CST)
-       /* An index added by reshape_init.  */
-       return true;
+       {
+         /* A C99 designator is OK if it matches the current index.  */
+         if (TREE_INT_CST_LOW (ce->index) == index)
+           return true;
+         else
+           sorry ("non-trivial designated initializers not supported");
+       }
       else
        {
          gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
@@ -4654,7 +4767,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          constructor_elt *ce;
          HOST_WIDE_INT i;
          FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
-           if (!check_array_designated_initializer (ce))
+           if (!check_array_designated_initializer (ce, i))
              failure = 1;
        }
 
@@ -4823,15 +4936,16 @@ check_for_uninitialized_const_var (tree decl)
   if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
-      && (!TYPE_NEEDS_CONSTRUCTING (type)
-         || !type_has_user_provided_default_constructor (type))
       && !DECL_INITIAL (decl))
     {
+      tree field = default_init_uninitialized_part (type);
+      if (!field)
+       return;
+
       permerror (DECL_SOURCE_LOCATION (decl),
                 "uninitialized const %qD", decl);
 
-      if (CLASS_TYPE_P (type)
-         && !type_has_user_provided_default_constructor (type))
+      if (CLASS_TYPE_P (type))
        {
          tree defaulted_ctor;
 
@@ -4842,6 +4956,8 @@ check_for_uninitialized_const_var (tree decl)
            inform (DECL_SOURCE_LOCATION (defaulted_ctor),
                    "constructor is not user-provided because it is "
                    "explicitly defaulted in the class body");
+         inform (0, "and the implicitly-defined constructor does not "
+                 "initialize %q+#D", field);
        }
     }
 }
@@ -4855,7 +4971,7 @@ typedef struct reshape_iterator_t
   constructor_elt *end;
 } reshape_iter;
 
-static tree reshape_init_r (tree, reshape_iter *, bool);
+static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);
 
 /* FIELD is a FIELD_DECL or NULL.  In the former case, the value
    returned is the next FIELD_DECL (possibly FIELD itself) that can be
@@ -4881,7 +4997,8 @@ next_initializable_field (tree field)
    the iterator within the constructor.  */
 
 static tree
-reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
+reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
+                     tsubst_flags_t complain)
 {
   tree new_init;
   bool sized_array_p = (max_index != NULL_TREE);
@@ -4912,8 +5029,9 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
     {
       tree elt_init;
 
-      check_array_designated_initializer (d->cur);
-      elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+      check_array_designated_initializer (d->cur, index);
+      elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
+                                complain);
       if (elt_init == error_mark_node)
        return error_mark_node;
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
@@ -4929,7 +5047,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
    Parameters are the same of reshape_init_r.  */
 
 static tree
-reshape_init_array (tree type, reshape_iter *d)
+reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
 {
   tree max_index = NULL_TREE;
 
@@ -4938,14 +5056,14 @@ reshape_init_array (tree type, reshape_iter *d)
   if (TYPE_DOMAIN (type))
     max_index = array_type_nelts (type);
 
-  return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
+  return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
 }
 
 /* Subroutine of reshape_init_r, processes the initializers for vectors.
    Parameters are the same of reshape_init_r.  */
 
 static tree
-reshape_init_vector (tree type, reshape_iter *d)
+reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain)
 {
   tree max_index = NULL_TREE;
 
@@ -4956,8 +5074,9 @@ reshape_init_vector (tree type, reshape_iter *d)
       tree value = d->cur->value;
       if (!same_type_p (TREE_TYPE (value), type))
        {
-         error ("invalid type %qT as initializer for a vector of type %qT",
-               TREE_TYPE (d->cur->value), type);
+         if (complain & tf_error)
+           error ("invalid type %qT as initializer for a vector of type %qT",
+                  TREE_TYPE (d->cur->value), type);
          value = error_mark_node;
        }
       ++d->cur;
@@ -4968,14 +5087,15 @@ reshape_init_vector (tree type, reshape_iter *d)
   if (TREE_CODE (type) == VECTOR_TYPE)
     max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);
 
-  return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
+  return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
 }
 
 /* Subroutine of reshape_init_r, processes the initializers for classes
    or union. Parameters are the same of reshape_init_r.  */
 
 static tree
-reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
+reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
+                   tsubst_flags_t complain)
 {
   tree field;
   tree new_init;
@@ -4995,7 +5115,8 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
        initializer-list {}.  */
       if (!first_initializer_p)
        {
-         error ("initializer for %qT must be brace-enclosed", type);
+         if (complain & tf_error)
+           error ("initializer for %qT must be brace-enclosed", type);
          return error_mark_node;
        }
       return new_init;
@@ -5013,8 +5134,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
 
          if (!field || TREE_CODE (field) != FIELD_DECL)
            {
-             error ("%qT has no non-static data member named %qD", type,
-                   d->cur->index);
+             if (complain & tf_error)
+               error ("%qT has no non-static data member named %qD", type,
+                      d->cur->index);
              return error_mark_node;
            }
        }
@@ -5024,7 +5146,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
        break;
 
       field_init = reshape_init_r (TREE_TYPE (field), d,
-                                  /*first_initializer_p=*/false);
+                                  /*first_initializer_p=*/false, complain);
       if (field_init == error_mark_node)
        return error_mark_node;
 
@@ -5051,13 +5173,40 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
    outermost CONSTRUCTOR node.  */
 
 static tree
-reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
+reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
+               tsubst_flags_t complain)
 {
   tree init = d->cur->value;
 
   if (error_operand_p (init))
     return error_mark_node;
 
+  if (TREE_CODE (type) == COMPLEX_TYPE)
+    {
+      /* A complex type can be initialized from one or two initializers,
+        but braces are not elided.  */
+      d->cur++;
+      if (BRACE_ENCLOSED_INITIALIZER_P (init))
+       {
+         if (CONSTRUCTOR_NELTS (init) > 2)
+           {
+             if (complain & tf_error)
+               error ("too many initializers for %qT", type);
+             else
+               return error_mark_node;
+           }
+       }
+      else if (first_initializer_p && d->cur != d->end)
+       {
+         VEC(constructor_elt, gc) *v = 0;
+         CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
+         CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value);
+         d->cur++;
+         init = build_constructor (init_list_type_node, v);
+       }
+      return init;
+    }
+
   /* A non-aggregate type is always initialized with a single
      initializer.  */
   if (!CP_AGGREGATE_TYPE_P (type))
@@ -5072,7 +5221,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
        {
          if (SCALAR_TYPE_P (type))
            {
-             error ("braces around scalar initializer for type %qT", type);
+             if (complain & tf_error)
+               error ("braces around scalar initializer for type %qT", type);
              init = error_mark_node;
            }
          else
@@ -5159,7 +5309,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
            {
              ++d->cur;
              gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
-             return reshape_init (type, init);
+             return reshape_init (type, init, complain);
            }
        }
 
@@ -5169,11 +5319,11 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
 
   /* Dispatch to specialized routines.  */
   if (CLASS_TYPE_P (type))
-    return reshape_init_class (type, d, first_initializer_p);
+    return reshape_init_class (type, d, first_initializer_p, complain);
   else if (TREE_CODE (type) == ARRAY_TYPE)
-    return reshape_init_array (type, d);
+    return reshape_init_array (type, d, complain);
   else if (TREE_CODE (type) == VECTOR_TYPE)
-    return reshape_init_vector (type, d);
+    return reshape_init_vector (type, d, complain);
   else
     gcc_unreachable();
 }
@@ -5194,7 +5344,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
    revised CONSTRUCTOR node is returned.  */
 
 tree
-reshape_init (tree type, tree init)
+reshape_init (tree type, tree init, tsubst_flags_t complain)
 {
   VEC(constructor_elt, gc) *v;
   reshape_iter d;
@@ -5213,14 +5363,19 @@ reshape_init (tree type, tree init)
   d.cur = VEC_index (constructor_elt, v, 0);
   d.end = d.cur + VEC_length (constructor_elt, v);
 
-  new_init = reshape_init_r (type, &d, true);
+  new_init = reshape_init_r (type, &d, true, complain);
   if (new_init == error_mark_node)
     return error_mark_node;
 
   /* Make sure all the element of the constructor were used. Otherwise,
      issue an error about exceeding initializers.  */
   if (d.cur != d.end)
-    error ("too many initializers for %qT", type);
+    {
+      if (complain & tf_error)
+       error ("too many initializers for %qT", type);
+      else
+       return error_mark_node;
+    }
 
   return new_init;
 }
@@ -5265,13 +5420,13 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags)
      
 {
   int saved_stmts_are_full_exprs_p = 0;
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     {
       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
     }
   init = build_aggr_init (decl, init, flags, tf_warning_or_error);
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     current_stmt_tree ()->stmts_are_full_exprs_p =
       saved_stmts_are_full_exprs_p;
   return init;
@@ -5296,6 +5451,14 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
      type.  */
   TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));
 
+  if (DECL_HAS_VALUE_EXPR_P (decl))
+    {
+      /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder,
+        it doesn't have storage to be initialized.  */
+      gcc_assert (init == NULL_TREE);
+      return NULL_TREE;
+    }
+
   if (type == error_mark_node)
     /* We will have already complained.  */
     return NULL_TREE;
@@ -5325,7 +5488,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
              maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
              init = build_zero_init (type, NULL_TREE, false);
            }
-         else if (init_len != 1)
+         else if (init_len != 1 && TREE_CODE (type) != COMPLEX_TYPE)
            {
              error ("scalar object %qD requires one element in initializer",
                     decl);
@@ -5347,8 +5510,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
   else if (!init && DECL_REALLY_EXTERN (decl))
     ;
   else if (TREE_CODE (type) == REFERENCE_TYPE)
-    init = grok_reference_init (decl, type, init, cleanup);
-  else if (init || TYPE_NEEDS_CONSTRUCTING (type))
+    init = grok_reference_init (decl, type, init, cleanup, flags);
+  else if (init || type_build_ctor_call (type))
     {
       if (!init)
        check_for_uninitialized_const_var (decl);
@@ -5373,7 +5536,11 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
              init = error_mark_node;
            }
          else
-           init = reshape_init (type, init);       
+           {
+             init = reshape_init (type, init, tf_warning_or_error);
+             if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type))
+               check_narrowing (type, init);
+           }
        }
 
       /* If DECL has an array type without a specific bound, deduce the
@@ -5383,7 +5550,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
       if (type == error_mark_node)
        return NULL_TREE;
 
-      if (TYPE_NEEDS_CONSTRUCTING (type)
+      if (type_build_ctor_call (type)
          || (CLASS_TYPE_P (type)
              && !(init && BRACE_ENCLOSED_INITIALIZER_P (init))))
        {
@@ -5566,7 +5733,9 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 static tree
 wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
 {
-  if (TYPE_P (*stmt_p))
+  /* Stop at types or full-expression boundaries.  */
+  if (TYPE_P (*stmt_p)
+      || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR)
     {
       *walk_subtrees = 0;
       return NULL_TREE;
@@ -5645,21 +5814,32 @@ initialize_local_var (tree decl, tree init)
   /* Perform the initialization.  */
   if (init)
     {
-      int saved_stmts_are_full_exprs_p;
+      if (TREE_CODE (init) == INIT_EXPR
+         && !TREE_SIDE_EFFECTS (TREE_OPERAND (init, 1)))
+       {
+         /* Stick simple initializers in DECL_INITIAL so that
+            -Wno-init-self works (c++/34772).  */
+         gcc_assert (TREE_OPERAND (init, 0) == decl);
+         DECL_INITIAL (decl) = TREE_OPERAND (init, 1);
+       }
+      else
+       {
+         int saved_stmts_are_full_exprs_p;
 
-      /* If we're only initializing a single object, guard the destructors
-        of any temporaries used in its initializer with its destructor.
-        This isn't right for arrays because each element initialization is
-        a full-expression.  */
-      if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
-       wrap_temporary_cleanups (init, cleanup);
+         /* If we're only initializing a single object, guard the
+            destructors of any temporaries used in its initializer with
+            its destructor.  This isn't right for arrays because each
+            element initialization is a full-expression.  */
+         if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
+           wrap_temporary_cleanups (init, cleanup);
 
-      gcc_assert (building_stmt_tree ());
-      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-      current_stmt_tree ()->stmts_are_full_exprs_p = 1;
-      finish_expr_stmt (init);
-      current_stmt_tree ()->stmts_are_full_exprs_p =
-       saved_stmts_are_full_exprs_p;
+         gcc_assert (building_stmt_list_p ());
+         saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+         current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+         finish_expr_stmt (init);
+         current_stmt_tree ()->stmts_are_full_exprs_p =
+           saved_stmts_are_full_exprs_p;
+       }
     }
 
   /* Set this to 0 so we can tell whether an aggregate which was
@@ -5803,7 +5983,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   cleanup = NULL_TREE;
 
   /* If a name was specified, get the string.  */
-  if (global_scope_p (current_binding_level))
+  if (at_namespace_scope_p ())
     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
   if (asmspec_tree && asmspec_tree != error_mark_node)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
@@ -5811,6 +5991,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (current_class_type
       && CP_DECL_CONTEXT (decl) == current_class_type
       && TYPE_BEING_DEFINED (current_class_type)
+      && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
@@ -5829,24 +6010,20 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
                                                  tf_warning_or_error);
       d_init = resolve_nondeduced_context (d_init);
-      if (describable_type (d_init))
-       {
-         type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
-                                                      auto_node);
-         if (type == error_mark_node)
-           return;
-       }
+      type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+                                                  auto_node);
+      if (type == error_mark_node)
+       return;
     }
 
-  if (TREE_CODE (decl) == FUNCTION_DECL
-      /* For members, defer until finalize_literal_type_property.  */
-      && (!DECL_CLASS_SCOPE_P (decl)
-         || !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))))
-    validate_constexpr_fundecl (decl);
-
-  else if (!ensure_literal_type_for_constexpr_object (decl))
+  if (!ensure_literal_type_for_constexpr_object (decl))
     DECL_DECLARED_CONSTEXPR_P (decl) = 0;
 
+  if (TREE_CODE (decl) == VAR_DECL
+      && DECL_CLASS_SCOPE_P (decl)
+      && DECL_INITIALIZED_IN_CLASS_P (decl))
+    check_static_variable_definition (decl, type);
+
   if (init && TREE_CODE (decl) == FUNCTION_DECL)
     {
       tree clone;
@@ -5876,6 +6053,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (init && TREE_CODE (decl) == VAR_DECL)
     {
       DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+      /* If DECL is a reference, then we want to know whether init is a
+        reference constant; init_const_expr_p as passed tells us whether
+        it's an rvalue constant.  */
+      if (TREE_CODE (type) == REFERENCE_TYPE)
+       init_const_expr_p = potential_constant_expression (init);
       if (init_const_expr_p)
        {
          /* Set these flags now for templates.  We'll update the flags in
@@ -5932,6 +6114,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       return;
     }
 
+  /* Just store non-static data member initializers for later.  */
+  if (init && TREE_CODE (decl) == FIELD_DECL)
+    DECL_INITIAL (decl) = init;
+
   /* Take care of TYPE_DECLs up front.  */
   if (TREE_CODE (decl) == TYPE_DECL)
     {
@@ -6091,7 +6277,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   /* Add this declaration to the statement-tree.  This needs to happen
      after the call to check_initializer so that the DECL_EXPR for a
      reference temp is added before the DECL_EXPR for the reference itself.  */
-  if (at_function_scope_p ())
+  if (DECL_FUNCTION_SCOPE_P (decl))
     add_decl_expr (decl);
 
   /* Let the middle end know about variables and functions -- but not
@@ -6186,6 +6372,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
   if (was_readonly)
     TREE_READONLY (decl) = 1;
+
+  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -6333,6 +6521,11 @@ get_dso_handle_node (void)
   dso_handle_node = declare_global_var (get_identifier ("__dso_handle"),
                                        ptr_type_node);
 
+#ifdef HAVE_GAS_HIDDEN
+  DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1;
+#endif
+
   return dso_handle_node;
 }
 
@@ -6529,7 +6722,6 @@ expand_static_init (tree decl, tree init)
       tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
       tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
       tree guard, guard_addr;
-      tree acquire_fn, release_fn, abort_fn;
       tree flag, begin;
 
       /* Emit code to perform this initialization but once.  This code
@@ -6579,29 +6771,31 @@ expand_static_init (tree decl, tree init)
 
       if (flag_threadsafe_statics)
        {
+         tree vfntype = NULL_TREE;
+         tree acquire_name, release_name, abort_name;
+         tree acquire_fn, release_fn, abort_fn;
          guard_addr = build_address (guard);
 
-         acquire_fn = get_identifier ("__cxa_guard_acquire");
-         release_fn = get_identifier ("__cxa_guard_release");
-         abort_fn = get_identifier ("__cxa_guard_abort");
-         if (!get_global_value_if_present (acquire_fn, &acquire_fn))
-           {
-             tree vfntype = build_function_type_list (void_type_node,
-                                                      TREE_TYPE (guard_addr),
-                                                      NULL_TREE);
-             acquire_fn = push_library_fn
-               (acquire_fn, build_function_type_list (integer_type_node,
+         acquire_name = get_identifier ("__cxa_guard_acquire");
+         release_name = get_identifier ("__cxa_guard_release");
+         abort_name = get_identifier ("__cxa_guard_abort");
+         acquire_fn = identifier_global_value (acquire_name);
+         release_fn = identifier_global_value (release_name);
+         abort_fn = identifier_global_value (abort_name);
+         if (!acquire_fn)
+           acquire_fn = push_library_fn
+             (acquire_name, build_function_type_list (integer_type_node,
                                                       TREE_TYPE (guard_addr),
                                                       NULL_TREE),
-                NULL_TREE);
-             release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
-             abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
-           }
-         else
-           {
-             release_fn = identifier_global_value (release_fn);
-             abort_fn = identifier_global_value (abort_fn);
-           }
+              NULL_TREE);
+         if (!release_fn || !abort_fn)
+           vfntype = build_function_type_list (void_type_node,
+                                               TREE_TYPE (guard_addr),
+                                               NULL_TREE);
+         if (!release_fn)
+           release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+         if (!abort_fn)
+           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
 
          inner_if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
@@ -6880,7 +7074,14 @@ build_this_parm (tree type, cp_cv_quals quals)
   tree parm;
   cp_cv_quals this_quals;
 
-  this_type = TREE_VALUE (TYPE_ARG_TYPES (type));
+  if (CLASS_TYPE_P (type))
+    {
+      this_type
+       = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
+      this_type = build_pointer_type (this_type);
+    }
+  else
+    this_type = type_of_this_parm (type);
   /* The `this' parameter is implicitly `const'; it cannot be
      assigned to.  */
   this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
@@ -6890,6 +7091,17 @@ build_this_parm (tree type, cp_cv_quals quals)
   return parm;
 }
 
+/* DECL is a static member function.  Complain if it was declared
+   with function-cv-quals.  */
+
+static void
+check_static_quals (tree decl, cp_cv_quals quals)
+{
+  if (quals != TYPE_UNQUALIFIED)
+    error ("static member function %q#D declared with type qualifiers",
+          decl);
+}
+
 /* CTYPE is class type, or null if non-class.
    TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
    or METHOD_TYPE.
@@ -7148,6 +7360,47 @@ grokfndecl (tree ctype,
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
       && !grok_op_properties (decl, /*complain=*/true))
     return NULL_TREE;
+  else if (UDLIT_OPER_P (DECL_NAME (decl)))
+    {
+      bool long_long_unsigned_p;
+      bool long_double_p;
+      const char *suffix = NULL;
+      /* [over.literal]/6: Literal operators shall not have C linkage. */
+      if (DECL_LANGUAGE (decl) == lang_c)
+       {
+         error ("literal operator with C linkage");
+         return NULL_TREE;
+       }
+
+      if (DECL_NAMESPACE_SCOPE_P (decl))
+       {
+         if (!check_literal_operator_args (decl, &long_long_unsigned_p,
+                                           &long_double_p))
+           {
+             error ("%qD has invalid argument list", decl);
+             return NULL_TREE;
+           }
+
+         suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
+         if (long_long_unsigned_p)
+           {
+             if (cpp_interpret_int_suffix (suffix, strlen (suffix)))
+               warning (0, "integer suffix %<%s%>"
+                           " shadowed by implementation", suffix);
+           }
+         else if (long_double_p)
+           {
+             if (cpp_interpret_float_suffix (suffix, strlen (suffix)))
+               warning (0, "floating point suffix %<%s%>"
+                           " shadowed by implementation", suffix);
+           }
+       }
+      else
+       {
+         error ("%qD must be a non-member function", decl);
+         return NULL_TREE;
+       }
+    }
 
   if (funcdef_flag)
     /* Make the init_value nonzero so pushdecl knows this is not
@@ -7171,6 +7424,9 @@ grokfndecl (tree ctype,
   if (decl == error_mark_node)
     return NULL_TREE;
 
+  if (DECL_STATIC_FUNCTION_P (decl))
+    check_static_quals (decl, quals);
+
   if (attrlist)
     {
       cplus_decl_attributes (&decl, *attrlist, 0);
@@ -7220,14 +7476,22 @@ grokfndecl (tree ctype,
 
          if (DECL_STATIC_FUNCTION_P (old_decl)
              && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
-           /* Remove the `this' parm added by grokclassfn.
-              XXX Isn't this done in start_function, too?  */
-           revert_static_member_fn (decl);
+           {
+             /* Remove the `this' parm added by grokclassfn.  */
+             revert_static_member_fn (decl);
+             check_static_quals (decl, quals);
+           }
          if (DECL_ARTIFICIAL (old_decl))
            {
              error ("definition of implicitly-declared %qD", old_decl);
              return NULL_TREE;
            }
+         else if (DECL_DEFAULTED_FN (old_decl))
+           {
+             error ("definition of explicitly-defaulted %q+D", decl);
+             error ("%q+#D explicitly defaulted here", old_decl);
+             return NULL_TREE;
+           }
 
          /* Since we've smashed OLD_DECL to its
             DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
@@ -7262,6 +7526,25 @@ grokfndecl (tree ctype,
   return decl;
 }
 
+/* decl is a FUNCTION_DECL.
+   specifiers are the parsed virt-specifiers.
+
+   Set flags to reflect the virt-specifiers.
+
+   Returns decl.  */
+
+static tree
+set_virt_specifiers (tree decl, cp_virt_specifiers specifiers)
+{
+  if (decl == NULL_TREE)
+    return decl;
+  if (specifiers & VIRT_SPEC_OVERRIDE)
+    DECL_OVERRIDE_P (decl) = 1;
+  if (specifiers & VIRT_SPEC_FINAL)
+    DECL_FINAL_P (decl) = 1;
+  return decl;
+}
+
 /* DECL is a VAR_DECL for a static data member.  Set flags to reflect
    the linkage that DECL will receive in the object file.  */
 
@@ -7513,9 +7796,12 @@ build_ptrmem_type (tree class_type, tree member_type)
    messages.  Return 1 if the definition is particularly bad, or 0
    otherwise.  */
 
-int
+static int
 check_static_variable_definition (tree decl, tree type)
 {
+  /* Can't check yet if we don't know the type.  */
+  if (dependent_type_p (type))
+    return 0;
   /* If DECL is declared constexpr, we'll do the appropriate checks
      in check_initializer.  */
   if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
@@ -7523,8 +7809,9 @@ check_static_variable_definition (tree decl, tree type)
   else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       if (literal_type_p (type))
-       error ("%<constexpr%> needed for in-class initialization of static "
-              "data member %q#D of non-integral type", decl);
+       permerror (input_location,
+                  "%<constexpr%> needed for in-class initialization of "
+                  "static data member %q#D of non-integral type", decl);
       else
        error ("in-class initialization of static data member %q#D of "
               "non-literal type", decl);
@@ -7555,6 +7842,39 @@ check_static_variable_definition (tree decl, tree type)
   return 0;
 }
 
+/* *expr_p is part of the TYPE_SIZE of a variably-sized array.  If any
+   SAVE_EXPRs in *expr_p wrap expressions with side-effects, break those
+   expressions out into temporary variables so that walk_tree doesn't
+   step into them (c++/15764).  */
+
+static tree
+stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+  struct pointer_set_t *pset = (struct pointer_set_t *)data;
+  tree expr = *expr_p;
+  if (TREE_CODE (expr) == SAVE_EXPR)
+    {
+      tree op = TREE_OPERAND (expr, 0);
+      cp_walk_tree (&op, stabilize_save_expr_r, data, pset);
+      if (TREE_SIDE_EFFECTS (op))
+       TREE_OPERAND (expr, 0) = get_temp_regvar (TREE_TYPE (op), op);
+      *walk_subtrees = 0;
+    }
+  else if (!EXPR_P (expr) || !TREE_SIDE_EFFECTS (expr))
+    *walk_subtrees = 0;
+  return NULL;
+}
+
+/* Entry point for the above.  */
+
+static void
+stabilize_vla_size (tree size)
+{
+  struct pointer_set_t *pset = pointer_set_create ();
+  /* Break out any function calls into temporary variables.  */
+  cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
+}
+
 /* Given the SIZE (i.e., number of elements) in an array, compute an
    appropriate index type for the array.  If non-NULL, NAME is the
    name of the thing being declared.  */
@@ -7588,6 +7908,17 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
              && CLASSTYPE_LITERAL_P (type))
            {
              size = build_expr_type_conversion (WANT_INT, size, true);
+             if (!size)
+               {
+                 if (!(complain & tf_error))
+                   return error_mark_node;
+                 if (name)
+                   error ("size of array %qD has non-integral type %qT",
+                          name, type);
+                 else
+                   error ("size of array has non-integral type %qT", type);
+                 size = integer_one_node;
+               }
              if (size == error_mark_node)
                return error_mark_node;
              type = TREE_TYPE (size);
@@ -7737,16 +8068,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       processing_template_decl = saved_processing_template_decl;
 
       if (!TREE_CONSTANT (itype))
-       {
-         /* A variable sized array.  */
-         if (TREE_SIDE_EFFECTS (itype))
-           /* Use get_temp_regvar rather than variable_size here so that
-              people walking expressions that use a variable of this type
-              don't walk into this expression.  */
-           itype = get_temp_regvar (TREE_TYPE (itype), itype);
-         else
-           itype = variable_size (itype);
-       }
+       /* A variable sized array.  */
+       itype = variable_size (itype);
       /* Make sure that there was no overflow when creating to a signed
         index type.  (For example, on a 32-bit machine, an array with
         size 2^32 - 1 is too big.)  */
@@ -7811,6 +8134,12 @@ create_array_type_for_decl (tree name, tree type, tree size)
   if (type == error_mark_node || size == error_mark_node)
     return error_mark_node;
 
+  /* 8.3.4/1: If the type of the identifier of D contains the auto
+     type-specifier, the program is ill-formed.  */
+  if (pedantic && type_uses_auto (type))
+    pedwarn (input_location, OPT_pedantic,
+            "declaration of %qD as array of %<auto%>", name);
+
   /* If there are some types which cannot be array elements,
      issue an error-message and return.  */
   switch (TREE_CODE (type))
@@ -8036,6 +8365,9 @@ grokdeclarator (const cp_declarator *declarator,
   /* cv-qualifiers that apply to the declarator, for a declaration of
      a member function.  */
   cp_cv_quals memfn_quals = TYPE_UNQUALIFIED;
+  /* virt-specifiers that apply to the declarator, for a declaration of
+     a member function.  */
+  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
   int type_quals;
   tree raises = NULL_TREE;
@@ -8139,10 +8471,15 @@ grokdeclarator (const cp_declarator *declarator,
                else if (TYPE_P (qualifying_scope))
                  {
                    ctype = qualifying_scope;
-                   if (innermost_code != cdk_function
-                       && current_class_type
-                       && !UNIQUELY_DERIVED_FROM_P (ctype,
-                                                    current_class_type))
+                   if (!MAYBE_CLASS_TYPE_P (ctype))
+                     {
+                       error ("%q#T is not a class or a namespace", ctype);
+                       ctype = NULL_TREE;
+                     }
+                   else if (innermost_code != cdk_function
+                            && current_class_type
+                            && !UNIQUELY_DERIVED_FROM_P (ctype,
+                                                         current_class_type))
                      {
                        error ("type %qT is not derived from type %qT",
                               ctype, current_class_type);
@@ -8255,6 +8592,29 @@ grokdeclarator (const cp_declarator *declarator,
       error ("declaration of %qD as non-function", dname);
       return error_mark_node;
     }
+  if (dname
+      && TREE_CODE (dname) == IDENTIFIER_NODE
+      && UDLIT_OPER_P (dname)
+      && innermost_code != cdk_function)
+    {
+      error ("declaration of %qD as non-function", dname);
+      return error_mark_node;
+    }
+
+  if (dname && IDENTIFIER_OPNAME_P (dname))
+    {
+      if (declspecs->specs[(int)ds_typedef])
+       {
+         error ("declaration of %qD as %<typedef%>", dname);
+         return error_mark_node;
+       }
+      else if (decl_context == PARM || decl_context == CATCHPARM)
+       {
+         error ("declaration of %qD as parameter", dname);
+         return error_mark_node;
+       }
+    }
 
   /* Anything declared one level down from the top level
      must be one of the parameters of a function
@@ -8272,7 +8632,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (decl_context == NORMAL && !toplevel_bindings_p ())
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       current_binding_level = b->level_chain;
       if (current_binding_level != 0 && toplevel_bindings_p ())
        decl_context = PARM;
@@ -8383,6 +8743,18 @@ grokdeclarator (const cp_declarator *declarator,
 
   ctype = NULL_TREE;
 
+  if (explicit_int128)
+    {
+      if (int128_integer_type_node == NULL_TREE)
+       {
+         error ("%<__int128%> is not supported by this target");
+         explicit_int128 = false;
+       }
+      else if (pedantic && ! in_system_header)
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C++ does not support %<__int128%> for %qs", name);
+    }
+
   /* Now process the modifiers that were specified
      and check for invalid combinations.  */
 
@@ -8406,8 +8778,6 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<signed%> and %<unsigned%> specified together for %qs", name);
       else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long long%> invalid for %qs", name);
-      else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE)
-       error ("%<__int128%> invalid for %qs", name);
       else if (long_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<long%> invalid for %qs", name);
       else if (short_p && TREE_CODE (type) == REAL_TYPE)
@@ -8438,22 +8808,6 @@ grokdeclarator (const cp_declarator *declarator,
              if (flag_pedantic_errors)
                ok = 0;
            }
-         if (explicit_int128)
-           {
-             if (int128_integer_type_node == NULL_TREE)
-               {
-                 error ("%<__int128%> is not supported by this target");
-                 ok = 0;
-               }
-             else if (pedantic)
-               {
-                 pedwarn (input_location, OPT_pedantic,
-                          "ISO C++ does not support %<__int128%> for %qs",
-                          name);
-                 if (flag_pedantic_errors)
-                   ok = 0;
-               }
-           }
        }
 
       /* Discard the type modifiers if they are invalid.  */
@@ -8464,7 +8818,6 @@ grokdeclarator (const cp_declarator *declarator,
          long_p = false;
          short_p = false;
          longlong = 0;
-         explicit_int128 = false;
        }
     }
 
@@ -8597,12 +8950,6 @@ grokdeclarator (const cp_declarator *declarator,
               || 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)
@@ -8796,9 +9143,14 @@ grokdeclarator (const cp_declarator *declarator,
 
            /* Pick up type qualifiers which should be applied to `this'.  */
            memfn_quals = declarator->u.function.qualifiers;
-
+           /* Pick up virt-specifiers.  */
+            virt_specifiers = declarator->u.function.virt_specifiers;
            /* Pick up the exception specifications.  */
            raises = declarator->u.function.exception_specification;
+           /* If the exception-specification is ill-formed, let's pretend
+              there wasn't one.  */
+           if (raises == error_mark_node)
+             raises = NULL_TREE;
 
            /* Say it's a definition only for the CALL_EXPR
               closest to the identifier.  */
@@ -8858,13 +9210,13 @@ grokdeclarator (const cp_declarator *declarator,
                   virtual.  A constructor may not be static.  */
                if (staticp == 2)
                  error ((flags == DTOR_FLAG)
-                        ? "destructor cannot be static member function"
-                        : "constructor cannot be static member function");
+                        ? G_("destructor cannot be static member function")
+                        : G_("constructor cannot be static member function"));
                if (memfn_quals)
                  {
                    error ((flags == DTOR_FLAG)
-                          ? "destructors may not be cv-qualified"
-                          : "constructors may not be cv-qualified");
+                          ? G_("destructors may not be cv-qualified")
+                          : G_("constructors may not be cv-qualified"));
                    memfn_quals = TYPE_UNQUALIFIED;
                  }
 
@@ -9019,7 +9371,12 @@ grokdeclarator (const cp_declarator *declarator,
              && (decl_context == NORMAL || decl_context == FIELD)
              && at_function_scope_p ()
              && variably_modified_type_p (type, NULL_TREE))
-           finish_expr_stmt (TYPE_SIZE (type));
+           {
+             /* First break out any side-effects.  */
+             stabilize_vla_size (TYPE_SIZE (type));
+             /* And then force evaluation of the SAVE_EXPR.  */
+             finish_expr_stmt (TYPE_SIZE (type));
+           }
 
          if (declarator->kind == cdk_reference)
            {
@@ -9034,13 +9391,18 @@ grokdeclarator (const cp_declarator *declarator,
                 to create the type "rvalue reference to cv TD' creates the
                 type TD."
               */
-             if (!VOID_TYPE_P (type))
+             if (VOID_TYPE_P (type))
+               /* We already gave an error.  */;
+             else if (TREE_CODE (type) == REFERENCE_TYPE)
+               {
+                 if (declarator->u.reference.rvalue_ref)
+                   /* Leave type alone.  */;
+                 else
+                   type = cp_build_reference_type (TREE_TYPE (type), false);
+               }
+             else
                type = cp_build_reference_type
-                      ((TREE_CODE (type) == REFERENCE_TYPE
-                        ? TREE_TYPE (type) : type),
-                       (declarator->u.reference.rvalue_ref
-                        && (TREE_CODE(type) != REFERENCE_TYPE
-                            || TYPE_REF_IS_RVALUE (type))));
+                 (type, declarator->u.reference.rvalue_ref);
 
              /* In C++0x, we need this check for direct reference to
                 reference declarations, which are forbidden by
@@ -9094,6 +9456,14 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
+  /* We need to stabilize side-effects in VLA sizes for regular array
+     declarations too, not just pointers to arrays.  */
+  if (type != error_mark_node && !TYPE_NAME (type)
+      && (decl_context == NORMAL || decl_context == FIELD)
+      && at_function_scope_p ()
+      && variably_modified_type_p (type, NULL_TREE))
+    stabilize_vla_size (TYPE_SIZE (type));
+
   /* A `constexpr' specifier used in an object declaration declares
      the object as `const'.  */
   if (constexpr_p && innermost_code != cdk_function)
@@ -9102,8 +9472,11 @@ grokdeclarator (const cp_declarator *declarator,
         error ("both %<const%> and %<constexpr%> cannot be used here");
       if (type_quals & TYPE_QUAL_VOLATILE)
         error ("both %<volatile%> and %<constexpr%> cannot be used here");
-      type_quals |= TYPE_QUAL_CONST;
-      type = cp_build_qualified_type (type, type_quals);
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       {
+         type_quals |= TYPE_QUAL_CONST;
+         type = cp_build_qualified_type (type, type_quals);
+       }
     }
 
   if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
@@ -9124,7 +9497,7 @@ grokdeclarator (const cp_declarator *declarator,
      would not have exited the loop above.  */
   if (declarator
       && declarator->u.id.qualifying_scope
-      && TYPE_P (declarator->u.id.qualifying_scope))
+      && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
     {
       tree t;
 
@@ -9196,8 +9569,10 @@ grokdeclarator (const cp_declarator *declarator,
              && (!friendp || funcdef_flag))
            {
              error (funcdef_flag
-                    ? "cannot define member function %<%T::%s%> within %<%T%>"
-                    : "cannot declare member function %<%T::%s%> within %<%T%>",
+                    ? G_("cannot define member function %<%T::%s%> "
+                         "within %<%T%>")
+                    : G_("cannot declare member function %<%T::%s%> "
+                         "within %<%T%>"),
                     ctype, name, current_class_type);
              return error_mark_node;
            }
@@ -9214,12 +9589,6 @@ grokdeclarator (const cp_declarator *declarator,
   if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
     ctype = current_class_type;
 
-  /* A constexpr non-static member function is implicitly const.  */
-  if (constexpr_p && ctype && staticp == 0
-      && TREE_CODE (type) == FUNCTION_TYPE
-      && sfk != sfk_constructor && sfk != sfk_destructor)
-    memfn_quals |= TYPE_QUAL_CONST;
-
   /* Now TYPE has the actual type.  */
 
   if (returned_attrs)
@@ -9335,6 +9704,12 @@ grokdeclarator (const cp_declarator *declarator,
           memfn_quals = TYPE_UNQUALIFIED;
         }
 
+      if (type_uses_auto (type))
+       {
+         error ("typedef declared %<auto%>");
+         type = error_mark_node;
+       }
+
       if (decl_context == FIELD)
        decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
@@ -9372,6 +9747,7 @@ grokdeclarator (const cp_declarator *declarator,
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_ANONYMOUS_P (type)
+         && declspecs->type_definition_p
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
          tree t;
@@ -9575,6 +9951,12 @@ grokdeclarator (const cp_declarator *declarator,
       if (ctype || in_namespace)
        error ("cannot use %<::%> in parameter declaration");
 
+      if (type_uses_auto (type))
+       {
+         error ("parameter declared %<auto%>");
+         type = error_mark_node;
+       }
+
       /* A parameter declared as an array of T is really a pointer to T.
         One declared as a function is really a pointer to a function.
         One declared as a member is really a pointer to member.  */
@@ -9591,7 +9973,12 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
       && !NEW_DELETE_OPNAME_P (unqualified_id))
-    type = build_memfn_type (type, ctype, memfn_quals);
+    {
+      cp_cv_quals real_quals = memfn_quals;
+      if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
+       real_quals |= TYPE_QUAL_CONST;
+      type = build_memfn_type (type, ctype, real_quals);
+    }
 
   {
     tree decl;
@@ -9721,6 +10108,7 @@ grokdeclarator (const cp_declarator *declarator,
                               sfk,
                               funcdef_flag, template_count, in_namespace,
                               attrlist, declarator->id_loc);
+            decl = set_virt_specifiers (decl, virt_specifiers);
            if (decl == NULL_TREE)
              return error_mark_node;
 #if 0
@@ -9752,7 +10140,7 @@ grokdeclarator (const cp_declarator *declarator,
               instantiation made the field's type be incomplete.  */
            if (current_class_type
                && TYPE_NAME (current_class_type)
-               && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type))
+               && IDENTIFIER_TEMPLATE (current_class_name)
                && declspecs->type
                && declspecs->type == type)
              error ("  in instantiation of template %qT",
@@ -9787,7 +10175,6 @@ grokdeclarator (const cp_declarator *declarator,
                      return error_mark_node;
                  }
 
-                DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
                decl = do_friend (ctype, unqualified_id, decl,
                                  *attrlist, flags,
                                  funcdef_flag);
@@ -9801,51 +10188,6 @@ grokdeclarator (const cp_declarator *declarator,
 
        if (decl == NULL_TREE)
          {
-           if (initialized)
-             {
-               if (!staticp)
-                 {
-                   /* An attempt is being made to initialize a non-static
-                      member.  But, from [class.mem]:
-
-                      4 A member-declarator can contain a
-                      constant-initializer only if it declares a static
-                      member (_class.static_) of integral or enumeration
-                      type, see _class.static.data_.
-
-                      This used to be relatively common practice, but
-                      the rest of the compiler does not correctly
-                      handle the initialization unless the member is
-                      static so we make it static below.  */
-                   if (cxx_dialect >= cxx0x)
-                     {
-                       sorry ("non-static data member initializers");
-                     }
-                   else
-                     {
-                       permerror (input_location, "ISO C++ forbids initialization of member %qD",
-                                  unqualified_id);
-                       permerror (input_location, "making %qD static", unqualified_id);
-                       staticp = 1;
-                     }
-                 }
-
-               if (uses_template_parms (type))
-                 /* We'll check at instantiation time.  */
-                 ;
-               else if (constexpr_p)
-                 /* constexpr has the same requirements.  */
-                 ;
-               else if (check_static_variable_definition (unqualified_id,
-                                                          type))
-                 /* If we just return the declaration, crashes
-                    will sometimes occur.  We therefore return
-                    void_type_node, as if this was a friend
-                    declaration, to cause callers to completely
-                    ignore this declaration.  */
-                 return error_mark_node;
-             }
-
            if (staticp)
              {
                /* C++ allows static class members.  All other work
@@ -9886,6 +10228,11 @@ grokdeclarator (const cp_declarator *declarator,
                    DECL_MUTABLE_P (decl) = 1;
                    storage_class = sc_none;
                  }
+
+               if (initialized)
+                 /* An attempt is being made to initialize a non-static
+                    member.  This is new in C++11.  */
+                 maybe_warn_cpp0x (CPP0X_NSDMI);
              }
 
            bad_specifiers (decl, BSP_FIELD, virtualp,
@@ -9914,6 +10261,8 @@ grokdeclarator (const cp_declarator *declarator,
        else if (thread_p)
          error ("storage class %<__thread%> invalid for function %qs", name);
 
+        if (virt_specifiers)
+          error ("virt-specifiers in %qs not allowed outside a class definition", name);
        /* Function declaration not at top level.
           Storage classes other than `extern' are not allowed
           and `extern' makes no difference.  */
@@ -9932,13 +10281,6 @@ grokdeclarator (const cp_declarator *declarator,
                       "declared out of global scope", name);
          }
 
-       if (ctype != NULL_TREE
-           && TREE_CODE (ctype) != NAMESPACE_DECL && !MAYBE_CLASS_TYPE_P (ctype))
-         {
-           error ("%q#T is not a class or a namespace", ctype);
-           ctype = NULL_TREE;
-         }
-
        if (ctype == NULL_TREE)
          {
            if (virtualp)
@@ -9950,8 +10292,8 @@ grokdeclarator (const cp_declarator *declarator,
                     || sfk == sfk_destructor)
              {
                error (funcdef_flag
-                      ? "%qs defined in a non-class scope"
-                      : "%qs declared in a non-class scope", name);
+                      ? G_("%qs defined in a non-class scope")
+                      : G_("%qs declared in a non-class scope"), name);
                sfk = sfk_none;
              }
          }
@@ -10035,8 +10377,11 @@ grokdeclarator (const cp_declarator *declarator,
              }
          }
        else if (constexpr_p && DECL_EXTERNAL (decl))
-         error ("declaration of constexpr variable %qD is not a definition",
-                decl);
+         {
+           error ("declaration of constexpr variable %qD is not a definition",
+                  decl);
+           constexpr_p = false;
+         }
       }
 
     if (storage_class == sc_extern && initialized && !funcdef_flag)
@@ -10065,8 +10410,8 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
-    /* Don't forget constexprness.  */
-    if (constexpr_p)
+    /* Set constexpr flag on vars (functions got it in grokfndecl).  */
+    if (constexpr_p && TREE_CODE (decl) == VAR_DECL)
       DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
     /* Record constancy and volatility on the DECL itself .  There's
@@ -10350,12 +10695,6 @@ grokparms (tree parmlist, tree *parms)
            init = check_default_argument (decl, init);
        }
 
-      if (TREE_CODE (decl) == PARM_DECL
-          && FUNCTION_PARAMETER_PACK_P (decl)
-          && TREE_CHAIN (parm)
-          && TREE_CHAIN (parm) != void_list_node)
-        error ("parameter packs must be at the end of the parameter list");
-
       DECL_CHAIN (decl) = decls;
       decls = decl;
       result = tree_cons (init, type, result);
@@ -11193,16 +11532,14 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
    TEMPLATE_HEADER_P is true when this declaration is preceded by
    a set of template parameters.  */
 
-tree
-xref_tag (enum tag_types tag_code, tree name,
-         tag_scope scope, bool template_header_p)
+static tree
+xref_tag_1 (enum tag_types tag_code, tree name,
+            tag_scope scope, bool template_header_p)
 {
   enum tree_code code;
   tree t;
   tree context = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
   switch (tag_code)
@@ -11230,7 +11567,7 @@ xref_tag (enum tag_types tag_code, tree name,
                               scope, template_header_p);
 
   if (t == error_mark_node)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+    return error_mark_node;
 
   if (scope != ts_current && t && current_class_type
       && template_class_depth (current_class_type)
@@ -11285,7 +11622,7 @@ xref_tag (enum tag_types tag_code, tree name,
       if (code == ENUMERAL_TYPE)
        {
          error ("use of enum %q#D without previous declaration", name);
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+         return error_mark_node;
        }
       else
        {
@@ -11299,7 +11636,7 @@ xref_tag (enum tag_types tag_code, tree name,
       if (template_header_p && MAYBE_CLASS_TYPE_P (t))
         {
          if (!redeclare_class_template (t, current_template_parms))
-            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+            return error_mark_node;
         }
       else if (!processing_template_decl
               && CLASS_TYPE_P (t)
@@ -11307,7 +11644,7 @@ xref_tag (enum tag_types tag_code, tree name,
        {
          error ("redeclaration of %qT as a non-template", t);
          error ("previous declaration %q+D", t);
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+         return error_mark_node;
        }
 
       /* Make injected friend class visible.  */
@@ -11325,9 +11662,24 @@ xref_tag (enum tag_types tag_code, tree name,
        }
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+  return t;
 }
 
+/* Wrapper for xref_tag_1.  */
+
+tree
+xref_tag (enum tag_types tag_code, tree name,
+          tag_scope scope, bool template_header_p)
+{
+  tree ret;
+  bool subtime;
+  subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = xref_tag_1 (tag_code, name, scope, template_header_p);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
+}
+
+
 tree
 xref_tag_from_type (tree old, tree id, tag_scope scope)
 {
@@ -11977,9 +12329,13 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
              tree prev_value;
              bool overflowed;
 
-             /* 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.  */
+             /* C++03 7.2/4: If no initializer is specified for the first
+                enumerator, the type is an unspecified integral
+                type. Otherwise the type is the same as the type of the
+                initializing value of the preceding enumerator unless the
+                incremented value is not representable in that type, in
+                which case the type is an unspecified integral type
+                sufficient to contain the incremented value.  */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
              if (error_operand_p (prev_value))
                value = error_mark_node;
@@ -11988,9 +12344,34 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc)
                  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)
+                   {
+                     double_int di;
+                     tree type = TREE_TYPE (prev_value);
+                     bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
+                     di.low = lo; di.high = hi;
+                     if (!double_int_fits_to_tree_p (type, di))
+                       {
+                         unsigned int itk;
+                         for (itk = itk_int; itk != itk_none; itk++)
+                           {
+                             type = integer_types[itk];
+                             if (type != NULL_TREE
+                                 && (pos || !TYPE_UNSIGNED (type))
+                                 && double_int_fits_to_tree_p (type, di))
+                               break;
+                           }
+                         if (type && cxx_dialect < cxx0x
+                             && itk > itk_unsigned_long)
+                           pedwarn (input_location, OPT_Wlong_long, pos ? "\
+incremented enumerator value is too large for %<unsigned long%>" :  "\
+incremented enumerator value is too large for %<long%>");
+                       }
+                     if (type == NULL_TREE)
+                       overflowed = true;
+                     else
+                       value = double_int_to_tree (type, di);
+                   }
 
                  if (overflowed)
                    {
@@ -12164,7 +12545,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   tree fntype;
   tree restype;
   int doing_friend = 0;
-  struct cp_binding_level *bl;
+  cp_binding_level *bl;
   tree current_function_parms;
   struct c_fileinfo *finfo
     = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
@@ -12214,12 +12595,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   /* Sometimes we don't notice that a function is a static member, and
      build a METHOD_TYPE for it.  Fix that up now.  */
-  if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
-      && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
-    {
-      revert_static_member_fn (decl1);
-      ctype = NULL_TREE;
-    }
+  gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+               && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
 
   /* Set up current_class_type, and enter the scope of the class, if
      appropriate.  */
@@ -12362,10 +12739,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
        maybe_apply_pragma_weak (decl1);
     }
 
-  /* constexpr functions must have literal argument types and
-     literal return type.  */
-  validate_constexpr_fundecl (decl1);
-
   /* Reset this in case the call to pushdecl changed it.  */
   current_function_decl = decl1;
 
@@ -12390,12 +12763,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   current_binding_level = bl;
 
-  /* Even though we're inside a function body, we still don't want to
-     call expand_expr to calculate the size of a variable-sized array.
-     We haven't necessarily assigned RTL to all variables yet, so it's
-     not safe to try to expand expressions involving them.  */
-  cfun->dont_save_pending_sizes_p = 1;
-
   /* Start the statement-tree, start the tree now.  */
   DECL_SAVED_TREE (decl1) = push_stmt_list ();
 
@@ -12417,6 +12784,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
       cp_function_chain->x_current_class_ref
        = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+      /* Set this second to avoid shortcut in cp_build_indirect_ref.  */
       cp_function_chain->x_current_class_ptr = t;
 
       /* Constructors and destructors need to know whether they're "in
@@ -12443,7 +12811,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
                        compiler-generated functions.  */
                     && !DECL_ARTIFICIAL (decl1));
 
-  if (DECL_INTERFACE_KNOWN (decl1))
+  if (processing_template_decl)
+    /* Don't mess with interface flags.  */;
+  else if (DECL_INTERFACE_KNOWN (decl1))
     {
       tree ctx = decl_function_context (decl1);
 
@@ -12462,8 +12832,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   else if (!finfo->interface_unknown && honor_interface)
     {
       if (DECL_DECLARED_INLINE_P (decl1)
-         || DECL_TEMPLATE_INSTANTIATION (decl1)
-         || processing_template_decl)
+         || DECL_TEMPLATE_INSTANTIATION (decl1))
        {
          DECL_EXTERNAL (decl1)
            = (finfo->interface_only
@@ -12595,7 +12964,7 @@ use_eh_spec_block (tree fn)
             not creating the EH_SPEC_BLOCK we save a little memory,
             and we avoid spurious warnings about unreachable
             code.  */
-         && !DECL_ARTIFICIAL (fn));
+         && !DECL_DEFAULTED_FN (fn));
 }
 
 /* Store the parameter declarations into the current function declaration.
@@ -12692,7 +13061,7 @@ save_function_data (tree decl)
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
-  f->base.x_stmt_tree.x_cur_stmt_list = NULL_TREE;
+  f->base.x_stmt_tree.x_cur_stmt_list = NULL;
   f->bindings = NULL;
   f->x_local_names = NULL;
 }
@@ -12804,7 +13173,8 @@ finish_destructor_body (void)
 /* Do the necessary processing for the beginning of a function body, which
    in this case includes member-initializers, but not the catch clauses of
    a function-try-block.  Currently, this means opening a binding level
-   for the member-initializers (in a ctor) and member cleanups (in a dtor).  */
+   for the member-initializers (in a ctor), member cleanups (in a dtor),
+   and capture proxies (in a lambda operator()).  */
 
 tree
 begin_function_body (void)
@@ -12937,7 +13307,7 @@ finish_function (int flags)
       This caused &foo to be of type ptr-to-const-function
       which then got a warning when stored in a ptr-to-function variable.  */
 
-  gcc_assert (building_stmt_tree ());
+  gcc_assert (building_stmt_list_p ());
   /* The current function is being defined, so its DECL_INITIAL should
      be set, and unless there's a multiple definition, it should be
      error_mark_node.  */
@@ -12949,22 +13319,13 @@ finish_function (int flags)
     {
       if (DECL_MAIN_P (current_function_decl))
        {
-         tree stmt;
-
          /* Make it so that `main' always returns 0 by default (or
             1 for VMS).  */
 #if VMS_TARGET
-         stmt = finish_return_stmt (integer_one_node);
+         finish_return_stmt (integer_one_node);
 #else
-         stmt = finish_return_stmt (integer_zero_node);
+         finish_return_stmt (integer_zero_node);
 #endif
-         /* Hack.  We don't want the middle-end to warn that this
-            return is unreachable, so put the statement on the
-            special line 0.  */
-         {
-           location_t linezero = linemap_line_start (line_table, 0, 1);
-           SET_EXPR_LOCATION (stmt, linezero);
-         }
        }
 
       if (use_eh_spec_block (current_function_decl))
@@ -13107,6 +13468,10 @@ finish_function (int flags)
       unused_but_set_errorcount = errorcount;
     }
 
+  /* Complain about locally defined typedefs that are not used in this
+     function.  */
+  maybe_warn_unused_local_typedefs ();
+
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
@@ -13422,12 +13787,11 @@ void
 revert_static_member_fn (tree decl)
 {
   tree stype = static_fn_type (decl);
+  cp_cv_quals quals = type_memfn_quals (stype);
+
+  if (quals != TYPE_UNQUALIFIED)
+    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
 
-  if (type_memfn_quals (stype) != TYPE_UNQUALIFIED)
-    {
-      error ("static member function %q#D declared with type qualifiers", decl);
-      stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
-    }
   TREE_TYPE (decl) = stype;
 
   if (DECL_ARGUMENTS (decl))
@@ -13444,6 +13808,7 @@ cp_tree_node_structure (union lang_tree_node * t)
   switch (TREE_CODE (&t->generic))
     {
     case DEFAULT_ARG:          return TS_CP_DEFAULT_ARG;
+    case DEFERRED_NOEXCEPT:    return TS_CP_DEFERRED_NOEXCEPT;
     case IDENTIFIER_NODE:      return TS_CP_IDENTIFIER;
     case OVERLOAD:             return TS_CP_OVERLOAD;
     case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;
@@ -13454,6 +13819,7 @@ cp_tree_node_structure (union lang_tree_node * t)
     case TRAIT_EXPR:           return TS_CP_TRAIT_EXPR;
     case LAMBDA_EXPR:          return TS_CP_LAMBDA_EXPR;
     case TEMPLATE_INFO:                return TS_CP_TEMPLATE_INFO;
+    case USERDEF_LITERAL:      return TS_CP_USERDEF_LITERAL;
     default:                   return TS_CP_GENERIC;
     }
 }