summaryrefslogtreecommitdiff
path: root/libbindgen
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-01-10 13:32:44 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-01-11 12:05:38 +0100
commitd5cd85d1a1ab2368a3dc8443ee5969e66aabc8ad (patch)
treef1603784da34cfa9d53cdf82950c0a7afb3af270 /libbindgen
parent4663ae9d7187fb4c7420bca8fedc6acdf0cea39d (diff)
codegen: Constify enum variants.
Diffstat (limited to 'libbindgen')
-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
-rw-r--r--libbindgen/tests/expectations/tests/constify-enum.rs22
-rw-r--r--libbindgen/tests/headers/constify-enum.h13
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> */
+};