OSDN Git Service

* pt.c (most_specialized_class): Use ngettext to determine
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 0047aae..c76d381 100644 (file)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "cp-tree.h"
 #include "c-family/c-common.h"
+#include "c-family/c-objc.h"
 #include "cp-objcp-common.h"
 #include "tree-inline.h"
 #include "decl.h"
@@ -137,7 +138,7 @@ static tree convert_template_argument (tree, tree, tree,
 static int for_each_template_parm (tree, tree_fn_t, void*,
                                   struct pointer_set_t*, bool);
 static tree expand_template_argument_pack (tree);
-static tree build_template_parm_index (int, int, int, tree, tree);
+static tree build_template_parm_index (int, int, int, int, tree, tree);
 static bool inline_needs_template_parms (tree);
 static void push_inline_template_parms_recursive (tree, int);
 static tree retrieve_local_specialization (tree);
@@ -187,9 +188,14 @@ static tree tsubst_decl (tree, tree, tsubst_flags_t);
 static void perform_typedefs_access_check (tree tmpl, tree targs);
 static void append_type_to_template_for_access_check_1 (tree, tree, tree,
                                                        location_t);
-static hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
 static tree listify (tree);
 static tree listify_autos (tree, tree);
+static tree template_parm_to_arg (tree t);
+static tree current_template_args (void);
+static tree fixup_template_type_parm_type (tree, int);
+static tree fixup_template_parm_index (tree, tree, int);
+static void fixup_template_parms (void);
+static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -1458,7 +1464,7 @@ hash_specialization (const void *p)
 /* Recursively calculate a hash value for a template argument ARG, for use
    in the hash tables of template specializations.  */
 
-static hashval_t
+hashval_t
 iterative_hash_template_arg (tree arg, hashval_t val)
 {
   unsigned HOST_WIDE_INT i;
@@ -3354,12 +3360,14 @@ check_template_shadow (tree decl)
 }
 
 /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
-   ORIG_LEVEL, DECL, and TYPE.  */
+   ORIG_LEVEL, DECL, and TYPE.  NUM_SIBLINGS is the total number of
+   template parameters.  */
 
 static tree
 build_template_parm_index (int index,
                           int level,
                           int orig_level,
+                          int num_siblings,
                           tree decl,
                           tree type)
 {
@@ -3367,6 +3375,7 @@ build_template_parm_index (int index,
   TEMPLATE_PARM_IDX (t) = index;
   TEMPLATE_PARM_LEVEL (t) = level;
   TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
+  TEMPLATE_PARM_NUM_SIBLINGS (t) = num_siblings;
   TEMPLATE_PARM_DECL (t) = decl;
   TREE_TYPE (t) = type;
   TREE_CONSTANT (t) = TREE_CONSTANT (decl);
@@ -3378,6 +3387,7 @@ build_template_parm_index (int index,
 /* Find the canonical type parameter for the given template type
    parameter.  Returns the canonical type parameter, which may be TYPE
    if no such parameter existed.  */
+
 static tree
 canonical_type_parameter (tree type)
 {
@@ -3431,6 +3441,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
       t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
                                     TEMPLATE_PARM_LEVEL (index) - levels,
                                     TEMPLATE_PARM_ORIG_LEVEL (index),
+                                    TEMPLATE_PARM_NUM_SIBLINGS (index),
                                     decl, type);
       TEMPLATE_PARM_DESCENDANTS (index) = t;
       TEMPLATE_PARM_PARAMETER_PACK (t) 
@@ -3446,15 +3457,20 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
   return TEMPLATE_PARM_DESCENDANTS (index);
 }
 
-/* Process information from new template parameter PARM and append it to the
-   LIST being built.  This new parameter is a non-type parameter iff
-   IS_NON_TYPE is true. This new parameter is a parameter
-   pack iff IS_PARAMETER_PACK is true.  The location of PARM is in 
-   PARM_LOC.  */
+/* Process information from new template parameter PARM and append it
+   to the LIST being built.  This new parameter is a non-type
+   parameter iff IS_NON_TYPE is true. This new parameter is a
+   parameter pack iff IS_PARAMETER_PACK is true.  The location of PARM
+   is in PARM_LOC. NUM_TEMPLATE_PARMS is the size of the template
+   parameter list PARM belongs to. This is used used to create a
+   proper canonical type for the type of PARM that is to be created,
+   iff PARM is a type.  If the size is not known, this parameter shall
+   be set to 0.  */
 
 tree
-process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_type, 
-                       bool is_parameter_pack)
+process_template_parm (tree list, location_t parm_loc, tree parm,
+                      bool is_non_type, bool is_parameter_pack,
+                      unsigned num_template_parms)
 {
   tree decl = 0;
   tree defval;
@@ -3529,6 +3545,7 @@ process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_ty
       DECL_INITIAL (parm) = DECL_INITIAL (decl)
        = build_template_parm_index (idx, processing_template_decl,
                                     processing_template_decl,
+                                    num_template_parms,
                                     decl, TREE_TYPE (parm));
 
       TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)) 
@@ -3562,6 +3579,7 @@ process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_ty
       TEMPLATE_TYPE_PARM_INDEX (t)
        = build_template_parm_index (idx, processing_template_decl,
                                     processing_template_decl,
+                                    num_template_parms,
                                     decl, TREE_TYPE (parm));
       TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack;
       TYPE_CANONICAL (t) = canonical_type_parameter (t);
@@ -3594,16 +3612,313 @@ end_template_parm_list (tree parms)
       next = TREE_CHAIN (parm);
       TREE_VEC_ELT (saved_parmlist, nparms) = parm;
       TREE_CHAIN (parm) = NULL_TREE;
-      if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
-       TEMPLATE_TYPE_PARM_SIBLING_PARMS (TREE_TYPE (TREE_VALUE (parm))) =
-             current_template_parms;
     }
 
+  fixup_template_parms ();
+
   --processing_template_parmlist;
 
   return saved_parmlist;
 }
 
+/* Create a new type almost identical to TYPE but which has the
+   following differences:
+
+     1/ T has a new TEMPLATE_PARM_INDEX that carries the new number of
+     template sibling parameters of T.
+
+     2/ T has a new canonical type that matches the new number
+     of sibling parms.
+
+     3/ From now on, T is going to be what lookups referring to the
+     name of TYPE will return. No lookup should return TYPE anymore.
+
+   NUM_PARMS is the new number of sibling parms TYPE belongs to.
+
+   This is a subroutine of fixup_template_parms.  */
+
+static tree
+fixup_template_type_parm_type (tree type, int num_parms)
+{
+  tree orig_idx = TEMPLATE_TYPE_PARM_INDEX (type), idx;
+  tree t;
+  /* This is the decl which name is inserted into the symbol table for
+     the template parm type. So whenever we lookup the type name, this
+     is the DECL we get.  */
+  tree decl;
+
+  /* Do not fix up the type twice.  */
+  if (orig_idx && TEMPLATE_PARM_NUM_SIBLINGS (orig_idx) != 0)
+    return type;
+
+  t = copy_type (type);
+  decl = TYPE_NAME (t);
+
+  TYPE_MAIN_VARIANT (t) = t;
+  TYPE_NEXT_VARIANT (t)= NULL_TREE;
+  TYPE_POINTER_TO (t) = 0;
+  TYPE_REFERENCE_TO (t) = 0;
+
+  idx = build_template_parm_index (TEMPLATE_PARM_IDX (orig_idx),
+                                  TEMPLATE_PARM_LEVEL (orig_idx),
+                                  TEMPLATE_PARM_ORIG_LEVEL (orig_idx),
+                                  num_parms,
+                                  decl, t);
+  TEMPLATE_PARM_DESCENDANTS (idx) = TEMPLATE_PARM_DESCENDANTS (orig_idx);
+  TEMPLATE_PARM_PARAMETER_PACK (idx) = TEMPLATE_PARM_PARAMETER_PACK (orig_idx);
+  TEMPLATE_TYPE_PARM_INDEX (t) = idx;
+
+  TYPE_STUB_DECL (t) = decl;
+  TEMPLATE_TYPE_DECL (t) = decl;
+  if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
+    TREE_TYPE (DECL_TEMPLATE_RESULT  (decl)) = t;
+
+  /* Update the type associated to the type name stored in the symbol
+     table. Now, whenever the type name is looked up, the resulting
+     type is properly fixed up.  */
+  TREE_TYPE (decl) = t;
+
+  TYPE_CANONICAL (t) = canonical_type_parameter (t);
+
+  return t;
+}
+
+/* Create and return a new TEMPLATE_PARM_INDEX that is almost
+   identical to I, but that is fixed up as to:
+
+   1/ carry the number of sibling parms (NUM_PARMS) of the template
+   parm represented by I.
+
+   2/ replace all references to template parm types declared before I
+   (in the same template parm list as I) by references to template
+   parm types contained in ARGS. ARGS should contain the list of
+   template parms that have been fixed up so far, in a form suitable
+   to be passed to tsubst.
+
+   This is a subroutine of fixup_template_parms.  */
+
+static tree
+fixup_template_parm_index (tree i, tree args, int num_parms)
+{
+  tree index, decl, type;
+
+  if (i == NULL_TREE
+      || TREE_CODE (i) != TEMPLATE_PARM_INDEX
+      /* Do not fix up the index twice.  */
+      || (TEMPLATE_PARM_NUM_SIBLINGS (i) != 0))
+    return i;
+
+  decl = TEMPLATE_PARM_DECL (i);
+  type = TREE_TYPE (decl);
+
+  index = build_template_parm_index (TEMPLATE_PARM_IDX (i),
+                                    TEMPLATE_PARM_LEVEL (i),
+                                    TEMPLATE_PARM_ORIG_LEVEL (i),
+                                    num_parms,
+                                    decl, type);
+
+  TEMPLATE_PARM_DESCENDANTS (index) = TEMPLATE_PARM_DESCENDANTS (i);
+  TEMPLATE_PARM_PARAMETER_PACK (index) = TEMPLATE_PARM_PARAMETER_PACK (i);
+
+  type = tsubst (type, args, tf_none, NULL_TREE);
+  
+  TREE_TYPE (decl) = type;
+  TREE_TYPE (index) = type;
+
+  return index;
+}
+
+/* 
+   This is a subroutine of fixup_template_parms.
+
+   It computes the canonical type of the type of the template
+   parameter PARM_DESC and update all references to that type so that
+   they use the newly computed canonical type. No access check is
+   performed during the fixup. PARM_DESC is a TREE_LIST which
+   TREE_VALUE is the template parameter and its TREE_PURPOSE is the
+   default argument of the template parm if any. IDX is the index of
+   the template parameter, starting at 0. NUM_PARMS is the number of
+   template parameters in the set PARM_DESC belongs to. ARGLIST is a
+   TREE_VEC containing the full set of template parameters in a form
+   suitable to be passed to substs functions as their ARGS
+   argument. This is what current_template_args returns for a given
+   template. The innermost vector of args in ARGLIST is the set of
+   template parms that have been fixed up so far. This function adds
+   the fixed up parameter into that vector.  */
+
+static void
+fixup_template_parm (tree parm_desc,
+                    int idx,
+                    int num_parms,
+                    tree arglist)
+{
+  tree parm = TREE_VALUE (parm_desc);
+  tree fixedup_args = INNERMOST_TEMPLATE_ARGS (arglist);
+
+  push_deferring_access_checks (dk_no_check);
+
+  if (TREE_CODE (parm) == TYPE_DECL)
+    {
+      /* PARM is a template type parameter. Fix up its type, add
+        the fixed-up template parm to the vector of fixed-up
+        template parms so far, and substitute the fixed-up
+        template parms into the default argument of this
+        parameter.  */
+      tree t =
+       fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
+      TREE_TYPE (parm) = t;
+
+      TREE_VEC_ELT (fixedup_args, idx) = template_parm_to_arg (parm_desc);
+    }
+  else if (TREE_CODE (parm) == TEMPLATE_DECL)
+    {
+      /* PARM is a template template parameter. This is going to
+        be interesting.  */
+      tree tparms, targs, innermost_args;
+      int j;
+
+      /* First, fix up the type of the parm.  */
+
+      tree t =
+       fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
+      TREE_TYPE (parm) = t;
+
+      TREE_VEC_ELT (fixedup_args, idx) =
+       template_parm_to_arg (parm_desc);
+
+      /* Now we need to substitute the template parm types that
+        have been fixed up so far into the non-type template
+        parms of this template template parm. E.g, consider this:
+
+        template<class T, template<T u> class TT> class S;
+
+        In this case we want to substitute T into the
+        template parameters of TT.
+
+        So let's walk the template parms of PARM here, and
+        tsubst ARGLIST into into each of the template
+        parms.   */
+
+      /* For this substitution we need to build the full set of
+        template parameters and use that as arguments for the
+        tsubsting function.  */
+      tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (parm));
+
+      /* This will contain the innermost parms of PARM into which
+        we have substituted so far.  */
+      innermost_args = make_tree_vec (TREE_VEC_LENGTH (tparms));
+      targs = add_to_template_args (arglist, innermost_args);
+      for (j = 0; j < TREE_VEC_LENGTH (tparms); ++j)
+       {
+         tree parameter;
+
+         parameter = TREE_VEC_ELT (tparms, j);
+
+         /* INNERMOST_ARGS needs to have at least the same number
+            of elements as the index PARAMETER, ortherwise
+            tsubsting into PARAMETER will result in partially
+            instantiating it, reducing its tempate parm
+            level. Let's tactically fill INNERMOST_ARGS for that
+            purpose.  */
+         TREE_VEC_ELT (innermost_args, j) =
+           template_parm_to_arg (parameter);
+
+         fixup_template_parm (parameter, j,
+                              TREE_VEC_LENGTH (tparms),
+                              targs);
+       }
+    }
+  else if (TREE_CODE (parm) == PARM_DECL)
+    {
+      /* PARM is a non-type template parameter. We need to:
+
+       * Fix up its TEMPLATE_PARM_INDEX to make it carry the
+       proper number of sibling parameters.
+
+       * Make lookups of the template parameter return a reference
+       to the fixed-up index. No lookup should return references
+       to the former index anymore.
+
+       * Substitute the template parms that got fixed up so far
+
+       * into the type of PARM.  */
+
+      tree index = DECL_INITIAL (parm);
+
+      /* PUSHED_DECL is the decl added to the symbol table with
+        the name of the parameter. E,g:
+            
+        template<class T, T u> //#0
+        auto my_function(T t) -> decltype(u); //#1
+
+        Here, when looking up u at //#1, we get the decl of u
+        resulting from the declaration in #0. This is what
+        PUSHED_DECL is. We need to replace the reference to the
+        old TEMPLATE_PARM_INDEX carried by PUSHED_DECL by the
+        fixed-up TEMPLATE_PARM_INDEX.  */
+      tree pushed_decl = TEMPLATE_PARM_DECL (index);
+
+      /* Let's fix up the TEMPLATE_PARM_INDEX then. Note that we must
+        fixup the type of PUSHED_DECL as well and luckily
+        fixup_template_parm_index does it for us too.  */
+      tree fixed_up_index =
+       fixup_template_parm_index (index, arglist, num_parms);
+
+      DECL_INITIAL (pushed_decl) = DECL_INITIAL (parm) = fixed_up_index;
+
+      /* Add this fixed up PARM to the template parms we've fixed
+        up so far and use that to substitute the fixed-up
+        template parms into the type of PARM.  */
+      TREE_VEC_ELT (fixedup_args, idx) =
+       template_parm_to_arg (parm_desc);
+      TREE_TYPE (parm) = tsubst (TREE_TYPE (parm), arglist,
+                                tf_none, NULL_TREE);
+    }
+
+  TREE_PURPOSE (parm_desc) =
+    tsubst_template_arg (TREE_PURPOSE (parm_desc),
+                        arglist, tf_none, parm);
+
+  pop_deferring_access_checks ();
+}
+
+/* Walk current the template parms and properly compute the canonical
+   types of the dependent types created during
+   cp_parser_template_parameter_list.  */
+
+static void
+fixup_template_parms (void)
+{
+  tree arglist;
+  tree parameter_vec;
+  tree fixedup_args;
+  int i, num_parms;
+
+  parameter_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+  if (parameter_vec == NULL_TREE)
+    return;
+
+  num_parms = TREE_VEC_LENGTH (parameter_vec);
+
+  /* This vector contains the current innermost template parms that
+     have been fixed up so far.  The form of FIXEDUP_ARGS is suitable
+     to be passed to tsubst* functions as their ARGS argument.  */
+  fixedup_args = make_tree_vec (num_parms);
+
+  /* This vector contains the full set of template parms in a form
+     suitable to be passed to substs functions as their ARGS
+     argument.  */
+  arglist = current_template_args ();
+  arglist = add_outermost_template_args (arglist, fixedup_args);
+
+  fixedup_args = INNERMOST_TEMPLATE_ARGS (arglist);
+
+  /* Let's do the proper fixup now.  */
+  for (i = 0; i < num_parms; ++i)
+    fixup_template_parm (TREE_VEC_ELT (parameter_vec, i),
+                        i, num_parms, arglist);
+}
+
 /* end_template_decl is called after a template declaration is seen.  */
 
 void
@@ -3621,6 +3936,68 @@ end_template_decl (void)
   current_template_parms = TREE_CHAIN (current_template_parms);
 }
 
+/* Takes a TREE_LIST representing a template parameter and convert it
+   into an argument suitable to be passed to the type substitution
+   functions.  Note that If the TREE_LIST contains an error_mark
+   node, the returned argument is error_mark_node.  */
+
+static tree
+template_parm_to_arg (tree t)
+{
+
+  if (t == NULL_TREE
+      || TREE_CODE (t) != TREE_LIST)
+    return t;
+
+  if (error_operand_p (TREE_VALUE (t)))
+    return error_mark_node;
+
+  t = TREE_VALUE (t);
+
+  if (TREE_CODE (t) == TYPE_DECL
+      || TREE_CODE (t) == TEMPLATE_DECL)
+    {
+      t = TREE_TYPE (t);
+
+      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+       {
+         /* Turn this argument into a TYPE_ARGUMENT_PACK
+            with a single element, which expands T.  */
+         tree vec = make_tree_vec (1);
+#ifdef ENABLE_CHECKING
+         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+           (vec, TREE_VEC_LENGTH (vec));
+#endif
+         TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+
+         t = cxx_make_type (TYPE_ARGUMENT_PACK);
+         SET_ARGUMENT_PACK_ARGS (t, vec);
+       }
+    }
+  else
+    {
+      t = DECL_INITIAL (t);
+
+      if (TEMPLATE_PARM_PARAMETER_PACK (t))
+       {
+         /* Turn this argument into a NONTYPE_ARGUMENT_PACK
+            with a single element, which expands T.  */
+         tree vec = make_tree_vec (1);
+         tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
+#ifdef ENABLE_CHECKING
+         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+           (vec, TREE_VEC_LENGTH (vec));
+#endif
+         TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+
+         t  = make_node (NONTYPE_ARGUMENT_PACK);
+         SET_ARGUMENT_PACK_ARGS (t, vec);
+         TREE_TYPE (t) = type;
+       }
+    }
+  return t;
+}
+
 /* Within the declaration of a template, return all levels of template
    parameters that apply.  The template parameters are represented as
    a TREE_VEC, in the form documented in cp-tree.h for template
@@ -3647,63 +4024,7 @@ current_template_args (void)
 
       TREE_TYPE (a) = NULL_TREE;
       for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
-       {
-         tree t = TREE_VEC_ELT (a, i);
-
-         /* T will be a list if we are called from within a
-            begin/end_template_parm_list pair, but a vector directly
-            if within a begin/end_member_template_processing pair.  */
-         if (TREE_CODE (t) == TREE_LIST)
-           {
-             t = TREE_VALUE (t);
-
-             if (!error_operand_p (t))
-               {
-                 if (TREE_CODE (t) == TYPE_DECL
-                     || TREE_CODE (t) == TEMPLATE_DECL)
-                    {
-                      t = TREE_TYPE (t);
-                      
-                      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
-                        {
-                          /* Turn this argument into a TYPE_ARGUMENT_PACK
-                             with a single element, which expands T.  */
-                          tree vec = make_tree_vec (1);
-#ifdef ENABLE_CHECKING
-                         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
-                               (vec, TREE_VEC_LENGTH (vec));
-#endif
-                          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
-                          
-                          t = cxx_make_type (TYPE_ARGUMENT_PACK);
-                          SET_ARGUMENT_PACK_ARGS (t, vec);
-                        }
-                    }
-                  else
-                    {
-                      t = DECL_INITIAL (t);
-                      
-                      if (TEMPLATE_PARM_PARAMETER_PACK (t))
-                        {
-                          /* Turn this argument into a NONTYPE_ARGUMENT_PACK
-                             with a single element, which expands T.  */
-                          tree vec = make_tree_vec (1);
-                          tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
-#ifdef ENABLE_CHECKING
-                         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
-                               (vec, TREE_VEC_LENGTH (vec));
-#endif
-                          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
-                          
-                          t  = make_node (NONTYPE_ARGUMENT_PACK);
-                          SET_ARGUMENT_PACK_ARGS (t, vec);
-                          TREE_TYPE (t) = type;
-                        }
-                    }
-                 TREE_VEC_ELT (a, i) = t;
-                }
-           }
-       }
+       TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
 
 #ifdef ENABLE_CHECKING
       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
@@ -3715,6 +4036,21 @@ current_template_args (void)
        args = a;
     }
 
+    if (length > 1 && TREE_VEC_ELT (args, 0) == NULL_TREE)
+      /* This can happen for template parms of a template template
+        parameter, e.g:
+
+        template<template<class T, class U> class TT> struct S;
+
+        Consider the level of the parms of TT; T and U both have
+        level 2; TT has no template parm of level 1. So in this case
+        the first element of full_template_args is NULL_TREE. If we
+        leave it like this TMPL_ARG_DEPTH on args returns 1 instead
+        of 2. This will make tsubst wrongly consider that T and U
+        have level 1. Instead, let's create a dummy vector as the
+        first element of full_template_args so that TMPL_ARG_DEPTH
+        returns the correct depth for args.  */
+      TREE_VEC_ELT (args, 0) = make_tree_vec (1);
   return args;
 }
 
@@ -4846,29 +5182,6 @@ fold_non_dependent_expr (tree expr)
   return fold_non_dependent_expr_sfinae (expr, tf_error);
 }
 
-/* EXPR is an expression which is used in a constant-expression context.
-   For instance, it could be a VAR_DECL with a constant initializer.
-   Extract the innermost constant expression.
-
-   This is basically a more powerful version of
-   integral_constant_value, which can be used also in templates where
-   initializers can maintain a syntactic rather than semantic form
-   (even if they are non-dependent, for access-checking purposes).  */
-
-static tree
-fold_decl_constant_value (tree expr)
-{
-  tree const_expr = expr;
-  do
-    {
-      expr = fold_non_dependent_expr (const_expr);
-      const_expr = integral_constant_value (expr);
-    }
-  while (expr != const_expr);
-
-  return expr;
-}
-
 /* Subroutine of convert_nontype_argument. Converts EXPR to TYPE, which
    must be a function or a pointer-to-function type, as specified
    in [temp.arg.nontype]: disambiguate EXPR if it is an overload set,
@@ -4912,14 +5225,18 @@ convert_nontype_argument_function (tree type, tree expr)
    Emit an error otherwise.  */
 
 static bool
-check_valid_ptrmem_cst_expr (tree type, tree expr)
+check_valid_ptrmem_cst_expr (tree type, tree expr,
+                            tsubst_flags_t complain)
 {
   STRIP_NOPS (expr);
   if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
     return true;
-  error ("%qE is not a valid template argument for type %qT",
-        expr, type);
-  error ("it must be a pointer-to-member of the form `&X::Y'");
+  if (complain & tf_error)
+    {
+      error ("%qE is not a valid template argument for type %qT",
+            expr, type);
+      error ("it must be a pointer-to-member of the form %<&X::Y%>");
+    }
   return false;
 }
 
@@ -5070,23 +5387,23 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
   if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       tree t = build_integral_nontype_arg_conv (type, expr, complain);
-      t = fold_decl_constant_value (t);
+      t = maybe_constant_value (t);
       if (t != error_mark_node)
        expr = t;
 
       if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
        return error_mark_node;
 
-      /* Conversion was allowed: fold it to a bare integer constant.  */
-      expr = fold (expr);
-
       /* Notice that there are constant expressions like '4 % 0' which
         do not fold into integer constants.  */
       if (TREE_CODE (expr) != INTEGER_CST)
        {
          if (complain & tf_error)
-           error ("%qE is not a valid template argument for type %qT "
-                  "because it is a non-constant expression", expr, type);
+           {
+             error ("%qE is not a valid template argument for type %qT "
+                    "because it is a non-constant expression", expr, type);
+             cxx_constant_value (expr);
+           }
          return NULL_TREE;
        }
     }
@@ -5288,7 +5605,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
 
       /* [temp.arg.nontype] bullet 1 says the pointer to member
          expression must be a pointer-to-member constant.  */
-      if (!check_valid_ptrmem_cst_expr (type, expr))
+      if (!check_valid_ptrmem_cst_expr (type, expr, complain))
        return error_mark_node;
 
       /* There is no way to disable standard conversions in
@@ -5320,7 +5637,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
     {
       /* [temp.arg.nontype] bullet 1 says the pointer to member
          expression must be a pointer-to-member constant.  */
-      if (!check_valid_ptrmem_cst_expr (type, expr))
+      if (!check_valid_ptrmem_cst_expr (type, expr, complain))
        return error_mark_node;
 
       expr = perform_qualification_conversions (type, expr);
@@ -8745,8 +9062,6 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
       for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
        {
           tree tuple;
-          tree default_value;
-          tree parm_decl;
 
           if (parms == error_mark_node)
             continue;
@@ -8756,18 +9071,8 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
           if (tuple == error_mark_node)
             continue;
 
-          default_value = TREE_PURPOSE (tuple);
-          parm_decl = TREE_VALUE (tuple);
-
-         parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
-         if (TREE_CODE (parm_decl) == PARM_DECL
-             && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain))
-           parm_decl = error_mark_node;
-         default_value = tsubst_template_arg (default_value, args,
-                                              complain, NULL_TREE);
-
-         tuple = build_tree_list (default_value, parm_decl);
-         TREE_VEC_ELT (new_vec, i) = tuple;
+         TREE_VEC_ELT (new_vec, i) =
+           tsubst_template_parm (tuple, args, complain);
        }
 
       *new_parms =
@@ -8781,6 +9086,36 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
   return r;
 }
 
+/* Return the result of substituting ARGS into one template parameter
+   given by T. T Must be a TREE_LIST which TREE_VALUE is the template
+   parameter and which TREE_PURPOSE is the default argument of the
+   template parameter.  */
+
+static tree
+tsubst_template_parm (tree t, tree args, tsubst_flags_t complain)
+{
+  tree default_value, parm_decl;
+
+  if (args == NULL_TREE
+      || t == NULL_TREE
+      || t == error_mark_node)
+    return t;
+
+  gcc_assert (TREE_CODE (t) == TREE_LIST);
+
+  default_value = TREE_PURPOSE (t);
+  parm_decl = TREE_VALUE (t);
+
+  parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+  if (TREE_CODE (parm_decl) == PARM_DECL
+      && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain))
+    parm_decl = error_mark_node;
+  default_value = tsubst_template_arg (default_value, args,
+                                      complain, NULL_TREE);
+
+  return build_tree_list (default_value, parm_decl);
+}
+
 /* Substitute the ARGS into the indicated aggregate (or enumeration)
    type T.  If T is not an aggregate or enumeration type, it is
    handled as if by tsubst.  IN_DECL is as for tsubst.  If
@@ -9638,8 +9973,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                RETURN (error_mark_node);
              }
            type = complete_type (type);
-           DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
-             = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
+           /* Wait until cp_finish_decl to set this again, to handle
+              circular dependency (template/instantiate6.C). */
+           DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = 0;
            type = check_var_type (DECL_NAME (r), type);
 
            if (DECL_HAS_VALUE_EXPR_P (t))
@@ -9700,10 +10036,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              = tsubst_expr (DECL_INITIAL (t), args, complain, in_decl,
                             /*constant_expression_p=*/false);
 
-           if (auto_node && init && describable_type (init))
+           if (auto_node && init)
              {
-               type = do_auto_deduction (type, init, auto_node);
-               TREE_TYPE (r) = type;
+               init = resolve_nondeduced_context (init);
+               if (describable_type (init))
+                 {
+                   type = do_auto_deduction (type, init, auto_node);
+                   TREE_TYPE (r) = type;
+                 }
              }
          }
        else
@@ -10126,9 +10466,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            && !TREE_TYPE (max))
          TREE_TYPE (max) = TREE_TYPE (TREE_OPERAND (max, 0));
 
-       max = mark_rvalue_use (max);
-       max = fold_decl_constant_value (max);
-
        /* If we're in a partial instantiation, preserve the magic NOP_EXPR
           with TREE_SIDE_EFFECTS that indicates this is not an integral
           constant expression.  */
@@ -10139,38 +10476,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            TREE_SIDE_EFFECTS (max) = 1;
          }
 
-       if (TREE_CODE (max) != INTEGER_CST
-           && !at_function_scope_p ()
-           && !TREE_SIDE_EFFECTS (max)
-           && !value_dependent_expression_p (max))
-         {
-           if (complain & tf_error)
-             error ("array bound is not an integer constant");
-           return error_mark_node;
-         }
-
-       /* [temp.deduct]
-
-          Type deduction may fail for any of the following
-          reasons:
-
-            Attempting to create an array with a size that is
-            zero or negative.  */
-       if (integer_zerop (max) && !(complain & tf_error))
-         /* We must fail if performing argument deduction (as
-            indicated by the state of complain), so that
-            another substitution can be found.  */
-         return error_mark_node;
-       else if (TREE_CODE (max) == INTEGER_CST
-                && INT_CST_LT (max, integer_zero_node))
-         {
-           if (complain & tf_error)
-             error ("creating array with negative size (%qE)", max);
-
-           return error_mark_node;
-         }
-
-       return compute_array_index_type (NULL_TREE, max);
+       return compute_array_index_type (NULL_TREE, max, complain);
       }
 
     case TEMPLATE_TYPE_PARM:
@@ -10577,8 +10883,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               But, such constructs have already been resolved by this
               point, so here CTX really should have complete type, unless
               it's a partial instantiation.  */
-           if (!(complain & tf_no_class_instantiations))
-             ctx = complete_type (ctx);
+           ctx = complete_type (ctx);
            if (!COMPLETE_TYPE_P (ctx))
              {
                if (complain & tf_error)
@@ -11358,6 +11663,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case INTEGER_CST:
     case REAL_CST:
     case STRING_CST:
+    case COMPLEX_CST:
       {
        /* Instantiate any typedefs in the type.  */
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
@@ -11659,10 +11965,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 
     case DECL_EXPR:
       {
-       tree decl;
+       tree decl, pattern_decl;
        tree init;
 
-       decl = DECL_EXPR_DECL (t);
+       pattern_decl = decl = DECL_EXPR_DECL (t);
        if (TREE_CODE (decl) == LABEL_DECL)
          finish_label_decl (DECL_NAME (decl));
        else if (TREE_CODE (decl) == USING_DECL)
@@ -11699,6 +12005,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                  finish_anon_union (decl);
                else
                  {
+                   int const_init = false;
                    maybe_push_decl (decl);
                    if (TREE_CODE (decl) == VAR_DECL
                        && DECL_PRETTY_FUNCTION_P (decl))
@@ -11731,7 +12038,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                          init = t;
                      }
 
-                   cp_finish_decl (decl, init, false, NULL_TREE, 0);
+                   if (TREE_CODE (decl) == VAR_DECL)
+                     const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
+                                   (pattern_decl));
+                   cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
                  }
              }
          }
@@ -12892,6 +13202,7 @@ tsubst_copy_and_build (tree t,
        if (TREE_HAS_CONSTRUCTOR (t))
          return finish_compound_literal (type, r);
 
+       TREE_TYPE (r) = type;
        return r;
       }
 
@@ -13011,6 +13322,12 @@ tsubst_copy_and_build (tree t,
        return build_lambda_object (r);
       }
 
+    case TARGET_EXPR:
+      /* We can get here for a constant initializer of non-dependent type.
+         FIXME stop folding in cp_parser_initializer_clause.  */
+      gcc_assert (TREE_CONSTANT (t));
+      return get_target_expr (RECUR (TARGET_EXPR_INITIAL (t)));
+
     default:
       /* Handle Objective-C++ constructs, if appropriate.  */
       {
@@ -14026,10 +14343,13 @@ resolve_nondeduced_context (tree orig_expr)
                                   BASELINK_ACCESS_BINFO (baselink),
                                   expr, BASELINK_OPTYPE (baselink));
          if (offset)
-           expr = build2 (OFFSET_REF, TREE_TYPE (expr),
-                          TREE_OPERAND (offset, 0), expr);
+           {
+             tree base
+               = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
+             expr = build_offset_ref (base, expr, addr);
+           }
          if (addr)
-           expr = build_address (expr);
+           expr = cp_build_addr_expr (expr, tf_warning_or_error);
          return expr;
        }
       else if (good == 0 && badargs)
@@ -14721,6 +15041,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          {
            tree parmvec = TYPE_TI_ARGS (parm);
            tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
+           tree full_argvec = add_to_template_args (targs, argvec);
            tree parm_parms 
               = DECL_INNERMOST_TEMPLATE_PARMS
                  (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
@@ -14755,7 +15076,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
              the global operator+ will be used; if they are not, the
              Lvalue_proxy will be converted to float.  */
            if (coerce_template_parms (parm_parms,
-                                       argvec,
+                                       full_argvec,
                                       TYPE_TI_TEMPLATE (parm),
                                       tf_none,
                                       /*require_all_args=*/true,
@@ -16191,7 +16512,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
       if (!(complain & tf_error))
        return error_mark_node;
       error ("ambiguous class template instantiation for %q#T", type);
-      str = TREE_CHAIN (list) ? _("candidates are:") : _("candidate is:");
+      str = ngettext ("candidate is:", "candidates are:", list_length (list));
       for (t = list; t; t = TREE_CHAIN (t))
         {
           error ("%s %+#T", spaces ? spaces : str, TREE_TYPE (t));
@@ -16832,6 +17153,8 @@ instantiate_decl (tree d, int defer_ok,
       && !DECL_NOT_REALLY_EXTERN (d))
     mark_definable (d);
 
+  DECL_SOURCE_LOCATION (td) = DECL_SOURCE_LOCATION (code_pattern);
+  DECL_SOURCE_LOCATION (d) = DECL_SOURCE_LOCATION (code_pattern);
   input_location = DECL_SOURCE_LOCATION (d);
 
   /* If D is a member of an explicitly instantiated class template,
@@ -16895,6 +17218,7 @@ instantiate_decl (tree d, int defer_ok,
        {
          tree ns;
          tree init;
+         bool const_init = false;
 
          ns = decl_namespace_context (d);
          push_nested_namespace (ns);
@@ -16903,7 +17227,11 @@ instantiate_decl (tree d, int defer_ok,
                              args,
                              tf_warning_or_error, NULL_TREE,
                              /*integral_constant_expression_p=*/false);
-         cp_finish_decl (d, init, /*init_const_expr_p=*/false,
+         /* Make sure the initializer is still constant, in case of
+            circular dependency (template/instantiate6.C). */
+         const_init
+           = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern);
+         cp_finish_decl (d, init, /*init_const_expr_p=*/const_init,
                          /*asmspec_tree=*/NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
          pop_nested_class ();
@@ -16974,6 +17302,7 @@ instantiate_decl (tree d, int defer_ok,
   if (TREE_CODE (d) == VAR_DECL)
     {
       tree init;
+      bool const_init = false;
 
       /* Clear out DECL_RTL; whatever was there before may not be right
         since we've reset the type of the declaration.  */
@@ -16981,7 +17310,8 @@ instantiate_decl (tree d, int defer_ok,
       DECL_IN_AGGR_P (d) = 0;
 
       /* The initializer is placed in DECL_INITIAL by
-        regenerate_decl_from_template.  Pull it out so that
+        regenerate_decl_from_template so we don't need to
+        push/pop_access_scope again here.  Pull it out so that
         cp_finish_decl can process it.  */
       init = DECL_INITIAL (d);
       DECL_INITIAL (d) = NULL_TREE;
@@ -16994,7 +17324,8 @@ instantiate_decl (tree d, int defer_ok,
 
       /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
-      cp_finish_decl (d, init, false, NULL_TREE, 0);
+      const_init = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern);
+      cp_finish_decl (d, init, const_init, NULL_TREE, 0);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
@@ -17634,6 +17965,23 @@ dependent_scope_p (tree scope)
    [temp.dep.constexpr].  EXPRESSION is already known to be a constant
    expression.  */
 
+/* FIXME this predicate is not appropriate for general expressions; the
+   predicates we want instead are "valid constant expression, value
+   dependent or not?", "really constant expression, not value dependent?"
+   and "instantiation-dependent?".  Try to integrate with
+   potential_constant_expression?
+
+   fold_non_dependent_expr: fold if constant and not type-dependent and not value-dependent.
+     (what about instantiation-dependent constant-expressions?)
+   is_late_template_attribute: defer if instantiation-dependent.
+   compute_array_index_type: proceed if constant and not t- or v-dependent
+     if instantiation-dependent, need to remember full expression
+   uses_template_parms: FIXME - need to audit callers
+   tsubst_decl [function_decl]: Why is this using value_dependent_expression_p?
+   dependent_type_p [array_type]: dependent if index type is dependent
+     (or non-constant?)
+   static_assert - instantiation-dependent */
+
 bool
 value_dependent_expression_p (tree expression)
 {
@@ -17690,7 +18038,8 @@ value_dependent_expression_p (tree expression)
            /* If there are no operands, it must be an expression such
               as "int()". This should not happen for aggregate types
               because it would form non-constant expressions.  */
-           gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+           gcc_assert (cxx_dialect >= cxx0x
+                       || INTEGRAL_OR_ENUMERATION_TYPE_P (type));
 
            return false;
          }
@@ -17734,12 +18083,6 @@ value_dependent_expression_p (tree expression)
       return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
              || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
 
-    case CALL_EXPR:
-      /* A CALL_EXPR may appear in a constant expression if it is a
-        call to a builtin function, e.g., __builtin_constant_p.  All
-        such calls are value-dependent.  */
-      return true;
-
     case NONTYPE_ARGUMENT_PACK:
       /* A NONTYPE_ARGUMENT_PACK is value-dependent if any packed argument
          is value-dependent.  */
@@ -17765,6 +18108,10 @@ value_dependent_expression_p (tree expression)
       return ((value_dependent_expression_p (TREE_OPERAND (expression, 0)))
              || (value_dependent_expression_p (TREE_OPERAND (expression, 2))));
 
+    case ARRAY_REF:
+      return ((value_dependent_expression_p (TREE_OPERAND (expression, 0)))
+             || (value_dependent_expression_p (TREE_OPERAND (expression, 1))));
+
     case ADDR_EXPR:
       {
        tree op = TREE_OPERAND (expression, 0);
@@ -17772,6 +18119,30 @@ value_dependent_expression_p (tree expression)
                || has_value_dependent_address (op));
       }
 
+    case CALL_EXPR:
+      {
+       tree fn = get_callee_fndecl (expression);
+       int i, nargs;
+       if (!fn && value_dependent_expression_p (CALL_EXPR_FN (expression)))
+         return true;
+       nargs = call_expr_nargs (expression);
+       for (i = 0; i < nargs; ++i)
+         {
+           tree op = CALL_EXPR_ARG (expression, i);
+           /* In a call to a constexpr member function, look through the
+              implicit ADDR_EXPR on the object argument so that it doesn't
+              cause the call to be considered value-dependent.  We also
+              look through it in potential_constant_expression.  */
+           if (i == 0 && fn && DECL_DECLARED_CONSTEXPR_P (fn)
+               && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+               && TREE_CODE (op) == ADDR_EXPR)
+             op = TREE_OPERAND (op, 0);
+           if (value_dependent_expression_p (op))
+             return true;
+         }
+       return false;
+      }
+
     default:
       /* A constant expression is value-dependent if any subexpression is
         value-dependent.  */
@@ -18016,6 +18387,13 @@ dependent_template_arg_p (tree arg)
   if (!processing_template_decl)
     return false;
 
+  /* Assume a template argument that was wrongly written by the user
+     is dependent. This is consistent with what
+     any_dependent_template_arguments_p [that calls this function]
+     does.  */
+  if (arg == error_mark_node)
+    return true;
+
   if (TREE_CODE (arg) == TEMPLATE_DECL
       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
     return dependent_template_p (arg);
@@ -18443,7 +18821,7 @@ make_auto (void)
   TYPE_STUB_DECL (au) = TYPE_NAME (au);
   TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
     (0, processing_template_decl + 1, processing_template_decl + 1,
-     TYPE_NAME (au), NULL_TREE);
+     0, TYPE_NAME (au), NULL_TREE);
   TYPE_CANONICAL (au) = canonical_type_parameter (au);
   DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
   SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
@@ -18526,6 +18904,8 @@ do_auto_deduction (tree type, tree init, tree auto_node)
   if (BRACE_ENCLOSED_INITIALIZER_P (init))
     type = listify_autos (type, auto_node);
 
+  init = resolve_nondeduced_context (init);
+
   parms = build_tree_list (NULL_TREE, type);
   args[0] = init;
   tparms = make_tree_vec (1);