From eaaa6b1578cf725fca7b44fcf1083de048f8dc27 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 24 May 2018 13:51:45 -0400 Subject: [PATCH 24/24] FIXME: introduce bitmask-enums.h --- gcc/bitmask-enums.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/dumpfile.h | 54 +++++++-------------------- 2 files changed, 117 insertions(+), 41 deletions(-) create mode 100644 gcc/bitmask-enums.h diff --git a/gcc/bitmask-enums.h b/gcc/bitmask-enums.h new file mode 100644 index 0000000..2df563b --- /dev/null +++ b/gcc/bitmask-enums.h @@ -0,0 +1,104 @@ +/* Support for typesafe bitmask enums. + Copyright (C) 2018 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +#ifndef GCC_BITMASK_ENUMS_H +#define GCC_BITMASK_ENUMS_H 1 + +/* Traits for controlling whether bitmask operations should be + supported for a given enum (off by default). + + If bitmask operations are to enabled on a particular enum, then specialize + this class, setting "enable" to true, and providing an underlying_t + typedef, e.g.: + + struct enum_bitmask_traits + { + static const bool enable = true; + typedef int underlying_t; + }; + + FIXME: should we use std::underlying_type? */ + +template +struct enable_bitmask_ops +{ + static const bool enable = false; +}; + +/* Bitmask operators on an enum. + These are only defined for those enums for which + the enable_bitmask_ops has been specialized + with an underlying_t. */ + +// FIXME: std::enable_if is C++11 onwards... +// FIXME: std::underlying_type is C++11 onwards... + +template +static inline CONSTEXPR +typename std::enable_if::enable, Enum_t>::type +operator| (Enum_t lhs, Enum_t rhs) +{ + typedef typename enable_bitmask_ops::underlying_t underlying_t; + return static_cast(static_cast (lhs) + | static_cast (rhs)); +} + +template +static inline CONSTEXPR +typename std::enable_if::enable, Enum_t>::type +operator& (Enum_t lhs, Enum_t rhs) +{ + typedef typename enable_bitmask_ops::underlying_t underlying_t; + return static_cast(static_cast (lhs) + & static_cast (rhs)); +} + +template +static inline CONSTEXPR +typename std::enable_if::enable, Enum_t>::type +operator~ (Enum_t flags) +{ + typedef typename enable_bitmask_ops::underlying_t underlying_t; + return static_cast(~(static_cast (flags))); +} + +template +static inline +typename std::enable_if::enable, Enum_t>::type & +operator|= (Enum_t &lhs, Enum_t rhs) +{ + typedef typename enable_bitmask_ops::underlying_t underlying_t; + lhs = static_cast(static_cast (lhs) + | static_cast (rhs)); + return lhs; +} + +template +static inline +typename std::enable_if::enable, Enum_t>::type & +operator&= (Enum_t &lhs, Enum_t rhs) +{ + typedef typename enable_bitmask_ops::underlying_t underlying_t; + lhs = static_cast(static_cast (lhs) + & static_cast (rhs)); + return lhs; +} + +#endif /* GCC_BITMASK_ENUMS_H */ diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index 3c4d5a6..14d31e5 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_DUMPFILE_H #define GCC_DUMPFILE_H 1 +#include "bitmask-enums.h" /* Different tree dump places. When you add new tree dump places, extend the DUMP_FILES array in dumpfile.c. */ @@ -151,39 +152,14 @@ enum dump_flag typedef enum dump_flag dump_flags_t; -// FIXME: template -// FIXME: underlying storage type? -static inline dump_flags_t -operator| (dump_flags_t lhs, dump_flags_t rhs) -{ - return (dump_flags_t)((int)lhs | (int)rhs); -} - -static inline dump_flags_t -operator& (dump_flags_t lhs, dump_flags_t rhs) -{ - return (dump_flags_t)((int)lhs & (int)rhs); -} +/* Enable bitmask operations on dump_flags_t. */ -static inline dump_flags_t -operator~ (dump_flags_t flags) +template<> +struct enable_bitmask_ops { - return (dump_flags_t)~((int)flags); -} - -static inline dump_flags_t & -operator|= (dump_flags_t &lhs, dump_flags_t rhs) -{ - lhs = (dump_flags_t)((int)lhs | (int)rhs); - return lhs; -} - -static inline dump_flags_t & -operator&= (dump_flags_t &lhs, dump_flags_t rhs) -{ - lhs = (dump_flags_t)((int)lhs & (int)rhs); - return lhs; -} + static const bool enable = true; + typedef uint64_t underlying_t; +}; /* Flags to control high-level -fopt-info dumps. Usually these flags define a group of passes. An optimization pass can be part of @@ -217,18 +193,14 @@ enum optgroup_flag typedef enum optgroup_flag optgroup_flags_t; -static inline optgroup_flags_t -operator| (optgroup_flags_t lhs, optgroup_flags_t rhs) -{ - return (optgroup_flags_t)((int)lhs | (int)rhs); -} +/* Enable bitmask operations on optgroup_flags_t. */ -static inline optgroup_flags_t & -operator|= (optgroup_flags_t &lhs, optgroup_flags_t rhs) +template<> +struct enable_bitmask_ops { - lhs = (optgroup_flags_t)((int)lhs | (int)rhs); - return lhs; -} + static const bool enable = true; + typedef int underlying_t; +}; /* Define a tree dump switch. */ struct dump_file_info -- 1.8.5.3