aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-09-04 11:31:30 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-09-04 11:31:30 +0000
commitcabc336a5ef33546fa4330972415152e59174ef8 (patch)
treeef867aa9935c51a5dcaa6ea21926721ed24b1b81 /gcc
parent7940acc401ef788bf2e287bd77250a3a125c9e80 (diff)
downloadgcc-cabc336a5ef33546fa4330972415152e59174ef8.zip
gcc-cabc336a5ef33546fa4330972415152e59174ef8.tar.gz
gcc-cabc336a5ef33546fa4330972415152e59174ef8.tar.bz2
cp-tree.h (hash_tree_cons_simple): New macro.
* cp-tree.h (hash_tree_cons_simple): New macro. * pt.c (tsubst_arg_types): New function. Use hash_tree_cons. (coerce_template_parms): Use make_temp_vec, instead of make_tree_vec. Document this behavior. (lookup_template_class): Likewise. (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types. Remove dead code (and add ssertion to check its deadness). Fix bug w.r.t. exception specifications. From-SVN: r22233
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/pt.c130
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/tmpl1.C15
4 files changed, 85 insertions, 73 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 656af65..1138e87 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+1998-09-04 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (hash_tree_cons_simple): New macro.
+ * pt.c (tsubst_arg_types): New function. Use hash_tree_cons.
+ (coerce_template_parms): Use make_temp_vec, instead of
+ make_tree_vec. Document this behavior.
+ (lookup_template_class): Likewise.
+ (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types.
+ Remove dead code (and add ssertion to check its deadness). Fix
+ bug w.r.t. exception specifications.
+
1998-09-03 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (import_export_vtable): Always make artificials comdat.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ebd0686..8bf6c5c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3040,6 +3040,8 @@ extern void push_expression_obstack PROTO((void));
#define build_scratch_list build_expr_list
#define make_scratch_vec make_temp_vec
#define push_scratch_obstack push_expression_obstack
+#define hash_tree_cons_simple(PURPOSE, VALUE, CHAIN) \
+ hash_tree_cons (0, 0, 0, (PURPOSE), (VALUE), (CHAIN))
/* in typeck.c */
extern tree condition_conversion PROTO((tree));
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d2251e8..b27621b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -126,6 +126,7 @@ static void set_mangled_name_for_template_decl PROTO((tree));
static int template_class_depth_real PROTO((tree, int));
static tree tsubst_aggr_type PROTO((tree, tree, tree, int));
static tree tsubst_decl PROTO((tree, tree, tree, tree));
+static tree tsubst_arg_types PROTO((tree, tree, tree));
/* We use TREE_VECs to hold template arguments. If there is only one
level of template arguments, then the TREE_VEC contains the
@@ -2802,7 +2803,10 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be
provided in ARGLIST, or else trailing parameters must have default
values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
- deduction for any unspecified trailing arguments. */
+ deduction for any unspecified trailing arguments.
+
+ The resulting TREE_VEC is allocated on a temporary obstack, and
+ must be explicitly copied if it will be permanent. */
static tree
coerce_template_parms (parms, args, in_decl,
@@ -2839,7 +2843,7 @@ coerce_template_parms (parms, args, in_decl,
return error_mark_node;
}
- new_inner_args = make_tree_vec (nparms);
+ new_inner_args = make_temp_vec (nparms);
new_args = add_outermost_template_args (args, new_inner_args);
for (i = 0; i < nparms; i++)
{
@@ -3300,7 +3304,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
int i;
int saved_depth = TMPL_ARGS_DEPTH (arglist);
- tree bound_args = make_tree_vec (parm_depth);
+ tree bound_args = make_temp_vec (parm_depth);
for (i = saved_depth,
t = DECL_TEMPLATE_PARMS (template);
@@ -5191,6 +5195,38 @@ tsubst_decl (t, args, type, in_decl)
}
+/* Substitue into the ARG_TYPES of a function type. */
+
+tree
+tsubst_arg_types (arg_types, args, in_decl)
+ tree arg_types;
+ tree args;
+ tree in_decl;
+{
+ tree remaining_arg_types;
+ tree result;
+ tree type;
+
+ if (!arg_types || arg_types == void_list_node)
+ return arg_types;
+
+ remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
+ args, in_decl);
+
+ /* We use TYPE_MAIN_VARIANT is because top-level qualifiers don't
+ matter on function types. */
+ type = TYPE_MAIN_VARIANT (type_decays_to
+ (tsubst (TREE_VALUE (arg_types),
+ args, in_decl)));
+
+ /* Note that we do not substitute into default arguments here. The
+ standard mandates that they be instantiated only when needed,
+ which is done in build_over_call. */
+ return hash_tree_cons_simple (TREE_PURPOSE (arg_types), type,
+ remaining_arg_types);
+
+}
+
/* Take the tree structure T and replace template parameters used therein
with the argument vector ARGS. IN_DECL is an associated decl for
diagnostics.
@@ -5495,83 +5531,31 @@ tsubst (t, args, in_decl)
case FUNCTION_TYPE:
case METHOD_TYPE:
{
- tree values = TYPE_ARG_TYPES (t);
- tree context = TYPE_CONTEXT (t);
- tree raises = TYPE_RAISES_EXCEPTIONS (t);
+ tree arg_types;
+ tree raises;
tree fntype;
- /* Don't bother recursing if we know it won't change anything. */
- if (values != void_list_node)
- {
- /* This should probably be rewritten to use hash_tree_cons for
- the memory savings. */
- tree first = NULL_TREE;
- tree last = NULL_TREE;
-
- for (; values && values != void_list_node;
- values = TREE_CHAIN (values))
- {
- tree value = TYPE_MAIN_VARIANT (type_decays_to
- (tsubst (TREE_VALUE (values), args, in_decl)));
- /* Don't instantiate default args unless they are used.
- Handle it in build_over_call instead. */
- tree purpose = TREE_PURPOSE (values);
- tree x = build_tree_list (purpose, value);
-
- if (first)
- TREE_CHAIN (last) = x;
- else
- first = x;
- last = x;
- }
-
- if (values == void_list_node)
- TREE_CHAIN (last) = void_list_node;
-
- values = first;
- }
- if (context)
- context = tsubst (context, args, in_decl);
- /* Could also optimize cases where return value and
- values have common elements (e.g., T min(const &T, const T&). */
-
- /* If the above parameters haven't changed, just return the type. */
- if (type == TREE_TYPE (t)
- && values == TYPE_VALUES (t)
- && context == TYPE_CONTEXT (t))
- return t;
+ /* The TYPE_CONTEXT is not used for function/method types. */
+ my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
+
+ /* Substitue the argument types. */
+ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, in_decl);
/* Construct a new type node and return it. */
- if (TREE_CODE (t) == FUNCTION_TYPE
- && context == NULL_TREE)
- {
- fntype = build_function_type (type, values);
- }
- else if (context == NULL_TREE)
- {
- tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))),
- args, in_decl);
- fntype = build_cplus_method_type (base, type,
- TREE_CHAIN (values));
- }
- else
- {
- fntype = make_node (TREE_CODE (t));
- TREE_TYPE (fntype) = type;
- TYPE_CONTEXT (fntype) = FROB_CONTEXT (context);
- TYPE_VALUES (fntype) = values;
- TYPE_SIZE (fntype) = TYPE_SIZE (t);
- TYPE_ALIGN (fntype) = TYPE_ALIGN (t);
- TYPE_MODE (fntype) = TYPE_MODE (t);
- if (TYPE_METHOD_BASETYPE (t))
- TYPE_METHOD_BASETYPE (fntype) = tsubst (TYPE_METHOD_BASETYPE (t),
- args, in_decl);
- /* Need to generate hash value. */
- my_friendly_abort (84);
- }
+ if (TREE_CODE (t) == FUNCTION_TYPE)
+ fntype = build_function_type (type, arg_types);
+ else
+ fntype
+ = build_cplus_method_type (TREE_TYPE (TREE_VALUE (arg_types)),
+ type,
+ TREE_CHAIN (arg_types));
+
fntype = build_type_variant (fntype,
TYPE_READONLY (t),
TYPE_VOLATILE (t));
+
+ /* Substitue the exception specification. */
+ raises = TYPE_RAISES_EXCEPTIONS (t);
if (raises)
{
raises = tsubst (raises, args, in_decl);
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/tmpl1.C b/gcc/testsuite/g++.old-deja/g++.eh/tmpl1.C
new file mode 100644
index 0000000..cdbd6e1
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/tmpl1.C
@@ -0,0 +1,15 @@
+template <class T>
+void f() throw (T)
+{
+ throw 7;
+}
+
+
+int main()
+{
+ try {
+ f<int>();
+ } catch (...) {
+ return 0;
+ }
+}