Skip to content

Commit 4c2f588

Browse files
committed
Add support for 'unsafe fields'
1 parent 4f92390 commit 4c2f588

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

src/gen.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,26 @@ fn comp_attrs(ctx: &GenCtx, ci: &CompInfo, name: &str, extra: &mut Vec<P<ast::It
841841
attrs
842842
}
843843

844+
fn gen_unsafe_field_accessors(ctx: &mut GenCtx, name: &str, ty: &ast::Ty, methods: &mut Vec<ast::ImplItem>) {
845+
let ident = ctx.ext_cx.ident_of(&format!("{}", name));
846+
let mutable_getter_name = ctx.ext_cx.ident_of(&format!("get_{}_mut", name));
847+
let getter_name = ctx.ext_cx.ident_of(&format!("get_{}", name));
848+
let imp = quote_item!(&ctx.ext_cx,
849+
impl X {
850+
#[inline]
851+
pub unsafe fn $getter_name(&self) -> & $ty {
852+
& self.$ident
853+
}
854+
pub unsafe fn $mutable_getter_name(&mut self) -> &mut $ty {
855+
&mut self.$ident
856+
}
857+
}
858+
);
859+
match imp.unwrap().node {
860+
ast::ItemKind::Impl(_, _, _, _, _, ref items) => methods.extend(items.clone()),
861+
_ => unreachable!()
862+
}
863+
}
844864

845865
fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>> {
846866
let layout = ci.layout;
@@ -879,14 +899,15 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
879899
};
880900

881901
if let Some(ref base) = base_vftable {
882-
vffields.push(ast::StructField {
902+
let field = ast::StructField {
883903
span: ctx.span,
884904
vis: ast::Visibility::Public,
885905
ident: Some(ctx.ext_cx.ident_of("_base")),
886906
id: ast::DUMMY_NODE_ID,
887907
ty: P(mk_ty(ctx, false, &[base.clone()])),
888908
attrs: vec![],
889-
});
909+
};
910+
vffields.push(field);
890911
}
891912

892913
for vm in ci.vmethods.iter() {
@@ -1053,15 +1074,22 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
10531074
} else {
10541075
rust_ty
10551076
};
1056-
1057-
fields.push(ast::StructField {
1077+
let vis = if f.private {
1078+
gen_unsafe_field_accessors(ctx, &f_name, &rust_ty, &mut methods);
1079+
ast::Visibility::Inherited
1080+
} else {
1081+
ast::Visibility::Public
1082+
};
1083+
let field = ast::StructField {
10581084
span: ctx.span,
10591085
ident: Some(ctx.ext_cx.ident_of(&f_name)),
1060-
vis: ast::Visibility::Public,
1086+
vis: vis,
10611087
id: ast::DUMMY_NODE_ID,
10621088
ty: rust_ty,
10631089
attrs: mk_doc_attr(ctx, &f.comment)
1064-
});
1090+
};
1091+
fields.push(field);
1092+
10651093
if bypass {
10661094
continue;
10671095
}

src/parser.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ struct Annotations {
544544
use_as: Option<String>,
545545
/// Disable deriving copy/clone on this struct.
546546
no_copy: bool,
547+
private: bool,
547548
}
548549

549550
impl Annotations {
@@ -553,6 +554,7 @@ impl Annotations {
553554
hide: false,
554555
use_as: None,
555556
no_copy: false,
557+
private: false,
556558
};
557559

558560
anno.parse(&cursor.comment());
@@ -571,6 +573,7 @@ impl Annotations {
571573
"hide" => self.hide = true,
572574
"replaces" => self.use_as = Some(comment.get_tag_attr_value(i)),
573575
"nocopy" => self.no_copy = true,
576+
"private" => self.private = true,
574577
_ => (),
575578
}
576579
}
@@ -791,13 +794,13 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
791794
};
792795

793796
if should_replace {
794-
*info = FieldInfo::new(name, ty, comment, bitfields, mutable);
797+
*info = FieldInfo::new(name, ty, comment, bitfields, mutable, anno.private);
795798
return CXChildVisit_Continue;
796799
}
797800
}
798801
}
799802

800-
let field = FieldInfo::new(name, ty, comment, bitfields, mutable);
803+
let field = FieldInfo::new(name, ty, comment, bitfields, mutable, anno.private);
801804
ci.members.push(CompMember::Field(field));
802805
}
803806
CXCursor_StructDecl |
@@ -837,7 +840,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
837840
// Anonymous structs are legal in both C++ and C11
838841
if ci2.borrow().was_unnamed {
839842
let ci2b = ci2.borrow();
840-
let field = FieldInfo::new(ci2b.name.clone(), TComp(ci2.clone()), ci2b.comment.clone(), None, false);
843+
let field = FieldInfo::new(ci2b.name.clone(), TComp(ci2.clone()), ci2b.comment.clone(), None, false, false);
841844
ci.members.push(CompMember::Field(field));
842845
}
843846
});
@@ -893,7 +896,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
893896
ci.typedefs.extend(info.borrow().typedefs.clone().into_iter());
894897
}
895898

896-
let field = FieldInfo::new(fieldname, ty, "".to_owned(), None, false);
899+
let field = FieldInfo::new(fieldname, ty, "".to_owned(), None, false, false);
897900
if !found_virtual_base && cursor.is_virtual_base() {
898901
ci.members.insert(0, CompMember::Field(field));
899902
ci.has_vtable = true;

src/types.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,20 +624,23 @@ pub struct FieldInfo {
624624
pub bitfields: Option<Vec<(String, u32)>>,
625625
/// If the C++ field is marked as `mutable`
626626
pub mutable: bool,
627+
pub private: bool,
627628
}
628629

629630
impl FieldInfo {
630631
pub fn new(name: String,
631632
ty: Type,
632633
comment: String,
633634
bitfields: Option<Vec<(String, u32)>>,
634-
mutable: bool) -> FieldInfo {
635+
mutable: bool,
636+
private: bool) -> FieldInfo {
635637
FieldInfo {
636638
name: name,
637639
ty: ty,
638640
comment: comment,
639641
bitfields: bitfields,
640642
mutable: mutable,
643+
private: private,
641644
}
642645
}
643646
}

0 commit comments

Comments
 (0)