diff options
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 557d27f57c5..b18e2e31ce2 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -375,7 +375,7 @@ static unsigned current_funcdef_fde; struct GTY(()) indirect_string_node { const char *str; unsigned int refcount; - unsigned int form; + enum dwarf_form form; char *label; }; @@ -3851,18 +3851,11 @@ new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1, static inline dw_loc_descr_ref new_reg_loc_descr (unsigned int reg, unsigned HOST_WIDE_INT offset) { - if (offset) - { - if (reg <= 31) - return new_loc_descr ((enum dwarf_location_atom) (DW_OP_breg0 + reg), - offset, 0); - else - return new_loc_descr (DW_OP_bregx, reg, offset); - } - else if (reg <= 31) - return new_loc_descr ((enum dwarf_location_atom) (DW_OP_reg0 + reg), 0, 0); + if (reg <= 31) + return new_loc_descr ((enum dwarf_location_atom) (DW_OP_breg0 + reg), + offset, 0); else - return new_loc_descr (DW_OP_regx, reg, 0); + return new_loc_descr (DW_OP_bregx, reg, offset); } /* Add a location description term to a location description expression. */ @@ -4995,7 +4988,7 @@ static hashval_t debug_str_do_hash (const void *); static int debug_str_eq (const void *, const void *); static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *); static inline const char *AT_string (dw_attr_ref); -static int AT_string_form (dw_attr_ref); +static enum dwarf_form AT_string_form (dw_attr_ref); static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref); static void add_AT_specification (dw_die_ref, dw_die_ref); static inline dw_die_ref AT_ref (dw_attr_ref); @@ -6001,7 +5994,7 @@ AT_string (dw_attr_ref a) /* Find out whether a string should be output inline in DIE or out-of-line in .debug_str section. */ -static int +static enum dwarf_form AT_string_form (dw_attr_ref a) { struct indirect_string_node *node; @@ -9702,7 +9695,13 @@ reg_loc_descriptor (rtx rtl, enum var_init_status initialized) static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized) { - dw_loc_descr_ref reg_loc_descr = new_reg_loc_descr (regno, 0); + dw_loc_descr_ref reg_loc_descr; + + if (regno <= 31) + reg_loc_descr + = new_loc_descr ((enum dwarf_location_atom) (DW_OP_reg0 + regno), 0, 0); + else + reg_loc_descr = new_loc_descr (DW_OP_regx, regno, 0); if (initialized == VAR_INIT_STATUS_UNINITIALIZED) add_loc_descr (®_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0)); @@ -11715,10 +11714,35 @@ loc_by_reference (dw_loc_descr_ref loc, tree decl) if ((TREE_CODE (decl) != PARM_DECL && TREE_CODE (decl) != RESULT_DECL - && (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))) + && TREE_CODE (decl) != VAR_DECL) || !DECL_BY_REFERENCE (decl)) return loc; + /* If loc is DW_OP_reg{0...31,x}, don't add DW_OP_deref, instead + change it into corresponding DW_OP_breg{0...31,x} 0. Then the + location expression is considered to be address of a memory location, + rather than the register itself. */ + if (((loc->dw_loc_opc >= DW_OP_reg0 && loc->dw_loc_opc <= DW_OP_reg31) + || loc->dw_loc_opc == DW_OP_regx) + && (loc->dw_loc_next == NULL + || (loc->dw_loc_next->dw_loc_opc == DW_OP_GNU_uninit + && loc->dw_loc_next->dw_loc_next == NULL))) + { + if (loc->dw_loc_opc == DW_OP_regx) + { + loc->dw_loc_opc = DW_OP_bregx; + loc->dw_loc_oprnd2.v.val_int = 0; + } + else + { + loc->dw_loc_opc + = (enum dwarf_location_atom) + (loc->dw_loc_opc + (DW_OP_breg0 - DW_OP_reg0)); + loc->dw_loc_oprnd1.v.val_int = 0; + } + return loc; + } + size = int_size_in_bytes (TREE_TYPE (decl)); if (size > DWARF2_ADDR_SIZE || size == -1) return 0; @@ -14048,19 +14072,13 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) else { tree type = TREE_TYPE (decl); - bool private_flag_valid = true; add_name_and_src_coords_attributes (var_die, decl); if ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL - || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))) + || TREE_CODE (decl) == VAR_DECL) && DECL_BY_REFERENCE (decl)) - { - add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die); - /* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE, - for PARM_DECL, RESULT_DECL or non-static VAR_DECL. */ - private_flag_valid = false; - } + add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die); else add_type_attribute (var_die, type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl), context_die); @@ -14073,7 +14091,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) if (TREE_PROTECTED (decl)) add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected); - else if (private_flag_valid && TREE_PRIVATE (decl)) + else if (TREE_PRIVATE (decl)) add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private); } @@ -15307,8 +15325,7 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die) /* Output any DIEs that are needed to specify the type of this data object. */ if ((TREE_CODE (decl_or_origin) == RESULT_DECL - || (TREE_CODE (decl_or_origin) == VAR_DECL - && !TREE_STATIC (decl_or_origin))) + || TREE_CODE (decl_or_origin) == VAR_DECL) && DECL_BY_REFERENCE (decl_or_origin)) gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die); else |