Skip to content

Commit

Permalink
Follow-up to mozilla#582 to address review comment.
Browse files Browse the repository at this point in the history
This avoids propagating the derive-ostream annotation from an enum to
the variant body if the variant body already has an explicit annotation
set. This allows for more possibilities ending in compilation failure
but generally only when the user explicitly sets these annotations without
defining necessary serializers themselves. We should be able to assume
the user knows what they're doing if they trigger these particular scenarios.
  • Loading branch information
staktrace committed Oct 1, 2020
1 parent 2be47c8 commit 48eb4e9
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/bindgen/ir/annotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ impl AnnotationSet {
self.annotations.insert(name.to_string(), value);
}

pub fn contains(&self, name: &str) -> bool {
self.annotations.contains_key(name)
}

pub fn list(&self, name: &str) -> Option<Vec<String>> {
match self.annotations.get(name) {
Some(&AnnotationValue::List(ref x)) => Some(x.clone()),
Expand Down
6 changes: 4 additions & 2 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ impl EnumVariant {

let variant_cfg = Cfg::append(mod_cfg, Cfg::load(&variant.attrs));
let mut annotations = AnnotationSet::load(&variant.attrs)?;
if let Some(b) = enum_annotations.bool("derive-ostream") {
annotations.add("derive-ostream", AnnotationValue::Bool(b));
if !annotations.contains("derive-ostream") {
if let Some(b) = enum_annotations.bool("derive-ostream") {
annotations.add("derive-ostream", AnnotationValue::Bool(b));
}
}
let body = match variant.fields {
syn::Fields::Unit => VariantBody::Empty(annotations),
Expand Down
25 changes: 24 additions & 1 deletion tests/expectations/both/derive_ostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,27 @@ typedef struct H {
};
} H;

void root(A a, B b, C c, D d, F f, H h);
enum J_Tag {
Hi,
Peoples,
};
typedef uint8_t J_Tag;

typedef struct Hi_Body {
int16_t _0;
} Hi_Body;

typedef struct Peoples_Body {
uint8_t x;
int16_t y;
} Peoples_Body;

typedef struct J {
J_Tag tag;
union {
Hi_Body hi;
Peoples_Body peoples;
};
} J;

void root(A a, B b, C c, D d, F f, H h, J j);
31 changes: 30 additions & 1 deletion tests/expectations/both/derive_ostream.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,40 @@ typedef struct H {
};
} H;

enum J_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
Hi,
Peoples,
};
#ifndef __cplusplus
typedef uint8_t J_Tag;
#endif // __cplusplus

typedef struct Hi_Body {
int16_t _0;
} Hi_Body;

typedef struct Peoples_Body {
uint8_t x;
int16_t y;
} Peoples_Body;

typedef struct J {
J_Tag tag;
union {
Hi_Body hi;
Peoples_Body peoples;
};
} J;

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

void root(A a, B b, C c, D d, F f, H h);
void root(A a, B b, C c, D d, F f, H h, J j);

#ifdef __cplusplus
} // extern "C"
Expand Down
25 changes: 24 additions & 1 deletion tests/expectations/derive_ostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,27 @@ typedef struct {
};
} H;

void root(A a, B b, C c, D d, F f, H h);
enum J_Tag {
Hi,
Peoples,
};
typedef uint8_t J_Tag;

typedef struct {
int16_t _0;
} Hi_Body;

typedef struct {
uint8_t x;
int16_t y;
} Peoples_Body;

typedef struct {
J_Tag tag;
union {
Hi_Body hi;
Peoples_Body peoples;
};
} J;

void root(A a, B b, C c, D d, F f, H h, J j);
31 changes: 30 additions & 1 deletion tests/expectations/derive_ostream.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,40 @@ typedef struct {
};
} H;

enum J_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
Hi,
Peoples,
};
#ifndef __cplusplus
typedef uint8_t J_Tag;
#endif // __cplusplus

typedef struct {
int16_t _0;
} Hi_Body;

typedef struct {
uint8_t x;
int16_t y;
} Peoples_Body;

typedef struct {
J_Tag tag;
union {
Hi_Body hi;
Peoples_Body peoples;
};
} J;

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

void root(A a, B b, C c, D d, F f, H h);
void root(A a, B b, C c, D d, F f, H h, J j);

#ifdef __cplusplus
} // extern "C"
Expand Down
29 changes: 28 additions & 1 deletion tests/expectations/derive_ostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,35 @@ struct H {
};
};

struct J {
enum class Tag : uint8_t {
Hi,
Peoples,
};

struct Hi_Body {
int16_t _0;
};

struct Peoples_Body {
uint8_t x;
int16_t y;

friend std::ostream& operator<<(std::ostream& stream, const Peoples_Body& instance) {
return stream << "{ " << "x=" << instance.x << ", "
<< "y=" << instance.y << " }";
}
};

Tag tag;
union {
Hi_Body hi;
Peoples_Body peoples;
};
};

extern "C" {

void root(A a, B b, C c, D d, F f, H h);
void root(A a, B b, C c, D d, F f, H h, J j);

} // extern "C"
25 changes: 24 additions & 1 deletion tests/expectations/tag/derive_ostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,27 @@ struct H {
};
};

void root(struct A a, struct B b, C c, struct D d, union F f, struct H h);
enum J_Tag {
Hi,
Peoples,
};
typedef uint8_t J_Tag;

struct Hi_Body {
int16_t _0;
};

struct Peoples_Body {
uint8_t x;
int16_t y;
};

struct J {
J_Tag tag;
union {
struct Hi_Body hi;
struct Peoples_Body peoples;
};
};

void root(struct A a, struct B b, C c, struct D d, union F f, struct H h, struct J j);
31 changes: 30 additions & 1 deletion tests/expectations/tag/derive_ostream.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,40 @@ struct H {
};
};

enum J_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
Hi,
Peoples,
};
#ifndef __cplusplus
typedef uint8_t J_Tag;
#endif // __cplusplus

struct Hi_Body {
int16_t _0;
};

struct Peoples_Body {
uint8_t x;
int16_t y;
};

struct J {
J_Tag tag;
union {
struct Hi_Body hi;
struct Peoples_Body peoples;
};
};

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

void root(struct A a, struct B b, C c, struct D d, union F f, struct H h);
void root(struct A a, struct B b, C c, struct D d, union F f, struct H h, struct J j);

#ifdef __cplusplus
} // extern "C"
Expand Down
9 changes: 9 additions & 0 deletions tests/rust/derive_ostream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ enum H {
Everyone
}

/// cbindgen:derive-ostream=false
#[repr(C, u8)]
enum J {
Hi(i16),
/// cbindgen:derive-ostream=true
Peoples { x: u8, y: i16 },
}

#[no_mangle]
pub extern "C" fn root(
a: A,
Expand All @@ -46,5 +54,6 @@ pub extern "C" fn root(
d: D,
f: F,
h: H,
j: J,
) { }

0 comments on commit 48eb4e9

Please sign in to comment.