fn gen_comp_methods(ctx: &mut GenCtx, data_field: &str, data_offset: usize,
                    kind: CompKind, members: &[CompMember],
                    extra: &mut Vec<P<ast::Item>>,
                    derive_debug: bool) -> Vec<ast::ImplItem> {

    let mk_field_method = |ctx: &mut GenCtx, f: &FieldInfo, offset: usize| {
        // TODO: Implement bitfield accessors
        if f.bitfields.is_some() { return None; }

        let (f_name, _) = rust_id(ctx, f.name.clone());
        let ret_ty = P(cty_to_rs(ctx, &TPtr(Box::new(f.ty.clone()), false, Layout::zero())));

        // When the offset is zero, generate slightly prettier code.
        let method = {
            let impl_str = format!(r"
                impl X {{
                    pub unsafe fn {}(&mut self) -> {} {{
                        let raw: *mut u8 = ::std::mem::transmute(&self.{});
                        ::std::mem::transmute(raw.offset({}))
                    }}
                }}
            ", f_name, tts_to_string(&ret_ty.to_tokens(&ctx.ext_cx)[..]), data_field, offset);

            parse::new_parser_from_source_str(ctx.ext_cx.parse_sess(),
                ctx.ext_cx.cfg(), "".to_owned(), impl_str).parse_item().unwrap().unwrap()
        };

        method.and_then(|i| {
            match i.node {
                ast::ItemKind::Impl(_, _, _, _, _, mut items) => {
                    items.pop()
                }
                _ => unreachable!("impl parsed to something other than impl")
            }
        })
    };

    let mut offset = data_offset;
    let mut methods = vec!();
    for m in members.into_iter() {
        let advance_by = match *m {
            CompMember::Field(ref f) => {
                methods.extend(mk_field_method(ctx, f, offset).into_iter());
                f.ty.size()
            }
            CompMember::Comp(ref rc_c) => {
                let c = &rc_c.borrow();
                methods.extend(gen_comp_methods(ctx, data_field, offset, c.kind,
                                                &c.members, extra, derive_debug).into_iter());
                c.layout.size
            }
            CompMember::CompField(ref rc_c, ref f) => {
                methods.extend(mk_field_method(ctx, f, offset).into_iter());

                let c = rc_c.borrow();
                extra.extend(comp_to_rs(ctx, c.kind, comp_name(c.kind, &c.name),
                                        derive_debug,
                                        c.layout, c.members.clone()).into_iter());
                f.ty.size()
            }
        };
        match kind {
            CompKind::Struct => { offset += advance_by; }
            CompKind::Union  => { }
        }
    }
    methods
}
/// Generates accessors for fields in nested structs and unions which must be
/// represented in Rust as an untyped array.  This process may generate
/// declarations and implementations that must be placed at the root level.
/// These are emitted into `extra`.
Generates accessors for fields in nested structs and unions which must be
represented in Rust as an untyped array.  This process may generate
declarations and implementations that must be placed at the root level.
These are emitted into `extra`.
Generates accessors for fields in nested structs and unions which must be represented in Rust as an untyped array . This process may generate declarations and implementations that must be placed at the root level . These are emitted into ` extra ` .
fn gen_comp_methods(ctx: &mut GenCtx, data_field: &str, data_offset: usize,
                    kind: CompKind, members: &[CompMember],
                    extra: &mut Vec<P<ast::Item>>,
                    derive_debug: bool) -> Vec<ast::ImplItem> {
    let mk_field_method = |ctx: &mut GenCtx, f: &FieldInfo, offset: usize| {
        // TODO: Implement bitfield accessors
        if f.bitfields.is_some() { return None; }
        let (f_name, _) = rust_id(ctx, f.name.clone());
        let ret_ty = P(cty_to_rs(ctx, &TPtr(Box::new(f.ty.clone()), false, Layout::zero())));
        // When the offset is zero, generate slightly prettier code.
        let method = {
            let impl_str = format!(r"
                impl X {{
                    pub unsafe fn {}(&mut self) -> {} {{
                        let raw: *mut u8 = ::std::mem::transmute(&self.{});
                        ::std::mem::transmute(raw.offset({}))
                    }}
                }}
            ", f_name, tts_to_string(&ret_ty.to_tokens(&ctx.ext_cx)[..]), data_field, offset);
            parse::new_parser_from_source_str(ctx.ext_cx.parse_sess(),
                ctx.ext_cx.cfg(), "".to_owned(), impl_str).parse_item().unwrap().unwrap()
        };
        method.and_then(|i| {
            match i.node {
                ast::ItemKind::Impl(_, _, _, _, _, mut items) => {
                    items.pop()
                }
                _ => unreachable!("impl parsed to something other than impl")
            }
        })
    };
    let mut offset = data_offset;
    let mut methods = vec!();
    for m in members.into_iter() {
        let advance_by = match *m {
            CompMember::Field(ref f) => {
                methods.extend(mk_field_method(ctx, f, offset).into_iter());
                f.ty.size()
            }
            CompMember::Comp(ref rc_c) => {
                let c = &rc_c.borrow();
                methods.extend(gen_comp_methods(ctx, data_field, offset, c.kind,
                                                &c.members, extra, derive_debug).into_iter());
                c.layout.size
            }
            CompMember::CompField(ref rc_c, ref f) => {
                methods.extend(mk_field_method(ctx, f, offset).into_iter());
                let c = rc_c.borrow();
                extra.extend(comp_to_rs(ctx, c.kind, comp_name(c.kind, &c.name),
                                        derive_debug,
                                        c.layout, c.members.clone()).into_iter());
                f.ty.size()
            }
        };
        match kind {
            CompKind::Struct => { offset += advance_by; }
            CompKind::Union  => { }
        }
    }
    methods
}
fn gen_comp_methods ( ctx : & mut GenCtx , data_field : & str , data_offset : usize , kind : CompKind , members : & [ CompMember ] , extra : & mut Vec < P < ast :: Item > > , derive_debug : bool ) -> Vec < ast :: ImplItem > { let mk_field_method = | ctx : & mut GenCtx , f : & FieldInfo , offset : usize | { // TODO: Implement bitfield accessors if f . bitfields . is_some ( ) { return None ; } let ( f_name , _ ) = rust_id ( ctx , f . name . clone ( ) ) ; let ret_ty = P ( cty_to_rs ( ctx , & TPtr ( Box :: new ( f . ty . clone ( ) ) , false , Layout :: zero ( ) ) ) ) ; // When the offset is zero, generate slightly prettier code. let method = { let impl_str = format ! ( r"
                impl X {{
                    pub unsafe fn {}(&mut self) -> {} {{
                        let raw: *mut u8 = ::std::mem::transmute(&self.{});
                        ::std::mem::transmute(raw.offset({}))
                    }}
                }}
            " f_name tts_to_string ( ret_ty to_tokens ( ctx ext_cx ) [ ] ) data_field offset ) ; parse :: new_parser_from_source_str ( ctx . ext_cx . parse_sess ( ) , ctx . ext_cx . cfg ( ) , " " . to_owned ( ) , impl_str ) . parse_item ( ) . unwrap ( ) . unwrap ( ) } ; method . and_then ( | i | { match i . node { ast :: ItemKind :: Impl ( _ , _ , _ , _ , _ , mut items ) => { items . pop ( ) } _ => unreachable ! ( " " ) } } ) } ; let mut offset = data_offset ; let mut methods = vec ! ( ) ; for m in members . into_iter ( ) { let advance_by = match * m { CompMember :: Field ( ref f ) => { methods . extend ( mk_field_method ( ctx , f , offset ) . into_iter ( ) ) ; f . ty . size ( ) } CompMember :: Comp ( ref rc_c ) => { let c = & rc_c . borrow ( ) ; methods . extend ( gen_comp_methods ( ctx , data_field , offset , c . kind , & c . members , extra , derive_debug ) . into_iter ( ) ) ; c . layout . size } CompMember :: CompField ( ref rc_c , ref f ) => { methods . extend ( mk_field_method ( ctx , f , offset ) . into_iter ( ) ) ; let c = rc_c . borrow ( ) ; extra . extend ( comp_to_rs ( ctx , c . kind , comp_name ( c . kind , & c . name ) , derive_debug , c . layout , c . members . clone ( ) ) . into_iter ( ) ) ; f . ty . size ( ) } } ; match kind { CompKind :: Struct => { offset += advance_by ; } CompKind :: Union => { } } } methods }
Generates accessors for fields in nested structs and unions which must be
represented in Rust as an untyped array.
Generates accessors for fields in nested structs and unions which must be represented in Rust as an untyped array .
ctx
&mut GenCtx
data_field
&str
data_offset
usize
kind
CompKind
members
&[CompMember]
extra
&mut Vec<P<ast::Item>>
derive_debug
bool