OSDN Git Service

* semantics.c (speculative_access_check): New.
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index 59a5312..3d62cd1 100644 (file)
@@ -4,7 +4,7 @@
    and during the instantiation of template functions.
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-                2008, 2009 Free Software Foundation, Inc.
+                2008, 2009, 2010 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -30,23 +30,20 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
-#include "c-common.h"
+#include "c-family/c-common.h"
 #include "tree-inline.h"
 #include "tree-mudflap.h"
-#include "except.h"
 #include "toplev.h"
 #include "flags.h"
-#include "rtl.h"
-#include "expr.h"
 #include "output.h"
 #include "timevar.h"
-#include "debug.h"
 #include "diagnostic.h"
 #include "cgraph.h"
 #include "tree-iterator.h"
 #include "vec.h"
 #include "target.h"
 #include "gimple.h"
+#include "bitmap.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -55,6 +52,8 @@ along with GCC; see the file COPYING3.  If not see
 
 static tree maybe_convert_cond (tree);
 static tree finalize_nrv_r (tree *, int *, void *);
+static tree capture_decltype (tree);
+static tree thisify_lambda_field (tree);
 
 
 /* Deferred Access Checking Overview
@@ -233,14 +232,10 @@ pop_to_parent_deferring_access_checks (void)
          int i, j;
          deferred_access_check *chk, *probe;
 
-         for (i = 0 ;
-              VEC_iterate (deferred_access_check, checks, i, chk) ;
-              ++i)
+         FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk)
            {
-             for (j = 0 ;
-                  VEC_iterate (deferred_access_check,
-                               ptr->deferred_access_checks, j, probe) ;
-                  ++j)
+             FOR_EACH_VEC_ELT (deferred_access_check,
+                               ptr->deferred_access_checks, j, probe)
                {
                  if (probe->binfo == chk->binfo &&
                      probe->decl == chk->decl &&
@@ -269,7 +264,7 @@ perform_access_checks (VEC (deferred_access_check,gc)* checks)
   if (!checks)
     return;
 
-  for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i)
+  FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk)
     enforce_access (chk->binfo, chk->decl, chk->diag_decl);
 }
 
@@ -324,10 +319,8 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
     }
 
   /* See if we are already going to perform this check.  */
-  for (i = 0 ;
-       VEC_iterate (deferred_access_check,
-                   ptr->deferred_access_checks, i, chk) ;
-       ++i)
+  FOR_EACH_VEC_ELT  (deferred_access_check,
+                    ptr->deferred_access_checks, i, chk)
     {
       if (chk->decl == decl && chk->binfo == binfo &&
          chk->diag_decl == diag_decl)
@@ -344,6 +337,30 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
   new_access->diag_decl = diag_decl;
 }
 
+/* Used by build_over_call in LOOKUP_SPECULATIVE mode: return whether DECL
+   is accessible in BINFO, and possibly complain if not.  If we're not
+   checking access, everything is accessible.  */
+
+bool
+speculative_access_check (tree binfo, tree decl, tree diag_decl,
+                         bool complain)
+{
+  if (deferred_access_no_check)
+    return true;
+
+  /* If we're checking for implicit delete, we don't want access
+     control errors.  */
+  if (!accessible_p (binfo, decl, true))
+    {
+      /* Unless we're under maybe_explain_implicit_delete.  */
+      if (complain)
+       enforce_access (binfo, decl, diag_decl);
+      return false;
+    }
+
+  return true;
+}
+
 /* Returns nonzero if the current statement is a full expression,
    i.e. temporaries created during that statement should be destroyed
    at the end of the statement.  */
@@ -544,10 +561,9 @@ finish_goto_stmt (tree destination)
     TREE_USED (destination) = 1;
   else
     {
-      /* The DESTINATION is being used as an rvalue.  */
+      destination = mark_rvalue_use (destination);
       if (!processing_template_decl)
        {
-         destination = decay_conversion (destination);
          destination = cp_convert (ptr_type_node, destination);
          if (error_operand_p (destination))
            return NULL_TREE;
@@ -610,10 +626,10 @@ finish_expr_stmt (tree expr)
        {
          if (warn_sequence_point)
            verify_sequence_points (expr);
-         expr = convert_to_void (expr, "statement", tf_warning_or_error);
+         expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
        }
       else if (!type_dependent_expression_p (expr))
-       convert_to_void (build_non_dependent_expr (expr), "statement"
+       convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT
                          tf_warning_or_error);
 
       if (check_for_bare_parameter_packs (expr))
@@ -871,11 +887,11 @@ finish_for_expr (tree expr, tree for_stmt)
     {
       if (warn_sequence_point)
        verify_sequence_points (expr);
-      expr = convert_to_void (expr, "3rd expression in for",
+      expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
                               tf_warning_or_error);
     }
   else if (!type_dependent_expression_p (expr))
-    convert_to_void (build_non_dependent_expr (expr), "3rd expression in for",
+    convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR,
                      tf_warning_or_error);
   expr = maybe_cleanup_point_expr_void (expr);
   if (check_for_bare_parameter_packs (expr))
@@ -885,12 +901,16 @@ finish_for_expr (tree expr, tree for_stmt)
 
 /* Finish the body of a for-statement, which may be given by
    FOR_STMT.  The increment-EXPR for the loop must be
-   provided.  */
+   provided.
+   It can also finish RANGE_FOR_STMT. */
 
 void
 finish_for_stmt (tree for_stmt)
 {
-  FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
+  if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
+    RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
+  else
+    FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
 
   /* Pop the scope for the body of the loop.  */
   if (flag_new_for_scope > 0)
@@ -903,6 +923,36 @@ finish_for_stmt (tree for_stmt)
   finish_stmt ();
 }
 
+/* Begin a range-for-statement.  Returns a new RANGE_FOR_STMT.
+   To finish it call finish_for_stmt(). */
+
+tree
+begin_range_for_stmt (void)
+{
+  tree r;
+
+  r = build_stmt (input_location, RANGE_FOR_STMT,
+                 NULL_TREE, NULL_TREE, NULL_TREE);
+
+  if (flag_new_for_scope > 0)
+    TREE_CHAIN (r) = do_pushlevel (sk_for);
+
+  return r;
+}
+
+/* Finish the head of a range-based for statement, which may
+   be given by RANGE_FOR_STMT. DECL must be the declaration
+   and EXPR must be the loop expression. */
+
+void
+finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
+{
+  RANGE_FOR_DECL (range_for_stmt) = decl;
+  RANGE_FOR_EXPR (range_for_stmt) = expr;
+  add_stmt (range_for_stmt);
+  RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
+}
+
 /* Finish a break-statement.  */
 
 tree
@@ -1182,7 +1232,19 @@ void
 finish_compound_stmt (tree stmt)
 {
   if (TREE_CODE (stmt) == BIND_EXPR)
-    BIND_EXPR_BODY (stmt) = do_poplevel (BIND_EXPR_BODY (stmt));
+    {
+      tree body = do_poplevel (BIND_EXPR_BODY (stmt));
+      /* If the STATEMENT_LIST is empty and this BIND_EXPR isn't special,
+        discard the BIND_EXPR so it can be merged with the containing
+        STATEMENT_LIST.  */
+      if (TREE_CODE (body) == STATEMENT_LIST
+         && STATEMENT_LIST_HEAD (body) == NULL
+         && !BIND_EXPR_BODY_BLOCK (stmt)
+         && !BIND_EXPR_TRY_BLOCK (stmt))
+       stmt = body;
+      else
+       BIND_EXPR_BODY (stmt) = body;
+    }
   else if (STATEMENT_LIST_NO_SCOPE (stmt))
     stmt = pop_stmt_list (stmt);
   else
@@ -1200,12 +1262,13 @@ finish_compound_stmt (tree stmt)
 }
 
 /* Finish an asm-statement, whose components are a STRING, some
-   OUTPUT_OPERANDS, some INPUT_OPERANDS, and some CLOBBERS.  Also note
-   whether the asm-statement should be considered volatile.  */
+   OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some
+   LABELS.  Also note whether the asm-statement should be
+   considered volatile.  */
 
 tree
 finish_asm_stmt (int volatile_p, tree string, tree output_operands,
-                tree input_operands, tree clobbers)
+                tree input_operands, tree clobbers, tree labels)
 {
   tree r;
   tree t;
@@ -1220,10 +1283,10 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
       tree operand;
       int i;
 
-      oconstraints = (const char **) alloca (noutputs * sizeof (char *));
+      oconstraints = XALLOCAVEC (const char *, noutputs);
 
       string = resolve_asm_operand_names (string, output_operands,
-                                         input_operands);
+                                         input_operands, labels);
 
       for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
        {
@@ -1237,6 +1300,8 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
             otherwise we'll get an error.  Gross, but ...  */
          STRIP_NOPS (operand);
 
+         operand = mark_lvalue_use (operand);
+
          if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
            operand = error_mark_node;
 
@@ -1251,7 +1316,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
                     effectively const.  */
                  || (CLASS_TYPE_P (TREE_TYPE (operand))
                      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
-           readonly_error (operand, "assignment (via 'asm' output)");
+           readonly_error (operand, REK_ASSIGNMENT_ASM);
 
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
          oconstraints[i] = constraint;
@@ -1309,7 +1374,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
 
   r = build_stmt (input_location, ASM_EXPR, string,
                  output_operands, input_operands,
-                 clobbers);
+                 clobbers, labels);
   ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
   r = maybe_cleanup_point_expr_void (r);
   return add_stmt (r);
@@ -1423,17 +1488,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 {
   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
-  if (!object && cp_unevaluated_operand != 0)
+  if (!object)
     {
-      /* DR 613: Can use non-static data members without an associated
-         object in sizeof/decltype/alignof.  */
       tree scope = qualifying_scope;
       if (scope == NULL_TREE)
        scope = context_for_name_lookup (decl);
       object = maybe_dummy_object (scope, NULL);
     }
 
-  if (!object)
+  /* DR 613: Can use non-static data members without an associated
+     object in sizeof/decltype/alignof.  */
+  if (is_dummy_object (object) && cp_unevaluated_operand == 0
+      && (!processing_template_decl || !current_class_ref))
     {
       if (current_function_decl
          && DECL_STATIC_FUNCTION_P (current_function_decl))
@@ -1444,6 +1510,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 
       return error_mark_node;
     }
+
   if (current_class_ptr)
     TREE_USED (current_class_ptr) = 1;
   if (processing_template_decl && !qualifying_scope)
@@ -1468,33 +1535,17 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 
       return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
     }
+  /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
+     QUALIFYING_SCOPE is also non-null.  Wrap this in a SCOPE_REF
+     for now.  */
+  else if (processing_template_decl)
+    return build_qualified_name (TREE_TYPE (decl),
+                                qualifying_scope,
+                                DECL_NAME (decl),
+                                /*template_p=*/false);
   else
     {
       tree access_type = TREE_TYPE (object);
-      tree lookup_context = context_for_name_lookup (decl);
-
-      while (!DERIVED_FROM_P (lookup_context, access_type))
-       {
-         access_type = TYPE_CONTEXT (access_type);
-         while (access_type && DECL_P (access_type))
-           access_type = DECL_CONTEXT (access_type);
-
-         if (!access_type)
-           {
-             error ("object missing in reference to %q+D", decl);
-             error ("from this location");
-             return error_mark_node;
-           }
-       }
-
-      /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
-        QUALIFYING_SCOPE is also non-null.  Wrap this in a SCOPE_REF
-        for now.  */
-      if (processing_template_decl)
-       return build_qualified_name (TREE_TYPE (decl),
-                                    qualifying_scope,
-                                    DECL_NAME (decl),
-                                    /*template_p=*/false);
 
       perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
                                     decl);
@@ -1515,6 +1566,37 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
     }
 }
 
+/* If we are currently parsing a template and we encountered a typedef
+   TYPEDEF_DECL that is being accessed though CONTEXT, this function
+   adds the typedef to a list tied to the current template.
+   At tempate instantiatin time, that list is walked and access check
+   performed for each typedef.
+   LOCATION is the location of the usage point of TYPEDEF_DECL.  */
+
+void
+add_typedef_to_current_template_for_access_check (tree typedef_decl,
+                                                  tree context,
+                                                 location_t location)
+{
+    tree template_info = NULL;
+    tree cs = current_scope ();
+
+    if (!is_typedef_decl (typedef_decl)
+       || !context
+       || !CLASS_TYPE_P (context)
+       || !cs)
+      return;
+
+    if (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)
+      template_info = get_template_info (cs);
+
+    if (template_info
+       && TI_TEMPLATE (template_info)
+       && !currently_open_class (context))
+      append_type_to_template_for_access_check (cs, typedef_decl,
+                                               context, location);
+}
+
 /* DECL was the declaration to which a qualified-id resolved.  Issue
    an error message if it is not accessible.  If OBJECT_TYPE is
    non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
@@ -1533,27 +1615,11 @@ check_accessibility_of_qualified_id (tree decl,
      add it to a list tied to the template.
      At template instantiation time, that list will be walked and
      access check performed.  */
-  if (is_typedef_decl (decl))
-    {
-      /* This the scope through which type_decl is accessed.
-        It will be useful information later to do access check for
-        type_decl usage.  */
-      tree scope = nested_name_specifier
-      ?  nested_name_specifier
-      : DECL_CONTEXT (decl);
-      tree templ_info = NULL;
-      tree cs = current_scope ();
-
-      if (cs && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
-       templ_info = get_template_info (cs);
-
-      if (templ_info
-         && TI_TEMPLATE (templ_info)
-         && scope
-         && CLASS_TYPE_P (scope)
-         && !currently_open_class (scope))
-       append_type_to_template_for_access_check (current_scope (), decl, scope);
-    }
+  add_typedef_to_current_template_for_access_check (decl,
+                                                   nested_name_specifier
+                                                   ? nested_name_specifier
+                                                   : DECL_CONTEXT (decl),
+                                                   input_location);
 
   /* If we're not checking, return immediately.  */
   if (deferred_access_no_check)
@@ -1654,24 +1720,21 @@ finish_qualified_id_expr (tree qualifying_class,
   else if (TREE_CODE (expr) == FIELD_DECL)
     {
       push_deferring_access_checks (dk_no_check);
-      expr = finish_non_static_data_member (expr, current_class_ref,
+      expr = finish_non_static_data_member (expr, NULL_TREE,
                                            qualifying_class);
       pop_deferring_access_checks ();
     }
   else if (BASELINK_P (expr) && !processing_template_decl)
     {
-      tree fns;
+      tree ob;
 
       /* See if any of the functions are non-static members.  */
-      fns = BASELINK_FUNCTIONS (expr);
-      if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
-       fns = TREE_OPERAND (fns, 0);
       /* If so, the expression may be relative to 'this'.  */
-      if (!shared_member_p (fns)
-         && current_class_ref
-         && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref)))
+      if (!shared_member_p (expr)
+         && (ob = maybe_dummy_object (qualifying_class, NULL),
+             !is_dummy_object (ob)))
        expr = (build_class_member_access_expr
-               (maybe_dummy_object (qualifying_class, NULL),
+               (ob,
                 expr,
                 BASELINK_ACCESS_BINFO (expr),
                 /*preserve_reference=*/false,
@@ -1816,20 +1879,53 @@ stmt_expr_value_expr (tree stmt_expr)
   return t;
 }
 
+/* Return TRUE iff EXPR_STMT is an empty list of
+   expression statements.  */
+
+bool
+empty_expr_stmt_p (tree expr_stmt)
+{
+  tree body = NULL_TREE;
+
+  if (expr_stmt == void_zero_node)
+    return true;
+
+  if (expr_stmt)
+    {
+      if (TREE_CODE (expr_stmt) == EXPR_STMT)
+       body = EXPR_STMT_EXPR (expr_stmt);
+      else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
+       body = expr_stmt;
+    }
+
+  if (body)
+    {
+      if (TREE_CODE (body) == STATEMENT_LIST)
+       return tsi_end_p (tsi_start (body));
+      else
+       return empty_expr_stmt_p (body);
+    }
+  return false;
+}
+
 /* Perform Koenig lookup.  FN is the postfix-expression representing
    the function (or functions) to call; ARGS are the arguments to the
-   call.  Returns the functions to be considered by overload
-   resolution.  */
+   call; if INCLUDE_STD then the `std' namespace is automatically
+   considered an associated namespace (used in range-based for loops).
+   Returns the functions to be considered by overload resolution.  */
 
 tree
-perform_koenig_lookup (tree fn, VEC(tree,gc) *args)
+perform_koenig_lookup (tree fn, VEC(tree,gc) *args, bool include_std)
 {
   tree identifier = NULL_TREE;
   tree functions = NULL_TREE;
   tree tmpl_args = NULL_TREE;
+  bool template_id = false;
 
   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
     {
+      /* Use a separate flag to handle null args.  */
+      template_id = true;
       tmpl_args = TREE_OPERAND (fn, 1);
       fn = TREE_OPERAND (fn, 0);
     }
@@ -1855,14 +1951,14 @@ perform_koenig_lookup (tree fn, VEC(tree,gc) *args)
   if (!any_type_dependent_arguments_p (args)
       && !any_dependent_template_arguments_p (tmpl_args))
     {
-      fn = lookup_arg_dependent (identifier, functions, args);
+      fn = lookup_arg_dependent (identifier, functions, args, include_std);
       if (!fn)
        /* The unqualified name could not be resolved.  */
        fn = unqualified_fn_lookup_error (identifier);
     }
 
-  if (fn && tmpl_args)
-    fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args);
+  if (fn && template_id)
+    fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
   
   return fn;
 }
@@ -1941,31 +2037,18 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
           . operator.... [Otherwise] a contrived object of type T
           becomes the implied object argument.
 
-       This paragraph is unclear about this situation:
+       In this situation:
 
          struct A { void f(); };
          struct B : public A {};
          struct C : public A { void g() { B::f(); }};
 
-       In particular, for `B::f', this paragraph does not make clear
-       whether "the class of that member function" refers to `A' or
-       to `B'.  We believe it refers to `B'.  */
-      if (current_class_type
-         && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                            current_class_type)
-         && current_class_ref)
-       object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                                    NULL);
-      else
-       {
-         tree representative_fn;
+       "the class of that member function" refers to `A'.  But 11.2
+       [class.access.base] says that we need to convert 'this' to B* as
+       part of the access, so we pass 'B' to maybe_dummy_object.  */
 
-         representative_fn = BASELINK_FUNCTIONS (fn);
-         if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
-           representative_fn = TREE_OPERAND (representative_fn, 0);
-         representative_fn = get_first_fn (representative_fn);
-         object = build_dummy_object (DECL_CONTEXT (representative_fn));
-       }
+      object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+                                  NULL);
 
       if (processing_template_decl)
        {
@@ -2045,7 +2128,14 @@ finish_this_expr (void)
 
   if (current_class_ptr)
     {
-      result = current_class_ptr;
+      tree type = TREE_TYPE (current_class_ref);
+
+      /* In a lambda expression, 'this' refers to the captured 'this'.  */
+      if (LAMBDA_TYPE_P (type))
+        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
+      else
+        result = current_class_ptr;
+
     }
   else if (current_function_decl
           && DECL_STATIC_FUNCTION_P (current_function_decl))
@@ -2185,19 +2275,7 @@ finish_compound_literal (tree type, tree compound_literal)
   if (TREE_CODE (type) == ARRAY_TYPE)
     cp_complete_array_type (&type, compound_literal, false);
   compound_literal = digest_init (type, compound_literal);
-  if ((!at_function_scope_p () || cp_type_readonly (type))
-      && initializer_constant_valid_p (compound_literal, type))
-    {
-      tree decl = create_temporary_var (type);
-      DECL_INITIAL (decl) = compound_literal;
-      TREE_STATIC (decl) = 1;
-      decl = pushdecl_top_level (decl);
-      DECL_NAME (decl) = make_anon_name ();
-      SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
-      return decl;
-    }
-  else
-    return get_target_expr (compound_literal);
+  return get_target_expr (compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
@@ -2302,6 +2380,26 @@ begin_class_definition (tree t, tree attributes)
       error ("definition of %q#T inside template parameter list", t);
       return error_mark_node;
     }
+
+  /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
+     are passed the same as decimal scalar types.  */
+  if (TREE_CODE (t) == RECORD_TYPE
+      && !processing_template_decl)
+    {
+      tree ns = TYPE_CONTEXT (t);
+      if (ns && TREE_CODE (ns) == NAMESPACE_DECL
+         && DECL_CONTEXT (ns) == std_node
+         && DECL_NAME (ns)
+         && !strcmp (IDENTIFIER_POINTER (DECL_NAME (ns)), "decimal"))
+       {
+         const char *n = TYPE_NAME_STRING (t);
+         if ((strcmp (n, "decimal32") == 0)
+             || (strcmp (n, "decimal64") == 0)
+             || (strcmp (n, "decimal128") == 0))
+           TYPE_TRANSPARENT_AGGR (t) = 1;
+       }
+    }
+
   /* A non-implicit typename comes from code like:
 
        template <typename T> struct A {
@@ -2320,9 +2418,6 @@ begin_class_definition (tree t, tree attributes)
       pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
     }
 
-  /* Update the location of the decl.  */
-  DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
-
   if (TYPE_BEING_DEFINED (t))
     {
       t = make_class_type (TREE_CODE (t));
@@ -2333,6 +2428,7 @@ begin_class_definition (tree t, tree attributes)
   TYPE_BEING_DEFINED (t) = 1;
 
   cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
+  fixup_attribute_variants (t);
 
   if (flag_pack_struct)
     {
@@ -2376,7 +2472,7 @@ finish_member_declaration (tree decl)
     return;
 
   /* We should see only one DECL at a time.  */
-  gcc_assert (TREE_CHAIN (decl) == NULL_TREE);
+  gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
 
   /* Set up access control for DECL.  */
   TREE_PRIVATE (decl)
@@ -2418,7 +2514,7 @@ finish_member_declaration (tree decl)
         CLASSTYPE_METHOD_VEC.  */
       if (add_method (current_class_type, decl, NULL_TREE))
        {
-         TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
+         DECL_CHAIN (decl) = TYPE_METHODS (current_class_type);
          TYPE_METHODS (current_class_type) = decl;
 
          maybe_add_class_template_decl_list (current_class_type, decl,
@@ -2451,7 +2547,7 @@ finish_member_declaration (tree decl)
          = chainon (TYPE_FIELDS (current_class_type), decl);
       else
        {
-         TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type);
+         DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
          TYPE_FIELDS (current_class_type) = decl;
        }
 
@@ -2563,20 +2659,21 @@ qualified_name_lookup_error (tree scope, tree name,
   else if (TYPE_P (scope))
     {
       if (!COMPLETE_TYPE_P (scope))
-       error ("%Hincomplete type %qT used in nested name specifier",
-              &location, scope);
+       error_at (location, "incomplete type %qT used in nested name specifier",
+                 scope);
       else if (TREE_CODE (decl) == TREE_LIST)
        {
-         error ("%Hreference to %<%T::%D%> is ambiguous", &location, scope, name);
+         error_at (location, "reference to %<%T::%D%> is ambiguous",
+                   scope, name);
          print_candidates (decl);
        }
       else
-       error ("%H%qD is not a member of %qT", &location, name, scope);
+       error_at (location, "%qD is not a member of %qT", name, scope);
     }
   else if (scope != global_namespace)
-    error ("%H%qD is not a member of %qD", &location, name, scope);
+    error_at (location, "%qD is not a member of %qD", name, scope);
   else
-    error ("%H%<::%D%> has not been declared", &location, name);
+    error_at (location, "%<::%D%> has not been declared", name);
 }
 
 /* If FNS is a member function, a set of member functions, or a
@@ -2608,6 +2705,30 @@ baselink_for_fns (tree fns)
   return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
 }
 
+/* Returns true iff DECL is an automatic variable from a function outside
+   the current one.  */
+
+static bool
+outer_automatic_var_p (tree decl)
+{
+  return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+         && DECL_FUNCTION_SCOPE_P (decl)
+         && !TREE_STATIC (decl)
+         && DECL_CONTEXT (decl) != current_function_decl);
+}
+
+/* Returns true iff DECL is a capture field from a lambda that is not our
+   immediate context.  */
+
+static bool
+outer_lambda_capture_p (tree decl)
+{
+  return (TREE_CODE (decl) == FIELD_DECL
+         && LAMBDA_TYPE_P (DECL_CONTEXT (decl))
+         && (!current_class_type
+             || !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type)));
+}
+
 /* ID_EXPRESSION is a representation of parsed, but unprocessed,
    id-expression.  (See cp_parser_id_expression for details.)  SCOPE,
    if non-NULL, is the type or namespace used to explicitly qualify
@@ -2709,12 +2830,70 @@ finish_id_expression (tree id_expression,
       if (!scope && decl != error_mark_node)
        maybe_note_name_used_in_class (id_expression, decl);
 
-      /* Disallow uses of local variables from containing functions.  */
-      if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+      /* Disallow uses of local variables from containing functions, except
+        within lambda-expressions.  */
+      if ((outer_automatic_var_p (decl)
+          || outer_lambda_capture_p (decl))
+         /* It's not a use (3.2) if we're in an unevaluated context.  */
+         && !cp_unevaluated_operand)
        {
-         tree context = decl_function_context (decl);
-         if (context != NULL_TREE && context != current_function_decl
-             && ! TREE_STATIC (decl))
+         tree context = DECL_CONTEXT (decl);
+         tree containing_function = current_function_decl;
+         tree lambda_stack = NULL_TREE;
+         tree lambda_expr = NULL_TREE;
+         tree initializer = decl;
+
+         /* Core issue 696: "[At the July 2009 meeting] the CWG expressed
+            support for an approach in which a reference to a local
+            [constant] automatic variable in a nested class or lambda body
+            would enter the expression as an rvalue, which would reduce
+            the complexity of the problem"
+
+            FIXME update for final resolution of core issue 696.  */
+         if (decl_constant_var_p (decl))
+           return integral_constant_value (decl);
+
+         if (TYPE_P (context))
+           {
+             /* Implicit capture of an explicit capture.  */
+             context = lambda_function (context);
+             initializer = thisify_lambda_field (decl);
+           }
+
+         /* If we are in a lambda function, we can move out until we hit
+            1. the context,
+            2. a non-lambda function, or
+            3. a non-default capturing lambda function.  */
+         while (context != containing_function
+                && LAMBDA_FUNCTION_P (containing_function))
+           {
+             lambda_expr = CLASSTYPE_LAMBDA_EXPR
+               (DECL_CONTEXT (containing_function));
+
+             if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
+                 == CPLD_NONE)
+               break;
+
+             lambda_stack = tree_cons (NULL_TREE,
+                                       lambda_expr,
+                                       lambda_stack);
+
+             containing_function
+               = decl_function_context (containing_function);
+           }
+
+         if (context == containing_function)
+           {
+             decl = add_default_capture (lambda_stack,
+                                         /*id=*/DECL_NAME (decl),
+                                         initializer);
+           }
+         else if (lambda_expr)
+           {
+             error ("%qD is not captured", decl);
+             return error_mark_node;
+           }
+         else
            {
              error (TREE_CODE (decl) == VAR_DECL
                     ? "use of %<auto%> variable from containing function"
@@ -2723,6 +2902,16 @@ finish_id_expression (tree id_expression,
              return error_mark_node;
            }
        }
+
+      /* Also disallow uses of function parameters outside the function
+        body, except inside an unevaluated context (i.e. decltype).  */
+      if (TREE_CODE (decl) == PARM_DECL
+         && DECL_CONTEXT (decl) == NULL_TREE
+         && !cp_unevaluated_operand)
+       {
+         error ("use of parameter %qD outside function body", decl);
+         return error_mark_node;
+       }
     }
 
   /* If we didn't find anything, or what we found was a type,
@@ -2904,7 +3093,7 @@ finish_id_expression (tree id_expression,
                 already.  Turn off checking to avoid duplicate errors.  */
              push_deferring_access_checks (dk_no_check);
              decl = finish_non_static_data_member
-                      (decl, current_class_ref,
+                      (decl, NULL_TREE,
                        /*qualifying_scope=*/NULL_TREE);
              pop_deferring_access_checks ();
              return decl;
@@ -2912,21 +3101,6 @@ finish_id_expression (tree id_expression,
          return id_expression;
        }
 
-      /* Only certain kinds of names are allowed in constant
-        expression.  Enumerators and template parameters have already
-        been handled above.  */
-      if (integral_constant_expression_p
-         && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
-         && ! builtin_valid_in_constant_expr_p (decl))
-       {
-         if (!allow_non_integral_constant_expression_p)
-           {
-             error ("%qD cannot appear in a constant-expression", decl);
-             return error_mark_node;
-           }
-         *non_integral_constant_expression_p = true;
-       }
-
       if (TREE_CODE (decl) == NAMESPACE_DECL)
        {
          error ("use of namespace %qD as expression", decl);
@@ -2953,6 +3127,21 @@ finish_id_expression (tree id_expression,
          || TREE_CODE (decl) == RESULT_DECL)
        mark_used (decl);
 
+      /* Only certain kinds of names are allowed in constant
+        expression.  Enumerators and template parameters have already
+        been handled above.  */
+      if (integral_constant_expression_p
+         && ! decl_constant_var_p (decl)
+         && ! builtin_valid_in_constant_expr_p (decl))
+       {
+         if (!allow_non_integral_constant_expression_p)
+           {
+             error ("%qD cannot appear in a constant-expression", decl);
+             return error_mark_node;
+           }
+         *non_integral_constant_expression_p = true;
+       }
+
       if (scope)
        {
          decl = (adjust_result_of_qualified_name_lookup
@@ -2972,7 +3161,13 @@ finish_id_expression (tree id_expression,
            {
              tree r = convert_from_reference (decl);
 
-             if (processing_template_decl && TYPE_P (scope))
+             /* In a template, return a SCOPE_REF for most qualified-ids
+                so that we can check access at instantiation time.  But if
+                we're looking at a member of the current instantiation, we
+                know we have access and building up the SCOPE_REF confuses
+                non-type template argument handling.  */
+             if (processing_template_decl && TYPE_P (scope)
+                 && !currently_open_class (scope))
                r = build_qualified_name (TREE_TYPE (r),
                                          scope, decl,
                                          template_p);
@@ -2985,7 +3180,7 @@ finish_id_expression (tree id_expression,
             Access checking has been performed during name lookup
             already.  Turn off checking to avoid duplicate errors.  */
          push_deferring_access_checks (dk_no_check);
-         decl = finish_non_static_data_member (decl, current_class_ref,
+         decl = finish_non_static_data_member (decl, NULL_TREE,
                                                /*qualifying_scope=*/NULL_TREE);
          pop_deferring_access_checks ();
        }
@@ -2993,10 +3188,7 @@ finish_id_expression (tree id_expression,
        {
          tree first_fn;
 
-         first_fn = decl;
-         if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
-           first_fn = TREE_OPERAND (first_fn, 0);
-         first_fn = get_first_fn (first_fn);
+         first_fn = get_first_fn (decl);
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
@@ -3058,6 +3250,8 @@ finish_typeof (tree expr)
       return type;
     }
 
+  expr = mark_type_use (expr);
+
   type = unlowered_expr_type (expr);
 
   if (!type || type == unknown_type_node)
@@ -3083,7 +3277,7 @@ finish_offsetof (tree expr)
     }
   if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
-      || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
+      || TREE_TYPE (expr) == unknown_type_node)
     {
       if (TREE_CODE (expr) == COMPONENT_REF
          || TREE_CODE (expr) == COMPOUND_EXPR)
@@ -3125,10 +3319,12 @@ simplify_aggr_init_expr (tree *tp)
       style = arg;
     }
 
-  call_expr = build_call_array (TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
-                               fn,
-                               aggr_init_expr_nargs (aggr_init_expr),
-                               AGGR_INIT_EXPR_ARGP (aggr_init_expr));
+  call_expr = build_call_array_loc (input_location,
+                                   TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+                                   fn,
+                                   aggr_init_expr_nargs (aggr_init_expr),
+                                   AGGR_INIT_EXPR_ARGP (aggr_init_expr));
+  TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
 
   if (style == ctor)
     {
@@ -3144,7 +3340,7 @@ simplify_aggr_init_expr (tree *tp)
         expand_call{,_inline}.  */
       cxx_mark_addressable (slot);
       CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
-      call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr);
+      call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr);
     }
   else if (style == pcc)
     {
@@ -3181,11 +3377,13 @@ emit_associated_thunks (tree fn)
      is so that you can know statically the entire set of thunks that
      will ever be needed for a given virtual function, thereby
      enabling you to output all the thunks with the function itself.  */
-  if (DECL_VIRTUAL_P (fn))
+  if (DECL_VIRTUAL_P (fn)
+      /* Do not emit thunks for extern template instantiations.  */
+      && ! DECL_REALLY_EXTERN (fn))
     {
       tree thunk;
 
-      for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk))
+      for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
        {
          if (!THUNK_ALIAS (thunk))
            {
@@ -3195,7 +3393,7 @@ emit_associated_thunks (tree fn)
                  tree probe;
 
                  for (probe = DECL_THUNKS (thunk);
-                      probe; probe = TREE_CHAIN (probe))
+                      probe; probe = DECL_CHAIN (probe))
                    use_thunk (probe, /*emit_p=*/1);
                }
            }
@@ -3207,8 +3405,8 @@ emit_associated_thunks (tree fn)
 
 /* Generate RTL for FN.  */
 
-void
-expand_or_defer_fn (tree fn)
+bool
+expand_or_defer_fn_1 (tree fn)
 {
   /* When the parser calls us after finishing the body of a template
      function, we don't really want to expand the body.  */
@@ -3222,10 +3420,10 @@ expand_or_defer_fn (tree fn)
         is not a GC root.  */
       if (!function_depth)
        ggc_collect ();
-      return;
+      return false;
     }
 
-  gcc_assert (gimple_body (fn));
+  gcc_assert (DECL_SAVED_TREE (fn));
 
   /* If this is a constructor or destructor body, we have to clone
      it.  */
@@ -3234,7 +3432,8 @@ expand_or_defer_fn (tree fn)
       /* We don't want to process FN again, so pretend we've written
         it out, even though we haven't.  */
       TREE_ASM_WRITTEN (fn) = 1;
-      return;
+      DECL_SAVED_TREE (fn) = NULL_TREE;
+      return false;
     }
 
   /* We make a decision about linkage for these functions at the end
@@ -3273,7 +3472,9 @@ expand_or_defer_fn (tree fn)
         this function as needed so that finish_file will make sure to
         output it later.  Similarly, all dllexport'd functions must
         be emitted; there may be callers in other DLLs.  */
-      if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+      if ((flag_keep_inline_functions
+          && DECL_DECLARED_INLINE_P (fn)
+          && !DECL_REALLY_EXTERN (fn))
          || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
        mark_needed (fn);
     }
@@ -3281,14 +3482,24 @@ expand_or_defer_fn (tree fn)
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
-    return;
+    return false;
 
-  function_depth++;
+  return true;
+}
+
+void
+expand_or_defer_fn (tree fn)
+{
+  if (expand_or_defer_fn_1 (fn))
+    {
+      function_depth++;
 
-  /* Expand or defer, at the whim of the compilation unit manager.  */
-  cgraph_finalize_function (fn, function_depth > 1);
+      /* Expand or defer, at the whim of the compilation unit manager.  */
+      cgraph_finalize_function (fn, function_depth > 1);
+      emit_associated_thunks (fn);
 
-  function_depth--;
+      function_depth--;
+    }
 }
 
 struct nrv_data
@@ -3333,7 +3544,7 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
       else
        init = build_empty_stmt (EXPR_LOCATION (*tp));
       DECL_INITIAL (dp->var) = NULL_TREE;
-      SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
+      SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
       *tp = init;
     }
   /* And replace all uses of the NRV with the RESULT_DECL.  */
@@ -3363,14 +3574,15 @@ finalize_nrv (tree *tp, tree var, tree result)
 {
   struct nrv_data data;
 
-  /* Copy debugging information from VAR to RESULT.  */
+  /* Copy name from VAR to RESULT.  */
   DECL_NAME (result) = DECL_NAME (var);
-  DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var);
-  DECL_IGNORED_P (result) = DECL_IGNORED_P (var);
-  DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var);
-  DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var);
   /* Don't forget that we take its address.  */
   TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
+  /* Finally set DECL_VALUE_EXPR to avoid assigning
+     a stack slot at -O0 for the original var and debug info
+     uses RESULT location for VAR.  */
+  SET_DECL_VALUE_EXPR (var, result);
+  DECL_HAS_VALUE_EXPR_P (var) = 1;
 
   data.var = var;
   data.result = result;
@@ -3379,31 +3591,6 @@ finalize_nrv (tree *tp, tree var, tree result)
   htab_delete (data.visited);
 }
 \f
-/* Return the declaration for the function called by CALL_EXPR T,
-   TYPE is the class type of the clause decl.  */
-
-static tree
-omp_clause_info_fndecl (tree t, tree type)
-{
-  tree ret = get_callee_fndecl (t);
-
-  if (ret)
-    return ret;
-
-  gcc_assert (TREE_CODE (t) == CALL_EXPR);
-  t = CALL_EXPR_FN (t);
-  STRIP_NOPS (t);
-  if (TREE_CODE (t) == OBJ_TYPE_REF)
-    {
-      t = cp_fold_obj_type_ref (t, type);
-      if (TREE_CODE (t) == ADDR_EXPR
-         && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
-       return TREE_OPERAND (t, 0);
-    }
-
-  return NULL_TREE;
-}
-
 /* Create CP_OMP_CLAUSE_INFO for clause C.  Returns true if it is invalid.  */
 
 bool
@@ -3421,80 +3608,27 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
   info = make_tree_vec (3);
   CP_OMP_CLAUSE_INFO (c) = info;
 
-  if (need_default_ctor
-      || (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type)))
+  if (need_default_ctor || need_copy_ctor)
     {
-      VEC(tree,gc) *vec;
-
       if (need_default_ctor)
-       vec = NULL;
+       t = get_default_ctor (type);
       else
-       {
-         t = build_int_cst (build_pointer_type (type), 0);
-         t = build1 (INDIRECT_REF, type, t);
-         vec = make_tree_vector_single (t);
-       }
-      t = build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                    &vec, type, LOOKUP_NORMAL,
-                                    tf_warning_or_error);
-
-      if (vec != NULL)
-       release_tree_vector (vec);
-
-      if (targetm.cxx.cdtor_returns_this () || errorcount)
-       /* Because constructors and destructors return this,
-          the call will have been cast to "void".  Remove the
-          cast here.  We would like to use STRIP_NOPS, but it
-          wouldn't work here because TYPE_MODE (t) and
-          TYPE_MODE (TREE_OPERAND (t, 0)) are different.
-          They are VOIDmode and Pmode, respectively.  */
-       if (TREE_CODE (t) == NOP_EXPR)
-         t = TREE_OPERAND (t, 0);
+       t = get_copy_ctor (type);
 
-      TREE_VEC_ELT (info, 0) = get_callee_fndecl (t);
+      if (t && !trivial_fn_p (t))
+       TREE_VEC_ELT (info, 0) = t;
     }
 
   if ((need_default_ctor || need_copy_ctor)
       && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-    {
-      t = build_int_cst (build_pointer_type (type), 0);
-      t = build1 (INDIRECT_REF, type, t);
-      t = build_special_member_call (t, complete_dtor_identifier,
-                                    NULL, type, LOOKUP_NORMAL,
-                                    tf_warning_or_error);
-
-      if (targetm.cxx.cdtor_returns_this () || errorcount)
-       /* Because constructors and destructors return this,
-          the call will have been cast to "void".  Remove the
-          cast here.  We would like to use STRIP_NOPS, but it
-          wouldn't work here because TYPE_MODE (t) and
-          TYPE_MODE (TREE_OPERAND (t, 0)) are different.
-          They are VOIDmode and Pmode, respectively.  */
-       if (TREE_CODE (t) == NOP_EXPR)
-         t = TREE_OPERAND (t, 0);
-
-      TREE_VEC_ELT (info, 1) = omp_clause_info_fndecl (t, type);
-    }
+    TREE_VEC_ELT (info, 1) = get_dtor (type);
 
-  if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type))
+  if (need_copy_assignment)
     {
-      VEC(tree,gc) *vec;
+      t = get_copy_assign (type);
 
-      t = build_int_cst (build_pointer_type (type), 0);
-      t = build1 (INDIRECT_REF, type, t);
-      vec = make_tree_vector_single (t);
-      t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
-                                    &vec, type, LOOKUP_NORMAL,
-                                    tf_warning_or_error);
-      release_tree_vector (vec);
-
-      /* We'll have called convert_from_reference on the call, which
-        may well have added an indirect_ref.  It's unneeded here,
-        and in the way, so kill it.  */
-      if (TREE_CODE (t) == INDIRECT_REF)
-       t = TREE_OPERAND (t, 0);
-
-      TREE_VEC_ELT (info, 2) = omp_clause_info_fndecl (t, type);
+      if (t && !trivial_fn_p (t))
+       TREE_VEC_ELT (info, 2) = t;
     }
 
   return errorcount != save_errorcount;
@@ -3984,7 +4118,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
     }
   if (cond == error_mark_node)
     {
-      error ("%Hinvalid controlling predicate", &elocus);
+      error_at (elocus, "invalid controlling predicate");
       return true;
     }
   diff = build_x_binary_op (MINUS_EXPR, TREE_OPERAND (cond, 1),
@@ -3994,8 +4128,8 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
     return true;
   if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
     {
-      error ("%Hdifference between %qE and %qD does not have integer type",
-            &elocus, TREE_OPERAND (cond, 1), iter);
+      error_at (elocus, "difference between %qE and %qD does not have integer type",
+               TREE_OPERAND (cond, 1), iter);
       return true;
     }
 
@@ -4089,7 +4223,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
 
   if (incr == error_mark_node)
     {
-      error ("%Hinvalid increment expression", &elocus);
+      error_at (elocus, "invalid increment expression");
       return true;
     }
 
@@ -4216,8 +4350,8 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
 
          if (decl == NULL)
            {
-             error ("%Hexpected iteration declaration or initialization",
-                    &locus);
+             error_at (locus,
+                       "expected iteration declaration or initialization");
              return NULL;
            }
        }
@@ -4227,13 +4361,13 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
 
       if (cond == NULL)
        {
-         error ("%Hmissing controlling predicate", &elocus);
+         error_at (elocus, "missing controlling predicate");
          return NULL;
        }
 
       if (incr == NULL)
        {
-         error ("%Hmissing increment expression", &elocus);
+         error_at (elocus, "missing increment expression");
          return NULL;
        }
 
@@ -4287,8 +4421,7 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
 
       if (!DECL_P (decl))
        {
-         error ("%Hexpected iteration declaration or initialization",
-                &elocus);
+         error_at (elocus, "expected iteration declaration or initialization");
          return NULL;
        }
 
@@ -4313,7 +4446,7 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
       if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
          && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
        {
-         error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
+         error_at (elocus, "invalid type for iteration variable %qE", decl);
          return NULL;
        }
 
@@ -4509,6 +4642,7 @@ finish_static_assert (tree condition, tree message, location_t location,
   /* Fold the expression and convert it to a boolean value. */
   condition = fold_non_dependent_expr (condition);
   condition = cp_convert (boolean_type_node, condition);
+  condition = maybe_constant_value (condition);
 
   if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
     /* Do nothing; the condition is satisfied. */
@@ -4523,32 +4657,29 @@ finish_static_assert (tree condition, tree message, location_t location,
         /* Report the error. */
         error ("static assertion failed: %E", message);
       else if (condition && condition != error_mark_node)
-        error ("non-constant condition for static assertion");
+       {
+         error ("non-constant condition for static assertion");
+         cxx_constant_value (condition);
+       }
       input_location = saved_loc;
     }
 }
 \f
-/* Returns decltype((EXPR)) for cases where we can drop the decltype and
-   just return the type even though EXPR is a type-dependent expression.
-   The ABI specifies which cases this applies to, which is a subset of the
-   possible cases.  */
+/* Returns the type of EXPR for cases where we can determine it even though
+   EXPR is a type-dependent expression.  */
 
 tree
 describable_type (tree expr)
 {
   tree type = NULL_TREE;
 
-  /* processing_template_decl isn't set when we're called from the mangling
-     code, so bump it now.  */
-  ++processing_template_decl;
   if (! type_dependent_expression_p (expr)
       && ! type_unknown_p (expr))
     {
-      type = TREE_TYPE (expr);
+      type = unlowered_expr_type (expr);
       if (real_lvalue_p (expr))
        type = build_reference_type (type);
     }
-  --processing_template_decl;
 
   if (type)
     return type;
@@ -4559,8 +4690,7 @@ describable_type (tree expr)
     case PARM_DECL:
     case RESULT_DECL:
     case FUNCTION_DECL:
-      /* Named rvalue reference becomes lvalue.  */
-      type = build_reference_type (non_reference (TREE_TYPE (expr)));
+      return TREE_TYPE (expr);
       break;
 
     case NEW_EXPR:
@@ -4619,7 +4749,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       return error_mark_node;
     }
 
-  if (type_dependent_expression_p (expr))
+  if (type_dependent_expression_p (expr)
+      /* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
+        if it isn't dependent, so that we can check access control at
+        instantiation time, so defer the decltype as well (PR 42277).  */
+      || (id_expression_or_member_access_p
+         && processing_template_decl
+         && TREE_CODE (expr) == COMPONENT_REF))
     {
       if (id_expression_or_member_access_p)
        {
@@ -4642,6 +4778,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       if (type && !type_uses_auto (type))
        return type;
 
+    treat_as_dependent:
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
       DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
@@ -4653,6 +4790,15 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
 
   /* The type denoted by decltype(e) is defined as follows:  */
 
+  expr = resolve_nondeduced_context (expr);
+
+  /* To get the size of a static data member declared as an array of
+     unknown bound, we need to instantiate it.  */
+  if (TREE_CODE (expr) == VAR_DECL
+      && VAR_HAD_UNKNOWN_BOUND (expr)
+      && DECL_TEMPLATE_INSTANTIATION (expr))
+    instantiate_decl (expr, /*defer_ok*/true, /*expl_inst_mem*/false);
+
   if (id_expression_or_member_access_p)
     {
       /* If e is an id-expression or a class member access (5.2.5
@@ -4678,9 +4824,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         /* See through BASELINK nodes to the underlying functions.  */
         expr = BASELINK_FUNCTIONS (expr);
 
+      if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
+       expr = TREE_OPERAND (expr, 0);
+
       if (TREE_CODE (expr) == OVERLOAD)
         {
-          if (OVL_CHAIN (expr))
+          if (OVL_CHAIN (expr)
+             || TREE_CODE (OVL_FUNCTION (expr)) == TEMPLATE_DECL)
             {
               error ("%qE refers to a set of overloaded functions", orig_expr);
               return error_mark_node;
@@ -4707,6 +4857,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         case PARM_DECL:
         case RESULT_DECL:
         case TEMPLATE_PARM_INDEX:
+         expr = mark_type_use (expr);
           type = TREE_TYPE (expr);
           break;
 
@@ -4715,6 +4866,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
           break;
 
         case COMPONENT_REF:
+         mark_type_use (expr);
           type = is_bitfield_expr_with_lowered_type (expr);
           if (!type)
             type = TREE_TYPE (TREE_OPERAND (expr, 1));
@@ -4764,6 +4916,11 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
                   && (TREE_CODE (TREE_TYPE (target_type)) == FUNCTION_TYPE
                       || TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE))
                 type = TREE_TYPE (TREE_TYPE (target_type));
+             else if (processing_template_decl)
+               /* Within a template finish_call_expr doesn't resolve
+                  CALL_EXPR_FN, so even though this decltype isn't really
+                  dependent let's defer resolving it.  */
+               goto treat_as_dependent;
               else
                 sorry ("unable to determine the declared type of expression %<%E%>",
                        expr);
@@ -4784,6 +4941,18 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
               if (real_lvalue_p (expr))
                 type = build_reference_type (type);
             }
+         /* Within a lambda-expression:
+
+            Every occurrence of decltype((x)) where x is a possibly
+            parenthesized id-expression that names an entity of
+            automatic storage duration is treated as if x were
+            transformed into an access to a corresponding data member
+            of the closure type that would have been declared if x
+            were a use of the denoted entity.  */
+         else if (outer_automatic_var_p (expr)
+                  && current_function_decl
+                  && LAMBDA_FUNCTION_P (current_function_decl))
+           type = capture_decltype (expr);
           else
             {
               /* Otherwise, where T is the type of e, if e is an lvalue,
@@ -4798,8 +4967,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
                 type = TYPE_MAIN_VARIANT (type);
               else if (real_lvalue_p (expr))
                 {
-                  if (TREE_CODE (type) != REFERENCE_TYPE)
-                    type = build_reference_type (type);
+                  if (TREE_CODE (type) != REFERENCE_TYPE
+                     || TYPE_REF_IS_RVALUE (type))
+                    type = build_reference_type (non_reference (type));
                 }
               else
                 type = non_reference (type);
@@ -4832,12 +5002,14 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
        return false;
       fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
     } 
-  else if (TYPE_HAS_INIT_REF (type))
+  else if (TYPE_HAS_COPY_CTOR (type))
     {
       /* If construction of the copy constructor was postponed, create
         it now.  */
       if (CLASSTYPE_LAZY_COPY_CTOR (type))
        lazily_declare_fn (sfk_copy_constructor, type);
+      if (CLASSTYPE_LAZY_MOVE_CTOR (type))
+       lazily_declare_fn (sfk_move_constructor, type);
       fns = CLASSTYPE_CONSTRUCTORS (type);
     }
   else
@@ -4875,6 +5047,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
   switch (kind)
     {
     case CPTK_HAS_NOTHROW_ASSIGN:
+      type1 = strip_array_types (type1);
       return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
              && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
                  || (CLASS_TYPE_P (type1)
@@ -4882,41 +5055,47 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
                                                                 true))));
 
     case CPTK_HAS_TRIVIAL_ASSIGN:
+      /* ??? The standard seems to be missing the "or array of such a class
+        type" wording for this trait.  */
+      type1 = strip_array_types (type1);
       return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
-             && (pod_type_p (type1)
+             && (trivial_type_p (type1)
                    || (CLASS_TYPE_P (type1)
-                       && TYPE_HAS_TRIVIAL_ASSIGN_REF (type1))));
+                       && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
 
     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
       type1 = strip_array_types (type1);
       return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) 
              || (CLASS_TYPE_P (type1)
-                 && (t = locate_ctor (type1, NULL))
+                 && (t = locate_ctor (type1))
                  && TYPE_NOTHROW_P (TREE_TYPE (t))));
 
     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
       type1 = strip_array_types (type1);
-      return (pod_type_p (type1)
+      return (trivial_type_p (type1)
              || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
 
     case CPTK_HAS_NOTHROW_COPY:
+      type1 = strip_array_types (type1);
       return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
              || (CLASS_TYPE_P (type1)
                  && classtype_has_nothrow_assign_or_copy_p (type1, false)));
 
     case CPTK_HAS_TRIVIAL_COPY:
-      return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
-             || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_INIT_REF (type1)));
+      /* ??? The standard seems to be missing the "or array of such a class
+        type" wording for this trait.  */
+      type1 = strip_array_types (type1);
+      return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
+             || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
 
     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
       type1 = strip_array_types (type1);
-      return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
+      return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
              || (CLASS_TYPE_P (type1)
                  && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
 
     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
-      return (CLASS_TYPE_P (type1)
-             && (t = locate_dtor (type1, NULL)) && DECL_VIRTUAL_P (t));
+      return type_has_virtual_destructor (type1);
 
     case CPTK_IS_ABSTRACT:
       return (CLASS_TYPE_P (type1) && CLASSTYPE_PURE_VIRTUALS (type1));
@@ -4944,9 +5123,18 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_POLYMORPHIC:
       return (CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1));
 
+    case CPTK_IS_STD_LAYOUT:
+      return (std_layout_type_p (type1));
+
+    case CPTK_IS_TRIVIAL:
+      return (trivial_type_p (type1));
+
     case CPTK_IS_UNION:
       return (type_code1 == UNION_TYPE);
 
+    case CPTK_IS_LITERAL_TYPE:
+      return (literal_type_p (type1));
+
     default:
       gcc_unreachable ();
       return false;
@@ -4962,7 +5150,8 @@ check_trait_type (tree type)
   if (COMPLETE_TYPE_P (type))
     return true;
 
-  if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
+  if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
+      && COMPLETE_TYPE_P (TREE_TYPE (type)))
     return true;
 
   if (VOID_TYPE_P (type))
@@ -4992,6 +5181,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
              || kind == CPTK_IS_ENUM
              || kind == CPTK_IS_POD
              || kind == CPTK_IS_POLYMORPHIC
+             || kind == CPTK_IS_STD_LAYOUT
+             || kind == CPTK_IS_TRIVIAL
+             || kind == CPTK_IS_LITERAL_TYPE
              || kind == CPTK_IS_UNION);
 
   if (kind == CPTK_IS_CONVERTIBLE_TO)
@@ -5033,6 +5225,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_EMPTY:
     case CPTK_IS_POD:
     case CPTK_IS_POLYMORPHIC:
+    case CPTK_IS_STD_LAYOUT:
+    case CPTK_IS_TRIVIAL:
+    case CPTK_IS_LITERAL_TYPE:
       if (!check_trait_type (type1))
        {
          error ("incomplete type %qT not allowed", type1);
@@ -5083,4 +5278,2821 @@ float_const_decimal64_p (void)
   return 0;
 }
 
+\f
+/* Return true if T is a literal type.   */
+
+bool
+literal_type_p (tree t)
+{
+  if (SCALAR_TYPE_P (t))
+    return true;
+  if (CLASS_TYPE_P (t))
+    return CLASSTYPE_LITERAL_P (t);
+  if (TREE_CODE (t) == ARRAY_TYPE)
+    return literal_type_p (strip_array_types (t));
+  return false;
+}
+
+/* If DECL is a variable declared `constexpr', require its type
+   be literal.  Return the DECL if OK, otherwise NULL.  */
+
+tree
+ensure_literal_type_for_constexpr_object (tree decl)
+{
+  tree type = TREE_TYPE (decl);
+  if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl)
+      && !processing_template_decl
+      /* The call to complete_type is just for initializer_list.  */
+      && !literal_type_p (complete_type (type)))
+    {
+      error ("the type %qT of constexpr variable %qD is not literal",
+             type, decl);
+      return NULL;
+    }
+  return decl;
+}
+
+/* Representation of entries in the constexpr function definition table.  */
+
+typedef struct GTY(()) constexpr_fundef {
+  tree decl;
+  tree body;
+} constexpr_fundef;
+
+/* This table holds all constexpr function definitions seen in
+   the current translation unit.  */
+
+static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table;
+
+static bool potential_constant_expression (tree, tsubst_flags_t);
+
+/* Utility function used for managing the constexpr function table.
+   Return true if the entries pointed to by P and Q are for the
+   same constexpr function.  */
+
+static inline int
+constexpr_fundef_equal (const void *p, const void *q)
+{
+  const constexpr_fundef *lhs = (const constexpr_fundef *) p;
+  const constexpr_fundef *rhs = (const constexpr_fundef *) q;
+  return lhs->decl == rhs->decl;
+}
+
+/* Utility function used for managing the constexpr function table.
+   Return a hash value for the entry pointed to by Q.  */
+
+static inline hashval_t
+constexpr_fundef_hash (const void *p)
+{
+  const constexpr_fundef *fundef = (const constexpr_fundef *) p;
+  return DECL_UID (fundef->decl);
+}
+
+/* Return a previously saved definition of function FUN.   */
+
+static constexpr_fundef *
+retrieve_constexpr_fundef (tree fun)
+{
+  constexpr_fundef fundef = { NULL, NULL };
+  if (constexpr_fundef_table == NULL)
+    return NULL;
+
+  fundef.decl = fun;
+  return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef);
+}
+
+/* Return true if type expression T is a valid parameter type, or
+   a valid return type, of a constexpr function.  */
+
+static bool
+valid_type_in_constexpr_fundecl_p (tree t)
+{
+  return (literal_type_p (t)
+         /* FIXME we allow ref to non-literal; should change standard to
+            match, or change back if not.  */
+         || TREE_CODE (t) == REFERENCE_TYPE);
+}
+
+/* Check whether the parameter and return types of FUN are valid for a
+   constexpr function, and complain if COMPLAIN.  */
+
+static bool
+is_valid_constexpr_fn (tree fun, bool complain)
+{
+  tree parm = FUNCTION_FIRST_USER_PARM (fun);
+  bool ret = true;
+  for (; parm != NULL; parm = TREE_CHAIN (parm))
+    if (!valid_type_in_constexpr_fundecl_p (TREE_TYPE (parm)))
+      {
+       ret = false;
+       if (complain)
+         error ("invalid type for parameter %q#D of constexpr function",
+                parm);
+      }
+
+  if (!DECL_CONSTRUCTOR_P (fun))
+    {
+      tree rettype = TREE_TYPE (TREE_TYPE (fun));
+      if (!valid_type_in_constexpr_fundecl_p (rettype))
+       {
+         ret = false;
+         if (complain)
+           error ("invalid return type %qT of constexpr function %qD",
+                  rettype, fun);
+       }
+
+      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
+         && COMPLETE_TYPE_P (DECL_CONTEXT (fun))
+         && !valid_type_in_constexpr_fundecl_p (DECL_CONTEXT (fun)))
+       {
+         ret = false;
+         if (complain)
+           error ("enclosing class of %q#D is not a literal type", fun);
+       }
+    }
+
+  return ret;
+}
+
+/* Return non-null if FUN certainly designates a valid constexpr function
+   declaration.  Otherwise return NULL.  Issue appropriate diagnostics
+   if necessary.  Note that we only check the declaration, not the body
+   of the function.  */
+
+tree
+validate_constexpr_fundecl (tree fun)
+{
+  constexpr_fundef entry;
+  constexpr_fundef **slot;
+
+  if (processing_template_decl || !DECL_DECLARED_CONSTEXPR_P (fun))
+    return NULL;
+  else if (DECL_CLONED_FUNCTION_P (fun))
+    /* We already checked the original function.  */
+    return fun;
+
+  if (!is_valid_constexpr_fn (fun, !DECL_TEMPLATE_INSTANTIATION (fun)))
+    {
+      DECL_DECLARED_CONSTEXPR_P (fun) = false;
+      return NULL;
+    }
+
+  /* Create the constexpr function table if necessary.  */
+  if (constexpr_fundef_table == NULL)
+    constexpr_fundef_table = htab_create_ggc (101,
+                                              constexpr_fundef_hash,
+                                              constexpr_fundef_equal,
+                                              ggc_free);
+  entry.decl = fun;
+  entry.body = NULL;
+  slot = (constexpr_fundef **)
+    htab_find_slot (constexpr_fundef_table, &entry, INSERT);
+  if (*slot == NULL)
+    {
+      *slot = ggc_alloc_constexpr_fundef ();
+      **slot = entry;
+    }
+  return fun;
+}
+
+/* Subroutine of  build_constexpr_constructor_member_initializers.
+   The expression tree T represents a data member initialization
+   in a (constexpr) constructor definition.  Build a pairing of
+   the data member with its initializer, and prepend that pair
+   to the existing initialization pair INITS.  */
+
+static bool
+build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
+{
+  tree member, init;
+  if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
+    t = TREE_OPERAND (t, 0);
+  if (TREE_CODE (t) == EXPR_STMT)
+    t = TREE_OPERAND (t, 0);
+  if (t == error_mark_node)
+    return false;
+  if (TREE_CODE (t) == CLEANUP_STMT)
+    /* We can't see a CLEANUP_STMT in a constructor for a literal class,
+       but we can in a constexpr constructor for a non-literal class.  Just
+       ignore it; either all the initialization will be constant, in which
+       case the cleanup can't run, or it can't be constexpr.  */
+    return true;
+  if (TREE_CODE (t) == CONVERT_EXPR)
+    t = TREE_OPERAND (t, 0);
+  if (TREE_CODE (t) == INIT_EXPR
+      || TREE_CODE (t) == MODIFY_EXPR)
+    {
+      member = TREE_OPERAND (t, 0);
+      init = unshare_expr (TREE_OPERAND (t, 1));
+      if (TREE_CODE (member) == INDIRECT_REF)
+       {
+         /* Don't put out anything for value-init of an empty base.  */
+         gcc_assert (is_empty_class (TREE_TYPE (member)));
+         gcc_assert (TREE_CODE (init) == CONSTRUCTOR
+                     && CONSTRUCTOR_NELTS (init) == 0);
+         return true;
+       }
+    }
+  else
+    {
+      tree memtype;
+      gcc_assert (TREE_CODE (t) == CALL_EXPR);
+      member = CALL_EXPR_ARG (t, 0);
+      memtype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (member)));
+      if (TREE_CODE (member) == NOP_EXPR)
+       {
+         /* We don't put out anything for an empty base.  */
+         gcc_assert (is_empty_class (memtype));
+         /* But if the constructor used isn't constexpr, leave in the call
+            so we complain later.  */
+         if (potential_constant_expression (t, tf_none))
+           return true;
+       }
+      else
+       {
+         gcc_assert (TREE_CODE (member) == ADDR_EXPR);
+         member = TREE_OPERAND (member, 0);
+       }
+      /* We don't use build_cplus_new here because it complains about
+        abstract bases.  T has the wrong type, but
+        cxx_eval_constant_expression doesn't care.  */
+      init = unshare_expr (t);
+    }
+  if (TREE_CODE (member) == COMPONENT_REF)
+    member = TREE_OPERAND (member, 1);
+  CONSTRUCTOR_APPEND_ELT (*vec, member, init);
+  return true;
+}
+
+/* Build compile-time evalable representations of member-initializer list
+   for a constexpr constructor.  */
+
+static tree
+build_constexpr_constructor_member_initializers (tree type, tree body)
+{
+  VEC(constructor_elt,gc) *vec = NULL;
+  bool ok = true;
+  if (TREE_CODE (body) == MUST_NOT_THROW_EXPR
+      || TREE_CODE (body) == EH_SPEC_BLOCK)
+    body = TREE_OPERAND (body, 0);
+  if (TREE_CODE (body) == BIND_EXPR)
+    body = BIND_EXPR_BODY (body);
+  if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
+    ok = build_data_member_initialization (body, &vec);
+  else if (TREE_CODE (body) == STATEMENT_LIST)
+    {
+      tree_stmt_iterator i;
+      for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
+       {
+         ok = build_data_member_initialization (tsi_stmt (i), &vec);
+         if (!ok)
+           break;
+       }
+    }
+  else
+    gcc_assert (errorcount > 0);
+  if (ok)
+    return build_constructor (type, vec);
+  else
+    return error_mark_node;
+}
+
+/* We are processing the definition of the constexpr function FUN.
+   Check that its BODY fulfills the propriate requirements and
+   enter it in the constexpr function definition table.
+   For constructor BODY is actually the TREE_LIST of the
+   member-initializer list.  */
+
+tree
+register_constexpr_fundef (tree fun, tree body)
+{
+  constexpr_fundef *fundef = retrieve_constexpr_fundef (fun);
+  gcc_assert (fundef != NULL && fundef->body == NULL);
+
+  if (DECL_CONSTRUCTOR_P (fun))
+    body = build_constexpr_constructor_member_initializers
+      (DECL_CONTEXT (fun), body);
+  else
+    {
+      if (TREE_CODE (body) == BIND_EXPR)
+       body = BIND_EXPR_BODY (body);
+      if (TREE_CODE (body) == EH_SPEC_BLOCK)
+        body = EH_SPEC_STMTS (body);
+      if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+       body = TREE_OPERAND (body, 0);
+      if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
+        body = TREE_OPERAND (body, 0);
+      if (TREE_CODE (body) != RETURN_EXPR)
+        {
+          error ("body of constexpr function %qD not a return-statement", fun);
+          DECL_DECLARED_CONSTEXPR_P (fun) = false;
+          return NULL;
+        }
+      body = unshare_expr (TREE_OPERAND (body, 0));
+    }
+
+  if (!potential_constant_expression (body, (DECL_TEMPLATE_INSTANTIATION (fun)
+                                            ? tf_none : tf_error)))
+    {
+      DECL_DECLARED_CONSTEXPR_P (fun) = false;
+      return NULL;
+    }
+  fundef->body = body;
+  return fun;
+}
+
+/* Objects of this type represent calls to constexpr functions
+   along with the bindings of parameters to their arguments, for
+   the purpose of compile time evaluation.  */
+
+typedef struct GTY(()) constexpr_call {
+  /* Description of the constexpr function definition.  */
+  constexpr_fundef *fundef;
+  /* Parameter bindings enironment.  A TREE_LIST where each TREE_PURPOSE
+     is a parameter _DECL and the TREE_VALUE is the value of the parameter.
+     Note: This arrangement is made to accomodate the use of
+     iterative_hash_template_arg (see pt.c).  If you change this
+     representation, also change the hash calculation in
+     cxx_eval_call_expression.  */
+  tree bindings;
+  /* Result of the call.
+       NULL means the call is being evaluated.
+       error_mark_node means that the evaluation was erroneous;
+       otherwise, the actuall value of the call.  */
+  tree result;
+  /* The hash of this call; we remember it here to avoid having to
+     recalculate it when expanding the hash table.  */
+  hashval_t hash;
+} constexpr_call;
+
+/* A table of all constexpr calls that have been evaluated by the
+   compiler in this translation unit.  */
+
+static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table;
+
+static tree cxx_eval_constant_expression (const constexpr_call *, tree,
+                                         bool, bool, bool *);
+
+/* Compute a hash value for a constexpr call representation.  */
+
+static hashval_t
+constexpr_call_hash (const void *p)
+{
+  const constexpr_call *info = (const constexpr_call *) p;
+  return info->hash;
+}
+
+/* Return 1 if the objects pointed to by P and Q represent calls
+   to the same constexpr function with the same arguments.
+   Otherwise, return 0.  */
+
+static int
+constexpr_call_equal (const void *p, const void *q)
+{
+  const constexpr_call *lhs = (const constexpr_call *) p;
+  const constexpr_call *rhs = (const constexpr_call *) q;
+  tree lhs_bindings;
+  tree rhs_bindings;
+  if (lhs == rhs)
+    return 1;
+  if (!constexpr_fundef_equal (lhs->fundef, rhs->fundef))
+    return 0;
+  lhs_bindings = lhs->bindings;
+  rhs_bindings = rhs->bindings;
+  while (lhs_bindings != NULL && rhs_bindings != NULL)
+    {
+      tree lhs_arg = TREE_VALUE (lhs_bindings);
+      tree rhs_arg = TREE_VALUE (rhs_bindings);
+      gcc_assert (TREE_TYPE (lhs_arg) == TREE_TYPE (rhs_arg));
+      if (!cp_tree_equal (lhs_arg, rhs_arg))
+        return 0;
+      lhs_bindings = TREE_CHAIN (lhs_bindings);
+      rhs_bindings = TREE_CHAIN (rhs_bindings);
+    }
+  return lhs_bindings == rhs_bindings;
+}
+
+/* Initialize the constexpr call table, if needed.  */
+
+static void
+maybe_initialize_constexpr_call_table (void)
+{
+  if (constexpr_call_table == NULL)
+    constexpr_call_table = htab_create_ggc (101,
+                                            constexpr_call_hash,
+                                            constexpr_call_equal,
+                                            ggc_free);
+}
+
+/* Return true if T designates the implied `this' parameter.  */
+
+static inline bool
+is_this_parameter (tree t)
+{
+  return t == current_class_ptr;
+}
+
+/* We have an expression tree T that represents a call, either CALL_EXPR
+   or AGGR_INIT_EXPR.  If the call is lexically to a named function,
+   retrun the _DECL for that function.  */
+
+static tree
+get_function_named_in_call (tree t)
+{
+  tree fun = NULL;
+  switch (TREE_CODE (t))
+    {
+    case CALL_EXPR:
+      fun = CALL_EXPR_FN (t);
+      break;
+
+    case AGGR_INIT_EXPR:
+      fun = AGGR_INIT_EXPR_FN (t);
+      break;
+
+    default:
+      gcc_unreachable();
+      break;
+    }
+  if (TREE_CODE (fun) == ADDR_EXPR
+      && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
+    fun = TREE_OPERAND (fun, 0);
+  return fun;
+}
+
+/* We have an expression tree T that represents a call, either CALL_EXPR
+   or AGGR_INIT_EXPR.  Return the Nth argument.  */
+
+static inline tree
+get_nth_callarg (tree t, int n)
+{
+  switch (TREE_CODE (t))
+    {
+    case CALL_EXPR:
+      return CALL_EXPR_ARG (t, n);
+
+    case AGGR_INIT_EXPR:
+      return AGGR_INIT_EXPR_ARG (t, n);
+
+    default:
+      gcc_unreachable ();
+      return NULL;
+    }
+}
+
+/* Look up the binding of the function parameter T in a constexpr
+   function call context CALL.  */
+
+static tree
+lookup_parameter_binding (const constexpr_call *call, tree t)
+{
+  tree b = purpose_member (t, call->bindings);
+  return TREE_VALUE (b);
+}
+
+/* Attempt to evaluate T which represents a call to a builtin function.
+   We assume here that all builtin functions evaluate to scalar types
+   represented by _CST nodes.  */
+
+static tree
+cxx_eval_builtin_function_call (const constexpr_call *call, tree t,
+                               bool allow_non_constant, bool addr,
+                               bool *non_constant_p)
+{
+  const int nargs = call_expr_nargs (t);
+  tree *args = (tree *) alloca (nargs * sizeof (tree));
+  tree new_call;
+  int i;
+  for (i = 0; i < nargs; ++i)
+    {
+      args[i] = cxx_eval_constant_expression (call, CALL_EXPR_ARG (t, i),
+                                             allow_non_constant, addr,
+                                             non_constant_p);
+      if (allow_non_constant && *non_constant_p)
+       return t;
+    }
+  if (*non_constant_p)
+    return t;
+  new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
+                                   CALL_EXPR_FN (t), nargs, args);
+  return fold (new_call);
+}
+
+/* TEMP is the constant value of a temporary object of type TYPE.  Adjust
+   the type of the value to match.  */
+
+static tree
+adjust_temp_type (tree type, tree temp)
+{
+  if (TREE_TYPE (temp) == type)
+    return temp;
+  /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
+  if (TREE_CODE (temp) == CONSTRUCTOR)
+    return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+  gcc_assert (SCALAR_TYPE_P (type));
+  return fold_convert (type, temp);
+}
+
+/* Subroutine of cxx_eval_call_expression.
+   We are processing a call expression (either CALL_EXPR or
+   AGGR_INIT_EXPR) in the call context of OLD_CALL.  Evaluate
+   all arguments and bind their values to correspondings
+   parameters, making up the NEW_CALL context.  */
+
+static void
+cxx_bind_parameters_in_call (const constexpr_call *old_call, tree t,
+                             constexpr_call *new_call,
+                            bool allow_non_constant,
+                            bool *non_constant_p)
+{
+  const int nargs = call_expr_nargs (t);
+  tree fun = new_call->fundef->decl;
+  tree parms = DECL_ARGUMENTS (fun);
+  int i;
+  for (i = 0; i < nargs; ++i)
+    {
+      tree x, arg;
+      tree type = parms ? TREE_TYPE (parms) : void_type_node;
+      /* For member function, the first argument is a pointer to the implied
+         object.  And for an object contruction, don't bind `this' before
+         it is fully constructed.  */
+      if (i == 0 && DECL_CONSTRUCTOR_P (fun))
+        goto next;
+      x = get_nth_callarg (t, i);
+      arg = cxx_eval_constant_expression (old_call, x, allow_non_constant,
+                                         TREE_CODE (type) == REFERENCE_TYPE,
+                                         non_constant_p);
+      /* Don't VERIFY_CONSTANT here.  */
+      if (*non_constant_p && allow_non_constant)
+       return;
+      /* Just discard ellipsis args after checking their constantitude.  */
+      if (!parms)
+       continue;
+
+      /* Make sure the binding has the same type as the parm.  */
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       arg = adjust_temp_type (type, arg);
+      new_call->bindings = tree_cons (parms, arg, new_call->bindings);
+    next:
+      parms = TREE_CHAIN (parms);
+    }
+}
+
+/* Variables and functions to manage constexpr call expansion context.
+   These do not need to be marked for PCH or GC.  */
+
+static VEC(tree,heap) *call_stack = NULL;
+static int call_stack_tick;
+static int last_cx_error_tick;
+
+static void
+push_cx_call_context (tree call)
+{
+  ++call_stack_tick;
+  if (!EXPR_HAS_LOCATION (call))
+    SET_EXPR_LOCATION (call, input_location);
+  VEC_safe_push (tree, heap, call_stack, call);
+}
+
+static void
+pop_cx_call_context (void)
+{
+  ++call_stack_tick;
+  VEC_pop (tree, call_stack);
+}
+
+VEC(tree,heap) *
+cx_error_context (void)
+{
+  VEC(tree,heap) *r = NULL;
+  if (call_stack_tick != last_cx_error_tick
+      && !VEC_empty (tree, call_stack))
+    r = call_stack;
+  last_cx_error_tick = call_stack_tick;
+  return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Evaluate the call expression tree T in the context of OLD_CALL expression
+   evaluation.  */
+
+static tree
+cxx_eval_call_expression (const constexpr_call *old_call, tree t,
+                         bool allow_non_constant, bool addr,
+                         bool *non_constant_p)
+{
+  location_t loc = EXPR_LOC_OR_HERE (t);
+  tree fun = get_function_named_in_call (t);
+  tree result;
+  constexpr_call new_call = { NULL, NULL, NULL, 0 };
+  constexpr_call **slot;
+  if (TREE_CODE (fun) != FUNCTION_DECL)
+    {
+      /* Might be a constexpr function pointer.  */
+      fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant,
+                                         /*addr*/false, non_constant_p);
+      if (TREE_CODE (fun) == ADDR_EXPR)
+       fun = TREE_OPERAND (fun, 0);
+    }
+  if (TREE_CODE (fun) != FUNCTION_DECL)
+    {
+      if (!allow_non_constant)
+       error_at (loc, "expression %qE does not designate a constexpr "
+                 "function", fun);
+      *non_constant_p = true;
+      return t;
+    }
+  if (DECL_CLONED_FUNCTION_P (fun))
+    fun = DECL_CLONED_FUNCTION (fun);
+  if (is_builtin_fn (fun))
+    return cxx_eval_builtin_function_call (old_call, t, allow_non_constant,
+                                          addr, non_constant_p);
+  if (!DECL_DECLARED_CONSTEXPR_P (fun))
+    {
+      if (!allow_non_constant)
+       {
+         error_at (loc, "%qD is not a constexpr function", fun);
+         if (DECL_TEMPLATE_INSTANTIATION (fun)
+             && DECL_DECLARED_CONSTEXPR_P (DECL_TEMPLATE_RESULT
+                                           (DECL_TI_TEMPLATE (fun))))
+           is_valid_constexpr_fn (fun, true);
+       }
+      *non_constant_p = true;
+      return t;
+    }
+
+  /* If in direct recursive call, optimize definition search.  */
+  if (old_call != NULL && old_call->fundef->decl == fun)
+    new_call.fundef = old_call->fundef;
+  else
+    {
+      new_call.fundef = retrieve_constexpr_fundef (fun);
+      if (new_call.fundef == NULL || new_call.fundef->body == NULL)
+        {
+         if (!allow_non_constant)
+           error_at (loc, "%qD used before its definition", fun);
+         *non_constant_p = true;
+          return t;
+        }
+    }
+  cxx_bind_parameters_in_call (old_call, t, &new_call,
+                              allow_non_constant, non_constant_p);
+  if (*non_constant_p)
+    return t;
+
+  push_cx_call_context (t);
+
+  new_call.hash
+    = iterative_hash_template_arg (new_call.bindings,
+                                  constexpr_fundef_hash (new_call.fundef));
+
+  /* If we have seen this call before, we are done.  */
+  maybe_initialize_constexpr_call_table ();
+  slot = (constexpr_call **)
+    htab_find_slot (constexpr_call_table, &new_call, INSERT);
+  if (*slot != NULL)
+    {
+      /* Calls which are in progress have their result set to NULL
+         so that we can detect circular dependencies.  */
+      if ((*slot)->result == NULL)
+        {
+         if (!allow_non_constant)
+           error ("call has circular dependency");
+         (*slot)->result = result = error_mark_node;
+        }
+      else
+       {
+         result = (*slot)->result;
+         if (result == error_mark_node && !allow_non_constant)
+           /* Re-evaluate to get the error.  */
+           cxx_eval_constant_expression (&new_call, new_call.fundef->body,
+                                         allow_non_constant, addr,
+                                         non_constant_p);
+       }
+    }
+  else
+    {
+      /* We need to keep a pointer to the entry, not just the slot, as the
+        slot can move in the call to cxx_eval_builtin_function_call.  */
+      constexpr_call *entry = ggc_alloc_constexpr_call ();
+      *entry = new_call;
+      *slot = entry;
+      result
+       = cxx_eval_constant_expression (&new_call, new_call.fundef->body,
+                                       allow_non_constant, addr,
+                                       non_constant_p);
+      if (*non_constant_p)
+       entry->result = result = error_mark_node;
+      else
+       {
+         /* If this was a call to initialize an object, set the type of
+            the CONSTRUCTOR to the type of that object.  */
+         if (DECL_CONSTRUCTOR_P (fun))
+           {
+             tree ob_arg = get_nth_callarg (t, 0);
+             STRIP_NOPS (ob_arg);
+             gcc_assert (TREE_CODE (TREE_TYPE (ob_arg)) == POINTER_TYPE
+                         && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (ob_arg))));
+             result = adjust_temp_type (TREE_TYPE (TREE_TYPE (ob_arg)),
+                                        result);
+           }
+         entry->result = result;
+       }
+    }
+
+  pop_cx_call_context ();
+  return result;
+}
+
+bool
+reduced_constant_expression_p (tree t)
+{
+  /* FIXME speed this up, it's taking 16% of compile time on sieve testcase.  */
+  if (cxx_dialect >= cxx0x && TREE_OVERFLOW_P (t))
+    /* In C++0x, integer overflow makes this not a constant expression.
+       FIXME arithmetic overflow is different from conversion truncation */
+    return false;
+  /* FIXME are we calling this too much?  */
+  return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+}
+
+/* Some expressions may have constant operands but are not constant
+   themselves, such as 1/0.  Call this function (or rather, the macro
+   following it) to check for that condition.
+
+   We only call this in places that require an arithmetic constant, not in
+   places where we might have a non-constant expression that can be a
+   component of a constant expression, such as the address of a constexpr
+   variable that might be dereferenced later.  */
+
+static bool
+verify_constant (tree t, bool allow_non_constant, bool *non_constant_p)
+{
+  if (!*non_constant_p && !reduced_constant_expression_p (t))
+    {
+      if (!allow_non_constant)
+       error ("%qE is not a constant expression", t);
+      *non_constant_p = true;
+    }
+  return *non_constant_p;
+}
+#define VERIFY_CONSTANT(X)                                             \
+do {                                                                   \
+  if (verify_constant ((X), allow_non_constant, non_constant_p))       \
+    return t;                                                          \
+ } while (0)
+
+/* Subroutine of cxx_eval_constant_expression.
+   Attempt to reduce the unary expression tree T to a compile time value.
+   If successful, return the value.  Otherwise issue a diagnostic
+   and return error_mark_node.  */
+
+static tree
+cxx_eval_unary_expression (const constexpr_call *call, tree t,
+                          bool allow_non_constant, bool addr,
+                          bool *non_constant_p)
+{
+  tree r;
+  tree orig_arg = TREE_OPERAND (t, 0);
+  tree arg = cxx_eval_constant_expression (call, orig_arg, allow_non_constant,
+                                          addr, non_constant_p);
+  VERIFY_CONSTANT (arg);
+  if (arg == orig_arg)
+    return t;
+  r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), arg);
+  VERIFY_CONSTANT (r);
+  return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Like cxx_eval_unary_expression, except for binary expressions.  */
+
+static tree
+cxx_eval_binary_expression (const constexpr_call *call, tree t,
+                           bool allow_non_constant, bool addr,
+                           bool *non_constant_p)
+{
+  tree r;
+  tree orig_lhs = TREE_OPERAND (t, 0);
+  tree orig_rhs = TREE_OPERAND (t, 1);
+  tree lhs, rhs;
+  lhs = cxx_eval_constant_expression (call, orig_lhs,
+                                     allow_non_constant, addr,
+                                     non_constant_p);
+  VERIFY_CONSTANT (lhs);
+  rhs = cxx_eval_constant_expression (call, orig_rhs,
+                                     allow_non_constant, addr,
+                                     non_constant_p);
+  VERIFY_CONSTANT (rhs);
+  if (lhs == orig_lhs && rhs == orig_rhs)
+    return t;
+  r = fold_build2 (TREE_CODE (t), TREE_TYPE (t), lhs, rhs);
+  VERIFY_CONSTANT (r);
+  return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Attempt to evaluate condition expressions.  Dead branches are not
+   looked into.  */
+
+static tree
+cxx_eval_conditional_expression (const constexpr_call *call, tree t,
+                                bool allow_non_constant, bool addr,
+                                bool *non_constant_p)
+{
+  tree val = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+                                          allow_non_constant, addr,
+                                          non_constant_p);
+  VERIFY_CONSTANT (val);
+  if (val == boolean_true_node)
+    return cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+                                        allow_non_constant, addr,
+                                        non_constant_p);
+  gcc_assert (val == boolean_false_node);
+  /* Don't VERIFY_CONSTANT here.  */
+  return cxx_eval_constant_expression (call, TREE_OPERAND (t, 2),
+                                      allow_non_constant, addr,
+                                      non_constant_p);
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Attempt to reduce a reference to an array slot.  */
+
+static tree
+cxx_eval_array_reference (const constexpr_call *call, tree t,
+                         bool allow_non_constant, bool addr,
+                         bool *non_constant_p)
+{
+  tree oldary = TREE_OPERAND (t, 0);
+  tree ary = cxx_eval_constant_expression (call, oldary,
+                                          allow_non_constant, addr,
+                                          non_constant_p);
+  tree index, oldidx;
+  HOST_WIDE_INT i;
+  unsigned len;
+  if (*non_constant_p)
+    return t;
+  oldidx = TREE_OPERAND (t, 1);
+  index = cxx_eval_constant_expression (call, oldidx,
+                                       allow_non_constant, false,
+                                       non_constant_p);
+  VERIFY_CONSTANT (index);
+  if (addr && ary == oldary && index == oldidx)
+    return t;
+  else if (addr)
+    return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
+  len = (TREE_CODE (ary) == CONSTRUCTOR
+        ? CONSTRUCTOR_NELTS (ary)
+        : (unsigned)TREE_STRING_LENGTH (ary));
+  if (compare_tree_int (index, len) >= 0)
+    {
+      if (!allow_non_constant)
+       error ("array subscript out of bound");
+      *non_constant_p = true;
+      return t;
+    }
+  i = tree_low_cst (index, 0);
+  if (TREE_CODE (ary) == CONSTRUCTOR)
+    return VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ary), i)->value;
+  else
+    return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
+                         TREE_STRING_POINTER (ary)[i]);
+  /* Don't VERIFY_CONSTANT here.  */
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Attempt to reduce a field access of a value of class type.  */
+
+static tree
+cxx_eval_component_reference (const constexpr_call *call, tree t,
+                             bool allow_non_constant, bool addr,
+                             bool *non_constant_p)
+{
+  unsigned HOST_WIDE_INT i;
+  tree field;
+  tree value;
+  tree part = TREE_OPERAND (t, 1);
+  tree orig_whole = TREE_OPERAND (t, 0);
+  tree whole = cxx_eval_constant_expression (call, orig_whole,
+                                            allow_non_constant, addr,
+                                            non_constant_p);
+  if (whole == orig_whole)
+    return t;
+  if (addr)
+    return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
+                       whole, part, NULL_TREE);
+  /* Don't VERIFY_CONSTANT here; we only want to check that we got a
+     CONSTRUCTOR.  */
+  if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
+    {
+      if (!allow_non_constant)
+       error ("%qE is not a constant expression", orig_whole);
+      *non_constant_p = true;
+    }
+  if (*non_constant_p)
+    return t;
+  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
+    {
+      if (field == part)
+        return value;
+    }
+  if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
+    {
+      /* FIXME Mike Miller wants this to be OK.  */
+      if (!allow_non_constant)
+       error ("accessing %qD member instead of initialized %qD member in "
+              "constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
+      *non_constant_p = true;
+      return t;
+    }
+  gcc_unreachable();
+  return error_mark_node;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   Evaluate a short-circuited logical expression T in the context
+   of a given constexpr CALL.  BAILOUT_VALUE is the value for
+   early return.  CONTINUE_VALUE is used here purely for
+   sanity check purposes.  */
+
+static tree
+cxx_eval_logical_expression (const constexpr_call *call, tree t,
+                             tree bailout_value, tree continue_value,
+                            bool allow_non_constant, bool addr,
+                            bool *non_constant_p)
+{
+  tree r;
+  tree lhs = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+                                          allow_non_constant, addr,
+                                          non_constant_p);
+  VERIFY_CONSTANT (lhs);
+  if (lhs == bailout_value)
+    return lhs;
+  gcc_assert (lhs == continue_value);
+  r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+                                   allow_non_constant, addr, non_constant_p);
+  VERIFY_CONSTANT (r);
+  return r;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   The expression tree T denotes a C-style array or a C-style
+   aggregate.  Reduce it to a constant expression.  */
+
+static tree
+cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
+                        bool allow_non_constant, bool addr,
+                        bool *non_constant_p)
+{
+  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (t);
+  VEC(constructor_elt,gc) *n = VEC_alloc (constructor_elt, gc,
+                                         VEC_length (constructor_elt, v));
+  constructor_elt *ce;
+  HOST_WIDE_INT i;
+  bool changed = false;
+  tree type = TREE_TYPE (t);
+  gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
+  for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
+    {
+      tree elt = cxx_eval_constant_expression (call, ce->value,
+                                              allow_non_constant, addr,
+                                              non_constant_p);
+      /* Don't VERIFY_CONSTANT here.  */
+      if (allow_non_constant && *non_constant_p)
+       goto fail;
+      if (elt != ce->value)
+       changed = true;
+      if (TREE_CODE (type) != ARRAY_TYPE
+         && !(same_type_ignoring_top_level_qualifiers_p
+              (DECL_CONTEXT (ce->index), type)))
+       {
+         /* Push our vtable pointer down into the base where it belongs.  */
+         tree vptr_base = DECL_CONTEXT (ce->index);
+         tree base_ctor;
+         gcc_assert (ce->index == TYPE_VFIELD (type));
+         for (base_ctor = VEC_index (constructor_elt, n, 0)->value; ;
+              base_ctor = CONSTRUCTOR_ELT (base_ctor, 0)->value)
+           if (TREE_TYPE (base_ctor) == vptr_base)
+             {
+               constructor_elt *p = CONSTRUCTOR_ELT (base_ctor, 0);
+               gcc_assert (p->index == ce->index);
+               p->value = elt;
+               break;
+             }
+       }
+      else
+       CONSTRUCTOR_APPEND_ELT (n, ce->index, elt);
+    }
+  if (*non_constant_p || !changed)
+    {
+    fail:
+      VEC_free (constructor_elt, gc, n);
+      return t;
+    }
+  t = build_constructor (TREE_TYPE (t), n);
+  TREE_CONSTANT (t) = true;
+  return t;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+   The expression tree T is a VEC_INIT_EXPR which denotes the desired
+   initialization of a non-static data member of array type.  Reduce it to a
+   CONSTRUCTOR.
+
+   Note that this is only intended to support the initializations done by
+   defaulted constructors for classes with non-static data members of array
+   type.  In this case, VEC_INIT_EXPR_INIT will either be NULL_TREE for the
+   default constructor, or a COMPONENT_REF for the copy/move
+   constructor.  */
+
+static tree
+cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
+                    bool allow_non_constant, bool addr,
+                    bool *non_constant_p)
+{
+  tree elttype = TREE_TYPE (atype);
+  int max = tree_low_cst (array_type_nelts (atype), 0);
+  VEC(constructor_elt,gc) *n = VEC_alloc (constructor_elt, gc, max + 1);
+  int i;
+
+  /* For the default constructor, build up a call to the default
+     constructor of the element type.  We only need to handle class types
+     here, as for a constructor to be constexpr, all members must be
+     initialized, which for a defaulted default constructor means they must
+     be of a class type with a constexpr default constructor.  */
+  if (!init)
+    {
+      VEC(tree,gc) *argvec = make_tree_vector ();
+      init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                       &argvec, elttype, LOOKUP_NORMAL,
+                                       tf_warning_or_error);
+      release_tree_vector (argvec);
+      init = cxx_eval_constant_expression (call, init, allow_non_constant,
+                                          addr, non_constant_p);
+    }
+
+  if (*non_constant_p && !allow_non_constant)
+    goto fail;
+
+  for (i = 0; i <= max; ++i)
+    {
+      tree idx = build_int_cst (size_type_node, i);
+      tree eltinit;
+      if (TREE_CODE (elttype) == ARRAY_TYPE)
+       {
+         /* A multidimensional array; recurse.  */
+         eltinit = cp_build_array_ref (input_location, init, idx,
+                                       tf_warning_or_error);
+         eltinit = cxx_eval_vec_init_1 (call, elttype, eltinit,
+                                        allow_non_constant, addr,
+                                        non_constant_p);
+       }
+      else if (TREE_CODE (init) == CONSTRUCTOR)
+       {
+         /* Initializing an element using the call to the default
+            constructor we just built above.  */
+         eltinit = unshare_expr (init);
+       }
+      else
+       {
+         /* Copying an element.  */
+         VEC(tree,gc) *argvec;
+         gcc_assert (same_type_ignoring_top_level_qualifiers_p
+                     (atype, TREE_TYPE (init)));
+         eltinit = cp_build_array_ref (input_location, init, idx,
+                                       tf_warning_or_error);
+         if (!real_lvalue_p (init))
+           eltinit = move (eltinit);
+         argvec = make_tree_vector ();
+         VEC_quick_push (tree, argvec, eltinit);
+         eltinit = (build_special_member_call
+                    (NULL_TREE, complete_ctor_identifier, &argvec,
+                     elttype, LOOKUP_NORMAL, tf_warning_or_error));
+         release_tree_vector (argvec);
+         eltinit = cxx_eval_constant_expression
+           (call, eltinit, allow_non_constant, addr, non_constant_p);
+       }
+      if (*non_constant_p && !allow_non_constant)
+       goto fail;
+      CONSTRUCTOR_APPEND_ELT (n, idx, eltinit);
+    }
+
+  if (!*non_constant_p)
+    {
+      init = build_constructor (TREE_TYPE (atype), n);
+      TREE_CONSTANT (init) = true;
+      return init;
+    }
+
+ fail:
+  VEC_free (constructor_elt, gc, n);
+  return init;
+}
+
+static tree
+cxx_eval_vec_init (const constexpr_call *call, tree t,
+                  bool allow_non_constant, bool addr,
+                  bool *non_constant_p)
+{
+  tree atype = TREE_TYPE (t);
+  tree init = VEC_INIT_EXPR_INIT (t);
+  tree r = cxx_eval_vec_init_1 (call, atype, init, allow_non_constant,
+                               addr, non_constant_p);
+  if (*non_constant_p)
+    return t;
+  else
+    return r;
+}
+
+/* A less strict version of fold_indirect_ref_1, which requires cv-quals to
+   match.  We want to be less strict for simple *& folding; if we have a
+   non-const temporary that we access through a const pointer, that should
+   work.  We handle this here rather than change fold_indirect_ref_1
+   because we're dealing with things like ADDR_EXPR of INTEGER_CST which
+   don't really make sense outside of constant expression evaluation.  Also
+   we want to allow folding to COMPONENT_REF, which could cause trouble
+   with TBAA in fold_indirect_ref_1.  */
+
+static tree
+cxx_eval_indirect_ref (const constexpr_call *call, tree t,
+                      bool allow_non_constant, bool addr,
+                      bool *non_constant_p)
+{
+  tree orig_op0 = TREE_OPERAND (t, 0);
+  tree op0 = cxx_eval_constant_expression (call, orig_op0, allow_non_constant,
+                                          /*addr*/false, non_constant_p);
+  tree type, sub, subtype, r;
+  bool empty_base;
+
+  /* Don't VERIFY_CONSTANT here.  */
+  if (*non_constant_p)
+    return t;
+
+  type = TREE_TYPE (t);
+  sub = op0;
+  r = NULL_TREE;
+  empty_base = false;
+
+  STRIP_NOPS (sub);
+  subtype = TREE_TYPE (sub);
+  gcc_assert (POINTER_TYPE_P (subtype));
+
+  if (TREE_CODE (sub) == ADDR_EXPR)
+    {
+      tree op = TREE_OPERAND (sub, 0);
+      tree optype = TREE_TYPE (op);
+
+      if (same_type_ignoring_top_level_qualifiers_p (optype, type))
+       r = op;
+      /* Also handle conversion to an empty base class, which
+        is represented with a NOP_EXPR.  */
+      else if (!addr && is_empty_class (type)
+              && CLASS_TYPE_P (optype)
+              && DERIVED_FROM_P (type, optype))
+       {
+         r = op;
+         empty_base = true;
+       }
+      /* *(foo *)&struct_with_foo_field => COMPONENT_REF */
+      else if (RECORD_OR_UNION_TYPE_P (optype))
+       {
+         tree field = TYPE_FIELDS (optype);
+         for (; field; field = DECL_CHAIN (field))
+           if (TREE_CODE (field) == FIELD_DECL
+               && integer_zerop (byte_position (field))
+               && (same_type_ignoring_top_level_qualifiers_p
+                   (TREE_TYPE (field), type)))
+             {
+               r = fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
+               break;
+             }
+       }
+    }
+  else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
+          && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+    {
+      tree op00 = TREE_OPERAND (sub, 0);
+      tree op01 = TREE_OPERAND (sub, 1);
+
+      STRIP_NOPS (op00);
+      if (TREE_CODE (op00) == ADDR_EXPR)
+       {
+         tree op00type;
+         op00 = TREE_OPERAND (op00, 0);
+         op00type = TREE_TYPE (op00);
+
+         /* ((foo *)&struct_with_foo_field)[1] => COMPONENT_REF */
+         if (RECORD_OR_UNION_TYPE_P (op00type))
+           {
+             tree field = TYPE_FIELDS (op00type);
+             for (; field; field = DECL_CHAIN (field))
+               if (TREE_CODE (field) == FIELD_DECL
+                   && tree_int_cst_equal (byte_position (field), op01)
+                   && (same_type_ignoring_top_level_qualifiers_p
+                       (TREE_TYPE (field), type)))
+                 {
+                   r = fold_build3 (COMPONENT_REF, type, op00,
+                                    field, NULL_TREE);
+                   break;
+                 }
+           }
+       }
+    }
+
+  /* Let build_fold_indirect_ref handle the cases it does fine with.  */
+  if (r == NULL_TREE)
+    r = build_fold_indirect_ref (op0);
+  if (TREE_CODE (r) != INDIRECT_REF)
+    r = cxx_eval_constant_expression (call, r, allow_non_constant,
+                                     addr, non_constant_p);
+  else if (TREE_CODE (sub) == ADDR_EXPR
+          || TREE_CODE (sub) == POINTER_PLUS_EXPR)
+    {
+      gcc_assert (!same_type_ignoring_top_level_qualifiers_p
+                 (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
+      /* FIXME Mike Miller wants this to be OK.  */
+      if (!allow_non_constant)
+       error ("accessing value of %qE through a %qT glvalue in a "
+              "constant expression", build_fold_indirect_ref (sub),
+              TREE_TYPE (t));
+      *non_constant_p = true;
+      return t;
+    }
+
+  /* If we're pulling out the value of an empty base, make sure
+     that the whole object is constant and then return an empty
+     CONSTRUCTOR.  */
+  if (empty_base)
+    {
+      VERIFY_CONSTANT (r);
+      r = build_constructor (TREE_TYPE (t), NULL);
+      TREE_CONSTANT (r) = true;
+    }
+
+  if (TREE_CODE (r) == INDIRECT_REF && TREE_OPERAND (r, 0) == orig_op0)
+    return t;
+  return r;
+}
+
+/* Attempt to reduce the expression T to a constant value.
+   On failure, issue diagnostic and return error_mark_node.  */
+/* FIXME unify with c_fully_fold */
+
+static tree
+cxx_eval_constant_expression (const constexpr_call *call, tree t,
+                             bool allow_non_constant, bool addr,
+                             bool *non_constant_p)
+{
+  tree r = t;
+
+  if (t == error_mark_node)
+    {
+      *non_constant_p = true;
+      return t;
+    }
+  if (CONSTANT_CLASS_P (t))
+    {
+      if (TREE_CODE (t) == PTRMEM_CST)
+       t = cplus_expand_constant (t);
+      return t;
+    }
+  if (TREE_CODE (t) != NOP_EXPR
+      && reduced_constant_expression_p (t))
+    return fold (t);
+
+  switch (TREE_CODE (t))
+    {
+    case VAR_DECL:
+      if (addr)
+       return t;
+      /* else fall through. */
+    case CONST_DECL:
+      r = integral_constant_value (t);
+      if (TREE_CODE (r) == TARGET_EXPR
+         && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
+       r = TARGET_EXPR_INITIAL (r);
+      if (DECL_P (r))
+       {
+         if (!allow_non_constant)
+           {
+             tree type = TREE_TYPE (r);
+             error ("the value of %qD is not usable in a constant "
+                    "expression", r);
+             if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+               {
+                 if (!CP_TYPE_CONST_P (type))
+                   inform (DECL_SOURCE_LOCATION (r),
+                           "%q#D is not const", r);
+                 else if (CP_TYPE_VOLATILE_P (type))
+                   inform (DECL_SOURCE_LOCATION (r),
+                           "%q#D is volatile", r);
+                 else if (!DECL_INITIAL (r))
+                   inform (DECL_SOURCE_LOCATION (r),
+                           "%qD was not initialized with a constant "
+                           "expression", r);
+                 else
+                   gcc_unreachable ();
+               }
+             else
+               {
+                 if (cxx_dialect >= cxx0x && !DECL_DECLARED_CONSTEXPR_P (r))
+                   inform (DECL_SOURCE_LOCATION (r),
+                           "%qD was not declared %<constexpr%>", r);
+                 else
+                   inform (DECL_SOURCE_LOCATION (r),
+                           "%qD does not have integral or enumeration type",
+                           r);
+               }
+           }
+         *non_constant_p = true;
+       }
+      break;
+
+    case FUNCTION_DECL:
+    case LABEL_DECL:
+      return t;
+
+    case PARM_DECL:
+      if (call && DECL_CONTEXT (t) == call->fundef->decl)
+       r = lookup_parameter_binding (call, t);
+      else if (addr)
+       /* Defer in case this is only used for its type.  */;
+      else
+       {
+         if (!allow_non_constant)
+           error ("%qE is not a constant expression", t);
+         *non_constant_p = true;
+       }
+      break;
+
+    case CALL_EXPR:
+    case AGGR_INIT_EXPR:
+      r = cxx_eval_call_expression (call, t, allow_non_constant, addr,
+                                   non_constant_p);
+      break;
+
+    case TARGET_EXPR:
+    case INIT_EXPR:
+      /* Pass false for 'addr' because these codes indicate
+        initialization of a temporary.  */
+      r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+                                       allow_non_constant, false,
+                                       non_constant_p);
+      if (!*non_constant_p)
+       /* Adjust the type of the result to the type of the temporary.  */
+       r = adjust_temp_type (TREE_TYPE (t), r);
+      break;
+
+    case SCOPE_REF:
+      r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1),
+                                       allow_non_constant, addr,
+                                       non_constant_p);
+      break;
+
+    case RETURN_EXPR:
+    case NON_LVALUE_EXPR:
+    case TRY_CATCH_EXPR:
+    case CLEANUP_POINT_EXPR:
+    case MUST_NOT_THROW_EXPR:
+    case SAVE_EXPR:
+      r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+                                       allow_non_constant, addr,
+                                       non_constant_p);
+      break;
+
+      /* These differ from cxx_eval_unary_expression in that this doesn't
+        check for a constant operand or result; an address can be
+        constant without its operand being, and vice versa.  */
+    case INDIRECT_REF:
+      r = cxx_eval_indirect_ref (call, t, allow_non_constant, addr,
+                                non_constant_p);
+      break;
+
+    case ADDR_EXPR:
+      {
+       tree oldop = TREE_OPERAND (t, 0);
+       tree op = cxx_eval_constant_expression (call, oldop,
+                                               allow_non_constant,
+                                               /*addr*/true,
+                                               non_constant_p);
+       /* Don't VERIFY_CONSTANT here.  */
+       if (*non_constant_p)
+         return t;
+       /* This function does more aggressive folding than fold itself.  */
+       r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
+       if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
+         return t;
+       break;
+      }
+
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
+    case CONJ_EXPR:
+    case FIX_TRUNC_EXPR:
+    case FLOAT_EXPR:
+    case NEGATE_EXPR:
+    case ABS_EXPR:
+    case BIT_NOT_EXPR:
+    case TRUTH_NOT_EXPR:
+    case FIXED_CONVERT_EXPR:
+      r = cxx_eval_unary_expression (call, t, allow_non_constant, addr,
+                                    non_constant_p);
+      break;
+
+    case COMPOUND_EXPR:
+      {
+       /* check_return_expr sometimes wraps a TARGET_EXPR in a
+          COMPOUND_EXPR; don't get confused.  Also handle EMPTY_CLASS_EXPR
+          introduced by build_call_a.  */
+       tree op0 = TREE_OPERAND (t, 0);
+       tree op1 = TREE_OPERAND (t, 1);
+       STRIP_NOPS (op1);
+       if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
+           || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
+         r = cxx_eval_constant_expression (call, op0, allow_non_constant,
+                                           addr, non_constant_p);
+       else
+         goto binary;
+      }
+      break;
+
+    case POINTER_PLUS_EXPR:
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+    case MULT_EXPR:
+    case TRUNC_DIV_EXPR:
+    case CEIL_DIV_EXPR:
+    case FLOOR_DIV_EXPR:
+    case ROUND_DIV_EXPR:
+    case TRUNC_MOD_EXPR:
+    case CEIL_MOD_EXPR:
+    case ROUND_MOD_EXPR:
+    case RDIV_EXPR:
+    case EXACT_DIV_EXPR:
+    case MIN_EXPR:
+    case MAX_EXPR:
+    case LSHIFT_EXPR:
+    case RSHIFT_EXPR:
+    case LROTATE_EXPR:
+    case RROTATE_EXPR:
+    case BIT_IOR_EXPR:
+    case BIT_XOR_EXPR:
+    case BIT_AND_EXPR:
+    case TRUTH_XOR_EXPR:
+    case LT_EXPR:
+    case LE_EXPR:
+    case GT_EXPR:
+    case GE_EXPR:
+    case EQ_EXPR:
+    case NE_EXPR:
+    case UNORDERED_EXPR:
+    case ORDERED_EXPR:
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+    case RANGE_EXPR:
+    case COMPLEX_EXPR:
+    binary:
+      r = cxx_eval_binary_expression (call, t, allow_non_constant, addr,
+                                     non_constant_p);
+      break;
+
+      /* fold can introduce non-IF versions of these; still treat them as
+        short-circuiting.  */
+    case TRUTH_AND_EXPR:
+    case TRUTH_ANDIF_EXPR:
+      r = cxx_eval_logical_expression (call, t, boolean_false_node,
+                                      boolean_true_node,
+                                      allow_non_constant, addr,
+                                      non_constant_p);
+      break;
+
+    case TRUTH_OR_EXPR:
+    case TRUTH_ORIF_EXPR:
+      r = cxx_eval_logical_expression (call, t, boolean_true_node,
+                                      boolean_false_node,
+                                      allow_non_constant, addr,
+                                      non_constant_p);
+      break;
+
+    case ARRAY_REF:
+      r = cxx_eval_array_reference (call, t, allow_non_constant, addr,
+                                   non_constant_p);
+      break;
+
+    case COMPONENT_REF:
+      r = cxx_eval_component_reference (call, t, allow_non_constant, addr,
+                                       non_constant_p);
+      break;
+
+    case COND_EXPR:
+    case VEC_COND_EXPR:
+      r = cxx_eval_conditional_expression (call, t, allow_non_constant, addr,
+                                          non_constant_p);
+      break;
+
+    case CONSTRUCTOR:
+      r = cxx_eval_bare_aggregate (call, t, allow_non_constant, addr,
+                                  non_constant_p);
+      break;
+
+    case VEC_INIT_EXPR:
+      /* We can get this in a defaulted constructor for a class with a
+        non-static data member of array type.  Either the initializer will
+        be NULL, meaning default-initialization, or it will be an lvalue
+        or xvalue of the same type, meaning direct-initialization from the
+        corresponding member.  */
+      r = cxx_eval_vec_init (call, t, allow_non_constant, addr,
+                            non_constant_p);
+      break;
+
+    case CONVERT_EXPR:
+    case VIEW_CONVERT_EXPR:
+    case NOP_EXPR:
+      {
+       tree oldop = TREE_OPERAND (t, 0);
+       tree op = oldop;
+       tree to = TREE_TYPE (t);
+       tree source = TREE_TYPE (op);
+        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (to)
+           && !(TREE_CODE (op) == COMPONENT_REF
+                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (op, 0)))))
+          {
+            if (!allow_non_constant)
+              error ("conversion of expression %qE of pointer type "
+                     "cannot yield a constant expression", op);
+           *non_constant_p = true;
+           return t;
+          }
+       op = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
+                                          allow_non_constant, addr,
+                                          non_constant_p);
+       if (*non_constant_p)
+         return t;
+       if (op == oldop)
+         /* We didn't fold at the top so we could check for ptr-int
+            conversion.  */
+         return fold (t);
+       r = fold_build1 (TREE_CODE (t), to, op);
+      }
+      break;
+
+    case EMPTY_CLASS_EXPR:
+      /* This is good enough for a function argument that might not get
+        used, and they can't do anything with it, so just return it.  */
+      return t;
+
+    case LAMBDA_EXPR:
+    case DYNAMIC_CAST_EXPR:
+    case PSEUDO_DTOR_EXPR:
+    case PREINCREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+    case NEW_EXPR:
+    case VEC_NEW_EXPR:
+    case DELETE_EXPR:
+    case VEC_DELETE_EXPR:
+    case THROW_EXPR:
+    case MODIFY_EXPR:
+    case MODOP_EXPR:
+      /* GCC internal stuff.  */
+    case VA_ARG_EXPR:
+    case OBJ_TYPE_REF:
+    case WITH_CLEANUP_EXPR:
+    case STATEMENT_LIST:
+    case BIND_EXPR:
+    case NON_DEPENDENT_EXPR:
+    case BASELINK:
+    case EXPR_STMT:
+      if (!allow_non_constant)
+        error_at (EXPR_LOC_OR_HERE (t),
+                 "expression %qE is not a constant-expression", t);
+      *non_constant_p = true;
+      break;
+
+    default:
+      internal_error ("unexpected expression %qE of kind %s", t,
+                     tree_code_name[TREE_CODE (t)]);
+      *non_constant_p = true;
+      break;
+    }
+
+  if (r == error_mark_node)
+    *non_constant_p = true;
+
+  if (*non_constant_p)
+    return t;
+  else
+    return r;
+}
+
+static tree
+cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant)
+{
+  bool non_constant_p = false;
+  tree r = cxx_eval_constant_expression (NULL, t, allow_non_constant,
+                                        false, &non_constant_p);
+
+  if (!non_constant_p && !reduced_constant_expression_p (r))
+    {
+      if (!allow_non_constant)
+       error ("%qE is not a constant expression", t);
+      non_constant_p = true;
+    }
+
+  if (non_constant_p && !allow_non_constant)
+    return error_mark_node;
+  else if (non_constant_p && TREE_CONSTANT (t))
+    {
+      /* This isn't actually constant, so unset TREE_CONSTANT.  */
+      if (EXPR_P (t) || TREE_CODE (t) == CONSTRUCTOR)
+       r = copy_node (t);
+      else
+       r = build_nop (TREE_TYPE (t), t);
+      TREE_CONSTANT (r) = false;
+      return r;
+    }
+  else if (non_constant_p || r == t)
+    return t;
+  else if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
+    {
+      if (TREE_CODE (t) == TARGET_EXPR
+         && TARGET_EXPR_INITIAL (t) == r)
+       return t;
+      else
+       {
+         r = get_target_expr (r);
+         TREE_CONSTANT (r) = true;
+         return r;
+       }
+    }
+  else
+    return r;
+}
+
+/* Returns true if T is a valid subexpression of a constant expression,
+   even if it isn't itself a constant expression.  */
+
+bool
+is_sub_constant_expr (tree t)
+{
+  bool non_constant_p = false;
+  cxx_eval_constant_expression (NULL, t, true, false, &non_constant_p);
+  return !non_constant_p;
+}
+
+/* If T represents a constant expression returns its reduced value.
+   Otherwise return error_mark_node.  If T is dependent, then
+   return NULL.  */
+
+tree
+cxx_constant_value (tree t)
+{
+  return cxx_eval_outermost_constant_expr (t, false);
+}
+
+/* If T is a constant expression, returns its reduced value.
+   Otherwise, if T does not have TREE_CONSTANT set, returns T.
+   Otherwise, returns a version of T without TREE_CONSTANT.  */
+
+tree
+maybe_constant_value (tree t)
+{
+  tree r;
+
+  if (type_dependent_expression_p (t)
+      /* FIXME shouldn't check value-dependence first; see comment before
+        value_dependent_expression_p.  */
+      || value_dependent_expression_p (t))
+    return t;
+
+  r = cxx_eval_outermost_constant_expr (t, true);
+#ifdef ENABLE_CHECKING
+  /* cp_tree_equal looks through NOPs, so allow them.  */
+  gcc_assert (r == t
+             || CONVERT_EXPR_P (t)
+             || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
+             || !cp_tree_equal (r, t));
+#endif
+  return r;
+}
+
+/* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
+   than wrapped in a TARGET_EXPR.  */
+
+tree
+maybe_constant_init (tree t)
+{
+  t = maybe_constant_value (t);
+  if (TREE_CODE (t) == TARGET_EXPR)
+    {
+      tree init = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (init) == CONSTRUCTOR
+         && TREE_CONSTANT (init))
+       t = init;
+    }
+  return t;
+}
+
+/* Return true if the object referred to by REF has automatic or thread
+   local storage.  */
+
+enum { ck_ok, ck_bad, ck_unknown };
+static int
+check_automatic_or_tls (tree ref)
+{
+  enum machine_mode mode;
+  HOST_WIDE_INT bitsize, bitpos;
+  tree offset;
+  int volatilep = 0, unsignedp = 0;
+  tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
+                                  &mode, &unsignedp, &volatilep, false);
+  duration_kind dk;
+
+  /* If there isn't a decl in the middle, we don't know the linkage here,
+     and this isn't a constant expression anyway.  */
+  if (!DECL_P (decl))
+    return ck_unknown;
+  dk = decl_storage_duration (decl);
+  return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
+}
+
+/* Return true if the DECL designates a builtin function that is
+   morally constexpr, in the sense that its parameter types and
+   return type are literal types and the compiler is allowed to
+   fold its invocations.  */
+
+static bool
+morally_constexpr_builtin_function_p (tree decl)
+{
+  tree funtype = TREE_TYPE (decl);
+  tree t;
+
+  if (!is_builtin_fn (decl))
+    return false;
+  if (!literal_type_p (TREE_TYPE (funtype)))
+    return false;
+  for (t = TYPE_ARG_TYPES (funtype); t != NULL ; t = TREE_CHAIN (t))
+    {
+      if (t == void_list_node)
+        return true;
+      if (!literal_type_p (TREE_VALUE (t)))
+        return false;
+    }
+  /* We assume no varargs builtins are suitable.  */
+  return t != NULL;
+}
+
+/* Return true if T denotes a constant expression, or potential constant
+   expression if POTENTIAL is true.
+   Issue diagnostic as appropriate under control of flags.  Variables
+   with static storage duration initialized by constant expressions
+   are guaranteed to be statically initialized.
+
+   C++0x [expr.const]
+
+   6 An expression is a potential constant expression if it is
+     a constant expression where all occurences of function
+     parameters are replaced by arbitrary constant expressions
+     of the appropriate type.
+
+   2  A conditional expression is a constant expression unless it
+      involves one of the following as a potentially evaluated
+      subexpression (3.2), but subexpressions of logical AND (5.14),
+      logical OR (5.15), and conditional (5.16) operations that are
+      not evaluated are not considered.   */
+
+static bool
+potential_constant_expression (tree t, tsubst_flags_t flags)
+{
+  int i;
+  tree tmp;
+  if (t == error_mark_node)
+    return false;
+  if (TREE_THIS_VOLATILE (t))
+    {
+      if (flags & tf_error)
+        error ("expression %qE has side-effects", t);
+      return false;
+    }
+  if (CONSTANT_CLASS_P (t))
+    return true;
+
+  switch (TREE_CODE (t))
+    {
+    case FUNCTION_DECL:
+    case LABEL_DECL:
+    case CONST_DECL:
+      return true;
+
+    case PARM_DECL:
+      /* -- this (5.1) unless it appears as the postfix-expression in a
+            class member access expression, including the result of the
+            implicit transformation in the body of the non-static
+            member function (9.3.1);  */
+      if (is_this_parameter (t))
+        {
+          if (flags & tf_error)
+            error ("%qE is not a potential constant expression", t);
+          return false;
+        }
+      return true;
+
+    case AGGR_INIT_EXPR:
+    case CALL_EXPR:
+      /* -- an invocation of a function other than a constexpr function
+            or a constexpr constructor.  */
+      {
+        tree fun = get_function_named_in_call (t);
+        const int nargs = call_expr_nargs (t);
+        if (TREE_CODE (fun) != FUNCTION_DECL)
+          {
+           if (potential_constant_expression (fun, flags))
+             /* Might end up being a constant function pointer.  */
+             return true;
+            if (flags & tf_error)
+              error ("%qE is not a function name", fun);
+            return false;
+          }
+       /* Skip initial arguments to base constructors.  */
+       if (DECL_BASE_CONSTRUCTOR_P (fun))
+         i = num_artificial_parms_for (fun);
+       else
+         i = 0;
+       fun = DECL_ORIGIN (fun);
+        if (builtin_valid_in_constant_expr_p (fun))
+          return true;
+        if (!DECL_DECLARED_CONSTEXPR_P (fun)
+            && !morally_constexpr_builtin_function_p (fun))
+          {
+            if (flags & tf_error)
+              error ("%qD is not %<constexpr%>", fun);
+            return false;
+          }
+        for (; i < nargs; ++i)
+          {
+            tree x = get_nth_callarg (t, i);
+            /* A call to a non-static member function takes the
+               address of the object as the first argument.
+               But in a constant expression the address will be folded
+              away, so look through it now.  */
+            if (i == 0 && DECL_NONSTATIC_MEMBER_P (fun)
+                && !DECL_CONSTRUCTOR_P (fun))
+             {
+               if (TREE_CODE (x) == ADDR_EXPR)
+                 x = TREE_OPERAND (x, 0);
+               if (is_this_parameter (x))
+                 /* OK.  */;
+                else if (!potential_constant_expression (x, flags))
+                 {
+                   if (flags & tf_error)
+                     error ("object argument is not a potential constant "
+                            "expression");
+                   return false;
+                 }
+              }
+           else if (!potential_constant_expression (x, flags))
+             {
+               if (flags & tf_error)
+                 error ("argument in position %qP is not a "
+                        "potential constant expression", i);
+               return false;
+              }
+          }
+        return true;
+      }
+
+    case NON_LVALUE_EXPR:
+      /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
+            -- an lvalue of integral type that refers to a non-volatile
+               const variable or static data member initialized with
+               constant expressions, or
+
+            -- an lvalue of literal type that refers to non-volatile
+               object defined with constexpr, or that refers to a
+               sub-object of such an object;  */
+      return potential_constant_expression (TREE_OPERAND (t, 0), flags);
+
+    case VAR_DECL:
+      if (!decl_constant_var_p (t))
+        {
+          if (flags & tf_error)
+            error ("variable %qD is not declared constexpr", t);
+          return false;
+        }
+      return true;
+
+    case NOP_EXPR:
+    case CONVERT_EXPR:
+    case VIEW_CONVERT_EXPR:
+      /* -- an array-to-pointer conversion that is applied to an lvalue
+            that designates an object with thread or automatic storage
+            duration;  FIXME not implemented as it breaks constexpr arrays;
+           need to fix the standard
+         -- a type conversion from a pointer or pointer-to-member type
+            to a literal type.  */
+      {
+        tree from = TREE_OPERAND (t, 0);
+        tree source = TREE_TYPE (from);
+        tree target = TREE_TYPE (t);
+        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (target)
+           && !(TREE_CODE (from) == COMPONENT_REF
+                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (from, 0)))))
+          {
+            if (flags & tf_error)
+              error ("conversion of expression %qE of pointer type "
+                     "cannot yield a constant expression", from);
+            return false;
+          }
+        return potential_constant_expression (from, flags);
+      }
+
+    case ADDR_EXPR:
+      /* -- a unary operator & that is applied to an lvalue that
+            designates an object with thread or automatic storage
+            duration;  */
+      t = TREE_OPERAND (t, 0);
+      i = check_automatic_or_tls (t);
+      if (i == ck_ok)
+       return true;
+      if (i == ck_bad)
+        {
+          if (flags & tf_error)
+            error ("address-of an object %qE with thread local or "
+                   "automatic storage is not a constant expression", t);
+          return false;
+        }
+      return potential_constant_expression (t, flags);
+
+    case COMPONENT_REF:
+    case BIT_FIELD_REF:
+      /* -- a class member access unless its postfix-expression is
+            of literal type or of pointer to literal type.  */
+      /* This test would be redundant, as it follows from the
+        postfix-expression being a potential constant expression.  */
+      return potential_constant_expression (TREE_OPERAND (t, 0), flags);
+
+    case INDIRECT_REF:
+      {
+        tree x = TREE_OPERAND (t, 0);
+        STRIP_NOPS (x);
+        if (is_this_parameter (x))
+         return true;
+       return potential_constant_expression (x, flags);
+      }
+
+    case LAMBDA_EXPR:
+    case DYNAMIC_CAST_EXPR:
+    case PSEUDO_DTOR_EXPR:
+    case PREINCREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+    case NEW_EXPR:
+    case VEC_NEW_EXPR:
+    case DELETE_EXPR:
+    case VEC_DELETE_EXPR:
+    case THROW_EXPR:
+    case MODIFY_EXPR:
+    case MODOP_EXPR:
+      /* GCC internal stuff.  */
+    case VA_ARG_EXPR:
+    case OBJ_TYPE_REF:
+    case WITH_CLEANUP_EXPR:
+    case CLEANUP_POINT_EXPR:
+    case MUST_NOT_THROW_EXPR:
+    case TRY_CATCH_EXPR:
+    case STATEMENT_LIST:
+    case BIND_EXPR:
+      if (flags & tf_error)
+        error ("expression %qE is not a constant-expression", t);
+      return false;
+
+    case TYPEID_EXPR:
+      /* -- a typeid expression whose operand is of polymorphic
+            class type;  */
+      {
+        tree e = TREE_OPERAND (t, 0);
+        if (!TYPE_P (e) && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
+          {
+            if (flags & tf_error)
+              error ("typeid-expression is not a constant expression "
+                     "because %qE is of polymorphic type", e);
+            return false;
+          }
+        return true;
+      }
+
+    case MINUS_EXPR:
+      /* -- a subtraction where both operands are pointers.   */
+      if (TYPE_PTR_P (TREE_OPERAND (t, 0))
+          && TYPE_PTR_P (TREE_OPERAND (t, 1)))
+        {
+          if (flags & tf_error)
+            error ("difference of two pointer expressions is not "
+                   "a constant expression");
+          return false;
+        }
+      goto binary;
+
+    case LT_EXPR:
+    case LE_EXPR:
+    case GT_EXPR:
+    case GE_EXPR:
+    case EQ_EXPR:
+    case NE_EXPR:
+      /* -- a relational or equality operator where at least
+            one of the operands is a pointer.  */
+      if (TYPE_PTR_P (TREE_OPERAND (t, 0))
+          || TYPE_PTR_P (TREE_OPERAND (t, 1)))
+        {
+          if (flags & tf_error)
+            error ("pointer comparison expression is not a "
+                   "constant expression");
+          return false;
+        }
+      goto binary;
+
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
+    case CONJ_EXPR:
+    case SAVE_EXPR:
+    case FIX_TRUNC_EXPR:
+    case FLOAT_EXPR:
+    case NEGATE_EXPR:
+    case ABS_EXPR:
+    case BIT_NOT_EXPR:
+    case TRUTH_NOT_EXPR:
+    case PAREN_EXPR:
+    case FIXED_CONVERT_EXPR:
+      /* For convenience.  */
+    case RETURN_EXPR:
+      return potential_constant_expression (TREE_OPERAND (t, 0), flags);
+
+    case INIT_EXPR:
+    case TARGET_EXPR:
+      return potential_constant_expression (TREE_OPERAND (t, 1), flags);
+
+    case CONSTRUCTOR:
+      {
+        VEC(constructor_elt, gc) *v = CONSTRUCTOR_ELTS (t);
+        constructor_elt *ce;
+        for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
+         if (!potential_constant_expression (ce->value, flags))
+           return false;
+       return true;
+      }
+
+    case TREE_LIST:
+      {
+       gcc_assert (TREE_PURPOSE (t) == NULL_TREE
+                   || DECL_P (TREE_PURPOSE (t)));
+       if (!potential_constant_expression (TREE_VALUE (t), flags))
+         return false;
+       if (TREE_CHAIN (t) == NULL_TREE)
+         return true;
+       return potential_constant_expression (TREE_CHAIN (t), flags);
+      }
+
+    case TRUNC_DIV_EXPR:
+    case CEIL_DIV_EXPR:
+    case FLOOR_DIV_EXPR:
+    case ROUND_DIV_EXPR:
+    case TRUNC_MOD_EXPR:
+    case CEIL_MOD_EXPR:
+    case ROUND_MOD_EXPR:
+      if (integer_zerop (maybe_constant_value (TREE_OPERAND (t, 1))))
+       return false;
+      else
+       goto binary;
+
+    case COMPOUND_EXPR:
+      {
+       /* check_return_expr sometimes wraps a TARGET_EXPR in a
+          COMPOUND_EXPR; don't get confused.  Also handle EMPTY_CLASS_EXPR
+          introduced by build_call_a.  */
+       tree op0 = TREE_OPERAND (t, 0);
+       tree op1 = TREE_OPERAND (t, 1);
+       STRIP_NOPS (op1);
+       if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
+           || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
+         return potential_constant_expression (op0, flags);
+       else
+         goto binary;
+      }
+
+      /* If the first operand is the non-short-circuit constant, look at
+        the second operand; otherwise we only care about the first one for
+        potentiality.  */
+    case TRUTH_AND_EXPR:
+    case TRUTH_ANDIF_EXPR:
+      tmp = boolean_true_node;
+      goto truth;
+    case TRUTH_OR_EXPR:
+    case TRUTH_ORIF_EXPR:
+      tmp = boolean_false_node;
+    truth:
+      if (TREE_OPERAND (t, 0) == tmp)
+       return potential_constant_expression (TREE_OPERAND (t, 1), flags);
+      else
+       return potential_constant_expression (TREE_OPERAND (t, 0), flags);
+
+    case ARRAY_REF:
+    case ARRAY_RANGE_REF:
+    case PLUS_EXPR:
+    case MULT_EXPR:
+    case POINTER_PLUS_EXPR:
+    case RDIV_EXPR:
+    case EXACT_DIV_EXPR:
+    case MIN_EXPR:
+    case MAX_EXPR:
+    case LSHIFT_EXPR:
+    case RSHIFT_EXPR:
+    case LROTATE_EXPR:
+    case RROTATE_EXPR:
+    case BIT_IOR_EXPR:
+    case BIT_XOR_EXPR:
+    case BIT_AND_EXPR:
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+    case RANGE_EXPR:
+    case COMPLEX_EXPR:
+    binary:
+      for (i = 0; i < 2; ++i)
+       if (!potential_constant_expression (TREE_OPERAND (t, i),
+                                     flags))
+         return false;
+      return true;
+
+    case COND_EXPR:
+    case VEC_COND_EXPR:
+      /* If the condition is a known constant, we know which of the legs we
+        care about; otherwise we only require that the condition and
+        either of the legs be potentially constant.  */
+      tmp = TREE_OPERAND (t, 0);
+      if (!potential_constant_expression (tmp, flags))
+       return false;
+      else if (tmp == boolean_true_node)
+       return potential_constant_expression (TREE_OPERAND (t, 1), flags);
+      else if (tmp == boolean_false_node)
+       return potential_constant_expression (TREE_OPERAND (t, 2), flags);
+      for (i = 1; i < 3; ++i)
+       if (potential_constant_expression (TREE_OPERAND (t, i), tf_none))
+         return true;
+      if (flags & tf_error)
+        error ("expression %qE is not a constant-expression", t);
+      return false;
+
+    case VEC_INIT_EXPR:
+      /* We should only see this in a defaulted constructor for a class
+        with a non-static data member of array type; if we get here we
+        know this is a potential constant expression.  */
+      gcc_assert (DECL_DEFAULTED_FN (current_function_decl));
+      return true;
+
+    default:
+      sorry ("unexpected ast of kind %s", tree_code_name[TREE_CODE (t)]);
+      gcc_unreachable();
+      return false;
+    }
+}
+
+\f
+/* Constructor for a lambda expression.  */
+
+tree
+build_lambda_expr (void)
+{
+  tree lambda = make_node (LAMBDA_EXPR);
+  LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE;
+  LAMBDA_EXPR_CAPTURE_LIST         (lambda) = NULL_TREE;
+  LAMBDA_EXPR_THIS_CAPTURE         (lambda) = NULL_TREE;
+  LAMBDA_EXPR_RETURN_TYPE          (lambda) = NULL_TREE;
+  LAMBDA_EXPR_MUTABLE_P            (lambda) = false;
+  return lambda;
+}
+
+/* Create the closure object for a LAMBDA_EXPR.  */
+
+tree
+build_lambda_object (tree lambda_expr)
+{
+  /* Build aggregate constructor call.
+     - cp_parser_braced_list
+     - cp_parser_functional_cast  */
+  VEC(constructor_elt,gc) *elts = NULL;
+  tree node, expr, type;
+  location_t saved_loc;
+
+  if (processing_template_decl)
+    return lambda_expr;
+
+  /* Make sure any error messages refer to the lambda-introducer.  */
+  saved_loc = input_location;
+  input_location = LAMBDA_EXPR_LOCATION (lambda_expr);
+
+  for (node = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr);
+       node;
+       node = TREE_CHAIN (node))
+    {
+      tree field = TREE_PURPOSE (node);
+      tree val = TREE_VALUE (node);
+
+      if (DECL_P (val))
+       mark_used (val);
+
+      /* Mere mortals can't copy arrays with aggregate initialization, so
+        do some magic to make it work here.  */
+      if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+       val = build_array_copy (val);
+      else if (DECL_NORMAL_CAPTURE_P (field)
+              && TREE_CODE (TREE_TYPE (field)) != REFERENCE_TYPE)
+       {
+         /* "the entities that are captured by copy are used to
+            direct-initialize each corresponding non-static data
+            member of the resulting closure object."
+
+            There's normally no way to express direct-initialization
+            from an element of a CONSTRUCTOR, so we build up a special
+            TARGET_EXPR to bypass the usual copy-initialization.  */
+         val = force_rvalue (val);
+         if (TREE_CODE (val) == TARGET_EXPR)
+           TARGET_EXPR_DIRECT_INIT_P (val) = true;
+       }
+
+      CONSTRUCTOR_APPEND_ELT (elts, DECL_NAME (field), val);
+    }
+
+  expr = build_constructor (init_list_type_node, elts);
+  CONSTRUCTOR_IS_DIRECT_INIT (expr) = 1;
+
+  /* N2927: "[The closure] class type is not an aggregate."
+     But we briefly treat it as an aggregate to make this simpler.  */
+  type = TREE_TYPE (lambda_expr);
+  CLASSTYPE_NON_AGGREGATE (type) = 0;
+  expr = finish_compound_literal (type, expr);
+  CLASSTYPE_NON_AGGREGATE (type) = 1;
+
+  input_location = saved_loc;
+  return expr;
+}
+
+/* Return an initialized RECORD_TYPE for LAMBDA.
+   LAMBDA must have its explicit captures already.  */
+
+tree
+begin_lambda_type (tree lambda)
+{
+  tree type;
+
+  {
+    /* Unique name.  This is just like an unnamed class, but we cannot use
+       make_anon_name because of certain checks against TYPE_ANONYMOUS_P.  */
+    tree name;
+    name = make_lambda_name ();
+
+    /* Create the new RECORD_TYPE for this lambda.  */
+    type = xref_tag (/*tag_code=*/record_type,
+                     name,
+                     /*scope=*/ts_within_enclosing_non_class,
+                     /*template_header_p=*/false);
+  }
+
+  /* Designate it as a struct so that we can use aggregate initialization.  */
+  CLASSTYPE_DECLARED_CLASS (type) = false;
+
+  /* Clear base types.  */
+  xref_basetypes (type, /*bases=*/NULL_TREE);
+
+  /* Start the class.  */
+  type = begin_class_definition (type, /*attributes=*/NULL_TREE);
+
+  /* Cross-reference the expression and the type.  */
+  TREE_TYPE (lambda) = type;
+  CLASSTYPE_LAMBDA_EXPR (type) = lambda;
+
+  return type;
+}
+
+/* Returns the type to use for the return type of the operator() of a
+   closure class.  */
+
+tree
+lambda_return_type (tree expr)
+{
+  tree type;
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      warning (0, "cannot deduce lambda return type from a braced-init-list");
+      return void_type_node;
+    }
+  if (type_dependent_expression_p (expr))
+    {
+      type = cxx_make_type (DECLTYPE_TYPE);
+      DECLTYPE_TYPE_EXPR (type) = expr;
+      DECLTYPE_FOR_LAMBDA_RETURN (type) = true;
+      SET_TYPE_STRUCTURAL_EQUALITY (type);
+    }
+  else
+    type = type_decays_to (unlowered_expr_type (expr));
+  return type;
+}
+
+/* Given a LAMBDA_EXPR or closure type LAMBDA, return the op() of the
+   closure type.  */
+
+tree
+lambda_function (tree lambda)
+{
+  tree type;
+  if (TREE_CODE (lambda) == LAMBDA_EXPR)
+    type = TREE_TYPE (lambda);
+  else
+    type = lambda;
+  gcc_assert (LAMBDA_TYPE_P (type));
+  /* Don't let debug_tree cause instantiation.  */
+  if (CLASSTYPE_TEMPLATE_INSTANTIATION (type) && !COMPLETE_TYPE_P (type))
+    return NULL_TREE;
+  lambda = lookup_member (type, ansi_opname (CALL_EXPR),
+                         /*protect=*/0, /*want_type=*/false);
+  if (lambda)
+    lambda = BASELINK_FUNCTIONS (lambda);
+  return lambda;
+}
+
+/* Returns the type to use for the FIELD_DECL corresponding to the
+   capture of EXPR.
+   The caller should add REFERENCE_TYPE for capture by reference.  */
+
+tree
+lambda_capture_field_type (tree expr)
+{
+  tree type;
+  if (type_dependent_expression_p (expr))
+    {
+      type = cxx_make_type (DECLTYPE_TYPE);
+      DECLTYPE_TYPE_EXPR (type) = expr;
+      DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
+      SET_TYPE_STRUCTURAL_EQUALITY (type);
+    }
+  else
+    type = non_reference (unlowered_expr_type (expr));
+  return type;
+}
+
+/* Recompute the return type for LAMBDA with body of the form:
+     { return EXPR ; }  */
+
+void
+apply_lambda_return_type (tree lambda, tree return_type)
+{
+  tree fco = lambda_function (lambda);
+  tree result;
+
+  LAMBDA_EXPR_RETURN_TYPE (lambda) = return_type;
+
+  /* If we got a DECLTYPE_TYPE, don't stick it in the function yet,
+     it would interfere with instantiating the closure type.  */
+  if (dependent_type_p (return_type))
+    return;
+  if (return_type == error_mark_node)
+    return;
+
+  /* TREE_TYPE (FUNCTION_DECL) == METHOD_TYPE
+     TREE_TYPE (METHOD_TYPE)   == return-type  */
+  TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
+
+  result = DECL_RESULT (fco);
+  if (result == NULL_TREE)
+    return;
+
+  /* We already have a DECL_RESULT from start_preparsed_function.
+     Now we need to redo the work it and allocate_struct_function
+     did to reflect the new type.  */
+  result = build_decl (input_location, RESULT_DECL, NULL_TREE,
+                      TYPE_MAIN_VARIANT (return_type));
+  DECL_ARTIFICIAL (result) = 1;
+  DECL_IGNORED_P (result) = 1;
+  cp_apply_type_quals_to_decl (cp_type_quals (return_type),
+                               result);
+
+  DECL_RESULT (fco) = result;
+
+  if (!processing_template_decl && aggregate_value_p (result, fco))
+    {
+#ifdef PCC_STATIC_STRUCT_RETURN
+      cfun->returns_pcc_struct = 1;
+#endif
+      cfun->returns_struct = 1;
+    }
+
+}
+
+/* DECL is a local variable or parameter from the surrounding scope of a
+   lambda-expression.  Returns the decltype for a use of the capture field
+   for DECL even if it hasn't been captured yet.  */
+
+static tree
+capture_decltype (tree decl)
+{
+  tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
+  /* FIXME do lookup instead of list walk? */
+  tree cap = value_member (decl, LAMBDA_EXPR_CAPTURE_LIST (lam));
+  tree type;
+
+  if (cap)
+    type = TREE_TYPE (TREE_PURPOSE (cap));
+  else
+    switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam))
+      {
+      case CPLD_NONE:
+       error ("%qD is not captured", decl);
+       return error_mark_node;
+
+      case CPLD_COPY:
+       type = TREE_TYPE (decl);
+       if (TREE_CODE (type) == REFERENCE_TYPE
+           && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
+         type = TREE_TYPE (type);
+       break;
+
+      case CPLD_REFERENCE:
+       type = TREE_TYPE (decl);
+       if (TREE_CODE (type) != REFERENCE_TYPE)
+         type = build_reference_type (TREE_TYPE (decl));
+       break;
+
+      default:
+       gcc_unreachable ();
+      }
+
+  if (TREE_CODE (type) != REFERENCE_TYPE)
+    {
+      if (!LAMBDA_EXPR_MUTABLE_P (lam))
+       type = cp_build_qualified_type (type, (cp_type_quals (type)
+                                              |TYPE_QUAL_CONST));
+      type = build_reference_type (type);
+    }
+  return type;
+}
+
+/* From an ID and INITIALIZER, create a capture (by reference if
+   BY_REFERENCE_P is true), add it to the capture-list for LAMBDA,
+   and return it.  */
+
+tree
+add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
+            bool explicit_init_p)
+{
+  tree type;
+  tree member;
+
+  type = lambda_capture_field_type (initializer);
+  if (by_reference_p)
+    {
+      type = build_reference_type (type);
+      if (!real_lvalue_p (initializer))
+       error ("cannot capture %qE by reference", initializer);
+    }
+
+  /* Make member variable.  */
+  member = build_lang_decl (FIELD_DECL, id, type);
+  if (!explicit_init_p)
+    /* Normal captures are invisible to name lookup but uses are replaced
+       with references to the capture field; we implement this by only
+       really making them invisible in unevaluated context; see
+       qualify_lookup.  For now, let's make explicitly initialized captures
+       always visible.  */
+    DECL_NORMAL_CAPTURE_P (member) = true;
+
+  /* Add it to the appropriate closure class if we've started it.  */
+  if (current_class_type && current_class_type == TREE_TYPE (lambda))
+    finish_member_declaration (member);
+
+  LAMBDA_EXPR_CAPTURE_LIST (lambda)
+    = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
+
+  if (id == get_identifier ("__this"))
+    {
+      if (LAMBDA_EXPR_CAPTURES_THIS_P (lambda))
+        error ("already captured %<this%> in lambda expression");
+      LAMBDA_EXPR_THIS_CAPTURE (lambda) = member;
+    }
+
+  return member;
+}
+
+/* Register all the capture members on the list CAPTURES, which is the
+   LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer.  */
+
+void register_capture_members (tree captures)
+{
+  if (captures)
+    {
+      register_capture_members (TREE_CHAIN (captures));
+      finish_member_declaration (TREE_PURPOSE (captures));
+    }
+}
+
+/* Given a FIELD_DECL decl belonging to a closure type, return a
+   COMPONENT_REF of it relative to the 'this' parameter of the op() for
+   that type.  */
+
+static tree
+thisify_lambda_field (tree decl)
+{
+  tree context = lambda_function (DECL_CONTEXT (decl));
+  tree object = cp_build_indirect_ref (DECL_ARGUMENTS (context),
+                                      RO_NULL,
+                                      tf_warning_or_error);
+  return finish_non_static_data_member (decl, object,
+                                       /*qualifying_scope*/NULL_TREE);
+}
+
+/* Similar to add_capture, except this works on a stack of nested lambdas.
+   BY_REFERENCE_P in this case is derived from the default capture mode.
+   Returns the capture for the lambda at the bottom of the stack.  */
+
+tree
+add_default_capture (tree lambda_stack, tree id, tree initializer)
+{
+  bool this_capture_p = (id == get_identifier ("__this"));
+
+  tree member = NULL_TREE;
+
+  tree saved_class_type = current_class_type;
+
+  tree node;
+
+  for (node = lambda_stack;
+       node;
+       node = TREE_CHAIN (node))
+    {
+      tree lambda = TREE_VALUE (node);
+
+      current_class_type = TREE_TYPE (lambda);
+      member = add_capture (lambda,
+                            id,
+                            initializer,
+                            /*by_reference_p=*/
+                           (!this_capture_p
+                            && (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
+                                == CPLD_REFERENCE)),
+                           /*explicit_init_p=*/false);
+      initializer = thisify_lambda_field (member);
+    }
+
+  current_class_type = saved_class_type;
+
+  return member;
+}
+
+/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
+   INDIRECT_REF, possibly adding it through default capturing.  */
+
+tree
+lambda_expr_this_capture (tree lambda)
+{
+  tree result;
+
+  tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
+
+  /* Try to default capture 'this' if we can.  */
+  if (!this_capture
+      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
+    {
+      tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda));
+      tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE);
+      tree init = NULL_TREE;
+
+      /* If we are in a lambda function, we can move out until we hit:
+           1. a non-lambda function,
+           2. a lambda function capturing 'this', or
+           3. a non-default capturing lambda function.  */
+      while (LAMBDA_FUNCTION_P (containing_function))
+        {
+          tree lambda
+            = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));
+
+          if (LAMBDA_EXPR_THIS_CAPTURE (lambda))
+           {
+             /* An outer lambda has already captured 'this'.  */
+             tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda);
+             init = thisify_lambda_field (cap);
+             break;
+           }
+
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_NONE)
+           /* An outer lambda won't let us capture 'this'.  */
+           break;
+
+          lambda_stack = tree_cons (NULL_TREE,
+                                    lambda,
+                                    lambda_stack);
+
+          containing_function = decl_function_context (containing_function);
+        }
+
+      if (!init && DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function)
+         && !LAMBDA_FUNCTION_P (containing_function))
+       /* First parameter is 'this'.  */
+       init = DECL_ARGUMENTS (containing_function);
+
+      if (init)
+       this_capture = add_default_capture (lambda_stack,
+                                           /*id=*/get_identifier ("__this"),
+                                           init);
+    }
+
+  if (!this_capture)
+    {
+      error ("%<this%> was not captured for this lambda function");
+      result = error_mark_node;
+    }
+  else
+    {
+      /* To make sure that current_class_ref is for the lambda.  */
+      gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
+
+      result = finish_non_static_data_member (this_capture,
+                                              NULL_TREE,
+                                              /*qualifying_scope=*/NULL_TREE);
+
+      /* If 'this' is captured, each use of 'this' is transformed into an
+        access to the corresponding unnamed data member of the closure
+        type cast (_expr.cast_ 5.4) to the type of 'this'. [ The cast
+        ensures that the transformed expression is an rvalue. ] */
+      result = rvalue (result);
+    }
+
+  return result;
+}
+
+/* Returns the method basetype of the innermost non-lambda function, or
+   NULL_TREE if none.  */
+
+tree
+nonlambda_method_basetype (void)
+{
+  tree fn, type;
+  if (!current_class_ref)
+    return NULL_TREE;
+
+  type = current_class_type;
+  if (!LAMBDA_TYPE_P (type))
+    return type;
+
+  /* Find the nearest enclosing non-lambda function.  */
+  fn = TYPE_NAME (type);
+  do
+    fn = decl_function_context (fn);
+  while (fn && LAMBDA_FUNCTION_P (fn));
+
+  if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+    return NULL_TREE;
+
+  return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
+}
+
+/* If the closure TYPE has a static op(), also add a conversion to function
+   pointer.  */
+
+void
+maybe_add_lambda_conv_op (tree type)
+{
+  bool nested = (current_function_decl != NULL_TREE);
+  tree callop = lambda_function (type);
+  tree rettype, name, fntype, fn, body, compound_stmt;
+  tree thistype, stattype, statfn, convfn, call, arg;
+  VEC (tree, gc) *argvec;
+
+  if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
+    return;
+
+  stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)),
+                                 FUNCTION_ARG_CHAIN (callop));
+
+  /* First build up the conversion op.  */
+
+  rettype = build_pointer_type (stattype);
+  name = mangle_conv_op_name_for_type (rettype);
+  thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+  fntype = build_method_type_directly (thistype, rettype, void_list_node);
+  fn = convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
+  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+
+  SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR);
+  grokclassfn (type, fn, NO_SPECIAL);
+  set_linkage_according_to_type (type, fn);
+  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+  DECL_IN_AGGR_P (fn) = 1;
+  DECL_ARTIFICIAL (fn) = 1;
+  DECL_NOT_REALLY_EXTERN (fn) = 1;
+  DECL_DECLARED_INLINE_P (fn) = 1;
+  DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST);
+  if (nested)
+    DECL_INTERFACE_KNOWN (fn) = 1;
+
+  add_method (type, fn, NULL_TREE);
+
+  /* Generic thunk code fails for varargs; we'll complain in mark_used if
+     the conversion op is used.  */
+  if (varargs_function_p (callop))
+    {
+      DECL_DELETED_FN (fn) = 1;
+      return;
+    }
+
+  /* Now build up the thunk to be returned.  */
+
+  name = get_identifier ("_FUN");
+  fn = statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
+  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+  grokclassfn (type, fn, NO_SPECIAL);
+  set_linkage_according_to_type (type, fn);
+  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+  DECL_IN_AGGR_P (fn) = 1;
+  DECL_ARTIFICIAL (fn) = 1;
+  DECL_NOT_REALLY_EXTERN (fn) = 1;
+  DECL_DECLARED_INLINE_P (fn) = 1;
+  DECL_STATIC_FUNCTION_P (fn) = 1;
+  DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop)));
+  for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg))
+    DECL_CONTEXT (arg) = fn;
+  if (nested)
+    DECL_INTERFACE_KNOWN (fn) = 1;
+
+  add_method (type, fn, NULL_TREE);
+
+  if (nested)
+    push_function_context ();
+
+  /* Generate the body of the thunk.  */
+
+  start_preparsed_function (statfn, NULL_TREE,
+                           SF_PRE_PARSED | SF_INCLASS_INLINE);
+  if (DECL_ONE_ONLY (statfn))
+    {
+      /* Put the thunk in the same comdat group as the call op.  */
+      struct cgraph_node *callop_node, *thunk_node;
+      DECL_COMDAT_GROUP (statfn) = DECL_COMDAT_GROUP (callop);
+      callop_node = cgraph_node (callop);
+      thunk_node = cgraph_node (statfn);
+      gcc_assert (callop_node->same_comdat_group == NULL);
+      gcc_assert (thunk_node->same_comdat_group == NULL);
+      callop_node->same_comdat_group = thunk_node;
+      thunk_node->same_comdat_group = callop_node;
+    }
+  body = begin_function_body ();
+  compound_stmt = begin_compound_stmt (0);
+
+  arg = build1 (NOP_EXPR, TREE_TYPE (DECL_ARGUMENTS (callop)),
+               null_pointer_node);
+  argvec = make_tree_vector ();
+  VEC_quick_push (tree, argvec, arg);
+  for (arg = DECL_ARGUMENTS (statfn); arg; arg = DECL_CHAIN (arg))
+    VEC_safe_push (tree, gc, argvec, arg);
+  call = build_call_a (callop, VEC_length (tree, argvec),
+                      VEC_address (tree, argvec));
+  CALL_FROM_THUNK_P (call) = 1;
+  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
+    call = build_cplus_new (TREE_TYPE (call), call);
+  call = convert_from_reference (call);
+  finish_return_stmt (call);
+
+  finish_compound_stmt (compound_stmt);
+  finish_function_body (body);
+
+  expand_or_defer_fn (finish_function (2));
+
+  /* Generate the body of the conversion op.  */
+
+  start_preparsed_function (convfn, NULL_TREE,
+                           SF_PRE_PARSED | SF_INCLASS_INLINE);
+  body = begin_function_body ();
+  compound_stmt = begin_compound_stmt (0);
+
+  finish_return_stmt (decay_conversion (statfn));
+
+  finish_compound_stmt (compound_stmt);
+  finish_function_body (body);
+
+  expand_or_defer_fn (finish_function (2));
+
+  if (nested)
+    pop_function_context ();
+}
 #include "gt-cp-semantics.h"