aboutsummaryrefslogtreecommitdiff
path: root/gcc/opts.c
diff options
context:
space:
mode:
authorIndu Bhagat <indu.bhagat@oracle.com>2021-04-30 07:52:40 -0700
committerDavid Faust <david.faust@oracle.com>2021-05-20 12:39:33 -0700
commit459d84e9b6e925922246b6aff76a5202b1d4d4ba (patch)
tree14bbc582c3a077083184c01d5cf49700df9e6111 /gcc/opts.c
parent9480491a6447576e8e695b8ea3c4989cf72c9670 (diff)
downloadgcc-459d84e9b6e925922246b6aff76a5202b1d4d4ba.zip
gcc-459d84e9b6e925922246b6aff76a5202b1d4d4ba.tar.gz
gcc-459d84e9b6e925922246b6aff76a5202b1d4d4ba.tar.bz2
opts: change write_symbols to support bitmasks
To support multiple debug formats, we need to move away from explicit enumeration of each individual combination of debug formats. 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.
Diffstat (limited to 'gcc/opts.c')
-rw-r--r--gcc/opts.c109
1 files changed, 98 insertions, 11 deletions
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.