JuliaInterop / Clang.jl

C binding generator and Julia interface to libclang
https://juliainterop.github.io/Clang.jl/
MIT License
217 stars 68 forks source link

Fix unhandled non-field struct children #479

Closed serenity4 closed 3 months ago

serenity4 commented 3 months ago

Unhandled non-field child nodes were sometimes present in children(cursor), and were already handled in printing but not in codegen, which triggered an assertion error at https://github.com/JuliaInterop/Clang.jl/blob/30aaa5de6be51c105dc80139533d0db67263b762/src/generator/print.jl#L119

where fields built from the codegened expression had an extra field for a forward struct declaration.

Here is an exemple header where the error appeared:

typedef struct _ExampleStruct {
  struct _ForwardA *a;
} ExampleStruct;

typedef struct _ForwardA {
  int a;
} ForwardA;

and codegen produced something like

struct _ExampleStruct
  _ForwardA::_ForwardA
  a::Ptr{_ForwardA}
end

Now we don't have that weird spurious _ForwardA::_ForwardA field.

It happened to me while wrapping a larger header (winuser.h) using this pattern, but I couldn't come up with a minimal reproducer. For some reason, fields(Clang.getCursorType(cursor)) for _ExampleStruct was empty in that larger header and Clang.jl fell back to using children to extract fields, while in any example I have tried for a minimal reproducer fields(Clang.getCursorType(cusor)) succeeded in returning the only field present as expected.

Gnimuc commented 3 months ago

_emit_getproperty_ptr! may also need to be patched.

Gnimuc commented 3 months ago

Could be related to the upstream changes discussed in #472

Gnimuc commented 3 months ago

let's wait for more bug reports.