From fd9c1fe2de777b34860ba06e0df29ab9919ca0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 19 Oct 2016 10:54:33 +0200 Subject: [PATCH] codegen: Generate constants names for unnamed enums in classes. --- src/codegen/mod.rs | 24 ++++++++++++++---- tests/expectations/anon_enum.rs | 2 ++ tests/expectations/const_enum_unnamed.rs | 31 ++++++++++++++++++++++++ tests/headers/const_enum_unnamed.hpp | 9 +++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 tests/expectations/const_enum_unnamed.rs create mode 100644 tests/headers/const_enum_unnamed.hpp diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 5688065f05..55312c3178 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -16,6 +16,7 @@ use ir::layout::Layout; use ir::annotations::FieldAccessorKind; use std::ops; +use std::borrow::Cow; use std::mem; use std::collections::BTreeSet; use std::collections::HashSet; @@ -1232,6 +1233,9 @@ impl CodeGenerator for Enum { result.push(constant); } + // Used to mangle the constants we generate in the unnamed-enum case. + let mut parent_canonical_name = None; + // A map where we keep a value -> variant relation. let mut seen_values = HashMap::<_, String>::new(); let enum_ty = item.expect_type(); @@ -1264,11 +1268,21 @@ impl CodeGenerator for Enum { if enum_ty.name().is_none() { // NB: if we want to do this for other kind of nested // enums we can probably mangle the name. - if item.is_toplevel(ctx) { - add_constant(enum_ty, &name, &variant_name, - &variant_name, enum_rust_ty.clone(), - result); - } + let mangled_name = if item.is_toplevel(ctx) { + variant_name.clone() + } else { + if parent_canonical_name.is_none() { + parent_canonical_name = Some(item.parent_id().canonical_name(ctx)); + } + + Cow::Owned( + format!("{}_{}", parent_canonical_name.as_ref().unwrap(), + variant_name)) + }; + + add_constant(enum_ty, &name, &mangled_name, + &variant_name, enum_rust_ty.clone(), + result); } entry.insert(variant_name.into_owned()); diff --git a/tests/expectations/anon_enum.rs b/tests/expectations/anon_enum.rs index b06585b120..17212c12b6 100644 --- a/tests/expectations/anon_enum.rs +++ b/tests/expectations/anon_enum.rs @@ -10,6 +10,8 @@ pub struct Test { pub foo: ::std::os::raw::c_int, pub bar: f32, } +pub const Test_T_NONE: Test__bindgen_ty_bindgen_id_6 = + Test__bindgen_ty_bindgen_id_6::T_NONE; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Test__bindgen_ty_bindgen_id_6 { T_NONE = 0, } diff --git a/tests/expectations/const_enum_unnamed.rs b/tests/expectations/const_enum_unnamed.rs new file mode 100644 index 0000000000..e16dc405ee --- /dev/null +++ b/tests/expectations/const_enum_unnamed.rs @@ -0,0 +1,31 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +pub const FOO_BAR: _bindgen_ty_bindgen_id_1 = + _bindgen_ty_bindgen_id_1::FOO_BAR; +pub const FOO_BAZ: _bindgen_ty_bindgen_id_1 = + _bindgen_ty_bindgen_id_1::FOO_BAZ; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum _bindgen_ty_bindgen_id_1 { FOO_BAR = 0, FOO_BAZ = 1, } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Foo { + pub _address: u8, +} +pub const Foo_FOO_BAR: Foo__bindgen_ty_bindgen_id_5 = + Foo__bindgen_ty_bindgen_id_5::FOO_BAR; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Foo__bindgen_ty_bindgen_id_5 { FOO_BAR = 10, } +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::() , 1usize); + assert_eq!(::std::mem::align_of::() , 1usize); +} +impl Clone for Foo { + fn clone(&self) -> Self { *self } +} diff --git a/tests/headers/const_enum_unnamed.hpp b/tests/headers/const_enum_unnamed.hpp new file mode 100644 index 0000000000..eb139434ce --- /dev/null +++ b/tests/headers/const_enum_unnamed.hpp @@ -0,0 +1,9 @@ + +enum { + FOO_BAR, + FOO_BAZ, +}; + +class Foo { + enum { FOO_BAR = 10 }; +};