Skip to content
This repository was archived by the owner on Feb 15, 2026. It is now read-only.
This repository was archived by the owner on Feb 15, 2026. It is now read-only.

Support nested anonymous types #85

Description

@HertzDevil

Currently, Bindgen doesn't support nested anonymous types at all:

struct T {
  struct { int x, y; } point;
  struct { float u, v; };
};
classes: { T: T }
types:
  T: { copy_structure: true }
lib Binding
  struct T
    point : T::(anonymous)*
    unnamed_arg_0 : T::(anonymous)*
  end

  # SanityCheck will complain about the inaccessible (anonymous) types
  # x, y, u, and v are entirely missing
end

There are many examples of these types in the wild, mostly C struct / union compounds: (union support would be in a separate issue)

/**
 *  Get the SDL joystick layer binding for this controller button/axis mapping
 */
typedef struct SDL_GameControllerButtonBind
{
    SDL_GameControllerBindType bindType;
    
    union
    {
        int button;
        int axis;
        struct {
            int hat;
            int hat_mask;
        } hat;
    } value;

} SDL_GameControllerButtonBind;

Successfully parsing the nested types is the first step to supporting these classes, whether they are wrapped or not. This issue could be broken down into several tasks:

  • Allow the Clang parser to emit nested anonymous types. The only chance to emit those types is while parsing the outer type, otherwise it would be quite difficult to map them to data members (point and unnamed_arg_0 end up having the same generated type name). Document type for the Clang parser #84 is a step towards this.
  • These anonymous types obviously cannot be named inside the YAML configuration files, so Bindgen needs to generate appropriate rules for them (my guess is either copy the structure only, or derive from the parent type's rules).
  • If an anonymous type does not define a data member, its structure should be copied to the parent type.
  • C/C++ methods cannot reference anonymous types, but the property methods from Crystal wrappers can, so something has to be done about it.

At the end, Binding::T should look like the following:

lib Binding
  struct T
    point : T_Unnamed0
    u : Float32
    v : Float32
  end
  struct T_Unnamed0
    x : Int32
    y : Int32
  end
end

Or if there is a Crystal wrapper:

class T
  @unwrap : Binding::T*

  def point : ??? end
  def point=(point : ???) end

  def u : Int32 end
  def u=(u : Int32) : Void end
  def v : Int32 end
  def v=(v : Int32) : Void end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions