[Clang] Add a builtin to get the bit width of an enum type
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
It's often useful to know how many bits are needed to store any value of an enum. A common use case is packing an enum into a bitfield alongside other data:
```c++
enum Flags {
FlagA = (1 << 0),
FlagB = (1 << 1),
FlagC = (1 << 2),
};
struct Packed {
uintptr_t uniqueID : (sizeof(uintptr_t) * CHAR_BIT) - __builtin_enum_bit_width(enum Flags);
enum Flags flags : __builtin_enum_bit_width(enum Flags);
};
```
This applies equally to non-bitmask enums:
```c++
enum Color {
Red, // 0
Green, // 1
Blue, // 2
};
```
Today there is no clean way to get this as a compile-time constant. A common workaround for bitmask enums is:
```c++
enum Flags {
FlagA = (1 << 0),
FlagB = (1 << 1),
FlagC = (1 << 2),
_FlagsLastPlusOne,
};
#define FlagBitCount (1 + __builtin_ctz((_FlagsLastPlusOne - 1)))
```
This has several problems:
- `_FlagsLastPlusOne` is not a valid flag value and pollutes the enum's value space.
- If the enum uses all bits of its underlying type, `_FlagsLastPlusOne` overflows.
- It's fragile and non-obvious and easy to get wrong when maintaining the enum.
One natural definition of the builtin would be to return the minimum bitfield width that would not trigger `-Wbitfield-enum-conversion`.
Thoughts on whether this would be useful and what the right spelling/semantics should be?
Contributor guide
Research direction
No implementation files or tests are named. Start by tracing Clang's builtin handling and the -Wbitfield-enum-conversion diagnostic; settle the spelling and compile-time semantics, then add coverage for bitmask and non-bitmask enums.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100