LLVM 20.0.0git
Classes | Namespaces | Macros | Functions | Variables
BitmaskEnum.h File Reference
#include <cassert>
#include <type_traits>
#include <utility>
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/Support/MathExtras.h"

Go to the source code of this file.

Classes

struct  llvm::is_bitmask_enum< E, Enable >
 Traits class to determine whether an enum has a LLVM_BITMASK_LARGEST_ENUMERATOR enumerator. More...
 
struct  llvm::is_bitmask_enum< E, std::enable_if_t< sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >=0 >
 
struct  llvm::largest_bitmask_enum_bit< E, std::enable_if_t< sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >=0 >
 

Namespaces

namespace  llvm
 This is an optimization pass for GlobalISel generic memory operations.
 
namespace  llvm::BitmaskEnumDetail
 

Macros

#define LLVM_MARK_AS_BITMASK_ENUM(LargestValue)    LLVM_BITMASK_LARGEST_ENUMERATOR = LargestValue
 LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can perform bitwise operations on it without putting static_cast everywhere.
 
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue)
 LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operation on such enum does not require static_cast.
 
#define LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() pulls the operator overloads used by LLVM_MARK_AS_BITMASK_ENUM into the current namespace.
 

Functions

template<typename E >
constexpr std::underlying_type_t< Ellvm::BitmaskEnumDetail::Mask ()
 Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
 
template<typename E >
constexpr std::underlying_type_t< Ellvm::BitmaskEnumDetail::Underlying (E Val)
 Check that Val is in range for E, and return Val cast to E's underlying type.
 
constexpr unsigned llvm::BitmaskEnumDetail::bitWidth (uint64_t Value)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr bool llvm::BitmaskEnumDetail::any (E Val)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator~ (E Val)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator| (E LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator& (E LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator^ (E LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator<< (E LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr E llvm::BitmaskEnumDetail::operator>> (E LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
Ellvm::BitmaskEnumDetail::operator|= (E &LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
Ellvm::BitmaskEnumDetail::operator&= (E &LHS, E RHS)
 
template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
Ellvm::BitmaskEnumDetail::operator^= (E &LHS, E RHS)
 
template<typename e , typename = std::enable_if_t<is_bitmask_enum<e>::value>>
e & llvm::BitmaskEnumDetail::operator<<= (e &lhs, e rhs)
 
template<typename e , typename = std::enable_if_t<is_bitmask_enum<e>::value>>
e & llvm::BitmaskEnumDetail::operator>>= (e &lhs, e rhs)
 
 llvm::LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE ()
 

Variables

template<typename E , typename = std::enable_if_t<is_bitmask_enum<E>::value>>
constexpr unsigned llvm::BitWidth
 

Macro Definition Documentation

◆ LLVM_DECLARE_ENUM_AS_BITMASK

#define LLVM_DECLARE_ENUM_AS_BITMASK (   Enum,
  LargestValue 
)
Value:
template <> struct is_bitmask_enum<Enum> : std::true_type {}; \
template <> struct largest_bitmask_enum_bit<Enum> { \
static constexpr std::underlying_type_t<Enum> value = LargestValue; \
}
Given that RA is a live value

LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operation on such enum does not require static_cast.

enum MyEnum { E1 = 1, E2 = 2, E3 = 4, E4 = 8 };
void Foo() {
MyEnum A = (E1 | E2) & E3 ^ ~E4; // No static_cast
}
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue)
LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operat...
Definition: BitmaskEnum.h:66
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

The second parameter to LLVM_DECLARE_ENUM_AS_BITMASK specifies the largest bit value of the enum type.

LLVM_DECLARE_ENUM_AS_BITMASK should be used in llvm namespace.

This a non-intrusive alternative for LLVM_MARK_AS_BITMASK_ENUM. It allows declaring more than one non-scoped enumerations as bitmask types in the same scope. Otherwise it provides the same functionality as LLVM_MARK_AS_BITMASK_ENUM.

Definition at line 66 of file BitmaskEnum.h.

◆ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE

#define LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE ( )
Value:
using ::llvm::BitmaskEnumDetail::operator~; \
using ::llvm::BitmaskEnumDetail::operator|; \
using ::llvm::BitmaskEnumDetail::operator&; \
using ::llvm::BitmaskEnumDetail::operator^; \
using ::llvm::BitmaskEnumDetail::operator<<; \
using ::llvm::BitmaskEnumDetail::operator>>; \
using ::llvm::BitmaskEnumDetail::operator|=; \
using ::llvm::BitmaskEnumDetail::operator&=; \
using ::llvm::BitmaskEnumDetail::operator^=; \
using ::llvm::BitmaskEnumDetail::operator<<=; \
using ::llvm::BitmaskEnumDetail::operator>>=; \
/* Force a semicolon at the end of this macro. */ \
using ::llvm::BitmaskEnumDetail::any

LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() pulls the operator overloads used by LLVM_MARK_AS_BITMASK_ENUM into the current namespace.

Suppose you have an enum foo::bar::MyEnum. Before using LLVM_MARK_AS_BITMASK_ENUM on MyEnum, you must put LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE() somewhere inside namespace foo or namespace foo::bar. This allows the relevant operator overloads to be found by ADL.

You don't need to use this macro in namespace llvm; it's done at the bottom of this file.

Definition at line 83 of file BitmaskEnum.h.

◆ LLVM_MARK_AS_BITMASK_ENUM

#define LLVM_MARK_AS_BITMASK_ENUM (   LargestValue)     LLVM_BITMASK_LARGEST_ENUMERATOR = LargestValue

LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can perform bitwise operations on it without putting static_cast everywhere.

enum MyEnum {
E1 = 1, E2 = 2, E3 = 4, E4 = 8,
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ E4)
};
void Foo() {
MyEnum A = (E1 | E2) & E3 ^ ~E4; // Look, ma: No static_cast!
}
#define LLVM_MARK_AS_BITMASK_ENUM(LargestValue)
LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can perform bitwise operatio...
Definition: BitmaskEnum.h:42

Normally when you do a bitwise operation on an enum value, you get back an instance of the underlying type (e.g. int). But using this macro, bitwise ops on your enum will return you back instances of the enum. This is particularly useful for enums which represent a combination of flags.

The parameter to LLVM_MARK_AS_BITMASK_ENUM should be the largest individual value in your enum.

All of the enum's values must be non-negative.

Definition at line 42 of file BitmaskEnum.h.