aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c239
1 files changed, 136 insertions, 103 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 48178b7..848926b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5153,11 +5153,11 @@ static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
static void gen_inlined_structure_type_die (tree, dw_die_ref);
static void gen_inlined_union_type_die (tree, dw_die_ref);
static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
-static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
+static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
static void gen_unspecified_parameters_die (tree, dw_die_ref);
static void gen_formal_types_die (tree, dw_die_ref);
static void gen_subprogram_die (tree, dw_die_ref);
-static void gen_variable_die (tree, dw_die_ref);
+static void gen_variable_die (tree, tree, dw_die_ref);
static void gen_const_die (tree, dw_die_ref);
static void gen_label_die (tree, dw_die_ref);
static void gen_lexical_block_die (tree, dw_die_ref, int);
@@ -5177,7 +5177,7 @@ static void gen_block_die (tree, dw_die_ref, int);
static void decls_for_scope (tree, dw_die_ref, int);
static int is_redundant_typedef (const_tree);
static void gen_namespace_die (tree);
-static void gen_decl_die (tree, dw_die_ref);
+static void gen_decl_die (tree, tree, dw_die_ref);
static dw_die_ref force_decl_die (tree);
static dw_die_ref force_type_die (tree);
static dw_die_ref setup_namespace_context (tree, dw_die_ref);
@@ -13293,16 +13293,17 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
argument type of some subprogram type. */
static dw_die_ref
-gen_formal_parameter_die (tree node, dw_die_ref context_die)
+gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
{
+ tree node_or_origin = node ? node : origin;
dw_die_ref parm_die
= new_die (DW_TAG_formal_parameter, context_die, node);
- tree origin;
- switch (TREE_CODE_CLASS (TREE_CODE (node)))
+ switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin)))
{
case tcc_declaration:
- origin = decl_ultimate_origin (node);
+ if (!origin)
+ origin = decl_ultimate_origin (node);
if (origin != NULL)
add_abstract_origin_attribute (parm_die, origin);
else
@@ -13321,15 +13322,17 @@ gen_formal_parameter_die (tree node, dw_die_ref context_die)
add_AT_flag (parm_die, DW_AT_artificial, 1);
}
- equate_decl_number_to_die (node, parm_die);
- if (! DECL_ABSTRACT (node))
- add_location_or_const_value_attribute (parm_die, node, DW_AT_location);
+ if (node)
+ equate_decl_number_to_die (node, parm_die);
+ if (! DECL_ABSTRACT (node_or_origin))
+ add_location_or_const_value_attribute (parm_die, node_or_origin,
+ DW_AT_location);
break;
case tcc_type:
/* We were called with some kind of a ..._TYPE node. */
- add_type_attribute (parm_die, node, 0, 0, context_die);
+ add_type_attribute (parm_die, node_or_origin, 0, 0, context_die);
break;
default:
@@ -13382,7 +13385,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
break;
/* Output a (nameless) DIE to represent the formal parameter itself. */
- parm_die = gen_formal_parameter_die (formal_type, context_die);
+ parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
&& link == first_parm_type)
|| (arg && DECL_ARTIFICIAL (arg)))
@@ -13442,7 +13445,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
}
}
else
- gen_variable_die (member, type_die);
+ gen_variable_die (member, NULL_TREE, type_die);
pop_decl_scope ();
}
@@ -13787,7 +13790,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
"__builtin_va_alist"))
gen_unspecified_parameters_die (parm, subr_die);
else
- gen_decl_die (parm, subr_die);
+ gen_decl_die (parm, NULL, subr_die);
}
/* Decide whether we need an unspecified_parameters DIE at the end.
@@ -13829,7 +13832,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
/* Emit a DW_TAG_variable DIE for a named return value. */
if (DECL_NAME (DECL_RESULT (decl)))
- gen_decl_die (DECL_RESULT (decl), subr_die);
+ gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
current_function_has_inlines = 0;
decls_for_scope (outer_scope, subr_die, 0);
@@ -13871,17 +13874,18 @@ common_block_die_table_eq (const void *x, const void *y)
return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
}
-/* Generate a DIE to represent a declared data object. */
+/* Generate a DIE to represent a declared data object.
+ Either DECL or ORIGIN must be non-null. */
static void
-gen_variable_die (tree decl, dw_die_ref context_die)
+gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{
HOST_WIDE_INT off;
tree com_decl;
+ tree decl_or_origin = decl ? decl : origin;
dw_die_ref var_die;
- tree origin = decl_ultimate_origin (decl);
- dw_die_ref old_die = lookup_decl_die (decl);
- int declaration = (DECL_EXTERNAL (decl)
+ dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
+ int declaration = (DECL_EXTERNAL (decl_or_origin)
/* If DECL is COMDAT and has not actually been
emitted, we cannot take its address; there
might end up being no definition anywhere in
@@ -13899,11 +13903,15 @@ gen_variable_die (tree decl, dw_die_ref context_die)
Here, S<int>::i is not DECL_EXTERNAL, but no
definition is required, so the compiler will
not emit a definition. */
- || (TREE_CODE (decl) == VAR_DECL
- && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
+ || (TREE_CODE (decl_or_origin) == VAR_DECL
+ && DECL_COMDAT (decl_or_origin)
+ && !TREE_ASM_WRITTEN (decl_or_origin))
|| class_or_namespace_scope_p (context_die));
- com_decl = fortran_common (decl, &off);
+ if (!origin)
+ origin = decl_ultimate_origin (decl);
+
+ com_decl = fortran_common (decl_or_origin, &off);
/* Symbol in common gets emitted as a child of the common block, in the form
of a data member. */
@@ -13914,7 +13922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
dw_loc_descr_ref loc;
die_node com_die_arg;
- var_die = lookup_decl_die (decl);
+ var_die = lookup_decl_die (decl_or_origin);
if (var_die)
{
if (get_AT (var_die, DW_AT_location) == NULL)
@@ -14071,20 +14079,22 @@ gen_variable_die (tree decl, dw_die_ref context_die)
if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1);
- if (DECL_ABSTRACT (decl) || declaration)
+ if (decl && (DECL_ABSTRACT (decl) || declaration))
equate_decl_number_to_die (decl, var_die);
- if (! declaration && ! DECL_ABSTRACT (decl))
+ if (! declaration && ! DECL_ABSTRACT (decl_or_origin))
{
- if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
- && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- defer_location (decl, var_die);
+ if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin)
+ && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
+ defer_location (decl_or_origin, var_die);
else
- add_location_or_const_value_attribute (var_die, decl, DW_AT_location);
- add_pubname (decl, var_die);
+ add_location_or_const_value_attribute (var_die,
+ decl_or_origin,
+ DW_AT_location);
+ add_pubname (decl_or_origin, var_die);
}
else
- tree_add_const_value_attribute (var_die, decl);
+ tree_add_const_value_attribute (var_die, decl_or_origin);
}
/* Generate a DIE to represent a named constant. */
@@ -14209,7 +14219,7 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
{
dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
- if (! BLOCK_ABSTRACT (stmt))
+ if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
add_high_low_attributes (stmt, stmt_die);
decls_for_scope (stmt, stmt_die, depth);
@@ -14234,7 +14244,8 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
= new_die (DW_TAG_inlined_subroutine, context_die, stmt);
add_abstract_origin_attribute (subr_die, decl);
- add_high_low_attributes (stmt, subr_die);
+ if (TREE_ASM_WRITTEN (stmt))
+ add_high_low_attributes (stmt, subr_die);
add_call_src_coords_attributes (stmt, subr_die);
decls_for_scope (stmt, subr_die, depth);
@@ -14466,7 +14477,7 @@ gen_member_die (tree type, dw_die_ref context_die)
if (child)
splice_child_die (context_die, child);
else
- gen_decl_die (member, context_die);
+ gen_decl_die (member, NULL, context_die);
}
/* Now output info about the function members (if any). */
@@ -14480,7 +14491,7 @@ gen_member_die (tree type, dw_die_ref context_die)
if (child)
splice_child_die (context_die, child);
else
- gen_decl_die (member, context_die);
+ gen_decl_die (member, NULL, context_die);
}
}
@@ -14655,7 +14666,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
TREE_ASM_WRITTEN (type) = 1;
- gen_decl_die (TYPE_NAME (type), context_die);
+ gen_decl_die (TYPE_NAME (type), NULL, context_die);
return;
}
@@ -14858,7 +14869,6 @@ static void
gen_block_die (tree stmt, dw_die_ref context_die, int depth)
{
int must_output_die = 0;
- tree decl;
bool inlined_func;
/* Ignore blocks that are NULL. */
@@ -14893,21 +14903,16 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */
- must_output_die = (BLOCK_VARS (stmt) != NULL
+ must_output_die = ((BLOCK_VARS (stmt) != NULL
+ || BLOCK_NUM_NONLOCALIZED_VARS (stmt))
&& (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt)));
- else
- /* We are in terse mode, so only local (nested) function
- definitions count as "significant" local declarations. */
- for (decl = BLOCK_VARS (stmt);
- decl != NULL; decl = TREE_CHAIN (decl))
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_INITIAL (decl))
- {
- must_output_die = 1;
- break;
- }
+ else if ((TREE_USED (stmt)
+ || TREE_ASM_WRITTEN (stmt)
+ || BLOCK_ABSTRACT (stmt))
+ && !dwarf2out_ignore_block (stmt))
+ must_output_die = 1;
}
/* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
@@ -14928,6 +14933,35 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
decls_for_scope (stmt, context_die, depth);
}
+/* Process variable DECL (or variable with origin ORIGIN) within
+ block STMT and add it to CONTEXT_DIE. */
+static void
+process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
+{
+ dw_die_ref die;
+ tree decl_or_origin = decl ? decl : origin;
+ tree ultimate_origin = origin ? decl_ultimate_origin (origin) : NULL;
+
+ if (ultimate_origin)
+ origin = ultimate_origin;
+
+ if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
+ die = lookup_decl_die (decl_or_origin);
+ else if (TREE_CODE (decl_or_origin) == TYPE_DECL
+ && TYPE_DECL_IS_STUB (decl_or_origin))
+ die = lookup_type_die (TREE_TYPE (decl_or_origin));
+ else
+ die = NULL;
+
+ if (die != NULL && die->die_parent == NULL)
+ add_child_die (context_die, die);
+ else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
+ dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin),
+ stmt, context_die);
+ else
+ gen_decl_die (decl, origin, context_die);
+}
+
/* Generate all of the decls declared within a given scope and (recursively)
all of its sub-blocks. */
@@ -14935,38 +14969,22 @@ static void
decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
{
tree decl;
+ unsigned int i;
tree subblocks;
/* Ignore NULL blocks. */
if (stmt == NULL_TREE)
return;
- if (TREE_USED (stmt))
- {
- /* Output the DIEs to represent all of the data objects and typedefs
- declared directly within this block but not within any nested
- sub-blocks. Also, nested function and tag DIEs have been
- generated with a parent of NULL; fix that up now. */
- for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
- {
- dw_die_ref die;
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- die = lookup_decl_die (decl);
- else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
- die = lookup_type_die (TREE_TYPE (decl));
- else
- die = NULL;
-
- if (die != NULL && die->die_parent == NULL)
- add_child_die (context_die, die);
- else if (TREE_CODE (decl) == IMPORTED_DECL)
- dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
- stmt, context_die);
- else
- gen_decl_die (decl, context_die);
- }
- }
+ /* Output the DIEs to represent all of the data objects and typedefs
+ declared directly within this block but not within any nested
+ sub-blocks. Also, nested function and tag DIEs have been
+ generated with a parent of NULL; fix that up now. */
+ for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
+ process_scope_var (stmt, decl, NULL_TREE, context_die);
+ for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
+ process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i),
+ context_die);
/* If we're at -g1, we're not interested in subblocks. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
@@ -15049,7 +15067,7 @@ force_decl_die (tree decl)
gen_decl_die() call. */
saved_external_flag = DECL_EXTERNAL (decl);
DECL_EXTERNAL (decl) = 1;
- gen_decl_die (decl, context_die);
+ gen_decl_die (decl, NULL, context_die);
DECL_EXTERNAL (decl) = saved_external_flag;
break;
@@ -15132,7 +15150,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die)
if (is_fortran ())
return ns_context;
if (DECL_P (thing))
- gen_decl_die (thing, ns_context);
+ gen_decl_die (thing, NULL, ns_context);
else
gen_type_die (thing, ns_context);
}
@@ -15183,14 +15201,15 @@ gen_namespace_die (tree decl)
/* Generate Dwarf debug information for a decl described by DECL. */
static void
-gen_decl_die (tree decl, dw_die_ref context_die)
+gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
{
- tree origin;
+ tree decl_or_origin = decl ? decl : origin;
+ tree class_origin = NULL;
- if (DECL_P (decl) && DECL_IGNORED_P (decl))
+ if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
return;
- switch (TREE_CODE (decl))
+ switch (TREE_CODE (decl_or_origin))
{
case ERROR_MARK:
break;
@@ -15215,8 +15234,10 @@ gen_decl_die (tree decl, dw_die_ref context_die)
case FUNCTION_DECL:
/* Don't output any DIEs to represent mere function declarations,
unless they are class members or explicit block externs. */
- if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE
- && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
+ if (DECL_INITIAL (decl_or_origin) == NULL_TREE
+ && DECL_CONTEXT (decl_or_origin) == NULL_TREE
+ && (current_function_decl == NULL_TREE
+ || DECL_ARTIFICIAL (decl_or_origin)))
break;
#if 0
@@ -15228,8 +15249,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
#endif
/* If we're emitting a clone, emit info for the abstract instance. */
- if (DECL_ORIGIN (decl) != decl)
- dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl));
+ if (origin || DECL_ORIGIN (decl) != decl)
+ dwarf2out_abstract_function (origin ? origin : DECL_ABSTRACT_ORIGIN (decl));
/* If we're emitting an out-of-line copy of an inline function,
emit info for the abstract instance and set up to refer to it. */
@@ -15257,7 +15278,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
gen_type_die (DECL_CONTEXT (decl), context_die);
/* And its containing type. */
- origin = decl_class_context (decl);
+ if (!origin)
+ origin = decl_class_context (decl);
if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die);
@@ -15266,7 +15288,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
}
/* Now output a DIE to represent the function itself. */
- gen_subprogram_die (decl, context_die);
+ if (decl)
+ gen_subprogram_die (decl, context_die);
break;
case TYPE_DECL:
@@ -15309,28 +15332,30 @@ gen_decl_die (tree decl, dw_die_ref context_die)
/* Output any DIEs that are needed to specify the type of this data
object. */
- if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl))
- gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
+ if (TREE_CODE (decl_or_origin) == RESULT_DECL
+ && DECL_BY_REFERENCE (decl_or_origin))
+ gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else
- gen_type_die (TREE_TYPE (decl), context_die);
+ gen_type_die (TREE_TYPE (decl_or_origin), context_die);
/* And its containing type. */
- origin = decl_class_context (decl);
- if (origin != NULL_TREE)
- gen_type_die_for_member (origin, decl, context_die);
+ class_origin = decl_class_context (decl_or_origin);
+ if (class_origin != NULL_TREE)
+ gen_type_die_for_member (class_origin, decl_or_origin, context_die);
/* And its containing namespace. */
- context_die = declare_in_namespace (decl, context_die);
+ context_die = declare_in_namespace (decl_or_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
represents an inlined instance of a formal parameter for an inline
function. */
- origin = decl_ultimate_origin (decl);
+ if (!origin)
+ origin = decl_ultimate_origin (decl);
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
- gen_formal_parameter_die (decl, context_die);
+ gen_formal_parameter_die (decl, origin, context_die);
else
- gen_variable_die (decl, context_die);
+ gen_variable_die (decl, origin, context_die);
break;
case FIELD_DECL:
@@ -15346,11 +15371,11 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break;
case PARM_DECL:
- if (DECL_BY_REFERENCE (decl))
- gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
+ if (DECL_BY_REFERENCE (decl_or_origin))
+ gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else
- gen_type_die (TREE_TYPE (decl), context_die);
- gen_formal_parameter_die (decl, context_die);
+ gen_type_die (TREE_TYPE (decl_or_origin), context_die);
+ gen_formal_parameter_die (decl, origin, context_die);
break;
case NAMESPACE_DECL:
@@ -15641,7 +15666,7 @@ dwarf2out_decl (tree decl)
return;
}
- gen_decl_die (decl, context_die);
+ gen_decl_die (decl, NULL, context_die);
}
/* Output a marker (i.e. a label) for the beginning of the generated code for
@@ -15676,11 +15701,19 @@ static bool
dwarf2out_ignore_block (const_tree block)
{
tree decl;
+ unsigned int i;
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
return 0;
+ for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++)
+ {
+ decl = BLOCK_NONLOCALIZED_VAR (block, i);
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
+ return 0;
+ }
return 1;
}