cp-tree.h: New prototype for walk_vtabls().
2002-09-19 Devang Patel <dpatel@apple.com> * cp/cp-tree.h: New prototype for walk_vtabls(). * cp/decl.c (walk_vtables_r): New function. (struct cp_binding_level): Add new members, namespaces, names_size and vtables. (add_decl_to_level): Add decl in namespaces or vtables chain, if conditions match. (walk_vtables): New function. (walk_namespaces_r): Travers separate namespace chain for namespace decls. (wrapup_globals_for_namespace): Use names_size instead of list_length(). * cp/decl2.c (finish_file): Use walk_vtables() instead of walk_globals() to walk vtable decls. From-SVN: r57305
This commit is contained in:
parent
b64ddb88fe
commit
70b76b34a3
@ -1,3 +1,19 @@
|
||||
2002-09-18 Devang Patel <dpatel@apple.com>
|
||||
|
||||
* cp/cp-tree.h: New prototype for walk_vtabls().
|
||||
* cp/decl.c (walk_vtables_r): New function.
|
||||
(struct cp_binding_level): Add new members, namespaces,
|
||||
names_size and vtables.
|
||||
(add_decl_to_level): Add decl in namespaces or vtables
|
||||
chain, if conditions match.
|
||||
(walk_vtables): New function.
|
||||
(walk_namespaces_r): Travers separate namespace chain
|
||||
for namespace decls.
|
||||
(wrapup_globals_for_namespace): Use names_size instead
|
||||
of list_length().
|
||||
* cp/decl2.c (finish_file): Use walk_vtables() instead of
|
||||
walk_globals() to walk vtable decls.
|
||||
|
||||
2002-09-19 Steve Ellcey <sje@cup.hp.com>
|
||||
|
||||
* config/ia64/hpux.h (CTORS_SECTION_ASM_OP): New.
|
||||
@ -279,7 +295,6 @@ Tue Sep 17 13:40:13 2002 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
* real.h (real_nan): Return bool.
|
||||
* doc/extend.texi: Document new builtins.
|
||||
|
||||
>>>>>>> 1.15460
|
||||
2002-09-16 Jason Merrill <jason@redhat.com>
|
||||
Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
|
@ -3724,6 +3724,9 @@ typedef int (*walk_globals_fn) PARAMS ((tree *, void *));
|
||||
extern int walk_globals PARAMS ((walk_globals_pred,
|
||||
walk_globals_fn,
|
||||
void *));
|
||||
extern int walk_vtables PARAMS ((walk_globals_pred,
|
||||
walk_globals_fn,
|
||||
void *));
|
||||
typedef int (*walk_namespaces_fn) PARAMS ((tree, void *));
|
||||
extern int walk_namespaces PARAMS ((walk_namespaces_fn,
|
||||
void *));
|
||||
|
121
gcc/cp/decl.c
121
gcc/cp/decl.c
@ -108,6 +108,7 @@ static struct cp_binding_level *innermost_nonclass_level PARAMS ((void));
|
||||
static void warn_about_implicit_typename_lookup PARAMS ((tree, tree));
|
||||
static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *));
|
||||
static int walk_globals_r PARAMS ((tree, void *));
|
||||
static int walk_vtables_r PARAMS ((tree, void*));
|
||||
static void add_decl_to_level PARAMS ((tree, struct cp_binding_level *));
|
||||
static tree make_label_decl PARAMS ((tree, int));
|
||||
static void use_label PARAMS ((tree));
|
||||
@ -319,6 +320,15 @@ struct cp_binding_level GTY(())
|
||||
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
|
||||
tree names;
|
||||
|
||||
/* Count of elements in names chain. */
|
||||
size_t names_size;
|
||||
|
||||
/* A chain of NAMESPACE_DECL nodes. */
|
||||
tree namespaces;
|
||||
|
||||
/* A chain of VTABLE_DECL nodes. */
|
||||
tree vtables;
|
||||
|
||||
/* A list of structure, union and enum definitions, for looking up
|
||||
tag names.
|
||||
It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
|
||||
@ -1007,10 +1017,25 @@ add_decl_to_level (decl, b)
|
||||
tree decl;
|
||||
struct cp_binding_level *b;
|
||||
{
|
||||
/* We build up the list in reverse order, and reverse it later if
|
||||
necessary. */
|
||||
TREE_CHAIN (decl) = b->names;
|
||||
b->names = decl;
|
||||
if (TREE_CODE (decl) == NAMESPACE_DECL
|
||||
&& !DECL_NAMESPACE_ALIAS (decl))
|
||||
{
|
||||
TREE_CHAIN (decl) = b->namespaces;
|
||||
b->namespaces = decl;
|
||||
}
|
||||
else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
|
||||
{
|
||||
TREE_CHAIN (decl) = b->vtables;
|
||||
b->vtables = decl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We build up the list in reverse order, and reverse it later if
|
||||
necessary. */
|
||||
TREE_CHAIN (decl) = b->names;
|
||||
b->names = decl;
|
||||
b->names_size++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bind DECL to ID in the current_binding_level, assumed to be a local
|
||||
@ -1747,6 +1772,50 @@ cp_namespace_decls (ns)
|
||||
return NAMESPACE_LEVEL (ns)->names;
|
||||
}
|
||||
|
||||
struct walk_globals_data {
|
||||
walk_globals_pred p;
|
||||
walk_globals_fn f;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* Walk the vtable 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_vtables_r (namespace, data)
|
||||
tree namespace;
|
||||
void *data;
|
||||
{
|
||||
struct walk_globals_data* wgd = (struct walk_globals_data *) data;
|
||||
walk_globals_fn f = wgd->f;
|
||||
void *d = wgd->data;
|
||||
tree decl = NAMESPACE_LEVEL (namespace)->vtables;
|
||||
int result = 0;
|
||||
|
||||
for (; decl ; decl = TREE_CHAIN (decl))
|
||||
result != (*f) (&decl, d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Walk the vtable 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_vtables (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_vtables_r, &wgd);
|
||||
}
|
||||
|
||||
/* Walk all the namespaces contained NAMESPACE, including NAMESPACE
|
||||
itself, calling F for each. The DATA is passed to F as well. */
|
||||
|
||||
@ -1756,22 +1825,13 @@ walk_namespaces_r (namespace, f, data)
|
||||
walk_namespaces_fn f;
|
||||
void *data;
|
||||
{
|
||||
tree current;
|
||||
int result = 0;
|
||||
tree current = NAMESPACE_LEVEL (namespace)->namespaces;
|
||||
|
||||
result |= (*f) (namespace, data);
|
||||
|
||||
for (current = cp_namespace_decls (namespace);
|
||||
current;
|
||||
current = TREE_CHAIN (current))
|
||||
{
|
||||
if (TREE_CODE (current) != NAMESPACE_DECL
|
||||
|| DECL_NAMESPACE_ALIAS (current))
|
||||
continue;
|
||||
|
||||
/* We found a namespace. */
|
||||
result |= walk_namespaces_r (current, f, data);
|
||||
}
|
||||
for (; current; current = TREE_CHAIN (current))
|
||||
result |= walk_namespaces_r (current, f, data);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1787,12 +1847,6 @@ walk_namespaces (f, 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. */
|
||||
@ -1855,7 +1909,7 @@ wrapup_globals_for_namespace (namespace, data)
|
||||
void *data;
|
||||
{
|
||||
tree globals = cp_namespace_decls (namespace);
|
||||
int len = list_length (globals);
|
||||
int len = NAMESPACE_LEVEL (namespace)->names_size;
|
||||
tree *vec = (tree *) alloca (sizeof (tree) * len);
|
||||
int i;
|
||||
int result;
|
||||
@ -1867,7 +1921,7 @@ wrapup_globals_for_namespace (namespace, data)
|
||||
return 0;
|
||||
|
||||
/* Process the decls in reverse order--earliest first.
|
||||
Put them into VEC from back to front, then take out from front. */
|
||||
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;
|
||||
|
||||
@ -1877,28 +1931,9 @@ wrapup_globals_for_namespace (namespace, data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Temporarily mark vtables as external. That prevents
|
||||
wrapup_global_declarations from writing them out; we must process
|
||||
them ourselves in finish_vtable_vardecl. */
|
||||
for (i = 0; i < len; ++i)
|
||||
if (vtable_decl_p (vec[i], /*data=*/0) && !DECL_EXTERNAL (vec[i]))
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (vec[i]) = 1;
|
||||
DECL_EXTERNAL (vec[i]) = 1;
|
||||
}
|
||||
|
||||
/* Write out any globals that need to be output. */
|
||||
result = wrapup_global_declarations (vec, len);
|
||||
|
||||
/* Undo the hack to DECL_EXTERNAL above. */
|
||||
for (i = 0; i < len; ++i)
|
||||
if (vtable_decl_p (vec[i], /*data=*/0)
|
||||
&& DECL_NOT_REALLY_EXTERN (vec[i]))
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (vec[i]) = 0;
|
||||
DECL_EXTERNAL (vec[i]) = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2774,7 +2774,7 @@ finish_file ()
|
||||
/* Write out virtual tables as required. Note that writing out
|
||||
the virtual table for a template class may cause the
|
||||
instantiation of members of that class. */
|
||||
if (walk_globals (vtable_decl_p,
|
||||
if (walk_vtables (vtable_decl_p,
|
||||
finish_vtable_vardecl,
|
||||
/*data=*/0))
|
||||
reconsider = 1;
|
||||
@ -2955,13 +2955,6 @@ finish_file ()
|
||||
linkage now. */
|
||||
pop_lang_context ();
|
||||
|
||||
/* Now delete from the chain of variables all virtual function tables.
|
||||
We output them all ourselves, because each will be treated
|
||||
specially. We don't do this if we're just doing semantic
|
||||
analysis, and not code-generation. */
|
||||
if (!flag_syntax_only)
|
||||
walk_globals (vtable_decl_p, prune_vtable_vardecl, /*data=*/0);
|
||||
|
||||
/* Now, issue warnings about static, but not defined, functions,
|
||||
etc., and emit debugging information. */
|
||||
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
|
||||
|
Loading…
x
Reference in New Issue
Block a user