On Thu, May 13, 2021 at 12:53 AM Indu Bhagat via Gcc-patches <gcc-patches@gcc.gnu.org> 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 >