rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Question: Is it possible to set a name for anonymous unions using an annotation comment to the C/C++ source code?

Open leinardi opened this issue 5 years ago • 6 comments

I would like to know if is possible to suggest to bindgen a name for anonymous unions.

For example, if I have this structure:

typedef struct
{
	unsigned int	tCL;
	union {
	unsigned int	tRCD;
	unsigned int	tRCD_RD;
	};
	unsigned int	tRCD_WR,
			tRP,
			tRAS,
			tRC,

			tRCPB,
			tRPPB;
	union {
	unsigned int	tRRD;
	unsigned int	tRRDS;
	};
	unsigned int	tRRDL,
			tRRDDLR,

			tFAW,
			tFAWSLR,
			tFAWDLR,

			tWTRS,
			tWTRL,
			tWR;
} RAM_TIMING;

bindgen generates a rust struct like this:

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RAM_TIMING {
    pub tCL: ::std::os::raw::c_uint,
    pub __bindgen_anon_1: RAM_TIMING__bindgen_ty_1,
    pub tRCD_WR: ::std::os::raw::c_uint,
    pub tRP: ::std::os::raw::c_uint,
    pub tRAS: ::std::os::raw::c_uint,
    pub tRC: ::std::os::raw::c_uint,
    pub tRCPB: ::std::os::raw::c_uint,
    pub tRPPB: ::std::os::raw::c_uint,
    pub __bindgen_anon_2: RAM_TIMING__bindgen_ty_2,
    pub tRRDL: ::std::os::raw::c_uint,
    pub tRRDDLR: ::std::os::raw::c_uint,
    pub tFAW: ::std::os::raw::c_uint,
    pub tFAWSLR: ::std::os::raw::c_uint,
    pub tFAWDLR: ::std::os::raw::c_uint,
    pub tWTRS: ::std::os::raw::c_uint,
    pub tWTRL: ::std::os::raw::c_uint,
    pub tWR: ::std::os::raw::c_uint
}

I was wondering if there is a way to specify a name for all the anonymous fiels, like __bindgen_anon_1 and RAM_TIMING__bindgen_ty_1.

I don't know if it makes sense, but I was hoping to be able to do something like:

typedef struct
{
	unsigned int	tCL;
        /// <div rustbindgen name="tRCD_u"></div>
	union {
	unsigned int	tRCD;
	unsigned int	tRCD_RD;
	};
[...]

to generate something like this:

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RAM_TIMING {
    pub tCL: ::std::os::raw::c_uint,
    pub tRCD_u: RAM_TIMING__tRCD_u,
[...]

Unfortunately I cannot simply give a name to the union. If the comment solution is not possible, is there any other way to control the name used by the generated code in case of anonymous unions?

leinardi avatar Jan 16 '21 13:01 leinardi

I don't think this is possible right now, but an annotation might be reasonable. What's the usecases for having the union be named? It cant' be named on C either.

emilio avatar Jan 29 '21 11:01 emilio

Hi @emilio, thank you for the answer. What I would like to achieve is to be able to pick a name for the __bindgen_anon_* fields.

Having several __bindgen_anon_* makes pretty hard to understand what are they actually mapping and I would love to be able to decide that name directly form the C header file with an annotation.

I would like to go from the current situation:

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RAM_TIMING {
    pub tCL: ::std::os::raw::c_uint,
    pub __bindgen_anon_1: RAM_TIMING__bindgen_ty_1,
[...]

to something like this:

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RAM_TIMING {
    pub tCL: ::std::os::raw::c_uint,
    pub tRCD_u: RAM_TIMING__tRCD_u,
[...]

I would like to have a way to decide the name of __bindgen_anon_1 and RAM_TIMING__bindgen_ty_1 so that, when I'm accessing this struct I could have self explanatory names instead of __bindgen_anon_*:

fn get_trct(ram_timing: &RAM_TIMING) -> u32 {
    ram_timing.tRCD_u.tRCD
}

instead of:

fn get_trct(ram_timing: &RAM_TIMING) -> u32 {
    ram_timing.__bindgen_anon_1.tRCD
}

leinardi avatar Jan 29 '21 12:01 leinardi

Ok, so there are two things that have automatic names right now, one of them is __bindgen_anon, the other one is the union name itself (RAM_TIMING__bindgen_ty_1). I think an annotation for these seems fine. Do you envision a use case for the two names to be different? If not it can probably be the same annotation.

emilio avatar Jan 29 '21 13:01 emilio

Mmm, right now I can't think of a use case where where can be useful having different names so I would say to use the same annotation for both :+1: Thanks a lot!

leinardi avatar Jan 29 '21 14:01 leinardi

Ah, I forgot to say it: could this annotation work also for anonymous struct the same way that works for the unions?

The use case is something like this:

typedef union
{
	signed long long	Proc;
	struct {
		unsigned int	Core;
		signed int	Thread;
	};
} SERVICE_PROC;

that currently generate this:

#[repr(C)]
#[derive(Copy, Clone)]
pub union SERVICE_PROC {
    pub Proc: ::std::os::raw::c_longlong,
    pub __bindgen_anon_1: SERVICE_PROC__bindgen_ty_1,
    _bindgen_union_align: u64,
}

I would like to be able to choose the name of the anonymous struct the same way I could set the name of an anonymous union.

leinardi avatar Jan 29 '21 14:01 leinardi

Randomly: right now I'm hitting an annoyance that this would solve. Specifically, I'm marking a particular struct as blocklist and opaque. But its anonymous substructure is still being generated, which pulls in a lot of other types we don't want/need bindings for.

Naming the substructure would let us exclude it without hardcoding the bindgen automatic name as blocked/opaque. Hardcoding the automatically-generated name feels fragile.

noahgibbs avatar Feb 17 '22 17:02 noahgibbs