diff options
Diffstat (limited to 'libbindgen/src')
-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 |
4 files changed, 27 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() |