summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/chooser.rs2
-rw-r--r--libbindgen/src/codegen/mod.rs25
-rw-r--r--libbindgen/src/ir/annotations.rs7
-rw-r--r--libbindgen/src/ir/enum_ty.rs2
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()