diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-06-19 14:01:46 -0700 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-06-20 15:35:27 -0700 |
commit | 979f5aae9a078a54aec18d4a6cfe38f34322f534 (patch) | |
tree | e1a7f6ef2a7df6a3835ec7870afe60cdded41a35 /src/codegen/mod.rs | |
parent | 26094eaec30a5b89aac61b541a9cd20a131f861d (diff) |
Ensure that every item is in some module's children list
Previously, if an item's parent was not a module (eg a nested class definition
whose parent it the outer class definition) and the parent was not whitelisted
but the item was transitively whitelisted, then we could generate uses of the
item without emitting any definition for it. This could happen because we were
relying on the outer type calling for code generation on its inner types, but
that relies on us doing code generation for the outer type, which won't happen
if the outer type is not whitelisted.
This commit avoids this gotcha by ensuring that all items end up in a module's
children list, and so will be code generated even if their parent is not
whitelisted.
Fixes #769
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 4f0ea371..73aa17c0 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -435,6 +435,16 @@ impl CodeGenerator for Var { } result.saw_var(&canonical_name); + // We can't generate bindings to static variables of templates. The + // number of actual variables for a single declaration are open ended + // and we don't know what instantiations do or don't exist. + let type_params = item.all_template_params(ctx); + if let Some(params) = type_params { + if !params.is_empty() { + return; + } + } + let ty = self.ty().to_rust_ty_or_opaque(ctx, &()); if let Some(val) = self.val() { @@ -752,6 +762,13 @@ impl CodeGenerator for TemplateInstantiation { return } + // If there are any unbound type parameters, then we can't generate a + // layout test because we aren't dealing with a concrete type with a + // concrete size and alignment. + if ctx.uses_any_template_parameters(item.id()) { + return; + } + let layout = item.kind().expect_type().layout(ctx); if let Some(layout) = layout { @@ -759,8 +776,11 @@ impl CodeGenerator for TemplateInstantiation { let align = layout.align; let name = item.canonical_name(ctx); - let fn_name = format!("__bindgen_test_layout_{}_instantiation_{}", - name, item.exposed_id(ctx)); + let mut fn_name = format!("__bindgen_test_layout_{}_instantiation", name); + let times_seen = result.overload_number(&fn_name); + if times_seen > 0 { + write!(&mut fn_name, "_{}", times_seen).unwrap(); + } let fn_name = ctx.rust_ident_raw(&fn_name); @@ -2920,6 +2940,17 @@ impl CodeGenerator for Function { item: &Item) { debug!("<Function as CodeGenerator>::codegen: item = {:?}", item); + // Similar to static member variables in a class template, we can't + // generate bindings to template functions, because the set of + // instantiations is open ended and we have no way of knowing which + // monomorphizations actually exist. + let type_params = item.all_template_params(ctx); + if let Some(params) = type_params { + if !params.is_empty() { + return; + } + } + let name = self.name(); let mut canonical_name = item.canonical_name(ctx); let mangled_name = self.mangled_name(); |