Commit ae673f14 by Jason Merrill Committed by Jason Merrill

class.c (finish_struct): If we're a local class in a template function, add a TAG_DEFN.

        * class.c (finish_struct): If we're a local class in a template
        function, add a TAG_DEFN.
        * pt.c (lookup_template_class): If this is a local class in a
        template function, call pushtag.
        (tsubst_expr, case TAG_DEFN): Handle classes, too.

        Emit debug info with the vtable.
        * search.c (maybe_suppress_debug_info): New function...
        * class.c (finish_struct_1): ...split out from here.
        * cp-tree.h: Declare it.
        * decl2.c (finish_vtable_vardecl): Override TYPE_DECL_SUPPRESS_DEBUG
        if we're writing out the vtable.
        * decl.c, search.c (dfs_debug_mark, dfs_debug_unmarked_p,
        note_debug_info_needed): #if 0 out.

From-SVN: r30541
parent 348bb3c7
1999-11-15 Jason Merrill <jason@casey.cygnus.com>
* class.c (finish_struct): If we're a local class in a template
function, add a TAG_DEFN.
* pt.c (lookup_template_class): If this is a local class in a
template function, call pushtag.
(tsubst_expr, case TAG_DEFN): Handle classes, too.
Emit debug info with the vtable.
* search.c (maybe_suppress_debug_info): New function...
* class.c (finish_struct_1): ...split out from here.
* cp-tree.h: Declare it.
* decl2.c (finish_vtable_vardecl): Override TYPE_DECL_SUPPRESS_DEBUG
if we're writing out the vtable.
* decl.c, search.c (dfs_debug_mark, dfs_debug_unmarked_p,
note_debug_info_needed): #if 0 out.
1999-11-14 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (DECL_LOCAL_FUCNTION_P): New macro.
......
......@@ -4180,46 +4180,7 @@ finish_struct_1 (t)
if (warn_overloaded_virtual)
warn_hidden (t);
#if 0
/* This has to be done after we have sorted out what to do with
the enclosing type. */
if (write_symbols != DWARF_DEBUG)
{
/* Be smarter about nested classes here. If a type is nested,
only output it if we would output the enclosing type. */
if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t)))
DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t));
}
#endif
if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG)
{
/* If the type has methods, we want to think about cutting down
the amount of symbol table stuff we output. The value stored in
the TYPE_DECL's DECL_IGNORED_P slot is a first approximation.
For example, if a member function is seen and we decide to
write out that member function, then we can change the value
of the DECL_IGNORED_P slot, and the type will be output when
that member function's debug info is written out.
We can't do this with DWARF, which does not support name
references between translation units. */
if (CLASSTYPE_METHOD_VEC (t))
{
/* Don't output full info about any type
which does not have its implementation defined here. */
if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
#if 0
/* XXX do something about this. */
else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
/* Only a first approximation! */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
#endif
}
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
}
maybe_suppress_debug_info (t);
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel_bindings_p ());
......@@ -4287,6 +4248,13 @@ finish_struct (t, attributes)
else
error ("trying to finish struct, but kicked out due to previous parse errors.");
if (processing_template_decl)
{
tree scope = current_scope ();
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_tree (build_min (TAG_DEFN, t));
}
return t;
}
......
......@@ -3830,6 +3830,7 @@ extern tree init_vbase_pointers PROTO((tree, tree));
extern void expand_indirect_vtbls_init PROTO((tree, tree, tree));
extern void clear_search_slots PROTO((tree));
extern tree get_vbase_types PROTO((tree));
extern void maybe_suppress_debug_info PROTO((tree));
extern void note_debug_info_needed PROTO((tree));
extern void push_class_decls PROTO((tree));
extern void pop_class_decls PROTO((void));
......
......@@ -7063,12 +7063,17 @@ layout_var_decl (decl)
cp_error ("storage size of `%D' isn't known", decl);
TREE_TYPE (decl) = error_mark_node;
}
#if 0
/* Keep this code around in case we later want to control debug info
based on whether a type is "used". (jason 1999-11-11) */
else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype))
/* Let debugger know it should output info for this type. */
note_debug_info_needed (ttype);
if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl))
note_debug_info_needed (DECL_CONTEXT (decl));
#endif
if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
&& DECL_SIZE (decl) != NULL_TREE
......@@ -13443,6 +13448,10 @@ finish_function (lineno, flags)
tree ttype = target_type (fntype);
tree parmdecl;
#if 0
/* Keep this code around in case we later want to control debug info
based on whether a type is "used". (jason 1999-11-11) */
if (IS_AGGR_TYPE (ttype))
/* Let debugger know it should output info for this type. */
note_debug_info_needed (ttype);
......@@ -13454,6 +13463,7 @@ finish_function (lineno, flags)
/* Let debugger know it should output info for this type. */
note_debug_info_needed (ttype);
}
#endif
}
/* Clean house because we will need to reorder insns here. */
......@@ -13643,8 +13653,13 @@ finish_function (lineno, flags)
mark_inline_for_output (fndecl);
}
#if 0
/* Keep this code around in case we later want to control debug info
based on whether a type is "used". (jason 1999-11-11) */
if (ctype && TREE_ASM_WRITTEN (fndecl))
note_debug_info_needed (ctype);
#endif
returns_null |= can_reach_end;
......
......@@ -2598,6 +2598,14 @@ finish_vtable_vardecl (t, data)
if (flag_syntax_only)
TREE_ASM_WRITTEN (vars) = 1;
/* Since we're writing out the vtable here, also write the debug
info. */
if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (ctype)))
{
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (ctype)) = 0;
rest_of_type_compilation (ctype, toplevel_bindings_p ());
}
return 1;
}
else if (!DECL_NEEDED_P (vars))
......
......@@ -369,7 +369,7 @@ build_eh_type_type_ref (type)
}
/* This routine is called to mark all the symbols representing runtime
type functions in the exception table as haveing been referenced.
type functions in the exception table as having been referenced.
This will make sure code is emitted for them. Called from finish_file. */
void
mark_all_runtime_matches ()
......
......@@ -3909,10 +3909,14 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
CLASSTYPE_GOT_SEMICOLON (t) = 1;
SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
pushtag (DECL_NAME (template), t, 0);
}
/* If we called start_enum above, this information will already
be set up. */
/* If we called start_enum or pushtag above, this information
will already be set up. */
if (!TYPE_NAME (t))
{
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
......@@ -7317,8 +7321,7 @@ tsubst_expr (t, args, complain, in_decl)
case TAG_DEFN:
prep_stmt (t);
t = TREE_TYPE (t);
if (TREE_CODE (t) == ENUMERAL_TYPE)
tsubst (t, args, complain, NULL_TREE);
tsubst (t, args, complain, NULL_TREE);
break;
default:
......
......@@ -103,8 +103,10 @@ static tree marked_new_vtablep PROTO((tree, void *));
static tree unmarked_new_vtablep PROTO((tree, void *));
static tree marked_pushdecls_p PROTO((tree, void *));
static tree unmarked_pushdecls_p PROTO((tree, void *));
#if 0
static tree dfs_debug_unmarkedp PROTO((tree, void *));
static tree dfs_debug_mark PROTO((tree, void *));
#endif
static tree dfs_find_vbases PROTO((tree, void *));
static tree dfs_clear_vbase_slots PROTO((tree, void *));
static tree dfs_init_vbase_pointers PROTO((tree, void *));
......@@ -2301,7 +2303,6 @@ unmarked_pushdecls_p (binfo, data)
#if 0
static int dfs_search_slot_nonempty_p (binfo) tree binfo;
{ return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
#endif
static tree
dfs_debug_unmarkedp (binfo, data)
......@@ -2311,6 +2312,7 @@ dfs_debug_unmarkedp (binfo, data)
return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo))
? binfo : NULL_TREE);
}
#endif
/* The worker functions for `dfs_walk'. These do not need to
test anything (vis a vis marking) if they are paired with
......@@ -2351,8 +2353,10 @@ dfs_unmark_new_vtable (binfo) tree binfo;
static void
dfs_clear_search_slot (binfo) tree binfo;
{ CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
#endif
/* Keep this code around in case we later want to control debug info
based on whether a type is "used". Currently, we only suppress debug
info if we can emit it with the vtable. jason 1999-11-11) */
static tree
dfs_debug_mark (binfo, data)
tree binfo;
......@@ -2360,47 +2364,18 @@ dfs_debug_mark (binfo, data)
{
tree t = BINFO_TYPE (binfo);
/* Use heuristic that if there are virtual functions,
ignore until we see a non-inline virtual function. */
tree methods = CLASSTYPE_METHOD_VEC (t);
CLASSTYPE_DEBUG_REQUESTED (t) = 1;
if (methods == 0)
return NULL_TREE;
/* If interface info is known, either we've already emitted the debug
info or we don't need to. */
if (CLASSTYPE_INTERFACE_KNOWN (t))
return NULL_TREE;
/* If debug info is requested from this context for this type, supply it.
If debug info is requested from another context for this type,
see if some third context can supply it. */
if (current_function_decl == NULL_TREE
|| DECL_CLASS_CONTEXT (current_function_decl) != t)
{
if (TREE_VEC_ELT (methods, 1))
methods = TREE_VEC_ELT (methods, 1);
else if (TREE_VEC_ELT (methods, 0))
methods = TREE_VEC_ELT (methods, 0);
else
methods = TREE_VEC_ELT (methods, 2);
methods = OVL_CURRENT (methods);
while (methods)
{
if (DECL_VINDEX (methods)
&& DECL_THIS_INLINE (methods) == 0
&& DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
{
/* Somebody, somewhere is going to have to define this
virtual function. When they do, they will provide
the debugging info. */
return NULL_TREE;
}
methods = TREE_CHAIN (methods);
}
}
/* If the class has virtual functions, we'll emit the debug info
with the vtable. */
if (TYPE_VIRTUAL_P (t))
return NULL_TREE;
/* We cannot rely on some alien method to solve our problems,
so we must write out the debug info ourselves. */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
......@@ -2408,6 +2383,7 @@ dfs_debug_mark (binfo, data)
return NULL_TREE;
}
#endif
struct vbase_info
{
......@@ -2933,6 +2909,41 @@ get_vbase_types (type)
return vbase_types;
}
/* Debug info for C++ classes can get very large; try to avoid
emitting it everywhere.
As it happens, this optimization wins even when the target supports
BINCL (though only slightly), so we always do it. */
void
maybe_suppress_debug_info (t)
tree t;
{
/* We don't bother with this for dwarf1, which shouldn't be used for C++
anyway. */
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
|| write_symbols == NO_DEBUG)
return;
/* If we already know how we're handling this class, handle debug info
the same way. */
if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
else if (CLASSTYPE_INTERFACE_KNOWN (t))
/* Don't set it. */;
/* If the class has virtual functions, write out the debug info
along with the vtable. */
else if (TYPE_VIRTUAL_P (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
/* Otherwise, just emit the debug info normally. */
}
#if 0
/* Keep this code around in case we later want to control debug info
based on whether a type is "used". Currently, we only suppress debug
info if we can emit it with the vtable. jason 1999-11-11) */
/* If we want debug info for a type TYPE, make sure all its base types
are also marked as being potentially interesting. This avoids
the problem of not writing any debug info for intermediate basetypes
......@@ -2952,10 +2963,9 @@ note_debug_info_needed (type)
return;
/* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
does not support name references between translation units. Well, we
could, but that would mean putting global labels in the debug output
before each exported type and each of its functions and static data
members. */
does not support name references between translation units. It supports
symbolic references between translation units, but only within a single
executable or shared library. */
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
|| write_symbols == NO_DEBUG)
return;
......@@ -2970,6 +2980,7 @@ note_debug_info_needed (type)
note_debug_info_needed (ttype);
}
}
#endif
/* Subroutines of push_class_decls (). */
......@@ -3333,7 +3344,9 @@ types_overlap_p (empty_type, next_type)
return oi.found_overlap;
}
/* Given a vtable VAR, determine which binfo it comes from. */
/* Given a vtable VAR, determine which binfo it comes from.
FIXME What about secondary vtables? */
tree
binfo_for_vtable (var)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment