summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2002-09-19 09:19:36 -0700
committerDevang Patel <dpatel@gcc.gnu.org>2002-09-19 09:19:36 -0700
commit70b76b34a36af13d99506906cf89af67af614071 (patch)
tree6333d5c0f5f4cb057d87889291e28c7b8dae27f9 /gcc
parentb64ddb88fe0f4211125d8afa2d7348d6a9c242cf (diff)
downloadgcc-70b76b34a36af13d99506906cf89af67af614071.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c121
-rw-r--r--gcc/cp/decl2.c9
4 files changed, 98 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e3e14f903ae..9b1be50bdcc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bbfdd3a889c..53d214a7de7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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 *));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 92093a2c5d2..4dba35adeab 100644
--- a/gcc/cp/decl.c
+++ b/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;
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8529176a881..613c353402d 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);