* except.c (do_pop_exception): Return a value.
+Mon Nov 10 20:25:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_new_method_call): Handle getting a
+ TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field
+ if we got template parms.
+ * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR,
+ not just the args.
+ * decl2.c (build_expr_from_tree): Tweak last change.
+ * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE.
+ (maybe_fold_nontype_arg): Split out from tsubst_copy.
+ * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR.
+
+Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (tsubst_copy): Handle explicit template arguments in
+ function calls.
+ * typeck.c (build_x_function_call): Likewise.
+ * decl2.c (build_expr_from_tree): Lookup function name if it
+ hasn't been done.
+
+ * pt.c (tsubst): Instantiate template functions properly when
+ template parameter does not appear in function arguments and return
+ type.
+ (comp_template_args): Handle member templates required by tsubst.
+
+Mon Nov 10 20:08:29 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * pt.c (coerce_template_parms): Tweak error message.
+
Mon Nov 10 03:04:20 1997 Jason Merrill <jason@yorick.cygnus.com>
Complete nested exception support.
}
else if (!TREE_CONSTANT (val))
{
- cp_error ("non-const `%E' cannot be used as template argument",
+ cp_error ("non-constant `%E' cannot be used as template argument",
arg);
val = error_mark_node;
}
continue;
if (TREE_CODE (nt) != TREE_CODE (ot))
return 0;
- if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
+ if (TREE_CODE (nt) == TREE_VEC)
+ {
+ /* For member templates */
+ if (comp_template_args (nt, ot))
+ continue;
+ }
+ else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
{
if (comptypes (ot, nt, 1))
continue;
return NULL_TREE;
}
+/* If arg is a non-type template parameter that does not depend on template
+ arguments, fold it like we weren't in the body of a template. */
+
+static tree
+maybe_fold_nontype_arg (arg)
+ tree arg;
+{
+ if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't'
+ && !uses_template_parms (arg))
+ {
+ /* Sometimes, one of the args was an expression involving a
+ template constant parameter, like N - 1. Now that we've
+ tsubst'd, we might have something like 2 - 1. This will
+ confuse lookup_template_class, so we do constant folding
+ here. We have to unset processing_template_decl, to
+ 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;
+ }
+ return arg;
+}
+
+/* Take the tree structure T and replace template parameters used therein
+ with the argument vector ARGS. NARGS is the number of args; should
+ be removed. IN_DECL is an associated decl for diagnostics.
+
+ tsubst is used for dealing with types, decls and the like; for
+ expressions, use tsubst_expr or tsubst_copy. */
+
tree
tsubst (t, args, nargs, in_decl)
tree t, args;
type = tsubst (type, args, nargs, in_decl);
}
- if (type == TREE_TYPE (t)
- && (! member || ctx == DECL_CLASS_CONTEXT (t)))
- {
- t = copy_node (t);
- copy_lang_decl (t);
- return t;
- }
-
/* Do we already have this instantiation? */
if (DECL_TEMPLATE_INFO (t) != NULL_TREE)
{
for (; decls; decls = TREE_CHAIN (decls))
if (TREE_TYPE (TREE_VALUE (decls)) == type
- && DECL_CLASS_CONTEXT (TREE_VALUE (decls)) == ctx)
+ && DECL_CLASS_CONTEXT (TREE_VALUE (decls)) == ctx
+ && comp_template_args (TREE_PURPOSE (decls), args))
return TREE_VALUE (decls);
}
for (i = 0; i < len; i++)
{
- elts[i] = tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl);
-
- if (TREE_CODE_CLASS (TREE_CODE (elts[i])) != 't'
- && !uses_template_parms (elts[i]))
- {
- /* Sometimes, one of the args was an expression involving a
- template constant parameter, like N - 1. Now that we've
- tsubst'd, we might have something like 2 - 1. This will
- confuse lookup_template_class, so we do constant folding
- here. We have to unset processing_template_decl, to
- fool build_expr_from_tree() into building an actual
- tree. */
-
- int saved_processing_template_decl = processing_template_decl;
- processing_template_decl = 0;
- elts[i] = fold (build_expr_from_tree (elts[i]));
- processing_template_decl = saved_processing_template_decl;
- }
+ elts[i] = maybe_fold_nontype_arg
+ (tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl));
if (elts[i] != TREE_VEC_ELT (t, i))
need_new = 1;
return t;
}
+/* Like tsubst, but deals with expressions. This function just replaces
+ template parms; to finish processing the resultant expression, use
+ tsubst_expr. */
+
tree
tsubst_copy (t, args, nargs, in_decl)
tree t, args;
{
tree fn = TREE_OPERAND (t, 0);
if (really_overloaded_fn (fn))
- fn = tsubst_copy (TREE_VALUE (fn), args, nargs, in_decl);
+ fn = tsubst_copy (get_first_fn (fn), args, nargs, in_decl);
else
fn = tsubst_copy (fn, args, nargs, in_decl);
return build_nt
case TEMPLATE_ID_EXPR:
{
- tree r = lookup_template_function
- (tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl),
- tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl));
- return r;
+ /* Substituted template arguments */
+ tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl);
+ tree chain;
+ for (chain = targs; chain; chain = TREE_CHAIN (chain))
+ TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
+
+ return lookup_template_function
+ (tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl), targs);
}
case TREE_LIST:
}
}
+/* Like tsubst_copy, but also does semantic processing and RTL expansion. */
+
tree
tsubst_expr (t, args, nargs, in_decl)
tree t, args;
tree function, params, decl;
{
tree type;
+ tree template_id = NULL_TREE;
int is_method;
if (function == error_mark_node)
if (processing_template_decl)
return build_min_nt (CALL_EXPR, function, params, NULL_TREE);
+ /* Save explicit template arguments if found */
+ if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
+ {
+ template_id = function;
+ function = TREE_OPERAND (function, 0);
+ }
+
type = TREE_TYPE (function);
if (TREE_CODE (type) == OFFSET_TYPE
decl = build_indirect_ref (decl, NULL_PTR);
}
+ /* Put back explicit template arguments, if any. */
+ if (template_id)
+ function = template_id;
return build_method_call (decl, function, params,
NULL_TREE, LOOKUP_NORMAL);
}
tree val = TREE_VALUE (function);
if (flag_ansi_overloading)
- return build_new_function_call (function, params);
+ {
+ /* Put back explicit template arguments, if any. */
+ if (template_id)
+ function = template_id;
+ return build_new_function_call (function, params);
+ }
if (TREE_CODE (val) == TEMPLATE_DECL)
return build_overload_call_real