|
|
Created:
12 years, 11 months ago by Cary Modified:
12 years, 11 months ago Reviewers:
Diego Novillo CC:
gcc-patches_gcc.gnu.org Base URL:
svn+ssh://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6/ Visibility:
Public. |
Patch Set 1 #Patch Set 2 : [google/gcc-4_6] More Fission updates #Patch Set 3 : [google/gcc-4_6] More Fission updates (revised) #
MessagesTotal messages: 8
This patch is for the google/gcc-4_6 branch. Fission improvements and bug fixes. Adds new DW_OP_GNU_const_index to handle TLS offsets in debug info. Adds -gpubnames/-gno-pubnames options to explicitly request .debug_pubnames/pubtypes sections. Adds style parameter to C/C++ pretty-printer so that we can get canonical pubnames without affecting diagnostic output. Bootstrapped and tested on x86_64. 2012-05-18 Sterling Augustine <saugustine@google.com> Cary Coutant <ccoutant@google.com> include/ * dwarf2.h: Add DW_OP_GNU_const_index. gcc/ * opts.c (finish_options): -gfission implies -gpubnames. (common_handle_option): Pass empty arg string to set_debug_level. * common.opt (gno-fission): New option. (gfission): Remove JoinedOrMissing, add RejectNegative. (gno-pubnames, gpubnames): New options. * target.def (want_debug_pub_sections): Change default to false. * gcc.c (check_live_switch): Check -g options for -gno- options. * c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Add support for gnu_v3 style. * c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enum constant. * cp/error.c (dump_decl): Add support for gnu_v3 style. (decl_as_string): Likewise. (lang_decl_name): Likewise. * cp/cp-lang.c (cxx_dwarf_name): Likewise. * cp/cp-tree.h (enum overload_flags): Add TFF_MATCH_GNU_V3_DEMANGLER. * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_const_index. (size_of_loc_descr): Likewise. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (want_pubnames): New macro. (dw_addr_op): New function. (new_addr_loc_descr): Call dw_addr_op. (add_AT_pubnames): Add DW_AT_GNU_pubnames/pubtypes only if generating .debug_pubnames/pubtypes sections. (add_pubname_string): Check for -gpubnames option. (add_pubname): Likewise. (add_pubtype): Likewise. (output_pubnames): Likewise. (mem_loc_descriptor): Call new_addr_loc_desc for TLS vars. (loc_list_from_tree): Likewise. (output_addr_table): Handle DW_OP_GNU_const_index. Add missing newline. (hash_loc_operands): Add DW_OP_GNU_const_index. (compare_loc_operands): Likewise. * testsuite/g++.old-deja/g++.pt/memtemp77.C: Revert earlier change to expected results. * testsuite/g++.dg/ext/pretty3.C: Likewise. * testsuite/g++.dg/warn/Wuninitializable-member.C: Likewise. * testsuite/g++.dg/warn/pr35711.C: Likewise. * testsuite/g++.dg/pr44486.C: Likewise. Index: include/dwarf2.h =================================================================== --- include/dwarf2.h (revision 187292) +++ include/dwarf2.h (working copy) @@ -546,8 +546,9 @@ enum dwarf_location_atom DW_OP_GNU_uninit = 0xf0, DW_OP_GNU_encoded_addr = 0xf1, DW_OP_GNU_implicit_pointer = 0xf2, - /* Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ + /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, /* HP extensions. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_is_value = 0xe1, Index: gcc/c-family/c-pretty-print.c =================================================================== --- gcc/c-family/c-pretty-print.c (revision 187169) +++ gcc/c-family/c-pretty-print.c (working copy) @@ -445,6 +445,9 @@ pp_c_specifier_qualifier_list (c_pretty_ { const enum tree_code code = TREE_CODE (t); + if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) + pp_c_type_qualifier_list (pp, t); + switch (code) { case REFERENCE_TYPE: @@ -489,7 +492,7 @@ pp_c_specifier_qualifier_list (c_pretty_ pp_simple_type_specifier (pp, t); break; } - if (TREE_CODE (t) != POINTER_TYPE) + if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) pp_c_type_qualifier_list (pp, t); } Index: gcc/c-family/c-pretty-print.h =================================================================== --- gcc/c-family/c-pretty-print.h (revision 187169) +++ gcc/c-family/c-pretty-print.h (working copy) @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. typedef enum { pp_c_flag_abstract = 1 << 1, - pp_c_flag_last_bit = 2 + pp_c_flag_last_bit = 2, + pp_c_flag_gnu_v3 = 4 } pp_c_pretty_print_flags; Index: gcc/target.def =================================================================== --- gcc/target.def (revision 187169) +++ gcc/target.def (working copy) @@ -2795,7 +2795,7 @@ DEFHOOKPOD "True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections\ should be emitted. These sections are not used on most platforms, and\ in particular GDB does not use them.", - bool, true) + bool, false) DEFHOOKPOD (delay_sched2, "True if sched2 is not to be run at its normal place. \ Index: gcc/gcc.c =================================================================== --- gcc/gcc.c (revision 187169) +++ gcc/gcc.c (working copy) @@ -448,7 +448,7 @@ ignored. White space may also appear an colon in these constructs, except between . or * and the corresponding word. -The -O, -f, -m, and -W switches are handled specifically in these +The -O, -f, -g, -m, and -W switches are handled specifically in these constructs. If another value of -O or the negated form of a -f, -m, or -W switch is found later in the command line, the earlier switch value is ignored, except with {S*} where S is just one letter; this @@ -5867,7 +5867,7 @@ process_brace_body (const char *p, const on the command line. PREFIX_LENGTH is the length of XXX in an {XXX*} spec, or -1 if either exact match or %* is used. - A -O switch is obsoleted by a later -O switch. A -f, -m, or -W switch + A -O switch is obsoleted by a later -O switch. A -f, -g, -m, or -W switch whose value does not begin with "no-" is obsoleted by the same value with the "no-", similarly for a switch with the "no-" prefix. */ @@ -5904,7 +5904,7 @@ check_live_switch (int switchnum, int pr } break; - case 'W': case 'f': case 'm': + case 'W': case 'f': case 'm': case 'g': if (! strncmp (name + 1, "no-", 3)) { /* We have Xno-YYY, search for XYYY. */ Index: gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (revision 187169) +++ gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (working copy) @@ -19,7 +19,7 @@ const char* S3<char>::h(int) { return __ int main() { if (strcmp (S3<double>::h(7), - "static char const* S3<T>::h(U) [with U = int, T = double]") == 0) + "static const char* S3<T>::h(U) [with U = int, T = double]") == 0) return 0; else return 1; Index: gcc/testsuite/g++.dg/ext/pretty3.C =================================================================== --- gcc/testsuite/g++.dg/ext/pretty3.C (revision 187169) +++ gcc/testsuite/g++.dg/ext/pretty3.C (working copy) @@ -16,4 +16,4 @@ int main () { printf ("%s\n", D<int>().foo (0)); } -// { dg-final { scan-assembler "char const\\* D<U>::foo\\(typename B<U>::X\\)" } } +// { dg-final { scan-assembler "const char\\* D<U>::foo\\(typename B<U>::X\\)" } } Index: gcc/testsuite/g++.dg/warn/Wuninitializable-member.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (revision 187169) +++ gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (working copy) @@ -8,7 +8,7 @@ public: }; class Y { - const int var;// { dg-warning "non-static const member 'int const Y::var' in class without a constructor" } + const int var;// { dg-warning "non-static const member 'const int Y::var' in class without a constructor" } public: int g(){ return 2*var; } }; Index: gcc/testsuite/g++.dg/warn/pr35711.C =================================================================== --- gcc/testsuite/g++.dg/warn/pr35711.C (revision 187169) +++ gcc/testsuite/g++.dg/warn/pr35711.C (working copy) @@ -4,5 +4,5 @@ int* foo (volatile int *p) { - return (int*)p; // { dg-warning "cast from type 'int volatile\\*' to type 'int\\*' casts away qualifiers" } + return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" } } Index: gcc/testsuite/g++.dg/pr44486.C =================================================================== --- gcc/testsuite/g++.dg/pr44486.C (revision 187169) +++ gcc/testsuite/g++.dg/pr44486.C (working copy) @@ -7,4 +7,4 @@ namespace { S f() { const char * s = __P int main() { f(); } -// { dg-final { scan-assembler "S \\(anonymous namespace\\)::f" } } +// { dg-final { scan-assembler "S \{anonymous\}::f" } } Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 187169) +++ gcc/cp/error.c (working copy) @@ -974,7 +974,12 @@ dump_decl (tree t, int flags) dump_scope (CP_DECL_CONTEXT (t), flags); flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) - pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + { + if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3)) + pp_cxx_ws_string (cxx_pp, M_("{anonymous}")); + else + pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + } else pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); } @@ -2459,6 +2464,8 @@ decl_as_string (tree decl, int flags) { reinit_cxx_pp (); pp_translate_identifiers (cxx_pp) = false; + if (flags & TFF_MATCH_GNU_V3_DEMANGLER) + pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3; dump_decl (decl, flags); return pp_formatted_text (cxx_pp); } @@ -2494,8 +2501,9 @@ lang_decl_name (tree decl, int v, bool t if (TREE_CODE (decl) == FUNCTION_DECL) dump_function_name (decl, TFF_PLAIN_IDENTIFIER); - else if (DECL_NAME (decl) == NULL && TREE_CODE (decl) == NAMESPACE_DECL) - pp_string (cxx_pp, M_("(anonymous namespace)")); + else if ((DECL_NAME (decl) == NULL_TREE) + && TREE_CODE (decl) == NAMESPACE_DECL) + dump_decl (decl, TFF_PLAIN_IDENTIFIER); else dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); Index: gcc/cp/cp-lang.c =================================================================== --- gcc/cp/cp-lang.c (revision 187169) +++ gcc/cp/cp-lang.c (working copy) @@ -185,8 +185,14 @@ cxx_dwarf_name (tree t, int verbosity) if (verbosity >= 2) return decl_as_string (t, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME - | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); + | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS + | TFF_MATCH_GNU_V3_DEMANGLER); + /* decl_as_string handles namespaces--especially anonymous ones--more + appropriately for debugging than cxx_printable_name. But + cxx_printable_name handles templates and global ctors and dtors better. */ + if (TREE_CODE (t) == NAMESPACE_DECL) + return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER); return cxx_printable_name (t, verbosity); } Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 187169) +++ gcc/cp/cp-tree.h (working copy) @@ -4365,7 +4365,9 @@ enum overload_flags { NO_SPECIAL = 0, DT TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the top-level entity. TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments - identical to their defaults. */ + identical to their defaults. + TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous + namespaces and order of type-qualifiers vs type-specifiers. */ #define TFF_PLAIN_IDENTIFIER (0) #define TFF_SCOPE (1) @@ -4381,6 +4383,7 @@ enum overload_flags { NO_SPECIAL = 0, DT #define TFF_NO_FUNCTION_ARGUMENTS (1 << 10) #define TFF_UNQUALIFIED_NAME (1 << 11) #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12) +#define TFF_MATCH_GNU_V3_DEMANGLER (1 << 13) /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM node. */ Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 187292) +++ gcc/dwarf2out.c (working copy) @@ -4782,6 +4782,8 @@ dwarf_stack_op_name (unsigned int op) return "DW_OP_GNU_implicit_pointer"; case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index"; + case DW_OP_GNU_const_index: + return "DW_OP_GNU_const_index"; default: return "OP_<unknown>"; @@ -4903,6 +4905,7 @@ size_of_loc_descr (dw_loc_descr_ref loc) size += DWARF2_ADDR_SIZE; break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: size += size_of_uleb128 (loc->dw_loc_oprnd1.val_index); break; case DW_OP_const1u: @@ -5284,8 +5287,9 @@ output_loc_operands (dw_loc_descr_ref lo break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: dw2_asm_output_data_uleb128 (loc->dw_loc_oprnd1.val_index, - "(address index)"); + "(index into .debug_addr)"); break; case DW_OP_GNU_implicit_pointer: @@ -5357,6 +5361,7 @@ output_loc_operands_raw (dw_loc_descr_re { case DW_OP_addr: case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: case DW_OP_implicit_value: /* We cannot output addresses in .cfi_escape, only bytes. */ gcc_unreachable (); @@ -5820,6 +5825,14 @@ const struct gcc_debug_hooks dwarf2_debu representation is done after the entire program has been compiled. The types below are used to describe the internal representation. */ +/* Whether to generate the DWARF accelerator tables in .debug_pubnames + and .debug_pubtypes. This is configured per-target, but can be + overridden by the -gpubnames or -gno-pubnames options. */ + +#define want_pubnames (debug_generate_pub_sections != -1 \ + ? debug_generate_pub_sections \ + : targetm.want_debug_pub_sections) + /* Various DIE's use offsets relative to the beginning of the .debug_info section to refer to each other. */ @@ -6589,17 +6602,30 @@ static bool generic_type_p (tree); static void schedule_generic_params_dies_gen (tree t); static void gen_scheduled_generic_parms_dies (void); +/* DW_OP_addr is relocated by the debug info consumer, while + tls relative operands should not be. */ + +static inline enum dwarf_location_atom dw_addr_op (bool dtprel) +{ + if (dtprel) + return (dwarf_split_debug_info ? DW_OP_GNU_const_index + : (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u)); + else + return (dwarf_split_debug_info ? DW_OP_GNU_addr_index : DW_OP_addr); +} + /* Return a pointer to a newly allocated address location description. If dwarf_split_debug_info is true, then record the address with the appropriate relocation. */ static inline dw_loc_descr_ref new_addr_loc_descr (rtx addr, int dtprel) { - dw_loc_descr_ref ref = new_loc_descr (DW_OP_addr, 0, 0); + dw_loc_descr_ref ref = new_loc_descr (dw_addr_op (dtprel), 0, 0); ref->dw_loc_oprnd1.val_class = dw_val_class_addr; ref->dw_loc_oprnd1.val_index = -1U; ref->dw_loc_oprnd1.v.val_addr = addr; + ref->dtprel = dtprel; if (dwarf_split_debug_info) { dw_attr_node attr; @@ -6610,7 +6636,6 @@ new_addr_loc_descr (rtx addr, int dtprel attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_addr = addr; - ref->dw_loc_opc = DW_OP_GNU_addr_index; ref->dw_loc_oprnd1.val_index = add_addr_table_entry (&attr); } return ref; @@ -11931,10 +11956,13 @@ output_comp_unit (dw_die_ref die, int ou static void add_AT_pubnames (dw_die_ref die) { - /* FIXME: Should use add_AT_pubnamesptr. This works because most targets - don't care what the base section is. */ - add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); - add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + if (want_pubnames) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because most targets + don't care what the base section is. */ + add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); + add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + } } /* Helper function to generate top-level dies for skeleton debug_info and @@ -12136,7 +12164,7 @@ dwarf2_name (tree decl, int scope) static void add_pubname_string (const char *str, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames) { pubname_entry e; @@ -12149,7 +12177,7 @@ add_pubname_string (const char *str, dw_ static void add_pubname (tree decl, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames) { if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) @@ -12182,7 +12210,7 @@ add_pubtype (tree decl, dw_die_ref die) { pubname_entry e; - if (!targetm.want_debug_pub_sections) + if (!want_pubnames) return; if ((TREE_PUBLIC (decl) @@ -12243,7 +12271,7 @@ output_pubnames (VEC (pubname_entry, gc) unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; - if (!targetm.want_debug_pub_sections || !info_section_emitted) + if (!want_pubnames || !info_section_emitted) return; if (names == pubname_table) { @@ -14528,15 +14556,7 @@ mem_loc_descriptor (rtx rtl, enum machin if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel) break; - /* We used to emit DW_OP_addr here, but that's wrong, since - DW_OP_addr should be relocated by the debug info consumer, - while DW_OP_GNU_push_tls_address operand should not. */ - temp = new_loc_descr (DWARF2_ADDR_SIZE == 4 - ? DW_OP_const4u : DW_OP_const8u, 0, 0); - temp->dw_loc_oprnd1.val_class = dw_val_class_addr; - temp->dw_loc_oprnd1.val_index = -1U; - temp->dw_loc_oprnd1.v.val_addr = rtl; - temp->dtprel = true; + temp = new_addr_loc_descr (rtl, true); mem_loc_result = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0); add_loc_descr (&mem_loc_result, temp); @@ -16113,8 +16133,7 @@ loc_list_from_tree (tree loc, int want_a if (DECL_THREAD_LOCAL_P (loc)) { rtx rtl; - enum dwarf_location_atom first_op; - enum dwarf_location_atom second_op; + enum dwarf_location_atom tls_op; bool dtprel = false; if (targetm.have_tls) @@ -16132,9 +16151,8 @@ loc_list_from_tree (tree loc, int want_a operand shouldn't be. */ if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc)) return 0; - first_op = DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u; dtprel = true; - second_op = DW_OP_GNU_push_tls_address; + tls_op = DW_OP_GNU_push_tls_address; } else { @@ -16146,8 +16164,7 @@ loc_list_from_tree (tree loc, int want_a no longer appear in gimple code. We used the control variable in specific so that we could pick it up here. */ loc = DECL_VALUE_EXPR (loc); - first_op = DW_OP_addr; - second_op = DW_OP_form_tls_address; + tls_op = DW_OP_form_tls_address; } rtl = rtl_for_decl_location (loc); @@ -16160,19 +16177,8 @@ loc_list_from_tree (tree loc, int want_a if (! CONSTANT_P (rtl)) return 0; - if (dwarf_split_debug_info && first_op == DW_OP_addr) - ret = new_addr_loc_descr (rtl, dtprel); - else - { - ret = new_loc_descr (first_op, 0, 0); - ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.val_index = -1U; - ret->dw_loc_oprnd1.v.val_addr = rtl; - } - - ret->dtprel = dtprel; - - ret1 = new_loc_descr (second_op, 0, 0); + ret = new_addr_loc_descr (rtl, dtprel); + ret1 = new_loc_descr (tls_op, 0, 0); add_loc_descr (&ret, ret1); have_address = 1; @@ -23195,7 +23201,8 @@ output_addr_table (void) gcc_assert (targetm.asm_out.output_dwarf_dtprel); targetm.asm_out.output_dwarf_dtprel (asm_out_file, DWARF2_ADDR_SIZE, - AT_addr (node)); + node->dw_attr_val.v.val_addr); + fputc ('\n', asm_out_file); break; case dw_val_class_lbl_id: dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (node), "%s", name); @@ -23949,6 +23956,7 @@ hash_loc_operands (dw_loc_descr_ref loc, hash = iterative_hash_rtx (val1->v.val_addr, hash); break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_ref attr = VEC_index (dw_attr_node, addr_index_table, val1->val_index); @@ -24116,6 +24124,7 @@ compare_loc_operands (dw_loc_descr_ref x hash_addr: return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr); case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_node *attrx1 = VEC_index (dw_attr_node, addr_index_table, Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 187169) +++ gcc/opts.c (working copy) @@ -850,6 +850,10 @@ finish_options (struct gcc_options *opts /* Turn on -ffunction-sections when -freorder-functions=* is used. */ if (opts->x_flag_reorder_functions > 1) opts->x_flag_function_sections = 1; + + /* The -gfission option requires -gpubnames. */ + if (opts->x_dwarf_split_debug_info) + opts->x_debug_generate_pub_sections = 1; } #define LEFT_COLUMN 27 @@ -1714,7 +1718,7 @@ common_handle_option (struct gcc_options break; case OPT_gfission: - set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set, + set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set, loc); break; Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 187169) +++ gcc/common.opt (working copy) @@ -2374,8 +2374,12 @@ gdwarf- Common Joined UInteger Var(dwarf_version) Init(2) Negative(gstabs) Generate debug information in DWARF v2 (or later) format +gno-fission +Common Driver RejectNegative Var(dwarf_split_debug_info,0) Init(0) +Don't generate debug information in separate .dwo files + gfission -Common Driver JoinedOrMissing Var(dwarf_split_debug_info,1) +Common Driver RejectNegative Var(dwarf_split_debug_info,1) Generate debug information in separate .dwo files ggdb @@ -2386,6 +2390,14 @@ gmlt Common RejectNegative Generate debug information at level 1 with minimal line table +gno-pubnames +Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1) +Don't generate DWARF pubnames and pubtypes sections. + +gpubnames +Common RejectNegative Var(debug_generate_pub_sections, 1) +Generate DWARF pubnames and pubtypes sections. + gstabs Common JoinedOrMissing Negative(gstabs+) Generate debug information in STABS format -- This patch is available for review at http://codereview.appspot.com/6219049
Sign in to reply to this message.
This patch is for the google/gcc-4_6 branch. Fission improvements and bug fixes. Adds new DW_OP_GNU_const_index to handle TLS offsets in debug info. Adds -gpubnames/-gno-pubnames options to explicitly request .debug_pubnames/pubtypes sections. Adds style parameter to C/C++ pretty-printer so that we can get canonical pubnames without affecting diagnostic output. Bootstrapped and tested on x86_64. 2012-05-18 Sterling Augustine <saugustine@google.com> Cary Coutant <ccoutant@google.com> include/ * dwarf2.h: Add DW_OP_GNU_const_index. gcc/ * opts.c (finish_options): -gfission implies -gpubnames. (common_handle_option): Pass empty arg string to set_debug_level. * common.opt (gno-fission): New option. (gfission): Remove JoinedOrMissing, add RejectNegative. (gno-pubnames, gpubnames): New options. * target.def (want_debug_pub_sections): Change default to false. * gcc.c (check_live_switch): Check -g options for -gno- options. * c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Add support for gnu_v3 style. * c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enum constant. * cp/error.c (dump_decl): Add support for gnu_v3 style. (decl_as_string): Likewise. (lang_decl_name): Likewise. * cp/cp-lang.c (cxx_dwarf_name): Likewise. * cp/cp-tree.h (enum overload_flags): Add TFF_MATCH_GNU_V3_DEMANGLER. * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_const_index. (size_of_loc_descr): Likewise. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (want_pubnames): New macro. (dw_addr_op): New function. (new_addr_loc_descr): Call dw_addr_op. (add_AT_pubnames): Add DW_AT_GNU_pubnames/pubtypes only if generating .debug_pubnames/pubtypes sections. (add_pubname_string): Check for -gpubnames option. (add_pubname): Likewise. (add_pubtype): Likewise. (output_pubnames): Likewise. (mem_loc_descriptor): Call new_addr_loc_desc for TLS vars. (loc_list_from_tree): Likewise. (output_addr_table): Handle DW_OP_GNU_const_index. Add missing newline. (hash_loc_operands): Add DW_OP_GNU_const_index. (compare_loc_operands): Likewise. * testsuite/g++.old-deja/g++.pt/memtemp77.C: Revert earlier change to expected results. * testsuite/g++.dg/ext/pretty3.C: Likewise. * testsuite/g++.dg/warn/Wuninitializable-member.C: Likewise. * testsuite/g++.dg/warn/pr35711.C: Likewise. * testsuite/g++.dg/pr44486.C: Likewise. Index: include/dwarf2.h =================================================================== --- include/dwarf2.h (revision 187751) +++ include/dwarf2.h (working copy) @@ -546,8 +546,9 @@ enum dwarf_location_atom DW_OP_GNU_uninit = 0xf0, DW_OP_GNU_encoded_addr = 0xf1, DW_OP_GNU_implicit_pointer = 0xf2, - /* Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ + /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, /* HP extensions. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_is_value = 0xe1, Index: gcc/c-family/c-pretty-print.c =================================================================== --- gcc/c-family/c-pretty-print.c (revision 187751) +++ gcc/c-family/c-pretty-print.c (working copy) @@ -445,6 +445,9 @@ pp_c_specifier_qualifier_list (c_pretty_ { const enum tree_code code = TREE_CODE (t); + if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) + pp_c_type_qualifier_list (pp, t); + switch (code) { case REFERENCE_TYPE: @@ -489,7 +492,7 @@ pp_c_specifier_qualifier_list (c_pretty_ pp_simple_type_specifier (pp, t); break; } - if (TREE_CODE (t) != POINTER_TYPE) + if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) pp_c_type_qualifier_list (pp, t); } Index: gcc/c-family/c-pretty-print.h =================================================================== --- gcc/c-family/c-pretty-print.h (revision 187751) +++ gcc/c-family/c-pretty-print.h (working copy) @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. typedef enum { pp_c_flag_abstract = 1 << 1, - pp_c_flag_last_bit = 2 + pp_c_flag_last_bit = 2, + pp_c_flag_gnu_v3 = 4 } pp_c_pretty_print_flags; Index: gcc/target.def =================================================================== --- gcc/target.def (revision 187751) +++ gcc/target.def (working copy) @@ -2795,7 +2795,7 @@ DEFHOOKPOD "True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections\ should be emitted. These sections are not used on most platforms, and\ in particular GDB does not use them.", - bool, true) + bool, false) DEFHOOKPOD (delay_sched2, "True if sched2 is not to be run at its normal place. \ Index: gcc/gcc.c =================================================================== --- gcc/gcc.c (revision 187751) +++ gcc/gcc.c (working copy) @@ -448,7 +448,7 @@ ignored. White space may also appear an colon in these constructs, except between . or * and the corresponding word. -The -O, -f, -m, and -W switches are handled specifically in these +The -O, -f, -g, -m, and -W switches are handled specifically in these constructs. If another value of -O or the negated form of a -f, -m, or -W switch is found later in the command line, the earlier switch value is ignored, except with {S*} where S is just one letter; this @@ -5867,7 +5867,7 @@ process_brace_body (const char *p, const on the command line. PREFIX_LENGTH is the length of XXX in an {XXX*} spec, or -1 if either exact match or %* is used. - A -O switch is obsoleted by a later -O switch. A -f, -m, or -W switch + A -O switch is obsoleted by a later -O switch. A -f, -g, -m, or -W switch whose value does not begin with "no-" is obsoleted by the same value with the "no-", similarly for a switch with the "no-" prefix. */ @@ -5904,7 +5904,7 @@ check_live_switch (int switchnum, int pr } break; - case 'W': case 'f': case 'm': + case 'W': case 'f': case 'm': case 'g': if (! strncmp (name + 1, "no-", 3)) { /* We have Xno-YYY, search for XYYY. */ Index: gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (revision 187751) +++ gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (working copy) @@ -19,7 +19,7 @@ const char* S3<char>::h(int) { return __ int main() { if (strcmp (S3<double>::h(7), - "static char const* S3<T>::h(U) [with U = int, T = double]") == 0) + "static const char* S3<T>::h(U) [with U = int, T = double]") == 0) return 0; else return 1; Index: gcc/testsuite/g++.dg/ext/pretty3.C =================================================================== --- gcc/testsuite/g++.dg/ext/pretty3.C (revision 187751) +++ gcc/testsuite/g++.dg/ext/pretty3.C (working copy) @@ -16,4 +16,4 @@ int main () { printf ("%s\n", D<int>().foo (0)); } -// { dg-final { scan-assembler "char const\\* D<U>::foo\\(typename B<U>::X\\)" } } +// { dg-final { scan-assembler "const char\\* D<U>::foo\\(typename B<U>::X\\)" } } Index: gcc/testsuite/g++.dg/warn/Wuninitializable-member.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (revision 187751) +++ gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (working copy) @@ -8,7 +8,7 @@ public: }; class Y { - const int var;// { dg-warning "non-static const member 'int const Y::var' in class without a constructor" } + const int var;// { dg-warning "non-static const member 'const int Y::var' in class without a constructor" } public: int g(){ return 2*var; } }; Index: gcc/testsuite/g++.dg/warn/pr35711.C =================================================================== --- gcc/testsuite/g++.dg/warn/pr35711.C (revision 187751) +++ gcc/testsuite/g++.dg/warn/pr35711.C (working copy) @@ -4,5 +4,5 @@ int* foo (volatile int *p) { - return (int*)p; // { dg-warning "cast from type 'int volatile\\*' to type 'int\\*' casts away qualifiers" } + return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" } } Index: gcc/testsuite/g++.dg/pr44486.C =================================================================== --- gcc/testsuite/g++.dg/pr44486.C (revision 187751) +++ gcc/testsuite/g++.dg/pr44486.C (working copy) @@ -7,4 +7,4 @@ namespace { S f() { const char * s = __P int main() { f(); } -// { dg-final { scan-assembler "S \\(anonymous namespace\\)::f" } } +// { dg-final { scan-assembler "S \{anonymous\}::f" } } Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 187751) +++ gcc/cp/error.c (working copy) @@ -974,7 +974,12 @@ dump_decl (tree t, int flags) dump_scope (CP_DECL_CONTEXT (t), flags); flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) - pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + { + if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3)) + pp_cxx_ws_string (cxx_pp, M_("{anonymous}")); + else + pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + } else pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); } @@ -2459,7 +2464,10 @@ decl_as_string (tree decl, int flags) { reinit_cxx_pp (); pp_translate_identifiers (cxx_pp) = false; + if (flags & TFF_MATCH_GNU_V3_DEMANGLER) + pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3; dump_decl (decl, flags); + pp_c_base (cxx_pp)->flags &= ~pp_c_flag_gnu_v3; return pp_formatted_text (cxx_pp); } @@ -2494,8 +2502,9 @@ lang_decl_name (tree decl, int v, bool t if (TREE_CODE (decl) == FUNCTION_DECL) dump_function_name (decl, TFF_PLAIN_IDENTIFIER); - else if (DECL_NAME (decl) == NULL && TREE_CODE (decl) == NAMESPACE_DECL) - pp_string (cxx_pp, M_("(anonymous namespace)")); + else if ((DECL_NAME (decl) == NULL_TREE) + && TREE_CODE (decl) == NAMESPACE_DECL) + dump_decl (decl, TFF_PLAIN_IDENTIFIER); else dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); Index: gcc/cp/cp-lang.c =================================================================== --- gcc/cp/cp-lang.c (revision 187751) +++ gcc/cp/cp-lang.c (working copy) @@ -185,8 +185,14 @@ cxx_dwarf_name (tree t, int verbosity) if (verbosity >= 2) return decl_as_string (t, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME - | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); + | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS + | TFF_MATCH_GNU_V3_DEMANGLER); + /* decl_as_string handles namespaces--especially anonymous ones--more + appropriately for debugging than cxx_printable_name. But + cxx_printable_name handles templates and global ctors and dtors better. */ + if (TREE_CODE (t) == NAMESPACE_DECL) + return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER); return cxx_printable_name (t, verbosity); } Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 187751) +++ gcc/cp/cp-tree.h (working copy) @@ -4365,7 +4365,9 @@ enum overload_flags { NO_SPECIAL = 0, DT TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the top-level entity. TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments - identical to their defaults. */ + identical to their defaults. + TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous + namespaces and order of type-qualifiers vs type-specifiers. */ #define TFF_PLAIN_IDENTIFIER (0) #define TFF_SCOPE (1) @@ -4381,6 +4383,7 @@ enum overload_flags { NO_SPECIAL = 0, DT #define TFF_NO_FUNCTION_ARGUMENTS (1 << 10) #define TFF_UNQUALIFIED_NAME (1 << 11) #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12) +#define TFF_MATCH_GNU_V3_DEMANGLER (1 << 13) /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM node. */ Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 187751) +++ gcc/dwarf2out.c (working copy) @@ -4782,6 +4782,8 @@ dwarf_stack_op_name (unsigned int op) return "DW_OP_GNU_implicit_pointer"; case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index"; + case DW_OP_GNU_const_index: + return "DW_OP_GNU_const_index"; default: return "OP_<unknown>"; @@ -4903,6 +4905,7 @@ size_of_loc_descr (dw_loc_descr_ref loc) size += DWARF2_ADDR_SIZE; break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: size += size_of_uleb128 (loc->dw_loc_oprnd1.val_index); break; case DW_OP_const1u: @@ -5284,8 +5287,9 @@ output_loc_operands (dw_loc_descr_ref lo break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: dw2_asm_output_data_uleb128 (loc->dw_loc_oprnd1.val_index, - "(address index)"); + "(index into .debug_addr)"); break; case DW_OP_GNU_implicit_pointer: @@ -5357,6 +5361,7 @@ output_loc_operands_raw (dw_loc_descr_re { case DW_OP_addr: case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: case DW_OP_implicit_value: /* We cannot output addresses in .cfi_escape, only bytes. */ gcc_unreachable (); @@ -5820,6 +5825,14 @@ const struct gcc_debug_hooks dwarf2_debu representation is done after the entire program has been compiled. The types below are used to describe the internal representation. */ +/* Whether to generate the DWARF accelerator tables in .debug_pubnames + and .debug_pubtypes. This is configured per-target, but can be + overridden by the -gpubnames or -gno-pubnames options. */ + +#define want_pubnames (debug_generate_pub_sections != -1 \ + ? debug_generate_pub_sections \ + : targetm.want_debug_pub_sections) + /* Various DIE's use offsets relative to the beginning of the .debug_info section to refer to each other. */ @@ -6589,17 +6602,30 @@ static bool generic_type_p (tree); static void schedule_generic_params_dies_gen (tree t); static void gen_scheduled_generic_parms_dies (void); +/* DW_OP_addr is relocated by the debug info consumer, while + tls relative operands should not be. */ + +static inline enum dwarf_location_atom dw_addr_op (bool dtprel) +{ + if (dtprel) + return (dwarf_split_debug_info ? DW_OP_GNU_const_index + : (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u)); + else + return (dwarf_split_debug_info ? DW_OP_GNU_addr_index : DW_OP_addr); +} + /* Return a pointer to a newly allocated address location description. If dwarf_split_debug_info is true, then record the address with the appropriate relocation. */ static inline dw_loc_descr_ref new_addr_loc_descr (rtx addr, int dtprel) { - dw_loc_descr_ref ref = new_loc_descr (DW_OP_addr, 0, 0); + dw_loc_descr_ref ref = new_loc_descr (dw_addr_op (dtprel), 0, 0); ref->dw_loc_oprnd1.val_class = dw_val_class_addr; ref->dw_loc_oprnd1.val_index = -1U; ref->dw_loc_oprnd1.v.val_addr = addr; + ref->dtprel = dtprel; if (dwarf_split_debug_info) { dw_attr_node attr; @@ -6610,7 +6636,6 @@ new_addr_loc_descr (rtx addr, int dtprel attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_addr = addr; - ref->dw_loc_opc = DW_OP_GNU_addr_index; ref->dw_loc_oprnd1.val_index = add_addr_table_entry (&attr); } return ref; @@ -11931,10 +11956,13 @@ output_comp_unit (dw_die_ref die, int ou static void add_AT_pubnames (dw_die_ref die) { - /* FIXME: Should use add_AT_pubnamesptr. This works because most targets - don't care what the base section is. */ - add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); - add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + if (want_pubnames) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because most targets + don't care what the base section is. */ + add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); + add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + } } /* Helper function to generate top-level dies for skeleton debug_info and @@ -12136,7 +12164,7 @@ dwarf2_name (tree decl, int scope) static void add_pubname_string (const char *str, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames) { pubname_entry e; @@ -12149,7 +12177,7 @@ add_pubname_string (const char *str, dw_ static void add_pubname (tree decl, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames) { if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) @@ -12182,7 +12210,7 @@ add_pubtype (tree decl, dw_die_ref die) { pubname_entry e; - if (!targetm.want_debug_pub_sections) + if (!want_pubnames) return; if ((TREE_PUBLIC (decl) @@ -12243,7 +12271,7 @@ output_pubnames (VEC (pubname_entry, gc) unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; - if (!targetm.want_debug_pub_sections || !info_section_emitted) + if (!want_pubnames || !info_section_emitted) return; if (names == pubname_table) { @@ -14528,15 +14556,7 @@ mem_loc_descriptor (rtx rtl, enum machin if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel) break; - /* We used to emit DW_OP_addr here, but that's wrong, since - DW_OP_addr should be relocated by the debug info consumer, - while DW_OP_GNU_push_tls_address operand should not. */ - temp = new_loc_descr (DWARF2_ADDR_SIZE == 4 - ? DW_OP_const4u : DW_OP_const8u, 0, 0); - temp->dw_loc_oprnd1.val_class = dw_val_class_addr; - temp->dw_loc_oprnd1.val_index = -1U; - temp->dw_loc_oprnd1.v.val_addr = rtl; - temp->dtprel = true; + temp = new_addr_loc_descr (rtl, true); mem_loc_result = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0); add_loc_descr (&mem_loc_result, temp); @@ -16113,8 +16133,7 @@ loc_list_from_tree (tree loc, int want_a if (DECL_THREAD_LOCAL_P (loc)) { rtx rtl; - enum dwarf_location_atom first_op; - enum dwarf_location_atom second_op; + enum dwarf_location_atom tls_op; bool dtprel = false; if (targetm.have_tls) @@ -16132,9 +16151,8 @@ loc_list_from_tree (tree loc, int want_a operand shouldn't be. */ if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc)) return 0; - first_op = DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u; dtprel = true; - second_op = DW_OP_GNU_push_tls_address; + tls_op = DW_OP_GNU_push_tls_address; } else { @@ -16146,8 +16164,7 @@ loc_list_from_tree (tree loc, int want_a no longer appear in gimple code. We used the control variable in specific so that we could pick it up here. */ loc = DECL_VALUE_EXPR (loc); - first_op = DW_OP_addr; - second_op = DW_OP_form_tls_address; + tls_op = DW_OP_form_tls_address; } rtl = rtl_for_decl_location (loc); @@ -16160,19 +16177,8 @@ loc_list_from_tree (tree loc, int want_a if (! CONSTANT_P (rtl)) return 0; - if (dwarf_split_debug_info && first_op == DW_OP_addr) - ret = new_addr_loc_descr (rtl, dtprel); - else - { - ret = new_loc_descr (first_op, 0, 0); - ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.val_index = -1U; - ret->dw_loc_oprnd1.v.val_addr = rtl; - } - - ret->dtprel = dtprel; - - ret1 = new_loc_descr (second_op, 0, 0); + ret = new_addr_loc_descr (rtl, dtprel); + ret1 = new_loc_descr (tls_op, 0, 0); add_loc_descr (&ret, ret1); have_address = 1; @@ -23195,7 +23201,8 @@ output_addr_table (void) gcc_assert (targetm.asm_out.output_dwarf_dtprel); targetm.asm_out.output_dwarf_dtprel (asm_out_file, DWARF2_ADDR_SIZE, - AT_addr (node)); + node->dw_attr_val.v.val_addr); + fputc ('\n', asm_out_file); break; case dw_val_class_lbl_id: dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (node), "%s", name); @@ -23949,6 +23956,7 @@ hash_loc_operands (dw_loc_descr_ref loc, hash = iterative_hash_rtx (val1->v.val_addr, hash); break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_ref attr = VEC_index (dw_attr_node, addr_index_table, val1->val_index); @@ -24116,6 +24124,7 @@ compare_loc_operands (dw_loc_descr_ref x hash_addr: return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr); case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_node *attrx1 = VEC_index (dw_attr_node, addr_index_table, Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 187751) +++ gcc/opts.c (working copy) @@ -850,6 +850,10 @@ finish_options (struct gcc_options *opts /* Turn on -ffunction-sections when -freorder-functions=* is used. */ if (opts->x_flag_reorder_functions > 1) opts->x_flag_function_sections = 1; + + /* The -gfission option requires -gpubnames. */ + if (opts->x_dwarf_split_debug_info) + opts->x_debug_generate_pub_sections = 1; } #define LEFT_COLUMN 27 @@ -1714,7 +1718,7 @@ common_handle_option (struct gcc_options break; case OPT_gfission: - set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set, + set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set, loc); break; Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 187751) +++ gcc/common.opt (working copy) @@ -2374,8 +2374,12 @@ gdwarf- Common Joined UInteger Var(dwarf_version) Init(2) Negative(gstabs) Generate debug information in DWARF v2 (or later) format +gno-fission +Common Driver RejectNegative Var(dwarf_split_debug_info,0) Init(0) +Don't generate debug information in separate .dwo files + gfission -Common Driver JoinedOrMissing Var(dwarf_split_debug_info,1) +Common Driver RejectNegative Var(dwarf_split_debug_info,1) Generate debug information in separate .dwo files ggdb @@ -2386,6 +2390,14 @@ gmlt Common RejectNegative Generate debug information at level 1 with minimal line table +gno-pubnames +Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1) +Don't generate DWARF pubnames and pubtypes sections. + +gpubnames +Common RejectNegative Var(debug_generate_pub_sections, 1) +Generate DWARF pubnames and pubtypes sections. + gstabs Common JoinedOrMissing Negative(gstabs+) Generate debug information in STABS format -- This patch is available for review at http://codereview.appspot.com/6219049
Sign in to reply to this message.
On 12-05-18 17:38 , Cary Coutant wrote: > @@ -5820,6 +5825,14 @@ const struct gcc_debug_hooks dwarf2_debu > representation is done after the entire program has been compiled. > The types below are used to describe the internal representation. */ > > +/* Whether to generate the DWARF accelerator tables in .debug_pubnames > + and .debug_pubtypes. This is configured per-target, but can be > + overridden by the -gpubnames or -gno-pubnames options. */ > + > +#define want_pubnames (debug_generate_pub_sections != -1 \ > + ? debug_generate_pub_sections \ > + : targetm.want_debug_pub_sections) > + Minor nit. Make it a static inline function? OK otherwise. Diego.
Sign in to reply to this message.
On 12-05-21 20:15 , Cary Coutant wrote: > This patch is for the google/gcc-4_6 branch. > > Fission improvements and bug fixes. Adds new DW_OP_GNU_const_index to > handle TLS offsets in debug info. Adds -gpubnames/-gno-pubnames options > to explicitly request .debug_pubnames/pubtypes sections. Adds style > parameter to C/C++ pretty-printer so that we can get canonical pubnames > without affecting diagnostic output. > > Bootstrapped and tested on x86_64. > > > 2012-05-18 Sterling Augustine<saugustine@google.com> > Cary Coutant<ccoutant@google.com> > > include/ > * dwarf2.h: Add DW_OP_GNU_const_index. > > gcc/ > * opts.c (finish_options): -gfission implies -gpubnames. > (common_handle_option): Pass empty arg string to set_debug_level. > * common.opt (gno-fission): New option. > (gfission): Remove JoinedOrMissing, add RejectNegative. > (gno-pubnames, gpubnames): New options. > * target.def (want_debug_pub_sections): Change default to false. > * gcc.c (check_live_switch): Check -g options for -gno- options. > > * c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Add > support for gnu_v3 style. > * c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enum constant. > * cp/error.c (dump_decl): Add support for gnu_v3 style. > (decl_as_string): Likewise. > (lang_decl_name): Likewise. > * cp/cp-lang.c (cxx_dwarf_name): Likewise. > * cp/cp-tree.h (enum overload_flags): Add TFF_MATCH_GNU_V3_DEMANGLER. > > * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_const_index. > (size_of_loc_descr): Likewise. > (output_loc_operands): Likewise. > (output_loc_operands_raw): Likewise. > (want_pubnames): New macro. > (dw_addr_op): New function. > (new_addr_loc_descr): Call dw_addr_op. > (add_AT_pubnames): Add DW_AT_GNU_pubnames/pubtypes only if > generating .debug_pubnames/pubtypes sections. > (add_pubname_string): Check for -gpubnames option. > (add_pubname): Likewise. > (add_pubtype): Likewise. > (output_pubnames): Likewise. > (mem_loc_descriptor): Call new_addr_loc_desc for TLS vars. > (loc_list_from_tree): Likewise. > (output_addr_table): Handle DW_OP_GNU_const_index. Add missing > newline. > (hash_loc_operands): Add DW_OP_GNU_const_index. > (compare_loc_operands): Likewise. > > * testsuite/g++.old-deja/g++.pt/memtemp77.C: Revert earlier change > to expected results. > * testsuite/g++.dg/ext/pretty3.C: Likewise. > * testsuite/g++.dg/warn/Wuninitializable-member.C: Likewise. > * testsuite/g++.dg/warn/pr35711.C: Likewise. > * testsuite/g++.dg/pr44486.C: Likewise. > OK. Diego.
Sign in to reply to this message.
>> +/* Whether to generate the DWARF accelerator tables in .debug_pubnames >> + and .debug_pubtypes. This is configured per-target, but can be >> + overridden by the -gpubnames or -gno-pubnames options. */ >> + >> +#define want_pubnames (debug_generate_pub_sections != -1 \ >> + ? debug_generate_pub_sections \ >> + : targetm.want_debug_pub_sections) >> + > > > Minor nit. Make it a static inline function? > > > OK otherwise. Done. I've updated the patch with this, and slipped in one more bug fix to output pubnames for all inline functions. Tests are running now. I'll send the updated patch shortly. Thanks, -cary
Sign in to reply to this message.
[Revised to address review comments and to fix a bug we found late: We've changed want_pubnames to a static inline function, and changed the pubnames output to include (ironically enough) inline functions.] This patch is for the google/gcc-4_6 branch. Fission improvements and bug fixes. Adds new DW_OP_GNU_const_index to handle TLS offsets in debug info. Adds -gpubnames/-gno-pubnames options to explicitly request .debug_pubnames/pubtypes sections. Adds style parameter to C/C++ pretty-printer so that we can get canonical pubnames without affecting diagnostic output. Bootstrapped and tested on x86_64. 2012-05-21 Sterling Augustine <saugustine@google.com> Cary Coutant <ccoutant@google.com> include/ * dwarf2.h: Add DW_OP_GNU_const_index. gcc/ * opts.c (finish_options): -gfission implies -gpubnames. (common_handle_option): Pass empty arg string to set_debug_level. * common.opt (gno-fission): New option. (gfission): Remove JoinedOrMissing, add RejectNegative. (gno-pubnames, gpubnames): New options. * target.def (want_debug_pub_sections): Change default to false. * gcc.c (check_live_switch): Check -g options for -gno- options. * c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Add support for gnu_v3 style. * c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enum constant. * cp/error.c (dump_decl): Add support for gnu_v3 style. (decl_as_string): Likewise. (lang_decl_name): Likewise. * cp/cp-lang.c (cxx_dwarf_name): Likewise. * cp/cp-tree.h (enum overload_flags): Add TFF_MATCH_GNU_V3_DEMANGLER. * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_const_index. (size_of_loc_descr): Likewise. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (dw_addr_op): New function. (new_addr_loc_descr): Call dw_addr_op. (want_pubnames): New function. (add_AT_pubnames): Add DW_AT_GNU_pubnames/pubtypes only if generating .debug_pubnames/pubtypes sections. (add_pubname_string): Check for -gpubnames option. (add_pubname): Likewise. (add_pubtype): Likewise. (output_pubnames): Likewise. (mem_loc_descriptor): Call new_addr_loc_desc for TLS vars. (loc_list_from_tree): Likewise. (gen_subprogram_die): Output pubnames for all inlined functions. (output_addr_table): Handle DW_OP_GNU_const_index. Add missing newline. (hash_loc_operands): Add DW_OP_GNU_const_index. (compare_loc_operands): Likewise. * testsuite/g++.old-deja/g++.pt/memtemp77.C: Revert earlier change to expected results. * testsuite/g++.dg/ext/pretty3.C: Likewise. * testsuite/g++.dg/warn/Wuninitializable-member.C: Likewise. * testsuite/g++.dg/warn/pr35711.C: Likewise. * testsuite/g++.dg/pr44486.C: Likewise. Index: include/dwarf2.h =================================================================== --- include/dwarf2.h (revision 187751) +++ include/dwarf2.h (working copy) @@ -546,8 +546,9 @@ enum dwarf_location_atom DW_OP_GNU_uninit = 0xf0, DW_OP_GNU_encoded_addr = 0xf1, DW_OP_GNU_implicit_pointer = 0xf2, - /* Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ + /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, /* HP extensions. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_is_value = 0xe1, Index: gcc/c-family/c-pretty-print.c =================================================================== --- gcc/c-family/c-pretty-print.c (revision 187751) +++ gcc/c-family/c-pretty-print.c (working copy) @@ -445,6 +445,9 @@ pp_c_specifier_qualifier_list (c_pretty_ { const enum tree_code code = TREE_CODE (t); + if (!(pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) + pp_c_type_qualifier_list (pp, t); + switch (code) { case REFERENCE_TYPE: @@ -489,7 +492,7 @@ pp_c_specifier_qualifier_list (c_pretty_ pp_simple_type_specifier (pp, t); break; } - if (TREE_CODE (t) != POINTER_TYPE) + if ((pp->flags & pp_c_flag_gnu_v3) && TREE_CODE (t) != POINTER_TYPE) pp_c_type_qualifier_list (pp, t); } Index: gcc/c-family/c-pretty-print.h =================================================================== --- gcc/c-family/c-pretty-print.h (revision 187751) +++ gcc/c-family/c-pretty-print.h (working copy) @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. typedef enum { pp_c_flag_abstract = 1 << 1, - pp_c_flag_last_bit = 2 + pp_c_flag_last_bit = 2, + pp_c_flag_gnu_v3 = 4 } pp_c_pretty_print_flags; Index: gcc/target.def =================================================================== --- gcc/target.def (revision 187751) +++ gcc/target.def (working copy) @@ -2795,7 +2795,7 @@ DEFHOOKPOD "True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections\ should be emitted. These sections are not used on most platforms, and\ in particular GDB does not use them.", - bool, true) + bool, false) DEFHOOKPOD (delay_sched2, "True if sched2 is not to be run at its normal place. \ Index: gcc/gcc.c =================================================================== --- gcc/gcc.c (revision 187751) +++ gcc/gcc.c (working copy) @@ -448,7 +448,7 @@ ignored. White space may also appear an colon in these constructs, except between . or * and the corresponding word. -The -O, -f, -m, and -W switches are handled specifically in these +The -O, -f, -g, -m, and -W switches are handled specifically in these constructs. If another value of -O or the negated form of a -f, -m, or -W switch is found later in the command line, the earlier switch value is ignored, except with {S*} where S is just one letter; this @@ -5867,7 +5867,7 @@ process_brace_body (const char *p, const on the command line. PREFIX_LENGTH is the length of XXX in an {XXX*} spec, or -1 if either exact match or %* is used. - A -O switch is obsoleted by a later -O switch. A -f, -m, or -W switch + A -O switch is obsoleted by a later -O switch. A -f, -g, -m, or -W switch whose value does not begin with "no-" is obsoleted by the same value with the "no-", similarly for a switch with the "no-" prefix. */ @@ -5904,7 +5904,7 @@ check_live_switch (int switchnum, int pr } break; - case 'W': case 'f': case 'm': + case 'W': case 'f': case 'm': case 'g': if (! strncmp (name + 1, "no-", 3)) { /* We have Xno-YYY, search for XYYY. */ Index: gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (revision 187751) +++ gcc/testsuite/g++.old-deja/g++.pt/memtemp77.C (working copy) @@ -19,7 +19,7 @@ const char* S3<char>::h(int) { return __ int main() { if (strcmp (S3<double>::h(7), - "static char const* S3<T>::h(U) [with U = int, T = double]") == 0) + "static const char* S3<T>::h(U) [with U = int, T = double]") == 0) return 0; else return 1; Index: gcc/testsuite/g++.dg/ext/pretty3.C =================================================================== --- gcc/testsuite/g++.dg/ext/pretty3.C (revision 187751) +++ gcc/testsuite/g++.dg/ext/pretty3.C (working copy) @@ -16,4 +16,4 @@ int main () { printf ("%s\n", D<int>().foo (0)); } -// { dg-final { scan-assembler "char const\\* D<U>::foo\\(typename B<U>::X\\)" } } +// { dg-final { scan-assembler "const char\\* D<U>::foo\\(typename B<U>::X\\)" } } Index: gcc/testsuite/g++.dg/warn/Wuninitializable-member.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (revision 187751) +++ gcc/testsuite/g++.dg/warn/Wuninitializable-member.C (working copy) @@ -8,7 +8,7 @@ public: }; class Y { - const int var;// { dg-warning "non-static const member 'int const Y::var' in class without a constructor" } + const int var;// { dg-warning "non-static const member 'const int Y::var' in class without a constructor" } public: int g(){ return 2*var; } }; Index: gcc/testsuite/g++.dg/warn/pr35711.C =================================================================== --- gcc/testsuite/g++.dg/warn/pr35711.C (revision 187751) +++ gcc/testsuite/g++.dg/warn/pr35711.C (working copy) @@ -4,5 +4,5 @@ int* foo (volatile int *p) { - return (int*)p; // { dg-warning "cast from type 'int volatile\\*' to type 'int\\*' casts away qualifiers" } + return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" } } Index: gcc/testsuite/g++.dg/pr44486.C =================================================================== --- gcc/testsuite/g++.dg/pr44486.C (revision 187751) +++ gcc/testsuite/g++.dg/pr44486.C (working copy) @@ -7,4 +7,4 @@ namespace { S f() { const char * s = __P int main() { f(); } -// { dg-final { scan-assembler "S \\(anonymous namespace\\)::f" } } +// { dg-final { scan-assembler "S \{anonymous\}::f" } } Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 187751) +++ gcc/cp/error.c (working copy) @@ -974,7 +974,12 @@ dump_decl (tree t, int flags) dump_scope (CP_DECL_CONTEXT (t), flags); flags &= ~TFF_UNQUALIFIED_NAME; if (DECL_NAME (t) == NULL_TREE) - pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + { + if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3)) + pp_cxx_ws_string (cxx_pp, M_("{anonymous}")); + else + pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)")); + } else pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); } @@ -2459,7 +2464,10 @@ decl_as_string (tree decl, int flags) { reinit_cxx_pp (); pp_translate_identifiers (cxx_pp) = false; + if (flags & TFF_MATCH_GNU_V3_DEMANGLER) + pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3; dump_decl (decl, flags); + pp_c_base (cxx_pp)->flags &= ~pp_c_flag_gnu_v3; return pp_formatted_text (cxx_pp); } @@ -2494,8 +2502,9 @@ lang_decl_name (tree decl, int v, bool t if (TREE_CODE (decl) == FUNCTION_DECL) dump_function_name (decl, TFF_PLAIN_IDENTIFIER); - else if (DECL_NAME (decl) == NULL && TREE_CODE (decl) == NAMESPACE_DECL) - pp_string (cxx_pp, M_("(anonymous namespace)")); + else if ((DECL_NAME (decl) == NULL_TREE) + && TREE_CODE (decl) == NAMESPACE_DECL) + dump_decl (decl, TFF_PLAIN_IDENTIFIER); else dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); Index: gcc/cp/cp-lang.c =================================================================== --- gcc/cp/cp-lang.c (revision 187751) +++ gcc/cp/cp-lang.c (working copy) @@ -185,8 +185,14 @@ cxx_dwarf_name (tree t, int verbosity) if (verbosity >= 2) return decl_as_string (t, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME - | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); + | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS + | TFF_MATCH_GNU_V3_DEMANGLER); + /* decl_as_string handles namespaces--especially anonymous ones--more + appropriately for debugging than cxx_printable_name. But + cxx_printable_name handles templates and global ctors and dtors better. */ + if (TREE_CODE (t) == NAMESPACE_DECL) + return decl_as_string (t, TFF_MATCH_GNU_V3_DEMANGLER); return cxx_printable_name (t, verbosity); } Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 187751) +++ gcc/cp/cp-tree.h (working copy) @@ -4365,7 +4365,9 @@ enum overload_flags { NO_SPECIAL = 0, DT TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the top-level entity. TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments - identical to their defaults. */ + identical to their defaults. + TFF_MATCH_GNU_V3_DEMANGLER: match the GNU v3 demangler's names for anonymous + namespaces and order of type-qualifiers vs type-specifiers. */ #define TFF_PLAIN_IDENTIFIER (0) #define TFF_SCOPE (1) @@ -4381,6 +4383,7 @@ enum overload_flags { NO_SPECIAL = 0, DT #define TFF_NO_FUNCTION_ARGUMENTS (1 << 10) #define TFF_UNQUALIFIED_NAME (1 << 11) #define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12) +#define TFF_MATCH_GNU_V3_DEMANGLER (1 << 13) /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM node. */ Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 187751) +++ gcc/dwarf2out.c (working copy) @@ -4782,6 +4782,8 @@ dwarf_stack_op_name (unsigned int op) return "DW_OP_GNU_implicit_pointer"; case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index"; + case DW_OP_GNU_const_index: + return "DW_OP_GNU_const_index"; default: return "OP_<unknown>"; @@ -4903,6 +4905,7 @@ size_of_loc_descr (dw_loc_descr_ref loc) size += DWARF2_ADDR_SIZE; break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: size += size_of_uleb128 (loc->dw_loc_oprnd1.val_index); break; case DW_OP_const1u: @@ -5284,8 +5287,9 @@ output_loc_operands (dw_loc_descr_ref lo break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: dw2_asm_output_data_uleb128 (loc->dw_loc_oprnd1.val_index, - "(address index)"); + "(index into .debug_addr)"); break; case DW_OP_GNU_implicit_pointer: @@ -5357,6 +5361,7 @@ output_loc_operands_raw (dw_loc_descr_re { case DW_OP_addr: case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: case DW_OP_implicit_value: /* We cannot output addresses in .cfi_escape, only bytes. */ gcc_unreachable (); @@ -6570,6 +6575,7 @@ static dw_loc_list_ref new_loc_list (dw_ const char *, const char *); static void output_loc_list (dw_loc_list_ref); static char *gen_internal_sym (const char *); +static bool want_pubnames (void); static void prune_unmark_dies (dw_die_ref); static void prune_unused_types_mark_generic_parms_dies (dw_die_ref); @@ -6589,17 +6595,30 @@ static bool generic_type_p (tree); static void schedule_generic_params_dies_gen (tree t); static void gen_scheduled_generic_parms_dies (void); +/* DW_OP_addr is relocated by the debug info consumer, while + tls relative operands should not be. */ + +static inline enum dwarf_location_atom dw_addr_op (bool dtprel) +{ + if (dtprel) + return (dwarf_split_debug_info ? DW_OP_GNU_const_index + : (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u)); + else + return (dwarf_split_debug_info ? DW_OP_GNU_addr_index : DW_OP_addr); +} + /* Return a pointer to a newly allocated address location description. If dwarf_split_debug_info is true, then record the address with the appropriate relocation. */ static inline dw_loc_descr_ref new_addr_loc_descr (rtx addr, int dtprel) { - dw_loc_descr_ref ref = new_loc_descr (DW_OP_addr, 0, 0); + dw_loc_descr_ref ref = new_loc_descr (dw_addr_op (dtprel), 0, 0); ref->dw_loc_oprnd1.val_class = dw_val_class_addr; ref->dw_loc_oprnd1.val_index = -1U; ref->dw_loc_oprnd1.v.val_addr = addr; + ref->dtprel = dtprel; if (dwarf_split_debug_info) { dw_attr_node attr; @@ -6610,7 +6629,6 @@ new_addr_loc_descr (rtx addr, int dtprel attr.dw_attr_val.val_index = -1U; attr.dw_attr_val.v.val_addr = addr; - ref->dw_loc_opc = DW_OP_GNU_addr_index; ref->dw_loc_oprnd1.val_index = add_addr_table_entry (&attr); } return ref; @@ -11926,15 +11944,30 @@ output_comp_unit (dw_die_ref die, int ou } } +/* Whether to generate the DWARF accelerator tables in .debug_pubnames + and .debug_pubtypes. This is configured per-target, but can be + overridden by the -gpubnames or -gno-pubnames options. */ + +static inline bool +want_pubnames (void) +{ + return (debug_generate_pub_sections != -1 + ? debug_generate_pub_sections + : targetm.want_debug_pub_sections); +} + /* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes. */ static void add_AT_pubnames (dw_die_ref die) { - /* FIXME: Should use add_AT_pubnamesptr. This works because most targets - don't care what the base section is. */ - add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); - add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + if (want_pubnames ()) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because most targets + don't care what the base section is. */ + add_AT_lineptr (die, DW_AT_GNU_pubnames, debug_pubnames_section_label); + add_AT_lineptr (die, DW_AT_GNU_pubtypes, debug_pubtypes_section_label); + } } /* Helper function to generate top-level dies for skeleton debug_info and @@ -12136,7 +12169,7 @@ dwarf2_name (tree decl, int scope) static void add_pubname_string (const char *str, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames ()) { pubname_entry e; @@ -12149,7 +12182,7 @@ add_pubname_string (const char *str, dw_ static void add_pubname (tree decl, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) + if (!GENERATE_MINIMUM_LINE_TABLE && want_pubnames ()) { if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) @@ -12182,7 +12215,7 @@ add_pubtype (tree decl, dw_die_ref die) { pubname_entry e; - if (!targetm.want_debug_pub_sections) + if (!want_pubnames ()) return; if ((TREE_PUBLIC (decl) @@ -12243,7 +12276,7 @@ output_pubnames (VEC (pubname_entry, gc) unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; - if (!targetm.want_debug_pub_sections || !info_section_emitted) + if (!want_pubnames () || !info_section_emitted) return; if (names == pubname_table) { @@ -14528,15 +14561,7 @@ mem_loc_descriptor (rtx rtl, enum machin if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel) break; - /* We used to emit DW_OP_addr here, but that's wrong, since - DW_OP_addr should be relocated by the debug info consumer, - while DW_OP_GNU_push_tls_address operand should not. */ - temp = new_loc_descr (DWARF2_ADDR_SIZE == 4 - ? DW_OP_const4u : DW_OP_const8u, 0, 0); - temp->dw_loc_oprnd1.val_class = dw_val_class_addr; - temp->dw_loc_oprnd1.val_index = -1U; - temp->dw_loc_oprnd1.v.val_addr = rtl; - temp->dtprel = true; + temp = new_addr_loc_descr (rtl, true); mem_loc_result = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0); add_loc_descr (&mem_loc_result, temp); @@ -16113,8 +16138,7 @@ loc_list_from_tree (tree loc, int want_a if (DECL_THREAD_LOCAL_P (loc)) { rtx rtl; - enum dwarf_location_atom first_op; - enum dwarf_location_atom second_op; + enum dwarf_location_atom tls_op; bool dtprel = false; if (targetm.have_tls) @@ -16132,9 +16156,8 @@ loc_list_from_tree (tree loc, int want_a operand shouldn't be. */ if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc)) return 0; - first_op = DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u; dtprel = true; - second_op = DW_OP_GNU_push_tls_address; + tls_op = DW_OP_GNU_push_tls_address; } else { @@ -16146,8 +16169,7 @@ loc_list_from_tree (tree loc, int want_a no longer appear in gimple code. We used the control variable in specific so that we could pick it up here. */ loc = DECL_VALUE_EXPR (loc); - first_op = DW_OP_addr; - second_op = DW_OP_form_tls_address; + tls_op = DW_OP_form_tls_address; } rtl = rtl_for_decl_location (loc); @@ -16160,19 +16182,8 @@ loc_list_from_tree (tree loc, int want_a if (! CONSTANT_P (rtl)) return 0; - if (dwarf_split_debug_info && first_op == DW_OP_addr) - ret = new_addr_loc_descr (rtl, dtprel); - else - { - ret = new_loc_descr (first_op, 0, 0); - ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.val_index = -1U; - ret->dw_loc_oprnd1.v.val_addr = rtl; - } - - ret->dtprel = dtprel; - - ret1 = new_loc_descr (second_op, 0, 0); + ret = new_addr_loc_descr (rtl, dtprel); + ret1 = new_loc_descr (tls_op, 0, 0); add_loc_descr (&ret, ret1); have_address = 1; @@ -19793,6 +19804,7 @@ gen_subprogram_die (tree decl, dw_die_re { subr_die = new_die (DW_TAG_subprogram, context_die, decl); add_AT_specification (subr_die, old_die); + add_pubname (decl, subr_die); if (get_AT_file (old_die, DW_AT_decl_file) != file_index) add_AT_file (subr_die, DW_AT_decl_file, file_index); if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line) @@ -19807,6 +19819,7 @@ gen_subprogram_die (tree decl, dw_die_re add_AT_flag (subr_die, DW_AT_external, 1); add_name_and_src_coords_attributes (subr_die, decl); + add_pubname (decl, subr_die); if (debug_info_level > DINFO_LEVEL_TERSE) { add_prototyped_attribute (subr_die, TREE_TYPE (decl)); @@ -19918,7 +19931,6 @@ gen_subprogram_die (tree decl, dw_die_re } #endif - add_pubname (decl, subr_die); } else { /* Generate pubnames entries for the split function code @@ -19940,7 +19952,6 @@ gen_subprogram_die (tree decl, dw_die_re add_ranges_by_labels (subr_die, fde->dw_fde_second_begin, fde->dw_fde_second_end, &range_list_added, false); - add_pubname (decl, subr_die); if (range_list_added) add_ranges (NULL); } @@ -19962,8 +19973,6 @@ gen_subprogram_die (tree decl, dw_die_re fde->dw_fde_begin, false); add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false); - /* Add it. */ - add_pubname (decl, subr_die); /* Build a minimal DIE for the secondary section. */ seg_die = new_die (DW_TAG_subprogram, @@ -19999,7 +20008,6 @@ gen_subprogram_die (tree decl, dw_die_re { add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin, false); add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false); - add_pubname (decl, subr_die); } } @@ -23195,7 +23203,8 @@ output_addr_table (void) gcc_assert (targetm.asm_out.output_dwarf_dtprel); targetm.asm_out.output_dwarf_dtprel (asm_out_file, DWARF2_ADDR_SIZE, - AT_addr (node)); + node->dw_attr_val.v.val_addr); + fputc ('\n', asm_out_file); break; case dw_val_class_lbl_id: dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (node), "%s", name); @@ -23949,6 +23958,7 @@ hash_loc_operands (dw_loc_descr_ref loc, hash = iterative_hash_rtx (val1->v.val_addr, hash); break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_ref attr = VEC_index (dw_attr_node, addr_index_table, val1->val_index); @@ -24116,6 +24126,7 @@ compare_loc_operands (dw_loc_descr_ref x hash_addr: return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr); case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: { dw_attr_node *attrx1 = VEC_index (dw_attr_node, addr_index_table, Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 187751) +++ gcc/opts.c (working copy) @@ -850,6 +850,10 @@ finish_options (struct gcc_options *opts /* Turn on -ffunction-sections when -freorder-functions=* is used. */ if (opts->x_flag_reorder_functions > 1) opts->x_flag_function_sections = 1; + + /* The -gfission option requires -gpubnames. */ + if (opts->x_dwarf_split_debug_info) + opts->x_debug_generate_pub_sections = 1; } #define LEFT_COLUMN 27 @@ -1714,7 +1718,7 @@ common_handle_option (struct gcc_options break; case OPT_gfission: - set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set, + set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set, loc); break; Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 187751) +++ gcc/common.opt (working copy) @@ -2374,8 +2374,12 @@ gdwarf- Common Joined UInteger Var(dwarf_version) Init(2) Negative(gstabs) Generate debug information in DWARF v2 (or later) format +gno-fission +Common Driver RejectNegative Var(dwarf_split_debug_info,0) Init(0) +Don't generate debug information in separate .dwo files + gfission -Common Driver JoinedOrMissing Var(dwarf_split_debug_info,1) +Common Driver RejectNegative Var(dwarf_split_debug_info,1) Generate debug information in separate .dwo files ggdb @@ -2386,6 +2390,14 @@ gmlt Common RejectNegative Generate debug information at level 1 with minimal line table +gno-pubnames +Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1) +Don't generate DWARF pubnames and pubtypes sections. + +gpubnames +Common RejectNegative Var(debug_generate_pub_sections, 1) +Generate DWARF pubnames and pubtypes sections. + gstabs Common JoinedOrMissing Negative(gstabs+) Generate debug information in STABS format -- This patch is available for review at http://codereview.appspot.com/6219049
Sign in to reply to this message.
On 12-05-22 21:56 , Cary Coutant wrote: > [Revised to address review comments and to fix a bug we found late: > We've changed want_pubnames to a static inline function, and changed > the pubnames output to include (ironically enough) inline functions.] > > This patch is for the google/gcc-4_6 branch. > > Fission improvements and bug fixes. Adds new DW_OP_GNU_const_index to > handle TLS offsets in debug info. Adds -gpubnames/-gno-pubnames options > to explicitly request .debug_pubnames/pubtypes sections. Adds style > parameter to C/C++ pretty-printer so that we can get canonical pubnames > without affecting diagnostic output. > > Bootstrapped and tested on x86_64. > > > 2012-05-21 Sterling Augustine<saugustine@google.com> > Cary Coutant<ccoutant@google.com> > > include/ > * dwarf2.h: Add DW_OP_GNU_const_index. > > gcc/ > * opts.c (finish_options): -gfission implies -gpubnames. > (common_handle_option): Pass empty arg string to set_debug_level. > * common.opt (gno-fission): New option. > (gfission): Remove JoinedOrMissing, add RejectNegative. > (gno-pubnames, gpubnames): New options. > * target.def (want_debug_pub_sections): Change default to false. > * gcc.c (check_live_switch): Check -g options for -gno- options. > > * c-family/c-pretty-print.c (pp_c_specifier_qualifier_list): Add > support for gnu_v3 style. > * c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enum constant. > * cp/error.c (dump_decl): Add support for gnu_v3 style. > (decl_as_string): Likewise. > (lang_decl_name): Likewise. > * cp/cp-lang.c (cxx_dwarf_name): Likewise. > * cp/cp-tree.h (enum overload_flags): Add TFF_MATCH_GNU_V3_DEMANGLER. > > * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_const_index. > (size_of_loc_descr): Likewise. > (output_loc_operands): Likewise. > (output_loc_operands_raw): Likewise. > (dw_addr_op): New function. > (new_addr_loc_descr): Call dw_addr_op. > (want_pubnames): New function. > (add_AT_pubnames): Add DW_AT_GNU_pubnames/pubtypes only if > generating .debug_pubnames/pubtypes sections. > (add_pubname_string): Check for -gpubnames option. > (add_pubname): Likewise. > (add_pubtype): Likewise. > (output_pubnames): Likewise. > (mem_loc_descriptor): Call new_addr_loc_desc for TLS vars. > (loc_list_from_tree): Likewise. > (gen_subprogram_die): Output pubnames for all inlined functions. > (output_addr_table): Handle DW_OP_GNU_const_index. Add missing > newline. > (hash_loc_operands): Add DW_OP_GNU_const_index. > (compare_loc_operands): Likewise. > > * testsuite/g++.old-deja/g++.pt/memtemp77.C: Revert earlier change > to expected results. > * testsuite/g++.dg/ext/pretty3.C: Likewise. > * testsuite/g++.dg/warn/Wuninitializable-member.C: Likewise. > * testsuite/g++.dg/warn/pr35711.C: Likewise. > * testsuite/g++.dg/pr44486.C: Likewise. OK with a couple of nits I found on the second read. > @@ -445,6 +445,9 @@ pp_c_specifier_qualifier_list (c_pretty_ > { > const enum tree_code code = TREE_CODE (t); > > + if (!(pp->flags& pp_c_flag_gnu_v3)&& TREE_CODE (t) != POINTER_TYPE) > + pp_c_type_qualifier_list (pp, t); You can use 'code' here instead of TREE_CODE(t). Either that, or remove the declaration of 'code' above. > + > switch (code) > { > case REFERENCE_TYPE: > @@ -489,7 +492,7 @@ pp_c_specifier_qualifier_list (c_pretty_ > pp_simple_type_specifier (pp, t); > break; > } > - if (TREE_CODE (t) != POINTER_TYPE) > + if ((pp->flags& pp_c_flag_gnu_v3)&& TREE_CODE (t) != POINTER_TYPE) Likewise here. > @@ -6589,17 +6595,30 @@ static bool generic_type_p (tree); > static void schedule_generic_params_dies_gen (tree t); > static void gen_scheduled_generic_parms_dies (void); > > +/* DW_OP_addr is relocated by the debug info consumer, while > + tls relative operands should not be. */ > + > +static inline enum dwarf_location_atom dw_addr_op (bool dtprel) Can you describe what DTPREL is used for here? Diego.
Sign in to reply to this message.
> OK with a couple of nits I found on the second read. > >> + if (!(pp->flags& pp_c_flag_gnu_v3)&& TREE_CODE (t) != POINTER_TYPE) >> + pp_c_type_qualifier_list (pp, t); > > You can use 'code' here instead of TREE_CODE(t). Either that, or remove the > declaration of 'code' above. > >> - if (TREE_CODE (t) != POINTER_TYPE) >> + if ((pp->flags& pp_c_flag_gnu_v3)&& TREE_CODE (t) != POINTER_TYPE) > > Likewise here. Fixed. Note that the original code was guilty as well. :-) >> +/* DW_OP_addr is relocated by the debug info consumer, while >> + tls relative operands should not be. */ >> + >> +static inline enum dwarf_location_atom dw_addr_op (bool dtprel) > > Can you describe what DTPREL is used for here? I've rewritten the comment as follows: /* Return the operator to use for an address of a variable. DTPREL is true for thread-local variables whose address is really an offset relative to the TLS pointer, which will need link-time relocation, but will not need relocation by the DWARF consumer. For those, we use DW_OP_const*. For regular variables, which need both link-time relocation and consumer-level relocation (e.g., to account for shared objects loaded at a random address), we use DW_OP_addr*. */ Thanks! -cary
Sign in to reply to this message.
|