binutils-gdb/gdbsupport
Pedro Alves 04902b0995 Rewrite enum_flags, add unit tests, fix problems
This patch started by adding comprehensive unit tests for enum_flags.

For the testing part, it adds:

 - tests of normal expected uses of the API.

 - checks that _invalid_ uses of the API would fail to compile.  I.e.,
   it validates that enum_flags really is a strong type, and that
   incorrect mixing of enum types would be caught at compile time.  It
   pulls that off making use of SFINEA and C++11's decltype/constexpr.

This revealed many holes in the enum_flags API.  For example, the f1
assignment below currently incorrectly fails to compile:

 enum_flags<flags> f1 = FLAG1;
 enum_flags<flags> f2 = FLAG2 | f1;

The unit tests also 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.

Also, several operators were missing.

These holes and more are plugged by this patch, by reworking how the
enum_flags operators are implemented, and making use of C++11's
feature of being able to delete methods/functions.

There are cases in gdb/compile/ where we need to call a function in a
C plugin 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.

This makes most of the enum_flags operators constexpr.  Beyond
enabling more compiler optimizations and enabling the new unit tests,
this has other advantages, like making it possible to use operator|
with enum_flags values in switch cases, where only compile-time
constants are allowed:

    enum_flags<flags> f = FLAG1 | FLAG2;
    switch (f)
      {
      case FLAG1 | FLAG2:
	break;
      }

Currently that fails to compile.

It also switches to a different mechanism of enabling the global
operators.  The current mechanism isn't namespace friendly, the new
one is.

It also switches to C++11-style SFINAE -- instead of wrapping the
return type in a SFINAE-friently structure, we use an unnamed template
parameter.  I.e., this:

  template <typename enum_type,
	    typename = is_enum_flags_enum_type_t<enum_type>>
  enum_type
  operator& (enum_type e1, enum_type e2)

instead of:

  template <typename enum_type>
  typename enum_flags_type<enum_type>::type
  operator& (enum_type e1, enum_type e2)

Note that the static_assert inside operator~() was converted to a
couple overloads (signed vs unsigned), because static_assert is too
late for SFINAE-based tests, which is important for the CHECK_VALID
unit tests.

Tested with gcc {4.8, 7.1, 9.3} and clang {5.0.2, 10.0.0}.

gdb/ChangeLog:

	* Makefile.in (SELFTESTS_SRCS): Add
	unittests/enum-flags-selftests.c.
	* btrace.c (ftrace_update_caller, ftrace_fixup_calle): Use
	btrace_function_flags instead of enum btrace_function_flag.
	* compile/compile-c-types.c (convert_qualified): Use
	enum_flags::raw.
	* compile/compile-cplus-symbols.c (convert_one_symbol)
	(convert_symbol_bmsym):
	* compile/compile-cplus-types.c (compile_cplus_convert_method)
	(compile_cplus_convert_struct_or_union_methods)
	(compile_cplus_instance::convert_qualified_base):
	* go-exp.y (parse_string_or_char): Add cast to int.
	* unittests/enum-flags-selftests.c: New file.
	* 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.

gdbsupport/ChangeLog:

	* enum-flags.h: Include "traits.h".
	(DEF_ENUM_FLAGS_TYPE): Declare a function instead of defining a
	structure.
	(enum_underlying_type): Update comment.
	(namespace enum_flags_detail): New.  Move struct zero_type here.
	(EnumIsUnsigned, EnumIsSigned): New.
	(class enum_flags): Make most methods constexpr.
	(operator&=, operator|=, operator^=): Take an enum_flags instead
	of an enum_type.  Make rvalue ref versions deleted.
	(operator enum_type()): Delete.
	(operator&, operator|, operator^, operator~): Delete, moved out of
	class.
	(raw()): New method.
	(is_enum_flags_enum_type_t): Declare.
	(ENUM_FLAGS_GEN_BINOP, ENUM_FLAGS_GEN_COMPOUND_ASSIGN)
	(ENUM_FLAGS_GEN_COMP): New.  Use them to reimplement global
	operators.
	(operator~): Now constexpr and reimplemented.
	(operator<<, operator>>): New deleted functions.
	* valid-expr.h (CHECK_VALID_EXPR_5, CHECK_VALID_EXPR_6): New.
2020-09-14 22:21:07 +01:00
..
.dir-locals.el gdbserver/gdbsupport: Add .dir-locals.el file 2020-03-06 11:29:46 +00:00
.gitattributes gdb, gdbserver, gdbsupport: add .gitattributes files 2020-03-05 15:59:22 +01:00
acinclude.m4 Move gdb/selftest.m4 to gdbsupport/selftest.m4 2020-03-12 14:19:38 -04:00
aclocal.m4
agent.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
agent.h
alt-stack.h
array-view.h
ax.def
block-signals.h
break-common.h
btrace-common.cc Don't pass NULL to memcpy in gdb 2020-03-31 07:29:53 -06:00
btrace-common.h Disable record btrace bts support for AMD processors 2020-05-14 17:56:33 -07:00
buffer.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
buffer.h
byte-vector.h
ChangeLog Rewrite enum_flags, add unit tests, fix problems 2020-09-14 22:21:07 +01:00
check-defines.el
cleanups.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
cleanups.h
common-debug.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
common-debug.h
common-defs.h gdbsupport: include cstdlib in common-defs.h 2020-04-27 09:28:03 -04:00
common-exceptions.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
common-exceptions.h
common-gdbthread.h
common-inferior.cc gdbsupport: Let construct_inferior_arguments take gdb::array_view param 2020-05-25 11:38:45 -04:00
common-inferior.h gdbsupport: Let construct_inferior_arguments take gdb::array_view param 2020-05-25 11:38:45 -04:00
common-regcache.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
common-regcache.h gdb: protect some 'regcache_read_pc' calls 2020-05-14 13:59:53 +02:00
common-types.h Change gdbsupport not to rely on BFD 2020-03-12 13:32:16 -06:00
common-utils.cc gdbsupport: Drop now unused function 'stringify_argv' 2020-05-25 11:40:35 -04:00
common-utils.h gdbsupport: Drop now unused function 'stringify_argv' 2020-05-25 11:40:35 -04:00
common.m4 Unify Solaris procfs and largefile handling 2020-07-30 15:41:50 +02:00
config.in Unify Solaris procfs and largefile handling 2020-07-30 15:41:50 +02:00
configure Unify Solaris procfs and largefile handling 2020-07-30 15:41:50 +02:00
configure.ac Move sourcing of development.sh to GDB_AC_COMMON 2020-03-12 14:18:00 -04:00
create-version.sh gdbsupport: Resolve shellcheck issues in create-version.sh script 2020-03-27 13:52:00 +00:00
def-vector.h
default-init-alloc.h
eintr.h Add handle_eintr to wrap EINTR handling in syscalls 2020-09-10 15:35:12 +02:00
enum-flags.h Rewrite enum_flags, add unit tests, fix problems 2020-09-14 22:21:07 +01:00
environ.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
environ.h
errors.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
errors.h Introduce and use flush_streams 2020-04-13 14:10:04 -06:00
event-loop.cc Move gdb_notifier comment 2020-04-13 14:10:04 -06:00
event-loop.h Move event-loop.[ch] to gdbsupport/ 2020-04-13 14:10:04 -06:00
fileio.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
fileio.h
filestuff.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
filestuff.h
filtered-iterator.h
format.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
format.h
forward-scope-exit.h
function-view.h
gdb_assert.h
gdb_binary_search.h Fix two typos in gdb_binary_search.h 2020-03-08 11:05:43 -06:00
gdb_locale.h
gdb_optional.h [gdb/build] Fix Wmaybe-uninitialized in gdb_optional.h 2020-07-28 15:07:44 +02:00
gdb_proc_service.h
gdb_ref_ptr.h Mark move constructors as "noexcept" 2020-04-20 11:45:06 -06:00
gdb_select.h Move gdb_select.h to gdbsupport/ 2020-04-13 14:10:03 -06:00
gdb_setjmp.h
gdb_signals.h
gdb_splay_tree.h
gdb_string_view.h Do not define basic_string_view::to_string 2020-06-30 07:53:03 -06:00
gdb_string_view.tcc
gdb_sys_time.h
gdb_tilde_expand.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
gdb_tilde_expand.h
gdb_unique_ptr.h
gdb_unlinker.h
gdb_vecs.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
gdb_vecs.h
gdb_wait.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
gdb_wait.h
gdb-dlfcn.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
gdb-dlfcn.h Fix comment for 'gdb_dlopen' 2020-02-28 11:04:28 -05:00
gdb-safe-ctype.h Use safe-ctype.h (ISSPACE etc.) in symbol parsing & comparison 2020-05-23 12:46:37 +01:00
gdb-sigmask.h Fix typo (thead -> thread) 2020-04-28 11:38:26 +02:00
hash_enum.h
host-defs.h
job-control.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
job-control.h
Makefile.am Unify Solaris procfs and largefile handling 2020-07-30 15:41:50 +02:00
Makefile.in Unify Solaris procfs and largefile handling 2020-07-30 15:41:50 +02:00
netstuff.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
netstuff.h
new-op.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
next-iterator.h
observable.h
offset-type.h
parallel-for.h
pathstuff.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
pathstuff.h
poison.h
preprocessor.h
print-utils.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
print-utils.h
ptid.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
ptid.h gdb: change regcache list to be a map 2020-08-07 11:29:00 -04:00
README
refcounted-object.h
rsp-low.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
rsp-low.h
run-time-clock.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
run-time-clock.h
safe-iterator.h
safe-strerror.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
scope-exit.h
scoped_fd.h Mark move constructors as "noexcept" 2020-04-20 11:45:06 -06:00
scoped_mmap.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
scoped_mmap.h Mark move constructors as "noexcept" 2020-04-20 11:45:06 -06:00
scoped_restore.h
selftest.cc gdb: allow specifying multiple filters when running selftests 2020-08-13 07:55:48 -04:00
selftest.h gdb: allow specifying multiple filters when running selftests 2020-08-13 07:55:48 -04:00
selftest.m4 Move gdb/selftest.m4 to gdbsupport/selftest.m4 2020-03-12 14:19:38 -04:00
signals-state-save-restore.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
signals-state-save-restore.h
signals.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
symbol.h
tdesc.cc Add bfloat16 support for AVX512 register view. 2020-09-11 11:42:47 -07:00
tdesc.h Add bfloat16 support for AVX512 register view. 2020-09-11 11:42:47 -07:00
thread-pool.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
thread-pool.h
traits.h Rewrite valid-expr.h's internals in terms of the detection idiom (C++17/N4502) 2020-09-14 22:19:31 +01:00
underlying.h
valid-expr.h Rewrite enum_flags, add unit tests, fix problems 2020-09-14 22:21:07 +01:00
version.h
warning.m4 gdb: enable -Wmissing-prototypes warning 2020-03-11 15:15:12 -04:00
x86-xstate.h
xml-utils.cc gdbsupport: rename source files to .cc 2020-02-13 16:27:03 -05:00
xml-utils.h

This is a helper library that is used by gdb and gdbserver.

To send patches, follow the gdb patch submission instructions in
../gdb/CONTRIBUTE.  For maintainers, see ../gdb/MAINTAINERS.