mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-12 02:04:47 +08:00
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
This commit is contained in:
parent
7aa74e4c2f
commit
e6f1275f86
@ -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
|
||||
|
134
gcc/cp/pt.c
134
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;
|
||||
|
@ -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])
|
||||
|
Loading…
Reference in New Issue
Block a user