This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for GC
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH for GC
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 07 Sep 1999 09:19:24 -0700
- Cc: Alexander Samuel <samuel at codesourcery dot com>
- Organization: CodeSourcery, LLC
This patch does everything except actually set ggc_p to 1. When doing
that, all tests continue to pass on my i686-pc-linux-gnu box. We'll
flip the switch as soon as the other back-ends are marking their
garbage; hopefully in the next day or so.
In the meantime, this patch makes us a little leaky. It does not,
however, begin to tap the real benefits of GC, whereby
copy_to_permanent and lots of other obstack goo go away.
Alex is working on the new, faster collector, based on `mmap' and
a big-bag-of-pages. That will be ready in the next few days.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-09-07 Mark Mitchell <mark@codesourcery.com>
* Makefile.in (tree.o): Depend on ggc.h.
* class.c (make_method_vec): Remove.
(free_method_vec): Likewise.
(free_method_vecs): Remove.
(add_method): Don't use them.
* cp-tree.def (PTRMEM_CST): Make it longer.
(TEMPLATE_PARM_INDEX): Make it shorter.
* cp-tree.h (BINDING_HAS_LEVEL_P): New macro.
(template_parm_index): Remove RTL field.
(ptrmem_cst): Add RTL field.
(finish_function): Removed parameter.
(process_next_inline): Change prototype.
(init_cplus_unsave): Rename to init_tree.
(binding_init): Remove.
* decl.c (free_binding_nodes): Remove.
(push_binding): Don't use them. Set BINDING_HAS_LEVEL_P.
(pop_binding): Don't use free_binding_nodes.
(free_binding_vecs): Remove.
(store_bindings): Don't use them.
(pop_from_top_level): Likewise.
(lookup_namespace_name): Simplify.
(build_typename_type): Don't use obstack_free.
(unqualified_namespace_lookup): Simplify.
(lookup_name_real): Simplify.
(start_function): Remove comment about leaks.
(finish_function): Removed nested parameter. Call
expand_end_bindings even when building_stmt_tree.
Call ggc_push_context and ggc_pop_context around
rest_of_compilation, if necessary.
(mark_cp_function_context): Handle a NULL language-context.
(lang_mark_false_label_stack): Fix typo.
(lang_mark_tree): Handle CPLUS_BINDING, OVERLOAD,
TEMPLATE_PARM_INDEX. Handle the funny TYPE_LANG_SPECIFIC on
pointer to method types.
(lang_cleanup_tree): Use free to free TYPE_LANG_SPECIFIC.
* decl2.c (finish_objects): Adjust call to finish_function.
(finish_static_store_duration_function): Likewise.
(do_nonmember_using_decl): Remove call to binding_init.
* except.c (end_anon_func): Adjust call to finish_function.
* lex.c (mark_impl_file_chain): New function.
(init_parse): Call init_tree, not init_cplus_unsave.
Add GC roots.
(cp_pramga_interface): Use xmalloc, not permalloc.
(cp_pragma_implementation): Likewise.
(begin_definition_of_inclass_inline): Simplify.
(process_next_inline): Adjust prototype.
(do_scoped_id): Don't call binding_init.
(make_lang_type): Allocate TYPE_LANG_SPECIFIC with xmalloc.
(emit_thunk): Adjust call to finish_function.
(synthesize_method): Likewise.
* parse.y (%union): Add a new `pi' variant.
(PRE_PARSED_FUNCTION_DECL): Use it.
(fn.defpen): Likewise.
(fndef): Adjust call to finish_function.
(instantiate_decl): Likewise.
(rtti.c): Likewise.
(semantics.c): Likewise.
* tree.c: Include ggc.h.
(mark_list_hash): New function.
(binding_init): Remove.
(init_cplus_unsave): Rename to ...
(init_tree): This. Add GC roots.
Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/Makefile.in,v
retrieving revision 1.65
diff -c -p -r1.65 Makefile.in
*** Makefile.in 1999/09/06 02:43:05 1.65
--- Makefile.in 1999/09/07 07:59:17
*************** cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H)
*** 271,277 ****
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
$(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
! $(srcdir)/../system.h $(srcdir)/../toplev.h
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
--- 271,277 ----
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
$(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
! $(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.182
diff -c -p -r1.182 class.c
*** class.c 1999/09/06 02:43:05 1.182
--- class.c 1999/09/07 07:59:22
*************** static void finish_struct_methods PROTO(
*** 115,122 ****
static void maybe_warn_about_overly_private_class PROTO ((tree));
static int field_decl_cmp PROTO ((const tree *, const tree *));
static int method_name_cmp PROTO ((const tree *, const tree *));
- static tree make_method_vec PROTO((int));
- static void free_method_vec PROTO((tree));
static tree add_implicitly_declared_members PROTO((tree, int, int, int));
static tree fixed_type_or_null PROTO((tree, int *));
static tree resolve_address_of_overloaded_function PROTO((tree, tree, int,
--- 115,120 ----
*************** add_virtual_function (pv, phv, has_virtu
*** 1066,1111 ****
struct obstack class_obstack;
extern struct obstack *current_obstack;
- /* These are method vectors that were too small for the number of
- methods in some class, and so were abandoned. */
- static tree free_method_vecs;
-
- /* Returns a method vector with enough room for N methods. N should
- be a power of two. */
-
- static tree
- make_method_vec (n)
- int n;
- {
- tree new_vec;
- tree* t;
-
- for (t = &free_method_vecs; *t; t = &(TREE_CHAIN (*t)))
- /* Note that we don't use >= n here because we don't want to
- allocate a very large vector where it isn't needed. */
- if (TREE_VEC_LENGTH (*t) == n)
- {
- new_vec = *t;
- *t = TREE_CHAIN (new_vec);
- TREE_CHAIN (new_vec) = NULL_TREE;
- bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree));
- return new_vec;
- }
-
- new_vec = make_tree_vec (n);
- return new_vec;
- }
-
- /* Free the method vector VEC. */
-
- static void
- free_method_vec (vec)
- tree vec;
- {
- TREE_CHAIN (vec) = free_method_vecs;
- free_method_vecs = vec;
- }
-
/* Add method METHOD to class TYPE.
If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of
--- 1064,1069 ----
*************** add_method (type, fields, method)
*** 1141,1149 ****
memory making the links in the list than we would by
over-allocating the size of the vector here. Furthermore,
we would complicate all the code that expects this to be a
! vector. We keep a free list of vectors that we outgrew so
! that we don't really waste any memory. */
! CLASSTYPE_METHOD_VEC (type) = make_method_vec (8);
method_vec = CLASSTYPE_METHOD_VEC (type);
len = TREE_VEC_LENGTH (method_vec);
--- 1099,1106 ----
memory making the links in the list than we would by
over-allocating the size of the vector here. Furthermore,
we would complicate all the code that expects this to be a
! vector. */
! CLASSTYPE_METHOD_VEC (type) = make_tree_vec (8);
method_vec = CLASSTYPE_METHOD_VEC (type);
len = TREE_VEC_LENGTH (method_vec);
*************** add_method (type, fields, method)
*** 1165,1175 ****
if (slot == len)
{
/* We need a bigger method vector. */
! tree new_vec = make_method_vec (2 * len);
bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0),
(PTR) &TREE_VEC_ELT (new_vec, 0),
len * sizeof (tree));
- free_method_vec (method_vec);
len = 2 * len;
method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
}
--- 1122,1131 ----
if (slot == len)
{
/* We need a bigger method vector. */
! tree new_vec = make_tree_vec (2 * len);
bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0),
(PTR) &TREE_VEC_ELT (new_vec, 0),
len * sizeof (tree));
len = 2 * len;
method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
}
Index: cp-tree.def
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.def,v
retrieving revision 1.34
diff -c -p -r1.34 cp-tree.def
*** cp-tree.def 1999/08/28 21:45:27 1.34
--- cp-tree.def 1999/09/07 07:59:23
*************** DEFTREECODE (OFFSET_REF, "offset_ref", '
*** 32,38 ****
/* A pointer-to-member constant. For a pointer-to-member constant
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
! DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 1)
/* For NEW_EXPR, operand 0 is the placement list.
Operand 1 is the new-declarator.
--- 32,38 ----
/* A pointer-to-member constant. For a pointer-to-member constant
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
! DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 2)
/* For NEW_EXPR, operand 0 is the placement list.
Operand 1 is the new-declarator.
*************** DEFTREECODE (TEMPLATE_PARM_INDEX, "templ
*** 130,136 ****
expression is to ensure against the case where
sizeof(char*) does not evenly divide
sizeof(HOST_WIDE_INT). */
! 2 + ((3 * sizeof (HOST_WIDE_INT) + sizeof(char*) - 1)
/ sizeof (char*)))
/* Index into a template parameter list. This parameter must be a type.
--- 130,136 ----
expression is to ensure against the case where
sizeof(char*) does not evenly divide
sizeof(HOST_WIDE_INT). */
! 1 + ((3 * sizeof (HOST_WIDE_INT) + sizeof(char*) - 1)
/ sizeof (char*)))
/* Index into a template parameter list. This parameter must be a type.
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.286
diff -c -p -r1.286 cp-tree.h
*** cp-tree.h 1999/09/06 02:43:05 1.286
--- cp-tree.h 1999/09/07 07:59:26
*************** Boston, MA 02111-1307, USA. */
*** 54,59 ****
--- 54,60 ----
BINFO_FIELDS_MARKED.
TYPE_VIRTUAL_P.
ICS_THIS_FLAG (in _CONV)
+ BINDING_HAS_LEVEL_P (In CPLUS_BINDING)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
*************** typedef struct
*** 139,146 ****
typedef struct
{
char common[sizeof (struct tree_common)];
- struct rtx_def *rtl; /* Unused, but required to match up with what
- the middle-end expects. */
HOST_WIDE_INT index;
HOST_WIDE_INT level;
HOST_WIDE_INT orig_level;
--- 140,145 ----
*************** typedef struct
*** 150,155 ****
--- 149,157 ----
typedef struct ptrmem_cst
{
char common[sizeof (struct tree_common)];
+ /* This isn't used, but the middle-end expects all constants to have
+ this field. */
+ struct rtx_def *rtl;
tree member;
}* ptrmem_cst_t;
*************** typedef struct ptrmem_cst
*** 168,173 ****
--- 170,178 ----
BINDING_LEVEL is used instead. */
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope.scope)
+ /* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */
+ #define BINDING_HAS_LEVEL_P(NODE) TREE_LANG_FLAG_2 ((NODE))
+
/* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
*************** extern int start_function PROTO((tree,
*** 3174,3180 ****
extern void expand_start_early_try_stmts PROTO((void));
extern void store_parm_decls PROTO((void));
extern void store_return_init PROTO((tree));
! extern void finish_function PROTO((int, int, int));
extern tree start_method PROTO((tree, tree, tree));
extern tree finish_method PROTO((tree));
extern void hack_incomplete_structures PROTO((tree));
--- 3179,3185 ----
extern void expand_start_early_try_stmts PROTO((void));
extern void store_parm_decls PROTO((void));
extern void store_return_init PROTO((tree));
! extern void finish_function PROTO((int, int));
extern tree start_method PROTO((tree, tree, tree));
extern tree finish_method PROTO((tree));
extern void hack_incomplete_structures PROTO((tree));
*************** extern void reinit_parse_for_function P
*** 3376,3382 ****
extern void print_parse_statistics PROTO((void));
extern void extract_interface_info PROTO((void));
extern void do_pending_inlines PROTO((void));
! extern void process_next_inline PROTO((tree));
extern struct pending_input *save_pending_input PROTO((void));
extern void restore_pending_input PROTO((struct pending_input *));
extern void yyungetc PROTO((int, int));
--- 3381,3387 ----
extern void print_parse_statistics PROTO((void));
extern void extract_interface_info PROTO((void));
extern void do_pending_inlines PROTO((void));
! extern void process_next_inline PROTO((struct pending_inline *));
extern struct pending_input *save_pending_input PROTO((void));
extern void restore_pending_input PROTO((struct pending_input *));
extern void yyungetc PROTO((int, int));
*************** extern int yylex PROTO((void));
*** 3640,3646 ****
extern tree arbitrate_lookup PROTO((tree, tree, tree));
/* in tree.c */
! extern void init_cplus_unsave PROTO((void));
extern void cplus_unsave_expr_now PROTO((tree));
extern int pod_type_p PROTO((tree));
extern void unshare_base_binfos PROTO((tree));
--- 3645,3651 ----
extern tree arbitrate_lookup PROTO((tree, tree, tree));
/* in tree.c */
! extern void init_tree PROTO((void));
extern void cplus_unsave_expr_now PROTO((tree));
extern int pod_type_p PROTO((tree));
extern void unshare_base_binfos PROTO((tree));
*************** extern tree reverse_path PROTO((tree))
*** 3670,3676 ****
extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree));
extern tree get_first_fn PROTO((tree));
- extern tree binding_init PROTO((struct tree_binding*));
extern int bound_pmf_p PROTO((tree));
extern tree ovl_cons PROTO((tree, tree));
extern tree scratch_ovl_cons PROTO((tree, tree));
--- 3675,3680 ----
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.429
diff -c -p -r1.429 decl.c
*** decl.c 1999/09/06 02:43:06 1.429
--- decl.c 1999/09/07 07:59:36
*************** extern tree global_namespace;
*** 59,67 ****
extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree));
! /* Don't use garbage collection. */
! int ggc_p = 0;
/* Obstack used for remembering local class declarations (like
enums and static (const) members. */
--- 59,67 ----
extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree));
! /* Use garbage collection. */
! int ggc_p = 1;
/* Obstack used for remembering local class declarations (like
enums and static (const) members. */
*************** pushlevel_temporary (tag_transparent)
*** 946,956 ****
#define BINDING_LEVEL(NODE) \
(((struct tree_binding*)NODE)->scope.level)
- /* These are currently unused, but permanent, CPLUS_BINDING nodes.
- They are kept here because they are allocated from the permanent
- obstack and cannot be easily freed. */
- static tree free_binding_nodes;
-
/* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */
--- 946,951 ----
*************** push_binding (id, decl, level)
*** 962,982 ****
{
tree binding;
! if (!free_binding_nodes)
! {
! /* There are no free nodes, so we must build one here. */
! push_permanent_obstack ();
! binding = make_node (CPLUS_BINDING);
! pop_obstacks ();
! }
! else
! {
! /* There are nodes on the free list. Grab the first one. */
! binding = free_binding_nodes;
!
! /* And update the free list. */
! free_binding_nodes = TREE_CHAIN (free_binding_nodes);
! }
/* Now, fill in the binding information. */
BINDING_VALUE (binding) = decl;
--- 957,963 ----
{
tree binding;
! binding = make_node (CPLUS_BINDING);
/* Now, fill in the binding information. */
BINDING_VALUE (binding) = decl;
*************** push_binding (id, decl, level)
*** 984,989 ****
--- 965,971 ----
BINDING_LEVEL (binding) = level;
INHERITED_VALUE_BINDING_P (binding) = 0;
LOCAL_BINDING_P (binding) = (level != class_binding_level);
+ BINDING_HAS_LEVEL_P (binding) = 1;
/* And put it on the front of the list of bindings for ID. */
TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);
*************** pop_binding (id, decl)
*** 1210,1224 ****
my_friendly_abort (0);
if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
! {
! /* We're completely done with the innermost binding for this
! identifier. Unhook it from the list of bindings. */
! IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
!
! /* And place it on the free list. */
! TREE_CHAIN (binding) = free_binding_nodes;
! free_binding_nodes = binding;
! }
}
/* When a label goes out of scope, check to see if that label was used
--- 1192,1200 ----
my_friendly_abort (0);
if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
! /* We're completely done with the innermost binding for this
! identifier. Unhook it from the list of bindings. */
! IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
}
/* When a label goes out of scope, check to see if that label was used
*************** mark_saved_scope (arg)
*** 2424,2434 ****
}
}
- /* A chain of the binding vecs created by store_bindings. We create a
- whole bunch of these during compilation, on permanent_obstack, so we
- can't just throw them away. */
- static tree free_binding_vecs;
-
static tree
store_bindings (names, old_bindings)
tree names, old_bindings;
--- 2400,2405 ----
*************** store_bindings (names, old_bindings)
*** 2454,2466 ****
if (TREE_VEC_ELT (t1, 0) == id)
goto skip_it;
! if (free_binding_vecs)
! {
! binding = free_binding_vecs;
! free_binding_vecs = TREE_CHAIN (free_binding_vecs);
! }
! else
! binding = make_tree_vec (4);
if (id)
{
--- 2425,2431 ----
if (TREE_VEC_ELT (t1, 0) == id)
goto skip_it;
! binding = make_tree_vec (4);
if (id)
{
*************** pop_from_top_level ()
*** 2567,2575 ****
VARRAY_FREE (current_lang_base);
scope_chain = s->prev;
! for (t = s->old_bindings; t; )
{
- tree save = t;
tree id = TREE_VEC_ELT (t, 0);
if (id)
{
--- 2532,2539 ----
VARRAY_FREE (current_lang_base);
scope_chain = s->prev;
! for (t = s->old_bindings; t; t = TREE_CHAIN (t))
{
tree id = TREE_VEC_ELT (t, 0);
if (id)
{
*************** pop_from_top_level ()
*** 2577,2585 ****
IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
}
- t = TREE_CHAIN (t);
- TREE_CHAIN (save) = free_binding_vecs;
- free_binding_vecs = save;
}
if (current_lang_name == lang_name_cplusplus)
--- 2541,2546 ----
*************** tree
*** 5262,5268 ****
lookup_namespace_name (namespace, name)
tree namespace, name;
{
- struct tree_binding _b;
tree val;
tree template_id = NULL_TREE;
--- 5223,5228 ----
*************** lookup_namespace_name (namespace, name)
*** 5293,5299 ****
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
! val = binding_init (&_b);
if (!qualified_lookup_using_namespace (name, namespace, val, 0))
return error_mark_node;
--- 5253,5259 ----
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
! val = make_node (CPLUS_BINDING);
if (!qualified_lookup_using_namespace (name, namespace, val, 0))
return error_mark_node;
*************** build_typename_type (context, name, full
*** 5425,5436 ****
/* See if we already have this type. */
e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0);
if (e)
! {
! /* This will free not only TREE_TYPE, but the lang-specific data
! and the TYPE_DECL as well. */
! obstack_free (&permanent_obstack, t);
! t = (tree) e->key;
! }
else
/* Insert the type into the table. */
hash_lookup (&ht, t, /*create=*/true, /*copy=*/0);
--- 5385,5391 ----
/* See if we already have this type. */
e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0);
if (e)
! t = (tree) e->key;
else
/* Insert the type into the table. */
hash_lookup (&ht, t, /*create=*/true, /*copy=*/0);
*************** unqualified_namespace_lookup (name, flag
*** 5571,5578 ****
int flags;
tree *spacesp;
{
! struct tree_binding _binding;
! tree b = binding_init (&_binding);
tree initial = current_decl_namespace();
tree scope = initial;
tree siter;
--- 5526,5532 ----
int flags;
tree *spacesp;
{
! tree b = make_node (CPLUS_BINDING);
tree initial = current_decl_namespace();
tree scope = initial;
tree siter;
*************** lookup_name_real (name, prefer_type, non
*** 5750,5757 ****
type = global_namespace;
if (TREE_CODE (type) == NAMESPACE_DECL)
{
! struct tree_binding b;
! val = binding_init (&b);
flags |= LOOKUP_COMPLAIN;
if (!qualified_lookup_using_namespace (name, type, val, flags))
return NULL_TREE;
--- 5704,5710 ----
type = global_namespace;
if (TREE_CODE (type) == NAMESPACE_DECL)
{
! val = make_node (CPLUS_BINDING);
flags |= LOOKUP_COMPLAIN;
if (!qualified_lookup_using_namespace (name, type, val, flags))
return NULL_TREE;
*************** static int function_depth;
*** 12930,12941 ****
For C++, we must first check whether that datum makes any sense.
For example, "class A local_a(1,2);" means that variable local_a
is an aggregate of type A, which should have a constructor
! applied to it with the argument list [1, 2].
- @@ There is currently no way to retrieve the storage
- @@ allocated to FUNCTION (or all of its parms) if we return
- @@ something we had previously. */
-
int
start_function (declspecs, declarator, attrs, pre_parsed_p)
tree declspecs, declarator, attrs;
--- 12883,12890 ----
For C++, we must first check whether that datum makes any sense.
For example, "class A local_a(1,2);" means that variable local_a
is an aggregate of type A, which should have a constructor
! applied to it with the argument list [1, 2]. */
int
start_function (declspecs, declarator, attrs, pre_parsed_p)
tree declspecs, declarator, attrs;
*************** store_return_init (decl)
*** 13550,13565 ****
2 - INCLASS_INLINE
We just finished processing the body of an in-class inline
function definition. (This processing will have taken place
! after the class definition is complete.)
!
! NESTED is nonzero if we were in the middle of compiling another function
! when we started on this one. */
void
! finish_function (lineno, flags, nested)
int lineno;
int flags;
- int nested;
{
register tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
--- 13499,13510 ----
2 - INCLASS_INLINE
We just finished processing the body of an in-class inline
function definition. (This processing will have taken place
! after the class definition is complete.) */
void
! finish_function (lineno, flags)
int lineno;
int flags;
{
register tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
*************** finish_function (lineno, flags, nested)
*** 13570,13584 ****
int call_poplevel = (flags & 1) != 0;
int inclass_inline = (flags & 2) != 0;
int expand_p;
/* When we get some parse errors, we can end up without a
current_function_decl, so cope. */
if (fndecl == NULL_TREE)
return;
! if (function_depth > 1)
! nested = 1;
!
fntype = TREE_TYPE (fndecl);
/* TREE_READONLY (fndecl) = 1;
--- 13515,13528 ----
int call_poplevel = (flags & 1) != 0;
int inclass_inline = (flags & 2) != 0;
int expand_p;
+ int nested;
/* When we get some parse errors, we can end up without a
current_function_decl, so cope. */
if (fndecl == NULL_TREE)
return;
! nested = function_depth > 1;
fntype = TREE_TYPE (fndecl);
/* TREE_READONLY (fndecl) = 1;
*************** finish_function (lineno, flags, nested)
*** 13600,13605 ****
--- 13544,13558 ----
expand_end_bindings (decls, decls != NULL_TREE, 0);
poplevel (decls != NULL_TREE, 0, 0);
}
+
+ /* Because we do not call expand_function_end, we won't call
+ expand_end_bindings to match the call to
+ expand_start_bindings we did in store_parm_decls. Therefore,
+ we explicitly call expand_end_bindings here. However, we
+ really shouldn't be calling expand_start_bindings at all when
+ building_stmt_tree; it's conceptually an RTL-generation
+ function, rather than a front-end function. */
+ expand_end_bindings (0, 0, 0);
}
else
{
*************** finish_function (lineno, flags, nested)
*** 14041,14049 ****
function is gone. See save_tree_status. */
flag_keep_inline_functions = 1;
/* Run the optimizers and output the assembler code for this
function. */
-
if (DECL_ARTIFICIAL (fndecl))
{
/* Do we really *want* to inline this synthesized method? */
--- 13994,14009 ----
function is gone. See save_tree_status. */
flag_keep_inline_functions = 1;
+ /* If this is a nested function (like a template instantiation
+ that we're compiling in the midst of compiling something
+ else), push a new GC context. That will keep local variables
+ on the stack from being collected while we're doing the
+ compilation of this function. */
+ if (function_depth > 1)
+ ggc_push_context ();
+
/* Run the optimizers and output the assembler code for this
function. */
if (DECL_ARTIFICIAL (fndecl))
{
/* Do we really *want* to inline this synthesized method? */
*************** finish_function (lineno, flags, nested)
*** 14061,14066 ****
--- 14021,14030 ----
else
rest_of_compilation (fndecl);
+ /* Undo the call to ggc_push_context above. */
+ if (function_depth > 1)
+ ggc_pop_context ();
+
flag_keep_inline_functions = saved_flag_keep_inline_functions;
if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
*************** mark_cp_function_context (f)
*** 14557,14562 ****
--- 14521,14529 ----
{
struct language_function *p = f->language;
+ if (!p)
+ return;
+
ggc_mark_tree (p->x_named_labels);
ggc_mark_tree (p->x_ctor_label);
ggc_mark_tree (p->x_dtor_label);
*************** lang_mark_false_label_stack (l)
*** 14588,14594 ****
struct label_node *l;
{
/* C++ doesn't use false_label_stack. It better be NULL. */
! my_friendly_assert (l != NULL, 19990904);
}
void
--- 14555,14561 ----
struct label_node *l;
{
/* C++ doesn't use false_label_stack. It better be NULL. */
! my_friendly_assert (l == NULL, 19990904);
}
void
*************** lang_mark_tree (t)
*** 14611,14616 ****
--- 14578,14595 ----
ggc_mark_tree (li2->error_locus);
}
}
+ else if (code == CPLUS_BINDING)
+ {
+ if (BINDING_HAS_LEVEL_P (t))
+ mark_binding_level (&BINDING_LEVEL (t));
+ else
+ ggc_mark_tree (BINDING_SCOPE (t));
+ ggc_mark_tree (BINDING_VALUE (t));
+ }
+ else if (code == OVERLOAD)
+ ggc_mark_tree (OVL_FUNCTION (t));
+ else if (code == TEMPLATE_PARM_INDEX)
+ ggc_mark_tree (TEMPLATE_PARM_DECL (t));
else if (TREE_CODE_CLASS (code) == 'd')
{
struct lang_decl *ld = DECL_LANG_SPECIFIC (t);
*************** lang_mark_tree (t)
*** 14635,14641 ****
{
struct lang_type *lt = TYPE_LANG_SPECIFIC (t);
! if (lt)
{
ggc_mark_tree (lt->vfields);
ggc_mark_tree (lt->vbases);
--- 14614,14621 ----
{
struct lang_type *lt = TYPE_LANG_SPECIFIC (t);
! if (lt && !(TREE_CODE (t) == POINTER_TYPE
! && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))
{
ggc_mark_tree (lt->vfields);
ggc_mark_tree (lt->vbases);
*************** lang_mark_tree (t)
*** 14647,14653 ****
--- 14627,14638 ----
ggc_mark_tree (lt->rtti);
ggc_mark_tree (lt->methods);
ggc_mark_tree (lt->template_info);
+ ggc_mark_tree (lt->befriending_classes);
}
+ else if (lt)
+ /* In the case of pointer-to-member function types, the
+ TYPE_LANG_SPECIFIC is really just a tree. */
+ ggc_mark_tree ((tree) lt);
}
}
*************** lang_cleanup_tree (t)
*** 14656,14666 ****
tree t;
{
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't'
! && TYPE_LANG_SPECIFIC (t) != NULL)
! {
! #if 0
! /* This is currently allocated with an obstack. This will change. */
! free (TYPE_LANG_SPECIFIC (t));
! #endif
! }
}
--- 14641,14648 ----
tree t;
{
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't'
! && TYPE_LANG_SPECIFIC (t) != NULL
! && !(TREE_CODE (t) == POINTER_TYPE
! && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))
! free (TYPE_LANG_SPECIFIC (t));
}
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.251
diff -c -p -r1.251 decl2.c
*** decl2.c 1999/09/06 02:43:07 1.251
--- decl2.c 1999/09/07 07:59:39
*************** finish_objects (method_type, initp)
*** 2860,2866 ****
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0, 0);
if (initp == DEFAULT_INIT_PRIORITY)
{
--- 2860,2866 ----
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0);
if (initp == DEFAULT_INIT_PRIORITY)
{
*************** finish_static_storage_duration_function
*** 3111,3117 ****
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0, 0);
}
/* Return the information about the indicated PRIORITY level. If no
--- 3111,3117 ----
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0);
}
/* Return the information about the indicated PRIORITY level. If no
*************** do_nonmember_using_decl (scope, name, ol
*** 4950,4959 ****
tree *newval, *newtype;
{
tree decls;
- struct tree_binding _decls;
*newval = *newtype = NULL_TREE;
! decls = binding_init (&_decls);
if (!qualified_lookup_using_namespace (name, scope, decls, 0))
/* Lookup error */
return;
--- 4950,4958 ----
tree *newval, *newtype;
{
tree decls;
*newval = *newtype = NULL_TREE;
! decls = make_node (CPLUS_BINDING);
if (!qualified_lookup_using_namespace (name, scope, decls, 0))
/* Lookup error */
return;
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/except.c,v
retrieving revision 1.77
diff -c -p -r1.77 except.c
*** except.c 1999/09/06 02:43:07 1.77
--- except.c 1999/09/07 07:59:39
*************** end_anon_func ()
*** 838,844 ****
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0, 0);
pop_from_top_level ();
pop_function_context_from (NULL_TREE);
--- 838,844 ----
poplevel (1, 0, 0);
pop_momentary ();
! finish_function (lineno, 0);
pop_from_top_level ();
pop_function_context_from (NULL_TREE);
Index: lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.142
diff -c -p -r1.142 lex.c
*** lex.c 1999/09/06 02:43:07 1.142
--- lex.c 1999/09/07 07:59:42
*************** static void pragma_ungetc PROTO((int));
*** 94,99 ****
--- 94,100 ----
static int read_line_number PROTO((int *));
static int token_getch PROTO ((void));
static void token_put_back PROTO ((int));
+ static void mark_impl_file_chain PROTO ((void *));
/* Given a file name X, return the nondirectory portion.
Keep in mind that X can be computed more than once. */
*************** extern int *token_count;
*** 185,190 ****
--- 186,218 ----
static tree defarg_fns;
static tree defarg_parm;
+ /* Functions and data structures for #pragma interface.
+
+ `#pragma implementation' means that the main file being compiled
+ is considered to implement (provide) the classes that appear in
+ its main body. I.e., if this is file "foo.cc", and class `bar'
+ is defined in "foo.cc", then we say that "foo.cc implements bar".
+
+ All main input files "implement" themselves automagically.
+
+ `#pragma interface' means that unless this file (of the form "foo.h"
+ is not presently being included by file "foo.cc", the
+ CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none
+ of the vtables nor any of the inline functions defined in foo.h
+ will ever be output.
+
+ There are cases when we want to link files such as "defs.h" and
+ "main.cc". In this case, we give "defs.h" a `#pragma interface',
+ and "main.cc" has `#pragma implementation "defs.h"'. */
+
+ struct impl_files
+ {
+ char *filename;
+ struct impl_files *next;
+ };
+
+ static struct impl_files *impl_file_chain;
+
/* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains.
*************** init_parse (filename)
*** 544,550 ****
set_identifier_size (sizeof (struct lang_identifier));
decl_printable_name = lang_printable_name;
! init_cplus_unsave ();
init_cplus_expand ();
memcpy (tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
--- 572,578 ----
set_identifier_size (sizeof (struct lang_identifier));
decl_printable_name = lang_printable_name;
! init_tree ();
init_cplus_expand ();
memcpy (tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
*************** init_parse (filename)
*** 894,900 ****
ggc_add_tree_root (&defarg_parm, 1);
ggc_add_tree_root (&this_filename_time, 1);
ggc_add_tree_root (&filename_times, 1);
!
return filename;
}
--- 922,929 ----
ggc_add_tree_root (&defarg_parm, 1);
ggc_add_tree_root (&this_filename_time, 1);
ggc_add_tree_root (&filename_times, 1);
! ggc_add_root (&impl_file_chain, 1, sizeof (impl_file_chain),
! mark_impl_file_chain);
return filename;
}
*************** set_yydebug (value)
*** 1091,1122 ****
}
! /* Functions and data structures for #pragma interface.
!
! `#pragma implementation' means that the main file being compiled
! is considered to implement (provide) the classes that appear in
! its main body. I.e., if this is file "foo.cc", and class `bar'
! is defined in "foo.cc", then we say that "foo.cc implements bar".
!
! All main input files "implement" themselves automagically.
!
! `#pragma interface' means that unless this file (of the form "foo.h"
! is not presently being included by file "foo.cc", the
! CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none
! of the vtables nor any of the inline functions defined in foo.h
! will ever be output.
! There are cases when we want to link files such as "defs.h" and
! "main.cc". In this case, we give "defs.h" a `#pragma interface',
! and "main.cc" has `#pragma implementation "defs.h"'. */
!
! struct impl_files
{
! char *filename;
! struct impl_files *next;
! };
! static struct impl_files *impl_file_chain;
/* Helper function to load global variables with interface
information. */
--- 1120,1137 ----
}
! /* Mark ARG (which is really a struct impl_files **) for GC. */
! static void
! mark_impl_file_chain (arg)
! void *arg;
{
! struct impl_files *ifs;
! ifs = *(struct impl_files **) arg;
! if (ifs)
! ggc_mark_string (ifs->filename);
! }
/* Helper function to load global variables with interface
information. */
*************** cp_pragma_interface (main_filename)
*** 1202,1208 ****
TREE_INT_CST_LOW (fi) = 0;
TREE_INT_CST_HIGH (fi) = 1;
/* Get default. */
! impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
impl_file_chain->filename = filename;
impl_file_chain->next = 0;
#endif
--- 1217,1224 ----
TREE_INT_CST_LOW (fi) = 0;
TREE_INT_CST_HIGH (fi) = 1;
/* Get default. */
! impl_file_chain
! = (struct impl_files *) xmalloc (sizeof (struct impl_files));
impl_file_chain->filename = filename;
impl_file_chain->next = 0;
#endif
*************** cp_pragma_implementation (main_filename)
*** 1237,1243 ****
}
if (ifiles == 0)
{
! ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
ifiles->filename = main_filename;
ifiles->next = impl_file_chain;
impl_file_chain = ifiles;
--- 1253,1259 ----
}
if (ifiles == 0)
{
! ifiles = (struct impl_files*) xmalloc (sizeof (struct impl_files));
ifiles->filename = main_filename;
ifiles->next = impl_file_chain;
impl_file_chain = ifiles;
*************** cp_pragma_implementation (main_filename)
*** 1247,1253 ****
&& ! strcmp (main_input_filename, input_filename))
|| ! strcmp (main_filename, input_filename))
{
! impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
impl_file_chain->filename = main_filename;
impl_file_chain->next = 0;
}
--- 1263,1269 ----
&& ! strcmp (main_input_filename, input_filename))
|| ! strcmp (main_filename, input_filename))
{
! impl_file_chain = (struct impl_files*) xmalloc (sizeof (struct impl_files));
impl_file_chain->filename = main_filename;
impl_file_chain->next = 0;
}
*************** begin_definition_of_inclass_inline (pi)
*** 1289,1295 ****
feed_input (pi->buf, pi->len, pi->filename, pi->lineno);
yychar = PRE_PARSED_FUNCTION_DECL;
! yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
/* Pass back a handle to the rest of the inline functions, so that they
can be processed later. */
DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
--- 1305,1311 ----
feed_input (pi->buf, pi->len, pi->filename, pi->lineno);
yychar = PRE_PARSED_FUNCTION_DECL;
! yylval.pi = pi;
/* Pass back a handle to the rest of the inline functions, so that they
can be processed later. */
DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
*************** do_pending_inlines ()
*** 1340,1350 ****
do_pending_inlines). */
void
! process_next_inline (t)
! tree t;
{
tree context;
- struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
context = hack_decl_function_context (i->fndecl);
if (context)
pop_function_context_from (context);
--- 1356,1365 ----
do_pending_inlines). */
void
! process_next_inline (i)
! struct pending_inline *i;
{
tree context;
context = hack_decl_function_context (i->fndecl);
if (context)
pop_function_context_from (context);
*************** linenum:
*** 2539,2545 ****
body_time = this_time;
}
! if (!TREE_PERMANENT (yylval.ttype))
{
input_filename
= (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
--- 2554,2560 ----
body_time = this_time;
}
! if (! ggc_p && !TREE_PERMANENT (yylval.ttype))
{
input_filename
= (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
*************** do_scoped_id (token, parsing)
*** 3254,3261 ****
/* during parsing, this is ::name. Otherwise, it is black magic. */
if (parsing)
{
! struct tree_binding _b;
! id = binding_init (&_b);
if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
id = NULL_TREE;
else
--- 3269,3275 ----
/* during parsing, this is ::name. Otherwise, it is black magic. */
if (parsing)
{
! id = make_node (CPLUS_BINDING);
if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
id = NULL_TREE;
else
*************** tree
*** 4836,4858 ****
make_lang_type (code)
enum tree_code code;
{
- extern struct obstack *current_obstack, *saveable_obstack;
register tree t = make_node (code);
/* Set up some flags that give proper default behavior. */
if (IS_AGGR_TYPE_CODE (code))
{
- struct obstack *obstack = current_obstack;
struct lang_type *pi;
SET_IS_AGGR_TYPE (t, 1);
-
- if (! TREE_PERMANENT (t))
- obstack = saveable_obstack;
- else
- my_friendly_assert (obstack == &permanent_obstack, 236);
! pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
bzero ((char *) pi, (int) sizeof (struct lang_type));
TYPE_LANG_SPECIFIC (t) = pi;
--- 4850,4865 ----
make_lang_type (code)
enum tree_code code;
{
register tree t = make_node (code);
/* Set up some flags that give proper default behavior. */
if (IS_AGGR_TYPE_CODE (code))
{
struct lang_type *pi;
SET_IS_AGGR_TYPE (t, 1);
! pi = (struct lang_type *) xmalloc (sizeof (struct lang_type));
bzero ((char *) pi, (int) sizeof (struct lang_type));
TYPE_LANG_SPECIFIC (t) = pi;
Index: method.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/method.c,v
retrieving revision 1.114
diff -c -p -r1.114 method.c
*** method.c 1999/09/06 02:43:08 1.114
--- method.c 1999/09/07 07:59:43
*************** emit_thunk (thunk_fndecl)
*** 2147,2153 ****
t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);
c_expand_return (t);
! finish_function (lineno, 0, 0);
/* Don't let the backend defer this function. */
if (DECL_DEFER_OUTPUT (thunk_fndecl))
--- 2147,2153 ----
t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);
c_expand_return (t);
! finish_function (lineno, 0);
/* Don't let the backend defer this function. */
if (DECL_DEFER_OUTPUT (thunk_fndecl))
*************** synthesize_method (fndecl)
*** 2388,2394 ****
}
}
! finish_function (lineno, 0, nested);
extract_interface_info ();
if (! context)
--- 2388,2394 ----
}
}
! finish_function (lineno, 0);
extract_interface_info ();
if (! context)
Index: parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.139
diff -c -p -r1.139 parse.y
*** parse.y 1999/09/05 16:21:30 1.139
--- parse.y 1999/09/07 07:59:50
*************** empty_parms ()
*** 90,96 ****
%start program
! %union {long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; }
/* All identifiers that are not reserved words
and are not declared typedefs in the current block */
--- 90,103 ----
%start program
! %union {
! long itype;
! tree ttype;
! char *strtype;
! enum tree_code code;
! flagged_type_tree ftype;
! struct pending_inline *pi;
! }
/* All identifiers that are not reserved words
and are not declared typedefs in the current block */
*************** empty_parms ()
*** 236,245 ****
/* C++ extensions */
%token <ttype> PTYPENAME
! %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
%type <ttype> component_constructor_declarator
! %type <ttype> fn.def2 return_id fn.defpen constructor_declarator
%type <itype> ctor_initializer_opt function_try_block
%type <ttype> named_class_head_sans_basetype
%type <ftype> class_head named_class_head
--- 243,254 ----
/* C++ extensions */
%token <ttype> PTYPENAME
! %token <ttype> EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
+ %token <pi> PRE_PARSED_FUNCTION_DECL
%type <ttype> component_constructor_declarator
! %type <ttype> fn.def2 return_id constructor_declarator
! %type <pi> fn.defpen
%type <itype> ctor_initializer_opt function_try_block
%type <ttype> named_class_head_sans_basetype
%type <ftype> class_head named_class_head
*************** extern void yyprint PROTO((FILE *, int
*** 311,317 ****
extern tree combine_strings PROTO((tree));
static int
! parse_decl(declarator, specs_attrs, attributes, initialized, decl)
tree declarator;
tree specs_attrs;
tree attributes;
--- 320,326 ----
extern tree combine_strings PROTO((tree));
static int
! parse_decl (declarator, specs_attrs, attributes, initialized, decl)
tree declarator;
tree specs_attrs;
tree attributes;
*************** eat_saved_input:
*** 651,663 ****
fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
! { finish_function (lineno, (int)$3, 0); }
| fn.def1 maybe_return_init function_try_block
! {
! int nested = (hack_decl_function_context
! (current_function_decl) != NULL_TREE);
! finish_function (lineno, (int)$3, nested);
! }
| fn.def1 maybe_return_init error
{ }
;
--- 660,668 ----
fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
! { finish_function (lineno, (int)$3); }
| fn.def1 maybe_return_init function_try_block
! { finish_function (lineno, (int)$3); }
| fn.def1 maybe_return_init error
{ }
;
*************** initlist:
*** 2059,2081 ****
fn.defpen:
PRE_PARSED_FUNCTION_DECL
! { start_function (NULL_TREE, TREE_VALUE ($1),
! NULL_TREE, 2);
reinit_parse_for_function (); }
pending_inline:
fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error
{
! int nested = (hack_decl_function_context
! (current_function_decl) != NULL_TREE);
! finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1);
}
| fn.defpen maybe_return_init function_try_block
{
! int nested = (hack_decl_function_context
! (current_function_decl) != NULL_TREE);
! finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1);
}
| fn.defpen maybe_return_init error
--- 2064,2081 ----
fn.defpen:
PRE_PARSED_FUNCTION_DECL
! { start_function (NULL_TREE, $1->fndecl, NULL_TREE, 2);
reinit_parse_for_function (); }
pending_inline:
fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error
{
! finish_function (lineno, (int)$3 | 2);
process_next_inline ($1);
}
| fn.defpen maybe_return_init function_try_block
{
! finish_function (lineno, (int)$3 | 2);
process_next_inline ($1);
}
| fn.defpen maybe_return_init error
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.348
diff -c -p -r1.348 pt.c
*** pt.c 1999/09/06 02:43:08 1.348
--- pt.c 1999/09/07 07:59:57
*************** instantiate_decl (d)
*** 9730,9736 ****
/* Clean up. */
pop_obstacks ();
! finish_function (lineno, 0, nested);
expanding_p = saved_expanding_p;
/* Now, generate RTL for the function. */
--- 9730,9736 ----
/* Clean up. */
pop_obstacks ();
! finish_function (lineno, 0);
expanding_p = saved_expanding_p;
/* Now, generate RTL for the function. */
Index: rtti.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/rtti.c,v
retrieving revision 1.35
diff -c -p -r1.35 rtti.c
*** rtti.c 1999/08/18 20:44:11 1.35
--- rtti.c 1999/09/07 07:59:58
*************** synthesize_tinfo_fn (fndecl)
*** 1173,1177 ****
tmp = build_indirect_ref (tmp, 0);
c_expand_return (tmp);
pop_momentary ();
! finish_function (lineno, 0, 0);
}
--- 1173,1177 ----
tmp = build_indirect_ref (tmp, 0);
c_expand_return (tmp);
pop_momentary ();
! finish_function (lineno, 0);
}
Index: semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.70
diff -c -p -r1.70 semantics.c
*** semantics.c 1999/09/02 19:14:06 1.70
--- semantics.c 1999/09/07 07:59:58
*************** expand_body (fn)
*** 2185,2198 ****
tree fn;
{
int saved_expanding_p;
- int nested;
tree t;
tree try_block;
- /* Remember whether we're already processing a function definition
- so that we can tell finish_function. */
- nested = in_function_p ();
-
/* Let the compiler know that now is the time to really generate
actualy RTL. */
saved_expanding_p = expanding_p;
--- 2185,2193 ----
*************** expand_body (fn)
*** 2248,2254 ****
finish_function_handler_sequence (NULL_TREE);
}
! finish_function (lineno, 0, nested);
/* Restore EXPANDING_P. */
expanding_p = saved_expanding_p;
--- 2243,2249 ----
finish_function_handler_sequence (NULL_TREE);
}
! finish_function (lineno, 0);
/* Restore EXPANDING_P. */
expanding_p = saved_expanding_p;
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.142
diff -c -p -r1.142 tree.c
*** tree.c 1999/08/29 13:47:37 1.142
--- tree.c 1999/09/07 08:00:00
*************** Boston, MA 02111-1307, USA. */
*** 27,32 ****
--- 27,33 ----
#include "flags.h"
#include "rtl.h"
#include "toplev.h"
+ #include "ggc.h"
static tree bot_manip PROTO((tree));
static tree perm_manip PROTO((tree));
*************** static int avoid_overlap PROTO((tree, tr
*** 39,44 ****
--- 40,46 ----
static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
static tree no_linkage_helper PROTO((tree));
static tree build_srcloc PROTO((char *, int));
+ static void mark_list_hash PROTO ((void *));
#define CEIL(x,y) (((x) + (y) - 1) / (y))
*************** debug_binfo (elem)
*** 1299,1323 ****
}
}
- /* Initialize an CPLUS_BINDING node that does not live on an obstack. */
-
- tree
- binding_init (node)
- struct tree_binding* node;
- {
- static struct tree_binding* source;
- if (!source)
- {
- extern struct obstack permanent_obstack;
- push_obstacks (&permanent_obstack, &permanent_obstack);
- source = (struct tree_binding*)make_node (CPLUS_BINDING);
- pop_obstacks ();
- }
- *node = *source;
- TREE_PERMANENT ((tree)node) = 0;
- return (tree)node;
- }
-
int
count_functions (t)
tree t;
--- 1301,1306 ----
*************** make_ptrmem_cst (type, member)
*** 2869,2880 ****
PTRMEM_CST_MEMBER (ptrmem_cst) = member;
return ptrmem_cst;
}
- /* Initialize unsave for C++. */
void
! init_cplus_unsave ()
{
lang_unsave_expr_now = cplus_unsave_expr_now;
}
/* The C++ version of unsave_expr_now.
--- 2852,2880 ----
PTRMEM_CST_MEMBER (ptrmem_cst) = member;
return ptrmem_cst;
}
+
+ /* Mark ARG (which is really a list_hash_table **) for GC. */
+
+ static void
+ mark_list_hash (arg)
+ void *arg;
+ {
+ struct list_hash *lh;
+
+ for (lh = * ((struct list_hash **) arg); lh; lh = lh->next)
+ ggc_mark_tree (lh->list);
+ }
+
+ /* Initialize tree.c. */
void
! init_tree ()
{
lang_unsave_expr_now = cplus_unsave_expr_now;
+ ggc_add_root (list_hash_table,
+ sizeof (list_hash_table) / sizeof (struct list_hash *),
+ sizeof (struct list_hash *),
+ mark_list_hash);
}
/* The C++ version of unsave_expr_now.