@@ -1723,147 +1723,15 @@ impl<'c> Translation<'c> {
17231723 max_field_alignment,
17241724 platform_byte_size,
17251725 ..
1726- } => {
1727- let name = self
1728- . type_converter
1729- . borrow ( )
1730- . resolve_decl_name ( decl_id)
1731- . unwrap ( ) ;
1732-
1733- // Check if the last field might be a flexible array member
1734- if let Some ( last_id) = fields. last ( ) {
1735- let field_decl = & self . ast_context [ * last_id] ;
1736- if let CDeclKind :: Field { typ, .. } = field_decl. kind {
1737- if self . ast_context . maybe_flexible_array ( typ. ctype ) {
1738- self . potential_flexible_array_members
1739- . borrow_mut ( )
1740- . insert ( * last_id) ;
1741- }
1742- }
1743- }
1744-
1745- // Pre-declare all the field names, checking for duplicates
1746- for & x in fields {
1747- if let CDeclKind :: Field { ref name, .. } = self . ast_context . index ( x) . kind {
1748- self . type_converter
1749- . borrow_mut ( )
1750- . declare_field_name ( decl_id, x, name) ;
1751- }
1752- }
1753-
1754- // Gather up all the field names and field types
1755- let ( field_entries, contains_va_list) =
1756- self . convert_struct_fields ( decl_id, fields, platform_byte_size) ?;
1757-
1758- let mut derives = vec ! [ ] ;
1759- if !contains_va_list {
1760- derives. push ( "Copy" ) ;
1761- derives. push ( "Clone" ) ;
1762- } ;
1763- let has_bitfields =
1764- fields
1765- . iter ( )
1766- . any ( |field_id| match self . ast_context . index ( * field_id) . kind {
1767- CDeclKind :: Field { bitfield_width, .. } => bitfield_width. is_some ( ) ,
1768- _ => unreachable ! ( "Found non-field in record field list" ) ,
1769- } ) ;
1770- if has_bitfields {
1771- derives. push ( "BitfieldStruct" ) ;
1772- self . use_crate ( ExternCrate :: C2RustBitfields ) ;
1773- }
1774-
1775- let mut reprs = vec ! [ mk( ) . meta_path( "C" ) ] ;
1776- let max_field_alignment = if is_packed {
1777- // `__attribute__((packed))` forces a max alignment of 1,
1778- // overriding `#pragma pack`; this is also what clang does
1779- Some ( 1 )
1780- } else {
1781- max_field_alignment
1782- } ;
1783- match max_field_alignment {
1784- Some ( 1 ) => reprs. push ( mk ( ) . meta_path ( "packed" ) ) ,
1785- Some ( mf) if mf > 1 => reprs. push ( mk ( ) . meta_list ( "packed" , vec ! [ mf] ) ) ,
1786- _ => { }
1787- }
1788-
1789- if let Some ( alignment) = manual_alignment {
1790- // This is the most complicated case: we have `align(N)` which
1791- // might be mixed with or included into a `packed` structure,
1792- // which Rust doesn't currently support; instead, we split
1793- // the structure into 2 structures like this:
1794- // #[align(N)]
1795- // pub struct Foo(pub Foo_Inner);
1796- // #[packed(M)]
1797- // pub struct Foo_Inner {
1798- // ...fields...
1799- // }
1800- //
1801- // TODO: right now, we always emit the pair of structures
1802- // instead, we should only split when needed, but that
1803- // would significantly complicate the implementation
1804- assert ! ( self . ast_context. has_inner_struct_decl( decl_id) ) ;
1805- let inner_name = self . resolve_decl_inner_name ( decl_id) ;
1806- let inner_ty = mk ( ) . path_ty ( vec ! [ inner_name. clone( ) ] ) ;
1807- let inner_struct = mk ( )
1808- . span ( span)
1809- . pub_ ( )
1810- . call_attr ( "derive" , derives)
1811- . call_attr ( "repr" , reprs)
1812- . struct_item ( inner_name. clone ( ) , field_entries, false ) ;
1813-
1814- let outer_ty = mk ( ) . path_ty ( vec ! [ name. clone( ) ] ) ;
1815- let outer_field = mk ( ) . pub_ ( ) . enum_field ( mk ( ) . ident_ty ( inner_name) ) ;
1816- let outer_struct = mk ( )
1817- . span ( span)
1818- . pub_ ( )
1819- . call_attr ( "derive" , vec ! [ "Copy" , "Clone" ] )
1820- . call_attr (
1821- "repr" ,
1822- vec ! [
1823- mk( ) . meta_path( "C" ) ,
1824- mk( ) . meta_list( "align" , vec![ alignment] ) ,
1825- // TODO: copy others from `reprs` above
1826- ] ,
1827- )
1828- . struct_item ( name, vec ! [ outer_field] , true ) ;
1829-
1830- // Emit `const X_PADDING: usize = size_of(Outer) - size_of(Inner);`
1831- let padding_name = self
1832- . type_converter
1833- . borrow_mut ( )
1834- . resolve_decl_suffix_name ( decl_id, PADDING_SUFFIX )
1835- . to_owned ( ) ;
1836- let padding_ty = mk ( ) . path_ty ( vec ! [ "usize" ] ) ;
1837- let outer_size = self . mk_size_of_ty_expr ( outer_ty) ?. to_expr ( ) ;
1838- let inner_size = self . mk_size_of_ty_expr ( inner_ty) ?. to_expr ( ) ;
1839- let padding_value =
1840- mk ( ) . binary_expr ( BinOp :: Sub ( Default :: default ( ) ) , outer_size, inner_size) ;
1841- let padding_const = mk ( )
1842- . span ( span)
1843- . call_attr ( "allow" , vec ! [ "dead_code" , "non_upper_case_globals" ] )
1844- . const_item ( padding_name, padding_ty, padding_value) ;
1845-
1846- let structs = vec ! [ outer_struct, inner_struct, padding_const] ;
1847- Ok ( ConvertedDecl :: Items ( structs) )
1848- } else {
1849- assert ! ( !self . ast_context. has_inner_struct_decl( decl_id) ) ;
1850- let mut mk_ = mk ( )
1851- . span ( span)
1852- . pub_ ( )
1853- . call_attr ( "derive" , derives)
1854- . call_attr ( "repr" , reprs) ;
1855-
1856- if contains_va_list {
1857- mk_ = mk_. generic_over ( mk ( ) . lt_param ( mk ( ) . ident ( "a" ) ) )
1858- }
1859-
1860- Ok ( ConvertedDecl :: Item ( mk_. struct_item (
1861- name,
1862- field_entries,
1863- false ,
1864- ) ) )
1865- }
1866- }
1726+ } => self . convert_struct (
1727+ decl_id,
1728+ span,
1729+ fields,
1730+ is_packed,
1731+ platform_byte_size,
1732+ manual_alignment,
1733+ max_field_alignment,
1734+ ) ,
18671735
18681736 Union {
18691737 fields : Some ( ref fields) ,
@@ -4895,16 +4763,13 @@ impl<'c> Translation<'c> {
48954763 fields : Some ( ref fields) ,
48964764 platform_byte_size,
48974765 ..
4898- } => {
4899- let name = self . resolve_decl_inner_name ( name_decl_id) ;
4900- self . convert_struct_zero_initializer (
4901- name,
4902- decl_id,
4903- fields,
4904- platform_byte_size,
4905- is_static,
4906- ) ?
4907- }
4766+ } => self . convert_struct_zero_initializer (
4767+ decl_id,
4768+ name_decl_id,
4769+ fields,
4770+ platform_byte_size,
4771+ is_static,
4772+ ) ?,
49084773
49094774 CDeclKind :: Struct { fields : None , .. } => {
49104775 return Err ( TranslationError :: generic (
0 commit comments