Commit f44b0c8e by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (saved_scope): Make old_bindings a vector.

	* cp-tree.h (saved_scope): Make old_bindings a vector.
	(unuse_fields): Remove.
	* name-lookup.h (cxx_saved_binding): Define it.
	* class.c (pushclass): Don't use unuse_fields.
	* name-lookup.c (cxx_saved_binding_make): Remove.
	(store_binding): Add new bindings to a vector, using an
	accumulator style, rather than adding them to a list.
	(store_bindings): Adjust accordingly.
	(store_class_bindings): Likewise.
	(push_to_top_level): Likewise.
	(pop_from_top_level): Likewise.
	* optimize.c (maybe_clone_body): Must push_to_top_level and
	pop_from_top_level calls outside of loop.
	* parser.c (cp_parser_class_specifier): Move push_scope/pop_scope
	calls here from cp_parser_late_parsing_default_args.
	(cp_parser_save_default_args): Record the class type in which the
	function is declared.
	(cp_parser_late_parsing_default_args): Do not call
	push_nested_class/pop_nested_class.
	* search.c (dfs_unuse_fields): Remove.
	(unuse_fields): Remove.

	* g++.dg/parse/defarg8.C: New test.

From-SVN: r84530
parent 4dcf7d66
2004-07-11 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (saved_scope): Make old_bindings a vector.
(unuse_fields): Remove.
* name-lookup.h (cxx_saved_binding): Define it.
* class.c (pushclass): Don't use unuse_fields.
* name-lookup.c (cxx_saved_binding_make): Remove.
(store_binding): Add new bindings to a vector, using an
accumulator style, rather than adding them to a list.
(store_bindings): Adjust accordingly.
(store_class_bindings): Likewise.
(push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
* optimize.c (maybe_clone_body): Must push_to_top_level and
pop_from_top_level calls outside of loop.
* parser.c (cp_parser_class_specifier): Move push_scope/pop_scope
calls here from cp_parser_late_parsing_default_args.
(cp_parser_save_default_args): Record the class type in which the
function is declared.
(cp_parser_late_parsing_default_args): Do not call
push_nested_class/pop_nested_class.
* search.c (dfs_unuse_fields): Remove.
(unuse_fields): Remove.
2004-07-11 Joseph S. Myers <jsm@polyomino.org.uk> 2004-07-11 Joseph S. Myers <jsm@polyomino.org.uk>
* cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP, LANG_HOOKS_PUSHLEVEL, * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP, LANG_HOOKS_PUSHLEVEL,
......
...@@ -5569,7 +5569,6 @@ pushclass (tree type) ...@@ -5569,7 +5569,6 @@ pushclass (tree type)
if (type_decl && TREE_CODE (type_decl) == TYPE_DECL) if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
set_identifier_type_value (id, type_decl); set_identifier_type_value (id, type_decl);
} }
unuse_fields (type);
} }
cxx_remember_type_decls (CLASSTYPE_NESTED_UTDS (type)); cxx_remember_type_decls (CLASSTYPE_NESTED_UTDS (type));
......
...@@ -630,7 +630,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; ...@@ -630,7 +630,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
struct saved_scope GTY(()) struct saved_scope GTY(())
{ {
cxx_saved_binding *old_bindings; VEC(cxx_saved_binding) *old_bindings;
tree old_namespace; tree old_namespace;
tree decl_ns_list; tree decl_ns_list;
tree class_name; tree class_name;
...@@ -4015,7 +4015,6 @@ extern void maybe_suppress_debug_info (tree); ...@@ -4015,7 +4015,6 @@ extern void maybe_suppress_debug_info (tree);
extern void note_debug_info_needed (tree); extern void note_debug_info_needed (tree);
extern void push_class_decls (tree); extern void push_class_decls (tree);
extern void pop_class_decls (void); extern void pop_class_decls (void);
extern void unuse_fields (tree);
extern void print_search_statistics (void); extern void print_search_statistics (void);
extern void init_search_processing (void); extern void init_search_processing (void);
extern void reinit_search_statistics (void); extern void reinit_search_statistics (void);
......
...@@ -4809,22 +4809,6 @@ pushtag (tree name, tree type, int globalize) ...@@ -4809,22 +4809,6 @@ pushtag (tree name, tree type, int globalize)
timevar_pop (TV_NAME_LOOKUP); timevar_pop (TV_NAME_LOOKUP);
} }
/* Allocate storage for saving a C++ binding. */
#define cxx_saved_binding_make() \
(ggc_alloc (sizeof (cxx_saved_binding)))
struct cxx_saved_binding GTY(())
{
/* Link that chains saved C++ bindings for a given name into a stack. */
cxx_saved_binding *previous;
/* The name of the current binding. */
tree identifier;
/* The binding we're saving. */
cxx_binding *binding;
tree class_value;
tree real_type_value;
};
/* 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
local-value slots of all identifiers, so that only the global values local-value slots of all identifiers, so that only the global values
...@@ -4832,46 +4816,39 @@ struct cxx_saved_binding GTY(()) ...@@ -4832,46 +4816,39 @@ struct cxx_saved_binding GTY(())
scope isn't enough, because more binding levels may be pushed. */ scope isn't enough, because more binding levels may be pushed. */
struct saved_scope *scope_chain; struct saved_scope *scope_chain;
/* If ID is not already in the SEARCH_BINDINGS, prepend its binding /* If ID has not already been marked, add an appropriate binding to
information to OLD_BINDINGS. Returns the new OLD_BINDINGS *OLD_BINDINGS. */
list. */
static cxx_saved_binding * static void
store_binding (tree id, store_binding (tree id, VEC(cxx_saved_binding) **old_bindings)
cxx_saved_binding *old_bindings,
cxx_saved_binding *search_bindings)
{ {
cxx_saved_binding *saved; cxx_saved_binding *saved;
cxx_saved_binding *t1;
if (!id if (!id
/* Note that we may have an IDENTIFIER_CLASS_VALUE even when /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
we have no IDENTIFIER_BINDING if we have left the class we have no IDENTIFIER_BINDING if we have left the class
scope, but cached the class-level declarations. */ scope, but cached the class-level declarations. */
|| !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
return old_bindings; return;
if (IDENTIFIER_MARKED (id))
return;
for (t1 = search_bindings; t1; t1 = t1->previous) IDENTIFIER_MARKED (id) = 1;
if (t1->identifier == id)
return old_bindings;
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); saved = VEC_safe_push (cxx_saved_binding, *old_bindings, NULL);
saved = cxx_saved_binding_make ();
saved->previous = old_bindings;
saved->identifier = id; saved->identifier = id;
saved->binding = IDENTIFIER_BINDING (id); saved->binding = IDENTIFIER_BINDING (id);
saved->class_value = IDENTIFIER_CLASS_VALUE (id);; saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
IDENTIFIER_BINDING (id) = NULL; IDENTIFIER_BINDING (id) = NULL;
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
return saved;
} }
static cxx_saved_binding * static void
store_bindings (tree names, cxx_saved_binding *old_bindings) store_bindings (tree names, VEC(cxx_saved_binding) **old_bindings)
{ {
tree t; tree t;
cxx_saved_binding *search_bindings = old_bindings;
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
for (t = names; t; t = TREE_CHAIN (t)) for (t = names; t; t = TREE_CHAIN (t))
...@@ -4883,30 +4860,27 @@ store_bindings (tree names, cxx_saved_binding *old_bindings) ...@@ -4883,30 +4860,27 @@ store_bindings (tree names, cxx_saved_binding *old_bindings)
else else
id = DECL_NAME (t); id = DECL_NAME (t);
old_bindings store_binding (id, old_bindings);
= store_binding (id, old_bindings, search_bindings);
} }
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings); timevar_pop (TV_NAME_LOOKUP);
} }
/* Like store_bindings, but NAMES is a vector of cp_class_binding /* Like store_bindings, but NAMES is a vector of cp_class_binding
objects, rather than a TREE_LIST. */ objects, rather than a TREE_LIST. */
static cxx_saved_binding * static void
store_class_bindings (VEC(cp_class_binding) *names, store_class_bindings (VEC(cp_class_binding) *names,
cxx_saved_binding *old_bindings) VEC(cxx_saved_binding) **old_bindings)
{ {
size_t i; size_t i;
cp_class_binding *cb; cp_class_binding *cb;
cxx_saved_binding *search_bindings = old_bindings;
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
for (i = 0; for (i = 0;
(cb = VEC_iterate(cp_class_binding, names, i)); (cb = VEC_iterate(cp_class_binding, names, i));
++i) ++i)
old_bindings store_binding (cb->identifier, old_bindings);
= store_binding (cb->identifier, old_bindings, search_bindings); timevar_pop (TV_NAME_LOOKUP);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
} }
void void
...@@ -4914,7 +4888,8 @@ push_to_top_level (void) ...@@ -4914,7 +4888,8 @@ push_to_top_level (void)
{ {
struct saved_scope *s; struct saved_scope *s;
struct cp_binding_level *b; struct cp_binding_level *b;
cxx_saved_binding *old_bindings; cxx_saved_binding *sb;
size_t i;
int need_pop; int need_pop;
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
...@@ -4931,10 +4906,9 @@ push_to_top_level (void) ...@@ -4931,10 +4906,9 @@ push_to_top_level (void)
else else
need_pop = 0; need_pop = 0;
old_bindings = NULL;
if (scope_chain && previous_class_level) if (scope_chain && previous_class_level)
old_bindings = store_class_bindings (previous_class_level->class_shadowed, store_class_bindings (previous_class_level->class_shadowed,
old_bindings); &s->old_bindings);
/* Have to include the global scope, because class-scope decls /* Have to include the global scope, because class-scope decls
aren't listed anywhere useful. */ aren't listed anywhere useful. */
...@@ -4949,18 +4923,23 @@ push_to_top_level (void) ...@@ -4949,18 +4923,23 @@ push_to_top_level (void)
if (global_scope_p (b)) if (global_scope_p (b))
break; break;
old_bindings = store_bindings (b->names, old_bindings); store_bindings (b->names, &s->old_bindings);
/* We also need to check class_shadowed to save class-level type /* We also need to check class_shadowed to save class-level type
bindings, since pushclass doesn't fill in b->names. */ bindings, since pushclass doesn't fill in b->names. */
if (b->kind == sk_class) if (b->kind == sk_class)
old_bindings = store_class_bindings (b->class_shadowed, old_bindings); store_class_bindings (b->class_shadowed, &s->old_bindings);
/* Unwind type-value slots back to top level. */ /* Unwind type-value slots back to top level. */
for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
} }
for (i = 0;
(sb = VEC_iterate (cxx_saved_binding, s->old_bindings, i));
++i)
IDENTIFIER_MARKED (sb->identifier) = 0;
s->prev = scope_chain; s->prev = scope_chain;
s->old_bindings = old_bindings;
s->bindings = b; s->bindings = b;
s->need_pop_function_context = need_pop; s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl; s->function_decl = current_function_decl;
...@@ -4978,6 +4957,7 @@ pop_from_top_level (void) ...@@ -4978,6 +4957,7 @@ pop_from_top_level (void)
{ {
struct saved_scope *s = scope_chain; struct saved_scope *s = scope_chain;
cxx_saved_binding *saved; cxx_saved_binding *saved;
size_t i;
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
/* Clear out class-level bindings cache. */ /* Clear out class-level bindings cache. */
...@@ -4987,7 +4967,9 @@ pop_from_top_level (void) ...@@ -4987,7 +4967,9 @@ pop_from_top_level (void)
current_lang_base = 0; current_lang_base = 0;
scope_chain = s->prev; scope_chain = s->prev;
for (saved = s->old_bindings; saved; saved = saved->previous) for (i = 0;
(saved = VEC_iterate (cxx_saved_binding, s->old_bindings, i));
++i)
{ {
tree id = saved->identifier; tree id = saved->identifier;
......
...@@ -51,10 +51,6 @@ extern void binding_table_foreach (binding_table, bt_foreach_proc, void *); ...@@ -51,10 +51,6 @@ extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
extern binding_entry binding_table_find (binding_table, tree); extern binding_entry binding_table_find (binding_table, tree);
extern void cxx_remember_type_decls (binding_table); extern void cxx_remember_type_decls (binding_table);
/* Datatype used to temporarily save C++ bindings (for implicit
instantiations purposes and like). Implemented in decl.c. */
typedef struct cxx_saved_binding cxx_saved_binding;
/* Datatype that represents binding established by a declaration between /* Datatype that represents binding established by a declaration between
a name and a C++ entity. */ a name and a C++ entity. */
typedef struct cxx_binding cxx_binding; typedef struct cxx_binding cxx_binding;
...@@ -84,6 +80,20 @@ struct cxx_binding GTY(()) ...@@ -84,6 +80,20 @@ struct cxx_binding GTY(())
unsigned is_local : 1; unsigned is_local : 1;
}; };
/* Datatype used to temporarily save C++ bindings (for implicit
instantiations purposes and like). Implemented in decl.c. */
typedef struct cxx_saved_binding GTY(())
{
/* The name of the current binding. */
tree identifier;
/* The binding we're saving. */
cxx_binding *binding;
tree class_value;
tree real_type_value;
} cxx_saved_binding;
DEF_VEC_O(cxx_saved_binding);
extern tree identifier_type_value (tree); extern tree identifier_type_value (tree);
extern void set_identifier_type_value (tree, tree); extern void set_identifier_type_value (tree, tree);
extern void pop_binding (tree, tree); extern void pop_binding (tree, tree);
......
...@@ -88,6 +88,7 @@ maybe_clone_body (tree fn) ...@@ -88,6 +88,7 @@ maybe_clone_body (tree fn)
/* We know that any clones immediately follow FN in the TYPE_METHODS /* We know that any clones immediately follow FN in the TYPE_METHODS
list. */ list. */
push_to_top_level ();
for (clone = TREE_CHAIN (fn); for (clone = TREE_CHAIN (fn);
clone && DECL_CLONED_FUNCTION_P (clone); clone && DECL_CLONED_FUNCTION_P (clone);
clone = TREE_CHAIN (clone)) clone = TREE_CHAIN (clone))
...@@ -131,7 +132,6 @@ maybe_clone_body (tree fn) ...@@ -131,7 +132,6 @@ maybe_clone_body (tree fn)
update_cloned_parm (parm, clone_parm); update_cloned_parm (parm, clone_parm);
/* Start processing the function. */ /* Start processing the function. */
push_to_top_level ();
start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
/* Remap the parameters. */ /* Remap the parameters. */
...@@ -198,8 +198,8 @@ maybe_clone_body (tree fn) ...@@ -198,8 +198,8 @@ maybe_clone_body (tree fn)
finish_function (0); finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn); BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
expand_or_defer_fn (clone); expand_or_defer_fn (clone);
pop_from_top_level ();
} }
pop_from_top_level ();
/* We don't need to process the original function any further. */ /* We don't need to process the original function any further. */
return 1; return 1;
......
...@@ -12386,6 +12386,8 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -12386,6 +12386,8 @@ cp_parser_class_specifier (cp_parser* parser)
{ {
tree queue_entry; tree queue_entry;
tree fn; tree fn;
tree class_type;
bool pop_p;
/* In a first pass, parse default arguments to the functions. /* In a first pass, parse default arguments to the functions.
Then, in a second pass, parse the bodies of the functions. Then, in a second pass, parse the bodies of the functions.
...@@ -12397,6 +12399,8 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -12397,6 +12399,8 @@ cp_parser_class_specifier (cp_parser* parser)
}; };
*/ */
class_type = NULL_TREE;
pop_p = false;
for (TREE_PURPOSE (parser->unparsed_functions_queues) for (TREE_PURPOSE (parser->unparsed_functions_queues)
= nreverse (TREE_PURPOSE (parser->unparsed_functions_queues)); = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues));
(queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues)); (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues));
...@@ -12404,14 +12408,24 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -12404,14 +12408,24 @@ cp_parser_class_specifier (cp_parser* parser)
= TREE_CHAIN (TREE_PURPOSE (parser->unparsed_functions_queues))) = TREE_CHAIN (TREE_PURPOSE (parser->unparsed_functions_queues)))
{ {
fn = TREE_VALUE (queue_entry); fn = TREE_VALUE (queue_entry);
/* Make sure that any template parameters are in scope. */
maybe_begin_member_template_processing (fn);
/* If there are default arguments that have not yet been processed, /* If there are default arguments that have not yet been processed,
take care of them now. */ take care of them now. */
if (class_type != TREE_PURPOSE (queue_entry))
{
if (pop_p)
pop_scope (class_type);
class_type = TREE_PURPOSE (queue_entry);
pop_p = push_scope (class_type);
}
/* Make sure that any template parameters are in scope. */
maybe_begin_member_template_processing (fn);
/* Parse the default argument expressions. */
cp_parser_late_parsing_default_args (parser, fn); cp_parser_late_parsing_default_args (parser, fn);
/* Remove any template parameters from the symbol table. */ /* Remove any template parameters from the symbol table. */
maybe_end_member_template_processing (); maybe_end_member_template_processing ();
} }
if (pop_p)
pop_scope (class_type);
/* Now parse the body of the functions. */ /* Now parse the body of the functions. */
for (TREE_VALUE (parser->unparsed_functions_queues) for (TREE_VALUE (parser->unparsed_functions_queues)
= nreverse (TREE_VALUE (parser->unparsed_functions_queues)); = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
...@@ -12429,7 +12443,6 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -12429,7 +12443,6 @@ cp_parser_class_specifier (cp_parser* parser)
cp_parser_late_parsing_for_member (parser, fn); cp_parser_late_parsing_for_member (parser, fn);
function_depth--; function_depth--;
} }
} }
/* Put back any saved access checks. */ /* Put back any saved access checks. */
...@@ -15240,7 +15253,7 @@ cp_parser_save_default_args (cp_parser* parser, tree decl) ...@@ -15240,7 +15253,7 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
if (TREE_PURPOSE (probe)) if (TREE_PURPOSE (probe))
{ {
TREE_PURPOSE (parser->unparsed_functions_queues) TREE_PURPOSE (parser->unparsed_functions_queues)
= tree_cons (NULL_TREE, decl, = tree_cons (current_class_type, decl,
TREE_PURPOSE (parser->unparsed_functions_queues)); TREE_PURPOSE (parser->unparsed_functions_queues));
break; break;
} }
...@@ -15248,7 +15261,9 @@ cp_parser_save_default_args (cp_parser* parser, tree decl) ...@@ -15248,7 +15261,9 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
} }
/* FN is a FUNCTION_DECL which may contains a parameter with an /* FN is a FUNCTION_DECL which may contains a parameter with an
unparsed DEFAULT_ARG. Parse the default args now. */ unparsed DEFAULT_ARG. Parse the default args now. This function
assumes that the current scope is the scope in which the default
argument should be processed. */
static void static void
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
...@@ -15288,11 +15303,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) ...@@ -15288,11 +15303,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
parser->local_variables_forbidden_p = true; parser->local_variables_forbidden_p = true;
/* Parse the assignment-expression. */ /* Parse the assignment-expression. */
if (DECL_CLASS_SCOPE_P (fn))
push_nested_class (DECL_CONTEXT (fn));
TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser); TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
if (DECL_CLASS_SCOPE_P (fn))
pop_nested_class ();
/* If the token stream has not been completely used up, then /* If the token stream has not been completely used up, then
there was extra junk after the end of the default there was extra junk after the end of the default
......
...@@ -88,7 +88,6 @@ static tree dfs_debug_unmarkedp (tree, int, void *); ...@@ -88,7 +88,6 @@ static tree dfs_debug_unmarkedp (tree, int, void *);
static tree dfs_debug_mark (tree, void *); static tree dfs_debug_mark (tree, void *);
static tree dfs_push_type_decls (tree, void *); static tree dfs_push_type_decls (tree, void *);
static tree dfs_push_decls (tree, void *); static tree dfs_push_decls (tree, void *);
static tree dfs_unuse_fields (tree, void *);
static tree add_conversions (tree, void *); static tree add_conversions (tree, void *);
static int look_for_overrides_r (tree, tree); static int look_for_overrides_r (tree, tree);
static struct search_level *push_search_level (struct stack_level *, static struct search_level *push_search_level (struct stack_level *,
...@@ -2247,45 +2246,6 @@ push_class_decls (tree type) ...@@ -2247,45 +2246,6 @@ push_class_decls (tree type)
dfs_walk (TYPE_BINFO (type), dfs_push_decls, marked_pushdecls_p, 0); dfs_walk (TYPE_BINFO (type), dfs_push_decls, marked_pushdecls_p, 0);
} }
/* Here's a subroutine we need because C lacks lambdas. */
static tree
dfs_unuse_fields (tree binfo, void *data ATTRIBUTE_UNUSED)
{
tree type = TREE_TYPE (binfo);
tree fields;
if (TREE_CODE (type) == TYPENAME_TYPE)
fields = TYPENAME_TYPE_FULLNAME (type);
else if (TREE_CODE (type) == TYPEOF_TYPE)
fields = TYPEOF_TYPE_EXPR (type);
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
fields = TEMPLATE_TYPE_PARM_INDEX (type);
else
fields = TYPE_FIELDS (type);
for (; fields; fields = TREE_CHAIN (fields))
{
if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
continue;
TREE_USED (fields) = 0;
if (DECL_NAME (fields) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
unuse_fields (TREE_TYPE (fields));
}
return NULL_TREE;
}
void
unuse_fields (tree type)
{
dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp, 0);
}
void void
pop_class_decls (void) pop_class_decls (void)
{ {
......
2004-07-11 Mark Mitchell <mark@codesourcery.com>
* g++.dg/parse/defarg8.C: New test.
2004-07-11 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> 2004-07-11 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/16433 PR fortran/16433
......
struct A {
static void g(int);
};
struct S {
static int i;
friend void f(int = i);
friend void A::g(int = i);
};
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