about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-08-19 14:18:25 +1000
committerGitHub <noreply@github.com>2025-08-19 14:18:25 +1000
commit8748d8e7d5b63932e3062361f736ff436c86be1f (patch)
treed4cea4efea98a8e0454e8c32b9c76498375669f6
parent8945924d77065c96d35f81bc19a0b9040664bb57 (diff)
parentcf8ec6798f53a67b811a08f0dd45646f1e075126 (diff)
downloadrust-8748d8e7d5b63932e3062361f736ff436c86be1f.tar.gz
rust-8748d8e7d5b63932e3062361f736ff436c86be1f.zip
Rollup merge of #145484 - Zalathar:archive-builder, r=bjorn3
Remove `LlvmArchiveBuilder` and supporting code/bindings

Switching over to the newer Rust-based `ArArchiveBuilder` happened in rust-lang/rust#128936, a year ago.

Per the comment in `new_archive_builder`, that seems like enough time to justify removing the older, unused `LlvmArchiveBuilder` implementation and its associated bindings.

Fixes rust-lang/rust#128955.
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs183
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs94
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs46
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs17
-rw-r--r--compiler/rustc_llvm/build.rs1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp208
6 files changed, 6 insertions, 543 deletions
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 0a161442933..7a340ae83f3 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -1,104 +1,21 @@
 //! A helper class for dealing with static archives
 
-use std::ffi::{CStr, CString, c_char, c_void};
-use std::path::{Path, PathBuf};
-use std::{io, mem, ptr, str};
+use std::ffi::{CStr, c_char, c_void};
+use std::io;
 
 use rustc_codegen_ssa::back::archive::{
-    ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder,
-    DEFAULT_OBJECT_READER, ObjectReader, UnknownArchiveKind, try_extract_macho_fat_archive,
+    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER, ObjectReader,
 };
 use rustc_session::Session;
 
-use crate::llvm::archive_ro::{ArchiveRO, Child};
-use crate::llvm::{self, ArchiveKind, last_error};
-
-/// Helper for adding many files to an archive.
-#[must_use = "must call build() to finish building the archive"]
-pub(crate) struct LlvmArchiveBuilder<'a> {
-    sess: &'a Session,
-    additions: Vec<Addition>,
-}
-
-enum Addition {
-    File { path: PathBuf, name_in_archive: String },
-    Archive { path: PathBuf, archive: ArchiveRO, skip: Box<dyn FnMut(&str) -> bool> },
-}
-
-impl Addition {
-    fn path(&self) -> &Path {
-        match self {
-            Addition::File { path, .. } | Addition::Archive { path, .. } => path,
-        }
-    }
-}
-
-fn is_relevant_child(c: &Child<'_>) -> bool {
-    match c.name() {
-        Some(name) => !name.contains("SYMDEF"),
-        None => false,
-    }
-}
-
-impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
-    fn add_archive(
-        &mut self,
-        archive: &Path,
-        skip: Box<dyn FnMut(&str) -> bool + 'static>,
-    ) -> io::Result<()> {
-        let mut archive = archive.to_path_buf();
-        if self.sess.target.llvm_target.contains("-apple-macosx") {
-            if let Some(new_archive) = try_extract_macho_fat_archive(self.sess, &archive)? {
-                archive = new_archive
-            }
-        }
-        let archive_ro = match ArchiveRO::open(&archive) {
-            Ok(ar) => ar,
-            Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
-        };
-        if self.additions.iter().any(|ar| ar.path() == archive) {
-            return Ok(());
-        }
-        self.additions.push(Addition::Archive {
-            path: archive,
-            archive: archive_ro,
-            skip: Box::new(skip),
-        });
-        Ok(())
-    }
-
-    /// Adds an arbitrary file to this archive
-    fn add_file(&mut self, file: &Path) {
-        let name = file.file_name().unwrap().to_str().unwrap();
-        self.additions
-            .push(Addition::File { path: file.to_path_buf(), name_in_archive: name.to_owned() });
-    }
-
-    /// Combine the provided files, rlibs, and native libraries into a single
-    /// `Archive`.
-    fn build(mut self: Box<Self>, output: &Path) -> bool {
-        match self.build_with_llvm(output) {
-            Ok(any_members) => any_members,
-            Err(error) => {
-                self.sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error })
-            }
-        }
-    }
-}
+use crate::llvm;
 
 pub(crate) struct LlvmArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
-        // Keeping LlvmArchiveBuilder around in case of a regression caused by using
-        // ArArchiveBuilder.
-        // FIXME(#128955) remove a couple of months after #128936 gets merged in case
-        // no regression is found.
-        if false {
-            Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
-        } else {
-            Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
-        }
+        // Use the `object` crate to build archives, with a little bit of help from LLVM.
+        Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
     }
 }
 
@@ -178,91 +95,3 @@ fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
 fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
     unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
 }
-
-impl<'a> LlvmArchiveBuilder<'a> {
-    fn build_with_llvm(&mut self, output: &Path) -> io::Result<bool> {
-        let kind = &*self.sess.target.archive_format;
-        let kind = kind
-            .parse::<ArchiveKind>()
-            .map_err(|_| kind)
-            .unwrap_or_else(|kind| self.sess.dcx().emit_fatal(UnknownArchiveKind { kind }));
-
-        let mut additions = mem::take(&mut self.additions);
-        // Values in the `members` list below will contain pointers to the strings allocated here.
-        // So they need to get dropped after all elements of `members` get freed.
-        let mut strings = Vec::new();
-        let mut members = Vec::new();
-
-        let dst = CString::new(output.to_str().unwrap())?;
-
-        unsafe {
-            for addition in &mut additions {
-                match addition {
-                    Addition::File { path, name_in_archive } => {
-                        let path = CString::new(path.to_str().unwrap())?;
-                        let name = CString::new(name_in_archive.as_bytes())?;
-                        members.push(llvm::LLVMRustArchiveMemberNew(
-                            path.as_ptr(),
-                            name.as_ptr(),
-                            None,
-                        ));
-                        strings.push(path);
-                        strings.push(name);
-                    }
-                    Addition::Archive { archive, skip, .. } => {
-                        for child in archive.iter() {
-                            let child = child.map_err(string_to_io_error)?;
-                            if !is_relevant_child(&child) {
-                                continue;
-                            }
-                            let child_name = child.name().unwrap();
-                            if skip(child_name) {
-                                continue;
-                            }
-
-                            // It appears that LLVM's archive writer is a little
-                            // buggy if the name we pass down isn't just the
-                            // filename component, so chop that off here and
-                            // pass it in.
-                            //
-                            // See LLVM bug 25877 for more info.
-                            let child_name =
-                                Path::new(child_name).file_name().unwrap().to_str().unwrap();
-                            let name = CString::new(child_name)?;
-                            let m = llvm::LLVMRustArchiveMemberNew(
-                                ptr::null(),
-                                name.as_ptr(),
-                                Some(child.raw),
-                            );
-                            members.push(m);
-                            strings.push(name);
-                        }
-                    }
-                }
-            }
-
-            let r = llvm::LLVMRustWriteArchive(
-                dst.as_ptr(),
-                members.len() as libc::size_t,
-                members.as_ptr() as *const &_,
-                true,
-                kind,
-                self.sess.target.arch == "arm64ec",
-            );
-            let ret = if r.into_result().is_err() {
-                let msg = last_error().unwrap_or_else(|| "failed to write archive".into());
-                Err(io::Error::new(io::ErrorKind::Other, msg))
-            } else {
-                Ok(!members.is_empty())
-            };
-            for member in members {
-                llvm::LLVMRustArchiveMemberFree(member);
-            }
-            ret
-        }
-    }
-}
-
-fn string_to_io_error(s: String) -> io::Error {
-    io::Error::new(io::ErrorKind::Other, format!("bad archive: {s}"))
-}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
deleted file mode 100644
index 51bcc4d123d..00000000000
--- a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-//! A wrapper around LLVM's archive (.a) code
-
-use std::path::Path;
-use std::{slice, str};
-
-use rustc_fs_util::path_to_c_string;
-
-pub(crate) struct ArchiveRO {
-    pub raw: &'static mut super::Archive,
-}
-
-unsafe impl Send for ArchiveRO {}
-
-pub(crate) struct Iter<'a> {
-    raw: &'a mut super::ArchiveIterator<'a>,
-}
-
-pub(crate) struct Child<'a> {
-    pub raw: &'a mut super::ArchiveChild<'a>,
-}
-
-impl ArchiveRO {
-    /// Opens a static archive for read-only purposes. This is more optimized
-    /// than the `open` method because it uses LLVM's internal `Archive` class
-    /// rather than shelling out to `ar` for everything.
-    ///
-    /// If this archive is used with a mutable method, then an error will be
-    /// raised.
-    pub(crate) fn open(dst: &Path) -> Result<ArchiveRO, String> {
-        unsafe {
-            let s = path_to_c_string(dst);
-            let ar = super::LLVMRustOpenArchive(s.as_ptr()).ok_or_else(|| {
-                super::last_error().unwrap_or_else(|| "failed to open archive".to_owned())
-            })?;
-            Ok(ArchiveRO { raw: ar })
-        }
-    }
-
-    pub(crate) fn iter(&self) -> Iter<'_> {
-        unsafe { Iter { raw: super::LLVMRustArchiveIteratorNew(self.raw) } }
-    }
-}
-
-impl Drop for ArchiveRO {
-    fn drop(&mut self) {
-        unsafe {
-            super::LLVMRustDestroyArchive(&mut *(self.raw as *mut _));
-        }
-    }
-}
-
-impl<'a> Iterator for Iter<'a> {
-    type Item = Result<Child<'a>, String>;
-
-    fn next(&mut self) -> Option<Result<Child<'a>, String>> {
-        unsafe {
-            match super::LLVMRustArchiveIteratorNext(self.raw) {
-                Some(raw) => Some(Ok(Child { raw })),
-                None => super::last_error().map(Err),
-            }
-        }
-    }
-}
-
-impl<'a> Drop for Iter<'a> {
-    fn drop(&mut self) {
-        unsafe {
-            super::LLVMRustArchiveIteratorFree(&mut *(self.raw as *mut _));
-        }
-    }
-}
-
-impl<'a> Child<'a> {
-    pub(crate) fn name(&self) -> Option<&'a str> {
-        unsafe {
-            let mut name_len = 0;
-            let name_ptr = super::LLVMRustArchiveChildName(self.raw, &mut name_len);
-            if name_ptr.is_null() {
-                None
-            } else {
-                let name = slice::from_raw_parts(name_ptr as *const u8, name_len as usize);
-                str::from_utf8(name).ok().map(|s| s.trim())
-            }
-        }
-    }
-}
-
-impl<'a> Drop for Child<'a> {
-    fn drop(&mut self) {
-        unsafe {
-            super::LLVMRustArchiveChildFree(&mut *(self.raw as *mut _));
-        }
-    }
-}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index d7316b11a90..55d26a97e2d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -616,17 +616,6 @@ pub(crate) enum DiagnosticLevel {
     Remark,
 }
 
-/// LLVMRustArchiveKind
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub(crate) enum ArchiveKind {
-    K_GNU,
-    K_BSD,
-    K_DARWIN,
-    K_COFF,
-    K_AIXBIG,
-}
-
 unsafe extern "C" {
     // LLVMRustThinLTOData
     pub(crate) type ThinLTOData;
@@ -775,19 +764,12 @@ pub(crate) struct Builder<'a>(InvariantOpaque<'a>);
 pub(crate) struct PassManager<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
     pub type TargetMachine;
-    pub(crate) type Archive;
 }
-#[repr(C)]
-pub(crate) struct ArchiveIterator<'a>(InvariantOpaque<'a>);
-#[repr(C)]
-pub(crate) struct ArchiveChild<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
     pub(crate) type Twine;
     pub(crate) type DiagnosticInfo;
     pub(crate) type SMDiagnostic;
 }
-#[repr(C)]
-pub(crate) struct RustArchiveMember<'a>(InvariantOpaque<'a>);
 /// Opaque pointee of `LLVMOperandBundleRef`.
 #[repr(C)]
 pub(crate) struct OperandBundle<'a>(InvariantOpaque<'a>);
@@ -2510,19 +2492,6 @@ unsafe extern "C" {
     pub(crate) fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
     pub(crate) fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
 
-    pub(crate) fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
-    pub(crate) fn LLVMRustArchiveIteratorNew(AR: &Archive) -> &mut ArchiveIterator<'_>;
-    pub(crate) fn LLVMRustArchiveIteratorNext<'a>(
-        AIR: &ArchiveIterator<'a>,
-    ) -> Option<&'a mut ArchiveChild<'a>>;
-    pub(crate) fn LLVMRustArchiveChildName(
-        ACR: &ArchiveChild<'_>,
-        size: &mut size_t,
-    ) -> *const c_char;
-    pub(crate) fn LLVMRustArchiveChildFree<'a>(ACR: &'a mut ArchiveChild<'a>);
-    pub(crate) fn LLVMRustArchiveIteratorFree<'a>(AIR: &'a mut ArchiveIterator<'a>);
-    pub(crate) fn LLVMRustDestroyArchive(AR: &'static mut Archive);
-
     pub(crate) fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString);
 
     pub(crate) fn LLVMRustUnpackOptimizationDiagnostic<'a>(
@@ -2560,21 +2529,6 @@ unsafe extern "C" {
         num_ranges: &mut usize,
     ) -> bool;
 
-    pub(crate) fn LLVMRustWriteArchive(
-        Dst: *const c_char,
-        NumMembers: size_t,
-        Members: *const &RustArchiveMember<'_>,
-        WriteSymbtab: bool,
-        Kind: ArchiveKind,
-        isEC: bool,
-    ) -> LLVMRustResult;
-    pub(crate) fn LLVMRustArchiveMemberNew<'a>(
-        Filename: *const c_char,
-        Name: *const c_char,
-        Child: Option<&ArchiveChild<'a>>,
-    ) -> &'a mut RustArchiveMember<'a>;
-    pub(crate) fn LLVMRustArchiveMemberFree<'a>(Member: &'a mut RustArchiveMember<'a>);
-
     pub(crate) fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine);
 
     pub(crate) fn LLVMRustPositionBuilderPastAllocas<'a>(B: &Builder<'a>, Fn: &'a Value);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index 0ea0af0c9af..7fea7b79a8c 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -3,7 +3,6 @@
 use std::ffi::{CStr, CString};
 use std::num::NonZero;
 use std::ptr;
-use std::str::FromStr;
 use std::string::FromUtf8Error;
 
 use libc::c_uint;
@@ -16,7 +15,6 @@ pub(crate) use self::MetadataType::*;
 pub(crate) use self::ffi::*;
 use crate::common::AsCCharPtr;
 
-pub(crate) mod archive_ro;
 pub(crate) mod diagnostic;
 pub(crate) mod enzyme_ffi;
 mod ffi;
@@ -152,21 +150,6 @@ pub(crate) enum CodeGenOptSize {
     CodeGenOptSizeAggressive = 2,
 }
 
-impl FromStr for ArchiveKind {
-    type Err = ();
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "gnu" => Ok(ArchiveKind::K_GNU),
-            "bsd" => Ok(ArchiveKind::K_BSD),
-            "darwin" => Ok(ArchiveKind::K_DARWIN),
-            "coff" => Ok(ArchiveKind::K_COFF),
-            "aix_big" => Ok(ArchiveKind::K_AIXBIG),
-            _ => Err(()),
-        }
-    }
-}
-
 pub(crate) fn SetInstructionCallConv(instr: &Value, cc: CallConv) {
     unsafe {
         LLVMSetInstructionCallConv(instr, cc as c_uint);
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 1394edcee6b..d01f79dcade 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -226,7 +226,6 @@ fn main() {
     rerun_if_changed_anything_in_dir(Path::new("llvm-wrapper"));
     cfg.file("llvm-wrapper/PassWrapper.cpp")
         .file("llvm-wrapper/RustWrapper.cpp")
-        .file("llvm-wrapper/ArchiveWrapper.cpp")
         .file("llvm-wrapper/CoverageMappingWrapper.cpp")
         .file("llvm-wrapper/SymbolWrapper.cpp")
         .file("llvm-wrapper/Linker.cpp")
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
deleted file mode 100644
index feac6a5649c..00000000000
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-#include "LLVMWrapper.h"
-
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/ArchiveWriter.h"
-#include "llvm/Support/Path.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-struct RustArchiveMember {
-  const char *Filename;
-  const char *Name;
-  Archive::Child Child;
-
-  RustArchiveMember()
-      : Filename(nullptr), Name(nullptr), Child(nullptr, nullptr, nullptr) {}
-  ~RustArchiveMember() {}
-};
-
-struct RustArchiveIterator {
-  bool First;
-  Archive::child_iterator Cur;
-  Archive::child_iterator End;
-  std::unique_ptr<Error> Err;
-
-  RustArchiveIterator(Archive::child_iterator Cur, Archive::child_iterator End,
-                      std::unique_ptr<Error> Err)
-      : First(true), Cur(Cur), End(End), Err(std::move(Err)) {}
-};
-
-enum class LLVMRustArchiveKind {
-  GNU,
-  BSD,
-  DARWIN,
-  COFF,
-  AIX_BIG,
-};
-
-static Archive::Kind fromRust(LLVMRustArchiveKind Kind) {
-  switch (Kind) {
-  case LLVMRustArchiveKind::GNU:
-    return Archive::K_GNU;
-  case LLVMRustArchiveKind::BSD:
-    return Archive::K_BSD;
-  case LLVMRustArchiveKind::DARWIN:
-    return Archive::K_DARWIN;
-  case LLVMRustArchiveKind::COFF:
-    return Archive::K_COFF;
-  case LLVMRustArchiveKind::AIX_BIG:
-    return Archive::K_AIXBIG;
-  default:
-    report_fatal_error("Bad ArchiveKind.");
-  }
-}
-
-typedef OwningBinary<Archive> *LLVMRustArchiveRef;
-typedef RustArchiveMember *LLVMRustArchiveMemberRef;
-typedef Archive::Child *LLVMRustArchiveChildRef;
-typedef Archive::Child const *LLVMRustArchiveChildConstRef;
-typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
-
-extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr = MemoryBuffer::getFile(
-      Path, /*IsText*/ false, /*RequiresNullTerminator=*/false);
-  if (!BufOr) {
-    LLVMRustSetLastError(BufOr.getError().message().c_str());
-    return nullptr;
-  }
-
-  Expected<std::unique_ptr<Archive>> ArchiveOr =
-      Archive::create(BufOr.get()->getMemBufferRef());
-
-  if (!ArchiveOr) {
-    LLVMRustSetLastError(toString(ArchiveOr.takeError()).c_str());
-    return nullptr;
-  }
-
-  OwningBinary<Archive> *Ret = new OwningBinary<Archive>(
-      std::move(ArchiveOr.get()), std::move(BufOr.get()));
-
-  return Ret;
-}
-
-extern "C" void LLVMRustDestroyArchive(LLVMRustArchiveRef RustArchive) {
-  delete RustArchive;
-}
-
-extern "C" LLVMRustArchiveIteratorRef
-LLVMRustArchiveIteratorNew(LLVMRustArchiveRef RustArchive) {
-  Archive *Archive = RustArchive->getBinary();
-  std::unique_ptr<Error> Err = std::make_unique<Error>(Error::success());
-  auto Cur = Archive->child_begin(*Err);
-  if (*Err) {
-    LLVMRustSetLastError(toString(std::move(*Err)).c_str());
-    return nullptr;
-  }
-  auto End = Archive->child_end();
-  return new RustArchiveIterator(Cur, End, std::move(Err));
-}
-
-extern "C" LLVMRustArchiveChildConstRef
-LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef RAI) {
-  if (RAI->Cur == RAI->End)
-    return nullptr;
-
-  // Advancing the iterator validates the next child, and this can
-  // uncover an error. LLVM requires that we check all Errors,
-  // so we only advance the iterator if we actually need to fetch
-  // the next child.
-  // This means we must not advance the iterator in the *first* call,
-  // but instead advance it *before* fetching the child in all later calls.
-  if (!RAI->First) {
-    ++RAI->Cur;
-    if (*RAI->Err) {
-      LLVMRustSetLastError(toString(std::move(*RAI->Err)).c_str());
-      return nullptr;
-    }
-  } else {
-    RAI->First = false;
-  }
-
-  if (RAI->Cur == RAI->End)
-    return nullptr;
-
-  const Archive::Child &Child = *RAI->Cur.operator->();
-  Archive::Child *Ret = new Archive::Child(Child);
-
-  return Ret;
-}
-
-extern "C" void LLVMRustArchiveChildFree(LLVMRustArchiveChildRef Child) {
-  delete Child;
-}
-
-extern "C" void LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef RAI) {
-  delete RAI;
-}
-
-extern "C" const char *
-LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
-  Expected<StringRef> NameOrErr = Child->getName();
-  if (!NameOrErr) {
-    // rustc_codegen_llvm currently doesn't use this error string, but it might
-    // be useful in the future, and in the meantime this tells LLVM that the
-    // error was not ignored and that it shouldn't abort the process.
-    LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
-    return nullptr;
-  }
-  StringRef Name = NameOrErr.get();
-  *Size = Name.size();
-  return Name.data();
-}
-
-extern "C" LLVMRustArchiveMemberRef
-LLVMRustArchiveMemberNew(char *Filename, char *Name,
-                         LLVMRustArchiveChildRef Child) {
-  RustArchiveMember *Member = new RustArchiveMember;
-  Member->Filename = Filename;
-  Member->Name = Name;
-  if (Child)
-    Member->Child = *Child;
-  return Member;
-}
-
-extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
-  delete Member;
-}
-
-extern "C" LLVMRustResult LLVMRustWriteArchive(
-    char *Dst, size_t NumMembers, const LLVMRustArchiveMemberRef *NewMembers,
-    bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) {
-
-  std::vector<NewArchiveMember> Members;
-  auto Kind = fromRust(RustKind);
-
-  for (size_t I = 0; I < NumMembers; I++) {
-    auto Member = NewMembers[I];
-    assert(Member->Name);
-    if (Member->Filename) {
-      Expected<NewArchiveMember> MOrErr =
-          NewArchiveMember::getFile(Member->Filename, true);
-      if (!MOrErr) {
-        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return LLVMRustResult::Failure;
-      }
-      MOrErr->MemberName = sys::path::filename(MOrErr->MemberName);
-      Members.push_back(std::move(*MOrErr));
-    } else {
-      Expected<NewArchiveMember> MOrErr =
-          NewArchiveMember::getOldMember(Member->Child, true);
-      if (!MOrErr) {
-        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return LLVMRustResult::Failure;
-      }
-      Members.push_back(std::move(*MOrErr));
-    }
-  }
-
-  auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab
-                                 : SymtabWritingMode::NoSymtab;
-  auto Result =
-      writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
-  if (!Result)
-    return LLVMRustResult::Success;
-  LLVMRustSetLastError(toString(std::move(Result)).c_str());
-
-  return LLVMRustResult::Failure;
-}