summaryrefslogtreecommitdiff
path: root/libbindgen/src/codegen/mod.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-01-11 03:07:26 -0800
committerGitHub <noreply@github.com>2017-01-11 03:07:26 -0800
commit6bfeae155155a12849033e1c5199ca6e48e8b22c (patch)
tree4b1a0e42b32238565eb3ab61e67623e13459a06f /libbindgen/src/codegen/mod.rs
parentdf043bf3dcc11bfd5c22cee5d3c6ba04d41c5f00 (diff)
parentfee7e96875f1d7c805a09e8ec8e02988de25e370 (diff)
Auto merge of #393 - emilio:enum-const-api, r=upsuper
Provide an API to constify enum variants. r? @upsuper
Diffstat (limited to 'libbindgen/src/codegen/mod.rs')
-rw-r--r--libbindgen/src/codegen/mod.rs28
1 files changed, 22 insertions, 6 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index c6d5fd39..6e63a791 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;
@@ -1671,7 +1670,22 @@ 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.hidden() {
+ continue;
+ }
+
+ 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 {
@@ -1711,9 +1725,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 {