You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* TODO: Emit .debug_line header even when there are no functions, since
the file numbers are used by .debug_info. Alternately, leave
#endif
}
+DEF_VEC_P(rtx);
+DEF_VEC_ALLOC_P(rtx,gc);
+
/* Array of RTXes referenced by the debugging information, which therefore
must be kept around forever. */
-static GTY(()) varray_type used_rtx_varray;
+static GTY(()) VEC(rtx,gc) *used_rtx_array;
/* A pointer to the base of a list of incomplete types which might be
- completed at some later time. incomplete_types_list needs to be a VARRAY
- because we want to tell the garbage collector about it. */
-static GTY(()) varray_type incomplete_types;
+ completed at some later time. incomplete_types_list needs to be a
+ VEC(tree,gc) because we want to tell the garbage collector about
+ it. */
+static GTY(()) VEC(tree,gc) *incomplete_types;
/* A pointer to the base of a table of references to declaration
scopes. This table is a display which tracks the nesting
of declaration scopes at the current scope and containing
scopes. This table is used to find the proper place to
define type declaration DIE's. */
-static GTY(()) varray_type decl_scope_table;
+static GTY(()) VEC(tree,gc) *decl_scope_table;
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
if (offset < 0)
continue;
- emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+ emit_move_insn (adjust_address (mem, mode, offset),
+ gen_int_mode (size, mode));
}
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
src = SET_SRC (expr);
dest = SET_DEST (expr);
- if (GET_CODE (src) == REG)
+ if (REG_P (src))
{
rtx rsi = reg_saved_in (src);
if (rsi)
int fde_encoding = DW_EH_PE_absptr;
int per_encoding = DW_EH_PE_absptr;
int lsda_encoding = DW_EH_PE_absptr;
+ int return_reg;
/* Don't emit a CIE if there won't be any FDEs. */
if (fde_table_in_use == 0)
dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT,
"CIE Data Alignment Factor");
+ return_reg = DWARF2_FRAME_REG_OUT (DWARF_FRAME_RETURN_COLUMN, for_eh);
if (DW_CIE_VERSION == 1)
- dw2_asm_output_data (1, DWARF_FRAME_RETURN_COLUMN, "CIE RA Column");
+ dw2_asm_output_data (1, return_reg, "CIE RA Column");
else
- dw2_asm_output_data_uleb128 (DWARF_FRAME_RETURN_COLUMN, "CIE RA Column");
+ dw2_asm_output_data_uleb128 (return_reg, "CIE RA Column");
if (augmentation[0])
{
return descr;
}
-
/* Add a location description term to a location description expression. */
static inline void
break;
case INTERNAL_DW_OP_tls_addr:
-#ifdef ASM_OUTPUT_DWARF_DTPREL
- ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
- val1->v.val_addr);
- fputc ('\n', asm_out_file);
-#else
- gcc_unreachable ();
-#endif
+ if (targetm.asm_out.output_dwarf_dtprel)
+ {
+ targetm.asm_out.output_dwarf_dtprel (asm_out_file,
+ DWARF2_ADDR_SIZE,
+ val1->v.val_addr);
+ fputc ('\n', asm_out_file);
+ }
+ else
+ gcc_unreachable ();
break;
default:
cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned;
break;
default:
- internal_error ("DW_LOC_OP %s not implemented\n",
+ internal_error ("DW_LOC_OP %s not implemented",
dwarf_stack_op_name (ptr->dw_loc_opc));
}
}
static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
static int type_is_enum (tree);
static unsigned int dbx_reg_number (rtx);
+static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
static dw_loc_descr_ref reg_loc_descriptor (rtx);
static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
#ifndef TEXT_SECTION_LABEL
#define TEXT_SECTION_LABEL "Ltext"
#endif
+#ifndef COLD_TEXT_SECTION_LABEL
+#define COLD_TEXT_SECTION_LABEL "Ltext_cold"
+#endif
#ifndef DEBUG_LINE_SECTION_LABEL
#define DEBUG_LINE_SECTION_LABEL "Ldebug_line"
#endif
static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char cold_text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char cold_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
#ifndef TEXT_END_LABEL
#define TEXT_END_LABEL "Letext"
#endif
+#ifndef COLD_END_LABEL
+#define COLD_END_LABEL "Letext_cold"
+#endif
#ifndef BLOCK_BEGIN_LABEL
#define BLOCK_BEGIN_LABEL "LBB"
#endif
static tree
decl_ultimate_origin (tree decl)
{
+ if (!CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_COMMON))
+ return NULL_TREE;
+
/* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
nodes in the function to point to themselves; ignore that if
we're trying to output the abstract instance of this function. */
{
dw_fde_ref fde;
+ gcc_assert (cfun);
+
fde = &fde_table[fde_table_in_use - 1];
fde->dw_fde_switched_sections = true;
- fde->dw_fde_hot_section_label = xstrdup (hot_section_label);
- fde->dw_fde_hot_section_end_label = xstrdup (hot_section_end_label);
- fde->dw_fde_unlikely_section_label = xstrdup (unlikely_section_label);
- fde->dw_fde_unlikely_section_end_label = xstrdup (cold_section_end_label);
+ fde->dw_fde_hot_section_label = cfun->hot_section_label;
+ fde->dw_fde_hot_section_end_label = cfun->hot_section_end_label;
+ fde->dw_fde_unlikely_section_label = cfun->cold_section_label;
+ fde->dw_fde_unlikely_section_end_label = cfun->cold_section_end_label;
separate_line_info_table_in_use++;
}
}
dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address");
- if (last_text_section == in_unlikely_executed_text
- || (last_text_section == in_named
- && last_text_section_name == unlikely_text_section_name))
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
- unlikely_section_label, "Length");
- else
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
- text_section_label, "Length");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
+ text_section_label, "Length");
+ if (flag_reorder_blocks_and_partition)
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, cold_text_section_label,
+ "Address");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
+ cold_text_section_label, "Length");
+ }
for (i = 0; i < arange_table_in_use; i++)
{
base of the text section. */
if (separate_line_info_table_in_use == 0)
{
- if (last_text_section == in_unlikely_executed_text
- || (last_text_section == in_named
- && last_text_section_name == unlikely_text_section_name))
- {
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
- unlikely_section_label,
- fmt, i * 2 * DWARF2_ADDR_SIZE);
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
- unlikely_section_label, NULL);
- }
- else
- {
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
- text_section_label,
- fmt, i * 2 * DWARF2_ADDR_SIZE);
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
- text_section_label, NULL);
- }
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
+ text_section_label,
+ fmt, i * 2 * DWARF2_ADDR_SIZE);
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
+ text_section_label, NULL);
}
/* Otherwise, we add a DW_AT_entry_pc attribute to force the
a series of state machine operations. */
current_file = 1;
current_line = 1;
- if (last_text_section == in_unlikely_executed_text
- || (last_text_section == in_named
- && last_text_section_name == unlikely_text_section_name))
- strcpy (prev_line_label, unlikely_section_label);
+
+ if (cfun
+ && (last_text_section == in_unlikely_executed_text
+ || (last_text_section == in_named
+ && last_text_section_name == cfun->unlikely_text_section_name)))
+ strcpy (prev_line_label, cfun->cold_section_label);
else
strcpy (prev_line_label, text_section_label);
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
return DBX_REGISTER_NUMBER (regno);
}
+/* Optionally add a DW_OP_piece term to a location description expression.
+ DW_OP_piece is only added if the location description expression already
+ doesn't end with DW_OP_piece. */
+
+static void
+add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
+{
+ dw_loc_descr_ref loc;
+
+ if (*list_head != NULL)
+ {
+ /* Find the end of the chain. */
+ for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
+ ;
+
+ if (loc->dw_loc_opc != DW_OP_piece)
+ loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
+ }
+}
+
/* Return a location descriptor that designates a machine register or
zero if there is none. */
t = one_reg_loc_descriptor (reg);
add_loc_descr (&loc_result, t);
- add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ add_loc_descr_op_piece (&loc_result, size);
++reg;
}
return loc_result;
t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
add_loc_descr (&loc_result, t);
size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
- add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ add_loc_descr_op_piece (&loc_result, size);
}
return loc_result;
}
mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl;
- VARRAY_PUSH_RTX (used_rtx_varray, rtl);
+ VEC_safe_push (rtx, gc, used_rtx_array, rtl);
break;
case PRE_MODIFY:
return 0;
cc_loc_result = x0_ref;
- add_loc_descr (&cc_loc_result,
- new_loc_descr (DW_OP_piece,
- GET_MODE_SIZE (GET_MODE (x0)), 0));
+ add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x0)));
add_loc_descr (&cc_loc_result, x1_ref);
- add_loc_descr (&cc_loc_result,
- new_loc_descr (DW_OP_piece,
- GET_MODE_SIZE (GET_MODE (x1)), 0));
+ add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
return cc_loc_result;
}
loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
can_use_fbreg);
mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
- add_loc_descr (&loc_result,
- new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
+ add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
for (i = 1; i < num_elem; i++)
{
dw_loc_descr_ref temp;
can_use_fbreg);
add_loc_descr (&loc_result, temp);
mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
- add_loc_descr (&loc_result,
- new_loc_descr (DW_OP_piece,
- GET_MODE_SIZE (mode), 0));
+ add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
}
}
break;
return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 1);
case VAR_DECL:
- if (DECL_THREAD_LOCAL (loc))
+ if (DECL_THREAD_LOCAL_P (loc))
{
rtx rtl;
-#ifndef ASM_OUTPUT_DWARF_DTPREL
/* If this is not defined, we have no way to emit the data. */
- return 0;
-#endif
+ if (!targetm.asm_out.output_dwarf_dtprel)
+ return 0;
/* The way DW_OP_GNU_push_tls_address is specified, we can only
look up addresses of objects in the current module. */
/* FALLTHRU */
case PARM_DECL:
- if (DECL_VALUE_EXPR (loc))
- return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc), want_address);
+ if (DECL_HAS_VALUE_EXPR_P (loc))
+ return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc),
+ want_address);
/* FALLTHRU */
case RESULT_DECL:
#ifdef ENABLE_CHECKING
/* Otherwise this is a generic code; we should just lists all of
- these explicitly. Aborting means we forgot one. */
+ these explicitly. We forgot one. */
gcc_unreachable ();
#else
/* In a release build, we want to degrade gracefully: better to
case LABEL_REF:
case CONST:
add_AT_addr (die, DW_AT_const_value, rtl);
- VARRAY_PUSH_RTX (used_rtx_varray, rtl);
+ VEC_safe_push (rtx, gc, used_rtx_array, rtl);
break;
case PLUS:
dw_loc_list_ref list;
rtx varloc;
-
/* We need to figure out what section we should use as the base
for the address ranges where a given location is valid.
1. If this particular DECL has a section associated with it,
XXX: If you split a variable across multiple sections, this
won't notice. */
- if (DECL_SECTION_NAME (decl))
+ if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_SECTION_NAME (decl))
{
tree sectree = DECL_SECTION_NAME (decl);
secname = TREE_STRING_POINTER (sectree);
tree sectree = DECL_SECTION_NAME (current_function_decl);
secname = TREE_STRING_POINTER (sectree);
}
- else if (last_text_section == in_unlikely_executed_text
- || (last_text_section == in_named
- && last_text_section_name == unlikely_text_section_name))
- secname = unlikely_section_label;
+ else if (cfun
+ && (last_text_section == in_unlikely_executed_text
+ || (last_text_section == in_named
+ && last_text_section_name ==
+ cfun->unlikely_text_section_name)))
+ secname = cfun->cold_section_label;
else
secname = text_section_label;
if (TYPE_P (fn))
fn = TYPE_STUB_DECL (fn);
- /* TYPE_STUB_DECL may have given us a NULL, which decl_function_context
- won't like. */
- if (fn)
- fn = decl_function_context (fn);
-
+ fn = decl_function_context (fn);
if (fn)
dwarf2out_abstract_function (fn);
}
trees (in the case of java, they simply have no block tree, in some other
languages). For these functions, there is nothing we can really do to
output correct debug info for inlined functions in all cases. Rather
- than abort, we'll just produce deficient debug info now, in that we will
+ than die, we'll just produce deficient debug info now, in that we will
have variables without a proper abstract origin. In the future, when all
functions are lowered, we should re-add a gcc_assert (origin_die)
here. */
{
add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address,
XEXP (DECL_RTL (decl), 0));
- VARRAY_PUSH_RTX (used_rtx_varray, XEXP (DECL_RTL (decl), 0));
+ VEC_safe_push (tree, gc, used_rtx_array, XEXP (DECL_RTL (decl), 0));
}
#endif
}
static void
push_decl_scope (tree scope)
{
- VARRAY_PUSH_TREE (decl_scope_table, scope);
+ VEC_safe_push (tree, gc, decl_scope_table, scope);
}
/* Pop a declaration scope. */
static inline void
pop_decl_scope (void)
{
- gcc_assert (VARRAY_ACTIVE_SIZE (decl_scope_table) > 0);
-
- VARRAY_POP (decl_scope_table);
+ VEC_pop (tree, decl_scope_table);
}
/* Return the DIE for the scope that immediately contains this type.
/* For types, we can just look up the appropriate DIE. But
first we check to see if we're in the middle of emitting it
so we know where the new DIE should go. */
- for (i = VARRAY_ACTIVE_SIZE (decl_scope_table) - 1; i >= 0; --i)
- if (VARRAY_TREE (decl_scope_table, i) == containing_scope)
+ for (i = VEC_length (tree, decl_scope_table) - 1; i >= 0; --i)
+ if (VEC_index (tree, decl_scope_table, i) == containing_scope)
break;
if (i < 0)
{
int i;
- for (i = VARRAY_ACTIVE_SIZE (incomplete_types) - 1; i >= 0; i--)
- gen_type_die (VARRAY_TREE (incomplete_types, i), comp_unit_die);
+ for (i = VEC_length (tree, incomplete_types) - 1; i >= 0; i--)
+ gen_type_die (VEC_index (tree, incomplete_types, i), comp_unit_die);
}
/* Generate a DIE to represent an inlined instance of an enumeration type. */
if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
&& ! lookup_decl_die (member))
{
+ dw_die_ref type_die;
gcc_assert (!decl_ultimate_origin (member));
push_decl_scope (type);
+ type_die = lookup_type_die (type);
if (TREE_CODE (member) == FUNCTION_DECL)
- gen_subprogram_die (member, lookup_type_die (type));
+ gen_subprogram_die (member, type_die);
+ else if (TREE_CODE (member) == FIELD_DECL)
+ {
+ /* Ignore the nameless fields that are used to skip bits but handle
+ C++ anonymous unions and structs. */
+ if (DECL_NAME (member) != NULL_TREE
+ || TREE_CODE (TREE_TYPE (member)) == UNION_TYPE
+ || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)
+ {
+ gen_type_die (member_declared_type (member), type_die);
+ gen_field_die (member, type_die);
+ }
+ }
else
- gen_variable_die (member, lookup_type_die (type));
+ gen_variable_die (member, type_die);
pop_decl_scope ();
}
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl)
+ /* If DECL is COMDAT and has not actually been
+ emitted, we cannot take its address; there
+ might end up being no definition anywhere in
+ the program. For example, consider the C++
+ test case:
+
+ template <class T>
+ struct S { static const int i = 7; };
+
+ template <class T>
+ const int S<T>::i;
+
+ int f() { return S<int>::i; }
+
+ 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))
|| class_or_namespace_scope_p (context_die));
if (origin != NULL)
copy decls and set the DECL_ABSTRACT flag on them instead of
sharing them.
- ??? Duplicated blocks have been rewritten to use .debug_ranges. */
- else if (old_die && TREE_STATIC (decl)
+ ??? Duplicated blocks have been rewritten to use .debug_ranges.
+
+ ??? The declare_in_namespace support causes us to get two DIEs for one
+ variable, both of which are declarations. We want to avoid considering
+ one to be a specification, so we must test that this DIE is not a
+ declaration. */
+ else if (old_die && TREE_STATIC (decl) && ! declaration
&& get_AT_flag (old_die, DW_AT_declaration) == 1)
{
/* This is a definition of a C++ class level static. */
}
}
+/* A helper function for gen_inlined_subroutine_die. Add source coordinate
+ attributes to the DIE for a block STMT, to describe where the inlined
+ function was called from. This is similar to add_src_coords_attributes. */
+
+static inline void
+add_call_src_coords_attributes (tree stmt, dw_die_ref die)
+{
+ expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt));
+ unsigned file_index = lookup_filename (s.file);
+
+ add_AT_unsigned (die, DW_AT_call_file, file_index);
+ add_AT_unsigned (die, DW_AT_call_line, s.line);
+}
+
/* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
Add low_pc and high_pc attributes to the DIE for a block STMT. */
add_abstract_origin_attribute (subr_die, decl);
add_high_low_attributes (stmt, subr_die);
+ add_call_src_coords_attributes (stmt, subr_die);
decls_for_scope (stmt, subr_die, depth);
current_function_has_inlines = 1;
/* First output info about the base classes. */
if (binfo)
{
- VEC (tree) *accesses = BINFO_BASE_ACCESSES (binfo);
+ VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (binfo);
int i;
tree base;
/* We don't need to do this for function-local types. */
if (TYPE_STUB_DECL (type)
&& ! decl_function_context (TYPE_STUB_DECL (type)))
- VARRAY_PUSH_TREE (incomplete_types, type);
+ VEC_safe_push (tree, gc, incomplete_types, type);
}
}
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
+ /* Do not produce debug information for static variables since
+ these might be optimized out. We are called for these later
+ in cgraph_varpool_analyze_pending_decls. */
+ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ ;
else
gen_decl_die (decl, context_die);
}
return 0;
}
-/* Returns the DIE for decl or aborts. */
+/* Returns the DIE for decl. A DIE will always be returned. */
static dw_die_ref
force_decl_die (tree decl)
gcc_unreachable ();
}
- /* See if we can find the die for this deci now.
- If not then abort. */
+ /* We should be able to find the DIE now. */
if (!decl_die)
decl_die = lookup_decl_die (decl);
gcc_assert (decl_die);
return decl_die;
}
-/* Returns the DIE for decl or aborts. */
+/* Returns the DIE for TYPE. A DIE is always returned. */
static dw_die_ref
force_type_die (tree type)
if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
at_import_die = force_type_die (TREE_TYPE (decl));
else
- at_import_die = force_decl_die (decl);
+ {
+ at_import_die = lookup_decl_die (decl);
+ if (!at_import_die)
+ {
+ /* If we're trying to avoid duplicate debug info, we may not have
+ emitted the member decl for this field. Emit it now. */
+ if (TREE_CODE (decl) == FIELD_DECL)
+ {
+ tree type = DECL_CONTEXT (decl);
+ dw_die_ref type_context_die;
+
+ if (TYPE_CONTEXT (type))
+ if (TYPE_P (TYPE_CONTEXT (type)))
+ type_context_die = force_type_die (TYPE_CONTEXT (type));
+ else
+ type_context_die = force_decl_die (TYPE_CONTEXT (type));
+ else
+ type_context_die = comp_unit_die;
+ gen_type_die_for_member (type, decl, type_context_die);
+ }
+ at_import_die = force_decl_die (decl);
+ }
+ }
/* OK, now we have DIEs for decl as well as scope. Emit imported die. */
if (TREE_CODE (decl) == NAMESPACE_DECL)
if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
return;
+ /* For local statics lookup proper context die. */
+ if (TREE_STATIC (decl) && decl_function_context (decl))
+ context_die = lookup_decl_die (DECL_CONTEXT (decl));
+
/* If we are in terse mode, don't generate any DIEs to represent any
variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
VARRAY_PUSH_CHAR_PTR (file_table, save_file_name);
VARRAY_PUSH_UINT (file_table_emitted, 0);
+ /* If the assembler is emitting the file table, and we aren't eliminating
+ unused debug types, then we must emit .file here. If we are eliminating
+ unused debug types, then this will be done by the maybe_emit_file call in
+ prune_unused_types_walk_attribs. */
+
+ if (DWARF2_ASM_LINE_DEBUG_INFO && ! flag_eliminate_unused_debug_types)
+ maybe_emit_file (i);
+
return i;
}
+/* If the assembler will construct the file table, then translate the compiler
+ internal file table number into the assembler file table number, and emit
+ a .file directive if we haven't already emitted one yet. The file table
+ numbers are different because we prune debug info for unused variables and
+ types, which may include filenames. */
+
static int
maybe_emit_file (int fileno)
{
return fileno;
}
+/* Initialize the compiler internal file table. */
+
static void
init_file_table (void)
{
newloc->var_loc_note = loc_note;
newloc->next = NULL;
- if (last_text_section == in_unlikely_executed_text
- || (last_text_section == in_named
- && last_text_section_name == unlikely_text_section_name))
- newloc->section_label = unlikely_section_label;
+ if (cfun
+ && (last_text_section == in_unlikely_executed_text
+ || (last_text_section == in_named
+ && last_text_section_name == cfun->unlikely_text_section_name)))
+ newloc->section_label = cfun->cold_section_label;
else
newloc->section_label = text_section_label;
last_insn = loc_note;
last_label = newloc->label;
decl = NOTE_VAR_LOCATION_DECL (loc_note);
- if (DECL_DEBUG_EXPR (decl) && DECL_DEBUG_EXPR_IS_FROM (decl)
+ if (DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
&& DECL_P (DECL_DEBUG_EXPR (decl)))
decl = DECL_DEBUG_EXPR (decl);
add_var_loc_to_decl (decl, newloc);
decl_loc_table_eq, NULL);
/* Allocate the initial hunk of the decl_scope_table. */
- VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
+ decl_scope_table = VEC_alloc (tree, gc, 256);
/* Allocate the initial hunk of the abbrev_die_table. */
abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT
in this value in dwarf2out_finish. */
comp_unit_die = gen_compile_unit_die (NULL);
- VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
+ incomplete_types = VEC_alloc (tree, gc, 64);
- VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
+ used_rtx_array = VEC_alloc (rtx, gc, 32);
ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
DEBUG_ABBREV_SECTION_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (cold_text_section_label,
+ COLD_TEXT_SECTION_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
DEBUG_INFO_SECTION_LABEL, 0);
text_section ();
ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
+ if (flag_reorder_blocks_and_partition)
+ {
+ unlikely_text_section ();
+ ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label);
+ }
}
/* A helper function for dwarf2out_finish called through
Make sure that it will get emitted. */
prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
}
- else if (a->dw_attr == DW_AT_decl_file)
+ else if (a->dw_attr == DW_AT_decl_file || a->dw_attr == DW_AT_call_file)
{
/* A reference to a file. Make sure the file name is emitted. */
a->dw_attr_val.v.val_unsigned =
/* Output a terminator label for the .text section. */
text_section ();
targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
+ if (flag_reorder_blocks_and_partition)
+ {
+ unlikely_text_section ();
+ targetm.asm_out.internal_label (asm_out_file, COLD_END_LABEL, 0);
+ }
/* Output the source line correspondence table. We must do this
even if there is no line information. Otherwise, on an empty