goplus / goplus/llcppg

Support bitfields

Open
#542 0 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.