aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-08-15 13:14:01 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2003-08-15 11:14:01 +0000
commit6cad4e1709ec73b0c7978e5fab9ed623b7ac043b (patch)
tree8cd74d2974a5e98a27d6bd910f280b5e804031ec
parent68ea098a059c352835b2090a02a163f47560ef17 (diff)
downloadgcc-6cad4e1709ec73b0c7978e5fab9ed623b7ac043b.zip
gcc-6cad4e1709ec73b0c7978e5fab9ed623b7ac043b.tar.gz
gcc-6cad4e1709ec73b0c7978e5fab9ed623b7ac043b.tar.bz2
decl2.c (mark_member_pointers): Rename to...
* decl2.c (mark_member_pointers): Rename to... (mark_member_pointers_and_eh_tinfos): ... this one; deal with eh tinfos (lower_function): Update call. * except.c (eh_type_info): Break out from ... (build_eh_type): ... here; tinfo is already used. (finish_eh_spec_block): Mark tinfos as used. * semantics.c (finish_handler_params): Mark tinfo as used. * cp-tree.h(eh_type_info): Declare. From-SVN: r70477
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c50
-rw-r--r--gcc/cp/except.c34
-rw-r--r--gcc/cp/semantics.c2
5 files changed, 82 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6f8b592..bee756c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Rename to...
+ (mark_member_pointers_and_eh_tinfos): ... this one; deal with eh tinfos
+ (lower_function): Update call.
+ * except.c (eh_type_info): Break out from ...
+ (build_eh_type): ... here; tinfo is already used.
+ (finish_eh_spec_block): Mark tinfos as used.
+ * semantics.c (finish_handler_params): Mark tinfo as used.
+ * cp-tree.h(eh_type_info): Declare.
+
2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (instantiate_class_template): Set location before
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 934acb9..eae862a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3829,6 +3829,7 @@ extern void mark_all_runtime_matches (void);
extern int nothrow_libfn_p (tree);
extern void check_handlers (tree);
extern void choose_personality_routine (enum languages);
+extern tree eh_type_info (tree);
/* in expr.c */
extern rtx cxx_expand_expr (tree, rtx,
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 54e627f..eb32f49 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2562,12 +2562,49 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
/* Callgraph code does not understand the member pointers. Mark the methods
referenced as used. */
static tree
-mark_member_pointers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *data ATTRIBUTE_UNUSED)
+mark_member_pointers_and_eh_handlers (tree *tp,
+ int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
{
- if (TREE_CODE (*tp) == PTRMEM_CST
- && TYPE_PTRMEMFUNC_P (TREE_TYPE (*tp)))
- cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)), 1);
+ /* Avoid useless walking of complex type and declaration nodes. */
+ if (TYPE_P (*tp) || DECL_P (*tp))
+ {
+ *walk_subtrees = 0;
+ return 0;
+ }
+ switch (TREE_CODE (*tp))
+ {
+ case PTRMEM_CST:
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (*tp)))
+ cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)), 1);
+ break;
+
+ /* EH handlers will emit EH tables referencing typeinfo. */
+ case HANDLER:
+ if (HANDLER_TYPE (*tp))
+ {
+ tree tinfo = eh_type_info (HANDLER_TYPE (*tp));
+
+ cgraph_varpool_mark_needed_node (cgraph_varpool_node (tinfo));
+ }
+ break;
+
+ case EH_SPEC_BLOCK:
+ {
+ tree type;
+
+ for (type = EH_SPEC_RAISES ((*tp)); type;
+ type = TREE_CHAIN (type))
+ {
+ tree tinfo = eh_type_info (TREE_VALUE (type));
+
+ cgraph_varpool_mark_needed_node (cgraph_varpool_node (tinfo));
+ }
+ }
+ break;
+ default:
+ break;
+ }
return 0;
}
@@ -2576,7 +2613,8 @@ mark_member_pointers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void
lower_function (tree fn)
{
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), mark_member_pointers,
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
+ mark_member_pointers_and_eh_handlers,
NULL);
}
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 390f12c..1303919 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -115,11 +115,9 @@ prepare_eh_type (tree type)
return type;
}
-/* Build the address of a typeinfo decl for use in the runtime
- matching field of the exception model. */
-
-static tree
-build_eh_type_type (tree type)
+/* Return the type info for TYPE as used by EH machinery. */
+tree
+eh_type_info (tree type)
{
tree exp;
@@ -131,12 +129,23 @@ build_eh_type_type (tree type)
else
exp = get_tinfo_decl (type);
- mark_used (exp);
- exp = build1 (ADDR_EXPR, ptr_type_node, exp);
-
return exp;
}
+/* Build the address of a typeinfo decl for use in the runtime
+ matching field of the exception model. */
+
+static tree
+build_eh_type_type (tree type)
+{
+ tree exp = eh_type_info (type);
+
+ if (!exp)
+ return NULL;
+
+ return build1 (ADDR_EXPR, ptr_type_node, exp);
+}
+
tree
build_exc_ptr (void)
{
@@ -470,8 +479,13 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
for (raises = NULL_TREE;
raw_raises && TREE_VALUE (raw_raises);
raw_raises = TREE_CHAIN (raw_raises))
- raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
- raises);
+ {
+ tree type = prepare_eh_type (TREE_VALUE (raw_raises));
+ tree tinfo = eh_type_info (type);
+
+ mark_used (tinfo);
+ raises = tree_cons (NULL_TREE, type, raises);
+ }
EH_SPEC_RAISES (eh_spec_block) = raises;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 29d5dd7..932bb98 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -956,6 +956,8 @@ finish_handler_parms (tree decl, tree handler)
type = expand_start_catch_block (decl);
HANDLER_TYPE (handler) = type;
+ if (type)
+ mark_used (eh_type_info (type));
}
/* Finish a handler, which may be given by HANDLER. The BLOCKs are