summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>1998-06-25 14:11:54 +0000
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>1998-06-25 14:11:54 +0000
commita85413a6ac28d432734c514cd140ee039daad06b (patch)
treebb987eafff1d4601db541283435b2bfed1629fa6
parent600e851bdb70dfca6f83809e7256c6fb5154a417 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/except.c30
-rw-r--r--gcc/cp/exception.cc3
-rw-r--r--gcc/eh-common.h5
-rw-r--r--gcc/except.c66
-rw-r--r--gcc/except.h5
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));