This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
dwarf2out patch: support TYPE_DECL_SUPPRESS_DEBUG
- To: gcc-patches at gcc dot gnu dot org
- Subject: dwarf2out patch: support TYPE_DECL_SUPPRESS_DEBUG
- From: Jason Merrill <jason at cygnus dot com>
- Date: Wed, 24 Nov 1999 18:26:57 -0800
As with stabs, we can handle TYPE_DECL_SUPPRESS_DEBUG in dwarf by
pretending that the type was never defined in the current translation
unit. This is somewhat more complex in dwarf because the info for members
needs to be nested within the info for the class; this patch causes us to
handle that by only including the info for members that are directly
referenced by other DIEs, as the DIE for the definition of a member
function refers to the declaration DIE within the class info.
1999-11-24 Jason Merrill <jason@casey.cygnus.com>
Generate minimal debug info for types with TYPE_DECL_SUPPRESS_INFO set.
* dwarf2out.c (gen_struct_or_union_type_die): TYPE_DECL_SUPPRESS_INFO
means pretend the type isn't defined.
Don't defer emitting types.
(gen_type_die_for_member): New fn.
(gen_decl_die): Call it.
(splice_child_die): New fn.
(gen_member_die): Call it rather than generate duplicate dies.
*** dwarf2out.c Mon Nov 15 12:06:13 1999
--- dwarf2out.c.~6~ Fri Nov 12 07:57:03 1999
*************** static void gen_decl_die PROTO((tree, d
*** 2552,2557 ****
--- 2552,2558 ----
static unsigned lookup_filename PROTO((const char *));
static void add_incomplete_type PROTO((tree));
static void retry_incomplete_types PROTO((void));
+ static void gen_type_die_for_member PROTO((tree, tree, dw_die_ref));
static void gen_abstract_function PROTO((tree));
/* Section names used to hold DWARF debugging information. */
*************** add_child_die (die, child_die)
*** 4122,4127 ****
--- 4153,4186 ----
}
}
+ /* Move CHILD, which must be a child of PARENT, to the front of
+ PARENT's list of children. */
+
+ static void
+ splice_child_die (parent, child)
+ dw_die_ref parent, child;
+ {
+ dw_die_ref *p;
+
+ /* We want the declaration DIE from inside the class, not the
+ specification DIE at toplevel. */
+ if (child->die_parent != parent)
+ child = get_AT_ref (child, DW_AT_specification);
+
+ if (parent == NULL || child == NULL || child->die_parent != parent)
+ abort ();
+
+ for (p = &(parent->die_child); *p; p = &((*p)->die_sib))
+ if (*p == child)
+ {
+ *p = child->die_sib;
+ break;
+ }
+
+ child->die_sib = parent->die_child;
+ parent->die_child = child;
+ }
+
/* Return a pointer to a newly created DIE node. */
static inline dw_die_ref
*************** gen_formal_types_die (function_or_method
*** 8202,8207 ****
--- 8203,8238 ----
}
}
+ /* We want to generate the DIE for TYPE so that we can generate the
+ die for MEMBER, which has been defined; we will need to refer back
+ to the member declaration nested within TYPE. If we're trying to
+ generate minimal debug info for TYPE, processing TYPE won't do the
+ trick; we need to attach the member declaration by hand. */
+
+ static void
+ gen_type_die_for_member (type, member, context_die)
+ tree type, member;
+ dw_die_ref context_die;
+ {
+ gen_type_die (type, context_die);
+
+ /* If we're trying to avoid duplicate debug info, we may not have
+ emitted the member decl for this function. Emit it now. */
+ if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
+ && ! lookup_decl_die (member))
+ {
+ if (decl_ultimate_origin (member))
+ abort ();
+
+ push_decl_scope (type);
+ if (TREE_CODE (member) == FUNCTION_DECL)
+ gen_subprogram_die (member, lookup_type_die (type));
+ else
+ gen_variable_die (member, lookup_type_die (type));
+ pop_decl_scope ();
+ }
+ }
+
/* Generate the DWARF2 info for the "abstract" instance
of a function which we may later generate inlined and/or
out-of-line instances of. */
*************** gen_member_die (type, context_die)
*** 8833,8838 ****
--- 8958,8964 ----
register dw_die_ref context_die;
{
register tree member;
+ dw_die_ref child;
/* If this is not an incomplete type, output descriptions of each of its
members. Note that as we output the DIEs necessary to represent the
*************** gen_member_die (type, context_die)
*** 8860,8873 ****
/* Now output info about the data members and type members. */
for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member))
! gen_decl_die (member, context_die);
/* Now output info about the function members (if any). */
for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member))
! gen_decl_die (member, context_die);
}
! /* Generate a DIE for a structure or union type. */
static void
gen_struct_or_union_type_die (type, context_die)
--- 8986,9018 ----
/* Now output info about the data members and type members. */
for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member))
! {
! /* If we thought we were generating minimal debug info for TYPE
! and then changed our minds, some of the member declarations
! may have already been defined. Don't define them again, but
! do put them in the right order. */
!
! child = lookup_decl_die (member);
! if (child)
! splice_child_die (context_die, child);
! else
! gen_decl_die (member, context_die);
! }
/* Now output info about the function members (if any). */
for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member))
! {
! child = lookup_decl_die (member);
! if (child)
! splice_child_die (context_die, child);
! else
! gen_decl_die (member, context_die);
! }
}
! /* Generate a DIE for a structure or union type. If TYPE_DECL_SUPPRESS_DEBUG
! is set, we pretend that the type was never defined, so we only get the
! member DIEs needed by later specification DIEs. */
static void
gen_struct_or_union_type_die (type, context_die)
*************** gen_struct_or_union_type_die (type, cont
*** 8877,8884 ****
register dw_die_ref type_die = lookup_type_die (type);
register dw_die_ref scope_die = 0;
register int nested = 0;
! if (type_die && ! TYPE_SIZE (type))
return;
if (TYPE_CONTEXT (type) != NULL_TREE
--- 9022,9031 ----
register dw_die_ref type_die = lookup_type_die (type);
register dw_die_ref scope_die = 0;
register int nested = 0;
+ int complete = (TYPE_SIZE (type)
+ && ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)));
! if (type_die && ! complete)
return;
if (TYPE_CONTEXT (type) != NULL_TREE
*************** gen_struct_or_union_type_die (type, cont
*** 8912,8918 ****
}
/* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */
! else if (TYPE_SIZE (type))
{
/* Prevent infinite recursion in cases where the type of some member of
this type is expressed in terms of this type itself. */
--- 9059,9065 ----
}
/* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */
! else if (complete)
{
/* Prevent infinite recursion in cases where the type of some member of
this type is expressed in terms of this type itself. */
*************** gen_decl_die (decl, context_die)
*** 9395,9401 ****
/* And its containing type. */
origin = decl_class_context (decl);
if (origin != NULL_TREE)
! gen_type_die (origin, context_die);
/* And its virtual context. */
if (DECL_VINDEX (decl) != NULL_TREE)
--- 9547,9553 ----
/* And its containing type. */
origin = decl_class_context (decl);
if (origin != NULL_TREE)
! gen_type_die_for_member (origin, decl, context_die);
/* And its virtual context. */
if (DECL_VINDEX (decl) != NULL_TREE)
*************** gen_decl_die (decl, context_die)
*** 9450,9456 ****
/* And its containing type. */
origin = decl_class_context (decl);
if (origin != NULL_TREE)
! gen_type_die (origin, context_die);
/* Now output the DIE to represent the data object itself. This gets
complicated because of the possibility that the VAR_DECL really
--- 9602,9608 ----
/* And its containing type. */
origin = decl_class_context (decl);
if (origin != NULL_TREE)
! gen_type_die_for_member (origin, decl, context_die);
/* Now output the DIE to represent the data object itself. This gets
complicated because of the possibility that the VAR_DECL really