summaryrefslogtreecommitdiff
path: root/libbindgen/src/codegen/mod.rs
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/src/codegen/mod.rs
parent4663ae9d7187fb4c7420bca8fedc6acdf0cea39d (diff)
codegen: Constify enum variants.
Diffstat (limited to 'libbindgen/src/codegen/mod.rs')
-rw-r--r--libbindgen/src/codegen/mod.rs25
1 files changed, 19 insertions, 6 deletions
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 {