pt.c (UNIFY_ALLOW_MAX_CORRECTION): Define.
[gcc.git] / gcc / cp / pt.c
index 3d6279a82823dd81224999c839c7ce80130b896c..5a5cf4dafe95cae073096ead0eae0ff6aaf3d7b4 100644 (file)
@@ -29,10 +29,10 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include "obstack.h"
-
 #include "tree.h"
 #include "flags.h"
 #include "cp-tree.h"
+#include "tree-inline.h"
 #include "decl.h"
 #include "parse.h"
 #include "lex.h"
@@ -84,6 +84,7 @@ static htab_t local_specializations;
 #define UNIFY_ALLOW_OUTER_LEVEL 16
 #define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
 #define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
+#define UNIFY_ALLOW_MAX_CORRECTION 128
 
 #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
                             virtual, or a base class of a virtual
@@ -1040,6 +1041,12 @@ determine_specialization (template_id, decl, targs_out,
             Here, S<int>::f is a non-template, but S<int> is a
             template class.  If FN has the same type as DECL, we
             might be in business.  */
+
+         if (!DECL_TEMPLATE_INFO (fn))
+           /* Its enclosing class is an explicit specialization
+              of a template class.  This is not a candidate.  */
+           continue;
+
          if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
                            TREE_TYPE (TREE_TYPE (fn))))
            /* The return types differ.  */
@@ -1929,7 +1936,7 @@ process_template_parm (list, next)
       my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
       /* is a const-param */
       parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
-                            PARM, 0, NULL_TREE);
+                            PARM, 0, NULL);
 
       /* [temp.param]
 
@@ -3907,6 +3914,19 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
 
       parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
 
+      /* Consider an example where a template template parameter declared as
+
+          template <class T, class U = std::allocator<T> > class TT
+
+        The template parameter level of T and U are one level larger than 
+        of TT.  To proper process the default argument of U, say when an 
+        instantiation `TT<int>' is seen, we need to build the full
+        arguments containing {int} as the innermost level.  Outer levels
+        can be obtained from `current_template_args ()'.  */
+
+      if (processing_template_decl)
+       arglist = add_to_template_args (current_template_args (), arglist);
+
       arglist2 = coerce_template_parms (parmlist, arglist, template,
                                         complain, /*require_all_args=*/1);
       if (arglist2 == error_mark_node)
@@ -4988,7 +5008,6 @@ instantiate_class_template (type)
   TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
   TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
   TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
-  TYPE_VEC_DELETE_TAKES_SIZE (type) = TYPE_VEC_DELETE_TAKES_SIZE (pattern);
   TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
   TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
   TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);
@@ -5281,12 +5300,7 @@ static tree
 maybe_fold_nontype_arg (arg)
      tree arg;
 {
-  /* If we're not in a template, ARG is already as simple as it's going to
-     get, and trying to reprocess the trees will break.  */
-  if (! processing_template_decl)
-    return arg;
-
-  if (!TYPE_P (arg) && !uses_template_parms (arg))
+  if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
     {
       /* Sometimes, one of the args was an expression involving a
         template constant parameter, like N - 1.  Now that we've
@@ -5296,10 +5310,18 @@ maybe_fold_nontype_arg (arg)
         fool build_expr_from_tree() into building an actual
         tree.  */
 
-      int saved_processing_template_decl = processing_template_decl; 
-      processing_template_decl = 0;
-      arg = fold (build_expr_from_tree (arg));
-      processing_template_decl = saved_processing_template_decl; 
+      /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+        as simple as it's going to get, and trying to reprocess
+        the trees will break.  */
+      if (!TREE_TYPE (arg))
+       {
+         int saved_processing_template_decl = processing_template_decl; 
+         processing_template_decl = 0;
+         arg = build_expr_from_tree (arg);
+         processing_template_decl = saved_processing_template_decl; 
+       }
+
+      arg = fold (arg);
     }
   return arg;
 }
@@ -5378,8 +5400,9 @@ tsubst_template_parms (parms, args, complain)
            TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i));
          
          TREE_VEC_ELT (new_vec, i)
-           = build_tree_list (tsubst (default_value, args, complain,
-                                      NULL_TREE), 
+           = build_tree_list (maybe_fold_nontype_arg (
+                                 tsubst_expr (default_value, args, complain,
+                                              NULL_TREE)), 
                               tsubst (parm_decl, args, complain,
                                       NULL_TREE));
        }
@@ -5989,7 +6012,7 @@ tsubst_decl (t, args, type)
        /* For __PRETTY_FUNCTION__ we have to adjust the initializer.  */
        if (DECL_PRETTY_FUNCTION_P (r))
          {
-           const char *name = (*decl_printable_name)
+           const char *const name = (*decl_printable_name)
                                (current_function_decl, 2);
            DECL_INITIAL (r) = cp_fname_init (name);
            TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
@@ -6248,7 +6271,6 @@ tsubst (t, args, complain, in_decl)
 
     case ERROR_MARK:
     case IDENTIFIER_NODE:
-    case OP_IDENTIFIER:
     case VOID_TYPE:
     case REAL_TYPE:
     case COMPLEX_TYPE:
@@ -6421,7 +6443,7 @@ tsubst (t, args, complain, in_decl)
              }
            else
              {
-               r = copy_node (t);
+               r = copy_type (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
                                                r, levels);
@@ -7168,7 +7190,7 @@ tsubst_expr (t, args, complain, in_decl)
      int complain;
      tree in_decl;
 {
-  tree stmt;
+  tree stmt, tmp;
 
   if (t == NULL_TREE || t == error_mark_node)
     return t;
@@ -7176,6 +7198,9 @@ tsubst_expr (t, args, complain, in_decl)
   if (processing_template_decl)
     return tsubst_copy (t, args, complain, in_decl);
 
+  if (!statement_code_p (TREE_CODE (t)))
+    return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+    
   switch (TREE_CODE (t))
     {
     case RETURN_INIT:
@@ -7183,7 +7208,6 @@ tsubst_expr (t, args, complain, in_decl)
       finish_named_return_value
        (TREE_OPERAND (t, 0),
         tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
-      tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
       break;
 
     case CTOR_INITIALIZER:
@@ -7197,7 +7221,6 @@ tsubst_expr (t, args, complain, in_decl)
        base_init_list
          = tsubst_initializer_list (TREE_OPERAND (t, 1), args);
        setup_vtbl_ptr (member_init_list, base_init_list);
-       tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
        break;
       }
 
@@ -7262,17 +7285,21 @@ tsubst_expr (t, args, complain, in_decl)
                cp_finish_decl (decl, init, NULL_TREE, 0);
              }
          }
-       return decl;
+
+       /* A DECL_STMT can also be used as an expression, in the condition
+          clause of a if/for/while construct.  If we aren't followed by
+          another statement, return our decl.  */
+       if (TREE_CHAIN (t) == NULL_TREE)
+         return decl;
       }
+      break;
 
     case FOR_STMT:
       {
-       tree tmp;
        prep_stmt (t);
 
        stmt = begin_for_stmt ();
-       for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
-         tsubst_expr (tmp, args, complain, in_decl);
+       tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
        finish_for_init_stmt (stmt);
        finish_for_cond (tsubst_expr (FOR_COND (t), args,
                                      complain, in_decl),
@@ -7310,8 +7337,6 @@ tsubst_expr (t, args, complain, in_decl)
 
     case IF_STMT:
       {
-       tree tmp;
-
        prep_stmt (t);
        stmt = begin_if_stmt ();
        finish_if_stmt_cond (tsubst_expr (IF_COND (t),
@@ -7337,15 +7362,10 @@ tsubst_expr (t, args, complain, in_decl)
 
     case COMPOUND_STMT:
       {
-       tree substmt;
-
        prep_stmt (t);
        stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
-       for (substmt = COMPOUND_BODY (t); 
-            substmt != NULL_TREE;
-            substmt = TREE_CHAIN (substmt))
-         tsubst_expr (substmt, args, complain, in_decl);
-       return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+       tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+       finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
       }
       break;
 
@@ -7386,15 +7406,15 @@ tsubst_expr (t, args, complain, in_decl)
 
     case GOTO_STMT:
       prep_stmt (t);
-      t = GOTO_DESTINATION (t);
-      if (TREE_CODE (t) != LABEL_DECL)
+      tmp = GOTO_DESTINATION (t);
+      if (TREE_CODE (tmp) != LABEL_DECL)
        /* Computed goto's must be tsubst'd into.  On the other hand,
           non-computed gotos must not be; the identifier in question
           will have no binding.  */
-       t = tsubst_expr (t, args, complain, in_decl);
+       tmp = tsubst_expr (tmp, args, complain, in_decl);
       else
-       t = DECL_NAME (t);
-      finish_goto_stmt (t);
+       tmp = DECL_NAME (tmp);
+      finish_goto_stmt (tmp);
       break;
 
     case ASM_STMT:
@@ -7420,8 +7440,6 @@ tsubst_expr (t, args, complain, in_decl)
        }
       else
        {
-         tree handler;
-
          if (FN_TRY_BLOCK_P (t))
            stmt = begin_function_try_block ();
          else
@@ -7434,9 +7452,7 @@ tsubst_expr (t, args, complain, in_decl)
          else
            finish_try_block (stmt);
 
-         handler = TRY_HANDLERS (t);
-         for (; handler; handler = TREE_CHAIN (handler))
-           tsubst_expr (handler, args, complain, in_decl);
+         tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
          if (FN_TRY_BLOCK_P (t))
            finish_function_handler_sequence (stmt);
          else
@@ -7469,14 +7485,18 @@ tsubst_expr (t, args, complain, in_decl)
 
     case TAG_DEFN:
       prep_stmt (t);
-      t = TREE_TYPE (t);
-      tsubst (t, args, complain, NULL_TREE);
+      tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
       break;
 
+    case CTOR_STMT:
+      add_stmt (copy_node (t));
+      break;
+      
     default:
-      return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+      abort ();
     }
-  return NULL_TREE;
+
+  return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
 }
 
 /* TMPL is a TEMPLATE_DECL for a cloned constructor or destructor.
@@ -8454,7 +8474,14 @@ check_cv_quals_for_unify (strict, arg, parm)
        qualified at this point.
      UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
        This is the outermost level of a deduction, and PARM can be less CV
-       qualified at this point.  */
+       qualified at this point.
+     UNIFY_ALLOW_MAX_CORRECTION:
+       This is an INTEGER_TYPE's maximum value.  Used if the range may
+       have been derived from a size specification, such as an array size.
+       If the size was given by a nontype template parameter N, the maximum
+       value will have the form N-1.  The flag says that we can (and indeed
+       must) unify N with (ARG + 1), an exception to the normal rules on
+       folding PARM.  */
 
 static int
 unify (tparms, targs, parm, arg, strict)
@@ -8510,6 +8537,7 @@ unify (tparms, targs, parm, arg, strict)
   strict &= ~UNIFY_ALLOW_DERIVED;
   strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
   strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
+  strict &= ~UNIFY_ALLOW_MAX_CORRECTION;
   
   switch (TREE_CODE (parm))
     {
@@ -8765,7 +8793,8 @@ unify (tparms, targs, parm, arg, strict)
            return 1;
          if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
              && unify (tparms, targs, TYPE_MAX_VALUE (parm),
-                       TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER))
+                       TYPE_MAX_VALUE (arg),
+                       UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION))
            return 1;
        }
       /* We have already checked cv-qualification at the top of the
@@ -8895,7 +8924,8 @@ unify (tparms, targs, parm, arg, strict)
       return 1;
 
     case MINUS_EXPR:
-      if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST)
+      if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node)
+         && (strict_in & UNIFY_ALLOW_MAX_CORRECTION))
        {
          /* We handle this case specially, since it comes up with
             arrays.  In particular, something like:
@@ -9356,7 +9386,7 @@ void
 do_decl_instantiation (declspecs, declarator, storage)
      tree declspecs, declarator, storage;
 {
-  tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
+  tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
   tree result = NULL_TREE;
   int extern_p = 0;
 
@@ -9880,7 +9910,8 @@ instantiate_decl (d, defer_ok)
   /* Reject all external templates except inline functions.  */
   else if (DECL_INTERFACE_KNOWN (d)
           && ! DECL_NOT_REALLY_EXTERN (d)
-          && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)))
+          && ! (TREE_CODE (d) == FUNCTION_DECL 
+                && DECL_INLINE (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
      forbidden from doing so.  We restore the source position here