Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,33 +164,35 @@ impl EnumVariant {
let body = match variant.fields {
syn::Fields::Unit => VariantBody::Empty(annotations),
syn::Fields::Named(ref fields) => {
let path = Path::new(format!("{}_Body", variant.ident));
let path = Path::new(format!("{}_{}_Body", self_path.name(), variant.ident));
let name = body_rule
.apply(
&variant.ident.unraw().to_string(),
IdentifierType::StructMember,
)
.into_owned();
let mut body = Struct::new(
path,
generic_params,
parse_fields(inline_tag_field, &fields.named, self_path, None)?,
inline_tag_field,
true,
None,
false,
None,
annotations,
Documentation::none(),
);
body.export_name = format!("{}_Body", variant.ident);
VariantBody::Body {
body: Struct::new(
path,
generic_params,
parse_fields(inline_tag_field, &fields.named, self_path, None)?,
inline_tag_field,
true,
None,
false,
None,
annotations,
Documentation::none(),
),
body,
name,
inline: false,
inline_casts: false,
}
}
syn::Fields::Unnamed(ref fields) => {
let path = Path::new(format!("{}_Body", variant.ident));
let path = Path::new(format!("{}_{}_Body", self_path.name(), variant.ident));
let name = body_rule
.apply(
&variant.ident.unraw().to_string(),
Expand All @@ -205,19 +207,21 @@ impl EnumVariant {
// As a result we don't currently inline variant definitions in C++ mode at all.
let inline = inline_casts && config.language != Language::Cxx;
let inline_name = if inline { Some(&*name) } else { None };
let mut body = Struct::new(
path,
generic_params,
parse_fields(inline_tag_field, &fields.unnamed, self_path, inline_name)?,
inline_tag_field,
true,
None,
false,
None,
annotations,
Documentation::none(),
);
body.export_name = format!("{}_Body", variant.ident);
VariantBody::Body {
body: Struct::new(
path,
generic_params,
parse_fields(inline_tag_field, &fields.unnamed, self_path, inline_name)?,
inline_tag_field,
true,
None,
false,
None,
annotations,
Documentation::none(),
),
body,
name,
inline,
inline_casts,
Expand Down
8 changes: 6 additions & 2 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ impl Struct {
config: &Config,
) -> Self {
let mangled_path = mangle::mangle_path(&self.path, generic_values, &config.export.mangle);
Struct::new(
let mangled_export_name =
mangle::mangle_name(&self.export_name, generic_values, &config.export.mangle);
let mut specialized = Struct::new(
mangled_path,
GenericParams::default(),
self.fields
Expand All @@ -219,7 +221,9 @@ impl Struct {
self.cfg.clone(),
self.annotations.clone(),
self.documentation.clone(),
)
);
specialized.export_name = mangled_export_name;
specialized
}

pub(crate) fn emit_bitflags_binop<F: Write>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
use_a;
use_b;
};
46 changes: 46 additions & 0 deletions tests/expectations/generic_enum_variant_collision.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
int32_t x;
} Payload;

typedef enum {
ResultA_Payload_Ok_Payload,
ResultA_Payload_Err_Payload,
} ResultA_Payload_Tag;

typedef struct {
ResultA_Payload_Tag tag;
union {
struct {
Payload ok;
};
struct {
void *err;
};
};
} ResultA_Payload;

typedef enum {
ResultB_Payload_Ok_Payload,
ResultB_Payload_Err_Payload,
} ResultB_Payload_Tag;

typedef struct {
ResultB_Payload_Tag tag;
union {
struct {
Payload ok;
};
struct {
void *err;
};
};
} ResultB_Payload;

void use_a(ResultA_Payload _a);

void use_b(ResultB_Payload _b);
54 changes: 54 additions & 0 deletions tests/expectations/generic_enum_variant_collision.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
int32_t x;
} Payload;

typedef enum {
ResultA_Payload_Ok_Payload,
ResultA_Payload_Err_Payload,
} ResultA_Payload_Tag;

typedef struct {
ResultA_Payload_Tag tag;
union {
struct {
Payload ok;
};
struct {
void *err;
};
};
} ResultA_Payload;

typedef enum {
ResultB_Payload_Ok_Payload,
ResultB_Payload_Err_Payload,
} ResultB_Payload_Tag;

typedef struct {
ResultB_Payload_Tag tag;
union {
struct {
Payload ok;
};
struct {
void *err;
};
};
} ResultB_Payload;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void use_a(ResultA_Payload _a);

void use_b(ResultB_Payload _b);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
61 changes: 61 additions & 0 deletions tests/expectations/generic_enum_variant_collision.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

struct Payload {
int32_t x;
};

template<typename T>
struct ResultA {
enum class Tag {
ResultA_Ok,
ResultA_Err,
};

struct ResultA_Ok_Body {
T _0;
};

struct ResultA_Err_Body {
void *_0;
};

Tag tag;
union {
ResultA_Ok_Body ok;
ResultA_Err_Body err;
};
};

template<typename T>
struct ResultB {
enum class Tag {
ResultB_Ok,
ResultB_Err,
};

struct ResultB_Ok_Body {
T _0;
};

struct ResultB_Err_Body {
void *_0;
};

Tag tag;
union {
ResultB_Ok_Body ok;
ResultB_Err_Body err;
};
};

extern "C" {

void use_a(ResultA<Payload> _a);

void use_b(ResultB<Payload> _b);

} // extern "C"
32 changes: 32 additions & 0 deletions tests/expectations/generic_enum_variant_collision.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list

cdef extern from *:

ctypedef struct Payload:
int32_t x;

ctypedef enum ResultA_Payload_Tag:
ResultA_Payload_Ok_Payload,
ResultA_Payload_Err_Payload,

ctypedef struct ResultA_Payload:
ResultA_Payload_Tag tag;
Payload ok;
void *err;

ctypedef enum ResultB_Payload_Tag:
ResultB_Payload_Ok_Payload,
ResultB_Payload_Err_Payload,

ctypedef struct ResultB_Payload:
ResultB_Payload_Tag tag;
Payload ok;
void *err;

void use_a(ResultA_Payload _a);

void use_b(ResultB_Payload _b);
46 changes: 46 additions & 0 deletions tests/expectations/generic_enum_variant_collision_both.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct Payload {
int32_t x;
} Payload;

typedef enum ResultA_Payload_Tag {
ResultA_Payload_Ok_Payload,
ResultA_Payload_Err_Payload,
} ResultA_Payload_Tag;

typedef struct ResultA_Payload {
ResultA_Payload_Tag tag;
union {
struct {
struct Payload ok;
};
struct {
void *err;
};
};
} ResultA_Payload;

typedef enum ResultB_Payload_Tag {
ResultB_Payload_Ok_Payload,
ResultB_Payload_Err_Payload,
} ResultB_Payload_Tag;

typedef struct ResultB_Payload {
ResultB_Payload_Tag tag;
union {
struct {
struct Payload ok;
};
struct {
void *err;
};
};
} ResultB_Payload;

void use_a(struct ResultA_Payload _a);

void use_b(struct ResultB_Payload _b);
Loading