From 6cad4e1709ec73b0c7978e5fab9ed623b7ac043b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 15 Aug 2003 13:14:01 +0200 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 11 ++++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 50 ++++++++++++++++++++++++++++++++++++++++------ gcc/cp/except.c | 34 +++++++++++++++++++++---------- gcc/cp/semantics.c | 2 ++ 5 files changed, 82 insertions(+), 16 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f8b592cbb0..bee756c8f5d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2003-08-14 Jan Hubicka + + * 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 * pt.c (instantiate_class_template): Set location before diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 934acb9934b..eae862a3380 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 54e627f5569..eb32f49378d 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 390f12c4551..1303919de37 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 29d5dd7524b..932bb982816 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 -- 2.30.2