diff options
Diffstat (limited to 'src/ir/comp.rs')
-rw-r--r-- | src/ir/comp.rs | 259 |
1 files changed, 139 insertions, 120 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 5e0b3ed6..a82fd756 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -52,13 +52,13 @@ pub enum MethodKind { }, } - impl MethodKind { /// Is this a destructor method? pub fn is_destructor(&self) -> bool { match *self { - MethodKind::Destructor | - MethodKind::VirtualDestructor { .. } => true, + MethodKind::Destructor | MethodKind::VirtualDestructor { .. } => { + true + } _ => false, } } @@ -87,7 +87,11 @@ pub struct Method { impl Method { /// Construct a new `Method`. - pub fn new(kind: MethodKind, signature: FunctionId, is_const: bool) -> Self { + pub fn new( + kind: MethodKind, + signature: FunctionId, + is_const: bool, + ) -> Self { Method { kind, signature, @@ -198,9 +202,7 @@ impl Field { /// Get this field's layout. pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> { match *self { - Field::Bitfields(BitfieldUnit { - layout, .. - }) => Some(layout), + Field::Bitfields(BitfieldUnit { layout, .. }) => Some(layout), Field::DataMember(ref data) => { ctx.resolve_type(data.ty).layout(ctx) } @@ -219,9 +221,7 @@ impl Trace for Field { Field::DataMember(ref data) => { tracer.visit_kind(data.ty.into(), EdgeKind::Field); } - Field::Bitfields(BitfieldUnit { - ref bitfields, .. - }) => { + Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => { for bf in bitfields { tracer.visit_kind(bf.ty().into(), EdgeKind::Field); } @@ -242,10 +242,10 @@ impl DotAttributes for Field { match *self { Field::DataMember(ref data) => data.dot_attributes(ctx, out), Field::Bitfields(BitfieldUnit { - layout, - ref bitfields, - .. - }) => { + layout, + ref bitfields, + .. + }) => { writeln!( out, r#"<tr> @@ -259,8 +259,7 @@ impl DotAttributes for Field { <td>unit.align</td><td>{}</td> </tr> "#, - layout.size, - layout.align + layout.size, layout.align )?; for bf in bitfields { bf.dot_attributes(ctx, out)?; @@ -373,7 +372,10 @@ impl Bitfield { /// Panics if called before assigning bitfield accessor names or if /// this bitfield have no name. pub fn getter_name(&self) -> &str { - assert!(self.name().is_some(), "`Bitfield::getter_name` called on anonymous field"); + assert!( + self.name().is_some(), + "`Bitfield::getter_name` called on anonymous field" + ); self.getter_name.as_ref().expect( "`Bitfield::getter_name` should only be called after\ assigning bitfield accessor names", @@ -385,7 +387,10 @@ impl Bitfield { /// Panics if called before assigning bitfield accessor names or if /// this bitfield have no name. pub fn setter_name(&self) -> &str { - assert!(self.name().is_some(), "`Bitfield::setter_name` called on anonymous field"); + assert!( + self.name().is_some(), + "`Bitfield::setter_name` called on anonymous field" + ); self.setter_name.as_ref().expect( "`Bitfield::setter_name` should only be called\ after assigning bitfield accessor names", @@ -423,7 +428,6 @@ impl FieldMethods for Bitfield { } } - /// A raw field might be either of a plain data member or a bitfield within a /// bitfield allocation unit, but we haven't processed it and determined which /// yet (which would involve allocating it into a bitfield unit if it is a @@ -597,9 +601,8 @@ where for bitfield in raw_bitfields { let bitfield_width = bitfield.bitfield_width().unwrap() as usize; - let bitfield_layout = ctx.resolve_type(bitfield.ty()) - .layout(ctx) - .ok_or(())?; + let bitfield_layout = + ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?; let bitfield_size = bitfield_layout.size; let bitfield_align = bitfield_layout.align; @@ -628,8 +631,8 @@ where } else { if offset != 0 && (bitfield_width == 0 || - (offset & (bitfield_align * 8 - 1)) + bitfield_width > - bitfield_size * 8) + (offset & (bitfield_align * 8 - 1)) + bitfield_width > + bitfield_size * 8) { offset = align_to(offset, bitfield_align * 8); } @@ -724,20 +727,17 @@ impl CompFields { } }; - let result = - raw_fields_to_fields_and_bitfield_units(ctx, raws); + let result = raw_fields_to_fields_and_bitfield_units(ctx, raws); match result { Ok(fields_and_units) => { mem::replace( self, - CompFields::AfterComputingBitfieldUnits(fields_and_units)); + CompFields::AfterComputingBitfieldUnits(fields_and_units), + ); } Err(()) => { - mem::replace( - self, - CompFields::ErrorComputingBitfieldUnits - ); + mem::replace(self, CompFields::ErrorComputingBitfieldUnits); } } } @@ -754,7 +754,11 @@ impl CompFields { } }; - fn has_method(methods: &[Method], ctx: &BindgenContext, name: &str) -> bool { + fn has_method( + methods: &[Method], + ctx: &BindgenContext, + name: &str, + ) -> bool { methods.iter().any(|method| { let method_name = ctx.resolve_func(method.signature()).name(); method_name == name || ctx.rust_mangle(&method_name) == name @@ -776,7 +780,8 @@ impl CompFields { .map(|bitfield_name| { let bitfield_name = bitfield_name.to_string(); let getter = { - let mut getter = ctx.rust_mangle(&bitfield_name).to_string(); + let mut getter = + ctx.rust_mangle(&bitfield_name).to_string(); if has_method(methods, ctx, &getter) { getter.push_str("_bindgen_bitfield"); } @@ -803,21 +808,24 @@ impl CompFields { } anon_field_counter += 1; - let generated_name = format!("__bindgen_anon_{}", anon_field_counter); + let generated_name = + format!("__bindgen_anon_{}", anon_field_counter); *name = Some(generated_name); } - Field::Bitfields(ref mut bu) => for bitfield in &mut bu.bitfields { - if bitfield.name().is_none() { - continue; - } + Field::Bitfields(ref mut bu) => { + for bitfield in &mut bu.bitfields { + if bitfield.name().is_none() { + continue; + } - if let Some(AccessorNamesPair { getter, setter }) = - accessor_names.remove(bitfield.name().unwrap()) - { - bitfield.getter_name = Some(getter); - bitfield.setter_name = Some(setter); + if let Some(AccessorNamesPair { getter, setter }) = + accessor_names.remove(bitfield.name().unwrap()) + { + bitfield.getter_name = Some(getter); + bitfield.setter_name = Some(setter); + } } - }, + } } } } @@ -1185,8 +1193,7 @@ impl CompInfo { let mut ci = CompInfo::new(kind); ci.is_forward_declaration = location.map_or(true, |cur| match cur.kind() { - CXCursor_StructDecl | - CXCursor_UnionDecl | + CXCursor_StructDecl | CXCursor_UnionDecl | CXCursor_ClassDecl => !cur.is_definition(), _ => false, }); @@ -1195,16 +1202,20 @@ impl CompInfo { cursor.visit(|cur| { if cur.kind() != CXCursor_FieldDecl { if let Some((ty, clang_ty, offset)) = - maybe_anonymous_struct_field.take() { + maybe_anonymous_struct_field.take() + { if cur.kind() == CXCursor_TypedefDecl && - cur.typedef_type().unwrap().canonical_type() == clang_ty { + cur.typedef_type().unwrap().canonical_type() == + clang_ty + { // Typedefs of anonymous structs appear later in the ast // than the struct itself, that would otherwise be an // anonymous field. Detect that case here, and do // nothing. } else { - let field = - RawField::new(None, ty, None, None, None, false, offset); + let field = RawField::new( + None, ty, None, None, None, false, offset, + ); ci.fields.append_raw_field(field); } } @@ -1213,7 +1224,8 @@ impl CompInfo { match cur.kind() { CXCursor_FieldDecl => { if let Some((ty, clang_ty, offset)) = - maybe_anonymous_struct_field.take() { + maybe_anonymous_struct_field.take() + { let mut used = false; cur.visit(|child| { if child.cur_type() == clang_ty { @@ -1222,22 +1234,20 @@ impl CompInfo { CXChildVisit_Continue }); if !used { - let field = RawField::new(None, - ty, - None, - None, - None, - false, - offset); + let field = RawField::new( + None, ty, None, None, None, false, offset, + ); ci.fields.append_raw_field(field); } } let bit_width = cur.bit_width(); - let field_type = Item::from_ty_or_ref(cur.cur_type(), - cur, - Some(potential_id), - ctx); + let field_type = Item::from_ty_or_ref( + cur.cur_type(), + cur, + Some(potential_id), + ctx, + ); let comment = cur.raw_comment(); let annotations = Annotations::new(&cur); @@ -1247,18 +1257,22 @@ impl CompInfo { // Name can be empty if there are bitfields, for example, // see tests/headers/struct_with_bitfields.h - assert!(!name.is_empty() || bit_width.is_some(), - "Empty field name?"); + assert!( + !name.is_empty() || bit_width.is_some(), + "Empty field name?" + ); let name = if name.is_empty() { None } else { Some(name) }; - let field = RawField::new(name, - field_type, - comment, - annotations, - bit_width, - is_mutable, - offset); + let field = RawField::new( + name, + field_type, + comment, + annotations, + bit_width, + is_mutable, + offset, + ); ci.fields.append_raw_field(field); // No we look for things like attributes and stuff. @@ -1268,7 +1282,6 @@ impl CompInfo { } CXChildVisit_Continue }); - } CXCursor_UnexposedAttr => { ci.found_unknown_attr = true; @@ -1293,8 +1306,8 @@ impl CompInfo { // definition, it's a valid inner type. // // [1]: https://github.com/rust-lang/rust-bindgen/issues/482 - let is_inner_struct = cur.semantic_parent() == cursor || - cur.is_definition(); + let is_inner_struct = + cur.semantic_parent() == cursor || cur.is_definition(); if !is_inner_struct { return CXChildVisit_Continue; } @@ -1311,19 +1324,22 @@ impl CompInfo { // A declaration of an union or a struct without name could // also be an unnamed field, unfortunately. if cur.spelling().is_empty() && - cur.kind() != CXCursor_EnumDecl { + cur.kind() != CXCursor_EnumDecl + { let ty = cur.cur_type(); let offset = cur.offset_of_field().ok(); - maybe_anonymous_struct_field = Some((inner, ty, offset)); + maybe_anonymous_struct_field = + Some((inner, ty, offset)); } } CXCursor_PackedAttr => { ci.packed_attr = true; } CXCursor_TemplateTypeParameter => { - let param = Item::type_param(None, cur, ctx) - .expect("Item::type_param should't fail when pointing \ - at a TemplateTypeParameter"); + let param = Item::type_param(None, cur, ctx).expect( + "Item::type_param should't fail when pointing \ + at a TemplateTypeParameter", + ); ci.template_params.push(param); } CXCursor_CXXBaseSpecifier => { @@ -1348,8 +1364,7 @@ impl CompInfo { field_name: field_name, }); } - CXCursor_Constructor | - CXCursor_Destructor | + CXCursor_Constructor | CXCursor_Destructor | CXCursor_CXXMethod => { let is_virtual = cur.method_is_virtual(); let is_static = cur.method_is_static(); @@ -1376,9 +1391,14 @@ impl CompInfo { // `FunctionSig`. let signature = match Item::parse(cur, Some(potential_id), ctx) { - Ok(item) if ctx.resolve_item(item) - .kind() - .is_function() => item, + Ok(item) + if ctx + .resolve_item(item) + .kind() + .is_function() => + { + item + } _ => return CXChildVisit_Continue, }; @@ -1424,7 +1444,8 @@ impl CompInfo { CXCursor_VarDecl => { let linkage = cur.linkage(); if linkage != CXLinkage_External && - linkage != CXLinkage_UniqueExternal { + linkage != CXLinkage_UniqueExternal + { return CXChildVisit_Continue; } @@ -1433,9 +1454,8 @@ impl CompInfo { return CXChildVisit_Continue; } - if let Ok(item) = Item::parse(cur, - Some(potential_id), - ctx) { + if let Ok(item) = Item::parse(cur, Some(potential_id), ctx) + { ci.inner_vars.push(item.as_var_id_unchecked()); } } @@ -1445,11 +1465,13 @@ impl CompInfo { CXCursor_FunctionTemplate | CXCursor_ConversionFunction => {} _ => { - warn!("unhandled comp member `{}` (kind {:?}) in `{}` ({})", - cur.spelling(), - clang::kind_to_str(cur.kind()), - cursor.spelling(), - cur.location()); + warn!( + "unhandled comp member `{}` (kind {:?}) in `{}` ({})", + cur.spelling(), + clang::kind_to_str(cur.kind()), + cursor.spelling(), + cur.location() + ); } } CXChildVisit_Continue @@ -1470,16 +1492,13 @@ impl CompInfo { use clang_sys::*; Ok(match cursor.kind() { CXCursor_UnionDecl => CompKind::Union, - CXCursor_ClassDecl | - CXCursor_StructDecl => CompKind::Struct, + CXCursor_ClassDecl | CXCursor_StructDecl => CompKind::Struct, CXCursor_CXXBaseSpecifier | CXCursor_ClassTemplatePartialSpecialization | - CXCursor_ClassTemplate => { - match cursor.template_kind() { - CXCursor_UnionDecl => CompKind::Union, - _ => CompKind::Struct, - } - } + CXCursor_ClassTemplate => match cursor.template_kind() { + CXCursor_UnionDecl => CompKind::Union, + _ => CompKind::Struct, + }, _ => { warn!("Unknown kind for comp type: {:?}", cursor); return Err(ParseError::Continue); @@ -1505,9 +1524,13 @@ impl CompInfo { } /// Is this compound type packed? - pub fn is_packed(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool { + pub fn is_packed( + &self, + ctx: &BindgenContext, + layout: &Option<Layout>, + ) -> bool { if self.packed_attr { - return true + return true; } // Even though `libclang` doesn't expose `#pragma packed(...)`, we can @@ -1632,7 +1655,7 @@ impl IsOpaque for CompInfo { fn is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool { if self.has_non_type_template_params { - return true + return true; } // When we do not have the layout for a bitfield's type (for example, it @@ -1647,17 +1670,14 @@ impl IsOpaque for CompInfo { // some strange things going on, and the best we can do is make the // whole struct opaque. if self.fields().iter().any(|f| match *f { - Field::DataMember(_) => { - false - }, - Field::Bitfields(ref unit) => { - unit.bitfields().iter().any(|bf| { - let bitfield_layout = ctx.resolve_type(bf.ty()) - .layout(ctx) - .expect("Bitfield without layout? Gah!"); - bf.width() / 8 > bitfield_layout.size as u32 - }) - } + Field::DataMember(_) => false, + Field::Bitfields(ref unit) => unit.bitfields().iter().any(|bf| { + let bitfield_layout = ctx + .resolve_type(bf.ty()) + .layout(ctx) + .expect("Bitfield without layout? Gah!"); + bf.width() / 8 > bitfield_layout.size as u32 + }), }) { return true; } @@ -1668,7 +1688,9 @@ impl IsOpaque for CompInfo { // // See https://github.com/rust-lang/rust-bindgen/issues/537 and // https://github.com/rust-lang/rust/issues/33158 - if self.is_packed(ctx, layout) && layout.map_or(false, |l| l.align > 1) { + if self.is_packed(ctx, layout) && + layout.map_or(false, |l| l.align > 1) + { warn!("Found a type that is both packed and aligned to greater than \ 1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \ are treating it as opaque. You may wish to set bindgen's rust target \ @@ -1682,10 +1704,7 @@ impl IsOpaque for CompInfo { } impl TemplateParameters for CompInfo { - fn self_template_params( - &self, - _ctx: &BindgenContext, - ) -> Vec<TypeId> { + fn self_template_params(&self, _ctx: &BindgenContext) -> Vec<TypeId> { self.template_params.clone() } } |