diff options
author | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-09-22 17:38:19 +0300 |
---|---|---|
committer | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-09-22 23:42:26 +0300 |
commit | a8663ae36aa7cc1acbe396bfc51863c45d4832c8 (patch) | |
tree | 6009f5f8496cc416073b117bb17321cf935d56f7 /src | |
parent | d386b5ef009d16a591c748b522f7a94202f8e262 (diff) |
Deanonymize fields
Clean.
Add timer.
Clean codegen
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/mod.rs | 30 | ||||
-rw-r--r-- | src/ir/comp.rs | 32 | ||||
-rw-r--r-- | src/ir/context.rs | 14 |
3 files changed, 47 insertions, 29 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index bd6656d7..0da01175 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -865,24 +865,6 @@ impl CodeGenerator for TemplateInstantiation { } } -/// Generates an infinite number of anonymous field names. -struct AnonFieldNames(usize); - -impl Default for AnonFieldNames { - fn default() -> AnonFieldNames { - AnonFieldNames(0) - } -} - -impl Iterator for AnonFieldNames { - type Item = String; - - fn next(&mut self) -> Option<String> { - self.0 += 1; - Some(format!("__bindgen_anon_{}", self.0)) - } -} - /// Trait for implementing the code generation of a struct or union field. trait FieldCodegen<'a> { type Extra; @@ -894,7 +876,6 @@ trait FieldCodegen<'a> { codegen_depth: usize, accessor_kind: FieldAccessorKind, parent: &CompInfo, - anon_field_names: &mut AnonFieldNames, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, @@ -915,7 +896,6 @@ impl<'a> FieldCodegen<'a> for Field { codegen_depth: usize, accessor_kind: FieldAccessorKind, parent: &CompInfo, - anon_field_names: &mut AnonFieldNames, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, @@ -933,7 +913,6 @@ impl<'a> FieldCodegen<'a> for Field { codegen_depth, accessor_kind, parent, - anon_field_names, result, struct_layout, fields, @@ -948,7 +927,6 @@ impl<'a> FieldCodegen<'a> for Field { codegen_depth, accessor_kind, parent, - anon_field_names, result, struct_layout, fields, @@ -970,7 +948,6 @@ impl<'a> FieldCodegen<'a> for FieldData { codegen_depth: usize, accessor_kind: FieldAccessorKind, parent: &CompInfo, - anon_field_names: &mut AnonFieldNames, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, @@ -1030,7 +1007,7 @@ impl<'a> FieldCodegen<'a> for FieldData { let field_name = self.name() .map(|name| ctx.rust_mangle(name).into_owned()) - .unwrap_or_else(|| anon_field_names.next().unwrap()); + .expect("Each field should have a name in codegen!"); let field_ident = ctx.rust_ident_raw(field_name.as_str()); if !parent.is_union() { @@ -1164,7 +1141,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { codegen_depth: usize, accessor_kind: FieldAccessorKind, parent: &CompInfo, - anon_field_names: &mut AnonFieldNames, result: &mut CodegenResult, struct_layout: &mut StructLayoutTracker, fields: &mut F, @@ -1213,7 +1189,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { codegen_depth, accessor_kind, parent, - anon_field_names, result, struct_layout, fields, @@ -1321,7 +1296,6 @@ impl<'a> FieldCodegen<'a> for Bitfield { _codegen_depth: usize, _accessor_kind: FieldAccessorKind, parent: &CompInfo, - _anon_field_names: &mut AnonFieldNames, _result: &mut CodegenResult, _struct_layout: &mut StructLayoutTracker, _fields: &mut F, @@ -1595,7 +1569,6 @@ impl CodeGenerator for CompInfo { let mut methods = vec![]; if !is_opaque { - let mut anon_field_names = AnonFieldNames::default(); let codegen_depth = item.codegen_depth(ctx); let fields_should_be_private = item.annotations().private_fields().unwrap_or(false); @@ -1609,7 +1582,6 @@ impl CodeGenerator for CompInfo { codegen_depth, struct_accessor_kind, self, - &mut anon_field_names, result, &mut struct_layout, &mut fields, diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 4c57a86b..fc17ab8f 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -666,6 +666,33 @@ impl CompFields { CompFields::AfterComputingBitfieldUnits(fields_and_units), ); } + + fn deanonymize_fields(&mut self) { + let fields = match *self { + CompFields::AfterComputingBitfieldUnits(ref mut fields) => { + fields + } + CompFields::BeforeComputingBitfieldUnits(_) => { + panic!("Not yet computed bitfield units."); + } + }; + + let mut anon_field_counter = 0; + for field in fields.iter_mut() { + let field_data = match *field { + Field::DataMember(ref mut fd) => fd, + Field::Bitfields(_) => continue, + }; + + if let Some(_) = field_data.name { + continue; + } + + anon_field_counter += 1; + let name = format!("__bindgen_anon_{}", anon_field_counter); + field_data.name = Some(name); + } + } } impl Trace for CompFields { @@ -1351,6 +1378,11 @@ impl CompInfo { self.fields.compute_bitfield_units(ctx); } + /// Assign for each anonymous field a generated name. + pub fn deanonymize_fields(&mut self) { + self.fields.deanonymize_fields(); + } + /// Returns whether the current union can be represented as a Rust `union` /// /// Requirements: diff --git a/src/ir/context.rs b/src/ir/context.rs index b2c53aac..337e925e 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -799,6 +799,18 @@ impl BindgenContext { } } + /// Assign a new generated name for each anonymous field. + fn deanonymize_fields(&mut self) { + let _t = self.timer("deanonymize_fields"); + let comp_types = self.items + .values_mut() + .filter_map(|item| item.kind_mut().as_type_mut()) + .filter_map(Type::as_comp_mut); + for comp_info in comp_types { + comp_info.deanonymize_fields(); + } + } + /// Iterate over all items and replace any item that has been named in a /// `replaces="SomeType"` annotation with the replacement type. fn process_replacements(&mut self) { @@ -940,6 +952,8 @@ impl BindgenContext { self.compute_bitfield_units(); self.process_replacements(); } + + self.deanonymize_fields(); // And assert once again, because resolving type refs and processing // replacements both mutate the IR graph. |