diff options
-rw-r--r-- | src/codegen/mod.rs | 8 | ||||
-rw-r--r-- | src/ir/context.rs | 14 | ||||
-rw-r--r-- | src/ir/derive.rs | 15 | ||||
-rw-r--r-- | src/ir/item.rs | 12 | ||||
-rw-r--r-- | src/lib.rs | 23 | ||||
-rw-r--r-- | src/options.rs | 11 | ||||
-rw-r--r-- | tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs | 2 | ||||
-rw-r--r-- | tests/expectations/tests/derive-hash-struct-with-float-array.rs | 2 | ||||
-rw-r--r-- | tests/expectations/tests/derive-hash-struct-with-pointer.rs | 10 | ||||
-rw-r--r-- | tests/expectations/tests/derive-hash-template-def-float.rs | 2 | ||||
-rw-r--r-- | tests/expectations/tests/derive-hash-template-inst-float.rs | 10 | ||||
-rw-r--r-- | tests/headers/derive-hash-blacklisting.hpp | 2 | ||||
-rw-r--r-- | tests/headers/derive-hash-struct-with-anon-struct-float.h | 4 | ||||
-rw-r--r-- | tests/headers/derive-hash-struct-with-float-array.h | 4 | ||||
-rw-r--r-- | tests/headers/derive-hash-struct-with-pointer.h | 4 | ||||
-rw-r--r-- | tests/headers/derive-hash-template-def-float.hpp | 4 | ||||
-rw-r--r-- | tests/headers/derive-hash-template-inst-float.hpp | 8 |
17 files changed, 100 insertions, 35 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 810f1367..ad4f65f4 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -12,8 +12,8 @@ use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field, FieldData, FieldMethods, Method, MethodKind}; use ir::context::{BindgenContext, ItemId}; use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, - CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq, - CanDeriveEq}; + CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, + CanDerivePartialEq, CanDeriveEq}; use ir::dot; use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; use ir::function::{Abi, Function, FunctionSig}; @@ -1494,6 +1494,10 @@ impl CodeGenerator for CompInfo { derives.push("PartialOrd"); } + if item.can_derive_ord(ctx) { + derives.push("Ord"); + } + if item.can_derive_partialeq(ctx) { derives.push("PartialEq"); } diff --git a/src/ir/context.rs b/src/ir/context.rs index 513cc665..799c2e7d 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -6,8 +6,8 @@ use super::analysis::{CannotDeriveCopy, CannotDeriveDebug, HasVtableAnalysis, HasDestructorAnalysis, UsedTemplateParameters, HasFloat, analyze}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, - CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq, - CanDeriveEq}; + CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, + CanDerivePartialEq, CanDeriveEq}; use super::int::IntKind; use super::item::{HasTypeParamInArray, IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet}; @@ -91,6 +91,14 @@ impl CanDeriveEq for ItemId { } } +impl CanDeriveOrd for ItemId { + fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { + ctx.options().derive_ord && + ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) && + !ctx.lookup_item_id_has_float(&self) + } +} + /// A key used to index a resolved type, so we only process it once. /// /// This is almost always a USR string (an unique identifier generated by @@ -2191,7 +2199,7 @@ impl BindgenContext { fn compute_has_float(&mut self) { let _t = self.timer("compute_has_float"); assert!(self.has_float.is_none()); - if self.options.derive_eq { + if self.options.derive_eq || self.options.derive_ord { self.has_float = Some(analyze::<HasFloat>(self)); } } diff --git a/src/ir/derive.rs b/src/ir/derive.rs index 0d6b2875..f518152a 100644 --- a/src/ir/derive.rs +++ b/src/ir/derive.rs @@ -97,7 +97,7 @@ pub trait CanDerivePartialEq { /// /// This should ideally be a no-op that just returns `true`, but instead needs /// to be a recursive method that checks whether all the proper members can -/// derive default or not, because of the limit rust has on 32 items as max in the +/// derive partial ord or not, because of the limit rust has on 32 items as max in the /// array. pub trait CanDerivePartialOrd { /// Return `true` if `PartialOrd` can be derived for this thing, `false` @@ -121,6 +121,19 @@ pub trait CanDeriveEq { -> bool; } +/// A trait that encapsulates the logic for whether or not we can derive `Ord` +/// for a given thing. +/// +/// This should ideally be a no-op that just returns `true`, but instead needs +/// to be a recursive method that checks whether all the proper members can +/// derive ord or not, because of the limit rust has on 32 items as max in the +/// array. +pub trait CanDeriveOrd { + /// Return `true` if `Ord` can be derived for this thing, `false` + /// otherwise. + fn can_derive_ord(&self, ctx: &BindgenContext) -> bool; +} + /// A trait that encapsulates the logic for whether or not we can derive `Hash`. /// The difference between this trait and the CanDeriveHash is that the type /// implementing this trait cannot use recursion or lookup result from fix point diff --git a/src/ir/item.rs b/src/ir/item.rs index dbc215cf..8a5a143b 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -6,8 +6,8 @@ use super::comment; use super::comp::MethodKind; use super::context::{BindgenContext, ItemId, PartialType}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, - CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq, - CanDeriveEq}; + CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, + CanDerivePartialEq, CanDeriveEq}; use super::dot::DotAttributes; use super::function::{Function, FunctionKind}; use super::item_kind::ItemKind; @@ -353,6 +353,14 @@ impl CanDeriveEq for Item { } } +impl CanDeriveOrd for Item { + fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { + ctx.options().derive_ord && + ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) && + !ctx.lookup_item_id_has_float(&self.id()) + } +} + /// An item is the base of the bindgen representation, it can be either a /// module, a type, a function, or a variable (see `ItemKind` for more /// information). @@ -265,6 +265,10 @@ impl Builder { output_vector.push("--with-derive-partialord".into()); } + if self.options.derive_ord { + output_vector.push("--with-derive-ord".into()); + } + if self.options.derive_partialeq { output_vector.push("--with-derive-partialeq".into()); } @@ -819,8 +823,22 @@ impl Builder { } /// Set whether `PartialOrd` should be derived by default. + /// If we don't compute partialord, we also cannot compute + /// ord. Set the derive_ord to `false` when doit is `false`. pub fn derive_partialord(mut self, doit: bool) -> Self { self.options.derive_partialord = doit; + if !doit { + self.options.derive_ord = false; + } + self + } + + /// Set whether `Ord` should be derived by default. + /// We can't compute `Ord` without computing `PartialOrd`, + /// so we set the same option to derive_partialord. + pub fn derive_ord(mut self, doit: bool) -> Self { + self.options.derive_ord = doit; + self.options.derive_partialord = doit; self } @@ -1190,6 +1208,10 @@ struct BindgenOptions { /// and types. derive_partialord: bool, + /// True if we should derive Ord trait implementations for C/C++ structures + /// and types. + derive_ord: bool, + /// True if we should derive PartialEq trait implementations for C/C++ structures /// and types. derive_partialeq: bool, @@ -1340,6 +1362,7 @@ impl Default for BindgenOptions { derive_default: false, derive_hash: false, derive_partialord: false, + derive_ord: false, derive_partialeq: false, derive_eq: false, enable_cxx_namespaces: false, diff --git a/src/options.rs b/src/options.rs index b3182270..6f5ad6c8 100644 --- a/src/options.rs +++ b/src/options.rs @@ -88,7 +88,12 @@ where .help("Derive partialord on any type."), Arg::with_name("with-derive-eq") .long("with-derive-eq") - .help("Derive eq on any type. Enable this option also enables --with-derive-partialeq"), + .help("Derive eq on any type. Enable this option also \ + enables --with-derive-partialeq"), + Arg::with_name("with-derive-ord") + .long("with-derive-ord") + .help("Derive ord on any type. Enable this option also \ + enables --with-derive-partialord"), Arg::with_name("no-doc-comments") .long("no-doc-comments") .help("Avoid including doc comments in the output, see: \ @@ -351,6 +356,10 @@ where builder = builder.derive_eq(true); } + if matches.is_present("with-derive-ord") { + builder = builder.derive_ord(true); + } + if matches.is_present("no-derive-default") { builder = builder.derive_default(false); } diff --git a/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs b/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs index da1d2b41..6436b69a 100644 --- a/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs +++ b/tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs @@ -5,7 +5,7 @@ -/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partialeq and partialord +/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd #[repr(C)] #[derive(Debug, Default, Copy, PartialOrd, PartialEq)] pub struct foo { diff --git a/tests/expectations/tests/derive-hash-struct-with-float-array.rs b/tests/expectations/tests/derive-hash-struct-with-float-array.rs index a14a0829..dd9acc6a 100644 --- a/tests/expectations/tests/derive-hash-struct-with-float-array.rs +++ b/tests/expectations/tests/derive-hash-struct-with-float-array.rs @@ -5,7 +5,7 @@ -/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq and partialord +/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd #[repr(C)] #[derive(Debug, Default, Copy, PartialOrd, PartialEq)] pub struct foo { diff --git a/tests/expectations/tests/derive-hash-struct-with-pointer.rs b/tests/expectations/tests/derive-hash-struct-with-pointer.rs index 664a19da..b2ae7ab2 100644 --- a/tests/expectations/tests/derive-hash-struct-with-pointer.rs +++ b/tests/expectations/tests/derive-hash-struct-with-pointer.rs @@ -5,9 +5,9 @@ -/// Pointers can derive Hash/PartialOrd/PartialEq/Eq +/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq #[repr(C)] -#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct ConstPtrMutObj { pub bar: *const ::std::os::raw::c_int, } @@ -45,7 +45,7 @@ impl Default for ConstPtrMutObj { } } #[repr(C)] -#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct MutPtrMutObj { pub bar: *mut ::std::os::raw::c_int, } @@ -83,7 +83,7 @@ impl Default for MutPtrMutObj { } } #[repr(C)] -#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct MutPtrConstObj { pub bar: *const ::std::os::raw::c_int, } @@ -121,7 +121,7 @@ impl Default for MutPtrConstObj { } } #[repr(C)] -#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct ConstPtrConstObj { pub bar: *const ::std::os::raw::c_int, } diff --git a/tests/expectations/tests/derive-hash-template-def-float.rs b/tests/expectations/tests/derive-hash-template-def-float.rs index d882f99d..853d77af 100644 --- a/tests/expectations/tests/derive-hash-template-def-float.rs +++ b/tests/expectations/tests/derive-hash-template-def-float.rs @@ -5,7 +5,7 @@ -/// Template definition containing a float, which cannot derive hash/eq but can derive partialeq and partialord. +/// Template definition containing a float, which cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd. #[repr(C)] #[derive(Debug, Copy, Clone, PartialOrd, PartialEq)] pub struct foo<T> { diff --git a/tests/expectations/tests/derive-hash-template-inst-float.rs b/tests/expectations/tests/derive-hash-template-inst-float.rs index 7f79af3e..6473beba 100644 --- a/tests/expectations/tests/derive-hash-template-inst-float.rs +++ b/tests/expectations/tests/derive-hash-template-inst-float.rs @@ -5,9 +5,9 @@ -/// Template definition that doesn't contain float can derive hash/partialord/partialeq/eq +/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq #[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct foo<T> { pub data: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>, @@ -17,9 +17,9 @@ impl<T> Default for foo<T> { unsafe { ::std::mem::zeroed() } } } -/// Can derive hash/partialeq/eq when instantiated with int +/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int #[repr(C)] -#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct IntStr { pub a: foo<::std::os::raw::c_int>, } @@ -56,7 +56,7 @@ impl Default for IntStr { unsafe { ::std::mem::zeroed() } } } -/// Cannot derive hash/eq when instantiated with float but can derive partialeq +/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd #[repr(C)] #[derive(Debug, Copy, PartialOrd, PartialEq)] pub struct FloatStr { diff --git a/tests/headers/derive-hash-blacklisting.hpp b/tests/headers/derive-hash-blacklisting.hpp index 94a9f783..e3256a01 100644 --- a/tests/headers/derive-hash-blacklisting.hpp +++ b/tests/headers/derive-hash-blacklisting.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq --whitelist-type 'Whitelisted.*' --blacklist-type Blacklisted --raw-line "#[repr(C)] #[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] pub struct Blacklisted<T> {t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>> }" +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq --whitelist-type 'Whitelisted.*' --blacklist-type Blacklisted --raw-line "#[repr(C)] #[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] pub struct Blacklisted<T> {t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>> }" // template <class T> struct Blacklisted { diff --git a/tests/headers/derive-hash-struct-with-anon-struct-float.h b/tests/headers/derive-hash-struct-with-anon-struct-float.h index f96b9449..dc6e7329 100644 --- a/tests/headers/derive-hash-struct-with-anon-struct-float.h +++ b/tests/headers/derive-hash-struct-with-anon-struct-float.h @@ -1,6 +1,6 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq // -/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partialeq and partialord +/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd struct foo { struct { float a; diff --git a/tests/headers/derive-hash-struct-with-float-array.h b/tests/headers/derive-hash-struct-with-float-array.h index 937217a0..2294b1de 100644 --- a/tests/headers/derive-hash-struct-with-float-array.h +++ b/tests/headers/derive-hash-struct-with-float-array.h @@ -1,6 +1,6 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq // -/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq and partialord +/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd struct foo { float bar[3]; }; diff --git a/tests/headers/derive-hash-struct-with-pointer.h b/tests/headers/derive-hash-struct-with-pointer.h index 9c8ba0f9..a3ce9cc5 100644 --- a/tests/headers/derive-hash-struct-with-pointer.h +++ b/tests/headers/derive-hash-struct-with-pointer.h @@ -1,6 +1,6 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq // -/// Pointers can derive Hash/PartialOrd/PartialEq/Eq +/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq struct ConstPtrMutObj { int* const bar; }; diff --git a/tests/headers/derive-hash-template-def-float.hpp b/tests/headers/derive-hash-template-def-float.hpp index 2dbe5409..253fb9ce 100644 --- a/tests/headers/derive-hash-template-def-float.hpp +++ b/tests/headers/derive-hash-template-def-float.hpp @@ -1,6 +1,6 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq // -/// Template definition containing a float, which cannot derive hash/eq but can derive partialeq and partialord. +/// Template definition containing a float, which cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd. template <typename T> struct foo { T data; diff --git a/tests/headers/derive-hash-template-inst-float.hpp b/tests/headers/derive-hash-template-inst-float.hpp index d189ba71..0a4fc0c1 100644 --- a/tests/headers/derive-hash-template-inst-float.hpp +++ b/tests/headers/derive-hash-template-inst-float.hpp @@ -1,17 +1,17 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq +// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq // -/// Template definition that doesn't contain float can derive hash/partialord/partialeq/eq +/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq template <typename T> struct foo { T data; }; -/// Can derive hash/partialeq/eq when instantiated with int +/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int struct IntStr { foo<int> a; }; -/// Cannot derive hash/eq when instantiated with float but can derive partialeq +/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd struct FloatStr { foo<float> a; }; |