Skip to content

Commit 986906e

Browse files
authored
transpile: Move some stuff into struct module (#1516)
Moving some things into the `struct` module that were previously in the `translator` and `literals` modules. Helps to keep things organised hopefully.
2 parents cf8667b + 36d7905 commit 986906e

File tree

3 files changed

+447
-432
lines changed

3 files changed

+447
-432
lines changed

c2rust-transpile/src/translator/literals.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -290,21 +290,7 @@ impl<'c> Translation<'c> {
290290
}
291291
}
292292
CTypeKind::Struct(struct_id) => {
293-
let mut literal = self.convert_struct_literal(ctx, struct_id, ids.as_ref());
294-
if self.ast_context.has_inner_struct_decl(struct_id) {
295-
// If the structure is split into an outer/inner,
296-
// wrap the inner initializer using the outer structure
297-
let outer_name = self
298-
.type_converter
299-
.borrow()
300-
.resolve_decl_name(struct_id)
301-
.unwrap();
302-
303-
let outer_path = mk().path_expr(vec![outer_name]);
304-
literal = literal
305-
.map(|lit_ws| lit_ws.map(|lit| mk().call_expr(outer_path, vec![lit])));
306-
};
307-
literal
293+
self.convert_struct_literal(ctx, struct_id, ids.as_ref())
308294
}
309295
CTypeKind::Union(union_id) => {
310296
self.convert_union_literal(ctx, union_id, ids.as_ref(), ty, opt_union_field_id)

c2rust-transpile/src/translator/mod.rs

Lines changed: 16 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)