/* automatically generated by rust-bindgen 0.69.4 */
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum TypeExport {
A = 0,
B = 1,
}
pub type TypeExport = ::std::os::raw::c_ulong;
Expected Results
/* automatically generated by rust-bindgen 0.69.4 */
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum _bindgen_ty_1 {
A = 0,
B = 1,
}
pub type TypeExport = ::std::os::raw::c_ulong;
Additional information
I was very confused at first but this makes sense in the end - take this with a grain of salt, my knowledge about C is very limited. It is important to note that
typedef enum Anonymous {
A,
B
} TypeExport __attribute__((mode(__word__)));
and
typedef enum Anonymous {
A,
B
} __attribute__((mode(__word__))) TypeExport;
appear to be different: In the first case the attribute (__attribute__((mode(__word__))) means "size of the type is a machine word") only applies to the typedef TypeExport, while in the second case the attribute applies directly to enum Anonymous and then transitively to TypeExport. I confirmed that by looking at LLVM output from two different clang versions (windows and ubuntu). See the following example output.
I would wish that annotating an attribute on the typedef would be forbidded in C and users would have to apply attributes to the enumeration itself, but this appears to be legal so bindgen should be able to handle that correctly.
Bindgen version
0.69.4
infers name for anonymous enumeration from its typedef, even if the typedef and enumerations are different.Input C/C++ Header
Bindgen Invocation
Actual Results
Expected Results
Additional information
I was very confused at first but this makes sense in the end - take this with a grain of salt, my knowledge about C is very limited. It is important to note that
and
appear to be different: In the first case the attribute (
__attribute__((mode(__word__)))
means "size of the type is a machine word") only applies to the typedefTypeExport
, while in the second case the attribute applies directly toenum Anonymous
and then transitively toTypeExport
. I confirmed that by looking at LLVM output from two different clang versions (windows and ubuntu). See the following example output.Ubuntu LLVM output
``` bash $ clang --version Ubuntu clang version 14.0.0-1ubuntu1.1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin bash $ cat old.c typedef enum Anonymous { A, B } TypeExport __attribute__((mode(__word__))); void some_function(enum Anonymous anonymous_input, TypeExport typed) {} bash $ clang -S -emit-llvm old.c && cat old.ll ; ModuleID = 'old.c' source_filename = "old.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define dso_local void @some_function(i32 noundef %0, i64 noundef %1) #0 { %3 = alloca i32, align 4 %4 = alloca i64, align 8 store i32 %0, i32* %3, align 4 store i64 %1, i64* %4, align 8 ret void } attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{i32 7, !"PIE Level", i32 2} !3 = !{i32 7, !"uwtable", i32 1} !4 = !{i32 7, !"frame-pointer", i32 2} !5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} bash $ cat new.c typedef enum Anonymous { A, B } __attribute__((mode(__word__))) TypeExport; void some_function(enum Anonymous anonymous_input, TypeExport typed) {} bash $ clang -S -emit-llvm new.c && cat new.ll ; ModuleID = 'new.c' source_filename = "new.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define dso_local void @some_function(i64 noundef %0, i64 noundef %1) #0 { %3 = alloca i64, align 8 %4 = alloca i64, align 8 store i64 %0, i64* %3, align 8 store i64 %1, i64* %4, align 8 ret void } attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{i32 7, !"PIE Level", i32 2} !3 = !{i32 7, !"uwtable", i32 1} !4 = !{i32 7, !"frame-pointer", i32 2} !5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} bash $ ```I would wish that annotating an attribute on the typedef would be forbidded in C and users would have to apply attributes to the enumeration itself, but this appears to be legal so bindgen should be able to handle that correctly.