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 '__'. * error.c (GLOBAL_THING): Always use '__'.

View File

@ -5757,6 +5757,14 @@ pop_nested_class ()
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 /* Set global variables CURRENT_LANG_NAME to appropriate value
so that behavior of name-mangling machinery is correct. */ so that behavior of name-mangling machinery is correct. */
@ -5764,15 +5772,7 @@ void
push_lang_context (name) push_lang_context (name)
tree name; tree name;
{ {
*current_lang_stack++ = current_lang_name; VARRAY_PUSH_TREE (current_lang_base, 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);
}
if (name == lang_name_cplusplus) if (name == lang_name_cplusplus)
{ {
@ -5807,10 +5807,8 @@ push_lang_context (name)
void void
pop_lang_context () pop_lang_context ()
{ {
/* Clear the current entry so that garbage collector won't hold on current_lang_name = VARRAY_TOP_TREE (current_lang_base);
to it. */ VARRAY_POP (current_lang_base);
*current_lang_stack = NULL_TREE;
current_lang_name = *--current_lang_stack;
} }
/* Type instantiation routines. */ /* Type instantiation routines. */
@ -7847,8 +7845,7 @@ build_vtable_entry (delta, vcall_index, entry, generate_with_vtable_p)
fn = TREE_OPERAND (entry, 0); fn = TREE_OPERAND (entry, 0);
if ((!integer_zerop (delta) || vcall_index != NULL_TREE) if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
&& fn != abort_fndecl && fn != abort_fndecl)
&& !DECL_TINFO_FN_P (fn))
{ {
entry = make_thunk (entry, delta, vcall_index, entry = make_thunk (entry, delta, vcall_index,
generate_with_vtable_p); generate_with_vtable_p);

View File

@ -787,7 +787,6 @@ struct saved_scope {
tree access_specifier; tree access_specifier;
tree function_decl; tree function_decl;
varray_type lang_base; varray_type lang_base;
tree *lang_stack;
tree lang_name; tree lang_name;
tree template_parms; tree template_parms;
tree x_previous_class_type; tree x_previous_class_type;
@ -830,7 +829,6 @@ struct saved_scope {
/* Pointer to the top of the language name stack. */ /* 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_base scope_chain->lang_base
#define current_lang_name scope_chain->lang_name #define current_lang_name scope_chain->lang_name
@ -1296,7 +1294,7 @@ struct lang_type
unsigned com_interface : 1; unsigned com_interface : 1;
unsigned non_pod_class : 1; unsigned non_pod_class : 1;
unsigned nearly_empty_p : 1; unsigned nearly_empty_p : 1;
unsigned vtable_needs_writing : 1; unsigned user_align : 1;
unsigned has_assign_ref : 1; unsigned has_assign_ref : 1;
unsigned has_new : 1; unsigned has_new : 1;
unsigned has_array_new : 1; unsigned has_array_new : 1;
@ -1328,7 +1326,6 @@ struct lang_type
unsigned has_abstract_assign_ref : 1; unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1; unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1; unsigned is_partial_instantiation : 1;
unsigned user_align : 1;
/* When adding a flag here, consider whether or not it ought to /* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If 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 /* 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 of this by updating the size of this bitfield whenever you add or
remove a flag. */ remove a flag. */
unsigned dummy : 8; unsigned dummy : 9;
int vsize; int vsize;
@ -1573,10 +1570,6 @@ struct lang_type
and there is no need to change it. */ and there is no need to change it. */
#define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->needs_virtual_reinit) #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. */ /* Nonzero means that this type has an X() constructor. */
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->has_default_ctor) #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 pending_inline_p : 1;
unsigned global_ctor_p : 1; unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1; unsigned global_dtor_p : 1;
unsigned tinfo_fn_p : 1;
unsigned assignment_operator_p : 1; unsigned assignment_operator_p : 1;
unsigned anticipated_p : 1; unsigned anticipated_p : 1;
unsigned generate_with_vtable_p : 1; unsigned generate_with_vtable_p : 1;
/* One unused bit. */ /* Two unused bits. */
union { union {
/* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this /* 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) \ #define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p) (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. */ /* Nonzero if NODE is an overloaded `operator delete[]' function. */
#define DECL_ARRAY_DELETE_OPERATOR_P(NODE) \ #define DECL_ARRAY_DELETE_OPERATOR_P(NODE) \
(DECL_OVERLOADED_OPERATOR_P (NODE) == VEC_DELETE_EXPR) (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. */ /* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list; 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". /* Node for "pointer to (virtual) function".
This may be distinct from ptr_type_node so gdb can distinguish them. */ This may be distinct from ptr_type_node so gdb can distinguish them. */
#define vfunc_ptr_type_node \ #define vfunc_ptr_type_node \
@ -3727,6 +3705,7 @@ extern void pushclass PARAMS ((tree, int));
extern void popclass PARAMS ((void)); extern void popclass PARAMS ((void));
extern void push_nested_class PARAMS ((tree, int)); extern void push_nested_class PARAMS ((tree, int));
extern void pop_nested_class PARAMS ((void)); extern void pop_nested_class PARAMS ((void));
extern int current_lang_depth PARAMS ((void));
extern void push_lang_context PARAMS ((tree)); extern void push_lang_context PARAMS ((tree));
extern void pop_lang_context PARAMS ((void)); extern void pop_lang_context PARAMS ((void));
extern tree instantiate_type PARAMS ((tree, tree, enum instantiate_type_flags)); 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; scope_chain = s;
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base"); 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_lang_name = lang_name_cplusplus;
current_namespace = global_namespace; current_namespace = global_namespace;
} }
@ -3313,8 +3312,7 @@ duplicate_decls (newdecl, olddecl)
/* extern "C" int foo (); /* extern "C" int foo ();
int foo () { bar (); } int foo () { bar (); }
is OK. */ is OK. */
if (current_lang_stack if (current_lang_depth () == 0)
== &VARRAY_TREE (current_lang_base, 0))
DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
else else
{ {
@ -12723,8 +12721,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
} }
if (TYPE_FOR_JAVA (basetype) if (TYPE_FOR_JAVA (basetype)
&& (current_lang_stack && (current_lang_depth () == 0))
== &VARRAY_TREE (current_lang_base, 0)))
TYPE_FOR_JAVA (ref) = 1; TYPE_FOR_JAVA (ref) = 1;
/* Note that the BINFO records which describe individual /* 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; 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 /* A list of static class variables. This is needed, because a
static class variable can be declared inside the class without static class variable can be declared inside the class without
an initializer, and then initialized, staticly, outside the class. */ 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; DECL_CONTEXT (decl) = current_class_type;
/* We cannot call pushdecl here, because that would fill in the /* 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. */ the right thing, namely, to put this decl out straight away. */
/* current_class_type can be NULL_TREE in case of error. */ /* current_class_type can be NULL_TREE in case of error. */
if (!asmspec_tree && current_class_type) if (!asmspec_tree && current_class_type)
@ -2297,7 +2294,7 @@ mark_vtable_entries (decl)
if (TREE_CODE (fnaddr) != ADDR_EXPR) if (TREE_CODE (fnaddr) != ADDR_EXPR)
/* This entry is an offset: a virtual base class offset, a /* 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; continue;
fn = TREE_OPERAND (fnaddr, 0); fn = TREE_OPERAND (fnaddr, 0);
@ -2411,7 +2408,7 @@ key_method (type)
method = TREE_CHAIN (method)) method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE if (DECL_VINDEX (method) != NULL_TREE
&& ! DECL_THIS_INLINE (method) && ! DECL_THIS_INLINE (method)
&& ! DECL_PURE_VIRTUAL_P (method)) && (! DECL_PURE_VIRTUAL_P (method) || DECL_DESTRUCTOR_P (method)))
return method; return method;
return NULL_TREE; return NULL_TREE;
@ -2440,7 +2437,7 @@ import_export_vtable (decl, type, final)
else if (CLASSTYPE_INTERFACE_KNOWN (type)) else if (CLASSTYPE_INTERFACE_KNOWN (type))
{ {
TREE_PUBLIC (decl) = 1; TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
DECL_INTERFACE_KNOWN (decl) = 1; DECL_INTERFACE_KNOWN (decl) = 1;
} }
else else
@ -2525,7 +2522,6 @@ import_export_class (ctype)
if (import_export) if (import_export)
{ {
SET_CLASSTYPE_INTERFACE_KNOWN (ctype); SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0);
CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0); CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
} }
} }
@ -2695,7 +2691,7 @@ import_export_decl (decl)
else else
comdat_linkage (decl); comdat_linkage (decl);
} }
else if (DECL_TINFO_FN_P (decl)) else if (tinfo_decl_p (decl, 0))
{ {
tree ctype = TREE_TYPE (DECL_NAME (decl)); tree ctype = TREE_TYPE (DECL_NAME (decl));
@ -5387,5 +5383,4 @@ init_decl2 ()
ggc_add_tree_root (&ssdf_decl, 1); ggc_add_tree_root (&ssdf_decl, 1);
ggc_add_tree_root (&priority_decl, 1); ggc_add_tree_root (&priority_decl, 1);
ggc_add_tree_root (&initialize_p_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) handle_pragma_vtable (dfile)
cpp_reader *dfile ATTRIBUTE_UNUSED; cpp_reader *dfile ATTRIBUTE_UNUSED;
{ {
tree vtbl = parse_strconst_pragma ("vtable", 0); parse_strconst_pragma ("vtable", 0);
sorry ("#pragma vtable no longer supported");
if (vtbl && vtbl != (tree)-1)
pending_vtables = tree_cons (NULL_TREE,
get_identifier (TREE_STRING_POINTER (vtbl)),
pending_vtables);
} }
static void static void

View File

@ -686,7 +686,7 @@ expand_call_inline (tp, walk_subtrees, data)
return NULL_TREE; 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 /* Because types were not copied in copy_body, CALL_EXPRs beneath
them should not be expanded. This can happen if the type is a them should not be expanded. This can happen if the type is a
dynamic array type, for example. */ 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) (for a function or static data member), or a TYPE (for a class)
indicating what we are hoping to instantiate. */ indicating what we are hoping to instantiate. */
static tree pending_templates; static tree pending_templates;
static tree *template_tail = &pending_templates; static tree last_pending_template;
static tree maybe_templates;
static tree *maybe_template_tail = &maybe_templates;
int processing_template_parmlist; int processing_template_parmlist;
static int template_header_count; static int template_header_count;
@ -176,7 +173,6 @@ void
init_pt () init_pt ()
{ {
ggc_add_tree_root (&pending_templates, 1); 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 (&saved_trees, 1);
ggc_add_tree_root (&current_tinst_level, 1); ggc_add_tree_root (&current_tinst_level, 1);
} }
@ -3719,6 +3715,7 @@ add_pending_template (d)
tree ti = (TYPE_P (d) tree ti = (TYPE_P (d)
? CLASSTYPE_TEMPLATE_INFO (d) ? CLASSTYPE_TEMPLATE_INFO (d)
: DECL_TEMPLATE_INFO (d)); : DECL_TEMPLATE_INFO (d));
tree pt;
int level; int level;
if (TI_PENDING_TEMPLATE_FLAG (ti)) if (TI_PENDING_TEMPLATE_FLAG (ti))
@ -3732,8 +3729,14 @@ add_pending_template (d)
if (level) if (level)
push_tinst_level (d); push_tinst_level (d);
*template_tail = tree_cons (current_tinst_level, d, NULL_TREE); pt = tree_cons (current_tinst_level, d, NULL_TREE);
template_tail = &TREE_CHAIN (*template_tail); if (last_pending_template)
TREE_CHAIN (last_pending_template) = pt;
else
pending_templates = pt;
last_pending_template = pt;
TI_PENDING_TEMPLATE_FLAG (ti) = 1; TI_PENDING_TEMPLATE_FLAG (ti) = 1;
if (level) if (level)
@ -4962,24 +4965,17 @@ instantiate_class_template (type)
{ {
CLASSTYPE_INTERFACE_ONLY (type) = interface_only; CLASSTYPE_INTERFACE_ONLY (type) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown); SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown);
CLASSTYPE_VTABLE_NEEDS_WRITING (type)
= (! CLASSTYPE_INTERFACE_ONLY (type)
&& CLASSTYPE_INTERFACE_KNOWN (type));
} }
else else
{ {
CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern); CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(type, CLASSTYPE_INTERFACE_UNKNOWN (pattern)); (type, CLASSTYPE_INTERFACE_UNKNOWN (pattern));
CLASSTYPE_VTABLE_NEEDS_WRITING (type)
= (! CLASSTYPE_INTERFACE_ONLY (type)
&& CLASSTYPE_INTERFACE_KNOWN (type));
} }
} }
else else
{ {
SET_CLASSTYPE_INTERFACE_UNKNOWN (type); SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
} }
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern); 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_EXPLICIT_INSTANTIATION (t);
SET_CLASSTYPE_INTERFACE_KNOWN (t); SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = extern_p; CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p; TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
if (! extern_p) if (! extern_p)
{ {
@ -9859,10 +9854,10 @@ instantiate_decl (d, defer_ok)
import_export_decl (d); import_export_decl (d);
} }
/* We need to set up DECL_INITIAL regardless, if if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)
the variable is initialized in the class body. */ && DECL_INITIAL (d) == NULL_TREE)
if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)) /* We should have set up DECL_INITIAL in instantiate_class_template. */
; abort ();
/* Reject all external templates except inline functions. */ /* Reject all external templates except inline functions. */
else if (DECL_INTERFACE_KNOWN (d) else if (DECL_INTERFACE_KNOWN (d)
&& ! DECL_NOT_REALLY_EXTERN (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 member function or static data member of a class template
shall be present in every translation unit in which it is shall be present in every translation unit in which it is
explicitly instantiated. */ explicitly instantiated. */
cp_error ("explicit instantiation of `%D' but no definition available", cp_pedwarn
d); ("explicit instantiation of `%D' but no definition available", d);
add_pending_template (d); add_pending_template (d);
goto out; goto out;
@ -9979,6 +9974,7 @@ int
instantiate_pending_templates () instantiate_pending_templates ()
{ {
tree *t; tree *t;
tree last = NULL_TREE;
int instantiated_something = 0; int instantiated_something = 0;
int reconsider; int reconsider;
@ -10017,8 +10013,11 @@ instantiate_pending_templates ()
/* If INSTANTIATION has been instantiated, then we don't /* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */ need to consider it again in the future. */
*t = TREE_CHAIN (*t); *t = TREE_CHAIN (*t);
else else
t = &TREE_CHAIN (*t); {
last = *t;
t = &TREE_CHAIN (*t);
}
} }
else else
{ {
@ -10039,43 +10038,16 @@ instantiate_pending_templates ()
/* If INSTANTIATION has been instantiated, then we don't /* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */ need to consider it again in the future. */
*t = TREE_CHAIN (*t); *t = TREE_CHAIN (*t);
else else
t = &TREE_CHAIN (*t); {
last = *t;
t = &TREE_CHAIN (*t);
}
} }
tinst_depth = 0; tinst_depth = 0;
current_tinst_level = NULL_TREE; current_tinst_level = NULL_TREE;
} }
template_tail = t; last_pending_template = last;
/* 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;
} }
while (reconsider); while (reconsider);

View File

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

View File

@ -340,7 +340,7 @@ get_tinfo_decl (type)
{ {
/* The tinfo decl is the type_info object itself. We make all /* The tinfo decl is the type_info object itself. We make all
tinfo objects look as type_info, even though they will end up 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 erroneously think we know the dynamic type -- be careful in the
runtime. */ runtime. */
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type); 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 SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(t, interface_unknown); (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(); reset_specialization();