On Thu, May 13, 2021 at 12:53 AM Indu Bhagat via Gcc-patches
<[email protected]> wrote:
>
> [No changes from V2]
>
> To support multiple debug formats, we need to move away from explicit
> enumeration of each individual combination of debug formats.
OK.
Thanks,
Richard.
> gcc/c-family/ChangeLog:
>
> * c-opts.c (c_common_post_options): Adjust access to debug_type_names.
> * c-pch.c (struct c_pch_validity): Use type uint32_t.
> (pch_init): Renamed member.
> (c_common_valid_pch): Adjust access to debug_type_names.
>
> gcc/ChangeLog:
>
> * common.opt: Change type to support bitmasks.
> * flag-types.h (enum debug_info_type): Rename enumerator constants.
> (NO_DEBUG): New bitmask.
> (DBX_DEBUG): Likewise.
> (DWARF2_DEBUG): Likewise.
> (XCOFF_DEBUG): Likewise.
> (VMS_DEBUG): Likewise.
> (VMS_AND_DWARF2_DEBUG): Likewise.
> * flags.h (debug_set_to_format): New function declaration.
> (debug_set_count): Likewise.
> (debug_set_names): Likewise.
> * opts.c (debug_type_masks): Array of bitmasks for debug formats.
> (debug_set_to_format): New function definition.
> (debug_set_count): Likewise.
> (debug_set_names): Likewise.
> (set_debug_level): Update access to debug_type_names.
> * toplev.c: Likewise.
>
> gcc/objc/ChangeLog:
>
> * objc-act.c (synth_module_prologue): Use uint32_t instead of enum
> debug_info_type.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/pch/valid-1.c: Adjust diagnostic message in testcase.
> * lib/dg-pch.exp: Adjust diagnostic message.
> ---
> gcc/c-family/c-opts.c | 7 ++-
> gcc/c-family/c-pch.c | 12 ++--
> gcc/common.opt | 2 +-
> gcc/flag-types.h | 29 +++++++---
> gcc/flags.h | 17 +++++-
> gcc/objc/objc-act.c | 2 +-
> gcc/opts.c | 109
> +++++++++++++++++++++++++++++++++----
> gcc/testsuite/gcc.dg/pch/valid-1.c | 2 +-
> gcc/testsuite/lib/dg-pch.exp | 4 +-
> gcc/toplev.c | 9 ++-
> 10 files changed, 157 insertions(+), 36 deletions(-)
>
> diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
> index 89e05a4..60b5802 100644
> --- a/gcc/c-family/c-opts.c
> +++ b/gcc/c-family/c-opts.c
> @@ -1112,9 +1112,10 @@ c_common_post_options (const char **pfilename)
> /* Only -g0 and -gdwarf* are supported with PCH, for other
> debug formats we warn here and refuse to load any PCH files. */
> if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
> - warning (OPT_Wdeprecated,
> - "the %qs debug format cannot be used with "
> - "pre-compiled headers", debug_type_names[write_symbols]);
> + warning (OPT_Wdeprecated,
> + "the %qs debug info cannot be used with "
> + "pre-compiled headers",
> + debug_set_names (write_symbols & ~DWARF2_DEBUG));
> }
> else if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
> c_common_no_more_pch ();
> diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
> index fd94c37..8f0f760 100644
> --- a/gcc/c-family/c-pch.c
> +++ b/gcc/c-family/c-pch.c
> @@ -52,7 +52,7 @@ enum {
>
> struct c_pch_validity
> {
> - unsigned char debug_info_type;
> + uint32_t pch_write_symbols;
> signed char match[MATCH_SIZE];
> void (*pch_init) (void);
> size_t target_data_length;
> @@ -108,7 +108,7 @@ pch_init (void)
> pch_outfile = f;
>
> memset (&v, '\0', sizeof (v));
> - v.debug_info_type = write_symbols;
> + v.pch_write_symbols = write_symbols;
> {
> size_t i;
> for (i = 0; i < MATCH_SIZE; i++)
> @@ -252,13 +252,13 @@ c_common_valid_pch (cpp_reader *pfile, const char
> *name, int fd)
> /* The allowable debug info combinations are that either the PCH file
> was built with the same as is being used now, or the PCH file was
> built for some kind of debug info but now none is in use. */
> - if (v.debug_info_type != write_symbols
> + if (v.pch_write_symbols != write_symbols
> && write_symbols != NO_DEBUG)
> {
> cpp_warning (pfile, CPP_W_INVALID_PCH,
> - "%s: created with -g%s, but used with -g%s", name,
> - debug_type_names[v.debug_info_type],
> - debug_type_names[write_symbols]);
> + "%s: created with '%s' debug info, but used with '%s'",
> name,
> + debug_set_names (v.pch_write_symbols),
> + debug_set_names (write_symbols));
> return 2;
> }
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index a75b44e..ffb968d 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -109,7 +109,7 @@ bool exit_after_options
> ; flag-types.h for the definitions of the different possible types of
> ; debugging information.
> Variable
> -enum debug_info_type write_symbols = NO_DEBUG
> +uint32_t write_symbols = NO_DEBUG
>
> ; Level of debugging information we are producing. See flag-types.h
> ; for the definitions of the different possible levels.
> diff --git a/gcc/flag-types.h b/gcc/flag-types.h
> index a038c8f..d60bb30 100644
> --- a/gcc/flag-types.h
> +++ b/gcc/flag-types.h
> @@ -24,15 +24,30 @@ along with GCC; see the file COPYING3. If not see
>
> enum debug_info_type
> {
> - NO_DEBUG, /* Write no debug info. */
> - DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */
> - DWARF2_DEBUG, /* Write Dwarf v2 debug info (using dwarf2out.c).
> */
> - XCOFF_DEBUG, /* Write IBM/Xcoff debug info (using dbxout.c). */
> - VMS_DEBUG, /* Write VMS debug info (using vmsdbgout.c). */
> - VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
> - and DWARF v2 debug info (using dwarf2out.c). */
> + DINFO_TYPE_NONE = 0, /* No debug info. */
> + DINFO_TYPE_DBX = 1, /* BSD .stabs for DBX. */
> + DINFO_TYPE_DWARF2 = 2, /* Dwarf v2 debug info. */
> + DINFO_TYPE_XCOFF = 3, /* IBM/Xcoff debug info. */
> + DINFO_TYPE_VMS = 4, /* VMS debug info. */
> + DINFO_TYPE_MAX = DINFO_TYPE_VMS /* Marker only. */
> };
>
> +#define NO_DEBUG (0U)
> +/* Write DBX debug info (using dbxout.c). */
> +#define DBX_DEBUG (1U << DINFO_TYPE_DBX)
> +/* Write DWARF2 debug info (using dwarf2out.c). */
> +#define DWARF2_DEBUG (1U << DINFO_TYPE_DWARF2)
> +/* Write IBM/XCOFF debug info (using dbxout.c). */
> +#define XCOFF_DEBUG (1U << DINFO_TYPE_XCOFF)
> +/* Write VMS debug info (using vmsdbgout.c). */
> +#define VMS_DEBUG (1U << DINFO_TYPE_VMS)
> +/* Note: Adding new definitions to handle -combination- of debug formats,
> + like VMS_AND_DWARF2_DEBUG is not recommended. This definition remains
> + here for historical reasons. */
> +/* Write VMS debug info (using vmsdbgout.c) and DWARF v2 debug info (using
> + dwarf2out.c). */
> +#define VMS_AND_DWARF2_DEBUG ((VMS_DEBUG | DWARF2_DEBUG))
> +
> enum debug_info_levels
> {
> DINFO_LEVEL_NONE, /* Write no debugging info. */
> diff --git a/gcc/flags.h b/gcc/flags.h
> index 0c4409e..3415493 100644
> --- a/gcc/flags.h
> +++ b/gcc/flags.h
> @@ -22,9 +22,24 @@ along with GCC; see the file COPYING3. If not see
>
> #if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
>
> -/* Names of debug_info_type, for error messages. */
> +/* Names of fundamental debug info formats indexed by enum
> + debug_info_type. */
> +
> extern const char *const debug_type_names[];
>
> +/* Get enum debug_info_type of the specified debug format, for error
> messages.
> + Can be used only for individual debug format types. */
> +
> +extern enum debug_info_type debug_set_to_format (uint32_t debug_info_set);
> +
> +/* Get the number of debug formats enabled for output. */
> +
> +unsigned int debug_set_count (uint32_t w_symbols);
> +
> +/* Get the names of the debug formats enabled for output. */
> +
> +const char * debug_set_names (uint32_t w_symbols);
> +
> extern void strip_off_ending (char *, int);
> extern int base_of_path (const char *path, const char **base_out);
>
> diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
> index 796256d..8d106a4 100644
> --- a/gcc/objc/objc-act.c
> +++ b/gcc/objc/objc-act.c
> @@ -3078,7 +3078,7 @@ static void
> synth_module_prologue (void)
> {
> tree type;
> - enum debug_info_type save_write_symbols = write_symbols;
> + uint32_t save_write_symbols = write_symbols;
> const struct gcc_debug_hooks *const save_hooks = debug_hooks;
>
> /* Suppress outputting debug symbols, because
> diff --git a/gcc/opts.c b/gcc/opts.c
> index fe6fddb..1604241 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -37,12 +37,95 @@ along with GCC; see the file COPYING3. If not see
>
> static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
>
> -/* Indexed by enum debug_info_type. */
> +/* Names of fundamental debug info formats indexed by enum
> + debug_info_type. */
> +
> const char *const debug_type_names[] =
> {
> "none", "stabs", "dwarf-2", "xcoff", "vms"
> };
>
> +/* Bitmasks of fundamental debug info formats indexed by enum
> + debug_info_type. */
> +
> +static uint32_t debug_type_masks[] =
> +{
> + NO_DEBUG, DBX_DEBUG, DWARF2_DEBUG, XCOFF_DEBUG, VMS_DEBUG
> +};
> +
> +/* Names of the set of debug formats requested by user. Updated and accessed
> + via debug_set_names. */
> +
> +static char df_set_names[sizeof "none stabs dwarf-2 xcoff vms"];
> +
> +/* Get enum debug_info_type of the specified debug format, for error
> messages.
> + Can be used only for individual debug format types. */
> +
> +enum debug_info_type
> +debug_set_to_format (uint32_t debug_info_set)
> +{
> + int idx = 0;
> + enum debug_info_type dinfo_type = DINFO_TYPE_NONE;
> + /* Find first set bit. */
> + if (debug_info_set)
> + idx = exact_log2 (debug_info_set & - debug_info_set);
> + /* Check that only one bit is set, if at all. This function is meant to be
> + used only for vanilla debug_info_set bitmask values, i.e. for individual
> + debug format types upto DINFO_TYPE_MAX. */
> + gcc_assert ((debug_info_set & (debug_info_set - 1)) == 0);
> + dinfo_type = (enum debug_info_type)idx;
> + gcc_assert (dinfo_type <= DINFO_TYPE_MAX);
> + return dinfo_type;
> +}
> +
> +/* Get the number of debug formats enabled for output. */
> +
> +unsigned int
> +debug_set_count (uint32_t w_symbols)
> +{
> + unsigned int count = 0;
> + while (w_symbols)
> + {
> + ++ count;
> + w_symbols &= ~ (w_symbols & - w_symbols);
> + }
> + return count;
> +}
> +
> +/* Get the names of the debug formats enabled for output. */
> +
> +const char *
> +debug_set_names (uint32_t w_symbols)
> +{
> + uint32_t df_mask = 0;
> + /* Reset the string to be returned. */
> + memset (df_set_names, 0, sizeof (df_set_names));
> + /* Get the popcount. */
> + int num_set_df = debug_set_count (w_symbols);
> + /* Iterate over the debug formats. Add name string for those enabled. */
> + for (int i = DINFO_TYPE_NONE; i <= DINFO_TYPE_MAX; i++)
> + {
> + df_mask = debug_type_masks[i];
> + if (w_symbols & df_mask)
> + {
> + strcat (df_set_names, debug_type_names[i]);
> + num_set_df--;
> + if (num_set_df)
> + strcat (df_set_names, " ");
> + else
> + break;
> + }
> + else if (!w_symbols)
> + {
> + /* No debug formats enabled. */
> + gcc_assert (i == DINFO_TYPE_NONE);
> + strcat (df_set_names, debug_type_names[i]);
> + break;
> + }
> + }
> + return df_set_names;
> +}
> +
> /* Parse the -femit-struct-debug-detailed option value
> and set the flag variables. */
>
> @@ -190,7 +273,7 @@ static const char use_diagnosed_msg[] = N_("Uses of this
> option are diagnosed.")
>
> typedef char *char_p; /* For DEF_VEC_P. */
>
> -static void set_debug_level (enum debug_info_type type, int extended,
> +static void set_debug_level (uint32_t dinfo, int extended,
> const char *arg, struct gcc_options *opts,
> struct gcc_options *opts_set,
> location_t loc);
> @@ -3027,17 +3110,17 @@ fast_math_flags_struct_set_p (struct cl_optimization
> *opt)
> }
>
> /* Handle a debug output -g switch for options OPTS
> - (OPTS_SET->x_write_symbols storing whether a debug type was passed
> + (OPTS_SET->x_write_symbols storing whether a debug format was passed
> explicitly), location LOC. EXTENDED is true or false to support
> extended output (2 is special and means "-ggdb" was given). */
> static void
> -set_debug_level (enum debug_info_type type, int extended, const char *arg,
> +set_debug_level (uint32_t dinfo, int extended, const char *arg,
> struct gcc_options *opts, struct gcc_options *opts_set,
> location_t loc)
> {
> opts->x_use_gnu_debug_info_extensions = extended;
>
> - if (type == NO_DEBUG)
> + if (dinfo == NO_DEBUG)
> {
> if (opts->x_write_symbols == NO_DEBUG)
> {
> @@ -3058,14 +3141,18 @@ set_debug_level (enum debug_info_type type, int
> extended, const char *arg,
> }
> else
> {
> - /* Does it conflict with an already selected type? */
> + /* Does it conflict with an already selected debug format? */
> if (opts_set->x_write_symbols != NO_DEBUG
> && opts->x_write_symbols != NO_DEBUG
> - && type != opts->x_write_symbols)
> - error_at (loc, "debug format %qs conflicts with prior selection",
> - debug_type_names[type]);
> - opts->x_write_symbols = type;
> - opts_set->x_write_symbols = type;
> + && dinfo != opts->x_write_symbols)
> + {
> + gcc_assert (debug_set_count (dinfo) <= 1);
> + error_at (loc, "debug format %qs conflicts with prior selection",
> + debug_type_names[debug_set_to_format (dinfo)]);
> + }
> +
> + opts->x_write_symbols = dinfo;
> + opts_set->x_write_symbols = dinfo;
> }
>
> /* A debug flag without a level defaults to level 2.
> diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.c
> b/gcc/testsuite/gcc.dg/pch/valid-1.c
> index d445c47..6e9abda 100644
> --- a/gcc/testsuite/gcc.dg/pch/valid-1.c
> +++ b/gcc/testsuite/gcc.dg/pch/valid-1.c
> @@ -1,7 +1,7 @@
> /* { dg-require-effective-target pch_supported_debug } */
> /* { dg-options "-I. -Winvalid-pch -g" } */
>
> -#include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g"
> } */
> +#include "valid-1.h"/* { dg-warning "created with .none. debug info, but
> used with" } */
> /* { dg-error "No such file" "no such file" { target *-*-* } 0 } */
> /* { dg-error "they were invalid" "invalid files" { target *-*-* } 0 } */
> /* { dg-message "terminated" "" { target *-*-* } 0 } */
> diff --git a/gcc/testsuite/lib/dg-pch.exp b/gcc/testsuite/lib/dg-pch.exp
> index 1f60fde..bb0ce46 100644
> --- a/gcc/testsuite/lib/dg-pch.exp
> +++ b/gcc/testsuite/lib/dg-pch.exp
> @@ -28,7 +28,7 @@ proc pch-init { args } {
>
> set result [check_compile pchtest object "int i;" "-g -x c-header"]
> set pch_unsupported_debug \
> - [regexp "debug format cannot be used with pre-compiled headers" \
> + [regexp "debug info cannot be used with pre-compiled headers" \
> [lindex $result 0]]
> remote_file build delete [lindex $result 1]
>
> @@ -38,7 +38,7 @@ proc pch-init { args } {
>
> set result [check_compile pchtest object "int i;" "-x c-header"]
> set pch_unsupported \
> - [regexp "debug format cannot be used with pre-compiled headers" \
> + [regexp "debug info cannot be used with pre-compiled headers" \
> [lindex $result 0]]
> remote_file build delete [lindex $result 1]
> }
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index 7e23253..1016fb9 100644
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -1461,9 +1461,12 @@ process_options (void)
> debug_hooks = &dwarf2_lineno_debug_hooks;
> #endif
> else
> - error_at (UNKNOWN_LOCATION,
> - "target system does not support the %qs debug format",
> - debug_type_names[write_symbols]);
> + {
> + gcc_assert (debug_set_count (write_symbols) <= 1);
> + error_at (UNKNOWN_LOCATION,
> + "target system does not support the %qs debug format",
> + debug_type_names[debug_set_to_format (write_symbols)]);
> + }
>
> /* We know which debug output will be used so we can set flag_var_tracking
> and flag_var_tracking_uninit if the user has not specified them. */
> --
> 1.8.3.1
>