diff options
author | Pedro Alves <palves@redhat.com> | 2015-11-17 13:31:29 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-11-17 13:31:29 +0000 |
commit | 8d297bbf604c8318ffc72d5a7b3db654409c5ed9 (patch) | |
tree | f47b66508e2b6cf6ddc1154e721071eb2143a127 /gdb/infrun.c | |
parent | 9a4073e20b2f1da74cb3b46707e4f6fc4e700950 (diff) | |
download | gdb-8d297bbf604c8318ffc72d5a7b3db654409c5ed9.zip gdb-8d297bbf604c8318ffc72d5a7b3db654409c5ed9.tar.gz gdb-8d297bbf604c8318ffc72d5a7b3db654409c5ed9.tar.bz2 |
Type-safe wrapper for enum flags
This patch fixes C++ build errors like this:
/home/pedro/gdb/mygit/cxx-convertion/src/gdb/linux-tdep.c:1126:35: error: invalid conversion from ‘int’ to ‘filterflags’ [-fpermissive]
| COREFILTER_HUGETLB_PRIVATE);
^
This is a case of enums used as bit flags. Unlike "regular" enums,
these values are supposed to be or'ed together. However, in C++, the
type of "(ENUM1 | ENUM2)" is int, and you then can't assign an int to
an enum variable without a cast. That means that this:
enum foo_flags flags = 0;
if (...)
flags |= FOO_FLAG1;
if (...)
flags |= FOO_FLAG2;
... would have to be written as:
enum foo_flags flags = (enum foo_flags) 0;
if (...)
flags = (enum foo_flags) (flags | FOO_FLAG1);
if (...)
flags = (enum foo_flags) (flags | FOO_FLAG2);
which is ... ugly. Alternatively, we'd have to use an int for the
variable's type, which isn't ideal either.
This patch instead adds an "enum flags" class. "enum flags" are
exactly the enums where the values are bits that are meant to be ORed
together.
This allows writing code like the below, while with raw enums this
would fail to compile without casts to enum type at the assignments to
'f':
enum some_flag
{
flag_val1 = 1 << 1,
flag_val2 = 1 << 2,
flag_val3 = 1 << 3,
flag_val4 = 1 << 4,
};
DEF_ENUM_FLAGS_TYPE(enum some_flag, some_flags)
some_flags f = flag_val1 | flag_val2;
f |= flag_val3;
It's also possible to assign literal zero to an enum flags variable
(meaning, no flags), dispensing either adding an awkward explicit "no
value" value to the enumeration or the cast to assignments from 0.
For example:
some_flags f = 0;
f |= flag_val3 | flag_val4;
Note that literal integers other than zero do fail to compile:
some_flags f = 1; // error
C is still supported -- DEF_ENUM_FLAGS_TYPE is just a typedef in that
case.
gdb/ChangeLog:
2015-11-17 Pedro Alves <palves@redhat.com>
* btrace.h: Include common/enum-flags.h.
(btrace_insn_flags): Define.
(struct btrace_insn) <flags>: Change type.
(btrace_function_flags): Define.
(struct btrace_function) <flags>: Change type.
(btrace_thread_flags): Define.
(struct btrace_thread_info) <flags>: Change type.
* c-exp.y (token_flags): Rename to ...
(token_flag): ... this.
(token_flags): Define.
(struct token) <flags>: Change type.
* common/enum-flags.h: New file.
* compile/compile-c-types.c (convert_qualified): Change type of
'quals' local.
* compile/compile-internal.h: Include "common/enum-flags.h".
(gcc_qualifiers_flags): Define.
* completer.c (enum reg_completer_targets): Rename to ...
(enum reg_completer_target): ... this.
(reg_completer_targets): Define.
(reg_or_group_completer_1): Change type of 'targets' parameter.
* disasm.c (do_mixed_source_and_assembly_deprecated): Change type
of 'psl_flags' local.
(do_mixed_source_and_assembly): Change type of 'psl_flags' local.
* infrun.c: Include "common/enum-flags.h".
(enum step_over_what): Rename to ...
(enum step_over_what_flag): ... this.
(step_over_what): Change type.
(start_step_over): Change type of 'step_what' local.
(thread_still_needs_step_over): Now returns a step_over_what.
Adjust.
(keep_going_pass_signal): Change type of 'step_what' local.
* linux-tdep.c: Include "common/enum-flags.h".
(enum filterflags): Rename to ...
(enum filter_flag): ... this.
(filter_flags): Define.
(dump_mapping_p): Change type of 'filterflags' parameter.
(linux_find_memory_regions_full): Change type of 'filterflags'
local.
(linux_find_memory_regions_full): Pass the address of an unsigned
int to sscanf instead of the address of an enum.
* record-btrace.c (btrace_print_lines): Change type of local
'psl_flags'.
(btrace_call_history): Replace 'flags' parameter
with 'int_flags' parameter. Adjust.
(record_btrace_call_history, record_btrace_call_history_range)
(record_btrace_call_history_from): Rename 'flags' parameter to
'int_flags'. Use record_print_flags.
* record.h: Include "common/enum-flags.h".
(record_print_flags): Define.
* source.c: Include "common/enum-flags.h".
(print_source_lines_base, print_source_lines): Change type of
flags parameter.
* symtab.h: Include "common/enum-flags.h".
(enum print_source_lines_flags): Rename to ...
(enum print_source_lines_flag): ... this.
(print_source_lines_flags): Define.
(print_source_lines): Change prototype.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index 185b79b..d1b0e12 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -63,6 +63,7 @@ #include "solist.h" #include "event-loop.h" #include "thread-fsm.h" +#include "common/enum-flags.h" /* Prototypes for local functions */ @@ -1269,7 +1270,7 @@ struct thread_info *step_over_queue_head; /* Bit flags indicating what the thread needs to step over. */ -enum step_over_what +enum step_over_what_flag { /* Step over a breakpoint. */ STEP_OVER_BREAKPOINT = 1, @@ -1279,6 +1280,7 @@ enum step_over_what expression. */ STEP_OVER_WATCHPOINT = 2 }; +DEF_ENUM_FLAGS_TYPE (enum step_over_what_flag, step_over_what); /* Info about an instruction that is being stepped over. */ @@ -2049,7 +2051,7 @@ reset_ecs (struct execution_control_state *ecs, struct thread_info *tp) static void keep_going_pass_signal (struct execution_control_state *ecs); static void prepare_to_wait (struct execution_control_state *ecs); static int keep_going_stepped_thread (struct thread_info *tp); -static int thread_still_needs_step_over (struct thread_info *tp); +static step_over_what thread_still_needs_step_over (struct thread_info *tp); static void stop_all_threads (void); /* Are there any pending step-over requests? If so, run all we can @@ -2069,7 +2071,7 @@ start_step_over (void) { struct execution_control_state ecss; struct execution_control_state *ecs = &ecss; - enum step_over_what step_what; + step_over_what step_what; int must_be_in_line; next = thread_step_over_chain_next (tp); @@ -2919,11 +2921,11 @@ thread_still_needs_step_over_bp (struct thread_info *tp) to make progress when resumed. Returns an bitwise or of enum step_over_what bits, indicating what needs to be stepped over. */ -static int +static step_over_what thread_still_needs_step_over (struct thread_info *tp) { struct inferior *inf = find_inferior_ptid (tp->ptid); - int what = 0; + step_over_what what = 0; if (thread_still_needs_step_over_bp (tp)) what |= STEP_OVER_BREAKPOINT; @@ -7575,7 +7577,7 @@ keep_going_pass_signal (struct execution_control_state *ecs) struct regcache *regcache = get_current_regcache (); int remove_bp; int remove_wps; - enum step_over_what step_what; + step_over_what step_what; /* Either the trap was not expected, but we are continuing anyway (if we got a signal, the user asked it be passed to |