diff options
author | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-09-19 22:42:22 +0300 |
---|---|---|
committer | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-09-19 22:42:22 +0300 |
commit | 40295d2c448725d940525d81ab04cbc1db0b94f7 (patch) | |
tree | a8e95c6b5d628da58fee91afa375f8a3ff2bf040 | |
parent | 1906a264c1d3b4620d803dd4030750f981b42978 (diff) |
Derive Ord when possible
-rw-r--r-- | src/codegen/mod.rs | 8 | ||||
-rw-r--r-- | src/ir/context.rs | 12 | ||||
-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 | 7 |
6 files changed, 70 insertions, 7 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..1e759b78 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 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..47b8feb2 100644 --- a/src/options.rs +++ b/src/options.rs @@ -89,6 +89,9 @@ where Arg::with_name("with-derive-eq") .long("with-derive-eq") .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"), Arg::with_name("no-doc-comments") .long("no-doc-comments") .help("Avoid including doc comments in the output, see: \ @@ -351,6 +354,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); } |