X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdwarf2out.c;h=d3de6e6afc68af6d8db44c999851fff3ad678d25;hb=cfaf579ddfaec5cb9bc5d220eadd212786138f3d;hp=e39e687edbbe44cadb89a5009188f132b6ec093c;hpb=d6d5e57f3996957205e6edf1787a67c2548af76a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e39e687edbb..d3de6e6afc6 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1,6 +1,6 @@ /* Output Dwarf2 format symbol table information from GCC. Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Gary Funck (gary@intrepid.com). Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com). Extensively modified by Jason Merrill (jason@cygnus.com). @@ -110,6 +110,9 @@ static void dwarf2out_source_line (unsigned int, const char *); #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO) #endif +/* Save the result of dwarf2out_do_frame across PCH. */ +static GTY(()) bool saved_do_cfi_asm = 0; + /* Decide whether we want to emit frame unwind information for the current translation unit. */ @@ -121,7 +124,7 @@ dwarf2out_do_frame (void) we're not going to output frame or unwind info. */ return (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG - || DWARF2_FRAME_INFO + || DWARF2_FRAME_INFO || saved_do_cfi_asm #ifdef DWARF2_UNWIND_INFO || (DWARF2_UNWIND_INFO && (flag_unwind_tables @@ -142,7 +145,7 @@ dwarf2out_do_cfi_asm (void) #endif if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ()) return false; - if (!eh_personality_libfunc) + if (saved_do_cfi_asm || !eh_personality_libfunc) return true; if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE) return false; @@ -156,6 +159,7 @@ dwarf2out_do_cfi_asm (void) if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel) return false; + saved_do_cfi_asm = true; return true; } @@ -411,7 +415,8 @@ static void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT); #ifdef DWARF2_UNWIND_INFO static void initial_return_save (rtx); #endif -static HOST_WIDE_INT stack_adjust_offset (const_rtx); +static HOST_WIDE_INT stack_adjust_offset (const_rtx, HOST_WIDE_INT, + HOST_WIDE_INT); static void output_cfi (dw_cfi_ref, dw_fde_ref, int); static void output_cfi_directive (dw_cfi_ref); static void output_call_frame_info (int); @@ -1110,7 +1115,8 @@ initial_return_save (rtx rtl) contains. */ static HOST_WIDE_INT -stack_adjust_offset (const_rtx pattern) +stack_adjust_offset (const_rtx pattern, HOST_WIDE_INT cur_args_size, + HOST_WIDE_INT cur_offset) { const_rtx src = SET_SRC (pattern); const_rtx dest = SET_DEST (pattern); @@ -1119,18 +1125,34 @@ stack_adjust_offset (const_rtx pattern) if (dest == stack_pointer_rtx) { - /* (set (reg sp) (plus (reg sp) (const_int))) */ code = GET_CODE (src); + + /* Assume (set (reg sp) (reg whatever)) sets args_size + level to 0. */ + if (code == REG && src != stack_pointer_rtx) + { + offset = -cur_args_size; +#ifndef STACK_GROWS_DOWNWARD + offset = -offset; +#endif + return offset - cur_offset; + } + if (! (code == PLUS || code == MINUS) || XEXP (src, 0) != stack_pointer_rtx || GET_CODE (XEXP (src, 1)) != CONST_INT) return 0; + /* (set (reg sp) (plus (reg sp) (const_int))) */ offset = INTVAL (XEXP (src, 1)); if (code == PLUS) offset = -offset; + return offset; } - else if (MEM_P (dest)) + + if (MEM_P (src) && !MEM_P (dest)) + dest = src; + if (MEM_P (dest)) { /* (set (mem (pre_dec (reg sp))) (foo)) */ src = XEXP (dest, 0); @@ -1199,7 +1221,7 @@ compute_barrier_args_size_1 (rtx insn, HOST_WIDE_INT cur_args_size, || sibcall_epilogue_contains (insn)) /* Nothing */; else if (GET_CODE (PATTERN (insn)) == SET) - offset = stack_adjust_offset (PATTERN (insn)); + offset = stack_adjust_offset (PATTERN (insn), cur_args_size, 0); else if (GET_CODE (PATTERN (insn)) == PARALLEL || GET_CODE (PATTERN (insn)) == SEQUENCE) { @@ -1207,7 +1229,8 @@ compute_barrier_args_size_1 (rtx insn, HOST_WIDE_INT cur_args_size, for them. */ for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) - offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i)); + offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i), + cur_args_size, offset); } } else @@ -1224,7 +1247,7 @@ compute_barrier_args_size_1 (rtx insn, HOST_WIDE_INT cur_args_size, rtx elem = XVECEXP (expr, 0, i); if (GET_CODE (elem) == SET && !RTX_FRAME_RELATED_P (elem)) - offset += stack_adjust_offset (elem); + offset += stack_adjust_offset (elem, cur_args_size, offset); } } } @@ -1312,13 +1335,25 @@ compute_barrier_args_size (void) body = PATTERN (insn); if (GET_CODE (body) == SEQUENCE) { + HOST_WIDE_INT dest_args_size = cur_args_size; for (i = 1; i < XVECLEN (body, 0); i++) + if (INSN_ANNULLED_BRANCH_P (XVECEXP (body, 0, 0)) + && INSN_FROM_TARGET_P (XVECEXP (body, 0, i))) + dest_args_size + = compute_barrier_args_size_1 (XVECEXP (body, 0, i), + dest_args_size, &next); + else + cur_args_size + = compute_barrier_args_size_1 (XVECEXP (body, 0, i), + cur_args_size, &next); + + if (INSN_ANNULLED_BRANCH_P (XVECEXP (body, 0, 0))) + compute_barrier_args_size_1 (XVECEXP (body, 0, 0), + dest_args_size, &next); + else cur_args_size - = compute_barrier_args_size_1 (XVECEXP (body, 0, i), + = compute_barrier_args_size_1 (XVECEXP (body, 0, 0), cur_args_size, &next); - cur_args_size - = compute_barrier_args_size_1 (XVECEXP (body, 0, 0), - cur_args_size, &next); } else cur_args_size @@ -1359,6 +1394,14 @@ dwarf2out_stack_adjust (rtx insn, bool after_p) if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn)) return; + /* If INSN is an instruction from target of an annulled branch, the + effects are for the target only and so current argument size + shouldn't change at all. */ + if (final_sequence + && INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)) + && INSN_FROM_TARGET_P (insn)) + return; + /* If only calls can throw, and we have a frame pointer, save up adjustments until we see the CALL_INSN. */ if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM) @@ -1404,7 +1447,7 @@ dwarf2out_stack_adjust (rtx insn, bool after_p) #endif } else if (GET_CODE (PATTERN (insn)) == SET) - offset = stack_adjust_offset (PATTERN (insn)); + offset = stack_adjust_offset (PATTERN (insn), args_size, 0); else if (GET_CODE (PATTERN (insn)) == PARALLEL || GET_CODE (PATTERN (insn)) == SEQUENCE) { @@ -1412,7 +1455,8 @@ dwarf2out_stack_adjust (rtx insn, bool after_p) for them. */ for (offset = 0, i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) - offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i)); + offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i), + args_size, offset); } else return; @@ -1871,7 +1915,7 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) { /* Stack adjustment combining might combine some post-prologue stack adjustment into a prologue stack adjustment. */ - HOST_WIDE_INT offset = stack_adjust_offset (elem); + HOST_WIDE_INT offset = stack_adjust_offset (elem, args_size, 0); if (offset != 0) dwarf2out_args_size_adjust (offset, label); @@ -4489,6 +4533,8 @@ static bool dwarf2out_ignore_block (const_tree); static void dwarf2out_global_decl (tree); static void dwarf2out_type_decl (tree, int); static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool); +static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree, + dw_die_ref); static void dwarf2out_abstract_function (tree); static void dwarf2out_var_location (rtx); static void dwarf2out_begin_function (tree); @@ -4746,6 +4792,10 @@ static GTY((param_is (struct dwarf_file_data))) htab_t file_table; The key is a DECL_UID() which is a unique number identifying each decl. */ static GTY ((param_is (struct die_struct))) htab_t decl_die_table; +/* A hash table of references to DIE's that describe COMMON blocks. + The key is DECL_UID() ^ die_parent. */ +static GTY ((param_is (struct die_struct))) htab_t common_block_die_table; + /* Node of the variable location list. */ struct var_loc_node GTY ((chain_next ("%h.next"))) { @@ -4958,6 +5008,8 @@ static void equate_type_number_to_die (tree, dw_die_ref); static hashval_t decl_die_table_hash (const void *); static int decl_die_table_eq (const void *, const void *); static dw_die_ref lookup_decl_die (tree); +static hashval_t common_block_die_table_hash (const void *); +static int common_block_die_table_eq (const void *, const void *); static hashval_t decl_loc_table_hash (const void *); static int decl_loc_table_eq (const void *, const void *); static var_loc_list *lookup_decl_loc (const_tree); @@ -10000,6 +10052,16 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, distinction between OP_REG and OP_BASEREG. */ if (REGNO (rtl) < FIRST_PSEUDO_REGISTER) mem_loc_result = based_loc_descr (rtl, 0, VAR_INIT_STATUS_INITIALIZED); + else if (stack_realign_drap + && crtl->drap_reg + && crtl->args.internal_arg_pointer == rtl + && REGNO (crtl->drap_reg) < FIRST_PSEUDO_REGISTER) + { + /* If RTL is internal_arg_pointer, which has been optimized + out, use DRAP instead. */ + mem_loc_result = based_loc_descr (crtl->drap_reg, 0, + VAR_INIT_STATUS_INITIALIZED); + } break; case MEM: @@ -13810,6 +13872,26 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) } +/* Returns a hash value for X (which really is a die_struct). */ + +static hashval_t +common_block_die_table_hash (const void *x) +{ + const_dw_die_ref d = (const_dw_die_ref) x; + return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent); +} + +/* Return nonzero if decl_id and die_parent of die_struct X is the same + as decl_id and die_parent of die_struct Y. */ + +static int +common_block_die_table_eq (const void *x, const void *y) +{ + const_dw_die_ref d = (const_dw_die_ref) x; + const_dw_die_ref e = (const_dw_die_ref) y; + return d->decl_id == e->decl_id && d->die_parent == e->die_parent; +} + /* Generate a DIE to represent a declared data object. */ static void @@ -13851,6 +13933,7 @@ gen_variable_die (tree decl, dw_die_ref context_die) tree field; dw_die_ref com_die; dw_loc_descr_ref loc; + die_node com_die_arg; var_die = lookup_decl_die (decl); if (var_die) @@ -13861,21 +13944,41 @@ gen_variable_die (tree decl, dw_die_ref context_die) if (loc) { if (off) - add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, + { + /* Optimize the common case. */ + if (loc->dw_loc_opc == DW_OP_addr + && loc->dw_loc_next == NULL + && GET_CODE (loc->dw_loc_oprnd1.v.val_addr) + == SYMBOL_REF) + loc->dw_loc_oprnd1.v.val_addr + = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off); + else + add_loc_descr (&loc, + new_loc_descr (DW_OP_plus_uconst, off, 0)); + } add_AT_loc (var_die, DW_AT_location, loc); remove_AT (var_die, DW_AT_declaration); } } return; } + + if (common_block_die_table == NULL) + common_block_die_table + = htab_create_ggc (10, common_block_die_table_hash, + common_block_die_table_eq, NULL); + field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0); - com_die = lookup_decl_die (com_decl); + com_die_arg.decl_id = DECL_UID (com_decl); + com_die_arg.die_parent = context_die; + com_die = (dw_die_ref) htab_find (common_block_die_table, &com_die_arg); loc = loc_descriptor_from_tree (com_decl); if (com_die == NULL) { const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl)); + void **slot; com_die = new_die (DW_TAG_common_block, context_die, decl); add_name_and_src_coords_attributes (com_die, com_decl); @@ -13889,7 +13992,9 @@ gen_variable_die (tree decl, dw_die_ref context_die) else if (DECL_EXTERNAL (decl)) add_AT_flag (com_die, DW_AT_declaration, 1); add_pubname_string (cnam, com_die); /* ??? needed? */ - equate_decl_number_to_die (com_decl, com_die); + com_die->decl_id = DECL_UID (com_decl); + slot = htab_find_slot (common_block_die_table, com_die, INSERT); + *slot = (void *) com_die; } else if (get_AT (com_die, DW_AT_location) == NULL && loc) { @@ -13905,7 +14010,17 @@ gen_variable_die (tree decl, dw_die_ref context_die) if (loc) { if (off) - add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, off, 0)); + { + /* Optimize the common case. */ + if (loc->dw_loc_opc == DW_OP_addr + && loc->dw_loc_next == NULL + && GET_CODE (loc->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF) + loc->dw_loc_oprnd1.v.val_addr + = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off); + else + add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, + off, 0)); + } add_AT_loc (var_die, DW_AT_location, loc); } else if (DECL_EXTERNAL (decl)) @@ -14918,6 +15033,9 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth) if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && !(is_fortran () && TREE_PUBLIC (decl))) ; + 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); } @@ -15309,6 +15427,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) break; case NAMESPACE_DECL: + case IMPORTED_DECL: gen_namespace_die (decl); break; @@ -15343,44 +15462,20 @@ dwarf2out_type_decl (tree decl, int local) } /* Output debug information for imported module or decl DECL. - NAME is non-NULL name in context if the decl has been renamed. - CHILD is true if decl is one of the renamed decls as part of - importing whole module. */ - + NAME is non-NULL name in the lexical block if the decl has been renamed. + LEXICAL_BLOCK is the lexical block (which TREE_CODE is a BLOCK) + that DECL belongs to. + LEXICAL_BLOCK_DIE is the DIE of LEXICAL_BLOCK. */ static void -dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, - bool child) +dwarf2out_imported_module_or_decl_1 (tree decl, + tree name, + tree lexical_block, + dw_die_ref lexical_block_die) { - dw_die_ref imported_die, at_import_die; - dw_die_ref scope_die; expanded_location xloc; + dw_die_ref imported_die = NULL; + dw_die_ref at_import_die; - if (debug_info_level <= DINFO_LEVEL_TERSE) - return; - - gcc_assert (decl); - - /* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs. - We need decl DIE for reference and scope die. First, get DIE for the decl - itself. */ - - /* Get the scope die for decl context. Use comp_unit_die for global module - or decl. If die is not found for non globals, force new die. */ - if (context - && TYPE_P (context) - && !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE)) - return; - scope_die = get_context_die (context); - - if (child) - { - gcc_assert (scope_die->die_child); - gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module); - gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL); - scope_die = scope_die->die_child; - } - - /* For TYPE_DECL or CONST_DECL, lookup TREE_TYPE. */ if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL) { if (is_base_type (TREE_TYPE (decl))) @@ -15398,6 +15493,19 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, gcc_assert (at_import_die); } } + else if (TREE_CODE (decl) == IMPORTED_DECL) + { + tree imported_ns_decl; + /* IMPORTED_DECL nodes that are not imported namespace are just not + supported yet. */ + gcc_assert (DECL_INITIAL (decl) + && TREE_CODE (DECL_INITIAL (decl)) == NAMESPACE_DECL); + imported_ns_decl = DECL_INITIAL (decl); + at_import_die = lookup_decl_die (imported_ns_decl); + if (!at_import_die) + at_import_die = force_decl_die (imported_ns_decl); + gcc_assert (at_import_die); + } else { at_import_die = lookup_decl_die (decl); @@ -15421,20 +15529,66 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, } } - /* OK, now we have DIEs for decl as well as scope. Emit imported die. */ if (TREE_CODE (decl) == NAMESPACE_DECL) - imported_die = new_die (DW_TAG_imported_module, scope_die, context); + imported_die = new_die (DW_TAG_imported_module, + lexical_block_die, + lexical_block); else - imported_die = new_die (DW_TAG_imported_declaration, scope_die, context); + imported_die = new_die (DW_TAG_imported_declaration, + lexical_block_die, + lexical_block); xloc = expand_location (input_location); add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file)); add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line); if (name) - add_AT_string (imported_die, DW_AT_name, IDENTIFIER_POINTER (name)); + add_AT_string (imported_die, DW_AT_name, + IDENTIFIER_POINTER (name)); add_AT_die_ref (imported_die, DW_AT_import, at_import_die); } +/* Output debug information for imported module or decl DECL. + NAME is non-NULL name in context if the decl has been renamed. + CHILD is true if decl is one of the renamed decls as part of + importing whole module. */ + +static void +dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, + bool child) +{ + /* dw_die_ref at_import_die; */ + dw_die_ref scope_die; + + if (debug_info_level <= DINFO_LEVEL_TERSE) + return; + + gcc_assert (decl); + + /* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs. + We need decl DIE for reference and scope die. First, get DIE for the decl + itself. */ + + /* Get the scope die for decl context. Use comp_unit_die for global module + or decl. If die is not found for non globals, force new die. */ + if (context + && TYPE_P (context) + && !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE)) + return; + scope_die = get_context_die (context); + + if (child) + { + gcc_assert (scope_die->die_child); + gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module); + gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL); + scope_die = scope_die->die_child; + } + + /* OK, now we have DIEs for decl as well as scope. Emit imported die. */ + dwarf2out_imported_module_or_decl_1 (decl, name, context, scope_die); + +} + /* Write the debugging output for DECL. */ void @@ -15519,6 +15673,7 @@ dwarf2out_decl (tree decl) break; case NAMESPACE_DECL: + case IMPORTED_DECL: if (debug_info_level <= DINFO_LEVEL_TERSE) return; if (lookup_decl_die (decl) != NULL) @@ -16137,6 +16292,37 @@ prune_unused_types_mark (dw_die_ref die, int dokids) } } +/* For local classes, look if any static member functions were emitted + and if so, mark them. */ + +static void +prune_unused_types_walk_local_classes (dw_die_ref die) +{ + dw_die_ref c; + + if (die->die_mark == 2) + return; + + switch (die->die_tag) + { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + break; + + case DW_TAG_subprogram: + if (!get_AT_flag (die, DW_AT_declaration) + || die->die_definition != NULL) + prune_unused_types_mark (die, 1); + return; + + default: + return; + } + + /* Mark children. */ + FOR_EACH_CHILD (die, c, prune_unused_types_walk_local_classes (c)); +} /* Walk the tree DIE and mark types that we actually use. */ @@ -16145,12 +16331,34 @@ prune_unused_types_walk (dw_die_ref die) { dw_die_ref c; - /* Don't do anything if this node is already marked. */ - if (die->die_mark) + /* Don't do anything if this node is already marked and + children have been marked as well. */ + if (die->die_mark == 2) return; switch (die->die_tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + if (die->die_perennial_p) + break; + + for (c = die->die_parent; c; c = c->die_parent) + if (c->die_tag == DW_TAG_subprogram) + break; + + /* Finding used static member functions inside of classes + is needed just for local classes, because for other classes + static member function DIEs with DW_AT_specification + are emitted outside of the DW_TAG_*_type. If we ever change + it, we'd need to call this even for non-local classes. */ + if (c) + prune_unused_types_walk_local_classes (die); + + /* It's a type node --- don't mark it. */ + return; + case DW_TAG_const_type: case DW_TAG_packed_type: case DW_TAG_pointer_type: @@ -16158,9 +16366,6 @@ prune_unused_types_walk (dw_die_ref die) case DW_TAG_volatile_type: case DW_TAG_typedef: case DW_TAG_array_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: case DW_TAG_interface_type: case DW_TAG_friend: case DW_TAG_variant_part: @@ -16182,10 +16387,15 @@ prune_unused_types_walk (dw_die_ref die) break; } - die->die_mark = 1; + if (die->die_mark == 0) + { + die->die_mark = 1; + + /* Now, mark any dies referenced from here. */ + prune_unused_types_walk_attribs (die); + } - /* Now, mark any dies referenced from here. */ - prune_unused_types_walk_attribs (die); + die->die_mark = 2; /* Mark children. */ FOR_EACH_CHILD (die, c, prune_unused_types_walk (c)); @@ -16489,7 +16699,9 @@ dwarf2out_finish (const char *filename) for (node = limbo_die_list; node; node = node->next) output_comp_unit (node->die, 0); - output_comp_unit (comp_unit_die, 0); + /* Output the main compilation unit if non-empty or if .debug_macinfo + has been emitted. */ + output_comp_unit (comp_unit_die, debug_info_level >= DINFO_LEVEL_VERBOSE); /* Output the abbreviation table. */ switch_to_section (debug_abbrev_section);