From b718662520b83a08c341eba27406198d946020dd Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 4 Dec 2018 12:18:54 -0500 Subject: [PATCH] Support references better This adds better support for references in the type system and uses them for enumeration helpers instead of string concatenation. --- src/bindgen/cdecl.rs | 16 ++++++++++++++++ src/bindgen/ir/enumeration.rs | 2 +- src/bindgen/ir/ty.rs | 24 ++++++++++++++++++++++++ src/bindgen/mangle.rs | 9 ++++++--- tests/expectations/annotation.cpp | 12 ++++++------ 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/bindgen/cdecl.rs b/src/bindgen/cdecl.rs index 882e45c..6a1691c 100644 --- a/src/bindgen/cdecl.rs +++ b/src/bindgen/cdecl.rs @@ -14,6 +14,7 @@ use bindgen::writer::{ListType, SourceWriter}; enum CDeclarator { Ptr(bool), + Ref, Array(String), Func(Vec<(Option, CDecl)>, bool), } @@ -22,6 +23,7 @@ impl CDeclarator { fn is_ptr(&self) -> bool { match self { &CDeclarator::Ptr(..) => true, + &CDeclarator::Ref => true, &CDeclarator::Func(..) => true, _ => false, } @@ -121,6 +123,14 @@ impl CDecl { self.declarators.push(CDeclarator::Ptr(is_const)); self.build_type(t, false); } + &Type::Ref(ref t) => { + self.declarators.push(CDeclarator::Ref); + self.build_type(t, true); + } + &Type::MutRef(ref t) => { + self.declarators.push(CDeclarator::Ref); + self.build_type(t, false); + } &Type::Array(ref t, ref constant) => { let len = constant.as_str().to_owned(); self.declarators.push(CDeclarator::Array(len)); @@ -180,6 +190,9 @@ impl CDecl { out.write("*"); } } + &CDeclarator::Ref => { + out.write("&"); + } &CDeclarator::Array(..) => { if next_is_pointer { out.write("("); @@ -207,6 +220,9 @@ impl CDecl { &CDeclarator::Ptr(..) => { last_was_pointer = true; } + &CDeclarator::Ref => { + last_was_pointer = true; + } &CDeclarator::Array(ref constant) => { if last_was_pointer { out.write(")"); diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index fce01cd..a739da3 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -672,7 +672,7 @@ impl Source for Enum { .skip(skip_fields) .map(|&(ref name, ref ty, _)| { // const-ref args to constructor - (format!("const& {}", arg_renamer(name)), ty.clone()) + (arg_renamer(name), Type::Ref(Box::new(ty.clone()))) }) .collect(); out.write_vertical_source_list(&vec[..], ListType::Join(",")); diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index 35b5adb..f472b11 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -199,6 +199,9 @@ impl ArrayLength { pub enum Type { ConstPtr(Box), Ptr(Box), + Ref(Box), + #[allow(dead_code)] // MutRef is not currently used + MutRef(Box), Path(GenericPath), Primitive(PrimitiveType), Array(Box, ArrayLength), @@ -393,6 +396,8 @@ impl Type { match current { &Type::ConstPtr(ref ty) => current = ty, &Type::Ptr(ref ty) => current = ty, + &Type::Ref(ref ty) => current = ty, + &Type::MutRef(ref ty) => current = ty, &Type::Path(ref generic) => { return Some(generic.path().clone()); } @@ -413,6 +418,8 @@ impl Type { match self { &Type::ConstPtr(ref ty) => Type::ConstPtr(Box::new(ty.specialize(mappings))), &Type::Ptr(ref ty) => Type::Ptr(Box::new(ty.specialize(mappings))), + &Type::Ref(ref ty) => Type::Ref(Box::new(ty.specialize(mappings))), + &Type::MutRef(ref ty) => Type::MutRef(Box::new(ty.specialize(mappings))), &Type::Path(ref generic_path) => { for &(param, value) in mappings { if generic_path.path() == param { @@ -457,6 +464,9 @@ impl Type { &Type::Ptr(ref ty) => { ty.add_dependencies_ignoring_generics(generic_params, library, out); } + &Type::Ref(ref ty) | &Type::MutRef(ref ty) => { + ty.add_dependencies_ignoring_generics(generic_params, library, out); + } &Type::Path(ref generic) => { for generic_value in generic.generics() { generic_value.add_dependencies_ignoring_generics(generic_params, library, out); @@ -508,6 +518,9 @@ impl Type { &Type::Ptr(ref ty) => { ty.add_monomorphs(library, out); } + &Type::Ref(ref ty) | &Type::MutRef(ref ty) => { + ty.add_monomorphs(library, out); + } &Type::Path(ref generic) => { if generic.generics().len() == 0 || out.contains(&generic) { return; @@ -541,6 +554,9 @@ impl Type { &mut Type::Ptr(ref mut ty) => { ty.rename_for_config(config, generic_params); } + &mut Type::Ref(ref mut ty) | &mut Type::MutRef(ref mut ty) => { + ty.rename_for_config(config, generic_params); + } &mut Type::Path(ref mut ty) => { ty.rename_for_config(config, generic_params); } @@ -566,6 +582,9 @@ impl Type { &mut Type::Ptr(ref mut ty) => { ty.resolve_declaration_types(resolver); } + &mut Type::Ref(ref mut ty) | &mut Type::MutRef(ref mut ty) => { + ty.resolve_declaration_types(resolver); + } &mut Type::Path(ref mut generic_path) => { generic_path.resolve_declaration_types(resolver); } @@ -590,6 +609,9 @@ impl Type { &mut Type::Ptr(ref mut ty) => { ty.mangle_paths(monomorphs); } + &mut Type::Ref(ref mut ty) | &mut Type::MutRef(ref mut ty) => { + ty.mangle_paths(monomorphs); + } &mut Type::Path(ref mut generic_path) => { if generic_path.generics().len() == 0 { return; @@ -622,6 +644,7 @@ impl Type { match self { &Type::ConstPtr(..) => true, &Type::Ptr(..) => true, + &Type::Ref(..) | &Type::MutRef(..) => false, &Type::Path(..) => true, &Type::Primitive(ref p) => p.can_cmp_order(), &Type::Array(..) => false, @@ -633,6 +656,7 @@ impl Type { match self { &Type::ConstPtr(..) => true, &Type::Ptr(..) => true, + &Type::Ref(..) | &Type::MutRef(..) => false, &Type::Path(..) => true, &Type::Primitive(ref p) => p.can_cmp_eq(), &Type::Array(..) => false, diff --git a/src/bindgen/mangle.rs b/src/bindgen/mangle.rs index 5fdcfe2..a4ce4fd 100644 --- a/src/bindgen/mangle.rs +++ b/src/bindgen/mangle.rs @@ -43,9 +43,12 @@ fn internal_mangle_name(name: &str, generic_values: &[Type], last_in_parent: boo &Type::Primitive(ref primitive) => { mangled.push_str(primitive.to_repr_rust()); } - &Type::ConstPtr(..) | &Type::Ptr(..) | &Type::Array(..) | &Type::FuncPtr(..) => { - unimplemented!() - } + &Type::MutRef(..) + | &Type::Ref(..) + | &Type::ConstPtr(..) + | &Type::Ptr(..) + | &Type::Array(..) + | &Type::FuncPtr(..) => unimplemented!(), } // Skip writing the trailing '>' mangling when possible diff --git a/tests/expectations/annotation.cpp b/tests/expectations/annotation.cpp index adc07e4..09a8a9d 100644 --- a/tests/expectations/annotation.cpp +++ b/tests/expectations/annotation.cpp @@ -51,15 +51,15 @@ union F { Foo_Body foo; Bar_Body bar; - static F Foo(int16_t const& a0) { + static F Foo(const int16_t &a0) { F result; result.foo._0 = a0; result.tag = Tag::Foo; return result; } - static F Bar(uint8_t const& aX, - int16_t const& aY) { + static F Bar(const uint8_t &aX, + const int16_t &aY) { F result; result.bar.x = aX; result.bar.y = aY; @@ -108,15 +108,15 @@ struct H { There_Body there; }; - static H Hello(int16_t const& a0) { + static H Hello(const int16_t &a0) { H result; result.hello._0 = a0; result.tag = Tag::Hello; return result; } - static H There(uint8_t const& aX, - int16_t const& aY) { + static H There(const uint8_t &aX, + const int16_t &aY) { H result; result.there.x = aX; result.there.y = aY;