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:
Devang Patel 2002-09-19 09:19:36 -07:00 committed by Devang Patel
parent b64ddb88fe
commit 70b76b34a3
4 changed files with 98 additions and 52 deletions

View File

@ -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>

View File

@ -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 *));

View File

@ -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;
}

View File

@ -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);