Support bitfields
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 33
- Forks
- 11
- Avg merge
- 1h 17m
- Merged PRs (30d)
- 51
Description
Bitfields are a useful feature for low-level tasks like OS development in C. However, Go's language specification does not include native support for bitfields.
C Example:
This C structure uses bitfields to pack data efficiently:
struct vector_desc_t {
int flags: 16; // Bitfield: OR of VECDESC_FL_* defines (16 bits)
unsigned int cpu: 1; // Bitfield (1 bit)
unsigned int intno: 5; // Bitfield (5 bits)
int source: 8; // Bitfield: Interrupt mux flags (used when not shared, 8 bits)
shared_vector_desc_t *shared_vec_info; // Pointer (used when VECDESC_FL_SHARED)
vector_desc_t *next; // Pointer
};
The numbers (16, 1, 5, 8) specify the exact number of bits each field occupies in memory.
Emulating Bitfields in Go
While Go lacks direct language-level support for bitfields, we can achieve similar functionality through code generation. This approach manually implements the bit manipulation operations.
The Go team exemplifies this technique in the https://cs.opensource.google/go/x/text/+/refs/tags/v0.28.0:internal/gen/bitfield/bitfield.go. For instance, code like this:
type myUint8 uint8
type test1 struct { // Represents 28 bits of data
foo uint16 `bitfield:",fob"` // Tag hints for field "foo" with getter "fob"
Bar int8 `bitfield:"5,baz"` // Tag: occupies 5 bits, getter named "baz"
Foo uint64 // Regular field (whole uint64)
bar myUint8 `bitfield:"3"` // Tag: occupies 3 bits (default getter "bar")
Bool bool `bitfield:""` // Tag: occupies 1 bit (default getter "Bool")
Baz int8 `bitfield:"3"` // Tag: occupies 3 bits (default getter "Baz")
}
Can be processed by a generator to produce methods that manipulate the bits within a single underlying integer type (here, uint32 for the bitfields):
type test1 uint32 // Underlying type holding the packed bits
func (t test1) fob() uint16 { // Getter for field 'foo' (tag defined name "fob")
return uint16((t >> 16) & 0xffff) // Shift and mask for bits 16-31
}
func (t test1) baz() int8 { // Getter for field 'Bar' (tag defined name "baz")
return int8((t >> 11) & 0x1f) // Shift and mask for 5 bits at pos 11
}
func (t test1) bar() myUint8 { // Getter for field 'bar' (type myUint8)
return myUint8((t >> 8) & 0x7) // Shift and mask for 3 bits at pos 8
}
func (t test1) Bool() bool { // Getter for field 'Bool' (1 bit)
const bit = 1 << 7 // Bit mask for position 7
return t&bit == bit // Check if bit at pos 7 is set
}
func (t test1) Baz() int8 { // Getter for field 'Baz'
return int8((t >> 4) & 0x7) // Shift and mask for 3 bits at pos 4
}
Memory alignment
By default, the most of compilers respect that memory alignment:
Size = ceil(bits ÷ unit_bits)+ padding for larger members.
(Unit size = sizeof(unsigned int), typically 32 bits).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the requested C bitfield examples and the Go team's internal/gen/bitfield/bitfield.go reference linked in the issue. Then locate llcppg's C/C++ code-generation entry points and existing tests, if any, to determine where bitfield declarations are handled. Done should include generated Go representations that preserve the requested bit widths and support the described field access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, go
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100