Commit 66c78aa9 by Jason Merrill Committed by Jason Merrill

Support namespaces in DWARF 2 output.

        * dwarf2out.c (gen_namespace_die): New function.
        (force_namespace_die, setup_namespace_context): New fns.
        (declare_in_namespace): New fn.
        (gen_decl_die): Call declare_in_namespace.  Handle namespaces.
        (dwarf2out_decl): Handle namespaces.
        (scope_die_for): Pass through a namespace scope.
        (class_scope_p): Rename to class_or_namespace_scope_p.
        (gen_subprogram_die, gen_variable_die): Adjust.
        (gen_struct_or_union_die): Always emit a declaration
        if context_die is a namespace.

Co-Authored-By: Daniel Berlin <dberlin@dberlin.org>

From-SVN: r74436
parent ed36980c
2003-12-08 Jason Merrill <jason@redhat.com>
Daniel Berlin <dberlin@dberlin.org>
Support namespaces in DWARF 2 output.
* dwarf2out.c (gen_namespace_die): New function.
(force_namespace_die, setup_namespace_context): New fns.
(declare_in_namespace): New fn.
(gen_decl_die): Call declare_in_namespace. Handle namespaces.
(dwarf2out_decl): Handle namespaces.
(scope_die_for): Pass through a namespace scope.
(class_scope_p): Rename to class_or_namespace_scope_p.
(gen_subprogram_die, gen_variable_die): Adjust.
(gen_struct_or_union_die): Always emit a declaration
if context_die is a namespace.
2003-12-08 Jan Hubicka <jh@suse.cz> 2003-12-08 Jan Hubicka <jh@suse.cz>
* unwind-pe.h (read_uleb128): Fix handling of large values * unwind-pe.h (read_uleb128): Fix handling of large values
......
...@@ -3740,7 +3740,7 @@ static void push_decl_scope (tree); ...@@ -3740,7 +3740,7 @@ static void push_decl_scope (tree);
static void pop_decl_scope (void); static void pop_decl_scope (void);
static dw_die_ref scope_die_for (tree, dw_die_ref); static dw_die_ref scope_die_for (tree, dw_die_ref);
static inline int local_scope_p (dw_die_ref); static inline int local_scope_p (dw_die_ref);
static inline int class_scope_p (dw_die_ref); static inline int class_or_namespace_scope_p (dw_die_ref);
static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref); static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
static const char *type_tag (tree); static const char *type_tag (tree);
static tree member_declared_type (tree); static tree member_declared_type (tree);
...@@ -3778,7 +3778,11 @@ static void gen_tagged_type_instantiation_die (tree, dw_die_ref); ...@@ -3778,7 +3778,11 @@ static void gen_tagged_type_instantiation_die (tree, dw_die_ref);
static void gen_block_die (tree, dw_die_ref, int); static void gen_block_die (tree, dw_die_ref, int);
static void decls_for_scope (tree, dw_die_ref, int); static void decls_for_scope (tree, dw_die_ref, int);
static int is_redundant_typedef (tree); static int is_redundant_typedef (tree);
static void gen_namespace_die (tree);
static void gen_decl_die (tree, dw_die_ref); static void gen_decl_die (tree, dw_die_ref);
static dw_die_ref force_namespace_die (tree);
static dw_die_ref setup_namespace_context (tree, dw_die_ref);
static void declare_in_namespace (tree, dw_die_ref);
static unsigned lookup_filename (const char *); static unsigned lookup_filename (const char *);
static void init_file_table (void); static void init_file_table (void);
static void retry_incomplete_types (void); static void retry_incomplete_types (void);
...@@ -4034,6 +4038,8 @@ dwarf_tag_name (unsigned int tag) ...@@ -4034,6 +4038,8 @@ dwarf_tag_name (unsigned int tag)
return "DW_TAG_namelist"; return "DW_TAG_namelist";
case DW_TAG_namelist_item: case DW_TAG_namelist_item:
return "DW_TAG_namelist_item"; return "DW_TAG_namelist_item";
case DW_TAG_namespace:
return "DW_TAG_namespace";
case DW_TAG_packed_type: case DW_TAG_packed_type:
return "DW_TAG_packed_type"; return "DW_TAG_packed_type";
case DW_TAG_subprogram: case DW_TAG_subprogram:
...@@ -10020,9 +10026,14 @@ scope_die_for (tree t, dw_die_ref context_die) ...@@ -10020,9 +10026,14 @@ scope_die_for (tree t, dw_die_ref context_die)
containing_scope = TYPE_CONTEXT (t); containing_scope = TYPE_CONTEXT (t);
/* Ignore namespaces for the moment. */ /* Use the containing namespace if it was passed in (for a declaration). */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL) if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
containing_scope = NULL_TREE; {
if (context_die == lookup_decl_die (containing_scope))
/* OK */;
else
containing_scope = NULL_TREE;
}
/* Ignore function type "scopes" from the C frontend. They mean that /* Ignore function type "scopes" from the C frontend. They mean that
a tagged type is local to a parmlist of a function declarator, but a tagged type is local to a parmlist of a function declarator, but
...@@ -10072,14 +10083,16 @@ local_scope_p (dw_die_ref context_die) ...@@ -10072,14 +10083,16 @@ local_scope_p (dw_die_ref context_die)
return 0; return 0;
} }
/* Returns nonzero if CONTEXT_DIE is a class. */ /* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding
whether or not to treat a DIE in this context as a declaration. */
static inline int static inline int
class_scope_p (dw_die_ref context_die) class_or_namespace_scope_p (dw_die_ref context_die)
{ {
return (context_die return (context_die
&& (context_die->die_tag == DW_TAG_structure_type && (context_die->die_tag == DW_TAG_structure_type
|| context_die->die_tag == DW_TAG_union_type)); || context_die->die_tag == DW_TAG_union_type
|| context_die->die_tag == DW_TAG_namespace));
} }
/* Many forms of DIEs require a "type description" attribute. This /* Many forms of DIEs require a "type description" attribute. This
...@@ -10599,7 +10612,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -10599,7 +10612,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
tree outer_scope; tree outer_scope;
dw_die_ref old_die = lookup_decl_die (decl); dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (current_function_decl != decl int declaration = (current_function_decl != decl
|| class_scope_p (context_die)); || class_or_namespace_scope_p (context_die));
/* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we /* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we
started to generate the abstract instance of an inline, decided to output started to generate the abstract instance of an inline, decided to output
...@@ -10608,7 +10621,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -10608,7 +10621,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
we'll get back to the abstract instance when done with the class. */ we'll get back to the abstract instance when done with the class. */
/* The class-scope declaration DIE must be the primary DIE. */ /* The class-scope declaration DIE must be the primary DIE. */
if (origin && declaration && class_scope_p (context_die)) if (origin && declaration && class_or_namespace_scope_p (context_die))
{ {
origin = NULL; origin = NULL;
if (old_die) if (old_die)
...@@ -10873,7 +10886,7 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -10873,7 +10886,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
dw_die_ref old_die = lookup_decl_die (decl); dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl) int declaration = (DECL_EXTERNAL (decl)
|| class_scope_p (context_die)); || class_or_namespace_scope_p (context_die));
if (origin != NULL) if (origin != NULL)
add_abstract_origin_attribute (var_die, origin); add_abstract_origin_attribute (var_die, origin);
...@@ -10926,7 +10939,7 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -10926,7 +10939,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
if (declaration) if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1); add_AT_flag (var_die, DW_AT_declaration, 1);
if (class_scope_p (context_die) || DECL_ABSTRACT (decl)) if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl))
equate_decl_number_to_die (decl, var_die); equate_decl_number_to_die (decl, var_die);
if (! declaration && ! DECL_ABSTRACT (decl)) if (! declaration && ! DECL_ABSTRACT (decl))
...@@ -11316,12 +11329,14 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die) ...@@ -11316,12 +11329,14 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
int complete = (TYPE_SIZE (type) int complete = (TYPE_SIZE (type)
&& (! TYPE_STUB_DECL (type) && (! TYPE_STUB_DECL (type)
|| ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)))); || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
if (type_die && ! complete) if (type_die && ! complete)
return; return;
if (TYPE_CONTEXT (type) != NULL_TREE if (TYPE_CONTEXT (type) != NULL_TREE
&& AGGREGATE_TYPE_P (TYPE_CONTEXT (type))) && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
|| TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL))
nested = 1; nested = 1;
scope_die = scope_die_for (type, context_die); scope_die = scope_die_for (type, context_die);
...@@ -11345,7 +11360,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die) ...@@ -11345,7 +11360,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
/* If this type has been completed, then give it a byte_size attribute and /* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */ then give a list of members. */
if (complete) if (complete && !ns_decl)
{ {
/* Prevent infinite recursion in cases where the type of some member of /* Prevent infinite recursion in cases where the type of some member of
this type is expressed in terms of this type itself. */ this type is expressed in terms of this type itself. */
...@@ -11570,7 +11585,10 @@ gen_type_die (tree type, dw_die_ref context_die) ...@@ -11570,7 +11585,10 @@ gen_type_die (tree type, dw_die_ref context_die)
need_pop = 1; need_pop = 1;
} }
else else
need_pop = 0; {
declare_in_namespace (type, context_die);
need_pop = 0;
}
if (TREE_CODE (type) == ENUMERAL_TYPE) if (TREE_CODE (type) == ENUMERAL_TYPE)
gen_enumeration_type_die (type, context_die); gen_enumeration_type_die (type, context_die);
...@@ -11803,6 +11821,98 @@ is_redundant_typedef (tree decl) ...@@ -11803,6 +11821,98 @@ is_redundant_typedef (tree decl)
return 0; return 0;
} }
/* Returns the DIE for namespace NS or aborts.
Note that namespaces don't really have a lexical context, so there's no
need to pass in a context_die. They always go inside their containing
namespace, or comp_unit_die if none. */
static dw_die_ref
force_namespace_die (tree ns)
{
dw_die_ref ns_die;
dwarf2out_decl (ns);
ns_die = lookup_decl_die (ns);
if (!ns_die)
abort();
return ns_die;
}
/* Force out any required namespaces to be able to output DECL,
and return the new context_die for it, if it's changed. */
static dw_die_ref
setup_namespace_context (tree thing, dw_die_ref context_die)
{
tree context = DECL_P (thing) ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing);
if (context && TREE_CODE (context) == NAMESPACE_DECL)
/* Force out the namespace. */
context_die = force_namespace_die (context);
return context_die;
}
/* Emit a declaration DIE for THING (which is either a DECL or a tagged
type) within its namespace, if appropriate.
For compatibility with older debuggers, namespace DIEs only contain
declarations; all definitions are emitted at CU scope. */
static void
declare_in_namespace (tree thing, dw_die_ref context_die)
{
dw_die_ref ns_context;
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
ns_context = setup_namespace_context (thing, context_die);
if (ns_context != context_die)
{
if (DECL_P (thing))
gen_decl_die (thing, ns_context);
else
gen_type_die (thing, ns_context);
}
}
/* Generate a DIE for a namespace or namespace alias */
static void
gen_namespace_die (tree decl)
{
dw_die_ref context_die = setup_namespace_context (decl, comp_unit_die);
/* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
they are an alias of.*/
if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
{
/* Output a real namespace */
dw_die_ref namespace_die
= new_die (DW_TAG_namespace, context_die, decl);
add_name_and_src_coords_attributes (namespace_die, decl);
equate_decl_number_to_die (decl, namespace_die);
}
else
{
/* Output a namespace alias */
/* Force out the namespace we are an alias of, if necessary */
dw_die_ref origin_die
= force_namespace_die (DECL_ABSTRACT_ORIGIN (decl));
/* Now create the namespace alias DIE. */
dw_die_ref namespace_die
= new_die (DW_TAG_imported_declaration, context_die, decl);
add_name_and_src_coords_attributes (namespace_die, decl);
add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
equate_decl_number_to_die (decl, namespace_die);
}
}
/* Generate Dwarf debug information for a decl described by DECL. */ /* Generate Dwarf debug information for a decl described by DECL. */
static void static void
...@@ -11838,7 +11948,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -11838,7 +11948,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
emit info for the abstract instance and set up to refer to it. */ emit info for the abstract instance and set up to refer to it. */
else if (cgraph_function_possibly_inlined_p (decl) else if (cgraph_function_possibly_inlined_p (decl)
&& ! DECL_ABSTRACT (decl) && ! DECL_ABSTRACT (decl)
&& ! class_scope_p (context_die) && ! class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just /* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */ that case, because that works only if we have a die. */
...@@ -11863,6 +11973,9 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -11863,6 +11973,9 @@ gen_decl_die (tree decl, dw_die_ref context_die)
origin = decl_class_context (decl); origin = decl_class_context (decl);
if (origin != NULL_TREE) if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die); gen_type_die_for_member (origin, decl, context_die);
/* And its containing namespace. */
declare_in_namespace (decl, context_die);
} }
/* Now output a DIE to represent the function itself. */ /* Now output a DIE to represent the function itself. */
...@@ -11914,6 +12027,9 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -11914,6 +12027,9 @@ gen_decl_die (tree decl, dw_die_ref context_die)
if (origin != NULL_TREE) if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die); gen_type_die_for_member (origin, decl, context_die);
/* And its containing namespace. */
declare_in_namespace (decl, context_die);
/* Now output the DIE to represent the data object itself. This gets /* Now output the DIE to represent the data object itself. This gets
complicated because of the possibility that the VAR_DECL really complicated because of the possibility that the VAR_DECL really
represents an inlined instance of a formal parameter for an inline represents an inlined instance of a formal parameter for an inline
...@@ -11942,7 +12058,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -11942,7 +12058,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
/* Ignore for now. */ gen_namespace_die (decl);
break; break;
default: default:
...@@ -12065,6 +12181,13 @@ dwarf2out_decl (tree decl) ...@@ -12065,6 +12181,13 @@ dwarf2out_decl (tree decl)
return; return;
break; break;
case NAMESPACE_DECL:
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
if (lookup_decl_die (decl) != NULL)
return;
break;
case TYPE_DECL: case TYPE_DECL:
/* Don't emit stubs for types unless they are needed by other DIEs. */ /* Don't emit stubs for types unless they are needed by other DIEs. */
if (TYPE_DECL_SUPPRESS_DEBUG (decl)) if (TYPE_DECL_SUPPRESS_DEBUG (decl))
......
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