summaryrefslogtreecommitdiff
path: root/gdb/common/enum-flags.h
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-11-04 02:02:39 +0000
committerPedro Alves <palves@redhat.com>2016-11-04 09:25:33 +0000
commit6893f30dd513e220bd68fcb13d5f9893f789b2c5 (patch)
tree506e3f7e11cd17f6e615cbd21ff61105881cf726 /gdb/common/enum-flags.h
parent38b7a97e00212cc3efe8a397cb7f9e9b0d21cb8e (diff)
downloadbinutils-gdb-users/palves/cxx-enum-flags.tar.gz
enum_flags: Fix ternary operator and remove implicit convertion to raw enumusers/palves/cxx-enum-flags
The unit tests added by the previous patch revealed that this useful use case doesn't work: enum flag { FLAG1 = 1, FLAG2 = 2 }; enum_flags<flag> src = FLAG1; enum_flags<flag> f1 = condition ? src : FLAG2; It fails to compile because enum_flags<flag> and flag are convertible to each other. Turns out that making enum_flags be implicitly convertible to the backing raw enum type was not a good idea. If we make it convertible to the underlying type instead, we fix that ternary operator use case, and, we find cases throughout the codebase that should be using the enum_flags but were using the raw backing enum instead. So it's a good change overall. There's one case in compile/compile-c-types.c where we need to call a function in a C API that expects the raw enum. To address cases like that, this adds a "raw()" method to enum_flags. This way we can keep using the safer enum_flags to construct the value, and then be explicit when we need to get at the raw enum. Tested with gcc 4.8, 4.9, 5.3, 7 (trunk) and clang 3.7. gdb/ChangeLog: yyyy-mm-dd Pedro Alves <palves@redhat.com> * common/enum-flags.h (enum_flags::operator&=): Change parameter type to enum_flags from enum_type and adjust. (enum_flags::operator|=): Likewise. (enum_flags::operator^=): Likewise. (enum_flags::operator enum_type): Delete. (enum_flags::raw): New method. (ENUM_FLAGS_GEN_BINOP): Adjust operator functions. * compile/compile-c-types.c (convert_qualified): Use enum_flags::raw. * enum-flags-selftests.c Adjust ternary operator CHECK_VALID tests. (selftests::enum_flags_tests::self_test): Add more ternary operator tests. * record-btrace.c (btrace_thread_flag_to_str): Change parameter's type to btrace_thread_flags from btrace_thread_flag. (record_btrace_cancel_resume, record_btrace_step_thread): Change local's type to btrace_thread_flags from btrace_thread_flag. Add cast in DEBUG call.
Diffstat (limited to 'gdb/common/enum-flags.h')
-rw-r--r--gdb/common/enum-flags.h26
1 files changed, 15 insertions, 11 deletions
diff --git a/gdb/common/enum-flags.h b/gdb/common/enum-flags.h
index becd2c74ece..50c60b4468f 100644
--- a/gdb/common/enum-flags.h
+++ b/gdb/common/enum-flags.h
@@ -114,24 +114,28 @@ public:
: m_enum_value ((enum_type) 0)
{}
- enum_flags &operator&= (enum_type e)
+ enum_flags &operator&= (enum_flags e)
{
- m_enum_value = (enum_type) (m_enum_value & e);
+ m_enum_value = (enum_type) (m_enum_value & e.m_enum_value);
return *this;
}
- enum_flags &operator|= (enum_type e)
+ enum_flags &operator|= (enum_flags e)
{
- m_enum_value = (enum_type) (m_enum_value | e);
+ m_enum_value = (enum_type) (m_enum_value | e.m_enum_value);
return *this;
}
- enum_flags &operator^= (enum_type e)
+ enum_flags &operator^= (enum_flags e)
{
- m_enum_value = (enum_type) (m_enum_value ^ e);
+ m_enum_value = (enum_type) (m_enum_value ^ e.m_enum_value);
return *this;
}
- /* Allow conversion to the enum type. */
- constexpr operator enum_type () const
+ /* Like raw enums, allow conversion to the underlying type. */
+ constexpr operator underlying_type () const
+ { return m_enum_value; }
+
+ /* Get the underlying value as a raw enum. */
+ constexpr enum_type raw () const
{ return m_enum_value; }
/* Binary operations involving some unrelated type (which would be a
@@ -167,19 +171,19 @@ private:
template <typename enum_type> \
constexpr typename enum_flags_type<enum_type>::type \
OPERATOR_OP (enum_flags<enum_type> e1, enum_type e2) \
- { return enum_type (e1) OP e2; } \
+ { return e1.raw () OP e2; } \
\
/* enum_flags on the RHS. */ \
template <typename enum_type> \
constexpr typename enum_flags_type<enum_type>::type \
OPERATOR_OP (enum_type e1, enum_flags<enum_type> e2) \
- { return e1 OP enum_type (e2); } \
+ { return e1 OP e2.raw (); } \
\
/* enum_flags on both LHS/RHS. */ \
template <typename enum_type> \
constexpr typename enum_flags_type<enum_type>::type \
OPERATOR_OP (enum_flags<enum_type> e1, enum_flags<enum_type> e2) \
- { return enum_type (e1) OP enum_type (e2); } \
+ { return e1.raw () OP e2.raw (); } \
\
/* Delete cases involving unrelated types. */ \
\