summaryrefslogtreecommitdiff
path: root/gdb/compile
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-11-17 13:31:29 +0000
committerPedro Alves <palves@redhat.com>2015-11-17 13:31:29 +0000
commit8d297bbf604c8318ffc72d5a7b3db654409c5ed9 (patch)
treef47b66508e2b6cf6ddc1154e721071eb2143a127 /gdb/compile
parent9a4073e20b2f1da74cb3b46707e4f6fc4e700950 (diff)
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/compile')
-rw-r--r--gdb/compile/compile-c-types.c2
-rw-r--r--gdb/compile/compile-internal.h4
2 files changed, 5 insertions, 1 deletions
diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index ccc9167714..8dcb1224ea 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -293,7 +293,7 @@ convert_qualified (struct compile_c_instance *context, struct type *type)
{
struct type *unqual = make_unqualified_type (type);
gcc_type unqual_converted;
- int quals = 0;
+ gcc_qualifiers_flags quals = 0;
unqual_converted = convert_type (context, unqual);
diff --git a/gdb/compile/compile-internal.h b/gdb/compile/compile-internal.h
index b1a5a88de4..e931967f59 100644
--- a/gdb/compile/compile-internal.h
+++ b/gdb/compile/compile-internal.h
@@ -19,6 +19,10 @@
#include "hashtab.h"
#include "gcc-c-interface.h"
+#include "common/enum-flags.h"
+
+/* enum-flags wrapper. */
+DEF_ENUM_FLAGS_TYPE (enum gcc_qualifiers, gcc_qualifiers_flags);
/* Debugging flag for the "compile" family of commands. */