From eec4ae1ce2438e2f82773b1f4d199072cb2214e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 4 Mar 2018 14:01:13 +0100 Subject: [PATCH 1/3] codegen: Avoid &String. --- src/codegen/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index b21c0dc447..1801520ad8 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2228,7 +2228,7 @@ impl<'a> EnumBuilder<'a> { self, ctx: &BindgenContext, variant: &EnumVariant, - mangling_prefix: Option<&String>, + mangling_prefix: Option<&str>, rust_ty: quote::Tokens, result: &mut CodegenResult<'b>, ) -> Self { @@ -2548,9 +2548,9 @@ impl CodeGenerator for Enum { let constant_mangling_prefix = if ctx.options().prepend_enum_name { if enum_ty.name().is_none() { - parent_canonical_name.as_ref().map(|n| &*n) + parent_canonical_name.as_ref().map(|n| &**n) } else { - Some(&name) + Some(&*name) } } else { None From 27641c23c6ad6f0c9e51494a2afdf5245c7090d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 4 Mar 2018 14:22:04 +0100 Subject: [PATCH 2/3] ir: Allow replacing enums. --- src/ir/context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index 0a9145235f..d1bb814218 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1062,6 +1062,7 @@ impl BindgenContext { match *ty.kind() { TypeKind::Comp(..) | TypeKind::TemplateAlias(..) | + TypeKind::Enum(..) | TypeKind::Alias(..) => {} _ => continue, } @@ -2065,7 +2066,7 @@ impl BindgenContext { /// Has the item with the given `name` and `id` been replaced by another /// type? - pub fn is_replaced_type>(&self, path: &[String], id: Id) -> bool { + fn is_replaced_type>(&self, path: &[String], id: Id) -> bool { let id = id.into(); match self.replacements.get(path) { Some(replaced_by) if *replaced_by != id => true, From 4c6c9977c8ce93a5753d28278a3eb7571aaddef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 4 Mar 2018 14:23:21 +0100 Subject: [PATCH 3/3] ir: Allow renaming variants using the replaces="" annotation or a custom callback. --- src/callbacks.rs | 15 ++++++-- src/ir/enum_ty.rs | 33 +++++++++++------- .../tests/enum-variant-replaces.rs | 14 ++++++++ tests/headers/enum-variant-replaces.h | 34 +++++++++++++++++++ 4 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 tests/expectations/tests/enum-variant-replaces.rs create mode 100644 tests/headers/enum-variant-replaces.h diff --git a/src/callbacks.rs b/src/callbacks.rs index 469314c4ce..f6935a554b 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -36,14 +36,23 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { } /// This function should return whether, given the a given enum variant - /// name, and value, returns whether this enum variant will forcibly be a - /// constant. + /// name, and value, this enum variant will forcibly be a constant. fn enum_variant_behavior( &self, _enum_name: Option<&str>, - _variant_name: &str, + _original_variant_name: &str, _variant_value: EnumVariantValue, ) -> Option { None } + + /// Allows to rename an enum variant, replacing `_original_variant_name`. + fn enum_variant_name( + &self, + _enum_name: Option<&str>, + _original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + None + } } diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index bc8e37ebb1..4ae311e21f 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -98,22 +98,31 @@ impl Enum { }; if let Some(val) = value { let name = cursor.spelling(); + let annotations = Annotations::new(&cursor); let custom_behavior = ctx.parse_callbacks() - .and_then( - |t| t.enum_variant_behavior(type_name, &name, val), - ) + .and_then(|callbacks| { + callbacks.enum_variant_behavior(type_name, &name, val) + }) .or_else(|| { - Annotations::new(&cursor).and_then( - |anno| if anno.hide() { - Some(EnumVariantCustomBehavior::Hide) - } else if anno.constify_enum_variant() { - Some(EnumVariantCustomBehavior::Constify) - } else { - None - }, - ) + let annotations = annotations.as_ref()?; + if annotations.hide() { + Some(EnumVariantCustomBehavior::Hide) + } else if annotations.constify_enum_variant() { + Some(EnumVariantCustomBehavior::Constify) + } else { + None + } }); + let name = ctx.parse_callbacks() + .and_then(|callbacks| { + callbacks.enum_variant_name(type_name, &name, val) + }) + .or_else(|| { + annotations.as_ref()?.use_instead_of()?.last().cloned() + }) + .unwrap_or(name); + let comment = cursor.raw_comment(); variants.push(EnumVariant::new( name, diff --git a/tests/expectations/tests/enum-variant-replaces.rs b/tests/expectations/tests/enum-variant-replaces.rs new file mode 100644 index 0000000000..aabcad753f --- /dev/null +++ b/tests/expectations/tests/enum-variant-replaces.rs @@ -0,0 +1,14 @@ +/* automatically generated by rust-bindgen */ + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + +///
+/// +/// Should see PASS below. +pub const OGRErr_PASS: OGRErr = 0; +///
+/// +/// Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below. +pub const OGRErr_OGRERR_NONE: OGRErr = 1; +///
+pub type OGRErr = u32; diff --git a/tests/headers/enum-variant-replaces.h b/tests/headers/enum-variant-replaces.h new file mode 100644 index 0000000000..45eb4d7a54 --- /dev/null +++ b/tests/headers/enum-variant-replaces.h @@ -0,0 +1,34 @@ + +/** Type for a OGR error */ +typedef enum +{ + OGRERR_NONE, /**< Success */ + OGRERR_NOT_ENOUGH_DATA, /**< Not enough data to deserialize */ + OGRERR_NOT_ENOUGH_MEMORY, /**< Not enough memory */ + OGRERR_UNSUPPORTED_GEOMETRY_TYPE, /**< Unsupported geometry type */ + OGRERR_UNSUPPORTED_OPERATION, /**< Unsupported operation */ + OGRERR_CORRUPT_DATA, /**< Corrupt data */ + OGRERR_FAILURE, /**< Failure */ + OGRERR_UNSUPPORTED_SRS, /**< Unsupported SRS */ + OGRERR_INVALID_HANDLE, /**< Invalid handle */ + OGRERR_NON_EXISTING_FEATURE /**< Non existing feature. Added in GDAL 2.0 */ +} OGRErr; + +/** + *
+ */ +typedef enum +{ + /** + *
+ * + * Should see PASS below. + */ + FAIL, + /** + *
+ * + * Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below. + */ + CUSTOM_OGRERR_NONE +} StrictOGRErr;