Skip to content

Commit c88a37b

Browse files
committed
Checkpoint to show a rust ICE.
1 parent 341ccee commit c88a37b

File tree

1 file changed

+71
-15
lines changed

1 file changed

+71
-15
lines changed

src/codegen/mod.rs

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ir::item_kind::ItemKind;
99
use ir::comp::{CompKind, CompInfo, Method};
1010
use ir::layout::Layout;
1111

12+
use std::ops;
1213
use std::collections::hash_map::{HashMap, Entry};
1314

1415
use syntax::abi::Abi;
@@ -44,6 +45,38 @@ macro_rules! link_name {
4445
}}
4546
}
4647

48+
struct CodegenResult {
49+
items: Vec<P<ast::Item>>,
50+
saw_union: bool,
51+
}
52+
53+
impl CodegenResult {
54+
fn new() -> Self {
55+
CodegenResult {
56+
items: vec![],
57+
saw_union: false,
58+
}
59+
}
60+
61+
fn saw_union(&mut self) {
62+
self.saw_union = true;
63+
}
64+
}
65+
66+
impl ops::Deref for CodegenResult {
67+
type Target = Vec<P<ast::Item>>;
68+
69+
fn deref(&self) -> &Self::Target {
70+
&self.items
71+
}
72+
}
73+
74+
impl ops::DerefMut for CodegenResult {
75+
fn deref_mut(&mut self) -> &mut Self::Target {
76+
&mut self.items
77+
}
78+
}
79+
4780
struct ForeignModBuilder {
4881
inner: ast::ForeignMod,
4982
}
@@ -242,7 +275,7 @@ trait CodeGenerator {
242275

243276
fn codegen(&self,
244277
ctx: &BindgenContext,
245-
result: &mut Vec<P<ast::Item>>,
278+
result: &mut CodegenResult,
246279
extra: &Self::Extra);
247280
}
248281

@@ -251,7 +284,7 @@ impl CodeGenerator for Item {
251284

252285
fn codegen(&self,
253286
ctx: &BindgenContext,
254-
result: &mut Vec<P<ast::Item>>,
287+
result: &mut CodegenResult,
255288
_extra: &()) {
256289
match *self.kind() {
257290
ItemKind::Module(..) => { /* TODO */ },
@@ -272,7 +305,7 @@ impl CodeGenerator for Var {
272305
type Extra = Item;
273306
fn codegen(&self,
274307
ctx: &BindgenContext,
275-
result: &mut Vec<P<ast::Item>>,
308+
result: &mut CodegenResult,
276309
item: &Item) {
277310
let name = item.canonical_name(ctx);
278311
let ty = self.ty().to_rust_ty(ctx);
@@ -312,7 +345,7 @@ impl CodeGenerator for Type {
312345

313346
fn codegen(&self,
314347
ctx: &BindgenContext,
315-
result: &mut Vec<P<ast::Item>>,
348+
result: &mut CodegenResult,
316349
item: &Item) {
317350
match *self.kind() {
318351
TypeKind::Void |
@@ -382,7 +415,7 @@ impl<'a> CodeGenerator for Vtable<'a> {
382415

383416
fn codegen(&self,
384417
ctx: &BindgenContext,
385-
result: &mut Vec<P<ast::Item>>,
418+
result: &mut CodegenResult,
386419
item: &Item) {
387420
assert_eq!(item.id(), self.item_id);
388421
// For now, generate an empty struct, later we should generate function
@@ -406,7 +439,7 @@ impl CodeGenerator for CompInfo {
406439

407440
fn codegen(&self,
408441
ctx: &BindgenContext,
409-
result: &mut Vec<P<ast::Item>>,
442+
result: &mut CodegenResult,
410443
item: &Item) {
411444
use aster::struct_field::StructFieldBuilder;
412445
// Don't output classes with template parameters that aren't types, and
@@ -460,6 +493,11 @@ impl CodeGenerator for CompInfo {
460493
fields.push(field);
461494
}
462495

496+
let is_union = self.kind() == CompKind::Union;
497+
if is_union {
498+
result.saw_union();
499+
}
500+
463501
for field in self.fields() {
464502
if let Some(_width) = field.bitfield() {
465503
// TODO: Compute bitfields.
@@ -473,15 +511,33 @@ impl CodeGenerator for CompInfo {
473511
}
474512
}
475513

476-
let ty = field.ty().to_rust_ty(ctx);
477-
let mut attrs = vec![];
478-
if let Some(comment) = field.comment() {
479-
attrs.push(doc!(comment));
514+
if !is_union {
515+
let ty = field.ty().to_rust_ty(ctx);
516+
517+
let ty = if is_union {
518+
quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
519+
} else {
520+
ty
521+
};
522+
523+
let mut attrs = vec![];
524+
if let Some(comment) = field.comment() {
525+
attrs.push(doc!(comment));
526+
}
527+
528+
let field = StructFieldBuilder::named(field.name()).pub_()
529+
.with_attrs(attrs)
530+
.build_ty(ty);
531+
fields.push(field);
480532
}
533+
}
481534

482-
let field = StructFieldBuilder::named(field.name()).pub_()
483-
.with_attrs(attrs)
484-
.build_ty(ty);
535+
if is_union {
536+
let layout = item.kind().expect_type().layout(ctx)
537+
.expect("Unable to get layout information?");
538+
let ty = BlobTyBuilder::new(layout).build();
539+
let field = StructFieldBuilder::named("bindgen_union_field").pub_()
540+
.build_ty(ty);
485541
fields.push(field);
486542
}
487543

@@ -536,7 +592,7 @@ impl CodeGenerator for Enum {
536592

537593
fn codegen(&self,
538594
ctx: &BindgenContext,
539-
result: &mut Vec<P<ast::Item>>,
595+
result: &mut CodegenResult,
540596
item: &Item) {
541597
use ir::enum_ty::EnumVariantValue;
542598

@@ -831,7 +887,7 @@ impl CodeGenerator for Function {
831887

832888
fn codegen(&self,
833889
ctx: &BindgenContext,
834-
result: &mut Vec<P<ast::Item>>,
890+
result: &mut CodegenResult,
835891
item: &Item) {
836892
let signature_item = ctx.resolve_item(self.signature());
837893
let signature = signature_item.kind().expect_type();

0 commit comments

Comments
 (0)