diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-10 13:32:44 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-11 12:05:38 +0100 |
commit | d5cd85d1a1ab2368a3dc8443ee5969e66aabc8ad (patch) | |
tree | f1603784da34cfa9d53cdf82950c0a7afb3af270 /libbindgen | |
parent | 4663ae9d7187fb4c7420bca8fedc6acdf0cea39d (diff) |
codegen: Constify enum variants.
Diffstat (limited to 'libbindgen')
-rw-r--r-- | libbindgen/src/chooser.rs | 2 | ||||
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 25 | ||||
-rw-r--r-- | libbindgen/src/ir/annotations.rs | 7 | ||||
-rw-r--r-- | libbindgen/src/ir/enum_ty.rs | 2 | ||||
-rw-r--r-- | libbindgen/tests/expectations/tests/constify-enum.rs | 22 | ||||
-rw-r--r-- | libbindgen/tests/headers/constify-enum.h | 13 |
6 files changed, 62 insertions, 9 deletions
diff --git a/libbindgen/src/chooser.rs b/libbindgen/src/chooser.rs index f28b32f1..660f423c 100644 --- a/libbindgen/src/chooser.rs +++ b/libbindgen/src/chooser.rs @@ -19,7 +19,7 @@ pub trait TypeChooser: fmt::Debug { fn constify_enum_variant(&self, _enum_name: Option<&str>, _variant_name: &str, - _variant_value: Option<EnumVariantValue>) -> bool { + _variant_value: EnumVariantValue) -> bool { false } } diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 24b862be..e4dbbd8f 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -1,6 +1,5 @@ mod helpers; - use aster; use ir::annotations::FieldAccessorKind; @@ -21,7 +20,7 @@ use self::helpers::{BlobTyBuilder, attributes}; use std::borrow::Cow; use std::cell::Cell; -use std::collections::HashSet; +use std::collections::{HashSet, VecDeque}; use std::collections::hash_map::{Entry, HashMap}; use std::fmt::Write; use std::iter; @@ -1667,7 +1666,19 @@ impl CodeGenerator for Enum { Some(&name) }; - for variant in self.variants().iter() { + // NB: We defer the creation of constified variants, in case we find + // another variant with the same value (which is the common thing to + // do). + let mut constified_variants = VecDeque::new(); + + let mut iter = self.variants().iter().peekable(); + while let Some(variant) = iter.next().or_else(|| constified_variants.pop_front()) { + + if variant.force_constification() && iter.peek().is_some() { + constified_variants.push_back(variant); + continue; + } + match seen_values.entry(variant.val()) { Entry::Occupied(ref entry) => { if is_rust_enum { @@ -1707,9 +1718,11 @@ impl CodeGenerator for Enum { let variant_name = ctx.rust_mangle(variant.name()); - // If it's an unnamed enum, we also generate a constant so - // it can be properly accessed. - if is_rust_enum && enum_ty.name().is_none() { + // If it's an unnamed enum, or constification is enforced, + // we also generate a constant so it can be properly + // accessed. + if (is_rust_enum && enum_ty.name().is_none()) || + variant.force_constification() { let mangled_name = if is_toplevel { variant_name.clone() } else { diff --git a/libbindgen/src/ir/annotations.rs b/libbindgen/src/ir/annotations.rs index 70f66051..6ae350cb 100644 --- a/libbindgen/src/ir/annotations.rs +++ b/libbindgen/src/ir/annotations.rs @@ -45,13 +45,18 @@ pub struct Annotations { /// /// ```cpp /// enum Foo { - /// Bar = 0, //< <div rustbindgen constant></div> + /// Bar = 0, /**< <div rustbindgen constant></div> */ /// Baz = 0, /// }; /// ``` /// /// In that case, bindgen will generate a constant for `Bar` instead of /// `Baz`. + /// + /// You can see the kind of comments that are accepted in the Doxygen + /// documentation: + /// + /// http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html constify_enum_variant: bool, } diff --git a/libbindgen/src/ir/enum_ty.rs b/libbindgen/src/ir/enum_ty.rs index 0c20b266..7d6d1a6e 100644 --- a/libbindgen/src/ir/enum_ty.rs +++ b/libbindgen/src/ir/enum_ty.rs @@ -82,7 +82,7 @@ impl Enum { let name = cursor.spelling(); let should_constify = ctx.type_chooser() .map_or(false, |c| { - c.constify_enum_variant(type_name, &name, value) + c.constify_enum_variant(type_name, &name, val) }) || Annotations::new(&cursor).map_or(false, |anno| { anno.constify_enum_variant() diff --git a/libbindgen/tests/expectations/tests/constify-enum.rs b/libbindgen/tests/expectations/tests/constify-enum.rs new file mode 100644 index 00000000..356aaa05 --- /dev/null +++ b/libbindgen/tests/expectations/tests/constify-enum.rs @@ -0,0 +1,22 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue: + nsCSSPropertyID = + nsCSSPropertyID::eCSSProperty_COUNT_unexistingVariantValue; +pub const nsCSSPropertyID_eCSSProperty_COUNT: nsCSSPropertyID = + nsCSSPropertyID::eCSSPropertyAlias_aa; +pub const nsCSSPropertyID_eCSSProperty_COUNT_DUMMY2: nsCSSPropertyID = + nsCSSPropertyID::eCSSProperty_b; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum nsCSSPropertyID { + eCSSProperty_a = 0, + eCSSProperty_b = 1, + eCSSPropertyAlias_aa = 2, + eCSSPropertyAlias_bb = 3, + eCSSProperty_COUNT_unexistingVariantValue = 4, +} diff --git a/libbindgen/tests/headers/constify-enum.h b/libbindgen/tests/headers/constify-enum.h new file mode 100644 index 00000000..f2771e59 --- /dev/null +++ b/libbindgen/tests/headers/constify-enum.h @@ -0,0 +1,13 @@ + +enum nsCSSPropertyID { + eCSSProperty_a, + eCSSProperty_b, + + eCSSProperty_COUNT, /**< <div rustbindgen constant></div> */ + eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1, /**< <div rustbindgen constant></div> */ + + eCSSPropertyAlias_aa, + eCSSPropertyAlias_bb, + + eCSSProperty_COUNT_unexistingVariantValue, /**< <div rustbindgen constant></div> */ +}; |