dw2_asm_output_data (1, (cfi->dw_cfi_opc
| (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
"DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
- cfi->dw_cfi_oprnd1.dw_cfi_offset);
+ ((unsigned HOST_WIDE_INT)
+ cfi->dw_cfi_oprnd1.dw_cfi_offset));
else if (cfi->dw_cfi_opc == DW_CFA_offset)
{
r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
fde->dw_fde_cfi = NULL;
fde->funcdef_number = current_function_funcdef_no;
fde->nothrow = TREE_NOTHROW (current_function_decl);
- fde->uses_eh_lsda = cfun->uses_eh_lsda;
- fde->all_throwers_are_sibcalls = cfun->all_throwers_are_sibcalls;
+ fde->uses_eh_lsda = crtl->uses_eh_lsda;
+ fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
args_size = old_args_size = 0;
fde = &fde_table[fde_table_in_use - 1];
fde->dw_fde_switched_sections = true;
- 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;
+ fde->dw_fde_hot_section_label = crtl->subsections.hot_section_label;
+ fde->dw_fde_hot_section_end_label = crtl->subsections.hot_section_end_label;
+ fde->dw_fde_unlikely_section_label = crtl->subsections.cold_section_label;
+ fde->dw_fde_unlikely_section_end_label = crtl->subsections.cold_section_end_label;
have_multiple_function_sections = true;
/* Reset the current label on switching text sections, so that we
The children of each node form a circular list linked by
die_sib. die_child points to the node *before* the "first" child node. */
-typedef struct die_struct GTY(())
+typedef struct die_struct GTY((chain_circular ("%h.die_sib")))
{
enum dwarf_tag die_tag;
char *die_symbol;
current_line = 1;
if (cfun && in_cold_section_p)
- strcpy (prev_line_label, cfun->cold_section_label);
+ strcpy (prev_line_label, crtl->subsections.cold_section_label);
else
strcpy (prev_line_label, text_section_label);
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
if (DECL_THREAD_LOCAL_P (loc))
{
rtx rtl;
+ unsigned first_op;
+ unsigned second_op;
- /* If this is not defined, we have no way to emit the data. */
- if (!targetm.have_tls || !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. */
- if (DECL_EXTERNAL (loc))
- return 0;
-
+ if (targetm.have_tls)
+ {
+ /* If this is not defined, we have no way to emit the
+ data. */
+ 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. */
+ if (DECL_EXTERNAL (loc))
+ return 0;
+ first_op = INTERNAL_DW_OP_tls_addr;
+ second_op = DW_OP_GNU_push_tls_address;
+ }
+ else
+ {
+ if (!targetm.emutls.debug_form_tls_address)
+ return 0;
+ loc = emutls_decl (loc);
+ first_op = DW_OP_addr;
+ second_op = DW_OP_form_tls_address;
+ }
+
rtl = rtl_for_decl_location (loc);
if (rtl == NULL_RTX)
return 0;
if (! CONSTANT_P (rtl))
return 0;
- ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
+ ret = new_loc_descr (first_op, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
ret->dw_loc_oprnd1.v.val_addr = rtl;
-
- ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
+
+ ret1 = new_loc_descr (second_op, 0, 0);
add_loc_descr (&ret, ret1);
have_address = 1;
case COMPOUND_EXPR:
return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), want_address);
- case NOP_EXPR:
- case CONVERT_EXPR:
- case NON_LVALUE_EXPR:
+ CASE_CONVERT:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
case GIMPLE_MODIFY_STMT:
return rtl;
}
-/* This is a specialized subset of expand_expr to evaluate a DECL_VALUE_EXPR.
- We stop if we find decls that haven't been expanded, or if the expression is
- getting so complex we won't be able to represent it anyway. Returns NULL on
- failure. */
-
-static rtx
-dw_expand_expr (tree expr)
-{
- switch (TREE_CODE (expr))
- {
- case VAR_DECL:
- case PARM_DECL:
- if (DECL_HAS_VALUE_EXPR_P (expr))
- return dw_expand_expr (DECL_VALUE_EXPR (expr));
- /* FALLTHRU */
-
- case CONST_DECL:
- case RESULT_DECL:
- return DECL_RTL_IF_SET (expr);
-
- case INTEGER_CST:
- return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
-
- case COMPONENT_REF:
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- case BIT_FIELD_REF:
- {
- enum machine_mode mode;
- HOST_WIDE_INT bitsize, bitpos;
- tree offset, tem;
- int volatilep = 0, unsignedp = 0;
- rtx x;
-
- tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
- &mode, &unsignedp, &volatilep, true);
-
- x = dw_expand_expr (tem);
- if (x == NULL || !MEM_P (x))
- return NULL;
- if (offset != NULL)
- {
- if (!host_integerp (offset, 0))
- return NULL;
- x = adjust_address_nv (x, mode, tree_low_cst (offset, 0));
- }
- if (bitpos != 0)
- x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
-
- return x;
- }
-
- default:
- return NULL;
- }
-}
-
/* Generate RTL for the variable DECL to represent its location. */
static rtx
secname = TREE_STRING_POINTER (sectree);
}
else if (cfun && in_cold_section_p)
- secname = cfun->cold_section_label;
+ secname = crtl->subsections.cold_section_label;
else
secname = text_section_label;
If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
value is the offset into the common block for the symbol. */
-static rtx
-common_check (tree decl, HOST_WIDE_INT *value)
+static tree
+fortran_common (tree decl, HOST_WIDE_INT *value)
{
- rtx home;
- rtx sym_addr;
- rtx res = NULL_RTX;
-
+ tree val_expr, cvar;
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ tree offset;
+ int volatilep = 0, unsignedp = 0;
+
/* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
it does not have a value (the offset into the common area), or if it
is thread local (as opposed to global) then it isn't common, and shouldn't
be handled as such. */
if (TREE_CODE (decl) != VAR_DECL
- || !TREE_PUBLIC(decl)
- || !TREE_STATIC(decl)
- || !DECL_HAS_VALUE_EXPR_P(decl)
- || DECL_THREAD_LOCAL_P (decl)
- || !is_fortran())
- return NULL;
-
- home = DECL_RTL (decl);
- if (home == NULL_RTX || GET_CODE (home) != MEM)
- return NULL;
-
- sym_addr = dw_expand_expr (DECL_VALUE_EXPR (decl));
- if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
- return NULL;
+ || !TREE_PUBLIC (decl)
+ || !TREE_STATIC (decl)
+ || !DECL_HAS_VALUE_EXPR_P (decl)
+ || !is_fortran ())
+ return NULL_TREE;
- sym_addr = XEXP (sym_addr, 0);
- if (GET_CODE (sym_addr) == CONST)
- sym_addr = XEXP (sym_addr, 0);
- if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
- && DECL_INITIAL (decl) == 0)
- {
-
- /* We have a sym that will go into a common area, meaning that it
- will get storage reserved with a .comm/.lcomm assembler pseudo-op.
+ val_expr = DECL_VALUE_EXPR (decl);
+ if (TREE_CODE (val_expr) != COMPONENT_REF)
+ return NULL_TREE;
- Determine name of common area this symbol will be an offset into,
- and offset into that area. Also retrieve the decl for the area
- that the symbol is offset into. */
- tree cdecl = NULL;
+ cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, true);
- switch (GET_CODE (sym_addr))
- {
- case PLUS:
- if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT)
- {
- res = XEXP (sym_addr, 1);
- *value = INTVAL (XEXP (sym_addr, 0));
- cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
- }
- else
- {
- res = XEXP (sym_addr, 0);
- *value = INTVAL (XEXP (sym_addr, 1));
- cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
- }
- break;
-
- case SYMBOL_REF:
- res = sym_addr;
- *value = 0;
- cdecl = SYMBOL_REF_DECL (sym_addr);
- break;
-
- default:
- error ("common symbol debug info is not structured as "
- "symbol+offset");
- }
+ if (cvar == NULL_TREE
+ || TREE_CODE (cvar) != VAR_DECL
+ || DECL_ARTIFICIAL (cvar)
+ || !TREE_PUBLIC (cvar))
+ return NULL_TREE;
- /* Check area common symbol is offset into. If this is not public, then
- it is not a symbol in a common block. It must be a .lcomm symbol, not
- a .comm symbol. */
- if (cdecl == NULL || !TREE_PUBLIC(cdecl))
- res = NULL_RTX;
+ *value = 0;
+ if (offset != NULL)
+ {
+ if (!host_integerp (offset, 0))
+ return NULL_TREE;
+ *value = tree_low_cst (offset, 0);
}
- else
- res = NULL_RTX;
+ if (bitpos != 0)
+ *value += bitpos / BITS_PER_UNIT;
- return res;
+ return cvar;
}
add_AT_unsigned (subrange_die, bound_attr, tree_low_cst (bound, 0));
break;
- case CONVERT_EXPR:
- case NOP_EXPR:
- case NON_LVALUE_EXPR:
+ CASE_CONVERT:
case VIEW_CONVERT_EXPR:
add_bound_info (subrange_die, bound_attr, TREE_OPERAND (bound, 0));
break;
switch (TREE_CODE (val))
{
- case NOP_EXPR:
- case CONVERT_EXPR:
+ CASE_CONVERT:
return descr_info_loc (TREE_OPERAND (val, 0), base_decl);
case INTEGER_CST:
if (host_integerp (val, 0))
gen_variable_die (tree decl, dw_die_ref context_die)
{
HOST_WIDE_INT off;
- rtx csym;
+ tree com_decl;
dw_die_ref var_die;
tree origin = decl_ultimate_origin (decl);
dw_die_ref old_die = lookup_decl_die (decl);
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
|| class_or_namespace_scope_p (context_die));
- csym = common_check (decl, &off);
+ com_decl = fortran_common (decl, &off);
/* Symbol in common gets emitted as a child of the common block, in the form
of a data member.
??? This creates a new common block die for every common block symbol.
Better to share same common block die for all symbols in that block. */
- if (csym)
+ if (com_decl)
{
- tree blok;
+ tree field;
dw_die_ref com_die;
- const char *cnam = targetm.strip_name_encoding(XSTR (csym, 0));
- dw_loc_descr_ref loc = mem_loc_descriptor (csym, dw_val_class_addr,
- VAR_INIT_STATUS_INITIALIZED);
+ const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
+ dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
- blok = (tree) TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
+ field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
var_die = new_die (DW_TAG_common_block, context_die, decl);
- add_name_and_src_coords_attributes (var_die, blok);
+ add_name_and_src_coords_attributes (var_die, field);
add_AT_flag (var_die, DW_AT_external, 1);
add_AT_loc (var_die, DW_AT_location, loc);
com_die = new_die (DW_TAG_member, var_die, decl);
add_name_and_src_coords_attributes (com_die, decl);
add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
- TREE_THIS_VOLATILE (decl), context_die);
- add_AT_loc (com_die, DW_AT_data_member_location, int_loc_descriptor(off));
+ TREE_THIS_VOLATILE (decl), context_die);
+ add_AT_loc (com_die, DW_AT_data_member_location,
+ int_loc_descriptor (off));
add_pubname_string (cnam, var_die); /* ??? needed? */
return;
}
newloc->next = NULL;
if (cfun && in_cold_section_p)
- newloc->section_label = cfun->cold_section_label;
+ newloc->section_label = crtl->subsections.cold_section_label;
else
newloc->section_label = text_section_label;