Introduce -grecord-gcc-switches=default|all|none alongside the existing -grecord-gcc-switches option. The all mode records all command line switches in DW_AT_producer, while default preserves current filtering. Update producer-string generation and documentation accordingly.
This allows this option to be used like `-grecord-command-line` in LLVM for more complete recording of compiler invocations. For performance analysis use cases, having all switches recorded like `-D` and `-I` can help tools better understand the build context. It can be beneficial to let analyzer tools understand the full context of the compilation from the DWARF info. Signed-off-by: Yangyu Chen <[email protected]> gcc/ChangeLog: * common.opt: Add -grecord-gcc-switches option with modes. * doc/invoke.texi: Document -grecord-gcc-switches option. * dwarf2out.cc (dwarf2out_early_finish): Pass new mode to gen_producer_string. * opts.cc (gen_command_line_string): Ditto. (gen_producer_string): Add new parameter for record-gcc-switches mode and implement filtering for 'all' mode. * opts.h (gen_command_line_string): Ditto. * toplev.cc (init_asm_output): Pass new mode to gen_producer_string. (process_options): Ditto. --- gcc/common.opt | 17 ++++ gcc/doc/invoke.texi | 5 ++ gcc/dwarf2out.cc | 3 +- gcc/opts.cc | 202 ++++++++++++++++++++++++-------------------- gcc/opts.h | 6 +- gcc/toplev.cc | 9 +- 6 files changed, 146 insertions(+), 96 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index 88b79bbf8f5..7fc3b341541 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3770,6 +3770,23 @@ grecord-gcc-switches Common Driver Var(dwarf_record_gcc_switches) Init(1) Record gcc command line switches in DWARF DW_AT_producer. +grecord-gcc-switches= +Common Driver Joined RejectNegative Var(dwarf_record_gcc_switches) Enum(record_gcc_switches) +-grecord-gcc-switches[=default|all|none] Record gcc command line +switches in DWARF DW_AT_producer. + +Enum +Name(record_gcc_switches) Type(int) + +EnumValue +Enum(record_gcc_switches) String(none) Value(0) + +EnumValue +Enum(record_gcc_switches) String(default) Value(1) + +EnumValue +Enum(record_gcc_switches) String(all) Value(2) + gsplit-dwarf Common Driver Var(dwarf_split_debug_info) Init(0) Generate debug information in separate .dwo files. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 58254b82b0e..098235dd525 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13069,6 +13069,7 @@ debugging information. @opindex grecord-gcc-switches @opindex gno-record-gcc-switches @item -grecord-gcc-switches +@itemx -grecord-gcc-switches=@var{mode} @itemx -gno-record-gcc-switches This switch causes the command-line options used to invoke the compiler that may affect code generation to be appended to the @@ -13076,6 +13077,10 @@ DW_AT_producer attribute in DWARF debugging information. The options are concatenated with spaces separating them from each other and from the compiler version. It is enabled by default. +The @var{mode} value may be @samp{default} (the existing filtering), +@samp{all} (record all command-line switches, including preprocessor +options such as @option{-I}, @option{-D}, and @option{-U}), or +@samp{none} (equivalent to @option{-gno-record-gcc-switches}). See also @option{-frecord-gcc-switches} for another way of storing compiler options into the object file. diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 31ff7ff1905..cd1e10e5562 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -33610,7 +33610,8 @@ dwarf2out_early_finish (const char *filename) if (dwarf_record_gcc_switches) producer_string = gen_producer_string (lang_hooks.name, save_decoded_options, - save_decoded_options_count); + save_decoded_options_count, + dwarf_record_gcc_switches); else producer_string = concat (lang_hooks.name, " ", version_string, NULL); diff --git a/gcc/opts.cc b/gcc/opts.cc index 6323fd58801..78fedccac71 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -3895,107 +3895,127 @@ make_option_url (diagnostics::option_id option_id) const char * gen_command_line_string (cl_decoded_option *options, - unsigned int options_count) + unsigned int options_count, + int record_gcc_switches_mode) { auto_vec<const char *> switches; char *options_string, *tail; const char *p; size_t len = 0; + const bool record_all_switches = (record_gcc_switches_mode > 1); for (unsigned i = 0; i < options_count; i++) - switch (options[i].opt_index) - { - case OPT_o: - case OPT_d: - case OPT_dumpbase: - case OPT_dumpbase_ext: - case OPT_dumpdir: - case OPT_quiet: - case OPT_version: - case OPT_v: - case OPT_w: - case OPT_L: - case OPT_I: - case OPT_SPECIAL_unknown: - case OPT_SPECIAL_ignore: - case OPT_SPECIAL_warn_removed: - case OPT_SPECIAL_program_name: - case OPT_SPECIAL_input_file: - case OPT_grecord_gcc_switches: - case OPT_frecord_gcc_switches: - case OPT__output_pch: - case OPT_fdiagnostics_show_highlight_colors: - case OPT_fdiagnostics_show_location_: - case OPT_fdiagnostics_show_option: - case OPT_fdiagnostics_show_caret: - case OPT_fdiagnostics_show_event_links: - case OPT_fdiagnostics_show_labels: - case OPT_fdiagnostics_show_line_numbers: - case OPT_fdiagnostics_color_: - case OPT_fdiagnostics_format_: - case OPT_fdiagnostics_show_nesting: - case OPT_fdiagnostics_show_nesting_locations: - case OPT_fdiagnostics_show_nesting_levels: - case OPT_fverbose_asm: - case OPT____: - case OPT__sysroot_: - case OPT_nostdinc: - case OPT_nostdinc__: - case OPT_fpreprocessed: - case OPT_fltrans_output_list_: - case OPT_fresolution_: - case OPT_fdebug_prefix_map_: - case OPT_fmacro_prefix_map_: - case OPT_ffile_prefix_map_: - case OPT_fprofile_prefix_map_: - case OPT_fcanon_prefix_map: - case OPT_fcompare_debug: - case OPT_fchecking: - case OPT_fchecking_: - /* Ignore these. */ - continue; - case OPT_D: - case OPT_U: - if (startswith (options[i].arg, "_FORTIFY_SOURCE") - && (options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] == '\0' - || (options[i].opt_index == OPT_D - && options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] == '='))) - { - switches.safe_push (options[i].orig_option_with_args_text); - len += strlen (options[i].orig_option_with_args_text) + 1; - } - /* Otherwise ignore these. */ - continue; - case OPT_flto_: + { + if (record_all_switches) { - const char *lto_canonical = "-flto"; - switches.safe_push (lto_canonical); - len += strlen (lto_canonical) + 1; - break; + switch (options[i].opt_index) + { + case OPT_SPECIAL_unknown: + case OPT_SPECIAL_ignore: + case OPT_SPECIAL_warn_removed: + case OPT_SPECIAL_program_name: + case OPT_SPECIAL_input_file: + continue; + default: + switches.safe_push (options[i].orig_option_with_args_text); + len += strlen (options[i].orig_option_with_args_text) + 1; + continue; + } } - default: - if (cl_options[options[i].opt_index].flags - & CL_NO_DWARF_RECORD) + + switch (options[i].opt_index) + { + case OPT_o: + case OPT_d: + case OPT_dumpbase: + case OPT_dumpbase_ext: + case OPT_dumpdir: + case OPT_quiet: + case OPT_version: + case OPT_v: + case OPT_w: + case OPT_L: + case OPT_I: + case OPT_SPECIAL_unknown: + case OPT_SPECIAL_ignore: + case OPT_SPECIAL_warn_removed: + case OPT_SPECIAL_program_name: + case OPT_SPECIAL_input_file: + case OPT_grecord_gcc_switches_: + case OPT_frecord_gcc_switches: + case OPT__output_pch: + case OPT_fdiagnostics_show_highlight_colors: + case OPT_fdiagnostics_show_location_: + case OPT_fdiagnostics_show_option: + case OPT_fdiagnostics_show_caret: + case OPT_fdiagnostics_show_event_links: + case OPT_fdiagnostics_show_labels: + case OPT_fdiagnostics_show_line_numbers: + case OPT_fdiagnostics_color_: + case OPT_fdiagnostics_format_: + case OPT_fdiagnostics_show_nesting: + case OPT_fdiagnostics_show_nesting_locations: + case OPT_fdiagnostics_show_nesting_levels: + case OPT_fverbose_asm: + case OPT____: + case OPT__sysroot_: + case OPT_nostdinc: + case OPT_nostdinc__: + case OPT_fpreprocessed: + case OPT_fltrans_output_list_: + case OPT_fresolution_: + case OPT_fdebug_prefix_map_: + case OPT_fmacro_prefix_map_: + case OPT_ffile_prefix_map_: + case OPT_fprofile_prefix_map_: + case OPT_fcanon_prefix_map: + case OPT_fcompare_debug: + case OPT_fchecking: + case OPT_fchecking_: + /* Ignore these. */ + continue; + case OPT_D: + case OPT_U: + if (startswith (options[i].arg, "_FORTIFY_SOURCE") + && (options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] == '\0' + || (options[i].opt_index == OPT_D + && options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] + == '='))) + { + switches.safe_push (options[i].orig_option_with_args_text); + len += strlen (options[i].orig_option_with_args_text) + 1; + } + /* Otherwise ignore these. */ continue; - gcc_checking_assert (options[i].canonical_option[0][0] == '-'); - switch (options[i].canonical_option[0][1]) + case OPT_flto_: { - case 'M': - case 'i': - case 'W': - continue; - case 'f': - if (strncmp (options[i].canonical_option[0] + 2, - "dump", 4) == 0) - continue; - break; - default: + const char *lto_canonical = "-flto"; + switches.safe_push (lto_canonical); + len += strlen (lto_canonical) + 1; break; } - switches.safe_push (options[i].orig_option_with_args_text); - len += strlen (options[i].orig_option_with_args_text) + 1; - break; - } + default: + if (cl_options[options[i].opt_index].flags & CL_NO_DWARF_RECORD) + continue; + gcc_checking_assert (options[i].canonical_option[0][0] == '-'); + switch (options[i].canonical_option[0][1]) + { + case 'M': + case 'i': + case 'W': + continue; + case 'f': + if (strncmp (options[i].canonical_option[0] + 2, "dump", 4) == 0) + continue; + break; + default: + break; + } + switches.safe_push (options[i].orig_option_with_args_text); + len += strlen (options[i].orig_option_with_args_text) + 1; + break; + } + } options_string = XNEWVEC (char, len + 1); tail = options_string; @@ -4021,9 +4041,11 @@ gen_command_line_string (cl_decoded_option *options, char * gen_producer_string (const char *language_string, cl_decoded_option *options, - unsigned int options_count) + unsigned int options_count, + int record_gcc_switches_mode) { - char *cmdline = gen_command_line_string (options, options_count); + char *cmdline = gen_command_line_string (options, options_count, + record_gcc_switches_mode); char *combined = concat (language_string, " ", version_string, " ", cmdline, NULL); free (cmdline); diff --git a/gcc/opts.h b/gcc/opts.h index a59475b1daf..f26e6cea581 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -519,10 +519,12 @@ extern void parse_options_from_collect_gcc_options (const char *, obstack *, extern void prepend_xassembler_to_collect_as_options (const char *, obstack *); extern char *gen_command_line_string (cl_decoded_option *options, - unsigned int options_count); + unsigned int options_count, + int record_gcc_switches_mode); extern char *gen_producer_string (const char *language_string, cl_decoded_option *options, - unsigned int options_count); + unsigned int options_count, + int record_gcc_switches_mode); /* Set OPTION in OPTS to VALUE if the option is not set in OPTS_SET. */ diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 9c93eb8ce1d..da8436eecf8 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -735,7 +735,8 @@ init_asm_output (const char *name) const char *str = gen_producer_string (lang_hooks.name, save_decoded_options, - save_decoded_options_count); + save_decoded_options_count, + 1); targetm.asm_out.record_gcc_switches (str); } else @@ -750,7 +751,8 @@ init_asm_output (const char *name) fputs (ASM_COMMENT_START, asm_out_file); fputs (" options passed: ", asm_out_file); char *cmdline = gen_command_line_string (save_decoded_options, - save_decoded_options_count); + save_decoded_options_count, + 1); fputs (cmdline, asm_out_file); free (cmdline); fputc ('\n', asm_out_file); @@ -1426,7 +1428,8 @@ process_options () { fputs ("options passed: ", stderr); char *cmdline = gen_command_line_string (save_decoded_options, - save_decoded_options_count); + save_decoded_options_count, + 1); fputs (cmdline, stderr); free (cmdline); -- 2.51.0
