pt.c (instantiate_decl): Abort if we see a member constant instantiation that doesn't already have its...

* pt.c (instantiate_decl): Abort if we see a member constant
        instantiation that doesn't already have its initializer.
        Downgrade explicit instantiation without definition to pedwarn.

        * cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
        * class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
        (import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.

        * cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
        (pending_vtables): Remove.
        * decl2.c (pending_vtables): Remove.
        (import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
        CLASSTYPE_VTABLE_NEEDS_WRITING.
        (import_export_class): Likewise.
        (init_decl2): Don't mark pending_vtables.
        * lex.c (handle_pragma_vtable): Just sorry.
        * pt.c (instantiate_class_template): Don't mess with
        CLASSTYPE_VTABLE_NEEDS_WRITING.
        (mark_class_instantiated): Likewise.
        * ptree.c (print_lang_type): Don't print it.
        * semantics.c (begin_class_definition): Don't set it.

        * pt.c (template_tail): Replace with last_pending_template.
        (maybe_templates, maybe_template_tail): Remove.
        (add_pending_template): Adjust.
        (instantiate_pending_templates): Adjust.

        * cp-tree.h (struct saved_scope): Remove lang_stack field.
        (current_lang_stack): Remove.
        * decl.c (maybe_push_to_top_level): Don't initialize it.
        (duplicate_decls): Use current_lang_depth.
        (xref_basetypes): Likewise.
        * class.c (current_lang_depth): New fn.
        (push_lang_context): Use more varray functionality.
        (pop_lang_context): Likewise.

From-SVN: r40724
This commit is contained in:
Jason Merrill 2001-03-21 19:55:13 -05:00 committed by Jason Merrill
parent 64d9c3fede
commit 46ccf50a6f
11 changed files with 92 additions and 128 deletions

View File

@ -1,4 +1,40 @@
2001-03-20 Jason Merrill <jason@redhat.com>
2001-03-21 Jason Merrill <jason@redhat.com>
* pt.c (instantiate_decl): Abort if we see a member constant
instantiation that doesn't already have its initializer.
Downgrade explicit instantiation without definition to pedwarn.
* cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
* class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
(import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.
* cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
(pending_vtables): Remove.
* decl2.c (pending_vtables): Remove.
(import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
CLASSTYPE_VTABLE_NEEDS_WRITING.
(import_export_class): Likewise.
(init_decl2): Don't mark pending_vtables.
* lex.c (handle_pragma_vtable): Just sorry.
* pt.c (instantiate_class_template): Don't mess with
CLASSTYPE_VTABLE_NEEDS_WRITING.
(mark_class_instantiated): Likewise.
* ptree.c (print_lang_type): Don't print it.
* semantics.c (begin_class_definition): Don't set it.
* pt.c (template_tail): Replace with last_pending_template.
(maybe_templates, maybe_template_tail): Remove.
(add_pending_template): Adjust.
(instantiate_pending_templates): Adjust.
* cp-tree.h (struct saved_scope): Remove lang_stack field.
(current_lang_stack): Remove.
* decl.c (maybe_push_to_top_level): Don't initialize it.
(duplicate_decls): Use current_lang_depth.
(xref_basetypes): Likewise.
* class.c (current_lang_depth): New fn.
(push_lang_context): Use more varray functionality.
(pop_lang_context): Likewise.
* error.c (GLOBAL_THING): Always use '__'.

View File

@ -5757,6 +5757,14 @@ pop_nested_class ()
pop_nested_class ();
}
/* Returns the number of extern "LANG" blocks we are nested within. */
int
current_lang_depth ()
{
return VARRAY_ACTIVE_SIZE (current_lang_base);
}
/* Set global variables CURRENT_LANG_NAME to appropriate value
so that behavior of name-mangling machinery is correct. */
@ -5764,15 +5772,7 @@ void
push_lang_context (name)
tree name;
{
*current_lang_stack++ = current_lang_name;
if (current_lang_stack - &VARRAY_TREE (current_lang_base, 0)
>= (ptrdiff_t) VARRAY_SIZE (current_lang_base))
{
size_t old_size = VARRAY_SIZE (current_lang_base);
VARRAY_GROW (current_lang_base, old_size + 10);
current_lang_stack = &VARRAY_TREE (current_lang_base, old_size);
}
VARRAY_PUSH_TREE (current_lang_base, current_lang_name);
if (name == lang_name_cplusplus)
{
@ -5807,10 +5807,8 @@ push_lang_context (name)
void
pop_lang_context ()
{
/* Clear the current entry so that garbage collector won't hold on
to it. */
*current_lang_stack = NULL_TREE;
current_lang_name = *--current_lang_stack;
current_lang_name = VARRAY_TOP_TREE (current_lang_base);
VARRAY_POP (current_lang_base);
}
/* Type instantiation routines. */
@ -7847,8 +7845,7 @@ build_vtable_entry (delta, vcall_index, entry, generate_with_vtable_p)
fn = TREE_OPERAND (entry, 0);
if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
&& fn != abort_fndecl
&& !DECL_TINFO_FN_P (fn))
&& fn != abort_fndecl)
{
entry = make_thunk (entry, delta, vcall_index,
generate_with_vtable_p);

View File

@ -787,7 +787,6 @@ struct saved_scope {
tree access_specifier;
tree function_decl;
varray_type lang_base;
tree *lang_stack;
tree lang_name;
tree template_parms;
tree x_previous_class_type;
@ -830,7 +829,6 @@ struct saved_scope {
/* Pointer to the top of the language name stack. */
#define current_lang_stack scope_chain->lang_stack
#define current_lang_base scope_chain->lang_base
#define current_lang_name scope_chain->lang_name
@ -1296,7 +1294,7 @@ struct lang_type
unsigned com_interface : 1;
unsigned non_pod_class : 1;
unsigned nearly_empty_p : 1;
unsigned vtable_needs_writing : 1;
unsigned user_align : 1;
unsigned has_assign_ref : 1;
unsigned has_new : 1;
unsigned has_array_new : 1;
@ -1328,7 +1326,6 @@ struct lang_type
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
unsigned user_align : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@ -1337,7 +1334,7 @@ struct lang_type
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
unsigned dummy : 8;
unsigned dummy : 9;
int vsize;
@ -1573,10 +1570,6 @@ struct lang_type
and there is no need to change it. */
#define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->needs_virtual_reinit)
/* Nonzero means that if this type has virtual functions, that
the virtual function table will be written out. */
#define CLASSTYPE_VTABLE_NEEDS_WRITING(NODE) (TYPE_LANG_SPECIFIC(NODE)->vtable_needs_writing)
/* Nonzero means that this type has an X() constructor. */
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->has_default_ctor)
@ -1824,11 +1817,10 @@ struct lang_decl_flags
unsigned pending_inline_p : 1;
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1;
unsigned tinfo_fn_p : 1;
unsigned assignment_operator_p : 1;
unsigned anticipated_p : 1;
unsigned generate_with_vtable_p : 1;
/* One unused bit. */
/* Two unused bits. */
union {
/* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
@ -2032,17 +2024,6 @@ struct lang_decl
#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p)
/* Non-zero for a FUNCTION_DECL that declares a type-info function.
This only happens in the old abi. */
#define DECL_TINFO_FN_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL \
&& DECL_ARTIFICIAL (NODE) \
&& DECL_LANG_SPECIFIC(NODE)->decl_flags.tinfo_fn_p)
/* Mark NODE as a type-info function. */
#define SET_DECL_TINFO_FN_P(NODE) \
(DECL_LANG_SPECIFIC((NODE))->decl_flags.tinfo_fn_p = 1)
/* Nonzero if NODE is an overloaded `operator delete[]' function. */
#define DECL_ARRAY_DELETE_OPERATOR_P(NODE) \
(DECL_OVERLOADED_OPERATOR_P (NODE) == VEC_DELETE_EXPR)
@ -3190,9 +3171,6 @@ extern int warn_nontemplate_friend;
/* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list;
/* A list of virtual function tables we must make sure to write out. */
extern tree pending_vtables;
/* Node for "pointer to (virtual) function".
This may be distinct from ptr_type_node so gdb can distinguish them. */
#define vfunc_ptr_type_node \
@ -3727,6 +3705,7 @@ extern void pushclass PARAMS ((tree, int));
extern void popclass PARAMS ((void));
extern void push_nested_class PARAMS ((tree, int));
extern void pop_nested_class PARAMS ((void));
extern int current_lang_depth PARAMS ((void));
extern void push_lang_context PARAMS ((tree));
extern void pop_lang_context PARAMS ((void));
extern tree instantiate_type PARAMS ((tree, tree, enum instantiate_type_flags));

View File

@ -2531,7 +2531,6 @@ maybe_push_to_top_level (pseudo)
scope_chain = s;
current_function_decl = NULL_TREE;
VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
current_lang_stack = &VARRAY_TREE (current_lang_base, 0);
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
}
@ -3313,8 +3312,7 @@ duplicate_decls (newdecl, olddecl)
/* extern "C" int foo ();
int foo () { bar (); }
is OK. */
if (current_lang_stack
== &VARRAY_TREE (current_lang_base, 0))
if (current_lang_depth () == 0)
DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
else
{
@ -12723,8 +12721,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
}
if (TYPE_FOR_JAVA (basetype)
&& (current_lang_stack
== &VARRAY_TREE (current_lang_base, 0)))
&& (current_lang_depth () == 0))
TYPE_FOR_JAVA (ref) = 1;
/* Note that the BINFO records which describe individual

View File

@ -94,9 +94,6 @@ static tree get_guard_bits PARAMS ((tree));
extern int current_class_depth;
/* A list of virtual function tables we must make sure to write out. */
tree pending_vtables;
/* A list of static class variables. This is needed, because a
static class variable can be declared inside the class without
an initializer, and then initialized, staticly, outside the class. */
@ -1514,7 +1511,7 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags)
DECL_CONTEXT (decl) = current_class_type;
/* We cannot call pushdecl here, because that would fill in the
decl of our TREE_CHAIN. Instead, we modify cp_finish_decl to do
TREE_CHAIN of our decl. Instead, we modify cp_finish_decl to do
the right thing, namely, to put this decl out straight away. */
/* current_class_type can be NULL_TREE in case of error. */
if (!asmspec_tree && current_class_type)
@ -2297,7 +2294,7 @@ mark_vtable_entries (decl)
if (TREE_CODE (fnaddr) != ADDR_EXPR)
/* This entry is an offset: a virtual base class offset, a
virtual call offset, and RTTI offset, etc. */
virtual call offset, an RTTI offset, etc. */
continue;
fn = TREE_OPERAND (fnaddr, 0);
@ -2411,7 +2408,7 @@ key_method (type)
method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE
&& ! DECL_THIS_INLINE (method)
&& ! DECL_PURE_VIRTUAL_P (method))
&& (! DECL_PURE_VIRTUAL_P (method) || DECL_DESTRUCTOR_P (method)))
return method;
return NULL_TREE;
@ -2440,7 +2437,7 @@ import_export_vtable (decl, type, final)
else if (CLASSTYPE_INTERFACE_KNOWN (type))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
DECL_INTERFACE_KNOWN (decl) = 1;
}
else
@ -2525,7 +2522,6 @@ import_export_class (ctype)
if (import_export)
{
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0);
CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
}
}
@ -2695,7 +2691,7 @@ import_export_decl (decl)
else
comdat_linkage (decl);
}
else if (DECL_TINFO_FN_P (decl))
else if (tinfo_decl_p (decl, 0))
{
tree ctype = TREE_TYPE (DECL_NAME (decl));
@ -5387,5 +5383,4 @@ init_decl2 ()
ggc_add_tree_root (&ssdf_decl, 1);
ggc_add_tree_root (&priority_decl, 1);
ggc_add_tree_root (&initialize_p_decl, 1);
ggc_add_tree_root (&pending_vtables, 1);
}

View File

@ -1078,12 +1078,8 @@ static void
handle_pragma_vtable (dfile)
cpp_reader *dfile ATTRIBUTE_UNUSED;
{
tree vtbl = parse_strconst_pragma ("vtable", 0);
if (vtbl && vtbl != (tree)-1)
pending_vtables = tree_cons (NULL_TREE,
get_identifier (TREE_STRING_POINTER (vtbl)),
pending_vtables);
parse_strconst_pragma ("vtable", 0);
sorry ("#pragma vtable no longer supported");
}
static void

View File

@ -686,7 +686,7 @@ expand_call_inline (tp, walk_subtrees, data)
return NULL_TREE;
}
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
if (TYPE_P (t))
/* Because types were not copied in copy_body, CALL_EXPRs beneath
them should not be expanded. This can happen if the type is a
dynamic array type, for example. */

View File

@ -57,10 +57,7 @@ extern struct obstack permanent_obstack;
(for a function or static data member), or a TYPE (for a class)
indicating what we are hoping to instantiate. */
static tree pending_templates;
static tree *template_tail = &pending_templates;
static tree maybe_templates;
static tree *maybe_template_tail = &maybe_templates;
static tree last_pending_template;
int processing_template_parmlist;
static int template_header_count;
@ -176,7 +173,6 @@ void
init_pt ()
{
ggc_add_tree_root (&pending_templates, 1);
ggc_add_tree_root (&maybe_templates, 1);
ggc_add_tree_root (&saved_trees, 1);
ggc_add_tree_root (&current_tinst_level, 1);
}
@ -3719,6 +3715,7 @@ add_pending_template (d)
tree ti = (TYPE_P (d)
? CLASSTYPE_TEMPLATE_INFO (d)
: DECL_TEMPLATE_INFO (d));
tree pt;
int level;
if (TI_PENDING_TEMPLATE_FLAG (ti))
@ -3732,8 +3729,14 @@ add_pending_template (d)
if (level)
push_tinst_level (d);
*template_tail = tree_cons (current_tinst_level, d, NULL_TREE);
template_tail = &TREE_CHAIN (*template_tail);
pt = tree_cons (current_tinst_level, d, NULL_TREE);
if (last_pending_template)
TREE_CHAIN (last_pending_template) = pt;
else
pending_templates = pt;
last_pending_template = pt;
TI_PENDING_TEMPLATE_FLAG (ti) = 1;
if (level)
@ -4962,24 +4965,17 @@ instantiate_class_template (type)
{
CLASSTYPE_INTERFACE_ONLY (type) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown);
CLASSTYPE_VTABLE_NEEDS_WRITING (type)
= (! CLASSTYPE_INTERFACE_ONLY (type)
&& CLASSTYPE_INTERFACE_KNOWN (type));
}
else
{
CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(type, CLASSTYPE_INTERFACE_UNKNOWN (pattern));
CLASSTYPE_VTABLE_NEEDS_WRITING (type)
= (! CLASSTYPE_INTERFACE_ONLY (type)
&& CLASSTYPE_INTERFACE_KNOWN (type));
}
}
else
{
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
}
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
@ -9471,7 +9467,6 @@ mark_class_instantiated (t, extern_p)
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
if (! extern_p)
{
@ -9859,10 +9854,10 @@ instantiate_decl (d, defer_ok)
import_export_decl (d);
}
/* We need to set up DECL_INITIAL regardless, if
the variable is initialized in the class body. */
if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d))
;
if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)
&& DECL_INITIAL (d) == NULL_TREE)
/* We should have set up DECL_INITIAL in instantiate_class_template. */
abort ();
/* Reject all external templates except inline functions. */
else if (DECL_INTERFACE_KNOWN (d)
&& ! DECL_NOT_REALLY_EXTERN (d)
@ -9885,8 +9880,8 @@ instantiate_decl (d, defer_ok)
member function or static data member of a class template
shall be present in every translation unit in which it is
explicitly instantiated. */
cp_error ("explicit instantiation of `%D' but no definition available",
d);
cp_pedwarn
("explicit instantiation of `%D' but no definition available", d);
add_pending_template (d);
goto out;
@ -9979,6 +9974,7 @@ int
instantiate_pending_templates ()
{
tree *t;
tree last = NULL_TREE;
int instantiated_something = 0;
int reconsider;
@ -10017,8 +10013,11 @@ instantiate_pending_templates ()
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
else
t = &TREE_CHAIN (*t);
else
{
last = *t;
t = &TREE_CHAIN (*t);
}
}
else
{
@ -10039,43 +10038,16 @@ instantiate_pending_templates ()
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
else
t = &TREE_CHAIN (*t);
else
{
last = *t;
t = &TREE_CHAIN (*t);
}
}
tinst_depth = 0;
current_tinst_level = NULL_TREE;
}
template_tail = t;
/* Go through the things that are template instantiations if we are
using guiding declarations. */
t = &maybe_templates;
while (*t)
{
tree template;
tree fn;
tree args;
fn = TREE_VALUE (*t);
if (DECL_INITIAL (fn))
/* If the FN is already defined, then it was either already
instantiated or, even though guiding declarations were
allowed, a non-template definition was provided. */
;
else
{
template = TREE_PURPOSE (*t);
args = get_bindings (template, fn, NULL_TREE);
fn = instantiate_template (template, args);
instantiate_decl (fn, /*defer_ok=*/0);
reconsider = 1;
}
/* Remove this entry from the chain. */
*t = TREE_CHAIN (*t);
}
maybe_template_tail = t;
last_pending_template = last;
}
while (reconsider);

View File

@ -152,8 +152,6 @@ print_lang_type (file, node, indent)
fprintf (file, " interface-only");
if (CLASSTYPE_INTERFACE_UNKNOWN (node))
fprintf (file, " interface-unknown");
if (CLASSTYPE_VTABLE_NEEDS_WRITING (node))
fprintf (file, " vtable-needs-writing");
print_node (file, "member-functions", CLASSTYPE_METHOD_VEC (node),
indent + 4);
}

View File

@ -340,7 +340,7 @@ get_tinfo_decl (type)
{
/* The tinfo decl is the type_info object itself. We make all
tinfo objects look as type_info, even though they will end up
being a subclass of that when emitted. This means the we'll
being a subclass of that when emitted. This means that we'll
erroneously think we know the dynamic type -- be careful in the
runtime. */
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);

View File

@ -1825,12 +1825,6 @@ begin_class_definition (t)
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(t, interface_unknown);
}
/* Only leave this bit clear if we know this
class is part of an interface-only specification. */
if (! CLASSTYPE_INTERFACE_KNOWN (t)
|| ! CLASSTYPE_INTERFACE_ONLY (t))
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
}
reset_specialization();