diff options
author | Devang Patel <dpatel@apple.com> | 2002-09-19 09:19:36 -0700 |
---|---|---|
committer | Devang Patel <dpatel@gcc.gnu.org> | 2002-09-19 09:19:36 -0700 |
commit | 70b76b34a36af13d99506906cf89af67af614071 (patch) | |
tree | 6333d5c0f5f4cb057d87889291e28c7b8dae27f9 /gcc | |
parent | b64ddb88fe0f4211125d8afa2d7348d6a9c242cf (diff) | |
download | gcc-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/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/decl.c | 121 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 9 |
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); |