summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs113
-rw-r--r--bindgen-tests/tests/expectations/tests/sort-items.rs220
-rw-r--r--bindgen-tests/tests/expectations/tests/sorted-items.rs82
-rw-r--r--bindgen-tests/tests/expectations/tests/sorted_items.rs220
-rw-r--r--bindgen-tests/tests/headers/merge-extern-blocks.h6
-rw-r--r--bindgen-tests/tests/headers/merge-extern-blocks.hpp14
-rw-r--r--bindgen-tests/tests/headers/sorted-items.h17
-rw-r--r--bindgen-tests/tests/headers/sorted_items.hpp35
-rw-r--r--bindgen/Cargo.toml2
-rw-r--r--bindgen/codegen/postprocessing/merge_extern_blocks.rs94
-rw-r--r--bindgen/codegen/postprocessing/mod.rs28
-rw-r--r--bindgen/codegen/postprocessing/sort_semantically.rs58
12 files changed, 681 insertions, 208 deletions
diff --git a/bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs b/bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs
index 66ceeff0..ae9799d2 100644
--- a/bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs
+++ b/bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs
@@ -5,33 +5,88 @@
non_upper_case_globals
)]
-#[repr(C)]
-#[derive(Debug, Default, Copy, Clone)]
-pub struct Point {
- pub x: ::std::os::raw::c_int,
-}
-#[test]
-fn bindgen_test_layout_Point() {
- const UNINIT: ::std::mem::MaybeUninit<Point> =
- ::std::mem::MaybeUninit::uninit();
- let ptr = UNINIT.as_ptr();
- assert_eq!(
- ::std::mem::size_of::<Point>(),
- 4usize,
- concat!("Size of: ", stringify!(Point))
- );
- assert_eq!(
- ::std::mem::align_of::<Point>(),
- 4usize,
- concat!("Alignment of ", stringify!(Point))
- );
- assert_eq!(
- unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
- 0usize,
- concat!("Offset of field: ", stringify!(Point), "::", stringify!(x))
- );
-}
-extern "C" {
- pub fn foo() -> ::std::os::raw::c_int;
- pub fn bar() -> ::std::os::raw::c_int;
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: ::std::os::raw::c_int,
+ }
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 4usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ }
+ pub mod ns {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: ::std::os::raw::c_int,
+ }
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 4usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ }
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3fooEv"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ #[link_name = "\u{1}_ZN2ns3barEv"]
+ pub fn bar() -> ::std::os::raw::c_int;
+ }
+ }
+ extern "C" {
+ #[link_name = "\u{1}_Z3foov"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ #[link_name = "\u{1}_Z3barv"]
+ pub fn bar() -> ::std::os::raw::c_int;
+ }
}
diff --git a/bindgen-tests/tests/expectations/tests/sort-items.rs b/bindgen-tests/tests/expectations/tests/sort-items.rs
new file mode 100644
index 00000000..e04e3b60
--- /dev/null
+++ b/bindgen-tests/tests/expectations/tests/sort-items.rs
@@ -0,0 +1,220 @@
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ pub type number = ::std::os::raw::c_int;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: root::number,
+ pub y: root::number,
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Angle {
+ pub a: root::number,
+ pub b: root::number,
+ }
+ pub const NUMBER: root::number = 42;
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(y)
+ )
+ );
+ }
+ #[test]
+ fn bindgen_test_layout_Angle() {
+ const UNINIT: ::std::mem::MaybeUninit<Angle> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Angle>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Angle))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Angle>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Angle))
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(b)
+ )
+ );
+ }
+ pub mod ns {
+ pub type number = ::std::os::raw::c_int;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: root::ns::number,
+ pub y: root::ns::number,
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Angle {
+ pub a: root::ns::number,
+ pub b: root::ns::number,
+ }
+ pub const NUMBER: root::ns::number = 42;
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(y)
+ )
+ );
+ }
+ #[test]
+ fn bindgen_test_layout_Angle() {
+ const UNINIT: ::std::mem::MaybeUninit<Angle> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Angle>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Angle))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Angle>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Angle))
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(b)
+ )
+ );
+ }
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3fooEv"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3barEi"]
+ pub fn bar(x: root::ns::number) -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3bazENS_5PointE"]
+ pub fn baz(point: root::ns::Point) -> ::std::os::raw::c_int;
+ }
+ }
+ #[allow(unused_imports)]
+ use self::super::root;
+ extern "C" {
+ #[link_name = "\u{1}_Z3foov"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_Z3bari"]
+ pub fn bar(x: root::number) -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_Z3baz5Point"]
+ pub fn baz(point: root::Point) -> ::std::os::raw::c_int;
+ }
+}
diff --git a/bindgen-tests/tests/expectations/tests/sorted-items.rs b/bindgen-tests/tests/expectations/tests/sorted-items.rs
deleted file mode 100644
index 7df7c3d7..00000000
--- a/bindgen-tests/tests/expectations/tests/sorted-items.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-#![allow(
- dead_code,
- non_snake_case,
- non_camel_case_types,
- non_upper_case_globals
-)]
-
-pub type number = ::std::os::raw::c_int;
-#[repr(C)]
-#[derive(Debug, Default, Copy, Clone)]
-pub struct Point {
- pub x: number,
- pub y: number,
-}
-#[repr(C)]
-#[derive(Debug, Default, Copy, Clone)]
-pub struct Angle {
- pub a: number,
- pub b: number,
-}
-pub const NUMBER: number = 42;
-#[test]
-fn bindgen_test_layout_Point() {
- const UNINIT: ::std::mem::MaybeUninit<Point> =
- ::std::mem::MaybeUninit::uninit();
- let ptr = UNINIT.as_ptr();
- assert_eq!(
- ::std::mem::size_of::<Point>(),
- 8usize,
- concat!("Size of: ", stringify!(Point))
- );
- assert_eq!(
- ::std::mem::align_of::<Point>(),
- 4usize,
- concat!("Alignment of ", stringify!(Point))
- );
- assert_eq!(
- unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
- 0usize,
- concat!("Offset of field: ", stringify!(Point), "::", stringify!(x))
- );
- assert_eq!(
- unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
- 4usize,
- concat!("Offset of field: ", stringify!(Point), "::", stringify!(y))
- );
-}
-#[test]
-fn bindgen_test_layout_Angle() {
- const UNINIT: ::std::mem::MaybeUninit<Angle> =
- ::std::mem::MaybeUninit::uninit();
- let ptr = UNINIT.as_ptr();
- assert_eq!(
- ::std::mem::size_of::<Angle>(),
- 8usize,
- concat!("Size of: ", stringify!(Angle))
- );
- assert_eq!(
- ::std::mem::align_of::<Angle>(),
- 4usize,
- concat!("Alignment of ", stringify!(Angle))
- );
- assert_eq!(
- unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },
- 0usize,
- concat!("Offset of field: ", stringify!(Angle), "::", stringify!(a))
- );
- assert_eq!(
- unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize },
- 4usize,
- concat!("Offset of field: ", stringify!(Angle), "::", stringify!(b))
- );
-}
-extern "C" {
- pub fn foo() -> ::std::os::raw::c_int;
-}
-extern "C" {
- pub fn bar(x: number) -> ::std::os::raw::c_int;
-}
-extern "C" {
- pub fn baz(point: Point) -> ::std::os::raw::c_int;
-}
diff --git a/bindgen-tests/tests/expectations/tests/sorted_items.rs b/bindgen-tests/tests/expectations/tests/sorted_items.rs
new file mode 100644
index 00000000..e04e3b60
--- /dev/null
+++ b/bindgen-tests/tests/expectations/tests/sorted_items.rs
@@ -0,0 +1,220 @@
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ pub type number = ::std::os::raw::c_int;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: root::number,
+ pub y: root::number,
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Angle {
+ pub a: root::number,
+ pub b: root::number,
+ }
+ pub const NUMBER: root::number = 42;
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(y)
+ )
+ );
+ }
+ #[test]
+ fn bindgen_test_layout_Angle() {
+ const UNINIT: ::std::mem::MaybeUninit<Angle> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Angle>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Angle))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Angle>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Angle))
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(b)
+ )
+ );
+ }
+ pub mod ns {
+ pub type number = ::std::os::raw::c_int;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Point {
+ pub x: root::ns::number,
+ pub y: root::ns::number,
+ }
+ #[repr(C)]
+ #[derive(Debug, Default, Copy, Clone)]
+ pub struct Angle {
+ pub a: root::ns::number,
+ pub b: root::ns::number,
+ }
+ pub const NUMBER: root::ns::number = 42;
+ #[test]
+ fn bindgen_test_layout_Point() {
+ const UNINIT: ::std::mem::MaybeUninit<Point> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Point>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Point))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Point>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Point))
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(x)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Point),
+ "::",
+ stringify!(y)
+ )
+ );
+ }
+ #[test]
+ fn bindgen_test_layout_Angle() {
+ const UNINIT: ::std::mem::MaybeUninit<Angle> =
+ ::std::mem::MaybeUninit::uninit();
+ let ptr = UNINIT.as_ptr();
+ assert_eq!(
+ ::std::mem::size_of::<Angle>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Angle))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Angle>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Angle))
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Angle),
+ "::",
+ stringify!(b)
+ )
+ );
+ }
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3fooEv"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3barEi"]
+ pub fn bar(x: root::ns::number) -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_ZN2ns3bazENS_5PointE"]
+ pub fn baz(point: root::ns::Point) -> ::std::os::raw::c_int;
+ }
+ }
+ #[allow(unused_imports)]
+ use self::super::root;
+ extern "C" {
+ #[link_name = "\u{1}_Z3foov"]
+ pub fn foo() -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_Z3bari"]
+ pub fn bar(x: root::number) -> ::std::os::raw::c_int;
+ }
+ extern "C" {
+ #[link_name = "\u{1}_Z3baz5Point"]
+ pub fn baz(point: root::Point) -> ::std::os::raw::c_int;
+ }
+}
diff --git a/bindgen-tests/tests/headers/merge-extern-blocks.h b/bindgen-tests/tests/headers/merge-extern-blocks.h
deleted file mode 100644
index 1d46b7d4..00000000
--- a/bindgen-tests/tests/headers/merge-extern-blocks.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// bindgen-flags: --merge-extern-blocks -- --target=x86_64-unknown-linux
-int foo();
-typedef struct Point {
- int x;
-} Point;
-int bar();
diff --git a/bindgen-tests/tests/headers/merge-extern-blocks.hpp b/bindgen-tests/tests/headers/merge-extern-blocks.hpp
new file mode 100644
index 00000000..392e34a3
--- /dev/null
+++ b/bindgen-tests/tests/headers/merge-extern-blocks.hpp
@@ -0,0 +1,14 @@
+// bindgen-flags: --merge-extern-blocks --enable-cxx-namespaces -- --target=x86_64-unknown-linux
+int foo();
+typedef struct Point {
+ int x;
+} Point;
+int bar();
+
+namespace ns {
+ int foo();
+ typedef struct Point {
+ int x;
+ } Point;
+ int bar();
+}
diff --git a/bindgen-tests/tests/headers/sorted-items.h b/bindgen-tests/tests/headers/sorted-items.h
deleted file mode 100644
index 11fc2ef4..00000000
--- a/bindgen-tests/tests/headers/sorted-items.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// bindgen-flags: --sort-semantically -- --target=x86_64-unknown-linux
-
-int foo();
-typedef int number;
-int bar(number x);
-struct Point
-{
- number x;
- number y;
-};
-struct Angle
-{
- number a;
- number b;
-};
-int baz(struct Point point);
-const number NUMBER = 42;
diff --git a/bindgen-tests/tests/headers/sorted_items.hpp b/bindgen-tests/tests/headers/sorted_items.hpp
new file mode 100644
index 00000000..9b5ced96
--- /dev/null
+++ b/bindgen-tests/tests/headers/sorted_items.hpp
@@ -0,0 +1,35 @@
+// bindgen-flags: --sort-semantically --enable-cxx-namespaces -- --target=x86_64-unknown-linux
+
+int foo();
+typedef int number;
+int bar(number x);
+struct Point
+{
+ number x;
+ number y;
+};
+struct Angle
+{
+ number a;
+ number b;
+};
+int baz(struct Point point);
+const number NUMBER = 42;
+
+namespace ns {
+ int foo();
+ typedef int number;
+ int bar(number x);
+ struct Point
+ {
+ number x;
+ number y;
+ };
+ struct Angle
+ {
+ number a;
+ number b;
+ };
+ int baz(struct Point point);
+ const number NUMBER = 42;
+}
diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml
index dca779bd..3965ad4d 100644
--- a/bindgen/Cargo.toml
+++ b/bindgen/Cargo.toml
@@ -45,7 +45,7 @@ lazycell = "1"
lazy_static = "1"
peeking_take_while = "0.1.2"
quote = { version = "1", default-features = false }
-syn = { version = "1.0.99", features = ["full", "extra-traits"]}
+syn = { version = "1.0.99", features = ["full", "extra-traits", "visit-mut"]}
regex = { version = "1.5", default-features = false , features = ["std", "unicode"] }
which = { version = "4.2.1", optional = true, default-features = false }
shlex = "1"
diff --git a/bindgen/codegen/postprocessing/merge_extern_blocks.rs b/bindgen/codegen/postprocessing/merge_extern_blocks.rs
index 2b761494..05e7e9ef 100644
--- a/bindgen/codegen/postprocessing/merge_extern_blocks.rs
+++ b/bindgen/codegen/postprocessing/merge_extern_blocks.rs
@@ -1,46 +1,66 @@
-use syn::{Item, ItemForeignMod};
+use syn::{
+ visit_mut::{visit_item_mod_mut, VisitMut},
+ Item, ItemForeignMod, ItemMod,
+};
-pub(super) fn merge_extern_blocks(items: &mut Vec<Item>) {
- // Keep all the extern blocks in a different `Vec` for faster search.
- let mut foreign_mods = Vec::<ItemForeignMod>::new();
+pub(super) fn merge_extern_blocks(item_mod: &mut ItemMod) {
+ Visitor.visit_item_mod_mut(item_mod)
+}
+
+struct Visitor;
- for item in std::mem::take(items) {
- match item {
- Item::ForeignMod(ItemForeignMod {
- attrs,
- abi,
- brace_token,
- items: foreign_items,
- }) => {
- let mut exists = false;
- for foreign_mod in &mut foreign_mods {
- // Check if there is a extern block with the same ABI and
- // attributes.
- if foreign_mod.attrs == attrs && foreign_mod.abi == abi {
- // Merge the items of the two blocks.
- foreign_mod.items.extend_from_slice(&foreign_items);
- exists = true;
- break;
+impl VisitMut for Visitor {
+ fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) {
+ if let Some((_, ref mut items)) = item_mod.content {
+ // Keep all the extern blocks in a different `Vec` for faster search.
+ let mut extern_blocks = Vec::<ItemForeignMod>::new();
+
+ for item in std::mem::take(items) {
+ if let Item::ForeignMod(ItemForeignMod {
+ attrs,
+ abi,
+ brace_token,
+ items: extern_block_items,
+ }) = item
+ {
+ let mut exists = false;
+ for extern_block in &mut extern_blocks {
+ // Check if there is a extern block with the same ABI and
+ // attributes.
+ if extern_block.attrs == attrs &&
+ extern_block.abi == abi
+ {
+ // Merge the items of the two blocks.
+ extern_block
+ .items
+ .extend_from_slice(&extern_block_items);
+ exists = true;
+ break;
+ }
}
+ // If no existing extern block had the same ABI and attributes, store
+ // it.
+ if !exists {
+ extern_blocks.push(ItemForeignMod {
+ attrs,
+ abi,
+ brace_token,
+ items: extern_block_items,
+ });
+ }
+ } else {
+ // If the item is not an extern block, we don't have to do anything and just
+ // push it back.
+ items.push(item);
}
- // If no existing extern block had the same ABI and attributes, store
- // it.
- if !exists {
- foreign_mods.push(ItemForeignMod {
- attrs,
- abi,
- brace_token,
- items: foreign_items,
- });
- }
}
- // If the item is not an extern block, we don't have to do anything.
- _ => items.push(item),
+
+ // Move all the extern blocks alongside the rest of the items.
+ for extern_block in extern_blocks {
+ items.push(Item::ForeignMod(extern_block));
+ }
}
- }
- // Move all the extern blocks alongside the rest of the items.
- for foreign_mod in foreign_mods {
- items.push(Item::ForeignMod(foreign_mod));
+ visit_item_mod_mut(self, item_mod)
}
}
diff --git a/bindgen/codegen/postprocessing/mod.rs b/bindgen/codegen/postprocessing/mod.rs
index c6612f2b..1d5a4983 100644
--- a/bindgen/codegen/postprocessing/mod.rs
+++ b/bindgen/codegen/postprocessing/mod.rs
@@ -1,6 +1,6 @@
use proc_macro2::TokenStream;
use quote::ToTokens;
-use syn::Item;
+use syn::{parse2, ItemMod};
use crate::BindgenOptions;
@@ -12,7 +12,7 @@ use sort_semantically::sort_semantically;
struct PostProcessingPass {
should_run: fn(&BindgenOptions) -> bool,
- run: fn(&mut Vec<Item>),
+ run: fn(&mut ItemMod),
}
// TODO: This can be a const fn when mutable references are allowed in const
@@ -21,7 +21,7 @@ macro_rules! pass {
($pass:ident) => {
PostProcessingPass {
should_run: |options| options.$pass,
- run: |items| $pass(items),
+ run: |item_mod| $pass(item_mod),
}
};
}
@@ -38,29 +38,29 @@ pub(crate) fn postprocessing(
return items.into_iter().collect();
}
let module_wrapped_tokens =
- quote!(mod wrapper_for_sorting_hack { #( #items )* });
+ quote!(mod wrapper_for_postprocessing_hack { #( #items )* });
// This syn business is a hack, for now. This means that we are re-parsing already
// generated code using `syn` (as opposed to `quote`) because `syn` provides us more
// control over the elements.
// One caveat is that some of the items coming from `quote`d output might have
// multiple items within them. Hence, we have to wrap the incoming in a `mod`.
- // The two `unwrap`s here are deliberate because
- // The first one won't panic because we build the `mod` and know it is there
- // The second one won't panic because we know original output has something in
- // it already.
- let (_, mut items) = syn::parse2::<syn::ItemMod>(module_wrapped_tokens)
- .unwrap()
- .content
- .unwrap();
+ // The `unwrap` here is deliberate because bindgen should generate valid rust items at all
+ // times.
+ let mut item_mod = parse2::<ItemMod>(module_wrapped_tokens).unwrap();
for pass in PASSES {
if (pass.should_run)(options) {
- (pass.run)(&mut items);
+ (pass.run)(&mut item_mod);
}
}
- let synful_items = items.into_iter().map(|item| item.into_token_stream());
+ let synful_items = item_mod
+ .content
+ .map(|(_, items)| items)
+ .unwrap_or_default()
+ .into_iter()
+ .map(|item| item.into_token_stream());
quote! { #( #synful_items )* }
}
diff --git a/bindgen/codegen/postprocessing/sort_semantically.rs b/bindgen/codegen/postprocessing/sort_semantically.rs
index 96596cb0..4f23ab73 100644
--- a/bindgen/codegen/postprocessing/sort_semantically.rs
+++ b/bindgen/codegen/postprocessing/sort_semantically.rs
@@ -1,24 +1,38 @@
-use syn::Item;
+use syn::{
+ visit_mut::{visit_item_mod_mut, VisitMut},
+ Item, ItemMod,
+};
-pub(super) fn sort_semantically(items: &mut [Item]) {
- items.sort_by_key(|item| match item {
- Item::Type(_) => 0,
- Item::Struct(_) => 1,
- Item::Const(_) => 2,
- Item::Fn(_) => 3,
- Item::Enum(_) => 4,
- Item::Union(_) => 5,
- Item::Static(_) => 6,
- Item::Trait(_) => 7,
- Item::TraitAlias(_) => 8,
- Item::Impl(_) => 9,
- Item::Mod(_) => 10,
- Item::Use(_) => 11,
- Item::Verbatim(_) => 12,
- Item::ExternCrate(_) => 13,
- Item::ForeignMod(_) => 14,
- Item::Macro(_) => 15,
- Item::Macro2(_) => 16,
- _ => 18,
- });
+pub(super) fn sort_semantically(item_mod: &mut ItemMod) {
+ Visitor.visit_item_mod_mut(item_mod)
+}
+
+struct Visitor;
+
+impl VisitMut for Visitor {
+ fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) {
+ if let Some((_, ref mut items)) = item_mod.content {
+ items.sort_by_key(|item| match item {
+ Item::Type(_) => 0,
+ Item::Struct(_) => 1,
+ Item::Const(_) => 2,
+ Item::Fn(_) => 3,
+ Item::Enum(_) => 4,
+ Item::Union(_) => 5,
+ Item::Static(_) => 6,
+ Item::Trait(_) => 7,
+ Item::TraitAlias(_) => 8,
+ Item::Impl(_) => 9,
+ Item::Mod(_) => 10,
+ Item::Use(_) => 11,
+ Item::Verbatim(_) => 12,
+ Item::ExternCrate(_) => 13,
+ Item::ForeignMod(_) => 14,
+ Item::Macro(_) => 15,
+ Item::Macro2(_) => 16,
+ _ => 18,
+ });
+ }
+ visit_item_mod_mut(self, item_mod)
+ }
}