diff --git a/engine/src/conversion/parse/bindgen_semantic_attributes.rs b/engine/src/conversion/parse/bindgen_semantic_attributes.rs
new file mode 100644
index 0000000..8b789ae
--- /dev/null
+++ b/engine/src/conversion/parse/bindgen_semantic_attributes.rs
@@ -0,0 +1,190 @@
+// Copyright 2022 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.
+
+use proc_macro2::{Ident, TokenStream};
+use syn::{
+    parenthesized,
+    parse::{Parse, Parser},
+    Attribute, LitStr,
+};
+
+use crate::conversion::{
+    api::{CppVisibility, Layout, References, SpecialMemberKind, Virtualness},
+    convert_error::{ConvertErrorWithContext, ErrorContext},
+    ConvertError,
+};
+
+/// The set of all annotations that autocxx_bindgen has added
+/// for our benefit.
+#[derive(Debug)]
+pub(crate) struct BindgenSemanticAttributes(Vec<BindgenSemanticAttribute>);
+
+impl BindgenSemanticAttributes {
+    // Remove `bindgen_` attributes. They don't have a corresponding macro defined anywhere,
+    // so they will cause compilation errors if we leave them in.
+    // We may return an error if one of the bindgen attributes shows that the
+    // item can't be processed.
+    pub(crate) fn new_retaining_others(attrs: &mut Vec<Attribute>) -> Self {
+        let metadata = Self::new(attrs);
+        attrs.retain(|a| a.path.segments.last().unwrap().ident != "cpp_semantics");
+        metadata
+    }
+
+    pub(crate) fn new(attrs: &[Attribute]) -> Self {
+        Self(
+            attrs
+                .iter()
+                .filter_map(|attr| {
+                    if attr.path.segments.last().unwrap().ident == "cpp_semantics" {
+                        let r: Result<BindgenSemanticAttribute, syn::Error> = attr.parse_args();
+                        r.ok()
+                    } else {
+                        None
+                    }
+                })
+                .collect(),
+        )
+    }
+
+    /// Some attributes indicate we can never handle a given item. Check for those.
+    pub(crate) fn check_for_fatal_attrs(
+        &self,
+        id_for_context: &Ident,
+    ) -> Result<(), ConvertErrorWithContext> {
+        if self.has_attr("unused_template_param") {
+            Err(ConvertErrorWithContext(
+                ConvertError::UnusedTemplateParam,
+                Some(ErrorContext::new_for_item(id_for_context.clone())),
+            ))
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Whether the given attribute is present.
+    pub(super) fn has_attr(&self, attr_name: &str) -> bool {
+        self.0.iter().any(|a| a.is_ident(attr_name))
+    }
+
+    /// The C++ visibility of the item.
+    pub(super) fn get_cpp_visibility(&self) -> CppVisibility {
+        if self.has_attr("visibility_private") {
+            CppVisibility::Private
+        } else if self.has_attr("visibility_protected") {
+            CppVisibility::Protected
+        } else {
+            CppVisibility::Public
+        }
+    }
+
+    /// Whether the item is virtual.
+    pub(super) fn get_virtualness(&self) -> Virtualness {
+        if self.has_attr("pure_virtual") {
+            Virtualness::PureVirtual
+        } else if self.has_attr("bindgen_virtual") {
+            Virtualness::Virtual
+        } else {
+            Virtualness::None
+        }
+    }
+
+    fn parse_if_present<T: Parse>(&self, annotation: &str) -> Option<T> {
+        self.0
+            .iter()
+            .find(|a| a.is_ident(annotation))
+            .map(|a| a.parse_args().unwrap())
+    }
+
+    fn string_if_present(&self, annotation: &str) -> Option<String> {
+        let ls: Option<LitStr> = self.parse_if_present(annotation);
+        ls.map(|ls| ls.value())
+    }
+
+    /// The in-memory layout of the item.
+    pub(super) fn get_layout(&self) -> Option<Layout> {
+        self.parse_if_present("layout")
+    }
+
+    /// The original C++ name, which bindgen may have changed.
+    pub(super) fn get_original_name(&self) -> Option<String> {
+        self.string_if_present("original_name")
+    }
+
+    /// Whether this is a move constructor or other special member.
+    pub(super) fn special_member_kind(&self) -> Option<SpecialMemberKind> {
+        self.string_if_present("special_member")
+            .map(|kind| match kind.as_str() {
+                "default_ctor" => SpecialMemberKind::DefaultConstructor,
+                "copy_ctor" => SpecialMemberKind::CopyConstructor,
+                "move_ctor" => SpecialMemberKind::MoveConstructor,
+                "dtor" => SpecialMemberKind::Destructor,
+                "assignment_operator" => SpecialMemberKind::AssignmentOperator,
+                _ => panic!("unexpected special_member_kind"),
+            })
+    }
+
+    /// Any reference parameters or return values.
+    pub(super) fn get_reference_parameters_and_return(&self) -> References {
+        let mut results = References::default();
+        for a in &self.0 {
+            if a.is_ident("ret_type_reference") {
+                results.ref_return = true;
+            } else if a.is_ident("ret_type_rvalue_reference") {
+                results.rvalue_ref_return = true;
+            } else if a.is_ident("arg_type_reference") {
+                let r: Result<Ident, syn::Error> = a.parse_args();
+                if let Ok(ls) = r {
+                    results.ref_params.insert(ls);
+                }
+            } else if a.is_ident("arg_type_rvalue_reference") {
+                let r: Result<Ident, syn::Error> = a.parse_args();
+                if let Ok(ls) = r {
+                    results.rvalue_ref_params.insert(ls);
+                }
+            }
+        }
+        results
+    }
+}
+
+#[derive(Debug)]
+struct BindgenSemanticAttribute {
+    annotation_name: Ident,
+    body: Option<TokenStream>,
+}
+
+impl BindgenSemanticAttribute {
+    fn is_ident(&self, name: &str) -> bool {
+        self.annotation_name == name
+    }
+
+    fn parse_args<T: Parse>(&self) -> Result<T, syn::Error> {
+        T::parse.parse2(self.body.as_ref().unwrap().clone())
+    }
+}
+
+impl Parse for BindgenSemanticAttribute {
+    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+        let annotation_name: Ident = input.parse()?;
+        if input.peek(syn::token::Paren) {
+            let body_contents;
+            parenthesized!(body_contents in input);
+            Ok(Self {
+                annotation_name,
+                body: Some(body_contents.parse()?),
+            })
+        } else if !input.is_empty() {
+            Err(input.error("expected nothing"))
+        } else {
+            Ok(Self {
+                annotation_name,
+                body: None,
+            })
+        }
+    }
+}
diff --git a/engine/src/conversion/parse/mod.rs b/engine/src/conversion/parse/mod.rs
new file mode 100644
index 0000000..3f42ce4
--- /dev/null
+++ b/engine/src/conversion/parse/mod.rs
@@ -0,0 +1,14 @@
+// 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.
+
+mod bindgen_semantic_attributes;
+mod parse_bindgen;
+mod parse_foreign_mod;
+
+pub(crate) use bindgen_semantic_attributes::BindgenSemanticAttributes;
+pub(crate) use parse_bindgen::ParseBindgen;
diff --git a/engine/src/conversion/parse/parse_bindgen.rs b/engine/src/conversion/parse/parse_bindgen.rs
new file mode 100644
index 0000000..0818aa5
--- /dev/null
+++ b/engine/src/conversion/parse/parse_bindgen.rs
@@ -0,0 +1,388 @@
+// 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.
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use crate::{
+    conversion::{
+        api::{Api, ApiName, NullPhase, StructDetails, SubclassName, TypedefKind, UnanalyzedApi},
+        apivec::ApiVec,
+        ConvertError,
+    },
+    types::Namespace,
+    types::QualifiedName,
+};
+use crate::{
+    conversion::{
+        convert_error::{ConvertErrorWithContext, ErrorContext},
+        error_reporter::report_any_error,
+    },
+    types::validate_ident_ok_for_cxx,
+};
+use autocxx_parser::{IncludeCppConfig, RustPath};
+use syn::{parse_quote, Fields, Ident, Item, Type, TypePath, UseTree};
+
+use super::{
+    super::utilities::generate_utilities, bindgen_semantic_attributes::BindgenSemanticAttributes,
+};
+
+use super::parse_foreign_mod::ParseForeignMod;
+
+/// Parses a bindgen mod in order to understand the APIs within it.
+pub(crate) struct ParseBindgen<'a> {
+    config: &'a IncludeCppConfig,
+    apis: ApiVec<NullPhase>,
+}
+
+fn api_name(ns: &Namespace, id: Ident, attrs: &BindgenSemanticAttributes) -> ApiName {
+    ApiName::new_with_cpp_name(ns, id, attrs.get_original_name())
+}
+
+pub(crate) fn api_name_qualified(
+    ns: &Namespace,
+    id: Ident,
+    attrs: &BindgenSemanticAttributes,
+) -> Result<ApiName, ConvertErrorWithContext> {
+    match validate_ident_ok_for_cxx(&id.to_string()) {
+        Err(e) => {
+            let ctx = ErrorContext::new_for_item(id);
+            Err(ConvertErrorWithContext(e, Some(ctx)))
+        }
+        Ok(..) => Ok(api_name(ns, id, attrs)),
+    }
+}
+
+impl<'a> ParseBindgen<'a> {
+    pub(crate) fn new(config: &'a IncludeCppConfig) -> Self {
+        ParseBindgen {
+            config,
+            apis: ApiVec::new(),
+        }
+    }
+
+    /// Parses items found in the `bindgen` output and returns a set of
+    /// `Api`s together with some other data.
+    pub(crate) fn parse_items(
+        mut self,
+        items: Vec<Item>,
+    ) -> Result<ApiVec<NullPhase>, ConvertError> {
+        let items = Self::find_items_in_root(items)?;
+        if !self.config.exclude_utilities() {
+            generate_utilities(&mut self.apis, self.config);
+        }
+        self.add_apis_from_config();
+        let root_ns = Namespace::new();
+        self.parse_mod_items(items, root_ns);
+        self.confirm_all_generate_directives_obeyed()?;
+        self.replace_extern_cpp_types();
+        Ok(self.apis)
+    }
+
+    /// Some API items are not populated from bindgen output, but instead
+    /// directly from items in the config.
+    fn add_apis_from_config(&mut self) {
+        self.apis
+            .extend(self.config.subclasses.iter().map(|sc| Api::Subclass {
+                name: SubclassName::new(sc.subclass.clone()),
+                superclass: QualifiedName::new_from_cpp_name(&sc.superclass),
+            }));
+        self.apis
+            .extend(self.config.extern_rust_funs.iter().map(|fun| {
+                let id = fun.sig.ident.clone();
+                Api::RustFn {
+                    name: ApiName::new_in_root_namespace(id),
+                    details: fun.clone(),
+                    receiver: fun.receiver.as_ref().map(|receiver_id| {
+                        QualifiedName::new(&Namespace::new(), receiver_id.clone())
+                    }),
+                }
+            }));
+        let unique_rust_types: HashSet<&RustPath> = self.config.rust_types.iter().collect();
+        self.apis.extend(unique_rust_types.into_iter().map(|path| {
+            let id = path.get_final_ident();
+            Api::RustType {
+                name: ApiName::new_in_root_namespace(id.clone()),
+                path: path.clone(),
+            }
+        }));
+        self.apis.extend(
+            self.config
+                .concretes
+                .0
+                .iter()
+                .map(|(cpp_definition, rust_id)| {
+                    let name = ApiName::new_in_root_namespace(rust_id.clone());
+                    Api::ConcreteType {
+                        name,
+                        cpp_definition: cpp_definition.clone(),
+                        rs_definition: None,
+                    }
+                }),
+        );
+    }
+
+    /// We do this last, _after_ we've parsed all the APIs, because we might want to actually
+    /// replace some of the existing APIs (structs/enums/etc.) with replacements.
+    fn replace_extern_cpp_types(&mut self) {
+        let pod_requests: HashSet<_> = self.config.get_pod_requests().iter().collect();
+        let replacements: HashMap<_, _> = self
+            .config
+            .externs
+            .0
+            .iter()
+            .map(|(cpp_definition, details)| {
+                let qn = QualifiedName::new_from_cpp_name(cpp_definition);
+                let pod = pod_requests.contains(&qn.to_cpp_name());
+                (
+                    qn.clone(),
+                    Api::ExternCppType {
+                        name: ApiName::new_from_qualified_name(qn),
+                        details: details.clone(),
+                        pod,
+                    },
+                )
+            })
+            .collect();
+        self.apis
+            .retain(|api| !replacements.contains_key(api.name()));
+        self.apis.extend(replacements.into_iter().map(|(_, v)| v));
+    }
+
+    fn find_items_in_root(items: Vec<Item>) -> Result<Vec<Item>, ConvertError> {
+        for item in items {
+            match item {
+                Item::Mod(root_mod) => {
+                    // With namespaces enabled, bindgen always puts everything
+                    // in a mod called 'root'. We don't want to pass that
+                    // onto cxx, so jump right into it.
+                    assert!(root_mod.ident == "root");
+                    if let Some((_, items)) = root_mod.content {
+                        return Ok(items);
+                    }
+                }
+                _ => return Err(ConvertError::UnexpectedOuterItem),
+            }
+        }
+        Ok(Vec::new())
+    }
+
+    /// Interpret the bindgen-generated .rs for a particular
+    /// mod, which corresponds to a C++ namespace.
+    fn parse_mod_items(&mut self, items: Vec<Item>, ns: Namespace) {
+        // This object maintains some state specific to this namespace, i.e.
+        // this particular mod.
+        let mut mod_converter = ParseForeignMod::new(ns.clone());
+        let mut more_apis = ApiVec::new();
+        for item in items {
+            report_any_error(&ns, &mut more_apis, || {
+                self.parse_item(item, &mut mod_converter, &ns)
+            });
+        }
+        self.apis.append(&mut more_apis);
+        mod_converter.finished(&mut self.apis);
+    }
+
+    fn parse_item(
+        &mut self,
+        item: Item,
+        mod_converter: &mut ParseForeignMod,
+        ns: &Namespace,
+    ) -> Result<(), ConvertErrorWithContext> {
+        match item {
+            Item::ForeignMod(fm) => {
+                mod_converter.convert_foreign_mod_items(fm.items);
+                Ok(())
+            }
+            Item::Struct(s) => {
+                if s.ident.to_string().ends_with("__bindgen_vtable") {
+                    return Ok(());
+                }
+                let annotations = BindgenSemanticAttributes::new(&s.attrs);
+                // cxx::bridge can't cope with type aliases to generic
+                // types at the moment.
+                let name = api_name_qualified(ns, s.ident.clone(), &annotations)?;
+                let err = annotations.check_for_fatal_attrs(&s.ident).err();
+                let api = if ns.is_empty() && self.config.is_rust_type(&s.ident) {
+                    None
+                } else if Self::spot_forward_declaration(&s.fields)
+                    || (Self::spot_zero_length_struct(&s.fields) && err.is_some())
+                {
+                    // Forward declarations are recorded especially because we can't
+                    // store them in UniquePtr or similar.
+                    // Templated forward declarations don't appear with an _unused field (which is what
+                    // we spot in the previous clause) but instead with an _address field.
+                    // So, solely in the case where we're storing up an error about such
+                    // a templated type, we'll also treat such cases as forward declarations.
+                    Some(UnanalyzedApi::ForwardDeclaration { name, err })
+                } else {
+                    let has_rvalue_reference_fields = s.fields.iter().any(|f| {
+                        BindgenSemanticAttributes::new(&f.attrs).has_attr("rvalue_reference")
+                    });
+                    Some(UnanalyzedApi::Struct {
+                        name,
+                        details: Box::new(StructDetails {
+                            vis: annotations.get_cpp_visibility(),
+                            layout: annotations.get_layout(),
+                            item: s,
+                            has_rvalue_reference_fields,
+                        }),
+                        analysis: (),
+                    })
+                };
+                if let Some(api) = api {
+                    if !self.config.is_on_blocklist(&api.name().to_cpp_name()) {
+                        self.apis.push(api);
+                    }
+                }
+                Ok(())
+            }
+            Item::Enum(e) => {
+                let annotations = BindgenSemanticAttributes::new(&e.attrs);
+                let api = UnanalyzedApi::Enum {
+                    name: api_name_qualified(ns, e.ident.clone(), &annotations)?,
+                    item: e,
+                };
+                if !self.config.is_on_blocklist(&api.name().to_cpp_name()) {
+                    self.apis.push(api);
+                }
+                Ok(())
+            }
+            Item::Impl(imp) => {
+                // We *mostly* ignore all impl blocks generated by bindgen.
+                // Methods also appear in 'extern "C"' blocks which
+                // we will convert instead. At that time we'll also construct
+                // synthetic impl blocks.
+                // We do however record which methods were spotted, since
+                // we have no other way of working out which functions are
+                // static methods vs plain functions.
+                mod_converter.convert_impl_items(imp);
+                Ok(())
+            }
+            Item::Mod(itm) => {
+                if let Some((_, items)) = itm.content {
+                    let new_ns = ns.push(itm.ident.to_string());
+                    self.parse_mod_items(items, new_ns);
+                }
+                Ok(())
+            }
+            Item::Use(use_item) => {
+                let mut segs = Vec::new();
+                let mut tree = &use_item.tree;
+                loop {
+                    match tree {
+                        UseTree::Path(up) => {
+                            segs.push(up.ident.clone());
+                            tree = &up.tree;
+                        }
+                        UseTree::Name(un) if un.ident == "root" => break, // we do not add this to any API since we generate equivalent
+                        // use statements in our codegen phase.
+                        UseTree::Rename(urn) => {
+                            let old_id = &urn.ident;
+                            let new_id = &urn.rename;
+                            let new_tyname = QualifiedName::new(ns, new_id.clone());
+                            assert!(segs.remove(0) == "self", "Path didn't start with self");
+                            assert!(
+                                segs.remove(0) == "super",
+                                "Path didn't start with self::super"
+                            );
+                            // This is similar to the path encountered within 'tree'
+                            // but without the self::super prefix which is unhelpful
+                            // in our output mod, because we prefer relative paths
+                            // (we're nested in another mod)
+                            let old_path: TypePath = parse_quote! {
+                                #(#segs)::* :: #old_id
+                            };
+                            let old_tyname = QualifiedName::from_type_path(&old_path);
+                            if new_tyname == old_tyname {
+                                return Err(ConvertErrorWithContext(
+                                    ConvertError::InfinitelyRecursiveTypedef(new_tyname),
+                                    Some(ErrorContext::new_for_item(new_id.clone())),
+                                ));
+                            }
+                            let annotations = BindgenSemanticAttributes::new(&use_item.attrs);
+                            self.apis.push(UnanalyzedApi::Typedef {
+                                name: api_name(ns, new_id.clone(), &annotations),
+                                item: TypedefKind::Use(
+                                    parse_quote! {
+                                        pub use #old_path as #new_id;
+                                    },
+                                    Box::new(Type::Path(old_path)),
+                                ),
+                                old_tyname: Some(old_tyname),
+                                analysis: (),
+                            });
+                            break;
+                        }
+                        _ => {
+                            return Err(ConvertErrorWithContext(
+                                ConvertError::UnexpectedUseStatement(
+                                    segs.into_iter().last().map(|i| i.to_string()),
+                                ),
+                                None,
+                            ))
+                        }
+                    }
+                }
+                Ok(())
+            }
+            Item::Const(const_item) => {
+                let annotations = BindgenSemanticAttributes::new(&const_item.attrs);
+                self.apis.push(UnanalyzedApi::Const {
+                    name: api_name(ns, const_item.ident.clone(), &annotations),
+                    const_item,
+                });
+                Ok(())
+            }
+            Item::Type(ity) => {
+                let annotations = BindgenSemanticAttributes::new(&ity.attrs);
+                // It's known that sometimes bindgen will give us duplicate typedefs with the
+                // same name - see test_issue_264.
+                self.apis.push(UnanalyzedApi::Typedef {
+                    name: api_name(ns, ity.ident.clone(), &annotations),
+                    item: TypedefKind::Type(ity),
+                    old_tyname: None,
+                    analysis: (),
+                });
+                Ok(())
+            }
+            _ => Err(ConvertErrorWithContext(
+                ConvertError::UnexpectedItemInMod,
+                None,
+            )),
+        }
+    }
+
+    fn spot_forward_declaration(s: &Fields) -> bool {
+        Self::spot_field(s, "_unused")
+    }
+
+    fn spot_zero_length_struct(s: &Fields) -> bool {
+        Self::spot_field(s, "_address")
+    }
+
+    fn spot_field(s: &Fields, desired_id: &str) -> bool {
+        s.iter()
+            .filter_map(|f| f.ident.as_ref())
+            .any(|id| id == desired_id)
+    }
+
+    fn confirm_all_generate_directives_obeyed(&self) -> Result<(), ConvertError> {
+        let api_names: HashSet<_> = self
+            .apis
+            .iter()
+            .map(|api| api.name().to_cpp_name())
+            .collect();
+        for generate_directive in self.config.must_generate_list() {
+            if !api_names.contains(&generate_directive) {
+                return Err(ConvertError::DidNotGenerateAnything(generate_directive));
+            }
+        }
+        Ok(())
+    }
+}
diff --git a/engine/src/conversion/parse/parse_foreign_mod.rs b/engine/src/conversion/parse/parse_foreign_mod.rs
new file mode 100644
index 0000000..08c1fd8
--- /dev/null
+++ b/engine/src/conversion/parse/parse_foreign_mod.rs
@@ -0,0 +1,177 @@
+// 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.
+
+use crate::conversion::api::{ApiName, NullPhase, Provenance};
+use crate::conversion::apivec::ApiVec;
+use crate::conversion::doc_attr::get_doc_attrs;
+use crate::conversion::error_reporter::report_any_error;
+use crate::conversion::{
+    api::{FuncToConvert, UnanalyzedApi},
+    convert_error::ConvertErrorWithContext,
+    convert_error::ErrorContext,
+};
+use crate::{
+    conversion::ConvertError,
+    types::{Namespace, QualifiedName},
+};
+use std::collections::HashMap;
+use syn::{Block, Expr, ExprCall, ForeignItem, Ident, ImplItem, ItemImpl, Stmt, Type};
+
+use super::bindgen_semantic_attributes::BindgenSemanticAttributes;
+
+/// Parses a given bindgen-generated 'mod' into suitable
+/// [Api]s. In bindgen output, a given mod concerns
+/// a specific C++ namespace.
+pub(crate) struct ParseForeignMod {
+    ns: Namespace,
+    // We mostly act upon the functions we see within the 'extern "C"'
+    // block of bindgen output, but we can't actually do this until
+    // we've seen the (possibly subsequent) 'impl' blocks so we can
+    // deduce which functions are actually static methods. Hence
+    // store them.
+    funcs_to_convert: Vec<FuncToConvert>,
+    // Evidence from 'impl' blocks about which of these items
+    // may actually be methods (static or otherwise). Mapping from
+    // function name to type name.
+    method_receivers: HashMap<Ident, QualifiedName>,
+    ignored_apis: ApiVec<NullPhase>,
+}
+
+impl ParseForeignMod {
+    pub(crate) fn new(ns: Namespace) -> Self {
+        Self {
+            ns,
+            funcs_to_convert: Vec::new(),
+            method_receivers: HashMap::new(),
+            ignored_apis: ApiVec::new(),
+        }
+    }
+
+    /// Record information from foreign mod items encountered
+    /// in bindgen output.
+    pub(crate) fn convert_foreign_mod_items(&mut self, foreign_mod_items: Vec<ForeignItem>) {
+        let mut extra_apis = ApiVec::new();
+        for i in foreign_mod_items {
+            report_any_error(&self.ns.clone(), &mut extra_apis, || {
+                self.parse_foreign_item(i)
+            });
+        }
+        self.ignored_apis.append(&mut extra_apis);
+    }
+
+    fn parse_foreign_item(&mut self, i: ForeignItem) -> Result<(), ConvertErrorWithContext> {
+        match i {
+            ForeignItem::Fn(item) => {
+                let annotations = BindgenSemanticAttributes::new(&item.attrs);
+                let doc_attrs = get_doc_attrs(&item.attrs);
+                self.funcs_to_convert.push(FuncToConvert {
+                    provenance: Provenance::Bindgen,
+                    self_ty: None,
+                    ident: item.sig.ident,
+                    doc_attrs,
+                    inputs: item.sig.inputs,
+                    output: item.sig.output,
+                    vis: item.vis,
+                    virtualness: annotations.get_virtualness(),
+                    cpp_vis: annotations.get_cpp_visibility(),
+                    special_member: annotations.special_member_kind(),
+                    unused_template_param: annotations
+                        .has_attr("incomprehensible_param_in_arg_or_return"),
+                    references: annotations.get_reference_parameters_and_return(),
+                    original_name: annotations.get_original_name(),
+                    synthesized_this_type: None,
+                    add_to_trait: None,
+                    is_deleted: annotations.has_attr("deleted"),
+                    synthetic_cpp: None,
+                    variadic: item.sig.variadic.is_some(),
+                });
+                Ok(())
+            }
+            ForeignItem::Static(item) => Err(ConvertErrorWithContext(
+                ConvertError::StaticData(item.ident.to_string()),
+                Some(ErrorContext::new_for_item(item.ident)),
+            )),
+            _ => Err(ConvertErrorWithContext(
+                ConvertError::UnexpectedForeignItem,
+                None,
+            )),
+        }
+    }
+
+    /// Record information from impl blocks encountered in bindgen
+    /// output.
+    pub(crate) fn convert_impl_items(&mut self, imp: ItemImpl) {
+        let ty_id = match *imp.self_ty {
+            Type::Path(typ) => typ.path.segments.last().unwrap().ident.clone(),
+            _ => return,
+        };
+        for i in imp.items {
+            if let ImplItem::Method(itm) = i {
+                let effective_fun_name = match get_called_function(&itm.block) {
+                    Some(id) => id.clone(),
+                    None => itm.sig.ident,
+                };
+                self.method_receivers.insert(
+                    effective_fun_name,
+                    QualifiedName::new(&self.ns, ty_id.clone()),
+                );
+            }
+        }
+    }
+
+    /// Indicate that all foreign mods and all impl blocks have been
+    /// fed into us, and we should process that information to generate
+    /// the resulting APIs.
+    pub(crate) fn finished(mut self, apis: &mut ApiVec<NullPhase>) {
+        apis.append(&mut self.ignored_apis);
+        while !self.funcs_to_convert.is_empty() {
+            let mut fun = self.funcs_to_convert.remove(0);
+            fun.self_ty = self.method_receivers.get(&fun.ident).cloned();
+            apis.push(UnanalyzedApi::Function {
+                name: ApiName::new_with_cpp_name(
+                    &self.ns,
+                    fun.ident.clone(),
+                    fun.original_name.clone(),
+                ),
+                fun: Box::new(fun),
+                analysis: (),
+            })
+        }
+    }
+}
+
+/// bindgen sometimes generates an impl fn called a which calls
+/// a function called a1(), if it's dealing with conflicting names.
+/// We actually care about the name a1, so we have to parse the
+/// name of the actual function call inside the block's body.
+fn get_called_function(block: &Block) -> Option<&Ident> {
+    match block.stmts.first() {
+        Some(Stmt::Expr(Expr::Call(ExprCall { func, .. }))) => match **func {
+            Expr::Path(ref exp) => exp.path.segments.first().map(|ps| &ps.ident),
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::get_called_function;
+    use syn::parse_quote;
+    use syn::Block;
+
+    #[test]
+    fn test_get_called_function() {
+        let b: Block = parse_quote! {
+            {
+                call_foo()
+            }
+        };
+        assert_eq!(get_called_function(&b).unwrap().to_string(), "call_foo");
+    }
+}
