diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-10 13:32:44 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-01-11 12:05:38 +0100 |
commit | d5cd85d1a1ab2368a3dc8443ee5969e66aabc8ad (patch) | |
tree | f1603784da34cfa9d53cdf82950c0a7afb3af270 /libbindgen/src/codegen/mod.rs | |
parent | 4663ae9d7187fb4c7420bca8fedc6acdf0cea39d (diff) |
codegen: Constify enum variants.
Diffstat (limited to 'libbindgen/src/codegen/mod.rs')
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 25 |
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 { |