Commit ec255269 by Mike Stump

84th Cygnus<->FSF merge

From-SVN: r11399
parent 9725066d
Fri Mar 1 13:09:33 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): If we don't have a pattern
yet, that's OK.
(coerce_template_parms): If we see a local class, bail.
* decl.c (grok_reference_init): Make sure there's a type before
checking its code.
* pt.c (do_function_instantiation): Avoid crashing on invalid decls.
(push_template_decl): Ditto.
* parse.y (named_class_head): Set
CLASSTYPE_TEMPLATE_SPECIALIZATION here if we have basetypes.
* decl.c (xref_tag): Diagnose redeclaration of template
type-parameter name.
* error.c (dump_type): Handle anonymous template type parms.
* pt.c (instantiate_template): Use TYPE_MAIN_DECL instead of
TYPE_STUB_DECL.
(coerce_template_parms): Ditto.
Thu Feb 29 16:26:01 1996 Mike Stump <mrs@cygnus.com>
* class.c (instantiate_type, case {ARRAY,INDIRECT}_REF,
case ADDR_EXPR): Don't modify rhs if a subinstantiation fails.
Thu Feb 29 08:20:25 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_template): Take the MAIN_VARIANT of the type
before trying to get its STUB_DECL.
(coerce_template_parms): Ditto.
* parse.y (template_type_parm): If they didn't use 'class',
pretend they did after giving an error.
* pt.c (coerce_template_parms): Diagnose use of local class.
* decl.c (grok_reference_init): Use instantiate_type.
* error.c (dump_expr): Handle TEMPLATE_DECLs.
* parse.y (named_class_head): Diagnose mismatching types and tags.
* decl.c (pushdecl): Type decls and class templates clash with
artificial type decls, not hide them.
* decl.c (redeclaration_error_message): Diagnose redefinition of
templates properly.
(duplicate_decls): Diagnose disallowed overloads for template
functions, too.
* decl.c (start_decl): Call complete_type before checking for a
destructor.
* pt.c (tsubst): Use tsubst_expr on the elts of a VEC.
* decl.c (xref_tag): A TEMPLATE_TYPE_PARM is a match.
Wed Feb 28 09:28:44 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grok_op_properties): Don't check for operator++(int) in
a template.
* tree.c (perm_manip): Return a copy of variable and function
decls with external linkage.
* tree.def: Change some of the min tree codes to type "1".
* pt.c (uses_template_parms): Handle 'e's, return 1 for LOOKUP_EXPRs.
* method.c (build_overload_int): Emit something arbitrary for
anything but an INTEGER_CST if we're in a template.
* decl.c (cp_finish_decl): Call complete_type before deciding
whether or not to lay out the decl.
* lex.c (do_identifier): Check for DECL_INITIAL before using it.
Tue Feb 27 16:35:32 1996 Jason Merrill <jason@yorick.cygnus.com>
......
......@@ -4842,9 +4842,12 @@ root_lang_context_p ()
/* Type instantiation routines. */
/* This function will instantiate the type of the expression given
in RHS to match the type of LHSTYPE. If LHSTYPE is NULL_TREE,
or other errors exist, the TREE_TYPE of RHS will be ERROR_MARK_NODE.
/* This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE. If errors exist, then return
error_mark_node. If only complain is COMPLAIN is set. If we are
not complaining, never modify rhs, as overload resolution wants to
try many possible instantiations, in hopes that at least one will
work.
This function is used in build_modify_expr, convert_arguments,
build_c_cast, and compute_conversion_costs. */
......@@ -4880,14 +4883,18 @@ instantiate_type (lhstype, rhs, complain)
case INDIRECT_REF:
case ARRAY_REF:
TREE_TYPE (rhs) = lhstype;
lhstype = build_pointer_type (lhstype);
TREE_OPERAND (rhs, 0)
= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
if (TREE_OPERAND (rhs, 0) == error_mark_node)
return error_mark_node;
{
tree new_rhs;
return rhs;
new_rhs = instantiate_type (build_pointer_type (lhstype),
TREE_OPERAND (rhs, 0), complain);
if (new_rhs == error_mark_node)
return error_mark_node;
TREE_TYPE (rhs) = lhstype;
TREE_OPERAND (rhs, 0) = new_rhs;
return rhs;
}
case NOP_EXPR:
rhs = copy_node (TREE_OPERAND (rhs, 0));
......@@ -5262,13 +5269,12 @@ instantiate_type (lhstype, rhs, complain)
error ("type for resolving address of overloaded function must be pointer type");
return error_mark_node;
}
TREE_TYPE (rhs) = lhstype;
lhstype = TREE_TYPE (lhstype);
{
tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
if (fn == error_mark_node)
return error_mark_node;
mark_addressable (fn);
TREE_TYPE (rhs) = lhstype;
TREE_OPERAND (rhs, 0) = fn;
TREE_CONSTANT (rhs) = staticp (fn);
}
......
......@@ -116,9 +116,9 @@ DEFTREECODE (USING_DECL, "using_decl", "d", 0)
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
DEFTREECODE (CAST_EXPR, "cast_expr", "e", 1)
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "e", 1)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "e", 1)
DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "1", 1)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
......
......@@ -2501,6 +2501,14 @@ duplicate_decls (newdecl, olddecl)
cp_error_at ("conflicts with previous declaration `%#D'",
olddecl);
}
else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
return 0;
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
......@@ -3044,8 +3052,15 @@ pushdecl (x)
}
else if (TREE_CODE (t) != TREE_CODE (x))
{
if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
|| (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
&& TREE_CODE (x) != TYPE_DECL
&& ! (TREE_CODE (x) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (x)) == TYPE_DECL))
|| (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
&& TREE_CODE (t) != TYPE_DECL
&& ! (TREE_CODE (t) == TEMPLATE_DECL
&& (TREE_CODE (DECL_TEMPLATE_RESULT (t))
== TYPE_DECL))))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
......@@ -3714,7 +3729,12 @@ redeclaration_error_message (newdecl, olddecl)
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
if (DECL_INITIAL (olddecl) && DECL_INITIAL (newdecl))
if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
&& DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
&& DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
|| (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
&& TYPE_SIZE (TREE_TYPE (newdecl))
&& TYPE_SIZE (TREE_TYPE (olddecl))))
return "redefinition of `%#D'";
return 0;
}
......@@ -5737,7 +5757,7 @@ start_decl (declarator, declspecs, initialized, raises)
/* Don't lose if destructors must be executed at file-level. */
if (! current_template_parms && TREE_STATIC (decl)
&& TYPE_NEEDS_DESTRUCTOR (type)
&& TYPE_NEEDS_DESTRUCTOR (complete_type (type))
&& !TREE_PERMANENT (decl))
{
push_obstacks (&permanent_obstack, &permanent_obstack);
......@@ -6029,6 +6049,10 @@ grok_reference_init (decl, type, init, cleanupp)
return;
}
if (TREE_TYPE (init) && TREE_CODE (TREE_TYPE (init)) == UNKNOWN_TYPE)
/* decay_conversion is probably wrong for references to functions. */
init = decay_conversion (instantiate_type (TREE_TYPE (type), init, 1));
if (TREE_CODE (init) == TREE_LIST)
init = build_compound_expr (init);
......@@ -6417,7 +6441,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (TREE_CODE (decl) == VAR_DECL)
{
if (DECL_SIZE (decl) == NULL_TREE
&& TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
&& TYPE_SIZE (complete_type (TREE_TYPE (decl))) != NULL_TREE)
layout_decl (decl, 0);
if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE)
......@@ -10152,6 +10176,7 @@ grok_op_properties (decl, virtualp, friendp)
{
if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
&& ! current_template_parms
&& TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
{
if (methodp)
......@@ -10259,11 +10284,16 @@ xref_tag (code_type_node, name, binfo, globalize)
}
else
t = IDENTIFIER_TYPE_VALUE (name);
if (t && TREE_CODE (t) != code)
if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM)
t = NULL_TREE;
if (! globalize)
{
if (pedantic && t && TREE_CODE (t) == TEMPLATE_TYPE_PARM)
{
cp_pedwarn ("redeclaration of template type-parameter `%T'", name);
cp_pedwarn_at (" previously declared here", t);
}
/* If we know we are defining this tag, only look it up in this scope
* and don't try to find it as a type. */
if (t && TYPE_CONTEXT(t) && TREE_MANGLED (name))
......
......@@ -209,7 +209,10 @@ dump_type (t, v)
break;
case TEMPLATE_TYPE_PARM:
OB_PUTID (TYPE_IDENTIFIER (t));
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
OB_PUTS ("{anonymous template type parm}");
break;
/* This is not always necessary for pointers and such, but doing this
......@@ -941,6 +944,7 @@ dump_expr (t, nop)
case FIELD_DECL:
case CONST_DECL:
case FUNCTION_DECL:
case TEMPLATE_DECL:
dump_decl (t, -1);
break;
......
......@@ -364,7 +364,8 @@ build_overload_int (value)
OB_PUTC ('_');
return;
}
else if (uses_template_parms (value))
else if (current_template_parms
&& TREE_CODE (value) != INTEGER_CST)
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
errors we'll notice. */
......
......@@ -427,7 +427,10 @@ template_type_parm:
if (TREE_PURPOSE ($$) == signature_type_node)
sorry ("signature as template type parameter");
else if (TREE_PURPOSE ($$) != class_type_node)
pedwarn ("template type parameters must use the keyword `class'");
{
pedwarn ("template type parameters must use the keyword `class'");
TREE_PURPOSE ($$) = class_type_node;
}
}
| aggr identifier
{ $$ = build_tree_list ($1, $2); goto ttpa; }
......@@ -2129,8 +2132,24 @@ named_class_head:
| named_complex_class_head_sans_basetype maybe_base_class_list
{
$$ = TREE_TYPE ($1);
if (TREE_INT_CST_LOW (current_aggr) == union_type
&& TREE_CODE ($$) != UNION_TYPE)
cp_pedwarn ("`union' tag used in declaring `%#T'", $$);
else if (TREE_CODE ($$) == UNION_TYPE
&& TREE_INT_CST_LOW (current_aggr) != union_type)
cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$);
if ($2)
xref_basetypes (current_aggr, $1, $$, $2);
{
if (IS_AGGR_TYPE ($$) && CLASSTYPE_USE_TEMPLATE ($$))
{
if (CLASSTYPE_IMPLICIT_INSTANTIATION ($$)
&& TYPE_SIZE ($$) == NULL_TREE)
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
cp_error ("specialization after instantiation of `%T'", $$);
}
xref_basetypes (current_aggr, $1, $$, $2);
}
}
;
......
......@@ -253,6 +253,8 @@ push_template_decl (decl)
CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (tmpl)) = info;
DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl));
}
else if (! DECL_LANG_SPECIFIC (decl))
cp_error ("template declaration of `%#D'", decl);
else
DECL_TEMPLATE_INFO (decl) = info;
}
......@@ -352,12 +354,24 @@ coerce_template_parms (parms, arglist, in_decl)
continue;
}
if (is_type)
val = groktypename (arg);
{
val = groktypename (arg);
if (! current_template_parms)
{
tree t = target_type (val);
if (IS_AGGR_TYPE (t)
&& decl_function_context (TYPE_MAIN_DECL (t)))
{
cp_error ("type `%T' composed from a local class is not a valid template-argument", val);
return error_mark_node;
}
}
}
else
{
tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
TREE_VEC_LENGTH (vec), in_decl);
if (current_template_parms && uses_template_parms (arg))
if (current_template_parms)
val = arg;
else
val = digest_init (t, arg, (tree *) 0);
......@@ -844,6 +858,7 @@ uses_template_parms (t)
/* NOTREACHED */
return 0;
case LOOKUP_EXPR:
case TYPENAME_TYPE:
return 1;
......@@ -857,7 +872,7 @@ uses_template_parms (t)
{
case '1':
case '2':
case '3':
case 'e':
case '<':
{
int i;
......@@ -980,11 +995,7 @@ instantiate_class_template (type)
pattern = TREE_TYPE (template);
if (TYPE_SIZE (pattern) == NULL_TREE)
{
cp_error_at ("no definition available for `%#D'", template);
cp_error (" trying to instantiate `%#T'", type);
return error_mark_node;
}
return type;
TYPE_BEING_DEFINED (type) = 1;
......@@ -1608,7 +1619,7 @@ tsubst (t, args, nargs, in_decl)
for (i = 0; i < len; i++)
{
elts[i] = tsubst_copy (TREE_VEC_ELT (t, i), args, nargs, in_decl);
elts[i] = tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl);
if (elts[i] != TREE_VEC_ELT (t, i))
need_new = 1;
}
......@@ -2287,7 +2298,7 @@ instantiate_template (tmpl, targ_ptr)
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
{
tree nt = target_type (t);
if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_STUB_DECL (nt)))
if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt)))
{
cp_error ("type `%T' composed from a local class is not a valid template-argument", t);
cp_error (" trying to instantiate `%D'", tmpl);
......@@ -2696,6 +2707,12 @@ do_function_instantiation (declspecs, declarator, storage)
tree result = NULL_TREE;
int extern_p = 0;
if (! DECL_LANG_SPECIFIC (decl))
{
cp_error ("explicit instantiation of non-template `%#D'", decl);
return;
}
/* If we've already seen this template instance, use it. */
if (name = DECL_ASSEMBLER_NAME (decl),
fn = IDENTIFIER_GLOBAL_VALUE (name),
......
......@@ -1625,6 +1625,10 @@ perm_manip (t)
{
if (TREE_PERMANENT (t))
return t;
/* Support `void f () { extern int i; A<&i> a; }' */
if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
&& TREE_PUBLIC (t))
return copy_node (t);
return NULL_TREE;
}
......
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