Skip to content

Cannot generate inner struct definition (worked on v0.20.0 but not v0.23.1) #643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
leeopop opened this issue Apr 19, 2017 · 1 comment
Closed

Comments

@leeopop
Copy link

leeopop commented Apr 19, 2017

Input C/C++ Header

// Insert your (minimal) C/C++ header here
struct rte_ring {
        /*
         * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
         * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
         * next time the ABI changes
         */
        char name[RTE_MEMZONE_NAMESIZE];    /**< Name of the ring. */
        int flags;                       /**< Flags supplied at creation. */
        const struct rte_memzone *memzone;
                        /**< Memzone, if any, containing the rte_ring */

        /** Ring producer status. */
        struct prod {
                uint32_t watermark;      /**< Maximum items before EDQUOT. */
                uint32_t sp_enqueue;     /**< True, if single producer. */
                uint32_t size;           /**< Size of ring. */
                uint32_t mask;           /**< Mask (size-1) of ring. */
                volatile uint32_t head;  /**< Producer head. */
                volatile uint32_t tail;  /**< Producer tail. */
        } prod __rte_cache_aligned;

        /** Ring consumer status. */
        struct cons {
                uint32_t sc_dequeue;     /**< True, if single consumer. */
                uint32_t size;           /**< Size of the ring. */
                uint32_t mask;           /**< Mask (size-1) of ring. */
                volatile uint32_t head;  /**< Consumer head. */
                volatile uint32_t tail;  /**< Consumer tail. */
#ifdef RTE_RING_SPLIT_PROD_CONS
        } cons __rte_cache_aligned;
#else
        } cons;
#endif

#ifdef RTE_LIBRTE_RING_DEBUG
        struct rte_ring_debug_stats stats[RTE_MAX_LCORE];
#endif

        void *ring[] __rte_cache_aligned;   /**< Memory space of ring starts here.
                                             * not volatile so need to be careful
                                             * about compiler re-ordering */
};

Bindgen Invokation

    bindgen::builder()
        .header(header_path.to_str().unwrap())
        .no_unstable_rust()
        .clang_arg(format!("-I{}", dpdk_include_path.to_str().unwrap()))
        .clang_arg(format!("-I{}", c_include_path.to_str().unwrap()))
        .clang_arg("-imacros")
        .clang_arg(dpdk_config_path.to_str().unwrap())
        .clang_arg("-march=native")
        .generate()
        .unwrap()
        .write_to_file(target_path)
        .ok();

Actual Results

// Insert the (incorrect) generated bindings here
#[repr(C)]
#[derive(Debug, Copy)]
pub struct rte_ring {
    /**< Name of the ring. */
    pub name: [::std::os::raw::c_char; 32usize],
    /**< Flags supplied at creation. */
    pub flags: ::std::os::raw::c_int,
    pub memzone: *const rte_memzone,
    pub prod: rte_ring_prod,
    pub cons: rte_ring_cons,
    /**< Memory space of ring starts here.
	                                     * not volatile so need to be careful
	                                     * about compiler re-ordering */
    pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>,
    pub __bindgen_padding_0: [u32; 9usize],
}
#[test]
fn bindgen_test_layout_rte_ring() {
    assert_eq!(::std::mem::size_of::<rte_ring>() , 128usize , concat ! (
               "Size of: " , stringify ! ( rte_ring ) ));
}
impl Clone for rte_ring {
    fn clone(&self) -> Self { *self }
}

and/or

Insert compilation errors generated when compiling the bindings with rustc here

error[E0412]: cannot find type `rte_ring_prod` in this scope
     --> /home/leeopop/git/rust-dpdk/src/dpdk.rs:12061:15
      |
12061 |     pub prod: rte_ring_prod,
      |               ^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `rte_ring_cons` in this scope
     --> /home/leeopop/git/rust-dpdk/src/dpdk.rs:12062:15
      |
12062 |     pub cons: rte_ring_cons,
      |               ^^^^^^^^^^^^^ did you mean `rte_intr_conf`?

error[E0204]: the trait `Copy` may not be implemented for this type
     --> /home/leeopop/git/rust-dpdk/src/dpdk.rs:12054:17
      |
12054 | #[derive(Debug, Copy)]
      |                 ^^^^
...
12061 |     pub prod: rte_ring_prod,
      |     ----------------------- this field does not implement `Copy`

-->

Expected Results

Result from bindgen 0.20.0

#[repr(C)]
#[derive(Debug, Copy)]
pub struct rte_ring {
    /**< Name of the ring. */
    pub name: [::std::os::raw::c_char; 32usize],
    /**< Flags supplied at creation. */
    pub flags: ::std::os::raw::c_int,
    pub memzone: *const rte_memzone,
    pub prod: rte_ring_prod,
    pub cons: rte_ring_cons,
    /**< Memory space of ring starts here.
	                                     * not volatile so need to be careful
	                                     * about compiler re-ordering */
    pub ring: *mut *mut ::std::os::raw::c_void,
}
/** Ring producer status. */
#[repr(C)]
#[derive(Debug, Copy)]
pub struct rte_ring_prod {
    /**< Maximum items before EDQUOT. */
    pub watermark: u32,
    /**< True, if single producer. */
    pub sp_enqueue: u32,
    /**< Size of ring. */
    pub size: u32,
    /**< Mask (size-1) of ring. */
    pub mask: u32,
    /**< Producer head. */
    pub head: u32,
    /**< Producer tail. */
    pub tail: u32,
}
#[test]
fn bindgen_test_layout_rte_ring_prod() {
    assert_eq!(::std::mem::size_of::<rte_ring_prod>() , 24usize);
    assert_eq!(::std::mem::align_of::<rte_ring_prod>() , 4usize);
}
impl Clone for rte_ring_prod {
    fn clone(&self) -> Self { *self }
}
/** Ring consumer status. */
#[repr(C)]
#[derive(Debug, Copy)]
pub struct rte_ring_cons {
    /**< True, if single consumer. */
    pub sc_dequeue: u32,
    /**< Size of the ring. */
    pub size: u32,
    /**< Mask (size-1) of ring. */
    pub mask: u32,
    /**< Consumer head. */
    pub head: u32,
    /**< Consumer tail. */
    pub tail: u32,
}
#[test]
fn bindgen_test_layout_rte_ring_cons() {
    assert_eq!(::std::mem::size_of::<rte_ring_cons>() , 20usize);
    assert_eq!(::std::mem::align_of::<rte_ring_cons>() , 4usize);
}
impl Clone for rte_ring_cons {
    fn clone(&self) -> Self { *self }
}
impl Clone for rte_ring {
    fn clone(&self) -> Self { *self }
}

RUST_LOG=bindgen Output

Insert debug logging when running bindgen with the RUST_LOG=bindgen environment
variable set.
@emilio
Copy link
Contributor

emilio commented Apr 19, 2017

Thanks for the report!

The regression was caused by #486, and the fix is at #644.

emilio added a commit to emilio/rust-bindgen that referenced this issue Apr 19, 2017
bors-servo pushed a commit that referenced this issue Apr 19, 2017
ir: consider all nested definitions inside structs to be inner types.

Fixes #643
Kowasaki pushed a commit to Kowasaki/rust-bindgen that referenced this issue May 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants