diff --git a/src/bindgen/ir/cfg.rs b/src/bindgen/ir/cfg.rs index 61b4a18b..b5591ec6 100644 --- a/src/bindgen/ir/cfg.rs +++ b/src/bindgen/ir/cfg.rs @@ -217,41 +217,19 @@ impl Cfg { } pub trait ToCondition: Sized { - type Output; - - fn to_condition(self, config: &Config) -> Option; -} - -impl<'a> ToCondition for &'a Option { - type Output = Condition; - - fn to_condition(self, config: &Config) -> Option { - self.clone().and_then(|cfg| cfg.to_condition(config)) - } + fn to_condition(&self, config: &Config) -> Option; } -impl ToCondition for Option { - type Output = Condition; - - fn to_condition(self, config: &Config) -> Option { - self.and_then(|cfg| cfg.to_condition(config)) +impl<'a> ToCondition for Option { + fn to_condition(&self, config: &Config) -> Option { + self.as_ref()?.to_condition(config) } } -impl<'a> ToCondition for &'a Cfg { - type Output = Condition; - - fn to_condition(self, config: &Config) -> Option { - self.clone().to_condition(config) - } -} - -impl ToCondition for Cfg { - type Output = Condition; - - fn to_condition(self, config: &Config) -> Option { - match self { - Cfg::Boolean(cfg_name) => { +impl<'a> ToCondition for Cfg { + fn to_condition(&self, config: &Config) -> Option { + match *self { + Cfg::Boolean(ref cfg_name) => { let define = config .defines .iter() @@ -261,12 +239,12 @@ impl ToCondition for Cfg { } else { warn!( "Missing `[defines]` entry for `{}` in cbindgen config.", - Cfg::Boolean(cfg_name) + self, ); None } } - Cfg::Named(cfg_name, cfg_value) => { + Cfg::Named(ref cfg_name, ref cfg_value) => { let define = config.defines.iter().find(|(key, ..)| { DefineKey::Named(&cfg_name, &cfg_value) == DefineKey::load(key) }); @@ -275,14 +253,14 @@ impl ToCondition for Cfg { } else { warn!( "Missing `[defines]` entry for `{}` in cbindgen config.", - Cfg::Named(cfg_name, cfg_value) + self, ); None } } - Cfg::Any(children) => { + Cfg::Any(ref children) => { let conditions: Vec<_> = children - .into_iter() + .iter() .filter_map(|x| x.to_condition(config)) .collect(); match conditions.len() { @@ -291,9 +269,9 @@ impl ToCondition for Cfg { _ => Some(Condition::Any(conditions)), } } - Cfg::All(children) => { + Cfg::All(ref children) => { let cfgs: Vec<_> = children - .into_iter() + .iter() .filter_map(|x| x.to_condition(config)) .collect(); match cfgs.len() { @@ -302,7 +280,7 @@ impl ToCondition for Cfg { _ => Some(Condition::All(cfgs)), } } - Cfg::Not(child) => child + Cfg::Not(ref child) => child .to_condition(config) .map(|cfg| Condition::Not(Box::new(cfg))), } @@ -361,8 +339,10 @@ pub trait ConditionWrite { impl ConditionWrite for Option { fn write_before(&self, config: &Config, out: &mut SourceWriter) { if let Some(ref cfg) = *self { + out.push_set_spaces(0); out.write("#if "); cfg.write(config, out); + out.pop_set_spaces(); out.new_line(); } } @@ -370,7 +350,9 @@ impl ConditionWrite for Option { fn write_after(&self, _config: &Config, out: &mut SourceWriter) { if self.is_some() { out.new_line(); + out.push_set_spaces(0); out.write("#endif"); + out.pop_set_spaces(); } } } diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index cf5596af..7b826a69 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -456,7 +456,7 @@ impl Constant { && config.constant.allow_static_const && !associated_to_transparent; - let condition = (&self.cfg).to_condition(config); + let condition = self.cfg.to_condition(config); condition.write_before(config, out); let name = if in_body { diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index 960862f1..99430595 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -26,6 +26,7 @@ pub struct EnumVariant { pub export_name: String, pub discriminant: Option, pub body: Option<(String, Struct)>, + pub cfg: Option, pub documentation: Documentation, } @@ -95,6 +96,7 @@ impl EnumVariant { Ok(res) } + let variant_cfg = Cfg::append(mod_cfg, Cfg::load(&variant.attrs)); let body = match variant.fields { syn::Fields::Unit => None, syn::Fields::Named(ref fields) => { @@ -108,7 +110,7 @@ impl EnumVariant { None, false, false, - Cfg::append(mod_cfg, Cfg::load(&variant.attrs)), + None, AnnotationSet::load(&variant.attrs)?, Documentation::none(), )) @@ -124,7 +126,7 @@ impl EnumVariant { None, false, true, - Cfg::append(mod_cfg, Cfg::load(&variant.attrs)), + None, AnnotationSet::load(&variant.attrs)?, Documentation::none(), )) @@ -143,6 +145,7 @@ impl EnumVariant { body, ) }), + variant_cfg, Documentation::load(&variant.attrs), )) } @@ -151,6 +154,7 @@ impl EnumVariant { name: String, discriminant: Option, body: Option<(String, Struct)>, + cfg: Option, documentation: Documentation, ) -> Self { let export_name = name.clone(); @@ -159,6 +163,7 @@ impl EnumVariant { export_name, discriminant, body, + cfg, documentation, } } @@ -182,6 +187,7 @@ impl EnumVariant { self.body .as_ref() .map(|&(ref name, ref ty)| (name.clone(), ty.specialize(generic_values, mappings))), + self.cfg.clone(), self.documentation.clone(), ) } @@ -201,12 +207,15 @@ impl EnumVariant { impl Source for EnumVariant { fn write(&self, config: &Config, out: &mut SourceWriter) { + let condition = self.cfg.to_condition(config); + condition.write_before(config, out); self.documentation.write(config, out); write!(out, "{}", self.export_name); if let Some(discriminant) = self.discriminant { write!(out, " = {}", discriminant); } out.write(","); + condition.write_after(config, out); } } @@ -289,7 +298,13 @@ impl Enum { if let Some(names) = annotations.list("enum-trailing-values") { for name in names { - variants.push(EnumVariant::new(name, None, None, Documentation::none())); + variants.push(EnumVariant::new( + name, + None, + None, + None, + Documentation::none(), + )); } } @@ -298,6 +313,7 @@ impl Enum { "Sentinel".to_owned(), None, None, + None, Documentation::simple(" Must be last for serialization purposes"), )); } @@ -443,6 +459,7 @@ impl Item for Enum { body.1.clone(), ) }), + variant.cfg.clone(), variant.documentation.clone(), ) }) @@ -523,8 +540,7 @@ impl Source for Enum { ReprType::I8 => "int8_t", }); - let condition = (&self.cfg).to_condition(config); - + let condition = self.cfg.to_condition(config); condition.write_before(config, out); self.documentation.write(config, out); @@ -642,8 +658,10 @@ impl Source for Enum { if let Some((_, ref body)) = variant.body { out.new_line(); out.new_line(); - + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); body.write(config, out); + condition.write_after(config, out); } } @@ -700,19 +718,26 @@ impl Source for Enum { out.open_brace(); } - for (i, &(ref field_name, ref body)) in self - .variants - .iter() - .filter_map(|variant| variant.body.as_ref()) - .enumerate() { - if i != 0 { - out.new_line(); - } - if config.style.generate_typedef() { - write!(out, "{} {};", body.export_name(), field_name); - } else { - write!(out, "struct {} {};", body.export_name(), field_name); + let mut first = true; + for variant in &self.variants { + let (field_name, body) = match variant.body { + Some((ref field_name, ref body)) => (field_name, body), + None => continue, + }; + + if !first { + out.new_line(); + } + first = false; + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); + if config.style.generate_typedef() { + write!(out, "{} {};", body.export_name(), field_name); + } else { + write!(out, "struct {} {};", body.export_name(), field_name); + } + condition.write_after(config, out); } } @@ -724,11 +749,16 @@ impl Source for Enum { // Emit convenience methods let derive_helper_methods = config.enumeration.derive_helper_methods(&self.annotations); + let derive_const_casts = config.enumeration.derive_const_casts(&self.annotations); + let derive_mut_casts = config.enumeration.derive_mut_casts(&self.annotations); if config.language == Language::Cxx && derive_helper_methods { for variant in &self.variants { out.new_line(); out.new_line(); + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); + let arg_renamer = |name: &str| { config .function @@ -794,9 +824,7 @@ impl Source for Enum { out.new_line(); write!(out, "return result;"); out.close_brace(false); - } - for variant in &self.variants { out.new_line(); out.new_line(); @@ -805,36 +833,27 @@ impl Source for Enum { out.open_brace(); write!(out, "return tag == {}::{};", enum_name, variant.export_name); out.close_brace(false); - } - } - - let derive_const_casts = config.enumeration.derive_const_casts(&self.annotations); - let derive_mut_casts = config.enumeration.derive_mut_casts(&self.annotations); - if config.language == Language::Cxx - && derive_helper_methods - && (derive_const_casts || derive_mut_casts) - { - let assert_name = match config.enumeration.cast_assert_name { - Some(ref n) => &**n, - None => "assert", - }; - for variant in &self.variants { - let (member_name, body) = match variant.body { - Some((ref member_name, ref body)) => (member_name, body), - None => continue, + let assert_name = match config.enumeration.cast_assert_name { + Some(ref n) => &**n, + None => "assert", }; - let field_count = body.fields.len() - skip_fields; - if field_count == 0 { - continue; - } - - let dig = field_count == 1 && body.tuple_struct; let mut derive_casts = |const_casts: bool| { + let (member_name, body) = match variant.body { + Some((ref member_name, ref body)) => (member_name, body), + None => return, + }; + + let field_count = body.fields.len() - skip_fields; + if field_count == 0 { + return; + } + out.new_line(); out.new_line(); + let dig = field_count == 1 && body.tuple_struct; if dig { let field = body.fields.iter().skip(skip_fields).next().unwrap(); let return_type = field.1.clone(); @@ -872,6 +891,8 @@ impl Source for Enum { if derive_mut_casts { derive_casts(false) } + + condition.write_after(config, out); } } @@ -902,6 +923,8 @@ impl Source for Enum { out.open_brace(); for variant in &self.variants { if let Some((ref variant_name, _)) = variant.body { + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); write!( out, "case {}::{}: return {} == {}.{};", @@ -912,6 +935,7 @@ impl Source for Enum { variant_name ); out.new_line(); + condition.write_after(config, out); } } write!(out, "default: return true;"); @@ -962,6 +986,8 @@ impl Source for Enum { out.open_brace(); for variant in &self.variants { if let Some((ref variant_name, ref item)) = variant.body { + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); write!( out, "case {}::{}: {}.~{}(); break;", @@ -971,6 +997,7 @@ impl Source for Enum { item.export_name(), ); out.new_line(); + condition.write_after(config, out); } } write!(out, "default: break;"); @@ -997,6 +1024,8 @@ impl Source for Enum { out.open_brace(); for variant in &self.variants { if let Some((ref variant_name, ref item)) = variant.body { + let condition = variant.cfg.to_condition(config); + condition.write_before(config, out); write!( out, "case {}::{}: ::new (&{}) ({})({}.{}); break;", @@ -1008,6 +1037,7 @@ impl Source for Enum { variant_name, ); out.new_line(); + condition.write_after(config, out); } } write!(out, "default: break;"); @@ -1051,7 +1081,6 @@ impl Source for Enum { out.close_brace(true); } } - condition.write_after(config, out); } } diff --git a/src/bindgen/ir/function.rs b/src/bindgen/ir/function.rs index e648e3f9..ebc9a335 100644 --- a/src/bindgen/ir/function.rs +++ b/src/bindgen/ir/function.rs @@ -182,7 +182,7 @@ impl Source for Function { let prefix = config.function.prefix(&func.annotations); let postfix = config.function.postfix(&func.annotations); - let condition = (&func.cfg).to_condition(config); + let condition = func.cfg.to_condition(config); condition.write_before(config, out); func.documentation.write(config, out); @@ -221,7 +221,7 @@ impl Source for Function { let prefix = config.function.prefix(&func.annotations); let postfix = config.function.postfix(&func.annotations); - let condition = (&func.cfg).to_condition(config); + let condition = func.cfg.to_condition(config); condition.write_before(config, out); diff --git a/src/bindgen/ir/opaque.rs b/src/bindgen/ir/opaque.rs index b8c917e2..a46dcee6 100644 --- a/src/bindgen/ir/opaque.rs +++ b/src/bindgen/ir/opaque.rs @@ -132,7 +132,7 @@ impl Item for OpaqueItem { impl Source for OpaqueItem { fn write(&self, config: &Config, out: &mut SourceWriter) { - let condition = (&self.cfg).to_condition(config); + let condition = self.cfg.to_condition(config); condition.write_before(config, out); self.documentation.write(config, out); diff --git a/src/bindgen/ir/structure.rs b/src/bindgen/ir/structure.rs index bfb588c8..141da2bb 100644 --- a/src/bindgen/ir/structure.rs +++ b/src/bindgen/ir/structure.rs @@ -406,7 +406,7 @@ impl Source for Struct { return; } - let condition = (&self.cfg).to_condition(config); + let condition = self.cfg.to_condition(config); condition.write_before(config, out); self.documentation.write(config, out); diff --git a/src/bindgen/ir/typedef.rs b/src/bindgen/ir/typedef.rs index 85e8be41..ae9567aa 100644 --- a/src/bindgen/ir/typedef.rs +++ b/src/bindgen/ir/typedef.rs @@ -193,7 +193,7 @@ impl Item for Typedef { impl Source for Typedef { fn write(&self, config: &Config, out: &mut SourceWriter) { - let condition = (&self.cfg).to_condition(config); + let condition = self.cfg.to_condition(config); condition.write_before(config, out); self.documentation.write(config, out); diff --git a/src/bindgen/ir/union.rs b/src/bindgen/ir/union.rs index 319d070c..fe048745 100644 --- a/src/bindgen/ir/union.rs +++ b/src/bindgen/ir/union.rs @@ -260,7 +260,7 @@ impl Item for Union { impl Source for Union { fn write(&self, config: &Config, out: &mut SourceWriter) { - let condition = (&self.cfg).to_condition(config); + let condition = self.cfg.to_condition(config); condition.write_before(config, out); self.documentation.write(config, out); diff --git a/src/bindgen/writer.rs b/src/bindgen/writer.rs index 78218586..06bec0d5 100644 --- a/src/bindgen/writer.rs +++ b/src/bindgen/writer.rs @@ -113,6 +113,10 @@ impl<'a, F: Write> SourceWriter<'a, F> { self.spaces.push(spaces); } + pub fn pop_set_spaces(&mut self) { + self.pop_tab() + } + pub fn line_length_for_align(&self) -> usize { if self.line_started { self.line_length diff --git a/tests/expectations/annotation.cpp b/tests/expectations/annotation.cpp index 35a07eb9..886bd03b 100644 --- a/tests/expectations/annotation.cpp +++ b/tests/expectations/annotation.cpp @@ -59,6 +59,10 @@ union F { return result; } + bool IsFoo() const { + return tag == Tag::Foo; + } + static F Bar(const uint8_t &aX, const int16_t &aY) { F result; @@ -68,20 +72,16 @@ union F { return result; } + bool IsBar() const { + return tag == Tag::Bar; + } + static F Baz() { F result; result.tag = Tag::Baz; return result; } - bool IsFoo() const { - return tag == Tag::Foo; - } - - bool IsBar() const { - return tag == Tag::Bar; - } - bool IsBaz() const { return tag == Tag::Baz; } @@ -116,6 +116,10 @@ struct H { return result; } + bool IsHello() const { + return tag == Tag::Hello; + } + static H There(const uint8_t &aX, const int16_t &aY) { H result; @@ -125,20 +129,16 @@ struct H { return result; } + bool IsThere() const { + return tag == Tag::There; + } + static H Everyone() { H result; result.tag = Tag::Everyone; return result; } - bool IsHello() const { - return tag == Tag::Hello; - } - - bool IsThere() const { - return tag == Tag::There; - } - bool IsEveryone() const { return tag == Tag::Everyone; } diff --git a/tests/expectations/asserted-cast.cpp b/tests/expectations/asserted-cast.cpp index 14aa20c9..0a9db482 100644 --- a/tests/expectations/asserted-cast.cpp +++ b/tests/expectations/asserted-cast.cpp @@ -37,33 +37,10 @@ struct H { return result; } - static H H_Bar(const uint8_t &aX, - const int16_t &aY) { - H result; - ::new (&result.bar.x) (uint8_t)(aX); - ::new (&result.bar.y) (int16_t)(aY); - result.tag = Tag::H_Bar; - return result; - } - - static H H_Baz() { - H result; - result.tag = Tag::H_Baz; - return result; - } - bool IsH_Foo() const { return tag == Tag::H_Foo; } - bool IsH_Bar() const { - return tag == Tag::H_Bar; - } - - bool IsH_Baz() const { - return tag == Tag::H_Baz; - } - const int16_t& AsH_Foo() const { MY_ASSERT(IsH_Foo()); return foo._0; @@ -74,6 +51,19 @@ struct H { return foo._0; } + static H H_Bar(const uint8_t &aX, + const int16_t &aY) { + H result; + ::new (&result.bar.x) (uint8_t)(aX); + ::new (&result.bar.y) (int16_t)(aY); + result.tag = Tag::H_Bar; + return result; + } + + bool IsH_Bar() const { + return tag == Tag::H_Bar; + } + const H_Bar_Body& AsH_Bar() const { MY_ASSERT(IsH_Bar()); return bar; @@ -83,6 +73,16 @@ struct H { MY_ASSERT(IsH_Bar()); return bar; } + + static H H_Baz() { + H result; + result.tag = Tag::H_Baz; + return result; + } + + bool IsH_Baz() const { + return tag == Tag::H_Baz; + } }; struct J { @@ -114,33 +114,10 @@ struct J { return result; } - static J J_Bar(const uint8_t &aX, - const int16_t &aY) { - J result; - ::new (&result.bar.x) (uint8_t)(aX); - ::new (&result.bar.y) (int16_t)(aY); - result.tag = Tag::J_Bar; - return result; - } - - static J J_Baz() { - J result; - result.tag = Tag::J_Baz; - return result; - } - bool IsJ_Foo() const { return tag == Tag::J_Foo; } - bool IsJ_Bar() const { - return tag == Tag::J_Bar; - } - - bool IsJ_Baz() const { - return tag == Tag::J_Baz; - } - const int16_t& AsJ_Foo() const { MY_ASSERT(IsJ_Foo()); return foo._0; @@ -151,6 +128,19 @@ struct J { return foo._0; } + static J J_Bar(const uint8_t &aX, + const int16_t &aY) { + J result; + ::new (&result.bar.x) (uint8_t)(aX); + ::new (&result.bar.y) (int16_t)(aY); + result.tag = Tag::J_Bar; + return result; + } + + bool IsJ_Bar() const { + return tag == Tag::J_Bar; + } + const J_Bar_Body& AsJ_Bar() const { MY_ASSERT(IsJ_Bar()); return bar; @@ -160,6 +150,16 @@ struct J { MY_ASSERT(IsJ_Bar()); return bar; } + + static J J_Baz() { + J result; + result.tag = Tag::J_Baz; + return result; + } + + bool IsJ_Baz() const { + return tag == Tag::J_Baz; + } }; union K { @@ -193,33 +193,10 @@ union K { return result; } - static K K_Bar(const uint8_t &aX, - const int16_t &aY) { - K result; - ::new (&result.bar.x) (uint8_t)(aX); - ::new (&result.bar.y) (int16_t)(aY); - result.tag = Tag::K_Bar; - return result; - } - - static K K_Baz() { - K result; - result.tag = Tag::K_Baz; - return result; - } - bool IsK_Foo() const { return tag == Tag::K_Foo; } - bool IsK_Bar() const { - return tag == Tag::K_Bar; - } - - bool IsK_Baz() const { - return tag == Tag::K_Baz; - } - const int16_t& AsK_Foo() const { MY_ASSERT(IsK_Foo()); return foo._0; @@ -230,6 +207,19 @@ union K { return foo._0; } + static K K_Bar(const uint8_t &aX, + const int16_t &aY) { + K result; + ::new (&result.bar.x) (uint8_t)(aX); + ::new (&result.bar.y) (int16_t)(aY); + result.tag = Tag::K_Bar; + return result; + } + + bool IsK_Bar() const { + return tag == Tag::K_Bar; + } + const K_Bar_Body& AsK_Bar() const { MY_ASSERT(IsK_Bar()); return bar; @@ -239,6 +229,16 @@ union K { MY_ASSERT(IsK_Bar()); return bar; } + + static K K_Baz() { + K result; + result.tag = Tag::K_Baz; + return result; + } + + bool IsK_Baz() const { + return tag == Tag::K_Baz; + } }; extern "C" { diff --git a/tests/expectations/both/cfg.c b/tests/expectations/both/cfg.c index 78556e98..a3242f9b 100644 --- a/tests/expectations/both/cfg.c +++ b/tests/expectations/both/cfg.c @@ -29,6 +29,32 @@ typedef struct FooHandle { } FooHandle; #endif +enum C_Tag { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +typedef uint8_t C_Tag; + +#if defined(PLATFORM_UNIX) +typedef struct C5_Body { + C_Tag tag; + int32_t int_; +} C5_Body; +#endif + +typedef union C { + C_Tag tag; +#if defined(PLATFORM_UNIX) + C5_Body c5; +#endif +} C; + #if (defined(PLATFORM_WIN) || defined(M_32)) typedef struct BarHandle { BarType ty; @@ -38,9 +64,9 @@ typedef struct BarHandle { #endif #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(FooHandle a); +void root(FooHandle a, C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(BarHandle a); +void root(BarHandle a, C c); #endif diff --git a/tests/expectations/both/cfg.compat.c b/tests/expectations/both/cfg.compat.c index e0d55f08..63df735a 100644 --- a/tests/expectations/both/cfg.compat.c +++ b/tests/expectations/both/cfg.compat.c @@ -41,6 +41,38 @@ typedef struct FooHandle { } FooHandle; #endif +enum C_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +#ifndef __cplusplus +typedef uint8_t C_Tag; +#endif // __cplusplus + +#if defined(PLATFORM_UNIX) +typedef struct C5_Body { + C_Tag tag; + int32_t int_; +} C5_Body; +#endif + +typedef union C { + C_Tag tag; +#if defined(PLATFORM_UNIX) + C5_Body c5; +#endif +} C; + #if (defined(PLATFORM_WIN) || defined(M_32)) typedef struct BarHandle { BarType ty; @@ -54,11 +86,11 @@ extern "C" { #endif // __cplusplus #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(FooHandle a); +void root(FooHandle a, C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(BarHandle a); +void root(BarHandle a, C c); #endif #ifdef __cplusplus diff --git a/tests/expectations/cfg.c b/tests/expectations/cfg.c index 2246dcf4..7cf77b34 100644 --- a/tests/expectations/cfg.c +++ b/tests/expectations/cfg.c @@ -29,6 +29,32 @@ typedef struct { } FooHandle; #endif +enum C_Tag { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +typedef uint8_t C_Tag; + +#if defined(PLATFORM_UNIX) +typedef struct { + C_Tag tag; + int32_t int_; +} C5_Body; +#endif + +typedef union { + C_Tag tag; +#if defined(PLATFORM_UNIX) + C5_Body c5; +#endif +} C; + #if (defined(PLATFORM_WIN) || defined(M_32)) typedef struct { BarType ty; @@ -38,9 +64,9 @@ typedef struct { #endif #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(FooHandle a); +void root(FooHandle a, C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(BarHandle a); +void root(BarHandle a, C c); #endif diff --git a/tests/expectations/cfg.compat.c b/tests/expectations/cfg.compat.c index d4c76438..6f9dc7ad 100644 --- a/tests/expectations/cfg.compat.c +++ b/tests/expectations/cfg.compat.c @@ -41,6 +41,38 @@ typedef struct { } FooHandle; #endif +enum C_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +#ifndef __cplusplus +typedef uint8_t C_Tag; +#endif // __cplusplus + +#if defined(PLATFORM_UNIX) +typedef struct { + C_Tag tag; + int32_t int_; +} C5_Body; +#endif + +typedef union { + C_Tag tag; +#if defined(PLATFORM_UNIX) + C5_Body c5; +#endif +} C; + #if (defined(PLATFORM_WIN) || defined(M_32)) typedef struct { BarType ty; @@ -54,11 +86,11 @@ extern "C" { #endif // __cplusplus #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(FooHandle a); +void root(FooHandle a, C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(BarHandle a); +void root(BarHandle a, C c); #endif #ifdef __cplusplus diff --git a/tests/expectations/cfg.cpp b/tests/expectations/cfg.cpp index 903b249f..8689cbd7 100644 --- a/tests/expectations/cfg.cpp +++ b/tests/expectations/cfg.cpp @@ -27,6 +27,33 @@ struct FooHandle { }; #endif +union C { + enum class Tag : uint8_t { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif + }; + +#if defined(PLATFORM_UNIX) + struct C5_Body { + Tag tag; + int32_t int_; + }; +#endif + + struct { + Tag tag; + }; +#if defined(PLATFORM_UNIX) + C5_Body c5; +#endif +}; + #if (defined(PLATFORM_WIN) || defined(M_32)) struct BarHandle { BarType ty; @@ -38,11 +65,11 @@ struct BarHandle { extern "C" { #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(FooHandle a); +void root(FooHandle a, C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(BarHandle a); +void root(BarHandle a, C c); #endif } // extern "C" diff --git a/tests/expectations/destructor-and-copy-ctor.cpp b/tests/expectations/destructor-and-copy-ctor.cpp index 9c0bbedb..d6a42c4d 100644 --- a/tests/expectations/destructor-and-copy-ctor.cpp +++ b/tests/expectations/destructor-and-copy-ctor.cpp @@ -71,6 +71,10 @@ struct Foo { return result; } + bool IsBar() const { + return tag == Tag::Bar; + } + static Foo Polygon1(const Polygon &a0) { Foo result; ::new (&result.polygon1._0) (Polygon)(a0); @@ -78,6 +82,10 @@ struct Foo { return result; } + bool IsPolygon1() const { + return tag == Tag::Polygon1; + } + static Foo Slice1(const OwnedSlice &a0) { Foo result; ::new (&result.slice1._0) (OwnedSlice)(a0); @@ -85,6 +93,10 @@ struct Foo { return result; } + bool IsSlice1() const { + return tag == Tag::Slice1; + } + static Foo Slice2(const OwnedSlice &a0) { Foo result; ::new (&result.slice2._0) (OwnedSlice)(a0); @@ -92,6 +104,10 @@ struct Foo { return result; } + bool IsSlice2() const { + return tag == Tag::Slice2; + } + static Foo Slice3(const FillRule &aFill, const OwnedSlice &aCoords) { Foo result; @@ -101,6 +117,10 @@ struct Foo { return result; } + bool IsSlice3() const { + return tag == Tag::Slice3; + } + static Foo Slice4(const FillRule &aFill, const OwnedSlice &aCoords) { Foo result; @@ -110,26 +130,6 @@ struct Foo { return result; } - bool IsBar() const { - return tag == Tag::Bar; - } - - bool IsPolygon1() const { - return tag == Tag::Polygon1; - } - - bool IsSlice1() const { - return tag == Tag::Slice1; - } - - bool IsSlice2() const { - return tag == Tag::Slice2; - } - - bool IsSlice3() const { - return tag == Tag::Slice3; - } - bool IsSlice4() const { return tag == Tag::Slice4; } @@ -225,6 +225,10 @@ union Baz { return result; } + bool IsBar2() const { + return tag == Tag::Bar2; + } + static Baz Polygon21(const Polygon &a0) { Baz result; ::new (&result.polygon21._0) (Polygon)(a0); @@ -232,6 +236,10 @@ union Baz { return result; } + bool IsPolygon21() const { + return tag == Tag::Polygon21; + } + static Baz Slice21(const OwnedSlice &a0) { Baz result; ::new (&result.slice21._0) (OwnedSlice)(a0); @@ -239,6 +247,10 @@ union Baz { return result; } + bool IsSlice21() const { + return tag == Tag::Slice21; + } + static Baz Slice22(const OwnedSlice &a0) { Baz result; ::new (&result.slice22._0) (OwnedSlice)(a0); @@ -246,6 +258,10 @@ union Baz { return result; } + bool IsSlice22() const { + return tag == Tag::Slice22; + } + static Baz Slice23(const FillRule &aFill, const OwnedSlice &aCoords) { Baz result; @@ -255,6 +271,10 @@ union Baz { return result; } + bool IsSlice23() const { + return tag == Tag::Slice23; + } + static Baz Slice24(const FillRule &aFill, const OwnedSlice &aCoords) { Baz result; @@ -264,26 +284,6 @@ union Baz { return result; } - bool IsBar2() const { - return tag == Tag::Bar2; - } - - bool IsPolygon21() const { - return tag == Tag::Polygon21; - } - - bool IsSlice21() const { - return tag == Tag::Slice21; - } - - bool IsSlice22() const { - return tag == Tag::Slice22; - } - - bool IsSlice23() const { - return tag == Tag::Slice23; - } - bool IsSlice24() const { return tag == Tag::Slice24; } @@ -355,6 +355,10 @@ union Taz { return result; } + bool IsBar3() const { + return tag == Tag::Bar3; + } + static Taz Taz1(const int32_t &a0) { Taz result; ::new (&result.taz1._0) (int32_t)(a0); @@ -362,6 +366,10 @@ union Taz { return result; } + bool IsTaz1() const { + return tag == Tag::Taz1; + } + static Taz Taz3(const OwnedSlice &a0) { Taz result; ::new (&result.taz3._0) (OwnedSlice)(a0); @@ -369,14 +377,6 @@ union Taz { return result; } - bool IsBar3() const { - return tag == Tag::Bar3; - } - - bool IsTaz1() const { - return tag == Tag::Taz1; - } - bool IsTaz3() const { return tag == Tag::Taz3; } @@ -435,6 +435,10 @@ union Tazz { return result; } + bool IsBar4() const { + return tag == Tag::Bar4; + } + static Tazz Taz2(const int32_t &a0) { Tazz result; ::new (&result.taz2._0) (int32_t)(a0); @@ -442,10 +446,6 @@ union Tazz { return result; } - bool IsBar4() const { - return tag == Tag::Bar4; - } - bool IsTaz2() const { return tag == Tag::Taz2; } diff --git a/tests/expectations/tag/cfg.c b/tests/expectations/tag/cfg.c index 92cd3871..89d04e11 100644 --- a/tests/expectations/tag/cfg.c +++ b/tests/expectations/tag/cfg.c @@ -29,6 +29,32 @@ struct FooHandle { }; #endif +enum C_Tag { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +typedef uint8_t C_Tag; + +#if defined(PLATFORM_UNIX) +struct C5_Body { + C_Tag tag; + int32_t int_; +}; +#endif + +union C { + C_Tag tag; +#if defined(PLATFORM_UNIX) + struct C5_Body c5; +#endif +}; + #if (defined(PLATFORM_WIN) || defined(M_32)) struct BarHandle { BarType ty; @@ -38,9 +64,9 @@ struct BarHandle { #endif #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(struct FooHandle a); +void root(struct FooHandle a, union C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(struct BarHandle a); +void root(struct BarHandle a, union C c); #endif diff --git a/tests/expectations/tag/cfg.compat.c b/tests/expectations/tag/cfg.compat.c index 3fb6f2d0..d8bed6d1 100644 --- a/tests/expectations/tag/cfg.compat.c +++ b/tests/expectations/tag/cfg.compat.c @@ -41,6 +41,38 @@ struct FooHandle { }; #endif +enum C_Tag +#ifdef __cplusplus + : uint8_t +#endif // __cplusplus + { + C1, + C2, +#if defined(PLATFORM_WIN) + C3, +#endif +#if defined(PLATFORM_UNIX) + C5, +#endif +}; +#ifndef __cplusplus +typedef uint8_t C_Tag; +#endif // __cplusplus + +#if defined(PLATFORM_UNIX) +struct C5_Body { + C_Tag tag; + int32_t int_; +}; +#endif + +union C { + C_Tag tag; +#if defined(PLATFORM_UNIX) + struct C5_Body c5; +#endif +}; + #if (defined(PLATFORM_WIN) || defined(M_32)) struct BarHandle { BarType ty; @@ -54,11 +86,11 @@ extern "C" { #endif // __cplusplus #if (defined(PLATFORM_UNIX) && defined(X11)) -void root(struct FooHandle a); +void root(struct FooHandle a, union C c); #endif #if (defined(PLATFORM_WIN) || defined(M_32)) -void root(struct BarHandle a); +void root(struct BarHandle a, union C c); #endif #ifdef __cplusplus diff --git a/tests/expectations/transform-op.cpp b/tests/expectations/transform-op.cpp index f848968d..3ce86a0a 100644 --- a/tests/expectations/transform-op.cpp +++ b/tests/expectations/transform-op.cpp @@ -54,42 +54,10 @@ union StyleFoo { return result; } - static StyleFoo Bar(const T &a0) { - StyleFoo result; - ::new (&result.bar._0) (T)(a0); - result.tag = Tag::Bar; - return result; - } - - static StyleFoo Baz(const StylePoint &a0) { - StyleFoo result; - ::new (&result.baz._0) (StylePoint)(a0); - result.tag = Tag::Baz; - return result; - } - - static StyleFoo Bazz() { - StyleFoo result; - result.tag = Tag::Bazz; - return result; - } - bool IsFoo() const { return tag == Tag::Foo; } - bool IsBar() const { - return tag == Tag::Bar; - } - - bool IsBaz() const { - return tag == Tag::Baz; - } - - bool IsBazz() const { - return tag == Tag::Bazz; - } - const Foo_Body& AsFoo() const { assert(IsFoo()); return foo; @@ -100,6 +68,17 @@ union StyleFoo { return foo; } + static StyleFoo Bar(const T &a0) { + StyleFoo result; + ::new (&result.bar._0) (T)(a0); + result.tag = Tag::Bar; + return result; + } + + bool IsBar() const { + return tag == Tag::Bar; + } + const T& AsBar() const { assert(IsBar()); return bar._0; @@ -110,6 +89,17 @@ union StyleFoo { return bar._0; } + static StyleFoo Baz(const StylePoint &a0) { + StyleFoo result; + ::new (&result.baz._0) (StylePoint)(a0); + result.tag = Tag::Baz; + return result; + } + + bool IsBaz() const { + return tag == Tag::Baz; + } + const StylePoint& AsBaz() const { assert(IsBaz()); return baz._0; @@ -119,6 +109,16 @@ union StyleFoo { assert(IsBaz()); return baz._0; } + + static StyleFoo Bazz() { + StyleFoo result; + result.tag = Tag::Bazz; + return result; + } + + bool IsBazz() const { + return tag == Tag::Bazz; + } }; template @@ -165,42 +165,10 @@ struct StyleBar { return result; } - static StyleBar Bar2(const T &a0) { - StyleBar result; - ::new (&result.bar2._0) (T)(a0); - result.tag = Tag::Bar2; - return result; - } - - static StyleBar Bar3(const StylePoint &a0) { - StyleBar result; - ::new (&result.bar3._0) (StylePoint)(a0); - result.tag = Tag::Bar3; - return result; - } - - static StyleBar Bar4() { - StyleBar result; - result.tag = Tag::Bar4; - return result; - } - bool IsBar1() const { return tag == Tag::Bar1; } - bool IsBar2() const { - return tag == Tag::Bar2; - } - - bool IsBar3() const { - return tag == Tag::Bar3; - } - - bool IsBar4() const { - return tag == Tag::Bar4; - } - const StyleBar1_Body& AsBar1() const { assert(IsBar1()); return bar1; @@ -211,6 +179,17 @@ struct StyleBar { return bar1; } + static StyleBar Bar2(const T &a0) { + StyleBar result; + ::new (&result.bar2._0) (T)(a0); + result.tag = Tag::Bar2; + return result; + } + + bool IsBar2() const { + return tag == Tag::Bar2; + } + const T& AsBar2() const { assert(IsBar2()); return bar2._0; @@ -221,6 +200,17 @@ struct StyleBar { return bar2._0; } + static StyleBar Bar3(const StylePoint &a0) { + StyleBar result; + ::new (&result.bar3._0) (StylePoint)(a0); + result.tag = Tag::Bar3; + return result; + } + + bool IsBar3() const { + return tag == Tag::Bar3; + } + const StylePoint& AsBar3() const { assert(IsBar3()); return bar3._0; @@ -230,6 +220,16 @@ struct StyleBar { assert(IsBar3()); return bar3._0; } + + static StyleBar Bar4() { + StyleBar result; + result.tag = Tag::Bar4; + return result; + } + + bool IsBar4() const { + return tag == Tag::Bar4; + } }; union StyleBaz { @@ -262,31 +262,10 @@ union StyleBaz { return result; } - static StyleBaz Baz2(const StylePoint &a0) { - StyleBaz result; - ::new (&result.baz2._0) (StylePoint)(a0); - result.tag = Tag::Baz2; - return result; - } - - static StyleBaz Baz3() { - StyleBaz result; - result.tag = Tag::Baz3; - return result; - } - bool IsBaz1() const { return tag == Tag::Baz1; } - bool IsBaz2() const { - return tag == Tag::Baz2; - } - - bool IsBaz3() const { - return tag == Tag::Baz3; - } - const StyleBar& AsBaz1() const { assert(IsBaz1()); return baz1._0; @@ -297,6 +276,17 @@ union StyleBaz { return baz1._0; } + static StyleBaz Baz2(const StylePoint &a0) { + StyleBaz result; + ::new (&result.baz2._0) (StylePoint)(a0); + result.tag = Tag::Baz2; + return result; + } + + bool IsBaz2() const { + return tag == Tag::Baz2; + } + const StylePoint& AsBaz2() const { assert(IsBaz2()); return baz2._0; @@ -306,6 +296,16 @@ union StyleBaz { assert(IsBaz2()); return baz2._0; } + + static StyleBaz Baz3() { + StyleBaz result; + result.tag = Tag::Baz3; + return result; + } + + bool IsBaz3() const { + return tag == Tag::Baz3; + } }; struct StyleTaz { @@ -336,31 +336,10 @@ struct StyleTaz { return result; } - static StyleTaz Taz2(const StyleBaz &a0) { - StyleTaz result; - ::new (&result.taz2._0) (StyleBaz)(a0); - result.tag = Tag::Taz2; - return result; - } - - static StyleTaz Taz3() { - StyleTaz result; - result.tag = Tag::Taz3; - return result; - } - bool IsTaz1() const { return tag == Tag::Taz1; } - bool IsTaz2() const { - return tag == Tag::Taz2; - } - - bool IsTaz3() const { - return tag == Tag::Taz3; - } - const StyleBar& AsTaz1() const { assert(IsTaz1()); return taz1._0; @@ -371,6 +350,17 @@ struct StyleTaz { return taz1._0; } + static StyleTaz Taz2(const StyleBaz &a0) { + StyleTaz result; + ::new (&result.taz2._0) (StyleBaz)(a0); + result.tag = Tag::Taz2; + return result; + } + + bool IsTaz2() const { + return tag == Tag::Taz2; + } + const StyleBaz& AsTaz2() const { assert(IsTaz2()); return taz2._0; @@ -380,6 +370,16 @@ struct StyleTaz { assert(IsTaz2()); return taz2._0; } + + static StyleTaz Taz3() { + StyleTaz result; + result.tag = Tag::Taz3; + return result; + } + + bool IsTaz3() const { + return tag == Tag::Taz3; + } }; extern "C" { diff --git a/tests/rust/cfg.rs b/tests/rust/cfg.rs index ed818233..d1836675 100644 --- a/tests/rust/cfg.rs +++ b/tests/rust/cfg.rs @@ -22,6 +22,16 @@ enum BarType { C, } +#[repr(u8)] +pub enum C { + C1, + C2, + #[cfg(windows)] + C3, + #[cfg(unix)] + C5 { int: i32 }, +} + #[cfg(any(windows, target_pointer_width="32"))] #[repr(C)] struct BarHandle { @@ -32,10 +42,10 @@ struct BarHandle { #[cfg(all(unix, x11))] #[no_mangle] -pub extern "C" fn root(a: FooHandle) +pub extern "C" fn root(a: FooHandle, c: C) { } #[cfg(any(windows, target_pointer_width="32"))] #[no_mangle] -pub extern "C" fn root(a: BarHandle) +pub extern "C" fn root(a: BarHandle, c: C) { }