diff --git a/bindgen-tests/tests/expectations/tests/allowlist-file.rs b/bindgen-tests/tests/expectations/tests/allowlist-file.rs index 1ee7a192ed..cdadf47f9d 100644 --- a/bindgen-tests/tests/expectations/tests/allowlist-file.rs +++ b/bindgen-tests/tests/expectations/tests/allowlist-file.rs @@ -1,5 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub const SOME_DEFUN: u32 = 123; extern "C" { #[link_name = "\u{1}_Z12SomeFunctionv"] pub fn SomeFunction(); @@ -72,6 +71,7 @@ impl Default for StructWithAllowlistedDefinition { } } } +pub const SOME_DEFUN: u32 = 123; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct StructWithAllowlistedFwdDecl { diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs index cfbf2f61cc..4ec58e7825 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -84,8 +84,6 @@ where } } pub const JSVAL_TAG_SHIFT: u32 = 47; -pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; -pub const JSVAL_TAG_MASK: i64 = -140737488355328; #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum JSValueType { @@ -127,6 +125,8 @@ pub enum JSValueShiftedTag { JSVAL_SHIFTED_TAG_NULL = 18445477436314353664, JSVAL_SHIFTED_TAG_OBJECT = 18445618173802708992, } +pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; +pub const JSVAL_TAG_MASK: i64 = -140737488355328; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum JSWhyMagic { diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs index b97bbac96f..fa55d5c1ce 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs @@ -127,8 +127,6 @@ impl ::std::cmp::PartialEq for __BindgenUnionField { } impl ::std::cmp::Eq for __BindgenUnionField {} pub const JSVAL_TAG_SHIFT: u32 = 47; -pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; -pub const JSVAL_TAG_MASK: i64 = -140737488355328; #[repr(u8)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum JSValueType { @@ -170,6 +168,8 @@ pub enum JSValueShiftedTag { JSVAL_SHIFTED_TAG_NULL = 18445477436314353664, JSVAL_SHIFTED_TAG_OBJECT = 18445618173802708992, } +pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; +pub const JSVAL_TAG_MASK: i64 = -140737488355328; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum JSWhyMagic { diff --git a/bindgen-tests/tests/expectations/tests/layout_arp.rs b/bindgen-tests/tests/expectations/tests/layout_arp.rs index 1ee045593f..ee6bdf01a8 100644 --- a/bindgen-tests/tests/expectations/tests/layout_arp.rs +++ b/bindgen-tests/tests/expectations/tests/layout_arp.rs @@ -1,12 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const ETHER_ADDR_LEN: u32 = 6; -pub const ARP_HRD_ETHER: u32 = 1; -pub const ARP_OP_REQUEST: u32 = 1; -pub const ARP_OP_REPLY: u32 = 2; -pub const ARP_OP_REVREQUEST: u32 = 3; -pub const ARP_OP_REVREPLY: u32 = 4; -pub const ARP_OP_INVREQUEST: u32 = 8; -pub const ARP_OP_INVREPLY: u32 = 9; /** Ethernet address: A universally administered address is uniquely assigned to a device by its manufacturer. The first three octets (in transmission order) contain the @@ -133,3 +126,10 @@ fn bindgen_test_layout_arp_hdr() { stringify!(arp_data)) ); } +pub const ARP_HRD_ETHER: u32 = 1; +pub const ARP_OP_REQUEST: u32 = 1; +pub const ARP_OP_REPLY: u32 = 2; +pub const ARP_OP_REVREQUEST: u32 = 3; +pub const ARP_OP_REVREPLY: u32 = 4; +pub const ARP_OP_INVREQUEST: u32 = 8; +pub const ARP_OP_INVREPLY: u32 = 9; diff --git a/bindgen-tests/tests/expectations/tests/layout_array.rs b/bindgen-tests/tests/expectations/tests/layout_array.rs index d9171be24b..3654c62c7c 100644 --- a/bindgen-tests/tests/expectations/tests/layout_array.rs +++ b/bindgen-tests/tests/expectations/tests/layout_array.rs @@ -1,13 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const RTE_CACHE_LINE_SIZE: u32 = 64; pub const RTE_MEMPOOL_OPS_NAMESIZE: u32 = 32; -pub const RTE_MEMPOOL_MAX_OPS_IDX: u32 = 16; -pub const RTE_HEAP_NUM_FREELISTS: u32 = 13; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct rte_mempool { - _unused: [u8; 0], -} /** Prototype for implementation specific data provisioning function. The function should provide the implementation specific memory for @@ -19,6 +12,11 @@ pub struct rte_mempool { pub type rte_mempool_alloc_t = ::std::option::Option< unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int, >; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rte_mempool { + _unused: [u8; 0], +} /// Free the opaque private data pointed to by mp->pool_data pointer. pub type rte_mempool_free_t = ::std::option::Option< unsafe extern "C" fn(mp: *mut rte_mempool), @@ -118,6 +116,7 @@ impl ::std::cmp::PartialEq for rte_mempool_ops { && self.get_count == other.get_count } } +pub const RTE_MEMPOOL_MAX_OPS_IDX: u32 = 16; /// The rte_spinlock_t type. #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -199,6 +198,7 @@ impl Default for rte_mempool_ops_table { } } } +pub const RTE_HEAP_NUM_FREELISTS: u32 = 13; /// Structure to hold malloc heap #[repr(C)] #[repr(align(64))] diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs index 1ec0744f0d..0916a16b85 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs @@ -90,31 +90,6 @@ pub const ETH_VMDQ_MAX_VLAN_FILTERS: u32 = 64; pub const ETH_DCB_NUM_USER_PRIORITIES: u32 = 8; pub const ETH_VMDQ_DCB_NUM_QUEUES: u32 = 128; pub const ETH_DCB_NUM_QUEUES: u32 = 128; -pub const RTE_ETH_FDIR_MAX_FLEXLEN: u32 = 16; -pub const RTE_ETH_INSET_SIZE_MAX: u32 = 128; -pub const RTE_ETH_FLOW_UNKNOWN: u32 = 0; -pub const RTE_ETH_FLOW_RAW: u32 = 1; -pub const RTE_ETH_FLOW_IPV4: u32 = 2; -pub const RTE_ETH_FLOW_FRAG_IPV4: u32 = 3; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_TCP: u32 = 4; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_UDP: u32 = 5; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: u32 = 6; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: u32 = 7; -pub const RTE_ETH_FLOW_IPV6: u32 = 8; -pub const RTE_ETH_FLOW_FRAG_IPV6: u32 = 9; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_TCP: u32 = 10; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_UDP: u32 = 11; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: u32 = 12; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: u32 = 13; -pub const RTE_ETH_FLOW_L2_PAYLOAD: u32 = 14; -pub const RTE_ETH_FLOW_IPV6_EX: u32 = 15; -pub const RTE_ETH_FLOW_IPV6_TCP_EX: u32 = 16; -pub const RTE_ETH_FLOW_IPV6_UDP_EX: u32 = 17; -pub const RTE_ETH_FLOW_PORT: u32 = 18; -pub const RTE_ETH_FLOW_VXLAN: u32 = 19; -pub const RTE_ETH_FLOW_GENEVE: u32 = 20; -pub const RTE_ETH_FLOW_NVGRE: u32 = 21; -pub const RTE_ETH_FLOW_MAX: u32 = 22; #[repr(u32)] /** A set of values to identify what method is to be used to route packets to multiple queues.*/ @@ -1214,6 +1189,8 @@ pub enum rte_eth_payload_type { RTE_ETH_L4_PAYLOAD = 4, RTE_ETH_PAYLOAD_MAX = 8, } +pub const RTE_ETH_FDIR_MAX_FLEXLEN: u32 = 16; +pub const RTE_ETH_INSET_SIZE_MAX: u32 = 128; /** A structure used to select bytes extracted from the protocol layers to flexible payload for filter*/ #[repr(C)] @@ -1286,6 +1263,29 @@ fn bindgen_test_layout_rte_eth_fdir_flex_mask() { stringify!(mask)) ); } +pub const RTE_ETH_FLOW_UNKNOWN: u32 = 0; +pub const RTE_ETH_FLOW_RAW: u32 = 1; +pub const RTE_ETH_FLOW_IPV4: u32 = 2; +pub const RTE_ETH_FLOW_FRAG_IPV4: u32 = 3; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_TCP: u32 = 4; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_UDP: u32 = 5; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: u32 = 6; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: u32 = 7; +pub const RTE_ETH_FLOW_IPV6: u32 = 8; +pub const RTE_ETH_FLOW_FRAG_IPV6: u32 = 9; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_TCP: u32 = 10; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_UDP: u32 = 11; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: u32 = 12; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: u32 = 13; +pub const RTE_ETH_FLOW_L2_PAYLOAD: u32 = 14; +pub const RTE_ETH_FLOW_IPV6_EX: u32 = 15; +pub const RTE_ETH_FLOW_IPV6_TCP_EX: u32 = 16; +pub const RTE_ETH_FLOW_IPV6_UDP_EX: u32 = 17; +pub const RTE_ETH_FLOW_PORT: u32 = 18; +pub const RTE_ETH_FLOW_VXLAN: u32 = 19; +pub const RTE_ETH_FLOW_GENEVE: u32 = 20; +pub const RTE_ETH_FLOW_NVGRE: u32 = 21; +pub const RTE_ETH_FLOW_MAX: u32 = 22; /** A structure used to define all flexible payload related setting include flex payload and flex mask*/ #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs index 086384c450..c20732c604 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs @@ -133,31 +133,6 @@ pub const ETH_VMDQ_MAX_VLAN_FILTERS: u32 = 64; pub const ETH_DCB_NUM_USER_PRIORITIES: u32 = 8; pub const ETH_VMDQ_DCB_NUM_QUEUES: u32 = 128; pub const ETH_DCB_NUM_QUEUES: u32 = 128; -pub const RTE_ETH_FDIR_MAX_FLEXLEN: u32 = 16; -pub const RTE_ETH_INSET_SIZE_MAX: u32 = 128; -pub const RTE_ETH_FLOW_UNKNOWN: u32 = 0; -pub const RTE_ETH_FLOW_RAW: u32 = 1; -pub const RTE_ETH_FLOW_IPV4: u32 = 2; -pub const RTE_ETH_FLOW_FRAG_IPV4: u32 = 3; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_TCP: u32 = 4; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_UDP: u32 = 5; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: u32 = 6; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: u32 = 7; -pub const RTE_ETH_FLOW_IPV6: u32 = 8; -pub const RTE_ETH_FLOW_FRAG_IPV6: u32 = 9; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_TCP: u32 = 10; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_UDP: u32 = 11; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: u32 = 12; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: u32 = 13; -pub const RTE_ETH_FLOW_L2_PAYLOAD: u32 = 14; -pub const RTE_ETH_FLOW_IPV6_EX: u32 = 15; -pub const RTE_ETH_FLOW_IPV6_TCP_EX: u32 = 16; -pub const RTE_ETH_FLOW_IPV6_UDP_EX: u32 = 17; -pub const RTE_ETH_FLOW_PORT: u32 = 18; -pub const RTE_ETH_FLOW_VXLAN: u32 = 19; -pub const RTE_ETH_FLOW_GENEVE: u32 = 20; -pub const RTE_ETH_FLOW_NVGRE: u32 = 21; -pub const RTE_ETH_FLOW_MAX: u32 = 22; #[repr(u32)] /** A set of values to identify what method is to be used to route packets to multiple queues.*/ @@ -1327,6 +1302,8 @@ pub enum rte_eth_payload_type { RTE_ETH_L4_PAYLOAD = 4, RTE_ETH_PAYLOAD_MAX = 8, } +pub const RTE_ETH_FDIR_MAX_FLEXLEN: u32 = 16; +pub const RTE_ETH_INSET_SIZE_MAX: u32 = 128; /** A structure used to select bytes extracted from the protocol layers to flexible payload for filter*/ #[repr(C)] @@ -1409,6 +1386,29 @@ impl Clone for rte_eth_fdir_flex_mask { *self } } +pub const RTE_ETH_FLOW_UNKNOWN: u32 = 0; +pub const RTE_ETH_FLOW_RAW: u32 = 1; +pub const RTE_ETH_FLOW_IPV4: u32 = 2; +pub const RTE_ETH_FLOW_FRAG_IPV4: u32 = 3; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_TCP: u32 = 4; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_UDP: u32 = 5; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: u32 = 6; +pub const RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: u32 = 7; +pub const RTE_ETH_FLOW_IPV6: u32 = 8; +pub const RTE_ETH_FLOW_FRAG_IPV6: u32 = 9; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_TCP: u32 = 10; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_UDP: u32 = 11; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: u32 = 12; +pub const RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: u32 = 13; +pub const RTE_ETH_FLOW_L2_PAYLOAD: u32 = 14; +pub const RTE_ETH_FLOW_IPV6_EX: u32 = 15; +pub const RTE_ETH_FLOW_IPV6_TCP_EX: u32 = 16; +pub const RTE_ETH_FLOW_IPV6_UDP_EX: u32 = 17; +pub const RTE_ETH_FLOW_PORT: u32 = 18; +pub const RTE_ETH_FLOW_VXLAN: u32 = 19; +pub const RTE_ETH_FLOW_GENEVE: u32 = 20; +pub const RTE_ETH_FLOW_NVGRE: u32 = 21; +pub const RTE_ETH_FLOW_MAX: u32 = 22; /** A structure used to define all flexible payload related setting include flex payload and flex mask*/ #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs b/bindgen-tests/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs index 0acb9ad8b8..0709e3eab9 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-5/issue-769-bad-instantiation-test.rs @@ -18,7 +18,6 @@ pub mod root { } } } - pub type AutoValueVector_Alias = ::std::os::raw::c_int; #[test] fn __bindgen_test_layout_Rooted_open0_int_close0_instantiation() { assert_eq!( @@ -32,6 +31,7 @@ pub mod root { ::std::os::raw::c_int >)) ); } + pub type AutoValueVector_Alias = ::std::os::raw::c_int; #[test] fn __bindgen_test_layout_Rooted_open0_AutoValueVector_Alias_close0_instantiation() { assert_eq!( diff --git a/bindgen-tests/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs b/bindgen-tests/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs index 0483cdaf75..404e586f22 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-5/type_alias_template_specialized.rs @@ -30,8 +30,6 @@ impl Default for Rooted { } } } -///
-pub type MaybeWrapped = a; #[test] fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { assert_eq!( @@ -45,3 +43,5 @@ fn __bindgen_test_layout_MaybeWrapped_open0_int_close0_instantiation() { ::std::os::raw::c_int >)) ); } +///
+pub type MaybeWrapped
= a; diff --git a/bindgen-tests/tests/expectations/tests/namespace.rs b/bindgen-tests/tests/expectations/tests/namespace.rs index 83543b851e..73f2fdf8ed 100644 --- a/bindgen-tests/tests/expectations/tests/namespace.rs +++ b/bindgen-tests/tests/expectations/tests/namespace.rs @@ -3,6 +3,14 @@ pub mod root { #[allow(unused_imports)] use self::super::root; + pub mod faraway { + #[allow(unused_imports)] + use self::super::super::root; + extern "C" { + #[link_name = "\u{1}_ZN7faraway3barEv"] + pub fn bar(); + } + } extern "C" { #[link_name = "\u{1}_Z9top_levelv"] pub fn top_level(); @@ -17,7 +25,7 @@ pub mod root { pub fn in_whatever(); } } - pub mod _bindgen_mod_id_17 { + pub mod _bindgen_mod_id_18 { #[allow(unused_imports)] use self::super::super::root; #[repr(C)] @@ -46,7 +54,7 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct C { - pub _base: root::_bindgen_mod_id_17::A, + pub _base: root::_bindgen_mod_id_18::A, pub m_c: T, pub m_c_ptr: *mut T, pub m_c_arr: [T; 10usize], @@ -101,12 +109,4 @@ pub mod root { pub fn foo(); } } - pub mod faraway { - #[allow(unused_imports)] - use self::super::super::root; - extern "C" { - #[link_name = "\u{1}_ZN7faraway3barEv"] - pub fn bar(); - } - } } diff --git a/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs index ab87b4160b..5816a6c5e9 100644 --- a/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs +++ b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs @@ -4,10 +4,6 @@ pub struct Foo { pub _address: u8, } -extern "C" { - #[link_name = "\u{1}_Z1fv"] - pub fn f(); -} #[test] fn __bindgen_test_layout_Foo_open0_Bar_close0_instantiation() { assert_eq!( @@ -19,6 +15,21 @@ fn __bindgen_test_layout_Foo_open0_Bar_close0_instantiation() { concat!("Alignment of template specialization: ", stringify!(Foo)) ); } +#[test] +fn __bindgen_test_layout_Foo_open0_Boo_close0_instantiation() { + assert_eq!( + ::std::mem::size_of:: < Foo > (), 1usize, + concat!("Size of template specialization: ", stringify!(Foo)) + ); + assert_eq!( + ::std::mem::align_of:: < Foo > (), 1usize, + concat!("Alignment of template specialization: ", stringify!(Foo)) + ); +} +extern "C" { + #[link_name = "\u{1}_Z1fv"] + pub fn f(); +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Baz { @@ -34,17 +45,6 @@ fn bindgen_test_layout_Baz() { stringify!(Baz)) ); } -#[test] -fn __bindgen_test_layout_Foo_open0_Boo_close0_instantiation() { - assert_eq!( - ::std::mem::size_of:: < Foo > (), 1usize, - concat!("Size of template specialization: ", stringify!(Foo)) - ); - assert_eq!( - ::std::mem::align_of:: < Foo > (), 1usize, - concat!("Alignment of template specialization: ", stringify!(Foo)) - ); -} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Bar { diff --git a/bindgen/clang.rs b/bindgen/clang.rs index 0060213336..5ee7c6ba74 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -6,6 +6,8 @@ use crate::ir::context::BindgenContext; use clang_sys::*; +use std::cmp; +use std::collections::HashMap; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; @@ -496,6 +498,41 @@ impl Cursor { } } + pub(crate) fn visit_sorted( + &self, + ctx: &mut BindgenContext, + mut visitor: Visitor, + ) where + Visitor: FnMut(&mut BindgenContext, Cursor) -> CXChildVisitResult, + { + let mut children = self.collect_children(); + + for child in &children { + if child.kind() == CXCursor_InclusionDirective { + if let Some(included_file) = child.get_included_file_name() { + let location = child.location(); + + let (file, _, _, offset) = location.location(); + + if let Some(source_file) = file.name() { + ctx.include_file(source_file, offset, included_file); + } + } + } + } + + children.sort_by(|child1, child2| { + child1 + .location() + .partial_cmp_with_context(&child2.location(), ctx) + .unwrap_or(std::cmp::Ordering::Equal) + }); + + for child in children { + visitor(ctx, child); + } + } + /// Collect all of this cursor's children into a vec and return them. pub(crate) fn collect_children(&self) -> Vec { let mut children = vec![]; @@ -1524,6 +1561,42 @@ impl SourceLocation { } } +impl SourceLocation { + /// Compare source locations, also considering `#include` directives. + pub(crate) fn partial_cmp_with_context( + &self, + other: &Self, + ctx: &BindgenContext, + ) -> Option { + let (file, _, _, offset) = self.location(); + let (other_file, _, _, other_offset) = other.location(); + + match (file.name(), other_file.name()) { + (Some(file), Some(other_file)) if file == other_file => { + offset.partial_cmp(&other_offset) + } + (Some(file), Some(other_file)) => { + if let Some(other_offset) = + ctx.included_file_offset(file.clone(), other_file.clone()) + { + return offset.partial_cmp(&other_offset); + } + + if let Some(offset) = ctx.included_file_offset(other_file, file) + { + return other_offset.partial_cmp(&offset); + } + + None + } + // Built-in definitions should come first. + (Some(_), None) => Some(cmp::Ordering::Greater), + (None, Some(_)) => Some(cmp::Ordering::Less), + (None, None) => Some(cmp::Ordering::Equal), + } + } +} + impl fmt::Display for SourceLocation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (file, line, col, _) = self.location(); diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index c381f57cb8..4cf8bd5b0d 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -274,6 +274,8 @@ struct CodegenResult<'a> { /// that name. This lets us give each overload a unique suffix. overload_counters: HashMap, + overload_counts: HashMap, + /// List of items to serialize. With optionally the argument for the wrap as /// variadic transformation to be applied. items_to_serialize: Vec<(ItemId, Option)>, @@ -294,6 +296,7 @@ impl<'a> CodegenResult<'a> { functions_seen: Default::default(), vars_seen: Default::default(), overload_counters: Default::default(), + overload_counts: Default::default(), items_to_serialize: Default::default(), } } @@ -348,6 +351,14 @@ impl<'a> CodegenResult<'a> { number } + fn set_overload_count(&mut self, id: ItemId, count: u32) { + self.overload_counts.insert(id, count); + } + + fn overload_count(&self, id: &ItemId) -> Option { + self.overload_counts.get(id).cloned() + } + fn seen_var(&self, name: &str) -> bool { self.vars_seen.contains(name) } @@ -2586,14 +2597,23 @@ impl Method { // First of all, output the actual function. let function_item = ctx.resolve_item(self.signature()); - if !function_item.process_before_codegen(ctx, result) { - return; - } let function = function_item.expect_function(); - let times_seen = function.codegen(ctx, result, function_item); - let times_seen = match times_seen { - Some(seen) => seen, - None => return, + let times_seen = if let Some(times_seen) = + result.overload_count(&function_item.id()) + { + times_seen + } else { + if !function_item.process_before_codegen(ctx, result) { + return; + } + + if let Some(times_seen) = + function.codegen(ctx, result, function_item) + { + times_seen + } else { + return; + } }; let signature_item = ctx.resolve_item(function.signature()); let mut name = match self.kind() { @@ -4179,8 +4199,7 @@ impl TryToRustTy for FunctionSig { impl CodeGenerator for Function { type Extra = Item; - /// If we've actually generated the symbol, the number of times we've seen - /// it. + /// If we've actually generated the symbol, the number of times we've seen it. type Return = Option; fn codegen( @@ -4340,6 +4359,7 @@ impl CodeGenerator for Function { // Handle overloaded functions by giving each overload its own unique // suffix. let times_seen = result.overload_number(&canonical_name); + result.set_overload_count(item.id(), times_seen); if times_seen > 0 { write!(&mut canonical_name, "{}", times_seen).unwrap(); } diff --git a/bindgen/deps.rs b/bindgen/deps.rs index 2edeaa8886..e348fa1303 100644 --- a/bindgen/deps.rs +++ b/bindgen/deps.rs @@ -9,7 +9,7 @@ pub(crate) struct DepfileSpec { impl DepfileSpec { pub fn write(&self, deps: &BTreeSet) -> std::io::Result<()> { - std::fs::write(&self.depfile_path, &self.to_string(deps)) + std::fs::write(&self.depfile_path, self.to_string(deps)) } fn to_string(&self, deps: &BTreeSet) -> String { diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs index ee07625430..20784c2dfd 100644 --- a/bindgen/ir/context.rs +++ b/bindgen/ir/context.rs @@ -356,6 +356,11 @@ pub(crate) struct BindgenContext { /// This needs to be an std::HashMap because the cexpr API requires it. parsed_macros: StdHashMap, cexpr::expr::EvalResult>, + /// A map with all include locations. + /// + /// This is needed so that items are created in the order they are defined in. + includes: StdHashMap<(String, String), usize>, + /// A set of all the included filenames. deps: BTreeSet, @@ -560,6 +565,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" BindgenContext { items: vec![Some(root_module)], + includes: Default::default(), deps, types: Default::default(), type_params: Default::default(), @@ -635,11 +641,28 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Add another path to the set of included files. - pub(crate) fn include_file(&mut self, filename: String) { + pub(crate) fn include_file( + &mut self, + source_file: String, + offset: usize, + included_file: String, + ) { for cb in &self.options().parse_callbacks { - cb.include_file(&filename); + cb.include_file(&included_file); } - self.deps.insert(filename); + self.deps.insert(included_file.clone()); + + let key = (source_file, included_file); + self.includes.entry(key).or_insert(offset); + } + + /// Get the offset of the `#include` directive for the `included_file` in the `source_file`. + pub(crate) fn included_file_offset( + &self, + source_file: String, + included_file: String, + ) -> Option { + self.includes.get(&(source_file, included_file)).cloned() } /// Get any included files. diff --git a/bindgen/ir/item.rs b/bindgen/ir/item.rs index f4dce45d83..1052c8b9e5 100644 --- a/bindgen/ir/item.rs +++ b/bindgen/ir/item.rs @@ -1461,7 +1461,12 @@ impl Item { ); } Some(filename) => { - ctx.include_file(filename); + let location = cursor.location(); + + let (file, _, _, offset) = location.location(); + let source_file = file.name().unwrap(); + + ctx.include_file(source_file, offset, filename); } } } diff --git a/bindgen/ir/module.rs b/bindgen/ir/module.rs index f25ef40f77..9ba84a7a3c 100644 --- a/bindgen/ir/module.rs +++ b/bindgen/ir/module.rs @@ -6,6 +6,7 @@ use super::item::ItemSet; use crate::clang; use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use crate::parse_one; +use std::collections::HashMap; use std::io; /// Whether this module is inline or not. @@ -82,8 +83,8 @@ impl ClangSubItemParser for Module { CXCursor_Namespace => { let module_id = ctx.module(cursor); ctx.with_module(module_id, |ctx| { - cursor.visit(|cursor| { - parse_one(ctx, cursor, Some(module_id.into())) + cursor.visit_sorted(ctx, |ctx, child| { + parse_one(ctx, child, Some(module_id.into())) }) }); diff --git a/bindgen/lib.rs b/bindgen/lib.rs index 2eb4486dac..cd03f805e9 100644 --- a/bindgen/lib.rs +++ b/bindgen/lib.rs @@ -66,7 +66,7 @@ use options::BindgenOptions; use parse::ParseError; use std::borrow::Cow; -use std::collections::hash_map::Entry; +use std::collections::{hash_map::Entry, HashMap as StdHashMap}; use std::env; use std::ffi::OsStr; use std::fs::{File, OpenOptions}; @@ -1085,7 +1085,8 @@ fn parse_one( Ok(..) => {} Err(ParseError::Continue) => {} Err(ParseError::Recurse) => { - cursor.visit(|child| parse_one(ctx, child, parent)); + cursor + .visit_sorted(ctx, |ctx, child| parse_one(ctx, child, parent)); } } CXChildVisit_Continue @@ -1126,8 +1127,8 @@ fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { } let root = context.root_module(); - context.with_module(root, |context| { - cursor.visit(|cursor| parse_one(context, cursor, None)) + context.with_module(root, |ctx| { + cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None)) }); assert!(