[llvm] 96c6604 - Revert "[llvm-libtool-darwin] Print a warning if object file names are repeated"

Shoaib Meenai via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 11 22:03:51 PST 2022


Author: Shoaib Meenai
Date: 2022-01-11T22:02:59-08:00
New Revision: 96c66040125e87808b23410632b1a6a34547b4e3

URL: https://github.com/llvm/llvm-project/commit/96c66040125e87808b23410632b1a6a34547b4e3
DIFF: https://github.com/llvm/llvm-project/commit/96c66040125e87808b23410632b1a6a34547b4e3.diff

LOG: Revert "[llvm-libtool-darwin] Print a warning if object file names are repeated"

This reverts commit 4993eff3e253a1c04e1a1a2fa5d68f6b33423419.

Tests are failing on Windows: http://45.33.8.238/win/52360/step_11.txt.
We'll need to account for forward slashes vs. backslashes.

Added: 
    

Modified: 
    llvm/test/tools/llvm-libtool-darwin/L-and-l.test
    llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
    llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
    llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-libtool-darwin/L-and-l.test b/llvm/test/tools/llvm-libtool-darwin/L-and-l.test
index e92501e779f9..182b923b4ec8 100644
--- a/llvm/test/tools/llvm-libtool-darwin/L-and-l.test
+++ b/llvm/test/tools/llvm-libtool-darwin/L-and-l.test
@@ -62,20 +62,6 @@
 # RUN: llvm-nm --print-armap %t.lib | \
 # RUN:   FileCheck %s --check-prefix=SINGLE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
-## Check that if two 
diff erent files with the same names are explicitly
-## specified, the command gives a warning.
-# RUN: cp %t-input2.o %t/dirname
-# RUN: llvm-libtool-darwin -static -o %t.lib \
-# RUN:   %t/dirname/%basename_t.tmp-input2.o %t-input2.o 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=DUPLICATE-INPUT \
-# RUN:     -DFILE=%basename_t.tmp-input2.o \
-# RUN:     -DINPUTA=%t/dirname/%basename_t.tmp-input2.o \
-# RUN:     -DINPUTB=%t-input2.o
-
-# DUPLICATE-INPUT:     warning: file '[[FILE]]' was specified multiple times.
-# DUPLICATE-INPUT-DAG: [[INPUTA]]
-# DUPLICATE-INPUT-DAG: [[INPUTB]]
-
 ## -l option combined with an input file:
 # RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o -linput2 -L%t/dirname
 # RUN: llvm-ar t %t.lib | \
@@ -83,23 +69,22 @@
 # RUN: llvm-nm --print-armap %t.lib | \
 # RUN:   FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
-## Specify the same file with a -l option and an input file:
-# RUN: rm -rf %t/copy
-# RUN: mkdir -p %t/copy
-# RUN: cp %t-input1.o %t/copy
-# RUN: llvm-libtool-darwin -static -o %t.lib \
-# RUN:   %t/copy/%basename_t.tmp-input1.o -l%basename_t.tmp-input1.o -L%t/copy 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=DUPLICATE-INPUT -DFILE=%basename_t.tmp-input1.o \
-# RUN:     -DINPUTA=%t/copy/%basename_t.tmp-input1.o \
-# RUN:     -DINPUTB=%t/copy/%basename_t.tmp-input1.o
-
 ## Specify same -l option twice:
-# RUN: llvm-libtool-darwin -static -o %t.lib -l%basename_t.tmp-input1.o \
-# RUN:  -l%basename_t.tmp-input1.o -L%t/copy 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=DUPLICATE-INPUT \
-# RUN:     -DFILE=%basename_t.tmp-input1.o \
-# RUN:     -DINPUTA=%t/copy/%basename_t.tmp-input1.o \
-# RUN:     -DINPUTB=%t/copy/%basename_t.tmp-input1.o
+## cctools' libtool raises a warning in this case.
+## The warning is not yet implemented for llvm-libtool-darwin.
+# RUN: llvm-libtool-darwin -static -o %t.lib -l%basename_t.tmp-input2.o -l%basename_t.tmp-input2.o -L%T
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DOUBLE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DOUBLE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
+
+# DOUBLE-NAMES:      [[PREFIX]]-input2.o
+# DOUBLE-NAMES-NEXT: [[PREFIX]]-input2.o
+
+# DOUBLE-SYMBOLS:      Archive map
+# DOUBLE-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# DOUBLE-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# DOUBLE-SYMBOLS-EMPTY:
 
 ## Check that an error is thrown when the input library cannot be found:
 # RUN: not llvm-libtool-darwin -static -o %t.lib -lfile-will-not-exist.o 2>&1 | \

diff  --git a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
index 3b133cdffba1..bfe2659e666d 100644
--- a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
+++ b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test
@@ -59,17 +59,6 @@
 # BOTH-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
 # BOTH-SYMBOLS-EMPTY:
 
-# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.bc %t.correct.ar %t-input1.o  2>&1 | \
-# RUN:   FileCheck %s --check-prefix=DUPLICATE-INPUT -DFILEA=%basename_t.tmp-input1.o \
-# RUN:   -DPATHA=%t-input1.o -DFILEB=%basename_t.tmp-x86_64.bc -DPATHB=%t-x86_64.bc -DPATHCORRECT=%t.correct.ar
-
-# DUPLICATE-INPUT:     warning: file '[[FILEA]]' was specified multiple times.
-# DUPLICATE-INPUT-DAG: [[PATHA]]
-# DUPLICATE-INPUT-DAG: [[PATHCORRECT]]
-# DUPLICATE-INPUT:     file '[[FILEB]]' was specified multiple times.
-# DUPLICATE-INPUT-DAG: [[PATHB]]
-# DUPLICATE-INPUT-DAG: [[PATHCORRECT]]
-
 ## Cannot read archive:
 # RUN: echo '!<arch>' >  %t-invalid-archive.lib
 # RUN: echo 'invalid' >> %t-invalid-archive.lib

diff  --git a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
index 916f569fa985..92baea34c7bc 100644
--- a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
+++ b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test
@@ -50,19 +50,21 @@
 # OVERWRITE-SYMBOLS-EMPTY:
 
 ## Duplicate a binary:
+## cctools' libtool raises a warning in this case.
+## The warning is not yet implemented for llvm-libtool-darwin.
 # RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o %t-input1.o 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=DUPLICATE-INPUT -DFILE=%basename_t.tmp-input1.o \
-# RUN:     -DINPUTA=%t-input1.o -DINPUTB=%t-input1.o
+# RUN:   FileCheck %s --allow-empty --implicit-check-not={{.}}
+# RUN: llvm-ar t %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DUPLICATE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp
+# RUN: llvm-nm --print-armap %t.lib | \
+# RUN:   FileCheck %s --check-prefix=DUPLICATE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines
 
-# DUPLICATE-INPUT:     warning: file '[[FILE]]' was specified multiple times.
-# DUPLICATE-INPUT-DAG: [[INPUTA]]
-# DUPLICATE-INPUT-DAG: [[INPUTB]]
+# DUPLICATE-NAMES:      [[PREFIX]]-input1.o
+# DUPLICATE-NAMES-NEXT: [[PREFIX]]-input2.o
+# DUPLICATE-NAMES-NEXT: [[PREFIX]]-input1.o
 
-## Make sure we can combine object files with the same name if
-## they are for 
diff erent architectures.
-# RUN: mkdir -p %t/arm64 %t/armv7
-# RUN: llvm-as %S/Inputs/arm64-ios.ll -o %t/arm64/out.bc
-# RUN: llvm-as %S/Inputs/armv7-ios.ll -o %t/armv7/out.bc
-## Command output should be empty.
-# RUN: llvm-libtool-darwin -static %t/arm64/out.bc %t/armv7/out.bc -o %t.lib 2>&1 | \
-# RUN:   FileCheck %s --implicit-check-not=warning: --allow-empty
+# DUPLICATE-SYMBOLS:      Archive map
+# DUPLICATE-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
+# DUPLICATE-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o
+# DUPLICATE-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o
+# DUPLICATE-SYMBOLS-EMPTY:

diff  --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index 9355d385d6f3..82c468823735 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -23,7 +23,6 @@
 #include "llvm/Support/LineIterator.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/TextAPI/Architecture.h"
 #include <map>
 #include <type_traits>
@@ -33,8 +32,8 @@ using namespace llvm::object;
 
 static LLVMContext LLVMCtx;
 
-class NewArchiveMemberList;
-typedef std::map<uint64_t, NewArchiveMemberList> MembersPerArchitectureMap;
+typedef std::map<uint64_t, std::vector<NewArchiveMember>>
+    MembersPerArchitectureMap;
 
 cl::OptionCategory LibtoolCategory("llvm-libtool-darwin Options");
 
@@ -213,50 +212,15 @@ struct MembersData {
   // members.
   MembersPerArchitectureMap MembersPerArchitecture;
   std::vector<std::unique_ptr<MemoryBuffer>> FileBuffers;
-};
-
-// NewArchiveMemberList instances serve as collections of archive members and
-// information about those members.
-class NewArchiveMemberList {
-  std::vector<NewArchiveMember> Members;
-  // This vector contains the file that each NewArchiveMember from Members came
-  // from. Therefore, it has the same size as Members.
-  std::vector<StringRef> Files;
 
-public:
-  // Add a NewArchiveMember and the file it came from to the list.
-  void push_back(NewArchiveMember &&Member, StringRef File) {
-    Members.push_back(std::move(Member));
-    Files.push_back(File);
-  }
-
-  ArrayRef<NewArchiveMember> getMembers() const { return Members; }
-
-  ArrayRef<StringRef> getFiles() const { return Files; }
-
-  static_assert(
-      std::is_same<decltype(MembersData::MembersPerArchitecture)::mapped_type,
-                   NewArchiveMemberList>(),
-      "This test makes sure NewArchiveMemberList is used by MembersData since "
-      "the following asserts test invariants required for MembersData.");
-  static_assert(
-      !std::is_copy_constructible<
-          decltype(NewArchiveMemberList::Members)::value_type>::value,
-      "MembersData::MembersPerArchitecture has a dependency on "
-      "MembersData::FileBuffers so it should not be able to "
-      "be copied on its own without FileBuffers. Unfortunately, "
-      "is_copy_constructible does not detect whether the container (ie vector) "
-      "of a non-copyable type is itself non-copyable so we have to test the "
-      "actual type of the stored data (ie, value_type).");
-  static_assert(
-      !std::is_copy_assignable<
-          decltype(NewArchiveMemberList::Members)::value_type>::value,
-      "MembersData::MembersPerArchitecture has a dependency on "
-      "MembersData::FileBuffers so it should not be able to "
-      "be copied on its own without FileBuffers. Unfortunately, "
-      "is_copy_constructible does not detect whether the container (ie vector) "
-      "of a non-copyable type is itself non-copyable so we have to test the "
-      "actual type of the stored data (ie, value_type).");
+  static_assert(!std::is_copy_constructible<NewArchiveMember>::value,
+                "MembersPerArchitecture has a dependency on FileBuffers so it "
+                "should not be able to be copied on its own without "
+                "FileBuffers.");
+  static_assert(!std::is_copy_assignable<NewArchiveMember>::value,
+                "MembersPerArchitecture has a dependency on FileBuffers so it "
+                "should not be able to be copied on its own without "
+                "FileBuffers.");
 };
 
 // MembersBuilder collects and organizes all members from the files provided by
@@ -267,7 +231,7 @@ class MembersBuilder {
 
   Expected<MembersData> build() {
     for (StringRef FileName : InputFiles)
-      if (Error E = AddMember(*this, FileName)())
+      if (Error E = addMember(FileName))
         return std::move(E);
 
     if (!ArchType.empty()) {
@@ -283,239 +247,227 @@ class MembersBuilder {
   }
 
 private:
-  class AddMember {
-    MembersBuilder &Builder;
-    StringRef FileName;
-
-  public:
-    AddMember(MembersBuilder &Builder, StringRef FileName)
-        : Builder(Builder), FileName(FileName) {}
-
-    Error operator()() {
-      Expected<NewArchiveMember> NewMemberOrErr =
-          NewArchiveMember::getFile(FileName, Builder.C.Deterministic);
-      if (!NewMemberOrErr)
-        return createFileError(FileName, NewMemberOrErr.takeError());
-      auto &NewMember = *NewMemberOrErr;
-
-      // For regular archives, use the basename of the object path for the
-      // member name.
-      NewMember.MemberName = sys::path::filename(NewMember.MemberName);
-      file_magic Magic = identify_magic(NewMember.Buf->getBuffer());
-
-      // Flatten archives.
-      if (Magic == file_magic::archive)
-        return addArchiveMembers(std::move(NewMember));
-
-      // Flatten universal files.
-      if (Magic == file_magic::macho_universal_binary)
-        return addUniversalMembers(std::move(NewMember));
-
-      // Bitcode files.
-      if (Magic == file_magic::bitcode)
-        return verifyAndAddIRObject(std::move(NewMember));
-
-      return verifyAndAddMachOObject(std::move(NewMember));
-    }
-
-  private:
-    // Check that a file's architecture [FileCPUType, FileCPUSubtype]
-    // matches the architecture specified under -arch_only flag.
-    bool acceptFileArch(uint32_t FileCPUType, uint32_t FileCPUSubtype) {
-      if (Builder.C.ArchCPUType != FileCPUType)
-        return false;
-
-      switch (Builder.C.ArchCPUType) {
-      case MachO::CPU_TYPE_ARM:
-      case MachO::CPU_TYPE_ARM64_32:
-      case MachO::CPU_TYPE_X86_64:
-        return Builder.C.ArchCPUSubtype == FileCPUSubtype;
-
-      case MachO::CPU_TYPE_ARM64:
-        if (Builder.C.ArchCPUSubtype == MachO::CPU_SUBTYPE_ARM64_ALL)
-          return FileCPUSubtype == MachO::CPU_SUBTYPE_ARM64_ALL ||
-                 FileCPUSubtype == MachO::CPU_SUBTYPE_ARM64_V8;
-        else
-          return Builder.C.ArchCPUSubtype == FileCPUSubtype;
-
-      default:
-        return true;
-      }
+  // Check that a file's architecture [FileCPUType, FileCPUSubtype]
+  // matches the architecture specified under -arch_only flag.
+  bool acceptFileArch(uint32_t FileCPUType, uint32_t FileCPUSubtype) {
+    if (C.ArchCPUType != FileCPUType)
+      return false;
+
+    switch (C.ArchCPUType) {
+    case MachO::CPU_TYPE_ARM:
+    case MachO::CPU_TYPE_ARM64_32:
+    case MachO::CPU_TYPE_X86_64:
+      return C.ArchCPUSubtype == FileCPUSubtype;
+
+    case MachO::CPU_TYPE_ARM64:
+      if (C.ArchCPUSubtype == MachO::CPU_SUBTYPE_ARM64_ALL)
+        return FileCPUSubtype == MachO::CPU_SUBTYPE_ARM64_ALL ||
+               FileCPUSubtype == MachO::CPU_SUBTYPE_ARM64_V8;
+      else
+        return C.ArchCPUSubtype == FileCPUSubtype;
+
+    default:
+      return true;
     }
+  }
 
-    Error verifyAndAddMachOObject(NewArchiveMember Member) {
-      auto MBRef = Member.Buf->getMemBufferRef();
-      Expected<std::unique_ptr<object::ObjectFile>> ObjOrErr =
-          object::ObjectFile::createObjectFile(MBRef);
+  Error verifyAndAddMachOObject(NewArchiveMember Member) {
+    auto MBRef = Member.Buf->getMemBufferRef();
+    Expected<std::unique_ptr<object::ObjectFile>> ObjOrErr =
+        object::ObjectFile::createObjectFile(MBRef);
 
-      // Throw error if not a valid object file.
-      if (!ObjOrErr)
-        return createFileError(Member.MemberName, ObjOrErr.takeError());
+    // Throw error if not a valid object file.
+    if (!ObjOrErr)
+      return createFileError(Member.MemberName, ObjOrErr.takeError());
 
-      // Throw error if not in Mach-O format.
-      if (!isa<object::MachOObjectFile>(**ObjOrErr))
-        return createStringError(std::errc::invalid_argument,
-                                 "'%s': format not supported",
-                                 Member.MemberName.data());
-
-      auto *O = dyn_cast<MachOObjectFile>(ObjOrErr->get());
-      uint32_t FileCPUType, FileCPUSubtype;
-      std::tie(FileCPUType, FileCPUSubtype) = MachO::getCPUTypeFromArchitecture(
-          MachO::getArchitectureFromName(O->getArchTriple().getArchName()));
-
-      // If -arch_only is specified then skip this file if it doesn't match
-      // the architecture specified.
-      if (!ArchType.empty() && !acceptFileArch(FileCPUType, FileCPUSubtype)) {
-        return Error::success();
-      }
+    // Throw error if not in Mach-O format.
+    if (!isa<object::MachOObjectFile>(**ObjOrErr))
+      return createStringError(std::errc::invalid_argument,
+                               "'%s': format not supported",
+                               Member.MemberName.data());
 
-      if (!NoWarningForNoSymbols && O->symbols().empty())
-        WithColor::warning() << Member.MemberName + " has no symbols\n";
+    auto *O = dyn_cast<MachOObjectFile>(ObjOrErr->get());
+    uint32_t FileCPUType, FileCPUSubtype;
+    std::tie(FileCPUType, FileCPUSubtype) = MachO::getCPUTypeFromArchitecture(
+        MachO::getArchitectureFromName(O->getArchTriple().getArchName()));
 
-      uint64_t FileCPUID = getCPUID(FileCPUType, FileCPUSubtype);
-      Builder.Data.MembersPerArchitecture[FileCPUID].push_back(
-          std::move(Member), FileName);
+    // If -arch_only is specified then skip this file if it doesn't match
+    // the architecture specified.
+    if (!ArchType.empty() && !acceptFileArch(FileCPUType, FileCPUSubtype)) {
       return Error::success();
     }
 
-    Error verifyAndAddIRObject(NewArchiveMember Member) {
-      auto MBRef = Member.Buf->getMemBufferRef();
-      Expected<std::unique_ptr<object::IRObjectFile>> IROrErr =
-          object::IRObjectFile::create(MBRef, LLVMCtx);
+    if (!NoWarningForNoSymbols && O->symbols().empty())
+      WithColor::warning() << Member.MemberName + " has no symbols\n";
 
-      // Throw error if not a valid IR object file.
-      if (!IROrErr)
-        return createFileError(Member.MemberName, IROrErr.takeError());
+    uint64_t FileCPUID = getCPUID(FileCPUType, FileCPUSubtype);
+    Data.MembersPerArchitecture[FileCPUID].push_back(std::move(Member));
+    return Error::success();
+  }
 
-      Triple TT = Triple(IROrErr->get()->getTargetTriple());
+  Error verifyAndAddIRObject(NewArchiveMember Member) {
+    auto MBRef = Member.Buf->getMemBufferRef();
+    Expected<std::unique_ptr<object::IRObjectFile>> IROrErr =
+        object::IRObjectFile::create(MBRef, LLVMCtx);
 
-      Expected<uint32_t> FileCPUTypeOrErr = MachO::getCPUType(TT);
-      if (!FileCPUTypeOrErr)
-        return FileCPUTypeOrErr.takeError();
+    // Throw error if not a valid IR object file.
+    if (!IROrErr)
+      return createFileError(Member.MemberName, IROrErr.takeError());
 
-      Expected<uint32_t> FileCPUSubTypeOrErr = MachO::getCPUSubType(TT);
-      if (!FileCPUSubTypeOrErr)
-        return FileCPUSubTypeOrErr.takeError();
+    Triple TT = Triple(IROrErr->get()->getTargetTriple());
 
-      // If -arch_only is specified then skip this file if it doesn't match
-      // the architecture specified.
-      if (!ArchType.empty() &&
-          !acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr)) {
-        return Error::success();
-      }
+    Expected<uint32_t> FileCPUTypeOrErr = MachO::getCPUType(TT);
+    if (!FileCPUTypeOrErr)
+      return FileCPUTypeOrErr.takeError();
 
-      uint64_t FileCPUID = getCPUID(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr);
-      Builder.Data.MembersPerArchitecture[FileCPUID].push_back(
-          std::move(Member), FileName);
+    Expected<uint32_t> FileCPUSubTypeOrErr = MachO::getCPUSubType(TT);
+    if (!FileCPUSubTypeOrErr)
+      return FileCPUSubTypeOrErr.takeError();
+
+    // If -arch_only is specified then skip this file if it doesn't match
+    // the architecture specified.
+    if (!ArchType.empty() &&
+        !acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr)) {
       return Error::success();
     }
 
-    Error addChildMember(const object::Archive::Child &M) {
-      Expected<NewArchiveMember> NewMemberOrErr =
-          NewArchiveMember::getOldMember(M, Builder.C.Deterministic);
-      if (!NewMemberOrErr)
-        return NewMemberOrErr.takeError();
-      auto &NewMember = *NewMemberOrErr;
+    uint64_t FileCPUID = getCPUID(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr);
+    Data.MembersPerArchitecture[FileCPUID].push_back(std::move(Member));
+    return Error::success();
+  }
 
-      file_magic Magic = identify_magic(NewMember.Buf->getBuffer());
+  Error addChildMember(const object::Archive::Child &M) {
+    Expected<NewArchiveMember> NewMemberOrErr =
+        NewArchiveMember::getOldMember(M, C.Deterministic);
+    if (!NewMemberOrErr)
+      return NewMemberOrErr.takeError();
+    auto &NewMember = *NewMemberOrErr;
 
-      if (Magic == file_magic::bitcode)
-        return verifyAndAddIRObject(std::move(NewMember));
+    file_magic Magic = identify_magic(NewMember.Buf->getBuffer());
 
-      return verifyAndAddMachOObject(std::move(NewMember));
-    }
+    if (Magic == file_magic::bitcode)
+      return verifyAndAddIRObject(std::move(NewMember));
 
-    Error processArchive(object::Archive &Lib) {
-      Error Err = Error::success();
-      for (const object::Archive::Child &Child : Lib.children(Err))
-        if (Error E = addChildMember(Child))
-          return createFileError(FileName, std::move(E));
-      if (Err)
-        return createFileError(FileName, std::move(Err));
+    return verifyAndAddMachOObject(std::move(NewMember));
+  }
 
-      return Error::success();
-    }
+  Error processArchive(object::Archive &Lib, StringRef FileName) {
+    Error Err = Error::success();
+    for (const object::Archive::Child &Child : Lib.children(Err))
+      if (Error E = addChildMember(Child))
+        return createFileError(FileName, std::move(E));
+    if (Err)
+      return createFileError(FileName, std::move(Err));
 
-    Error addArchiveMembers(NewArchiveMember NewMember) {
-      Expected<std::unique_ptr<Archive>> LibOrErr =
-          object::Archive::create(NewMember.Buf->getMemBufferRef());
-      if (!LibOrErr)
-        return createFileError(FileName, LibOrErr.takeError());
+    return Error::success();
+  }
 
-      if (Error E = processArchive(**LibOrErr))
-        return E;
+  Error addArchiveMembers(NewArchiveMember NewMember, StringRef FileName) {
+    Expected<std::unique_ptr<Archive>> LibOrErr =
+        object::Archive::create(NewMember.Buf->getMemBufferRef());
+    if (!LibOrErr)
+      return createFileError(FileName, LibOrErr.takeError());
 
-      // Update vector FileBuffers with the MemoryBuffers to transfer
-      // ownership.
-      Builder.Data.FileBuffers.push_back(std::move(NewMember.Buf));
-      return Error::success();
-    }
+    if (Error E = processArchive(**LibOrErr, FileName))
+      return E;
+
+    // Update vector FileBuffers with the MemoryBuffers to transfer
+    // ownership.
+    Data.FileBuffers.push_back(std::move(NewMember.Buf));
+    return Error::success();
+  }
 
-    Error addUniversalMembers(NewArchiveMember NewMember) {
-      Expected<std::unique_ptr<MachOUniversalBinary>> BinaryOrErr =
-          MachOUniversalBinary::create(NewMember.Buf->getMemBufferRef());
-      if (!BinaryOrErr)
-        return createFileError(FileName, BinaryOrErr.takeError());
-
-      auto *UO = BinaryOrErr->get();
-      for (const MachOUniversalBinary::ObjectForArch &O : UO->objects()) {
-
-        Expected<std::unique_ptr<MachOObjectFile>> MachOObjOrErr =
-            O.getAsObjectFile();
-        if (MachOObjOrErr) {
-          NewArchiveMember NewMember =
-              NewArchiveMember(MachOObjOrErr->get()->getMemoryBufferRef());
-          NewMember.MemberName = sys::path::filename(NewMember.MemberName);
-
-          if (Error E = verifyAndAddMachOObject(std::move(NewMember)))
-            return E;
-          continue;
-        }
-
-        Expected<std::unique_ptr<IRObjectFile>> IRObjectOrError =
-            O.getAsIRObject(LLVMCtx);
-        if (IRObjectOrError) {
-          // A universal file member can be a MachOObjectFile, an IRObject or an
-          // Archive. In case we can successfully cast the member as an
-          // IRObject, it is safe to throw away the error generated due to
-          // casting the object as a MachOObjectFile.
-          consumeError(MachOObjOrErr.takeError());
-
-          NewArchiveMember NewMember =
-              NewArchiveMember(IRObjectOrError->get()->getMemoryBufferRef());
-          NewMember.MemberName = sys::path::filename(NewMember.MemberName);
-
-          if (Error E = verifyAndAddIRObject(std::move(NewMember)))
-            return E;
-          continue;
-        }
-
-        Expected<std::unique_ptr<Archive>> ArchiveOrError = O.getAsArchive();
-        if (ArchiveOrError) {
-          // A universal file member can be a MachOObjectFile, an IRObject or an
-          // Archive. In case we can successfully cast the member as an Archive,
-          // it is safe to throw away the error generated due to casting the
-          // object as a MachOObjectFile.
-          consumeError(MachOObjOrErr.takeError());
-          consumeError(IRObjectOrError.takeError());
-
-          if (Error E = processArchive(**ArchiveOrError))
-            return E;
-          continue;
-        }
-
-        Error CombinedError = joinErrors(
-            ArchiveOrError.takeError(),
-            joinErrors(IRObjectOrError.takeError(), MachOObjOrErr.takeError()));
-        return createFileError(FileName, std::move(CombinedError));
+  Error addUniversalMembers(NewArchiveMember NewMember, StringRef FileName) {
+    Expected<std::unique_ptr<MachOUniversalBinary>> BinaryOrErr =
+        MachOUniversalBinary::create(NewMember.Buf->getMemBufferRef());
+    if (!BinaryOrErr)
+      return createFileError(FileName, BinaryOrErr.takeError());
+
+    auto *UO = BinaryOrErr->get();
+    for (const MachOUniversalBinary::ObjectForArch &O : UO->objects()) {
+
+      Expected<std::unique_ptr<MachOObjectFile>> MachOObjOrErr =
+          O.getAsObjectFile();
+      if (MachOObjOrErr) {
+        NewArchiveMember NewMember =
+            NewArchiveMember(MachOObjOrErr->get()->getMemoryBufferRef());
+        NewMember.MemberName = sys::path::filename(NewMember.MemberName);
+
+        if (Error E = verifyAndAddMachOObject(std::move(NewMember)))
+          return E;
+        continue;
       }
 
-      // Update vector FileBuffers with the MemoryBuffers to transfer
-      // ownership.
-      Builder.Data.FileBuffers.push_back(std::move(NewMember.Buf));
-      return Error::success();
+      Expected<std::unique_ptr<IRObjectFile>> IRObjectOrError =
+          O.getAsIRObject(LLVMCtx);
+      if (IRObjectOrError) {
+        // A universal file member can be a MachOObjectFile, an IRObject or an
+        // Archive. In case we can successfully cast the member as an IRObject,
+        // it is safe to throw away the error generated due to casting the
+        // object as a MachOObjectFile.
+        consumeError(MachOObjOrErr.takeError());
+
+        NewArchiveMember NewMember =
+            NewArchiveMember(IRObjectOrError->get()->getMemoryBufferRef());
+        NewMember.MemberName = sys::path::filename(NewMember.MemberName);
+
+        if (Error E = verifyAndAddIRObject(std::move(NewMember)))
+          return E;
+        continue;
+      }
+
+      Expected<std::unique_ptr<Archive>> ArchiveOrError = O.getAsArchive();
+      if (ArchiveOrError) {
+        // A universal file member can be a MachOObjectFile, an IRObject or an
+        // Archive. In case we can successfully cast the member as an Archive,
+        // it is safe to throw away the error generated due to casting the
+        // object as a MachOObjectFile.
+        consumeError(MachOObjOrErr.takeError());
+        consumeError(IRObjectOrError.takeError());
+
+        if (Error E = processArchive(**ArchiveOrError, FileName))
+          return E;
+        continue;
+      }
+
+      Error CombinedError = joinErrors(
+          ArchiveOrError.takeError(),
+          joinErrors(IRObjectOrError.takeError(), MachOObjOrErr.takeError()));
+      return createFileError(FileName, std::move(CombinedError));
     }
-  };
+
+    // Update vector FileBuffers with the MemoryBuffers to transfer
+    // ownership.
+    Data.FileBuffers.push_back(std::move(NewMember.Buf));
+    return Error::success();
+  }
+
+  Error addMember(StringRef FileName) {
+    Expected<NewArchiveMember> NewMemberOrErr =
+        NewArchiveMember::getFile(FileName, C.Deterministic);
+    if (!NewMemberOrErr)
+      return createFileError(FileName, NewMemberOrErr.takeError());
+    auto &NewMember = *NewMemberOrErr;
+
+    // For regular archives, use the basename of the object path for the member
+    // name.
+    NewMember.MemberName = sys::path::filename(NewMember.MemberName);
+    file_magic Magic = identify_magic(NewMember.Buf->getBuffer());
+
+    // Flatten archives.
+    if (Magic == file_magic::archive)
+      return addArchiveMembers(std::move(NewMember), FileName);
+
+    // Flatten universal files.
+    if (Magic == file_magic::macho_universal_binary)
+      return addUniversalMembers(std::move(NewMember), FileName);
+
+    // Bitcode files.
+    if (Magic == file_magic::bitcode)
+      return verifyAndAddIRObject(std::move(NewMember));
+
+    return verifyAndAddMachOObject(std::move(NewMember));
+  }
 
   MembersData Data;
   const Config &C;
@@ -535,41 +487,6 @@ buildSlices(ArrayRef<OwningBinary<Archive>> OutputBinaries) {
   return Slices;
 }
 
-static Error
-checkForDuplicates(const MembersPerArchitectureMap &MembersPerArch) {
-  for (const auto &M : MembersPerArch) {
-    ArrayRef<NewArchiveMember> Members = M.second.getMembers();
-    ArrayRef<StringRef> Files = M.second.getFiles();
-    StringMap<std::vector<StringRef>> MembersToFiles;
-    for (auto Iterators = std::make_pair(Members.begin(), Files.begin());
-         Iterators.first != Members.end();
-         ++Iterators.first, ++Iterators.second) {
-      assert(Iterators.second != Files.end() &&
-             "Files should be the same size as Members.");
-      MembersToFiles[Iterators.first->MemberName].push_back(*Iterators.second);
-    }
-
-    std::string ErrorData;
-    raw_string_ostream ErrorStream(ErrorData);
-    for (const auto &MemberToFile : MembersToFiles) {
-      if (MemberToFile.getValue().size() > 1) {
-        ErrorStream << "file '" << MemberToFile.getKey().str()
-                    << "' was specified multiple times.\n";
-
-        for (StringRef OriginalFile : MemberToFile.getValue())
-          ErrorStream << "in: " << OriginalFile.str() << '\n';
-
-        ErrorStream << '\n';
-      }
-    }
-
-    ErrorStream.flush();
-    if (ErrorData.size() > 0)
-      return createStringError(std::errc::invalid_argument, ErrorData.c_str());
-  }
-  return Error::success();
-}
-
 static Error createStaticLibrary(const Config &C) {
   MembersBuilder Builder(C);
   auto DataOrError = Builder.build();
@@ -578,19 +495,18 @@ static Error createStaticLibrary(const Config &C) {
 
   const auto &NewMembers = DataOrError->MembersPerArchitecture;
 
-  if (Error E = checkForDuplicates(NewMembers))
-    WithColor::defaultWarningHandler(std::move(E));
-
-  if (NewMembers.size() == 1)
-    return writeArchive(OutputFile, NewMembers.begin()->second.getMembers(),
+  if (NewMembers.size() == 1) {
+    return writeArchive(OutputFile, NewMembers.begin()->second,
                         /*WriteSymtab=*/true,
                         /*Kind=*/object::Archive::K_DARWIN, C.Deterministic,
                         /*Thin=*/false);
+  }
 
   SmallVector<OwningBinary<Archive>, 2> OutputBinaries;
-  for (const std::pair<const uint64_t, NewArchiveMemberList> &M : NewMembers) {
+  for (const std::pair<const uint64_t, std::vector<NewArchiveMember>> &M :
+       NewMembers) {
     Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
-        writeArchiveToBuffer(M.second.getMembers(),
+        writeArchiveToBuffer(M.second,
                              /*WriteSymtab=*/true,
                              /*Kind=*/object::Archive::K_DARWIN,
                              C.Deterministic,


        


More information about the llvm-commits mailing list