cbindgen icon indicating copy to clipboard operation
cbindgen copied to clipboard

Generate forward declarations for structs with cyclical pointer references

Open eqrion opened this issue 8 years ago • 4 comments

Example

struct Foo {
    data: *const Bar,
}
struct Bar {
    data: *const Foo,
}

Possible output

struct Bar;
struct Foo {
    const Bar* data;
}
struct Bar {
    const Foo* data;
}

This would require the dependency ordering algorithm to understand when a reference needs a declaration and when it needs a definition. If in the previous example, the data members were not pointers then it wouldn't work.

eqrion avatar Aug 17 '17 16:08 eqrion

Hello :-),

Thanks for using cbindgen!

I'm facing this issue right now. Any idea how to solve it?

Hywan avatar Jun 04 '18 15:06 Hywan

#832 has some pointers into how to fix this.

emilio avatar May 29 '23 17:05 emilio

I was having a go at this issue because it also affects me. The forward declarations I have to put in after_includes keep increasing...

I managed to record what is being declared during output to use as reference but now I'm kinda lost. It is unclear how the transformations are supposed to work...

Currently it parses to IR first, fixes some stuff, then does transformations while outputting, which means I have to predict what transformations will occur (error prone) or move even more stuff to the output stage.

In my view the language backends should affect the syn parse stage, generating and transforming IR stuff according to the config and language, reflecting what will really be generated. The output stage should be limited to generating the header according to style choices, no transformations.

@emilio Any advice on how I should proceed?

flaviojs avatar Jun 11 '24 07:06 flaviojs

After analyzing the source this flowchart appears to be what was originally intended.

flowchart TD
    bindgen::builder::Builder -->|parse stage => build IR from rust code| bindgen::library::Library
    bindgen::library::Library -->|transform stage => mutate IR| bindgen::bindings::Bindings
    bindgen::bindings::Bindings -->|write stage => translate IR to text| files(header file and depfile)

If this is true, then transformations that happen after Bindings should be moved to before it is generated. (ex: transparent struct -> typedef in write_struct)

Is this interpretation correct?

flaviojs avatar Jun 13 '24 11:06 flaviojs