Commit e7e66632 by Kriang Lerdsuwanakij Committed by Jason Merrill

error.c (dump_decl): Fix type of default arguments for template template parameters and nontype...

	* error.c (dump_decl): Fix type of default arguments for template
	template parameters and nontype template parameters.
	* parse.y (template_parm): Handle invalid default template
	template arguments here.
	* parse.y (template_parm): Use template_arg instead of PTYPENAME
	for default template template argument.
	* pt.c (coerce_template_parms): Merge default template argument
	codes.  Can treat RECORD_TYPE as template name if it is implicitly
	created.  Fix argument index in error message.
	* typeck.c (comptypes): Merge template argument comparison codes in
	TEMPLATE_TEMPLATE_PARM and RECORD_TYPE.

From-SVN: r17650
parent d47d138a
Tue Feb 3 22:04:01 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
* error.c (dump_decl): Fix type of default arguments for template
template parameters and nontype template parameters.
* parse.y (template_parm): Handle invalid default template
template arguments here.
* parse.y (template_parm): Use template_arg instead of PTYPENAME
for default template template argument.
* pt.c (coerce_template_parms): Merge default template argument
codes. Can treat RECORD_TYPE as template name if it is implicitly
created. Fix argument index in error message.
* typeck.c (comptypes): Merge template argument comparison codes in
TEMPLATE_TEMPLATE_PARM and RECORD_TYPE.
Tue Jan 6 01:42:44 1998 Mumit Khan <khan@xraylith.wisc.edu> Tue Jan 6 01:42:44 1998 Mumit Khan <khan@xraylith.wisc.edu>
* lex.c (file_name_nondirectory): Also check for '/'. * lex.c (file_name_nondirectory): Also check for '/'.
......
...@@ -789,10 +789,11 @@ dump_decl (t, v) ...@@ -789,10 +789,11 @@ dump_decl (t, v)
if (defval) if (defval)
{ {
OB_PUTS (" = "); OB_PUTS (" = ");
if (TREE_CODE (arg) == TYPE_DECL) if (TREE_CODE (arg) == TYPE_DECL
|| TREE_CODE (arg) == TEMPLATE_DECL)
dump_type (defval, 1); dump_type (defval, 1);
else else
dump_decl (defval, 1); dump_expr (defval, 1);
} }
OB_PUTC2 (',', ' '); OB_PUTC2 (',', ' ');
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -512,19 +512,17 @@ template_parm: ...@@ -512,19 +512,17 @@ template_parm:
{ $$ = build_tree_list ($3, $1.t); } { $$ = build_tree_list ($3, $1.t); }
| template_template_parm | template_template_parm
{ $$ = build_tree_list (NULL_TREE, $1); } { $$ = build_tree_list (NULL_TREE, $1); }
| template_template_parm '=' PTYPENAME | template_template_parm '=' template_arg
{ {
tree defarg; if (TREE_CODE ($3) != TEMPLATE_DECL
arg_looking_for_template = 1; && TREE_CODE ($3) != TEMPLATE_TEMPLATE_PARM
defarg = lookup_name ($3, 0); && TREE_CODE ($3) != TYPE_DECL)
arg_looking_for_template = 0; {
error ("invalid default template argument");
if (!defarg || defarg == error_mark_node $3 = error_mark_node;
|| (TREE_CODE (defarg) != TEMPLATE_DECL }
&& TREE_CODE (defarg) != TEMPLATE_TEMPLATE_PARM)) $$ = build_tree_list ($3, $1);
defarg = do_identifier ($3, 1); }
$$ = build_tree_list (defarg, $1);
}
; ;
template_def: template_def:
...@@ -3071,10 +3069,7 @@ nonnested_type: ...@@ -3071,10 +3069,7 @@ nonnested_type:
{ {
if (TREE_CODE ($1) == IDENTIFIER_NODE) if (TREE_CODE ($1) == IDENTIFIER_NODE)
{ {
arg_looking_for_template = processing_template_arg;
$$ = lookup_name ($1, 1); $$ = lookup_name ($1, 1);
arg_looking_for_template = 0;
if (current_class_type if (current_class_type
&& TYPE_BEING_DEFINED (current_class_type) && TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE ($1)) && ! IDENTIFIER_CLASS_VALUE ($1))
......
...@@ -1744,36 +1744,14 @@ coerce_template_parms (parms, arglist, in_decl, ...@@ -1744,36 +1744,14 @@ coerce_template_parms (parms, arglist, in_decl,
return error_mark_node; return error_mark_node;
} }
if (arglist && TREE_CODE (arglist) == TREE_VEC) if (arglist && TREE_CODE (arglist) == TREE_VEC && nargs == nparms)
{ vec = copy_node (arglist);
if (nargs == nparms)
vec = copy_node (arglist);
else
{
/* We arrive here when a template with some default arguments
is used as template template argument. */
is_tmpl_parm = 1;
vec = make_tree_vec (nparms);
for (i = 0; i < nparms; i++)
{
tree arg;
if (i < nargs)
arg = TREE_VEC_ELT (arglist, i);
else if (TREE_CODE (TREE_VALUE (TREE_VEC_ELT (parms, i)))
== TYPE_DECL)
arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (parms, i)),
vec, i, in_decl);
else
arg = tsubst_expr (TREE_PURPOSE (TREE_VEC_ELT (parms, i)),
vec, i, in_decl);
TREE_VEC_ELT (vec, i) = arg;
}
}
}
else else
{ {
/* We can arrive here with arglist being a TREE_VEC when a
template with some default arguments is used as template
template argument. */
is_tmpl_parm = TREE_CODE (arglist) == TREE_VEC;
vec = make_tree_vec (nparms); vec = make_tree_vec (nparms);
for (i = 0; i < nparms; i++) for (i = 0; i < nparms; i++)
...@@ -1791,6 +1769,12 @@ coerce_template_parms (parms, arglist, in_decl, ...@@ -1791,6 +1769,12 @@ coerce_template_parms (parms, arglist, in_decl,
else else
arg = TREE_VALUE (arg); arg = TREE_VALUE (arg);
} }
else if (is_tmpl_parm && i < nargs)
{
arg = TREE_VEC_ELT (arglist, i);
if (arg == error_mark_node)
lost++;
}
else if (TREE_PURPOSE (parm) == NULL_TREE) else if (TREE_PURPOSE (parm) == NULL_TREE)
{ {
my_friendly_assert (!require_all_arguments, 0); my_friendly_assert (!require_all_arguments, 0);
...@@ -1846,20 +1830,29 @@ coerce_template_parms (parms, arglist, in_decl, ...@@ -1846,20 +1830,29 @@ coerce_template_parms (parms, arglist, in_decl,
arg = TREE_VALUE (arg); arg = TREE_VALUE (arg);
} }
/* Check if it is a class template. */ requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
requires_type = TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type;
/* Check if it is a class template. If REQUIRES_TMPL_TYPE is true,
we also accept implicitly created TYPE_DECL as a valid argument. */
is_tmpl_type = (TREE_CODE (arg) == TEMPLATE_DECL is_tmpl_type = (TREE_CODE (arg) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
&& !CLASSTYPE_TEMPLATE_INFO (arg)); && !CLASSTYPE_TEMPLATE_INFO (arg))
|| (TREE_CODE (arg) == RECORD_TYPE
&& CLASSTYPE_TEMPLATE_INFO (arg)
&& TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
&& DECL_ARTIFICIAL (TYPE_NAME (arg))
&& requires_tmpl_type);
if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
arg = TYPE_STUB_DECL (arg); arg = TYPE_STUB_DECL (arg);
else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
arg = CLASSTYPE_TI_TEMPLATE (arg);
requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't' is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
|| is_tmpl_type || is_tmpl_type
|| (is_tmpl_parm && TREE_CODE (arg) == TYPE_DECL); || (is_tmpl_parm && TREE_CODE (arg) == TYPE_DECL);
requires_type = TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type;
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM) && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
...@@ -1896,7 +1889,7 @@ coerce_template_parms (parms, arglist, in_decl, ...@@ -1896,7 +1889,7 @@ coerce_template_parms (parms, arglist, in_decl,
if (in_decl) if (in_decl)
{ {
cp_error ("type/value mismatch at argument %d in template parameter list for `%D'", cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
i, in_decl); i + 1, in_decl);
if (is_tmpl_type) if (is_tmpl_type)
cp_error (" expected a type, got `%T'", DECL_NAME (arg)); cp_error (" expected a type, got `%T'", DECL_NAME (arg));
else else
......
...@@ -749,10 +749,21 @@ comptypes (type1, type2, strict) ...@@ -749,10 +749,21 @@ comptypes (type1, type2, strict)
switch (TREE_CODE (t1)) switch (TREE_CODE (t1))
{ {
case TEMPLATE_TEMPLATE_PARM:
if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
|| TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
return 0;
if (! CLASSTYPE_TEMPLATE_INFO (t1) && ! CLASSTYPE_TEMPLATE_INFO (t2))
return 1;
/* Don't check inheritance. */
strict = 1;
/* fall through */
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2) if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
&& CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)) && (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
{ {
int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1)); int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0); tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
...@@ -845,37 +856,6 @@ comptypes (type1, type2, strict) ...@@ -845,37 +856,6 @@ comptypes (type1, type2, strict)
val = comp_array_types (comptypes, t1, t2, strict); val = comp_array_types (comptypes, t1, t2, strict);
break; break;
case TEMPLATE_TEMPLATE_PARM:
if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
|| TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
return 0;
if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2))
{
int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
tree *p2 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t2), 0);
while (i--)
{
if (TREE_CODE_CLASS (TREE_CODE (p1[i])) == 't')
{
if (! comptypes (p1[i], p2[i], 1))
return 0;
}
else
{
if (simple_cst_equal (p1[i], p2[i]) <= 0)
return 0;
}
}
return 1;
}
else if (CLASSTYPE_TEMPLATE_INFO (t1) || CLASSTYPE_TEMPLATE_INFO (t2))
return 0;
else
return 1;
case TEMPLATE_TYPE_PARM: case TEMPLATE_TYPE_PARM:
return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2) return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
&& TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2); && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment