aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1998-03-20 05:44:06 -0500
committerJason Merrill <jason@gcc.gnu.org>1998-03-20 05:44:06 -0500
commite6f1275f861e69c54e4812870d5c05c8c72df757 (patch)
treeecbafe902e4da99957d7fb9189bf75722c9b4995 /gcc
parent7aa74e4c2f4ca8b4a819099127b6263b4e0257c7 (diff)
downloadgcc-e6f1275f861e69c54e4812870d5c05c8c72df757.zip
gcc-e6f1275f861e69c54e4812870d5c05c8c72df757.tar.gz
gcc-e6f1275f861e69c54e4812870d5c05c8c72df757.tar.bz2
pt.c (complete_template_args): Rewrite.
* pt.c (complete_template_args): Rewrite. (tsubst, FUNCTION_DECL): Use it. * semantics.c (finish_asm_stmt): Fix combine strings. Call c_expand_asm_operands () if output_operands, input_operands or clobbers is not NULL_TREE. * pt.c (complete_template_args): New function. (get_bindings): Deal with specializations of function templates with return type containing parameters from outer class templates. (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, substitute arguments and compose a new type. From-SVN: r18724
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog20
-rw-r--r--gcc/cp/pt.c134
-rw-r--r--gcc/cp/semantics.c5
3 files changed, 140 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5c41abc..6c7d567 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,23 @@
+Fri Mar 20 10:42:07 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (complete_template_args): Rewrite.
+ (tsubst, FUNCTION_DECL): Use it.
+
+Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org)
+
+ * semantics.c (finish_asm_stmt): Fix combine strings. Call
+ c_expand_asm_operands () if output_operands, input_operands or
+ clobbers is not NULL_TREE.
+
+Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * pt.c (complete_template_args): New function.
+ (get_bindings): Deal with specializations of function templates
+ with return type containing parameters from outer class
+ templates.
+ (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level,
+ substitute arguments and compose a new type.
+
Thu Mar 19 19:01:48 1998 Mark Mitchell <mmitchell@usa.net>
* pt.c (tsubst): Clear DECL_PENDING_INLINE_INFO for new
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6102bea..d372e11 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -81,6 +81,7 @@ static tree get_class_bindings PROTO((tree, tree, tree, tree));
static tree coerce_template_parms PROTO((tree, tree, tree, int, int, int));
static tree tsubst_enum PROTO((tree, tree, tree *));
static tree add_to_template_args PROTO((tree, tree));
+static tree complete_template_args PROTO((tree, tree, int));
static int type_unification_real PROTO((tree, tree *, tree, tree,
int, int, int));
static void note_template_header PROTO((int));
@@ -340,6 +341,103 @@ is_member_template (t)
return 0;
}
+/* Return a new template argument vector which contains all of ARGS
+ for all outer templates TYPE is contained in, but has as its
+ innermost set of arguments the EXTRA_ARGS. If UNBOUND_ONLY, we
+ are only interested in unbound template arguments, not arguments from
+ enclosing templates that have been instantiated already. */
+
+static tree
+complete_template_args (tmpl, extra_args, unbound_only)
+ tree tmpl, extra_args;
+ int unbound_only;
+{
+ /* depth is the number of levels of enclosing args we're adding. */
+ int depth, i;
+ tree args, new_args, spec_args = NULL_TREE;
+
+ my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+ my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0);
+
+ if (DECL_TEMPLATE_INFO (tmpl) && !unbound_only)
+ {
+ /* A specialization of a member template of a template class shows up
+ as a TEMPLATE_DECL with DECL_TEMPLATE_SPECIALIZATION set.
+ DECL_TI_ARGS is the specialization args, and DECL_TI_TEMPLATE
+ is the template being specialized. */
+ if (DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ {
+ spec_args = DECL_TI_ARGS (tmpl);
+ tmpl = DECL_TI_TEMPLATE (tmpl);
+ }
+
+ if (DECL_TEMPLATE_INFO (tmpl))
+ {
+ /* A partial instantiation of a member template shows up as a
+ TEMPLATE_DECL with DECL_TEMPLATE_INFO. DECL_TI_ARGS is
+ all the bound template arguments. */
+ args = DECL_TI_ARGS (tmpl);
+ if (TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC)
+ depth = 1;
+ else
+ depth = TREE_VEC_LENGTH (args);
+ }
+ else
+ /* If we are a specialization, we might have no previously bound
+ template args. */
+ depth = 0;
+
+ new_args = make_tree_vec (depth + 1 + (!!spec_args));
+
+ if (depth == 1)
+ TREE_VEC_ELT (new_args, 0) = args;
+ else
+ for (i = 0; i < depth; ++i)
+ TREE_VEC_ELT (new_args, i) = TREE_VEC_ELT (args, i);
+ }
+ else
+ {
+ tree type;
+ int skip;
+
+ /* For unbound args, we have to do more work. We are getting bindings
+ for the innermost args from extra_args, so we start from our
+ context and work out until we've seen all the args. We need to
+ do it this way to handle partial specialization. */
+
+ depth = list_length (DECL_TEMPLATE_PARMS (tmpl)) - 1;
+ if (depth == 0)
+ return extra_args;
+
+ new_args = make_tree_vec (depth + 1);
+
+ if (! is_member_template (tmpl))
+ /* If this isn't a member template, extra_args is for the innermost
+ template class, so skip over it. */
+ skip = 1;
+
+ type = DECL_REAL_CONTEXT (tmpl);
+ for (i = depth; i; type = TYPE_CONTEXT (type))
+ if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
+ {
+ if (skip)
+ skip = 0;
+ else
+ {
+ --i;
+ TREE_VEC_ELT (new_args, i) = CLASSTYPE_TI_ARGS (type);
+ }
+ }
+ }
+
+ TREE_VEC_ELT (new_args, depth) = extra_args;
+
+ if (spec_args)
+ TREE_VEC_ELT (new_args, depth + 1) = spec_args;
+
+ return new_args;
+}
+
/* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. */
@@ -3591,7 +3689,20 @@ tsubst (t, args, in_decl)
{
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
- r = copy_node (t);
+
+ if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+ && CLASSTYPE_TEMPLATE_INFO (t))
+ {
+ tree argvec = tsubst (CLASSTYPE_TI_ARGS (t),
+ args, in_decl);
+ r = lookup_template_class (TYPE_NAME (t), argvec, in_decl,
+ DECL_CONTEXT (TYPE_NAME (t)));
+ r = cp_build_type_variant (r, TYPE_READONLY (t),
+ TYPE_VOLATILE (t));
+ }
+ else
+ r = copy_node (t);
+
TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r, levels);
@@ -3804,21 +3915,8 @@ tsubst (t, args, in_decl)
/* Start by getting the innermost args. */
argvec = tsubst (DECL_TI_ARGS (t), args, in_decl);
- /* If tmpl is an instantiation of a member template, tack on
- the args for the enclosing class. NOTE: this will change
- for member class templates. The generalized procedure
- is to grab the outer args, then tack on the current args,
- then any specialized args. */
- if (DECL_TEMPLATE_INFO (tmpl) && DECL_TI_ARGS (tmpl))
- {
- if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
- argvec = add_to_template_args (DECL_TI_ARGS (tmpl), argvec);
- else
- /* In this case, we are instantiating a
- specialization. The innermost template args are
- already given by the specialization. */
- argvec = add_to_template_args (argvec, DECL_TI_ARGS (tmpl));
- }
+ if (DECL_TEMPLATE_INFO (tmpl))
+ argvec = complete_template_args (tmpl, argvec, 0);
/* Do we already have this instantiation? */
spec = retrieve_specialization (tmpl, argvec);
@@ -5701,7 +5799,9 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
if (check_rettype)
{
/* Check to see that the resulting return type is also OK. */
- tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, NULL_TREE);
+ tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)),
+ complete_template_args (fn, targs, 1),
+ NULL_TREE);
if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
return NULL_TREE;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f302246..79f5038 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -709,7 +709,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
tree clobbers;
{
if (TREE_CHAIN (string))
- combine_strings (string);
+ string = combine_strings (string);
if (processing_template_decl)
{
@@ -721,7 +721,8 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
else
{
emit_line_note (input_filename, lineno);
- if (output_operands != NULL_TREE)
+ if (output_operands != NULL_TREE || input_operands != NULL_TREE
+ || clobbers != NULL_TREE)
{
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])