Select builtins lazily during code generation
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 5dcf91c..c690995 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -18,7 +18,7 @@
writeln!(out.include, "#pragma once");
}
- pick_includes_and_builtins(out, apis);
+ pick_includes_and_builtins(out);
out.include.extend(&opt.include);
let apis_by_namespace = NamespaceEntries::new(apis);
@@ -141,7 +141,7 @@
}
}
-fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {
+fn pick_includes_and_builtins(out: &mut OutFile) {
for ty in out.types {
match ty {
Type::Ident(ident) => match Atom::from(&ident.rust) {
@@ -194,50 +194,6 @@
_ => {}
}
}
-
- for api in apis {
- match api {
- Api::CxxFunction(efn) if !out.header => {
- if efn.throws {
- out.builtin.trycatch = true;
- } else if let Some(Type::Str(_)) = efn.ret {
- out.builtin.rust_str_repr = true;
- }
- for arg in &efn.args {
- match arg.ty {
- Type::Str(_) => out.builtin.rust_str_new_unchecked = true,
- Type::RustVec(_) => out.builtin.unsafe_bitcopy = true,
- _ => out.builtin.unsafe_bitcopy |= arg.ty == RustString,
- }
- }
- }
- Api::RustFunction(efn) if !out.header => {
- if efn.throws {
- out.include.exception = true;
- out.include.string = true;
- out.builtin.rust_str = true;
- out.builtin.rust_error = true;
- out.builtin.maybe_uninit = true;
- }
- for arg in &efn.args {
- if arg.ty != RustString && out.types.needs_indirect_abi(&arg.ty) {
- out.builtin.manually_drop = true;
- }
- if let Type::Str(_) = arg.ty {
- out.builtin.rust_str_repr = true;
- }
- }
- if let Some(ret) = &efn.ret {
- if out.types.needs_indirect_abi(ret) {
- out.builtin.maybe_uninit = true;
- } else if let Type::Str(_) = ret {
- out.builtin.rust_str_new_unchecked = true;
- }
- }
- }
- _ => {}
- }
- }
}
fn write_struct(out: &mut OutFile, strct: &Struct) {
@@ -469,6 +425,7 @@
writeln!(out, ";");
write!(out, " ");
if efn.throws {
+ out.builtin.trycatch = true;
writeln!(out, "::rust::repr::PtrLen throw$;");
writeln!(out, " ::rust::behavior::trycatch(");
writeln!(out, " [&] {{");
@@ -484,7 +441,10 @@
}
match &efn.ret {
Some(Type::Ref(_)) => write!(out, "&"),
- Some(Type::Str(_)) if !indirect_return => write!(out, "::rust::impl<::rust::Str>::repr("),
+ Some(Type::Str(_)) if !indirect_return => {
+ out.builtin.rust_str_repr = true;
+ write!(out, "::rust::impl<::rust::Str>::repr(");
+ }
Some(Type::SliceRefU8(_)) if !indirect_return => {
write!(out, "::rust::Slice<uint8_t>::Repr(")
}
@@ -505,18 +465,21 @@
write_type(out, &arg.ty);
write!(out, "({})", arg.ident);
} else if let Type::Str(_) = arg.ty {
+ out.builtin.rust_str_new_unchecked = true;
write!(
out,
"::rust::impl<::rust::Str>::new_unchecked({})",
arg.ident,
);
} else if arg.ty == RustString {
+ out.builtin.unsafe_bitcopy = true;
write!(
out,
"::rust::String(::rust::unsafe_bitcopy, *{})",
arg.ident,
);
} else if let Type::RustVec(_) = arg.ty {
+ out.builtin.unsafe_bitcopy = true;
write_type(out, &arg.ty);
write!(out, "(::rust::unsafe_bitcopy, *{})", arg.ident);
} else if out.types.needs_indirect_abi(&arg.ty) {
@@ -698,6 +661,7 @@
for arg in &sig.args {
if arg.ty != RustString && out.types.needs_indirect_abi(&arg.ty) {
out.include.utility = true;
+ out.builtin.manually_drop = true;
write!(out, " ::rust::ManuallyDrop<");
write_type(out, &arg.ty);
writeln!(out, "> {}$(::std::move({0}));", arg.ident);
@@ -706,6 +670,7 @@
write!(out, " ");
let indirect_return = indirect_return(sig, out.types);
if indirect_return {
+ out.builtin.maybe_uninit = true;
write!(out, "::rust::MaybeUninit<");
write_type(out, sig.ret.as_ref().unwrap());
writeln!(out, "> return$;");
@@ -722,7 +687,10 @@
write!(out, "(");
}
Type::Ref(_) => write!(out, "*"),
- Type::Str(_) => write!(out, "::rust::impl<::rust::Str>::new_unchecked("),
+ Type::Str(_) => {
+ out.builtin.rust_str_new_unchecked = true;
+ write!(out, "::rust::impl<::rust::Str>::new_unchecked(");
+ }
_ => {}
}
}
@@ -738,7 +706,10 @@
write!(out, ", ");
}
match &arg.ty {
- Type::Str(_) => write!(out, "::rust::impl<::rust::Str>::repr("),
+ Type::Str(_) => {
+ out.builtin.rust_str_repr = true;
+ write!(out, "::rust::impl<::rust::Str>::repr(");
+ }
Type::SliceRefU8(_) => write!(out, "::rust::Slice<uint8_t>::Repr("),
ty if out.types.needs_indirect_abi(ty) => write!(out, "&"),
_ => {}
@@ -774,6 +745,8 @@
}
writeln!(out, ";");
if sig.throws {
+ out.include.exception = true;
+ out.builtin.rust_error = true;
writeln!(out, " if (error$.ptr) {{");
writeln!(out, " throw ::rust::impl<::rust::Error>::error(error$);");
writeln!(out, " }}");