diff options
author | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-25 14:11:54 +0000 |
---|---|---|
committer | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-25 14:11:54 +0000 |
commit | a85413a6ac28d432734c514cd140ee039daad06b (patch) | |
tree | bb987eafff1d4601db541283435b2bfed1629fa6 | |
parent | 600e851bdb70dfca6f83809e7256c6fb5154a417 (diff) | |
download | gcc-a85413a6ac28d432734c514cd140ee039daad06b.tar.gz |
Thu Jun 25 16:59:18 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
* except.h (CATCH_ALL_TYPE): Definition moved to eh-common.h.
(find_all_handler_type_matches): Add function prototype.
* eh-common.h (CATCH_ALL_TYPE): Definition added.
* except.c (find_all_handler_type_matches): Add function to find all
runtime type info in the exception table.
(output_exception_table_entry): Special case for CATCH_ALL_TYPE.
1998-06-25 Andrew MacLeod <amacleod@cygnus.com>
* cp-tree.h (mark_all_runtime_matches): Add function prototype.
* except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED
flag for all function decls which are in the exception table.
* exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match.
* decl2.c (finish_file): Call mark_all_runtime_matches to make sure
code is emitted for any referenced rtti function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20718 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/except.c | 30 | ||||
-rw-r--r-- | gcc/cp/exception.cc | 3 | ||||
-rw-r--r-- | gcc/eh-common.h | 5 | ||||
-rw-r--r-- | gcc/except.c | 66 | ||||
-rw-r--r-- | gcc/except.h | 5 |
9 files changed, 126 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ff713faed1..7360bff192f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Thu Jun 25 16:59:18 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> + + * except.h (CATCH_ALL_TYPE): Definition moved to eh-common.h. + (find_all_handler_type_matches): Add function prototype. + * eh-common.h (CATCH_ALL_TYPE): Definition added. + * except.c (find_all_handler_type_matches): Add function to find all + runtime type info in the exception table. + (output_exception_table_entry): Special case for CATCH_ALL_TYPE. + Thu Jun 25 15:47:55 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * Makefile.in (xcoffout.o): Depend on toplev.h, output.h and dbxout.h. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 97fd41b806a..0934e2a0544 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1998-06-25 Andrew MacLeod <amacleod@cygnus.com> + + * cp-tree.h (mark_all_runtime_matches): Add function prototype. + * except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED + flag for all function decls which are in the exception table. + * exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match. + * decl2.c (finish_file): Call mark_all_runtime_matches to make sure + code is emitted for any referenced rtti function. + 1998-06-25 Dave Brolley <brolley@cygnus.com> * lang-specs.h: Use new | syntax to eliminate diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5d0e25bcafe..1e0a4b2642d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2523,6 +2523,7 @@ extern tree start_anon_func PROTO((void)); extern void end_anon_func PROTO((void)); extern void expand_throw PROTO((tree)); extern tree build_throw PROTO((tree)); +extern void mark_all_runtime_matches PROTO((void)); /* in expr.c */ extern void init_cplus_expand PROTO((void)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 87f65fa665f..f1f83b4ec07 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3257,6 +3257,8 @@ finish_file () import_export_decl (decl); } + mark_all_runtime_matches (); + /* Now write out inline functions which had their addresses taken and which were not declared virtual and which were not declared `extern inline'. */ diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 438351ef8cd..4139dfdaeb0 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -472,6 +472,34 @@ build_eh_type (exp) return build_eh_type_type (TREE_TYPE (exp)); } +/* This routine is called to mark all the symbols representing runtime + type functions in the exception table as haveing been referenced. + This will make sure code is emitted for them. Called from finish_file. */ +void +mark_all_runtime_matches () +{ + int x,num; + void **ptr; + tree exp; + + num = find_all_handler_type_matches (&ptr); + if (num == 0 || ptr == NULL) + return; + + for (x=0; x <num; x++) + { + exp = (tree) ptr[x]; + if (TREE_CODE (exp) == ADDR_EXPR) + { + exp = TREE_OPERAND (exp, 0); + if (TREE_CODE (exp) == FUNCTION_DECL) + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (exp)) = 1; + } + } + + free (ptr); +} + /* Build up a call to __cp_pop_exception, to destroy the exception object for the current catch block. HANDLER is either true or false, telling the library whether or not it is being called from an exception handler; @@ -721,7 +749,7 @@ process_start_catch_block (declspecs, declarator) if (decl) start_catch_handler (build_eh_type_type_ref (TREE_TYPE (decl))); else - start_catch_handler (NULL_TREE); + start_catch_handler (CATCH_ALL_TYPE); emit_line_note (input_filename, lineno); diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc index bb36a669621..4c10404cad8 100644 --- a/gcc/cp/exception.cc +++ b/gcc/cp/exception.cc @@ -160,6 +160,9 @@ __cplus_type_matcher (cp_eh_info *info, rtimetype match_info, if (exception_table->lang.language != EH_LANG_C_plus_plus) return NULL; + if (match_info == CATCH_ALL_TYPE) + return info->value; + /* we don't worry about version info yet, there is only one version! */ void *match_type = match_info (); diff --git a/gcc/eh-common.h b/gcc/eh-common.h index c8d98c09072..143ddff10d7 100644 --- a/gcc/eh-common.h +++ b/gcc/eh-common.h @@ -86,9 +86,14 @@ typedef struct exception_descriptor typedef void * (*__eh_matcher) PROTO ((void *, void *, void *)); +/* This value is to be checked as a 'match all' case in the runtime field. */ + +#define CATCH_ALL_TYPE ((void *) -1) + /* This is the runtime exception information. This forms the minimum required information for an exception info pointer in an eh_context structure. */ + typedef struct __eh_info { __eh_matcher match_function; diff --git a/gcc/except.c b/gcc/except.c index 4c6fd6dfb1f..86871d0eea8 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -787,6 +787,66 @@ void remove_handler (removing_label) } } +/* This function will return a malloc'd pointer to an array of + void pointer representing the runtime match values that + currently exist in all regions. */ + +int +find_all_handler_type_matches (void ***array) +{ + struct handler_info *handler, *last; + int x,y; + void *val; + void **ptr; + int max_ptr; + int n_ptr = 0; + + *array = NULL; + + if (!doing_eh (0) || ! flag_new_exceptions) + return 0; + + max_ptr = 100; + ptr = (void **)malloc (max_ptr * sizeof (void *)); + + if (ptr == NULL) + return 0; + + for (x = 0 ; x < current_func_eh_entry; x++) + { + last = NULL; + handler = function_eh_regions[x].handlers; + for ( ; handler; last = handler, handler = handler->next) + { + val = handler->type_info; + if (val != NULL && val != CATCH_ALL_TYPE) + { + /* See if this match value has already been found. */ + for (y = 0; y < n_ptr; y++) + if (ptr[y] == val) + break; + + /* If we break early, we already found this value. */ + if (y < n_ptr) + continue; + + /* Do we need to allocate more space? */ + if (n_ptr >= max_ptr) + { + max_ptr += max_ptr / 2; + ptr = (void **)realloc (ptr, max_ptr * sizeof (void *)); + if (ptr == NULL) + return 0; + } + ptr[n_ptr] = val; + n_ptr++; + } + } + } + *array = ptr; + return n_ptr; +} + /* Create a new handler structure initialized with the handler label and typeinfo fields passed in. */ @@ -1852,7 +1912,11 @@ output_exception_table_entry (file, n) if (handler->type_info == NULL) assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); else - output_constant ((tree)(handler->type_info), + if (handler->type_info == CATCH_ALL_TYPE) + assemble_integer (GEN_INT (CATCH_ALL_TYPE), + POINTER_SIZE / BITS_PER_UNIT, 1); + else + output_constant ((tree)(handler->type_info), POINTER_SIZE / BITS_PER_UNIT); } putc ('\n', file); /* blank line */ diff --git a/gcc/except.h b/gcc/except.h index edb95ade5fc..c08d0c58399 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -161,8 +161,6 @@ void set_exception_version_code PROTO((short)); exception. NEXT is a pointer to the next handler for this region. NULL means there are no more. */ -#define CATCH_ALL_TYPE (tree *) -1 - typedef struct handler_info { rtx handler_label; @@ -209,6 +207,9 @@ int duplicate_handlers PROTO((int, int)); struct handler_info *get_first_handler PROTO((int)); +/* Find all the runtime handlers type matches currently referenced */ + +int find_all_handler_type_matches PROTO((void ***)); extern void init_eh PROTO((void)); |