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/btrace.h | |
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/btrace.h')
-rw-r--r-- | gdb/btrace.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/gdb/btrace.h b/gdb/btrace.h index f844df8..6c54c6f 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -28,6 +28,7 @@ #include "btrace-common.h" #include "target/waitstatus.h" /* For enum target_stop_reason. */ +#include "common/enum-flags.h" #if defined (HAVE_LIBIPT) # include <intel-pt.h> @@ -58,6 +59,7 @@ enum btrace_insn_flag /* The instruction has been executed speculatively. */ BTRACE_INSN_FLAG_SPECULATIVE = (1 << 0) }; +DEF_ENUM_FLAGS_TYPE (enum btrace_insn_flag, btrace_insn_flags); /* A branch trace instruction. @@ -74,7 +76,7 @@ struct btrace_insn enum btrace_insn_class iclass; /* A bit vector of BTRACE_INSN_FLAGS. */ - enum btrace_insn_flag flags; + btrace_insn_flags flags; }; /* A vector of branch trace instructions. */ @@ -100,6 +102,7 @@ enum btrace_function_flag if bfun_up_links_to_ret is clear. */ BFUN_UP_LINKS_TO_TAILCALL = (1 << 1) }; +DEF_ENUM_FLAGS_TYPE (enum btrace_function_flag, btrace_function_flags); /* Decode errors for the BTS recording format. */ enum btrace_bts_error @@ -181,7 +184,7 @@ struct btrace_function int level; /* A bit-vector of btrace_function_flag. */ - enum btrace_function_flag flags; + btrace_function_flags flags; }; /* A branch trace instruction iterator. */ @@ -245,6 +248,7 @@ enum btrace_thread_flag /* The thread is to be stopped. */ BTHR_STOP = (1 << 4) }; +DEF_ENUM_FLAGS_TYPE (enum btrace_thread_flag, btrace_thread_flags); #if defined (HAVE_LIBIPT) /* A packet. */ @@ -342,7 +346,7 @@ struct btrace_thread_info unsigned int ngaps; /* A bit-vector of btrace_thread_flag. */ - enum btrace_thread_flag flags; + btrace_thread_flags flags; /* The instruction history iterator. */ struct btrace_insn_history *insn_history; |