Repository: rust-lang/rust-bindgen
Pull request #2543 (2023-06-03 06:38:45)

Parse code by source order.
Extracted from https://github.com/rust-lang/rust-bindgen/pull/2369.

In order to somewhat support `#undef`, code needs to be parsed in the correct order. Previously, all macros were parsed before all variables, making it impossible to reason about whether a variable was declared before or after a macro with the same name.

bors-servo: :umbrella: The latest upstream changes (presumably bfc5b7faeb6498a8bed02ba89f2f45400d320b5a) made this pull request unmergeable. Please resolve the merge conflicts.
pvdrz: I just did a review and added a few comments, most of them are just about documentation. 

Could you also please document these changes in the changelog. Mainly the fact that the order of the bindings has changed and that the `__bindgen_ty_\d+` types might change name because of this?

Also I have a last question: The evaluation of define directives is not affected by this new ordering yet, right? 
reitermarkus: > The evaluation of define directives is not affected by this new ordering yet, right?

No, this is simply extracting this logic from https://github.com/rust-lang/rust-bindgen/pull/2369 for easier review.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93072cb4..610c2cfc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -188,6 +188,8 @@
 * Updated `bitflags` dependency to 2.2.1. This changes the API of `CodegenConfig`.
 * Prettyplease formatting is gated by an optional, enabled by default Cargo
   feature when depending on `bindgen` as a library.
+* Items are now parsed in the order they appear in source files. This may result in
+  auto-generated `_bindgen_*` names having a different index.
 
 ## Removed
 
diff --git a/bindgen/clang.rs b/bindgen/clang.rs
index 00602133..0559faf4 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::ffi::{CStr, CString};
 use std::fmt;
 use std::hash::Hash;
@@ -496,6 +498,44 @@ impl Cursor {
         }
     }
 
+    /// Traverse this curser's children, sorted by where they appear in source code.
+    ///
+    /// Call the given function on each AST node traversed.
+    pub(crate) fn visit_sorted<Visitor>(
+        &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 (source_file, _, _, offset) = location.location();
+
+                    if let Some(source_file) = source_file.name() {
+                        ctx.add_include(source_file, included_file, offset);
+                    }
+                }
+            }
+        }
+
+        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<Cursor> {
         let mut children = vec![];
@@ -1524,6 +1564,63 @@ impl SourceLocation {
     }
 }
 
+impl SourceLocation {
+    /// Compare source locations, also considering `#include` directives.
+    ///
+    /// Built-in items provided by the compiler (which don't have a source file),
+    /// are sorted first. Remaining files are sorted by their position in the source file.
+    /// If the items' source files differ, they are sorted by the position of the first
+    /// `#include` for their source file. If no source files are included, `None` is returned.
+    pub(crate) fn partial_cmp_with_context(
+        &self,
+        other: &Self,
+        ctx: &BindgenContext,
+    ) -> Option<cmp::Ordering> {
+        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 {
+                    return offset.partial_cmp(&other_offset);
+                }
+
+                let include_location = ctx.included_file_location(&file);
+                let other_include_location =
+                    ctx.included_file_location(&other_file);
+
+                match (include_location, other_include_location) {
+                    (Some((file2, offset2)), _) if file2 == other_file => {
+                        offset2.partial_cmp(&other_offset)
+                    }
+                    (Some(_), None) => Some(cmp::Ordering::Greater),
+                    (_, Some((other_file2, other_offset2)))
+                        if file == other_file2 =>
+                    {
+                        offset.partial_cmp(&other_offset2)
+                    }
+                    (None, Some(_)) => Some(cmp::Ordering::Less),
+                    (
+                        Some((file2, offset2)),
+                        Some((other_file2, other_offset2)),
+                    ) => {
+                        if file2 == other_file2 {
+                            offset2.partial_cmp(&other_offset2)
+                        } else {
+                            None
+                        }
+                    }
+                    (None, None) => Some(cmp::Ordering::Equal),
+                }
+            }
+            // 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/deps.rs b/bindgen/deps.rs
index 2edeaa88..e348fa13 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<String>) -> 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>) -> String {
diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs
index ee076254..bc9e59c3 100644
--- a/bindgen/ir/context.rs
+++ b/bindgen/ir/context.rs
@@ -356,6 +356,14 @@ pub(crate) struct BindgenContext {
     /// This needs to be an std::HashMap because the cexpr API requires it.
     parsed_macros: StdHashMap<Vec<u8>, cexpr::expr::EvalResult>,
 
+    /// A map with all include locations.
+    ///
+    /// This is needed so that items are created in the order they are defined in.
+    ///
+    /// The key is the included file, the value is a pair of the source file and
+    /// the position of the `#include` directive in the source file.
+    includes: StdHashMap<String, (String, usize)>,
+
     /// A set of all the included filenames.
     deps: BTreeSet<String>,
 
@@ -560,6 +568,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(),
@@ -634,12 +643,29 @@ 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) {
-        for cb in &self.options().parse_callbacks {
-            cb.include_file(&filename);
-        }
-        self.deps.insert(filename);
+    /// Add the location of the `#include` directive for the `included_file`.
+    pub(crate) fn add_include(
+        &mut self,
+        source_file: String,
+        included_file: String,
+        offset: usize,
+    ) {
+        self.includes
+            .entry(included_file)
+            .or_insert((source_file, offset));
+    }
+
+    /// Get the location of the first `#include` directive for the `included_file`.
+    pub(crate) fn included_file_location(
+        &self,
+        included_file: &str,
+    ) -> Option<(String, usize)> {
+        self.includes.get(included_file).cloned()
+    }
+
+    /// Add an included file.
+    pub(crate) fn add_dep(&mut self, dep: String) {
+        self.deps.insert(dep);
     }
 
     /// Get any included files.
diff --git a/bindgen/ir/item.rs b/bindgen/ir/item.rs
index f4dce45d..1b9d7694 100644
--- a/bindgen/ir/item.rs
+++ b/bindgen/ir/item.rs
@@ -1460,8 +1460,12 @@ impl Item {
                                 cursor
                             );
                         }
-                        Some(filename) => {
-                            ctx.include_file(filename);
+                        Some(included_file) => {
+                            for cb in &ctx.options().parse_callbacks {
+                                cb.include_file(&included_file);
+                            }
+
+                            ctx.add_dep(included_file);
                         }
                     }
                 }
diff --git a/bindgen/ir/module.rs b/bindgen/ir/module.rs
index f25ef40f..5ec55e90 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::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 2eb4486d..be0cd826 100644
--- a/bindgen/lib.rs
+++ b/bindgen/lib.rs
@@ -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!(


Test patch:
diff --git a/bindgen-tests/tests/expectations/tests/allowlist-file.rs b/bindgen-tests/tests/expectations/tests/allowlist-file.rs
index 1ee7a192..63953ccb 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();
@@ -7,6 +6,7 @@ extern "C" {
 extern "C" {
     pub static mut someVar: ::std::os::raw::c_int;
 }
+pub const SOME_DEFUN: u32 = 123;
 #[repr(C)]
 #[derive(Debug, Default, Copy, Clone)]
 pub struct someClass {
diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs
index cfbf2f61..4ec58e78 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 b97bbac9..fa55d5c1 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<T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
 }
 impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
 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 1ee04559..ee6bdf01 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 d9171be2..3654c62c 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 1ec0744f..0916a16b 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 086384c4..c20732c6 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/namespace.rs b/bindgen-tests/tests/expectations/tests/namespace.rs
index 83543b85..a99711b2 100644
--- a/bindgen-tests/tests/expectations/tests/namespace.rs
+++ b/bindgen-tests/tests/expectations/tests/namespace.rs
@@ -17,7 +17,7 @@ pub mod root {
             pub fn in_whatever();
         }
     }
-    pub mod _bindgen_mod_id_17 {
+    pub mod _bindgen_mod_id_13 {
         #[allow(unused_imports)]
         use self::super::super::root;
         #[repr(C)]
@@ -46,7 +46,7 @@ pub mod root {
     #[repr(C)]
     #[derive(Debug)]
     pub struct C<T> {
-        pub _base: root::_bindgen_mod_id_17::A,
+        pub _base: root::_bindgen_mod_id_13::A,
         pub m_c: T,
         pub m_c_ptr: *mut T,
         pub m_c_arr: [T; 10usize],
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 ab87b416..5816a6c5 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 {