Skip to content

Commit 04fa978

Browse files
author
bors-servo
authored
Auto merge of #936 - jhod0:no_fieldgen_on_opaque, r=fitzgen
Avoid generating fields/methods for opaque objects WIP fix for issue #929 With libclang 4, passes all tests on my machine except `dump_preprocessed_input`, but that fails on the master branch as well
2 parents 05caa82 + 034200a commit 04fa978

File tree

1 file changed

+70
-67
lines changed

1 file changed

+70
-67
lines changed

src/codegen/mod.rs

Lines changed: 70 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,57 +1551,61 @@ impl CodeGenerator for CompInfo {
15511551
//
15521552
// Also, we need to generate the vtable in such a way it "inherits" from
15531553
// the parent too.
1554+
let is_opaque = item.is_opaque(ctx, &());
15541555
let mut fields = vec![];
15551556
let mut struct_layout =
15561557
StructLayoutTracker::new(ctx, self, &canonical_name);
1557-
if self.needs_explicit_vtable(ctx, item) {
1558-
let vtable =
1559-
Vtable::new(item.id(), self.methods(), self.base_members());
1560-
vtable.codegen(ctx, result, item);
15611558

1562-
let vtable_type = vtable
1563-
.try_to_rust_ty(ctx, &())
1564-
.expect("vtable to Rust type conversion is infallible")
1565-
.to_ptr(true, ctx.span());
1559+
if !is_opaque {
1560+
if self.needs_explicit_vtable(ctx, item) {
1561+
let vtable =
1562+
Vtable::new(item.id(), self.methods(), self.base_members());
1563+
vtable.codegen(ctx, result, item);
15661564

1567-
let vtable_field = StructFieldBuilder::named("vtable_")
1568-
.pub_()
1569-
.build_ty(vtable_type);
1565+
let vtable_type = vtable
1566+
.try_to_rust_ty(ctx, &())
1567+
.expect("vtable to Rust type conversion is infallible")
1568+
.to_ptr(true, ctx.span());
15701569

1571-
struct_layout.saw_vtable();
1570+
let vtable_field = StructFieldBuilder::named("vtable_")
1571+
.pub_()
1572+
.build_ty(vtable_type);
15721573

1573-
fields.push(vtable_field);
1574-
}
1574+
struct_layout.saw_vtable();
15751575

1576-
for (i, base) in self.base_members().iter().enumerate() {
1577-
// Virtual bases are already taken into account by the vtable
1578-
// pointer.
1579-
//
1580-
// FIXME(emilio): Is this always right?
1581-
if base.is_virtual() {
1582-
continue;
1576+
fields.push(vtable_field);
15831577
}
15841578

1585-
let base_ty = ctx.resolve_type(base.ty);
1586-
// NB: We won't include unsized types in our base chain because they
1587-
// would contribute to our size given the dummy field we insert for
1588-
// unsized types.
1589-
if base_ty.is_unsized(ctx, &base.ty) {
1590-
continue;
1591-
}
1579+
for (i, base) in self.base_members().iter().enumerate() {
1580+
// Virtual bases are already taken into account by the vtable
1581+
// pointer.
1582+
//
1583+
// FIXME(emilio): Is this always right?
1584+
if base.is_virtual() {
1585+
continue;
1586+
}
15921587

1593-
let inner = base.ty.to_rust_ty_or_opaque(ctx, &());
1594-
let field_name = if i == 0 {
1595-
"_base".into()
1596-
} else {
1597-
format!("_base_{}", i)
1598-
};
1588+
let base_ty = ctx.resolve_type(base.ty);
1589+
// NB: We won't include unsized types in our base chain because they
1590+
// would contribute to our size given the dummy field we insert for
1591+
// unsized types.
1592+
if base_ty.is_unsized(ctx, &base.ty) {
1593+
continue;
1594+
}
15991595

1600-
struct_layout.saw_base(base_ty);
1596+
let inner = base.ty.to_rust_ty_or_opaque(ctx, &());
1597+
let field_name = if i == 0 {
1598+
"_base".into()
1599+
} else {
1600+
format!("_base_{}", i)
1601+
};
1602+
1603+
struct_layout.saw_base(base_ty);
16011604

1602-
let field =
1603-
StructFieldBuilder::named(field_name).pub_().build_ty(inner);
1604-
fields.extend(Some(field));
1605+
let field =
1606+
StructFieldBuilder::named(field_name).pub_().build_ty(inner);
1607+
fields.extend(Some(field));
1608+
}
16051609
}
16061610
if is_union {
16071611
result.saw_union();
@@ -1610,34 +1614,34 @@ impl CodeGenerator for CompInfo {
16101614
}
16111615
}
16121616

1613-
let layout = item.kind().expect_type().layout(ctx);
1614-
1615-
let fields_should_be_private =
1616-
item.annotations().private_fields().unwrap_or(false);
1617-
let struct_accessor_kind = item.annotations()
1618-
.accessor_kind()
1619-
.unwrap_or(FieldAccessorKind::None);
1620-
16211617
let mut methods = vec![];
1622-
let mut anon_field_names = AnonFieldNames::default();
1623-
let codegen_depth = item.codegen_depth(ctx);
1624-
for field in self.fields() {
1625-
field.codegen(
1626-
ctx,
1627-
fields_should_be_private,
1628-
codegen_depth,
1629-
struct_accessor_kind,
1630-
self,
1631-
&mut anon_field_names,
1632-
result,
1633-
&mut struct_layout,
1634-
&mut fields,
1635-
&mut methods,
1636-
(),
1637-
);
1618+
if !is_opaque {
1619+
let mut anon_field_names = AnonFieldNames::default();
1620+
let codegen_depth = item.codegen_depth(ctx);
1621+
let fields_should_be_private =
1622+
item.annotations().private_fields().unwrap_or(false);
1623+
let struct_accessor_kind = item.annotations()
1624+
.accessor_kind()
1625+
.unwrap_or(FieldAccessorKind::None);
1626+
for field in self.fields() {
1627+
field.codegen(
1628+
ctx,
1629+
fields_should_be_private,
1630+
codegen_depth,
1631+
struct_accessor_kind,
1632+
self,
1633+
&mut anon_field_names,
1634+
result,
1635+
&mut struct_layout,
1636+
&mut fields,
1637+
&mut methods,
1638+
(),
1639+
);
1640+
}
16381641
}
16391642

1640-
if is_union {
1643+
let layout = item.kind().expect_type().layout(ctx);
1644+
if is_union && !is_opaque {
16411645
let layout = layout.expect("Unable to get layout information?");
16421646
let ty = helpers::blob(layout);
16431647

@@ -1654,11 +1658,10 @@ impl CodeGenerator for CompInfo {
16541658
fields.push(field);
16551659
}
16561660

1657-
// Yeah, sorry about that.
1658-
let is_opaque = item.is_opaque(ctx, &());
16591661
if is_opaque {
1660-
fields.clear();
1661-
methods.clear();
1662+
// Opaque item should not have generated methods, fields.
1663+
debug_assert!(fields.is_empty());
1664+
debug_assert!(methods.is_empty());
16621665

16631666
match layout {
16641667
Some(l) => {

0 commit comments

Comments
 (0)