summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-06-19 14:01:46 -0700
committerNick Fitzgerald <fitzgen@gmail.com>2017-06-20 15:35:27 -0700
commit979f5aae9a078a54aec18d4a6cfe38f34322f534 (patch)
treee1a7f6ef2a7df6a3835ec7870afe60cdded41a35 /src/codegen/mod.rs
parent26094eaec30a5b89aac61b541a9cd20a131f861d (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.rs35
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();