mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-31 16:40:27 +08:00
86th Cygnus<->FSF quick merge
From-SVN: r11952
This commit is contained in:
parent
637dec4188
commit
a50f091815
@ -1,3 +1,41 @@
|
||||
Mon May 6 01:23:32 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (finish_file): Don't try to emit functions that haven't
|
||||
been compiled.
|
||||
|
||||
Fri May 3 09:30:13 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (finish_vtable_vardecl): Oops.
|
||||
|
||||
* decl.c (maybe_push_to_top_level): Do save previous_class_*.
|
||||
Also store the bindings from previous_class_values.
|
||||
(pop_from_top_level): Restore them.
|
||||
|
||||
Thu May 2 21:56:49 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (finish_vtable_vardecl): Only write out vtable if its
|
||||
symbol has been referenced.
|
||||
(finish_file): Re-join synthesis/vtable loop with inline emission
|
||||
loop, disable inlining when an inline is output.
|
||||
|
||||
Thu May 2 17:20:02 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (init_exception_processing): Setup saved_in_catch.
|
||||
(push_eh_cleanup): Reset __eh_in_catch.
|
||||
(expand_start_catch_block): Set __eh_in_catch.
|
||||
|
||||
Thu May 2 16:21:17 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (push_eh_cleanup): Add tracking for whether or not we
|
||||
have an active exception object.
|
||||
(expand_builtin_throw): Use it to make sure a rethrow without an
|
||||
exception object is caught.
|
||||
|
||||
Thu May 2 11:26:41 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (maybe_push_to_top_level): Clear out class-level bindings
|
||||
cache.
|
||||
|
||||
Wed May 1 11:26:52 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl2.c (finish_file): Also use sentries for vars with
|
||||
|
@ -2540,18 +2540,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
||||
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)));
|
||||
|
||||
{
|
||||
int is_constructor;
|
||||
|
||||
if (TREE_CODE (function) == FUNCTION_DECL)
|
||||
{
|
||||
is_constructor = DECL_CONSTRUCTOR_P (function);
|
||||
function = default_conversion (function);
|
||||
}
|
||||
else
|
||||
{
|
||||
is_constructor = 0;
|
||||
function = default_conversion (function);
|
||||
}
|
||||
int is_constructor
|
||||
= TREE_CODE (function) == FUNCTION_DECL
|
||||
&& DECL_CONSTRUCTOR_P (function);
|
||||
|
||||
function = default_conversion (function);
|
||||
|
||||
result = build_nt (CALL_EXPR, function, parms, NULL_TREE);
|
||||
|
||||
|
@ -1747,9 +1747,9 @@ struct saved_scope {
|
||||
int minimal_parse_mode;
|
||||
tree last_function_parms;
|
||||
tree template_parms;
|
||||
tree previous_class_type, previous_class_values;
|
||||
};
|
||||
static struct saved_scope *current_saved_scope;
|
||||
extern tree prev_class_type;
|
||||
|
||||
tree
|
||||
store_bindings (names, old_bindings)
|
||||
@ -1803,6 +1803,9 @@ maybe_push_to_top_level (pseudo)
|
||||
struct binding_level *b = inner_binding_level;
|
||||
tree old_bindings = NULL_TREE;
|
||||
|
||||
if (previous_class_type)
|
||||
old_bindings = store_bindings (previous_class_values, old_bindings);
|
||||
|
||||
/* Have to include global_binding_level, because class-level decls
|
||||
aren't listed anywhere useful. */
|
||||
for (; b; b = b->level_chain)
|
||||
@ -1840,6 +1843,8 @@ maybe_push_to_top_level (pseudo)
|
||||
s->minimal_parse_mode = minimal_parse_mode;
|
||||
s->last_function_parms = last_function_parms;
|
||||
s->template_parms = current_template_parms;
|
||||
s->previous_class_type = previous_class_type;
|
||||
s->previous_class_values = previous_class_values;
|
||||
current_class_name = current_class_type = NULL_TREE;
|
||||
current_function_decl = NULL_TREE;
|
||||
class_binding_level = (struct binding_level *)0;
|
||||
@ -1850,6 +1855,7 @@ maybe_push_to_top_level (pseudo)
|
||||
strict_prototype = strict_prototypes_lang_cplusplus;
|
||||
named_labels = NULL_TREE;
|
||||
minimal_parse_mode = 0;
|
||||
previous_class_type = previous_class_values = NULL_TREE;
|
||||
if (!pseudo)
|
||||
current_template_parms = NULL_TREE;
|
||||
|
||||
@ -1913,6 +1919,8 @@ pop_from_top_level ()
|
||||
minimal_parse_mode = s->minimal_parse_mode;
|
||||
last_function_parms = s->last_function_parms;
|
||||
current_template_parms = s->template_parms;
|
||||
previous_class_type = s->previous_class_type;
|
||||
previous_class_values = s->previous_class_values;
|
||||
|
||||
free (s);
|
||||
}
|
||||
@ -5839,12 +5847,10 @@ start_decl (declarator, declspecs, initialized, raises)
|
||||
|
||||
#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
|
||||
/* Tell the back-end to use or not use .common as appropriate. If we say
|
||||
-fconserve-space, we want this to save space, at the expense of wrong
|
||||
semantics. If we say -fno-conserve-space, we want this to produce
|
||||
errors about redefs; to do this we force variables into the data
|
||||
segment. Common storage is okay for non-public uninitialized data;
|
||||
the linker can't match it with storage from other files, and we may
|
||||
save some disk space. */
|
||||
-fconserve-space, we want this to save .data space, at the expense of
|
||||
wrong semantics. If we say -fno-conserve-space, we want this to
|
||||
produce errors about redefs; to do this we force variables into the
|
||||
data segment. */
|
||||
DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
|
||||
#endif
|
||||
|
||||
|
@ -2591,7 +2591,9 @@ finish_vtable_vardecl (prev, vars)
|
||||
tree prev, vars;
|
||||
{
|
||||
if (write_virtuals >= 0
|
||||
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))
|
||||
&& ! DECL_EXTERNAL (vars)
|
||||
&& ((TREE_PUBLIC (vars) && ! DECL_WEAK (vars) && ! DECL_ONE_ONLY (vars))
|
||||
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)))
|
||||
&& ! TREE_ASM_WRITTEN (vars))
|
||||
{
|
||||
/* Write it out. */
|
||||
@ -2630,7 +2632,7 @@ finish_vtable_vardecl (prev, vars)
|
||||
rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
else if (! TREE_USED (vars))
|
||||
else if (! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)))
|
||||
/* We don't know what to do with this one yet. */
|
||||
return 0;
|
||||
|
||||
@ -3233,30 +3235,17 @@ finish_file ()
|
||||
reconsider = 1;
|
||||
}
|
||||
|
||||
/* Catch new template instantiations. */
|
||||
if (decl != TREE_VALUE (*p))
|
||||
;
|
||||
else if (TREE_ASM_WRITTEN (decl)
|
||||
|| (DECL_SAVED_INSNS (decl) == 0
|
||||
&& ! DECL_ARTIFICIAL (decl)))
|
||||
continue;
|
||||
|
||||
if (TREE_ASM_WRITTEN (decl)
|
||||
|| (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl)))
|
||||
*p = TREE_CHAIN (*p);
|
||||
else
|
||||
else if (DECL_INITIAL (decl) == 0)
|
||||
p = &TREE_CHAIN (*p);
|
||||
}
|
||||
}
|
||||
|
||||
reconsider = 1; /* More may be referenced; check again */
|
||||
while (reconsider)
|
||||
{
|
||||
tree *p = &saved_inlines;
|
||||
reconsider = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
tree decl = TREE_VALUE (*p);
|
||||
|
||||
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
|
||||
*p = TREE_CHAIN (*p);
|
||||
else if ((TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
|
||||
else if ((TREE_PUBLIC (decl) && ! DECL_WEAK (decl)
|
||||
&& ! DECL_ONE_ONLY (decl))
|
||||
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|
||||
|| flag_keep_inline_functions)
|
||||
{
|
||||
@ -3264,6 +3253,11 @@ finish_file ()
|
||||
{
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
reconsider = 1;
|
||||
/* We can't inline this function after it's been
|
||||
emitted, so just disable inlining. We want a
|
||||
variant of output_inline_function that doesn't
|
||||
prevent subsequent integration... */
|
||||
flag_no_inline = 1;
|
||||
temporary_allocation ();
|
||||
output_inline_function (decl);
|
||||
permanent_allocation (1);
|
||||
|
@ -326,6 +326,8 @@ static tree saved_throw_type;
|
||||
static tree saved_throw_value;
|
||||
/* Holds the cleanup for the value being thrown. */
|
||||
static tree saved_cleanup;
|
||||
/* Indicates if we are in a catch clause. */
|
||||
static tree saved_in_catch;
|
||||
|
||||
static int throw_used;
|
||||
|
||||
@ -754,6 +756,13 @@ init_exception_processing ()
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_cleanup = lookup_name (get_identifier ("__eh_cleanup"), 0);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, get_identifier ("bool"), NULL_TREE);
|
||||
d = get_identifier ("__eh_in_catch");
|
||||
d = start_decl (d, declspecs, 0, NULL_TREE);
|
||||
DECL_COMMON (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
|
||||
saved_in_catch = lookup_name (get_identifier ("__eh_in_catch"), 0);
|
||||
}
|
||||
|
||||
/* call this to begin a block of unwind protection (ie: when an object is
|
||||
@ -950,6 +959,9 @@ push_eh_cleanup ()
|
||||
|
||||
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
|
||||
tree cleanup = build_function_call (saved_cleanup, NULL_TREE);
|
||||
cleanup = build (COMPOUND_EXPR, void_type_node, cleanup,
|
||||
build_modify_expr (saved_in_catch, NOP_EXPR,
|
||||
build_modify_expr (saved_throw_type, NOP_EXPR, integer_zero_node)));
|
||||
cp_expand_decl_cleanup (NULL_TREE, cleanup);
|
||||
|
||||
resume_momentary (yes);
|
||||
@ -1045,6 +1057,7 @@ expand_start_catch_block (declspecs, declarator)
|
||||
/* Fall into the catch all section. */
|
||||
}
|
||||
|
||||
emit_move_insn (DECL_RTL (saved_in_catch), const1_rtx);
|
||||
/* This is the starting of something to protect. */
|
||||
emit_label (protect_label_rtx);
|
||||
|
||||
@ -1327,6 +1340,13 @@ expand_builtin_throw ()
|
||||
top_of_loop = gen_label_rtx ();
|
||||
unwind_first = gen_label_rtx ();
|
||||
|
||||
/* These two can be frontend specific. If wanted, they can go in
|
||||
expand_throw. */
|
||||
/* Do we have a valid object we are throwing? */
|
||||
emit_cmp_insn (DECL_RTL (saved_throw_type), const0_rtx, EQ, NULL_RTX,
|
||||
GET_MODE (DECL_RTL (saved_throw_type)), 0, 0);
|
||||
emit_jump_insn (gen_beq (gotta_call_terminate));
|
||||
|
||||
emit_jump (unwind_first);
|
||||
|
||||
emit_label (top_of_loop);
|
||||
@ -1678,6 +1698,7 @@ expand_throw (exp)
|
||||
{
|
||||
rtx cleanup_insns;
|
||||
tree object;
|
||||
|
||||
/* Make a copy of the thrown object. WP 15.1.5 */
|
||||
exp = build_new (NULL_TREE, TREE_TYPE (exp),
|
||||
build_tree_list (NULL_TREE, exp),
|
||||
|
@ -1219,15 +1219,18 @@ All completely constructed temps and local variables are cleaned up in
|
||||
all unwinded scopes. Completely constructed parts of partially
|
||||
constructed objects are cleaned up. This includes partially built
|
||||
arrays. Exception specifications are now handled. Thrown objects are
|
||||
now cleaned up all the time.
|
||||
now cleaned up all the time. We can now tell if we have an active
|
||||
exception being thrown or not (__eh_type != 0). We use this to call
|
||||
terminate if someone does a throw; without there being an active
|
||||
exception object. uncaught_exception () works.
|
||||
|
||||
The below points out some flaws in g++'s exception handling, as it now
|
||||
stands.
|
||||
|
||||
Only exact type matching or reference matching of throw types works when
|
||||
-fno-rtti is used. Only works on a SPARC (like Suns), i386, arm,
|
||||
rs6000, PowerPC, Alpha, mips, VAX, m68k and z8k machines. Partial support
|
||||
is in for all other machines, but a stack unwinder called
|
||||
-fno-rtti is used. Only works on a SPARC (like Suns), SPARClite, i386,
|
||||
arm, rs6000, PowerPC, Alpha, mips, VAX, m68k and z8k machines. Partial
|
||||
support is in for all other machines, but a stack unwinder called
|
||||
__unwind_function has to be written, and added to libgcc2 for them. The
|
||||
new EH code doesn't rely upon the __unwind_function for C++ code,
|
||||
instead it creates per function unwinders right inside the function,
|
||||
|
Loading…
Reference in New Issue
Block a user