Commit 0aafb128 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (lang_decl_flags): Remove returns_first_arg and preserves_first_arg.

	* cp-tree.h (lang_decl_flags): Remove returns_first_arg and
	preserves_first_arg.  Enlarge dummy accordingly.
	(DECL_TINFO_FN_P): New macro.
	(SET_DECL_TINO_FN_P): Likeiwse.
	(DECL_RETURNS_FIRST_ARG): Remove.
	(DECL_PRESERVES_THIS): Likewise.
	(DECL_INIT_PRIORITY): New macro.
	(finish_struct_1): Change prototype.
	(cat_namespace_levels): Remove prototype.
	(vtable_decl_p): New prototype.
	(vtype_decl_p): Likewise.
	(sigtable_decl_p): Likewise.
	(walk_globals_pred): New typedef.
	(walk_globals_fn): Likewise.
	(walk_globals): New prototype.
	(walk_namespaces_fn): New typedef.
	(walk_namespaces): New prototype.
	(wrapup_globals_for_namespace): Likewise.
	(walk_vtables): Remove prototype.
	(walk_sigtables): Likewise.
	(instantiate_pending_templates): New prototype.
	* class.c (finish_struct_1): Don't return a value.
	* decl.h (pending_statics): Remove declaration.
	* decl.c (walk_namespaces_r): New function.
	(walk_globals_r): Likewise.
	(vtable_decl_p): Likewise.
	(vtype_decl_p): Likewise.
	(sigtable_decl_p): Likewise.
	(walk_namespaces): Likewise.
	(walk_globals_data): New type.
	(walk_globals): New function.
	(wrapup_globals_for_namespace): Likewise.
	(expand_static_init): Remove assertion.  Remove redundancy in
	conditional.  Don't put static data members in static_aggregates
	Tidy.
	(finish_function): Remove redundancy in conditional.  Don't set
	DECL_RETURNS_FIRST_ARG.
	(cat_namespace_levels): Remove.
	* decl2.c: Include splay-tree.h and varray.h.
	(priority_info_s): New structure.
	(finish_vtable_vardecl): Change prototype.  Adjust for new calling
	conventions.
	(prune_vtable_vardecl): Likewise.
	(finish_sigtable_vardecl): Likewise.
	(setup_initp): Remove.
	(do_dtors): Remove.
	(do_ctors): Remove.
	(start_static_storage_duration_function): New function.
	(generate_inits_for_priority): Likewise.
	(finish_static_storage_duration_function): Likewise.
	(get_priority_info): Likewise.
	(do_static_initialization): Likewise.
	(do_static_destruction): Likewise.
	(do_static_initialization_and_destruction): Likewise.
	(generate_ctor_or_dtor_function): Likewise.
	(generate_ctor_and_dtor_functions_for_priority): Likewise.
	(pending_statics): Make it a varray.
	(pending_statics_used): New variable.
	(saved_inlines): Make it a varray.
	(saved_inlines_used): New variable.
	(finish_static_data_member): Change method of updating
	pending_statics.
	(mark_inline_for_output): Remove #if 0'd code.  Change method of
	updating saved_inlines.
	(walk_vtables): Remove.
	(walk_sigtables): Likewise.
	(import_export_decl): Use DECL_TINFO_FN_P.
	(pending_templates): Remove declaration.
	(maybe_templates): Likewise.
	(static_aggregates_initp): Likewise.
	(setup_initp): Likewise.
	(finish_objects): Simplify.
	(INITIALIZE_P_IDENTIFIER): New macro.
	(PRIORITY_IDENTIFIER): New macro.
	(SSDF_IDENTIFIER): New macro.
	(initialize_p_decl): New variable.
	(priority_decl): Likewise.
	(ssdf_decl): Likewise.
	(priority_info_map): Likewise.
	(finish_file): Recode output of static intializers and other
	file-scope finalization tasks.
	* error.c (OB_END_TEMPLATE_ID): New macro.
	(dump_type_real): Use it.
	(dump_decl): Likewise.
	(dump_function_name): Likewise.
	* lex.c (set_typedecl_interface_info): Adjust for new walk_globals
	interface.
	(check_newline): Use walk_globals, not walk_vtables.
	* pt.c (pending_tempalte_expansions): Remove.
	(set_vardecl_interface_info): Likewise.
	(pending_templates): Make static.
	(maybe_templates): Likewise.
	(instantiate_class_template): Adjust call to finish_struct_1.
	(instantiate_pending_templates): New function.
	* rtti.c (get_tinfo_fn): Use SET_DECL_TINFO_FN_P.
	* tree.c (static_aggregates_initp): Remove.
	(cp_valid_lang_attribute): Don't use it; use DECL_INIT_PRIORITY
	instead.
	* Makefile.in (decl2.o): Depend on varray.h and splay-tree.h.

From-SVN: r26594
parent 32291f94
1999-04-22 Mark Mitchell <mark@codesourcery.com> 1999-04-22 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (lang_decl_flags): Remove returns_first_arg and
preserves_first_arg. Enlarge dummy accordingly.
(DECL_TINFO_FN_P): New macro.
(SET_DECL_TINO_FN_P): Likeiwse.
(DECL_RETURNS_FIRST_ARG): Remove.
(DECL_PRESERVES_THIS): Likewise.
(DECL_INIT_PRIORITY): New macro.
(finish_struct_1): Change prototype.
(cat_namespace_levels): Remove prototype.
(vtable_decl_p): New prototype.
(vtype_decl_p): Likewise.
(sigtable_decl_p): Likewise.
(walk_globals_pred): New typedef.
(walk_globals_fn): Likewise.
(walk_globals): New prototype.
(walk_namespaces_fn): New typedef.
(walk_namespaces): New prototype.
(wrapup_globals_for_namespace): Likewise.
(walk_vtables): Remove prototype.
(walk_sigtables): Likewise.
(instantiate_pending_templates): New prototype.
* class.c (finish_struct_1): Don't return a value.
* decl.h (pending_statics): Remove declaration.
* decl.c (walk_namespaces_r): New function.
(walk_globals_r): Likewise.
(vtable_decl_p): Likewise.
(vtype_decl_p): Likewise.
(sigtable_decl_p): Likewise.
(walk_namespaces): Likewise.
(walk_globals_data): New type.
(walk_globals): New function.
(wrapup_globals_for_namespace): Likewise.
(expand_static_init): Remove assertion. Remove redundancy in
conditional. Don't put static data members in static_aggregates
Tidy.
(finish_function): Remove redundancy in conditional. Don't set
DECL_RETURNS_FIRST_ARG.
(cat_namespace_levels): Remove.
* decl2.c: Include splay-tree.h and varray.h.
(priority_info_s): New structure.
(finish_vtable_vardecl): Change prototype. Adjust for new calling
conventions.
(prune_vtable_vardecl): Likewise.
(finish_sigtable_vardecl): Likewise.
(setup_initp): Remove.
(do_dtors): Remove.
(do_ctors): Remove.
(start_static_storage_duration_function): New function.
(generate_inits_for_priority): Likewise.
(finish_static_storage_duration_function): Likewise.
(get_priority_info): Likewise.
(do_static_initialization): Likewise.
(do_static_destruction): Likewise.
(do_static_initialization_and_destruction): Likewise.
(generate_ctor_or_dtor_function): Likewise.
(generate_ctor_and_dtor_functions_for_priority): Likewise.
(pending_statics): Make it a varray.
(pending_statics_used): New variable.
(saved_inlines): Make it a varray.
(saved_inlines_used): New variable.
(finish_static_data_member): Change method of updating
pending_statics.
(mark_inline_for_output): Remove #if 0'd code. Change method of
updating saved_inlines.
(walk_vtables): Remove.
(walk_sigtables): Likewise.
(import_export_decl): Use DECL_TINFO_FN_P.
(pending_templates): Remove declaration.
(maybe_templates): Likewise.
(static_aggregates_initp): Likewise.
(setup_initp): Likewise.
(finish_objects): Simplify.
(INITIALIZE_P_IDENTIFIER): New macro.
(PRIORITY_IDENTIFIER): New macro.
(SSDF_IDENTIFIER): New macro.
(initialize_p_decl): New variable.
(priority_decl): Likewise.
(ssdf_decl): Likewise.
(priority_info_map): Likewise.
(finish_file): Recode output of static intializers and other
file-scope finalization tasks.
* error.c (OB_END_TEMPLATE_ID): New macro.
(dump_type_real): Use it.
(dump_decl): Likewise.
(dump_function_name): Likewise.
* lex.c (set_typedecl_interface_info): Adjust for new walk_globals
interface.
(check_newline): Use walk_globals, not walk_vtables.
* pt.c (pending_tempalte_expansions): Remove.
(set_vardecl_interface_info): Likewise.
(pending_templates): Make static.
(maybe_templates): Likewise.
(instantiate_class_template): Adjust call to finish_struct_1.
(instantiate_pending_templates): New function.
* rtti.c (get_tinfo_fn): Use SET_DECL_TINFO_FN_P.
* tree.c (static_aggregates_initp): Remove.
(cp_valid_lang_attribute): Don't use it; use DECL_INIT_PRIORITY
instead.
* Makefile.in (decl2.o): Depend on varray.h and splay-tree.h.
* gxx.gperf (RETURN): Rename to RETURN_KEYWORD to avoid clashes * gxx.gperf (RETURN): Rename to RETURN_KEYWORD to avoid clashes
with the RTL code RETURN. with the RTL code RETURN.
* hash.h: Regenerated. * hash.h: Regenerated.
......
...@@ -261,7 +261,8 @@ decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ ...@@ -261,7 +261,8 @@ decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \ lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \ $(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \
$(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h $(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \
$(srcdir)/../../include/splay-tree.h $(srcdir)/../varray.h
typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../system.h $(srcdir)/../toplev.h
typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
......
...@@ -3099,7 +3099,7 @@ add_implicitly_declared_members (t, cant_have_default_ctor, ...@@ -3099,7 +3099,7 @@ add_implicitly_declared_members (t, cant_have_default_ctor,
ATTRIBUTES is the set of decl attributes to be applied, if any. */ ATTRIBUTES is the set of decl attributes to be applied, if any. */
tree void
finish_struct_1 (t, warn_anon) finish_struct_1 (t, warn_anon)
tree t; tree t;
int warn_anon; int warn_anon;
...@@ -3144,7 +3144,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3144,7 +3144,7 @@ finish_struct_1 (t, warn_anon)
else else
my_friendly_abort (172); my_friendly_abort (172);
popclass (); popclass ();
return t; return;
} }
GNU_xref_decl (current_function_decl, t); GNU_xref_decl (current_function_decl, t);
...@@ -4116,7 +4116,7 @@ finish_struct_1 (t, warn_anon) ...@@ -4116,7 +4116,7 @@ finish_struct_1 (t, warn_anon)
/* Finish debugging output for this type. */ /* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel_bindings_p ()); rest_of_type_compilation (t, toplevel_bindings_p ());
return t; return;
} }
/* When T was built up, the member declarations were added in reverse /* When T was built up, the member declarations were added in reverse
...@@ -4210,7 +4210,7 @@ finish_struct (t, attributes, warn_anon) ...@@ -4210,7 +4210,7 @@ finish_struct (t, attributes, warn_anon)
TYPE_SIZE (t) = integer_zero_node; TYPE_SIZE (t) = integer_zero_node;
} }
else else
t = finish_struct_1 (t, warn_anon); finish_struct_1 (t, warn_anon);
TYPE_BEING_DEFINED (t) = 0; TYPE_BEING_DEFINED (t) = 0;
......
...@@ -88,6 +88,9 @@ Boston, MA 02111-1307, USA. */ ...@@ -88,6 +88,9 @@ Boston, MA 02111-1307, USA. */
For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME. For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
For a TEMPLATE_TEMPLATE_PARM, this is For a TEMPLATE_TEMPLATE_PARM, this is
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
DECL_SAVED_INSNS/DECL_FIELD_SIZE
For a static VAR_DECL, this is DECL_INIT_PRIORITY.
*/ */
/* Language-dependent contents of an identifier. */ /* Language-dependent contents of an identifier. */
...@@ -1149,8 +1152,6 @@ struct lang_decl_flags ...@@ -1149,8 +1152,6 @@ struct lang_decl_flags
unsigned operator_attr : 1; unsigned operator_attr : 1;
unsigned constructor_attr : 1; unsigned constructor_attr : 1;
unsigned returns_first_arg : 1;
unsigned preserves_first_arg : 1;
unsigned friend_attr : 1; unsigned friend_attr : 1;
unsigned static_function : 1; unsigned static_function : 1;
unsigned const_memfunc : 1; unsigned const_memfunc : 1;
...@@ -1171,7 +1172,7 @@ struct lang_decl_flags ...@@ -1171,7 +1172,7 @@ struct lang_decl_flags
unsigned needs_final_overrider : 1; unsigned needs_final_overrider : 1;
unsigned bitfield : 1; unsigned bitfield : 1;
unsigned defined_in_class : 1; unsigned defined_in_class : 1;
unsigned dummy : 1; unsigned dummy : 3;
tree access; tree access;
tree context; tree context;
...@@ -1221,20 +1222,20 @@ struct lang_decl ...@@ -1221,20 +1222,20 @@ struct lang_decl
for an object with virtual baseclasses. */ for an object with virtual baseclasses. */
#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) #define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr)
/* Non-zero for a FUNCTION_DECL that declares a type-info function. */
#define DECL_TINFO_FN_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL \
&& DECL_ARTIFICIAL (NODE) \
&& DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag)
/* Mark NODE as a type-info function. */
#define SET_DECL_TINFO_FN_P(NODE) \
(DECL_LANG_SPECIFIC((NODE))->decl_flags.mutable_flag = 1)
/* For FUNCTION_DECLs: nonzero means that this function is a default /* For FUNCTION_DECLs: nonzero means that this function is a default
implementation of a signature method. */ implementation of a signature method. */
#define IS_DEFAULT_IMPLEMENTATION(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_default_implementation) #define IS_DEFAULT_IMPLEMENTATION(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_default_implementation)
/* For FUNCTION_DECLs: nonzero means that the constructor
is known to return a non-zero `this' unchanged. */
#define DECL_RETURNS_FIRST_ARG(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.returns_first_arg)
/* Nonzero for FUNCTION_DECL means that this constructor is known to
not make any assignment to `this', and therefore can be trusted
to return it unchanged. Otherwise, we must re-assign `current_class_ptr'
after performing base initializations. */
#define DECL_PRESERVES_THIS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.preserves_first_arg)
/* Nonzero for _DECL means that this decl appears in (or will appear /* Nonzero for _DECL means that this decl appears in (or will appear
in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for
detecting circularity in case members are multiply defined. In the detecting circularity in case members are multiply defined. In the
...@@ -1352,6 +1353,11 @@ struct lang_decl ...@@ -1352,6 +1353,11 @@ struct lang_decl
#define ORIGINAL_NAMESPACE(NODE) \ #define ORIGINAL_NAMESPACE(NODE) \
(DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE))
/* In a non-local VAR_DECL with static storage duration, this is the
initialization priority. If this value is zero, the NODE will be
initialized at the DEFAULT_INIT_PRIORITY. */
#define DECL_INIT_PRIORITY(NODE) (DECL_FIELD_SIZE ((NODE)))
/* In a TREE_LIST concatenating using directives, indicate indirekt /* In a TREE_LIST concatenating using directives, indicate indirekt
directives */ directives */
#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0) #define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0)
...@@ -2715,7 +2721,7 @@ extern int currently_open_class PROTO((tree)); ...@@ -2715,7 +2721,7 @@ extern int currently_open_class PROTO((tree));
extern tree get_vfield_offset PROTO((tree)); extern tree get_vfield_offset PROTO((tree));
extern void duplicate_tag_error PROTO((tree)); extern void duplicate_tag_error PROTO((tree));
extern tree finish_struct PROTO((tree, tree, int)); extern tree finish_struct PROTO((tree, tree, int));
extern tree finish_struct_1 PROTO((tree, int)); extern void finish_struct_1 PROTO((tree, int));
extern int resolves_to_fixed_type_p PROTO((tree, int *)); extern int resolves_to_fixed_type_p PROTO((tree, int *));
extern void init_class_processing PROTO((void)); extern void init_class_processing PROTO((void));
extern int is_empty_class PROTO((tree)); extern int is_empty_class PROTO((tree));
...@@ -2873,7 +2879,6 @@ extern int in_function_p PROTO((void)); ...@@ -2873,7 +2879,6 @@ extern int in_function_p PROTO((void));
extern void replace_defarg PROTO((tree, tree)); extern void replace_defarg PROTO((tree, tree));
extern void print_other_binding_stack PROTO((struct binding_level *)); extern void print_other_binding_stack PROTO((struct binding_level *));
extern void revert_static_member_fn PROTO((tree*, tree*, tree*)); extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
extern void cat_namespace_levels PROTO((void));
extern void fixup_anonymous_union PROTO((tree)); extern void fixup_anonymous_union PROTO((tree));
extern int check_static_variable_definition PROTO((tree, tree)); extern int check_static_variable_definition PROTO((tree, tree));
extern void push_local_binding PROTO((tree, tree, int)); extern void push_local_binding PROTO((tree, tree, int));
...@@ -2882,6 +2887,18 @@ extern tree check_default_argument PROTO((tree, tree)); ...@@ -2882,6 +2887,18 @@ extern tree check_default_argument PROTO((tree, tree));
extern tree push_overloaded_decl PROTO((tree, int)); extern tree push_overloaded_decl PROTO((tree, int));
extern void clear_identifier_class_values PROTO((void)); extern void clear_identifier_class_values PROTO((void));
extern void storetags PROTO((tree)); extern void storetags PROTO((tree));
extern int vtable_decl_p PROTO((tree, void *));
extern int vtype_decl_p PROTO((tree, void *));
extern int sigtable_decl_p PROTO((tree, void *));
typedef int (*walk_globals_pred) PROTO((tree, void *));
typedef int (*walk_globals_fn) PROTO((tree *, void *));
extern int walk_globals PROTO((walk_globals_pred,
walk_globals_fn,
void *));
typedef int (*walk_namespaces_fn) PROTO((tree, void *));
extern int walk_namespaces PROTO((walk_namespaces_fn,
void *));
extern int wrapup_globals_for_namespace PROTO((tree, void *));
/* in decl2.c */ /* in decl2.c */
extern int check_java_method PROTO((tree)); extern int check_java_method PROTO((tree));
...@@ -2919,10 +2936,6 @@ extern tree coerce_delete_type PROTO((tree)); ...@@ -2919,10 +2936,6 @@ extern tree coerce_delete_type PROTO((tree));
extern void comdat_linkage PROTO((tree)); extern void comdat_linkage PROTO((tree));
extern void import_export_class PROTO((tree)); extern void import_export_class PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int)); extern void import_export_vtable PROTO((tree, tree, int));
extern int walk_vtables PROTO((void (*)(tree, tree),
int (*)(tree, tree)));
extern void walk_sigtables PROTO((void (*)(tree, tree),
void (*)(tree, tree)));
extern void import_export_decl PROTO((tree)); extern void import_export_decl PROTO((tree));
extern tree build_cleanup PROTO((tree)); extern tree build_cleanup PROTO((tree));
extern void finish_file PROTO((void)); extern void finish_file PROTO((void));
...@@ -3158,6 +3171,7 @@ extern void maybe_process_partial_specialization PROTO((tree)); ...@@ -3158,6 +3171,7 @@ extern void maybe_process_partial_specialization PROTO((tree));
extern void maybe_check_template_type PROTO((tree)); extern void maybe_check_template_type PROTO((tree));
extern tree most_specialized_instantiation PROTO((tree, tree)); extern tree most_specialized_instantiation PROTO((tree, tree));
extern void print_candidates PROTO((tree)); extern void print_candidates PROTO((tree));
extern int instantiate_pending_templates PROTO((void));
extern int processing_specialization; extern int processing_specialization;
extern int processing_explicit_instantiation; extern int processing_explicit_instantiation;
......
...@@ -192,6 +192,8 @@ static void find_class_binding_level PROTO((void)); ...@@ -192,6 +192,8 @@ static void find_class_binding_level PROTO((void));
static struct binding_level *innermost_nonclass_level PROTO((void)); static struct binding_level *innermost_nonclass_level PROTO((void));
static tree poplevel_class PROTO((void)); static tree poplevel_class PROTO((void));
static void warn_about_implicit_typename_lookup PROTO((tree, tree)); static void warn_about_implicit_typename_lookup PROTO((tree, tree));
static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *));
static int walk_globals_r PROTO((tree, void *));
#if defined (DEBUG_CP_BINDING_LEVELS) #if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PROTO((void)); static void indent PROTO((void));
...@@ -1833,6 +1835,179 @@ clear_identifier_class_values () ...@@ -1833,6 +1835,179 @@ clear_identifier_class_values ()
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
} }
/* Returns non-zero if T is a virtual function table. */
int
vtable_decl_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t));
}
/* Returns non-zero if T is a TYPE_DECL for a type with virtual
functions. */
int
vtype_decl_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return (TREE_CODE (t) == TYPE_DECL
&& TREE_TYPE (t) != error_mark_node
&& TYPE_LANG_SPECIFIC (TREE_TYPE (t))
&& CLASSTYPE_VSIZE (TREE_TYPE (t)));
}
/* Returns non-zero if T is a signature table. */
int
sigtable_decl_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return (TREE_CODE (t) == VAR_DECL
&& TREE_TYPE (t) != error_mark_node
&& IS_SIGNATURE (TREE_TYPE (t)));
}
/* Walk all the namespaces contained NAMESPACE, including NAMESPACE
itself, calling F for each. The DATA is passed to F as well. */
static int
walk_namespaces_r (namespace, f, data)
tree namespace;
walk_namespaces_fn f;
void *data;
{
tree current;
int result = 0;
result |= (*f) (namespace, data);
for (current = NAMESPACE_LEVEL (namespace)->names;
current;
current = TREE_CHAIN (current))
{
if (TREE_CODE (current) != NAMESPACE_DECL
|| DECL_NAMESPACE_ALIAS (current))
continue;
if (!DECL_LANG_SPECIFIC (current))
{
/* Hmm. std. */
my_friendly_assert (current == std_node, 393);
continue;
}
/* We found a namespace. */
result |= walk_namespaces_r (current, f, data);
}
return result;
}
/* Walk all the namespaces, calling F for each. The DATA is passed to
F as well. */
int
walk_namespaces (f, data)
walk_namespaces_fn f;
void *data;
{
return walk_namespaces_r (global_namespace, f, data);
}
struct walk_globals_data {
walk_globals_pred p;
walk_globals_fn f;
void *data;
};
/* Walk the global declarations in NAMESPACE. Whenever one is found
for which P returns non-zero, call F with its address. If any call
to F returns a non-zero value, return a non-zero value. */
static int
walk_globals_r (namespace, data)
tree namespace;
void *data;
{
struct walk_globals_data* wgd = (struct walk_globals_data *) data;
walk_globals_pred p = wgd->p;
walk_globals_fn f = wgd->f;
void *d = wgd->data;
tree *t;
int result = 0;
t = &NAMESPACE_LEVEL (namespace)->names;
while (*t)
{
tree glbl = *t;
if ((*p) (glbl, d))
result |= (*f) (t, d);
/* If F changed *T, then *T still points at the next item to
examine. */
if (*t == glbl)
t = &TREE_CHAIN (*t);
}
return result;
}
/* Walk the global declarations. Whenever one is found for which P
returns non-zero, call F with its address. If any call to F
returns a non-zero value, return a non-zero value. */
int
walk_globals (p, f, data)
walk_globals_pred p;
walk_globals_fn f;
void *data;
{
struct walk_globals_data wgd;
wgd.p = p;
wgd.f = f;
wgd.data = data;
return walk_namespaces (walk_globals_r, &wgd);
}
/* Call wrapup_globals_declarations for the globals in NAMESPACE. If
DATA is non-NULL, this is the last time we will call
wrapup_global_declarations for this NAMESPACE. */
int
wrapup_globals_for_namespace (namespace, data)
tree namespace;
void *data;
{
tree globals = NAMESPACE_LEVEL (namespace)->names;
int len = list_length (globals);
tree *vec = (tree *) alloca (sizeof (tree) * len);
int i;
tree decl;
int last_time = (data != 0);
if (last_time && namespace == global_namespace)
/* Let compile_file handle the global namespace. */
return 0;
/* Process the decls in reverse order--earliest first.
Put them into VEC from back to front, then take out from front. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
if (!last_time)
return wrapup_global_declarations (vec, len);
check_global_declarations (vec, len);
return 0;
}
/* For debugging. */ /* For debugging. */
static int no_print_functions = 0; static int no_print_functions = 0;
...@@ -2196,38 +2371,6 @@ pop_namespace () ...@@ -2196,38 +2371,6 @@ pop_namespace ()
suspend_binding_level (); suspend_binding_level ();
} }
/* Concatenate the binding levels of all namespaces. */
void
cat_namespace_levels()
{
tree current;
tree last;
struct binding_level *b;
last = NAMESPACE_LEVEL (global_namespace) -> names;
/* The nested namespaces appear in the names list of their ancestors. */
for (current = last; current; current = TREE_CHAIN (current))
{
/* Catch simple infinite loops. */
if (TREE_CHAIN (current) == current)
my_friendly_abort (990126);
if (TREE_CODE (current) != NAMESPACE_DECL
|| DECL_NAMESPACE_ALIAS (current))
continue;
if (!DECL_LANG_SPECIFIC (current))
{
/* Hmm. std. */
my_friendly_assert (current == std_node, 393);
continue;
}
b = NAMESPACE_LEVEL (current);
while (TREE_CHAIN (last))
last = TREE_CHAIN (last);
TREE_CHAIN (last) = NAMESPACE_LEVEL (current) -> names;
}
}
/* Subroutines for reverting temporarily to top-level for instantiation /* Subroutines for reverting temporarily to top-level for instantiation
of templates and such. We actually need to clear out the class- and of templates and such. We actually need to clear out the class- and
...@@ -8259,15 +8402,12 @@ expand_static_init (decl, init) ...@@ -8259,15 +8402,12 @@ expand_static_init (decl, init)
{ {
tree oldstatic = value_member (decl, static_aggregates); tree oldstatic = value_member (decl, static_aggregates);
/* If at_eof is 2, we're too late. */
my_friendly_assert (at_eof <= 1, 990323);
if (oldstatic) if (oldstatic)
{ {
if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
cp_error ("multiple initializations given for `%D'", decl); cp_error ("multiple initializations given for `%D'", decl);
} }
else if (! toplevel_bindings_p () && ! pseudo_global_level_p ()) else if (! toplevel_bindings_p ())
{ {
/* Emit code to perform this initialization but once. */ /* Emit code to perform this initialization but once. */
tree temp; tree temp;
...@@ -8369,22 +8509,16 @@ expand_static_init (decl, init) ...@@ -8369,22 +8509,16 @@ expand_static_init (decl, init)
} }
expand_end_cond (); expand_end_cond ();
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
{
static_aggregates = perm_tree_cons (temp, decl, static_aggregates);
TREE_STATIC (static_aggregates) = 1;
}
/* Resume old (possibly temporary) allocation. */ /* Resume old (possibly temporary) allocation. */
pop_obstacks (); pop_obstacks ();
} }
else else
{ {
/* This code takes into account memory allocation /* This code takes into account memory allocation policy of
policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING does not
does not hold for this object, then we must make permanent hold for this object, then we must make permanent the storage
the storage currently in the temporary obstack. */ currently in the temporary obstack. */
if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
preserve_initializer (); preserve_initializer ();
static_aggregates = perm_tree_cons (init, decl, static_aggregates); static_aggregates = perm_tree_cons (init, decl, static_aggregates);
} }
...@@ -13758,7 +13892,7 @@ finish_function (lineno, flags, nested) ...@@ -13758,7 +13892,7 @@ finish_function (lineno, flags, nested)
if (fndecl == NULL_TREE) if (fndecl == NULL_TREE)
return; return;
if (! nested && function_depth > 1) if (function_depth > 1)
nested = 1; nested = 1;
fntype = TREE_TYPE (fndecl); fntype = TREE_TYPE (fndecl);
...@@ -14029,8 +14163,6 @@ finish_function (lineno, flags, nested) ...@@ -14029,8 +14163,6 @@ finish_function (lineno, flags, nested)
tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type);
CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE;
DECL_RETURNS_FIRST_ARG (fndecl) = 1;
if (flag_this_is_variable > 0) if (flag_this_is_variable > 0)
{ {
cond = build_binary_op (EQ_EXPR, cond = build_binary_op (EQ_EXPR,
......
...@@ -42,11 +42,6 @@ extern tree this_identifier, in_charge_identifier; ...@@ -42,11 +42,6 @@ extern tree this_identifier, in_charge_identifier;
or a chain or parameter decls here. */ or a chain or parameter decls here. */
extern tree last_function_parms; extern tree last_function_parms;
/* 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. */
extern tree pending_statics;
/* A list of objects which have constructors or destructors /* A list of objects which have constructors or destructors
which reside in the global scope. The decl is stored in which reside in the global scope. The decl is stored in
the TREE_VALUE slot and the initializer is stored the TREE_VALUE slot and the initializer is stored
......
...@@ -86,6 +86,11 @@ static char *scratch_firstobj; ...@@ -86,6 +86,11 @@ static char *scratch_firstobj;
OB_PUTCP (digit_buffer); } while (0) OB_PUTCP (digit_buffer); } while (0)
# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N)); # define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
# define OB_END_TEMPLATE_ID() \
((obstack_next_free (&scratch_obstack) != obstack_base (&scratch_obstack) \
&& obstack_next_free (&scratch_obstack)[-1] == '>') \
? OB_PUTC2 (' ', '>') : OB_PUTC ('>'))
# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
enum pad { none, before, after }; enum pad { none, before, after };
...@@ -292,7 +297,7 @@ dump_type_real (t, v, canonical_name) ...@@ -292,7 +297,7 @@ dump_type_real (t, v, canonical_name)
if (i < TREE_VEC_LENGTH (args)-1) if (i < TREE_VEC_LENGTH (args)-1)
OB_PUTC2 (',', ' '); OB_PUTC2 (',', ' ');
} }
OB_PUTC ('>'); OB_END_TEMPLATE_ID ();
} }
break; break;
...@@ -863,7 +868,8 @@ dump_decl (t, v) ...@@ -863,7 +868,8 @@ dump_decl (t, v)
} }
if (len != 0) if (len != 0)
OB_UNPUT (2); OB_UNPUT (2);
OB_PUTC2 ('>', ' '); OB_END_TEMPLATE_ID ();
OB_PUTC (' ');
} }
nreverse(orig_args); nreverse(orig_args);
...@@ -905,7 +911,7 @@ dump_decl (t, v) ...@@ -905,7 +911,7 @@ dump_decl (t, v)
if (TREE_CHAIN (args)) if (TREE_CHAIN (args))
OB_PUTC2 (',', ' '); OB_PUTC2 (',', ' ');
} }
OB_PUTC ('>'); OB_END_TEMPLATE_ID ();
} }
break; break;
...@@ -1199,7 +1205,7 @@ dump_function_name (t) ...@@ -1199,7 +1205,7 @@ dump_function_name (t)
} }
} }
} }
OB_PUTC ('>'); OB_END_TEMPLATE_ID ();
} }
} }
......
...@@ -65,9 +65,9 @@ static int interface_strcmp PROTO((const char *)); ...@@ -65,9 +65,9 @@ static int interface_strcmp PROTO((const char *));
static int readescape PROTO((int *)); static int readescape PROTO((int *));
static char *extend_token_buffer PROTO((const char *)); static char *extend_token_buffer PROTO((const char *));
static void consume_string PROTO((struct obstack *, int)); static void consume_string PROTO((struct obstack *, int));
static void set_typedecl_interface_info PROTO((tree, tree)); static int set_typedecl_interface_info PROTO((tree *, void *));
static void feed_defarg PROTO((tree, tree)); static void feed_defarg PROTO((tree, tree));
static int set_vardecl_interface_info PROTO((tree, tree)); static int set_vardecl_interface_info PROTO((tree *, void *));
static void store_pending_inline PROTO((tree, struct pending_inline *)); static void store_pending_inline PROTO((tree, struct pending_inline *));
static void reinit_parse_for_expr PROTO((struct obstack *)); static void reinit_parse_for_expr PROTO((struct obstack *));
static int *init_cpp_parse PROTO((void)); static int *init_cpp_parse PROTO((void));
...@@ -1134,32 +1134,35 @@ interface_strcmp (s) ...@@ -1134,32 +1134,35 @@ interface_strcmp (s)
return 1; return 1;
} }
static void static int
set_typedecl_interface_info (prev, vars) set_typedecl_interface_info (t, data)
tree prev ATTRIBUTE_UNUSED, vars; tree *t;
void *data ATTRIBUTE_UNUSED;
{ {
tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); tree id = get_time_identifier (DECL_SOURCE_FILE (*t));
tree fileinfo = TIME_IDENTIFIER_FILEINFO (id); tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
tree type = TREE_TYPE (vars); tree type = TREE_TYPE (*t);
CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
= interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars))); = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (*t)));
return 0;
} }
static int static int
set_vardecl_interface_info (prev, vars) set_vardecl_interface_info (t, data)
tree prev, vars; tree *t;
void *data ATTRIBUTE_UNUSED;
{ {
tree type = DECL_CONTEXT (vars); tree type = DECL_CONTEXT (*t);
if (CLASSTYPE_INTERFACE_KNOWN (type)) if (CLASSTYPE_INTERFACE_KNOWN (type))
{ {
if (CLASSTYPE_INTERFACE_ONLY (type)) if (CLASSTYPE_INTERFACE_ONLY (type))
set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type)); set_typedecl_interface_info (&TYPE_MAIN_DECL (type), data);
else else
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); DECL_EXTERNAL (*t) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1; TREE_PUBLIC (*t) = 1;
return 1; return 1;
} }
return 0; return 0;
...@@ -2461,7 +2464,14 @@ linenum: ...@@ -2461,7 +2464,14 @@ linenum:
main_input_filename = input_filename; main_input_filename = input_filename;
if (write_virtuals == 3) if (write_virtuals == 3)
walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); {
walk_globals (vtable_decl_p,
set_vardecl_interface_info,
/*data=*/0);
walk_globals (vtype_decl_p,
set_typedecl_interface_info,
/*data=*/0);
}
} }
extract_interface_info (); extract_interface_info ();
......
...@@ -50,15 +50,21 @@ extern struct obstack permanent_obstack; ...@@ -50,15 +50,21 @@ extern struct obstack permanent_obstack;
extern int lineno; extern int lineno;
extern char *input_filename; extern char *input_filename;
struct pending_inline *pending_template_expansions;
tree current_template_parms; tree current_template_parms;
HOST_WIDE_INT processing_template_decl; HOST_WIDE_INT processing_template_decl;
tree pending_templates; /* The PENDING_TEMPLATES is a TREE_LIST of templates whose
instantiations have been deferred, either because their definitions
were not yet available, or because we were putting off doing the
work. The TREE_PURPOSE of each entry is a SRCLOC indicating where
the instantiate request occurred; the TREE_VALUE is a either a DECL
(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 *template_tail = &pending_templates;
tree maybe_templates; static tree maybe_templates;
static tree *maybe_template_tail = &maybe_templates; static tree *maybe_template_tail = &maybe_templates;
int minimal_parse_mode; int minimal_parse_mode;
...@@ -5124,7 +5130,7 @@ instantiate_class_template (type) ...@@ -5124,7 +5130,7 @@ instantiate_class_template (type)
input_filename = DECL_SOURCE_FILE (typedecl); input_filename = DECL_SOURCE_FILE (typedecl);
unreverse_member_declarations (type); unreverse_member_declarations (type);
type = finish_struct_1 (type, 0); finish_struct_1 (type, 0);
CLASSTYPE_GOT_SEMICOLON (type) = 1; CLASSTYPE_GOT_SEMICOLON (type) = 1;
/* Clear this now so repo_template_used is happy. */ /* Clear this now so repo_template_used is happy. */
...@@ -9421,6 +9427,115 @@ out: ...@@ -9421,6 +9427,115 @@ out:
return d; return d;
} }
/* Run through the list of templates that we wish we could
instantiate, and instantiate any we can. */
int
instantiate_pending_templates ()
{
tree *t;
int instantiated_something = 0;
int reconsider;
do
{
reconsider = 0;
t = &pending_templates;
while (*t)
{
tree srcloc = TREE_PURPOSE (*t);
tree instantiation = TREE_VALUE (*t);
input_filename = SRCLOC_FILE (srcloc);
lineno = SRCLOC_LINE (srcloc);
if (TREE_CODE_CLASS (TREE_CODE (instantiation)) == 't')
{
tree fn;
if (!TYPE_SIZE (instantiation))
{
instantiate_class_template (instantiation);
if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
for (fn = TYPE_METHODS (instantiation);
fn;
fn = TREE_CHAIN (fn))
if (! DECL_ARTIFICIAL (fn))
instantiate_decl (fn);
if (TYPE_SIZE (instantiation))
{
instantiated_something = 1;
reconsider = 1;
}
}
if (TYPE_SIZE (instantiation))
/* 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
{
if (DECL_TEMPLATE_INSTANTIATION (instantiation)
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
{
instantiation = instantiate_decl (instantiation);
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
{
instantiated_something = 1;
reconsider = 1;
}
}
if (!DECL_TEMPLATE_INSTANTIATION (instantiation)
|| DECL_TEMPLATE_INSTANTIATED (instantiation))
/* 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);
}
}
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);
reconsider = 1;
}
/* Remove this entry from the chain. */
*t = TREE_CHAIN (*t);
}
maybe_template_tail = t;
}
while (reconsider);
return instantiated_something;
}
/* Substitute ARGVEC into T, which is a TREE_LIST. In particular, it /* Substitute ARGVEC into T, which is a TREE_LIST. In particular, it
is an initializer list: the TREE_PURPOSEs are DECLs, and the is an initializer list: the TREE_PURPOSEs are DECLs, and the
TREE_VALUEs are initializer values. Used by instantiate_decl. */ TREE_VALUEs are initializer values. Used by instantiate_decl. */
......
...@@ -381,7 +381,7 @@ get_tinfo_fn (type) ...@@ -381,7 +381,7 @@ get_tinfo_fn (type)
TREE_PUBLIC (d) = 1; TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1; DECL_ARTIFICIAL (d) = 1;
DECL_NOT_REALLY_EXTERN (d) = 1; DECL_NOT_REALLY_EXTERN (d) = 1;
DECL_MUTABLE_P (d) = 1; SET_DECL_TINFO_FN_P (d);
TREE_TYPE (name) = copy_to_permanent (type); TREE_TYPE (name) = copy_to_permanent (type);
pushdecl_top_level (d); pushdecl_top_level (d);
......
...@@ -2687,12 +2687,6 @@ pod_type_p (t) ...@@ -2687,12 +2687,6 @@ pod_type_p (t)
return 1; return 1;
} }
/* A list of objects which have constructors or destructors
which reside in the global scope. The decl is stored in
the TREE_VALUE slot and the initializer is stored
in the TREE_PURPOSE slot. */
tree static_aggregates_initp;
/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid C++-specific /* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid C++-specific
attribute for either declaration DECL or type TYPE and 0 otherwise. attribute for either declaration DECL or type TYPE and 0 otherwise.
Plugged into valid_lang_attribute. */ Plugged into valid_lang_attribute. */
...@@ -2773,9 +2767,7 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type) ...@@ -2773,9 +2767,7 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
("requested init_priority is reserved for internal use"); ("requested init_priority is reserved for internal use");
} }
static_aggregates_initp DECL_INIT_PRIORITY (decl) = pri;
= perm_tree_cons (initp_expr, decl, static_aggregates_initp);
return 1; return 1;
} }
......
// Build don't run:
// Special g++ Options: -O3
// Origin: Mark Mitchell <mark@codesourcery.com>
typedef int (*fp)();
struct S
{
fp f;
};
struct T
{
static int f() {}
};
static const S s = { &T::f };
int main()
{
return (*s.f)();
}
// Build don't run:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
int f(T);
template <class T>
struct S {
template <class U>
friend int f(U) { return 0; }
};
int k = f(2);
template <class T>
int g(T);
int h = g(7);
template <class T>
int g(T) {
S<T> si;
return 0;
}
int main()
{
}
// Origin: Mark Mitchell <mark@codesourcery.com>
int i;
template <class T>
struct S {
S() { ++i; }
virtual void g() {}
virtual void f();
static S s;
};
template <class T>
void S<T>::f() {
s.f();
}
S<int> si;
template <class T>
S<T> S<T>::s;
int main ()
{
si.g();
if (i != 2)
return 1;
else
return 0;
}
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