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:
parent
32291f940e
commit
0aafb128c0
100
gcc/cp/ChangeLog
100
gcc/cp/ChangeLog
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
232
gcc/cp/decl.c
232
gcc/cp/decl.c
@ -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,
|
||||
|
@ -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
|
||||
|
1326
gcc/cp/decl2.c
1326
gcc/cp/decl2.c
File diff suppressed because it is too large
Load Diff
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
40
gcc/cp/lex.c
40
gcc/cp/lex.c
@ -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 ();
|
||||
|
123
gcc/cp/pt.c
123
gcc/cp/pt.c
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
22
gcc/testsuite/g++.old-deja/g++.other/init12.C
Normal file
22
gcc/testsuite/g++.old-deja/g++.other/init12.C
Normal 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)();
|
||||
}
|
29
gcc/testsuite/g++.old-deja/g++.pt/link1.C
Normal file
29
gcc/testsuite/g++.old-deja/g++.pt/link1.C
Normal 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()
|
||||
{
|
||||
}
|
||||
|
32
gcc/testsuite/g++.old-deja/g++.pt/static8.C
Normal file
32
gcc/testsuite/g++.old-deja/g++.pt/static8.C
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user