diff --git a/engine/src/lib.rs b/engine/src/lib.rs
new file mode 100644
index 0000000..4edc4a4
--- /dev/null
+++ b/engine/src/lib.rs
@@ -0,0 +1,735 @@
+//! The core of the `autocxx` engine, used by both the
+//! `autocxx_macro` and also code generators (e.g. `autocxx_build`).
+//! See [IncludeCppEngine] for general description of how this engine works.
+
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This feature=nightly could be set by build.rs, but since we only care
+// about it for docs, we ask docs.rs to set it in the Cargo.toml.
+#![cfg_attr(feature = "nightly", feature(doc_cfg))]
+#![forbid(unsafe_code)]
+
+mod ast_discoverer;
+mod conversion;
+mod cxxbridge;
+mod known_types;
+mod output_generators;
+mod parse_callbacks;
+mod parse_file;
+mod rust_pretty_printer;
+mod types;
+
+#[cfg(any(test, feature = "build"))]
+mod builder;
+
+use autocxx_parser::{IncludeCppConfig, UnsafePolicy};
+use conversion::BridgeConverter;
+use miette::{SourceOffset, SourceSpan};
+use parse_callbacks::AutocxxParseCallbacks;
+use parse_file::CppBuildable;
+use proc_macro2::TokenStream as TokenStream2;
+use regex::Regex;
+use std::path::PathBuf;
+use std::{
+    fs::File,
+    io::prelude::*,
+    path::Path,
+    process::{Command, Stdio},
+};
+use tempfile::NamedTempFile;
+
+use quote::ToTokens;
+use syn::Result as ParseResult;
+use syn::{
+    parse::{Parse, ParseStream},
+    parse_quote, ItemMod, Macro,
+};
+use thiserror::Error;
+
+use itertools::{join, Itertools};
+use known_types::known_types;
+use log::info;
+use miette::Diagnostic;
+
+/// We use a forked version of bindgen - for now.
+/// We hope to unfork.
+use autocxx_bindgen as bindgen;
+
+#[cfg(any(test, feature = "build"))]
+pub use builder::{
+    Builder, BuilderBuild, BuilderContext, BuilderError, BuilderResult, BuilderSuccess,
+};
+pub use output_generators::{generate_rs_archive, generate_rs_single, RsOutput};
+pub use parse_file::{parse_file, ParseError, ParsedFile};
+
+pub use cxx_gen::HEADER;
+
+#[derive(Clone)]
+/// Some C++ content which should be written to disk and built.
+pub struct CppFilePair {
+    /// Declarations to go into a header file.
+    pub header: Vec<u8>,
+    /// Implementations to go into a .cpp file.
+    pub implementation: Option<Vec<u8>>,
+    /// The name which should be used for the header file
+    /// (important as it may be `#include`d elsewhere)
+    pub header_name: String,
+}
+
+/// All generated C++ content which should be written to disk.
+pub struct GeneratedCpp(pub Vec<CppFilePair>);
+
+/// A [`syn::Error`] which also implements [`miette::Diagnostic`] so can be pretty-printed
+/// to show the affected span of code.
+#[derive(Error, Debug, Diagnostic)]
+#[error("{err}")]
+pub struct LocatedSynError {
+    err: syn::Error,
+    #[source_code]
+    file: String,
+    #[label("error here")]
+    span: SourceSpan,
+}
+
+impl LocatedSynError {
+    fn new(err: syn::Error, file: &str) -> Self {
+        let span = proc_macro_span_to_miette_span(&err.span());
+        Self {
+            err,
+            file: file.to_string(),
+            span,
+        }
+    }
+}
+
+/// Errors which may occur in generating bindings for these C++
+/// functions.
+#[derive(Debug, Error, Diagnostic)]
+pub enum Error {
+    #[error("Bindgen was unable to generate the initial .rs bindings for this file. This may indicate a parsing problem with the C++ headers.")]
+    Bindgen(()),
+    #[error(transparent)]
+    #[diagnostic(transparent)]
+    MacroParsing(LocatedSynError),
+    #[error(transparent)]
+    #[diagnostic(transparent)]
+    BindingsParsing(LocatedSynError),
+    #[error("no C++ include directory was provided.")]
+    NoAutoCxxInc,
+    #[error(transparent)]
+    Conversion(conversion::ConvertError),
+}
+
+/// Result type.
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+
+struct GenerationResults {
+    item_mod: ItemMod,
+    cpp: Option<CppFilePair>,
+    #[allow(dead_code)]
+    inc_dirs: Vec<PathBuf>,
+    cxxgen_header_name: String,
+}
+enum State {
+    NotGenerated,
+    ParseOnly,
+    Generated(Box<GenerationResults>),
+}
+
+const AUTOCXX_CLANG_ARGS: &[&str; 4] = &["-x", "c++", "-std=c++14", "-DBINDGEN"];
+
+/// Implement to learn of header files which get included
+/// by this build process, such that your build system can choose
+/// to rerun the build process if any such file changes in future.
+pub trait RebuildDependencyRecorder: std::fmt::Debug {
+    /// Records that this autocxx build depends on the given
+    /// header file. Full paths will be provided.
+    fn record_header_file_dependency(&self, filename: &str);
+}
+
+#[cfg_attr(doc, aquamarine::aquamarine)]
+/// Core of the autocxx engine.
+///
+/// The basic idea is this. We will run `bindgen` which will spit
+/// out a ton of Rust code corresponding to all the types and functions
+/// defined in C++. We'll then post-process that bindgen output
+/// into a form suitable for ingestion by `cxx`.
+/// (It's the `BridgeConverter` mod which does that.)
+/// Along the way, the `bridge_converter` might tell us of additional
+/// C++ code which we should generate, e.g. wrappers to move things
+/// into and out of `UniquePtr`s.
+///
+/// ```mermaid
+/// flowchart TB
+///     s[(C++ headers)]
+///     s --> lc
+///     rss[(.rs input)]
+///     rss --> parser
+///     parser --> include_cpp_conf
+///     cpp_output[(C++ output)]
+///     rs_output[(.rs output)]
+///     subgraph autocxx[autocxx_engine]
+///     parser[File parser]
+///     subgraph bindgen[autocxx_bindgen]
+///     lc[libclang parse]
+///     bir(bindgen IR)
+///     lc --> bir
+///     end
+///     bgo(bindgen generated bindings)
+///     bir --> bgo
+///     include_cpp_conf(Config from include_cpp)
+///     syn[Parse with syn]
+///     bgo --> syn
+///     conv[['conversion' mod: see below]]
+///     syn --> conv
+///     rsgen(Generated .rs TokenStream)
+///     conv --> rsgen
+///     subgraph cxx_gen
+///     cxx_codegen[cxx_gen C++ codegen]
+///     end
+///     rsgen --> cxx_codegen
+///     end
+///     conv -- autocxx C++ codegen --> cpp_output
+///     rsgen -- autocxx .rs codegen --> rs_output
+///     cxx_codegen -- cxx C++ codegen --> cpp_output
+///     subgraph rustc [rustc build]
+///     subgraph autocxx_macro
+///     include_cpp[autocxx include_cpp macro]
+///     end
+///     subgraph cxx
+///     cxxm[cxx procedural macro]
+///     end
+///     comprs(Fully expanded Rust code)
+///     end
+///     rs_output-. included .->include_cpp
+///     include_cpp --> cxxm
+///     cxxm --> comprs
+///     rss --> rustc
+///     include_cpp_conf -. used to configure .-> bindgen
+///     include_cpp_conf --> conv
+///     link[linker]
+///     cpp_output --> link
+///     comprs --> link
+/// ```
+///
+/// Here's a zoomed-in view of the "conversion" part:
+///
+/// ```mermaid
+/// flowchart TB
+///     syn[(syn parse)]
+///     apis(Unanalyzed APIs)
+///     subgraph parse
+///     syn ==> parse_bindgen
+///     end
+///     parse_bindgen ==> apis
+///     subgraph analysis
+///     typedef[typedef analysis]
+///     pod[POD analysis]
+///     apis ==> typedef
+///     typedef ==> pod
+///     podapis(APIs with POD analysis)
+///     pod ==> podapis
+///     fun[Function materialization analysis]
+///     podapis ==> fun
+///     funapis(APIs with function analysis)
+///     fun ==> funapis
+///     gc[Garbage collection]
+///     funapis ==> gc
+///     ctypes[C int analysis]
+///     gc ==> ctypes
+///     ctypes ==> finalapis
+///     end
+///     finalapis(Analyzed APIs)
+///     codegenrs(.rs codegen)
+///     codegencpp(.cpp codegen)
+///     finalapis ==> codegenrs
+///     finalapis ==> codegencpp
+/// ```
+pub struct IncludeCppEngine {
+    config: IncludeCppConfig,
+    state: State,
+}
+
+impl Parse for IncludeCppEngine {
+    fn parse(input: ParseStream) -> ParseResult<Self> {
+        let config = input.parse::<IncludeCppConfig>()?;
+        let state = if config.parse_only {
+            State::ParseOnly
+        } else {
+            State::NotGenerated
+        };
+        Ok(Self { config, state })
+    }
+}
+
+impl IncludeCppEngine {
+    pub fn new_from_syn(mac: Macro, file_contents: &str) -> Result<Self> {
+        mac.parse_body::<IncludeCppEngine>()
+            .map_err(|e| Error::MacroParsing(LocatedSynError::new(e, file_contents)))
+    }
+
+    pub fn config_mut(&mut self) -> &mut IncludeCppConfig {
+        assert!(
+            matches!(self.state, State::NotGenerated),
+            "Can't alter config after generation commenced"
+        );
+        &mut self.config
+    }
+
+    fn build_header(&self) -> String {
+        join(
+            self.config
+                .inclusions
+                .iter()
+                .map(|path| format!("#include \"{}\"\n", path)),
+            "",
+        )
+    }
+
+    fn make_bindgen_builder(
+        &self,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) -> bindgen::Builder {
+        let mut builder = bindgen::builder()
+            .clang_args(make_clang_args(inc_dirs, extra_clang_args))
+            .derive_copy(false)
+            .derive_debug(false)
+            .default_enum_style(bindgen::EnumVariation::Rust {
+                non_exhaustive: false,
+            })
+            .size_t_is_usize(true)
+            .enable_cxx_namespaces()
+            .generate_inline_functions(true)
+            .respect_cxx_access_specs(true)
+            .use_specific_virtual_function_receiver(true)
+            .cpp_semantic_attributes(true)
+            .represent_cxx_operators(true)
+            .use_distinct_char16_t(true)
+            .layout_tests(false); // TODO revisit later
+        for item in known_types().get_initial_blocklist() {
+            builder = builder.blocklist_item(item);
+        }
+
+        // 3. Passes allowlist and other options to the bindgen::Builder equivalent
+        //    to --output-style=cxx --allowlist=<as passed in>
+        if let Some(allowlist) = self.config.bindgen_allowlist() {
+            for a in allowlist {
+                // TODO - allowlist type/functions/separately
+                builder = builder
+                    .allowlist_type(&a)
+                    .allowlist_function(&a)
+                    .allowlist_var(&a);
+            }
+        }
+
+        log::info!(
+            "Bindgen flags would be: {}",
+            builder
+                .command_line_flags()
+                .into_iter()
+                .map(|f| format!("\"{}\"", f))
+                .join(" ")
+        );
+        builder
+    }
+
+    pub fn get_rs_filename(&self) -> String {
+        self.config.get_rs_filename()
+    }
+
+    /// Generate the Rust bindings. Call `generate` first.
+    pub fn get_rs_output(&self) -> RsOutput {
+        RsOutput {
+            config: &self.config,
+            rs: match &self.state {
+                State::NotGenerated => panic!("Generate first"),
+                State::Generated(gen_results) => gen_results.item_mod.to_token_stream(),
+                State::ParseOnly => TokenStream2::new(),
+            },
+        }
+    }
+
+    /// Returns the name of the mod which this `include_cpp!` will generate.
+    /// Can and should be used to ensure multiple mods in a file don't conflict.
+    pub fn get_mod_name(&self) -> String {
+        self.config.get_mod_name().to_string()
+    }
+
+    fn parse_bindings(&self, bindings: bindgen::Bindings) -> Result<ItemMod> {
+        // This bindings object is actually a TokenStream internally and we're wasting
+        // effort converting to and from string. We could enhance the bindgen API
+        // in future.
+        let bindings = bindings.to_string();
+        // Manually add the mod ffi {} so that we can ask syn to parse
+        // into a single construct.
+        let bindings = format!("mod bindgen {{ {} }}", bindings);
+        info!("Bindings: {}", bindings);
+        syn::parse_str::<ItemMod>(&bindings)
+            .map_err(|e| Error::BindingsParsing(LocatedSynError::new(e, &bindings)))
+    }
+
+    /// Actually examine the headers to find out what needs generating.
+    /// Most errors occur at this stage as we fail to interpret the C++
+    /// headers properly.
+    ///
+    /// See documentation for this type for flow diagrams and more details.
+    pub fn generate(
+        &mut self,
+        inc_dirs: Vec<PathBuf>,
+        extra_clang_args: &[&str],
+        dep_recorder: Option<Box<dyn RebuildDependencyRecorder>>,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<()> {
+        // If we are in parse only mode, do nothing. This is used for
+        // doc tests to ensure the parsing is valid, but we can't expect
+        // valid C++ header files or linkers to allow a complete build.
+        match self.state {
+            State::ParseOnly => return Ok(()),
+            State::NotGenerated => {}
+            State::Generated(_) => panic!("Only call generate once"),
+        }
+
+        let mod_name = self.config.get_mod_name();
+        let mut builder = self.make_bindgen_builder(&inc_dirs, extra_clang_args);
+        if let Some(dep_recorder) = dep_recorder {
+            builder = builder.parse_callbacks(Box::new(AutocxxParseCallbacks(dep_recorder)));
+        }
+        let header_contents = self.build_header();
+        self.dump_header_if_so_configured(&header_contents, &inc_dirs, extra_clang_args);
+        let header_and_prelude = format!("{}\n\n{}", known_types().get_prelude(), header_contents);
+        log::info!("Header and prelude for bindgen:\n{}", header_and_prelude);
+        builder = builder.header_contents("example.hpp", &header_and_prelude);
+
+        let bindings = builder.generate().map_err(Error::Bindgen)?;
+        let bindings = self.parse_bindings(bindings)?;
+
+        let converter = BridgeConverter::new(&self.config.inclusions, &self.config);
+
+        let conversion = converter
+            .convert(
+                bindings,
+                self.config.unsafe_policy.clone(),
+                header_contents,
+                cpp_codegen_options,
+            )
+            .map_err(Error::Conversion)?;
+        let mut items = conversion.rs;
+        let mut new_bindings: ItemMod = parse_quote! {
+            #[allow(non_snake_case)]
+            #[allow(dead_code)]
+            #[allow(non_upper_case_globals)]
+            #[allow(non_camel_case_types)]
+            mod #mod_name {
+            }
+        };
+        new_bindings.content.as_mut().unwrap().1.append(&mut items);
+        info!(
+            "New bindings:\n{}",
+            rust_pretty_printer::pretty_print(&new_bindings.to_token_stream())
+        );
+        self.state = State::Generated(Box::new(GenerationResults {
+            item_mod: new_bindings,
+            cpp: conversion.cpp,
+            inc_dirs,
+            cxxgen_header_name: conversion.cxxgen_header_name,
+        }));
+        Ok(())
+    }
+
+    /// Return the include directories used for this include_cpp invocation.
+    #[cfg(any(test, feature = "build"))]
+    fn include_dirs(&self) -> impl Iterator<Item = &PathBuf> {
+        match &self.state {
+            State::Generated(gen_results) => gen_results.inc_dirs.iter(),
+            _ => panic!("Must call generate() before include_dirs()"),
+        }
+    }
+
+    fn dump_header_if_so_configured(
+        &self,
+        header: &str,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) {
+        if let Ok(output_path) = std::env::var("AUTOCXX_PREPROCESS") {
+            self.make_preprocessed_file(
+                &PathBuf::from(output_path),
+                header,
+                inc_dirs,
+                extra_clang_args,
+            );
+        }
+        #[cfg(feature = "reproduction_case")]
+        if let Ok(output_path) = std::env::var("AUTOCXX_REPRO_CASE") {
+            let tf = NamedTempFile::new().unwrap();
+            self.make_preprocessed_file(
+                &PathBuf::from(tf.path()),
+                header,
+                inc_dirs,
+                extra_clang_args,
+            );
+            let header = std::fs::read(tf.path()).unwrap();
+            let header = String::from_utf8_lossy(&header);
+            let output_path = PathBuf::from(output_path);
+            let config = self.config.to_token_stream().to_string();
+            let json = serde_json::json!({
+                "header": header,
+                "config": config
+            });
+            let f = File::create(&output_path).unwrap();
+            serde_json::to_writer(f, &json).unwrap();
+        }
+    }
+
+    fn make_preprocessed_file(
+        &self,
+        output_path: &Path,
+        header: &str,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) {
+        // Include a load of system headers at the end of the preprocessed output,
+        // because we would like to be able to generate bindings from the
+        // preprocessed header, and then build those bindings. The C++ parts
+        // of those bindings might need things inside these various headers;
+        // we make sure all these definitions and declarations are inside
+        // this one header file so that the reduction process does not have
+        // to refer to local headers on the reduction machine too.
+        let suffix = ALL_KNOWN_SYSTEM_HEADERS
+            .iter()
+            .map(|hdr| format!("#include <{}>\n", hdr))
+            .join("\n");
+        let input = format!("/*\nautocxx config:\n\n{:?}\n\nend autocxx config.\nautocxx preprocessed input:\n*/\n\n{}\n\n/* autocxx: extra headers added below for completeness. */\n\n{}\n{}\n",
+            self.config, header, suffix, cxx_gen::HEADER);
+        let mut tf = NamedTempFile::new().unwrap();
+        write!(tf, "{}", input).unwrap();
+        let tp = tf.into_temp_path();
+        preprocess(&tp, &PathBuf::from(output_path), inc_dirs, extra_clang_args).unwrap();
+    }
+}
+
+/// This is a list of all the headers known to be included in generated
+/// C++ by cxx. We only use this when `AUTOCXX_PERPROCESS` is set to true,
+/// in an attempt to make the resulting preprocessed header more hermetic.
+/// We clearly should _not_ use this in any other circumstance; obviously
+/// we'd then want to add an API to cxx_gen such that we could retrieve
+/// that information from source.
+static ALL_KNOWN_SYSTEM_HEADERS: &[&str] = &[
+    "memory",
+    "string",
+    "algorithm",
+    "array",
+    "cassert",
+    "cstddef",
+    "cstdint",
+    "cstring",
+    "exception",
+    "functional",
+    "initializer_list",
+    "iterator",
+    "memory",
+    "new",
+    "stdexcept",
+    "type_traits",
+    "utility",
+    "vector",
+    "sys/types.h",
+];
+
+pub fn do_cxx_cpp_generation(
+    rs: TokenStream2,
+    cpp_codegen_options: &CppCodegenOptions,
+    cxxgen_header_name: String,
+) -> Result<CppFilePair, cxx_gen::Error> {
+    let mut opt = cxx_gen::Opt::default();
+    opt.cxx_impl_annotations = cpp_codegen_options.cxx_impl_annotations.clone();
+    let cxx_generated = cxx_gen::generate_header_and_cc(rs, &opt)?;
+    Ok(CppFilePair {
+        header: strip_system_headers(
+            cxx_generated.header,
+            cpp_codegen_options.suppress_system_headers,
+        ),
+        header_name: cxxgen_header_name,
+        implementation: Some(strip_system_headers(
+            cxx_generated.implementation,
+            cpp_codegen_options.suppress_system_headers,
+        )),
+    })
+}
+
+pub(crate) fn strip_system_headers(input: Vec<u8>, suppress_system_headers: bool) -> Vec<u8> {
+    if suppress_system_headers {
+        std::str::from_utf8(&input)
+            .unwrap()
+            .lines()
+            .filter(|l| !l.starts_with("#include <"))
+            .join("\n")
+            .as_bytes()
+            .to_vec()
+    } else {
+        input
+    }
+}
+
+impl CppBuildable for IncludeCppEngine {
+    /// Generate C++-side bindings for these APIs. Call `generate` first.
+    fn generate_h_and_cxx(
+        &self,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<GeneratedCpp, cxx_gen::Error> {
+        let mut files = Vec::new();
+        match &self.state {
+            State::ParseOnly => panic!("Cannot generate C++ in parse-only mode"),
+            State::NotGenerated => panic!("Call generate() first"),
+            State::Generated(gen_results) => {
+                let rs = gen_results.item_mod.to_token_stream();
+                files.push(do_cxx_cpp_generation(
+                    rs,
+                    cpp_codegen_options,
+                    gen_results.cxxgen_header_name.clone(),
+                )?);
+                if let Some(cpp_file_pair) = &gen_results.cpp {
+                    files.push(cpp_file_pair.clone());
+                }
+            }
+        };
+        Ok(GeneratedCpp(files))
+    }
+}
+
+/// Get clang args as if we were operating clang the same way as we operate
+/// bindgen.
+pub fn make_clang_args<'a>(
+    incs: &'a [PathBuf],
+    extra_args: &'a [&str],
+) -> impl Iterator<Item = String> + 'a {
+    // AUTOCXX_CLANG_ARGS come first so that any defaults defined there(e.g. for the `-std`
+    // argument) can be overridden by extra_args.
+    AUTOCXX_CLANG_ARGS
+        .iter()
+        .map(|s| s.to_string())
+        .chain(incs.iter().map(|i| format!("-I{}", i.to_str().unwrap())))
+        .chain(extra_args.iter().map(|s| s.to_string()))
+}
+
+/// Preprocess a file using the same options
+/// as is used by autocxx. Input: listing_path, output: preprocess_path.
+pub fn preprocess(
+    listing_path: &Path,
+    preprocess_path: &Path,
+    incs: &[PathBuf],
+    extra_clang_args: &[&str],
+) -> Result<(), std::io::Error> {
+    let mut cmd = Command::new(get_clang_path());
+    cmd.arg("-E");
+    cmd.arg("-C");
+    cmd.args(make_clang_args(incs, extra_clang_args));
+    cmd.arg(listing_path.to_str().unwrap());
+    cmd.stderr(Stdio::inherit());
+    let result = cmd.output().expect("failed to execute clang++");
+    assert!(result.status.success(), "failed to preprocess");
+    let mut file = File::create(preprocess_path)?;
+    file.write_all(&result.stdout)?;
+    Ok(())
+}
+
+/// Get the path to clang which is effective for any preprocessing
+/// operations done by autocxx.
+pub fn get_clang_path() -> String {
+    // `CLANG_PATH` is the environment variable that clang-sys uses to specify
+    // the path to Clang, so in most cases where someone is using a compiler
+    // that's not on the path, things should just work. We also check `CXX`,
+    // since some users may have set that.
+    std::env::var("CLANG_PATH")
+        .or_else(|_| std::env::var("CXX"))
+        .unwrap_or_else(|_| "clang++".to_string())
+}
+
+/// Function to generate the desired name of the header containing autocxx's
+/// extra generated C++.
+/// Newtype wrapper so we can give it a [`Default`].
+pub struct AutocxxgenHeaderNamer<'a>(pub Box<dyn 'a + Fn(String) -> String>);
+
+impl Default for AutocxxgenHeaderNamer<'static> {
+    fn default() -> Self {
+        Self(Box::new(|mod_name| format!("autocxxgen_{}.h", mod_name)))
+    }
+}
+
+impl AutocxxgenHeaderNamer<'_> {
+    fn name_header(&self, mod_name: String) -> String {
+        self.0(mod_name)
+    }
+}
+
+/// Function to generate the desired name of the header containing cxx's
+/// declarations.
+/// Newtype wrapper so we can give it a [`Default`].
+pub struct CxxgenHeaderNamer<'a>(pub Box<dyn 'a + Fn() -> String>);
+
+impl Default for CxxgenHeaderNamer<'static> {
+    fn default() -> Self {
+        Self(Box::new(|| "cxxgen.h".into()))
+    }
+}
+
+impl CxxgenHeaderNamer<'_> {
+    fn name_header(&self) -> String {
+        self.0()
+    }
+}
+
+/// Options for C++ codegen
+#[derive(Default)]
+pub struct CppCodegenOptions<'a> {
+    /// Whether to avoid generating `#include <some-system-header>`.
+    /// You may wish to do this to make a hermetic test case with no
+    /// external dependencies.
+    pub suppress_system_headers: bool,
+    /// Optionally, a prefix to go at `#include "<here>cxx.h". This is a header file from the `cxx`
+    /// crate.
+    pub path_to_cxx_h: Option<String>,
+    /// Optionally, a prefix to go at `#include "<here>cxxgen.h". This is a header file which we
+    /// generate.
+    pub path_to_cxxgen_h: Option<String>,
+    /// Optionally, a function called to determine the name that will be used
+    /// for the autocxxgen.h file.
+    /// The function is passed the name of the module generated by each `include_cpp`,
+    /// configured via `name`. These will be unique.
+    pub autocxxgen_header_namer: AutocxxgenHeaderNamer<'a>,
+    /// A function to generate the name of the cxxgen.h header that should be output.
+    pub cxxgen_header_namer: CxxgenHeaderNamer<'a>,
+    /// An annotation optionally to include on each C++ function.
+    /// For example to export the symbol from a library.
+    pub cxx_impl_annotations: Option<String>,
+}
+
+fn proc_macro_span_to_miette_span(span: &proc_macro2::Span) -> SourceSpan {
+    // A proc_macro2::Span stores its location as a byte offset. But there are
+    // no APIs to get that offset out.
+    // We could use `.start()` and `.end()` to get the line + column numbers, but it appears
+    // they're a little buggy. Hence we do this, to get the offsets directly across into
+    // miette.
+    struct Err;
+    let r: Result<(usize, usize), Err> = (|| {
+        let span_desc = format!("{:?}", span);
+        let re = Regex::new(r"(\d+)..(\d+)").unwrap();
+        let captures = re.captures(&span_desc).ok_or(Err)?;
+        let start = captures.get(1).ok_or(Err)?;
+        let start: usize = start.as_str().parse().map_err(|_| Err)?;
+        let start = start.saturating_sub(1); // proc_macro::Span offsets seem to be off-by-one
+        let end = captures.get(2).ok_or(Err)?;
+        let end: usize = end.as_str().parse().map_err(|_| Err)?;
+        let end = end.saturating_sub(1); // proc_macro::Span offsets seem to be off-by-one
+        Ok((start, end.saturating_sub(start)))
+    })();
+    let (start, end) = r.unwrap_or((0, 0));
+    SourceSpan::new(SourceOffset::from(start), SourceOffset::from(end))
+}
