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
This commit is contained in:
Mark Mitchell 1999-04-22 23:13:12 +00:00 committed by Mark Mitchell
parent 32291f940e
commit 0aafb128c0
15 changed files with 1272 additions and 726 deletions

View File

@ -1,5 +1,105 @@
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
with the RTL code RETURN.
* hash.h: Regenerated.

View File

@ -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 \
lex.h decl.h $(EXPR_H) $(srcdir)/../except.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 \
$(srcdir)/../system.h $(srcdir)/../toplev.h
typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \

View File

@ -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. */
tree
void
finish_struct_1 (t, warn_anon)
tree t;
int warn_anon;
@ -3144,7 +3144,7 @@ finish_struct_1 (t, warn_anon)
else
my_friendly_abort (172);
popclass ();
return t;
return;
}
GNU_xref_decl (current_function_decl, t);
@ -4116,7 +4116,7 @@ finish_struct_1 (t, warn_anon)
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel_bindings_p ());
return t;
return;
}
/* When T was built up, the member declarations were added in reverse
@ -4210,7 +4210,7 @@ finish_struct (t, attributes, warn_anon)
TYPE_SIZE (t) = integer_zero_node;
}
else
t = finish_struct_1 (t, warn_anon);
finish_struct_1 (t, warn_anon);
TYPE_BEING_DEFINED (t) = 0;

View File

@ -88,6 +88,9 @@ Boston, MA 02111-1307, USA. */
For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
For a TEMPLATE_TEMPLATE_PARM, this is
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. */
@ -1149,8 +1152,6 @@ struct lang_decl_flags
unsigned operator_attr : 1;
unsigned constructor_attr : 1;
unsigned returns_first_arg : 1;
unsigned preserves_first_arg : 1;
unsigned friend_attr : 1;
unsigned static_function : 1;
unsigned const_memfunc : 1;
@ -1171,7 +1172,7 @@ struct lang_decl_flags
unsigned needs_final_overrider : 1;
unsigned bitfield : 1;
unsigned defined_in_class : 1;
unsigned dummy : 1;
unsigned dummy : 3;
tree access;
tree context;
@ -1221,20 +1222,20 @@ struct lang_decl
for an object with virtual baseclasses. */
#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
implementation of a signature method. */
#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
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
@ -1352,6 +1353,11 @@ struct lang_decl
#define ORIGINAL_NAMESPACE(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
directives */
#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0)
@ -2715,7 +2721,7 @@ extern int currently_open_class PROTO((tree));
extern tree get_vfield_offset PROTO((tree));
extern void duplicate_tag_error PROTO((tree));
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 void init_class_processing PROTO((void));
extern int is_empty_class PROTO((tree));
@ -2873,7 +2879,6 @@ extern int in_function_p PROTO((void));
extern void replace_defarg PROTO((tree, tree));
extern void print_other_binding_stack PROTO((struct binding_level *));
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 int check_static_variable_definition PROTO((tree, tree));
extern void push_local_binding PROTO((tree, tree, int));
@ -2882,6 +2887,18 @@ extern tree check_default_argument PROTO((tree, tree));
extern tree push_overloaded_decl PROTO((tree, int));
extern void clear_identifier_class_values PROTO((void));
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 */
extern int check_java_method PROTO((tree));
@ -2919,10 +2936,6 @@ extern tree coerce_delete_type PROTO((tree));
extern void comdat_linkage PROTO((tree));
extern void import_export_class PROTO((tree));
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 tree build_cleanup PROTO((tree));
extern void finish_file PROTO((void));
@ -3158,6 +3171,7 @@ extern void maybe_process_partial_specialization PROTO((tree));
extern void maybe_check_template_type PROTO((tree));
extern tree most_specialized_instantiation PROTO((tree, tree));
extern void print_candidates PROTO((tree));
extern int instantiate_pending_templates PROTO((void));
extern int processing_specialization;
extern int processing_explicit_instantiation;

View File

@ -192,6 +192,8 @@ static void find_class_binding_level PROTO((void));
static struct binding_level *innermost_nonclass_level PROTO((void));
static tree poplevel_class PROTO((void));
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)
static void indent PROTO((void));
@ -1833,6 +1835,179 @@ clear_identifier_class_values ()
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. */
static int no_print_functions = 0;
@ -2196,38 +2371,6 @@ pop_namespace ()
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
of templates and such. We actually need to clear out the class- and
@ -8259,15 +8402,12 @@ expand_static_init (decl, init)
{
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 (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
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. */
tree temp;
@ -8369,22 +8509,16 @@ expand_static_init (decl, init)
}
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. */
pop_obstacks ();
}
else
{
/* This code takes into account memory allocation
policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING
does not hold for this object, then we must make permanent
the storage currently in the temporary obstack. */
if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
/* This code takes into account memory allocation policy of
`start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING does not
hold for this object, then we must make permanent the storage
currently in the temporary obstack. */
if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
preserve_initializer ();
static_aggregates = perm_tree_cons (init, decl, static_aggregates);
}
@ -13758,7 +13892,7 @@ finish_function (lineno, flags, nested)
if (fndecl == NULL_TREE)
return;
if (! nested && function_depth > 1)
if (function_depth > 1)
nested = 1;
fntype = TREE_TYPE (fndecl);
@ -14029,8 +14163,6 @@ finish_function (lineno, flags, nested)
tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type);
CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE;
DECL_RETURNS_FIRST_ARG (fndecl) = 1;
if (flag_this_is_variable > 0)
{
cond = build_binary_op (EQ_EXPR,

View File

@ -42,11 +42,6 @@ extern tree this_identifier, in_charge_identifier;
or a chain or parameter decls here. */
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
which reside in the global scope. The decl is stored in
the TREE_VALUE slot and the initializer is stored

File diff suppressed because it is too large Load Diff

View File

@ -86,6 +86,11 @@ static char *scratch_firstobj;
OB_PUTCP (digit_buffer); } while (0)
# 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)))
enum pad { none, before, after };
@ -292,7 +297,7 @@ dump_type_real (t, v, canonical_name)
if (i < TREE_VEC_LENGTH (args)-1)
OB_PUTC2 (',', ' ');
}
OB_PUTC ('>');
OB_END_TEMPLATE_ID ();
}
break;
@ -863,7 +868,8 @@ dump_decl (t, v)
}
if (len != 0)
OB_UNPUT (2);
OB_PUTC2 ('>', ' ');
OB_END_TEMPLATE_ID ();
OB_PUTC (' ');
}
nreverse(orig_args);
@ -905,7 +911,7 @@ dump_decl (t, v)
if (TREE_CHAIN (args))
OB_PUTC2 (',', ' ');
}
OB_PUTC ('>');
OB_END_TEMPLATE_ID ();
}
break;
@ -1199,7 +1205,7 @@ dump_function_name (t)
}
}
}
OB_PUTC ('>');
OB_END_TEMPLATE_ID ();
}
}

View File

@ -65,9 +65,9 @@ static int interface_strcmp PROTO((const char *));
static int readescape PROTO((int *));
static char *extend_token_buffer PROTO((const char *));
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 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 reinit_parse_for_expr PROTO((struct obstack *));
static int *init_cpp_parse PROTO((void));
@ -1134,32 +1134,35 @@ interface_strcmp (s)
return 1;
}
static void
set_typedecl_interface_info (prev, vars)
tree prev ATTRIBUTE_UNUSED, vars;
static int
set_typedecl_interface_info (t, data)
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 type = TREE_TYPE (vars);
tree type = TREE_TYPE (*t);
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
set_vardecl_interface_info (prev, vars)
tree prev, vars;
set_vardecl_interface_info (t, data)
tree *t;
void *data ATTRIBUTE_UNUSED;
{
tree type = DECL_CONTEXT (vars);
tree type = DECL_CONTEXT (*t);
if (CLASSTYPE_INTERFACE_KNOWN (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
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1;
DECL_EXTERNAL (*t) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (*t) = 1;
return 1;
}
return 0;
@ -2461,7 +2464,14 @@ linenum:
main_input_filename = input_filename;
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 ();

View File

@ -50,15 +50,21 @@ extern struct obstack permanent_obstack;
extern int lineno;
extern char *input_filename;
struct pending_inline *pending_template_expansions;
tree current_template_parms;
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;
tree maybe_templates;
static tree maybe_templates;
static tree *maybe_template_tail = &maybe_templates;
int minimal_parse_mode;
@ -5124,7 +5130,7 @@ instantiate_class_template (type)
input_filename = DECL_SOURCE_FILE (typedecl);
unreverse_member_declarations (type);
type = finish_struct_1 (type, 0);
finish_struct_1 (type, 0);
CLASSTYPE_GOT_SEMICOLON (type) = 1;
/* Clear this now so repo_template_used is happy. */
@ -9421,6 +9427,115 @@ out:
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
is an initializer list: the TREE_PURPOSEs are DECLs, and the
TREE_VALUEs are initializer values. Used by instantiate_decl. */

View File

@ -381,7 +381,7 @@ get_tinfo_fn (type)
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (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);
pushdecl_top_level (d);

View File

@ -2687,12 +2687,6 @@ pod_type_p (t)
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
attribute for either declaration DECL or type TYPE and 0 otherwise.
Plugged into valid_lang_attribute. */
@ -2773,9 +2767,7 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
("requested init_priority is reserved for internal use");
}
static_aggregates_initp
= perm_tree_cons (initp_expr, decl, static_aggregates_initp);
DECL_INIT_PRIORITY (decl) = pri;
return 1;
}

View File

@ -0,0 +1,22 @@
// 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)();
}

View File

@ -0,0 +1,29 @@
// 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()
{
}

View File

@ -0,0 +1,32 @@
// 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;
}