Re-commit r247683: Replace Triple with a new TargetTuple in MCTargetDesc/* and relate...
[oota-llvm.git] / tools / dsymutil / BinaryHolder.h
index 04871b5d585501fa2abb6a0876f3178c2b878784..9d7b4bd8787f3cb126852e836c5ef94027d51003 100644 (file)
 #ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H
 #define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H
 
+#include "llvm/ADT/Triple.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Error.h"
+#include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/TimeValue.h"
 
 namespace llvm {
 namespace dsymutil {
@@ -35,69 +38,98 @@ namespace dsymutil {
 /// meaning that a mapping request will invalidate the previous memory
 /// mapping.
 class BinaryHolder {
-  std::unique_ptr<object::Archive> CurrentArchive;
+  std::vector<std::unique_ptr<object::Archive>> CurrentArchives;
   std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer;
-  std::unique_ptr<object::ObjectFile> CurrentObjectFile;
+  std::vector<std::unique_ptr<object::ObjectFile>> CurrentObjectFiles;
+  std::unique_ptr<object::MachOUniversalBinary> CurrentFatBinary;
   bool Verbose;
 
-  /// \brief Get the MemoryBufferRef for the file specification in \p
-  /// Filename from the current archive.
+  /// Get the MemoryBufferRefs for the file specification in \p
+  /// Filename from the current archive. Multiple buffers are returned
+  /// when there are multiple architectures available for the
+  /// requested file.
   ///
   /// This function performs no system calls, it just looks up a
   /// potential match for the given \p Filename in the currently
   /// mapped archive if there is one.
-  ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename);
+  ErrorOr<std::vector<MemoryBufferRef>>
+  GetArchiveMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
 
-  /// \brief Interpret Filename as an archive member specification,
-  /// map the corresponding archive to memory and return the
-  /// MemoryBufferRef corresponding to the described member.
-  ErrorOr<MemoryBufferRef> MapArchiveAndGetMemberBuffer(StringRef Filename);
+  /// Interpret Filename as an archive member specification map the
+  /// corresponding archive to memory and return the MemoryBufferRefs
+  /// corresponding to the described member. Multiple buffers are
+  /// returned when there are multiple architectures available for the
+  /// requested file.
+  ErrorOr<std::vector<MemoryBufferRef>>
+  MapArchiveAndGetMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
 
-  /// \brief Return the MemoryBufferRef that holds the memory
-  /// mapping for the given \p Filename. This function will try to
-  /// parse archive member specifications of the form
-  /// /path/to/archive.a(member.o).
+  /// Return the MemoryBufferRef that holds the memory mapping for the
+  /// given \p Filename. This function will try to parse archive
+  /// member specifications of the form /path/to/archive.a(member.o).
   ///
-  /// The returned MemoryBufferRef points to a buffer owned by this
+  /// The returned MemoryBufferRefs points to a buffer owned by this
   /// object. The buffer is valid until the next call to
   /// GetMemoryBufferForFile() on this object.
-  ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename);
+  /// Multiple buffers are returned when there are multiple
+  /// architectures available for the requested file.
+  ErrorOr<std::vector<MemoryBufferRef>>
+  GetMemoryBuffersForFile(StringRef Filename, sys::TimeValue Timestamp);
+
+  void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf);
+  ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T);
 
 public:
   BinaryHolder(bool Verbose) : Verbose(Verbose) {}
 
-  /// \brief Get the ObjectFile designated by the \p Filename. This
+  /// Get the ObjectFiles designated by the \p Filename. This
   /// might be an archive member specification of the form
   /// /path/to/archive.a(member.o).
   ///
   /// Calling this function invalidates the previous mapping owned by
-  /// the BinaryHolder.
-  ErrorOr<const object::ObjectFile &> GetObjectFile(StringRef Filename);
+  /// the BinaryHolder. Multiple buffers are returned when there are
+  /// multiple architectures available for the requested file.
+  ErrorOr<std::vector<const object::ObjectFile *>>
+  GetObjectFiles(StringRef Filename,
+                 sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime());
 
-  /// \brief Wraps GetObjectFile() to return a derived ObjectFile type.
+  /// Wraps GetObjectFiles() to return a derived ObjectFile type.
   template <typename ObjectFileType>
-  ErrorOr<const ObjectFileType &> GetFileAs(StringRef Filename) {
-    auto ErrOrObjFile = GetObjectFile(Filename);
+  ErrorOr<std::vector<const ObjectFileType *>>
+  GetFilesAs(StringRef Filename,
+             sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()) {
+    auto ErrOrObjFile = GetObjectFiles(Filename, Timestamp);
     if (auto Err = ErrOrObjFile.getError())
       return Err;
-    if (const auto *Derived = dyn_cast<ObjectFileType>(CurrentObjectFile.get()))
-      return *Derived;
-    return make_error_code(object::object_error::invalid_file_type);
+
+    std::vector<const ObjectFileType *> Objects;
+    Objects.reserve((*ErrOrObjFile).size());
+    for (const auto &Obj : *ErrOrObjFile) {
+      const auto *Derived = dyn_cast<ObjectFileType>(Obj);
+      if (!Derived)
+        return make_error_code(object::object_error::invalid_file_type);
+      Objects.push_back(Derived);
+    }
+    return std::move(Objects);
   }
 
-  /// \brief Access the currently owned ObjectFile. As successfull
-  /// call to GetObjectFile() or GetFileAs() must have been performed
-  /// before calling this.
-  const object::ObjectFile &Get() {
-    assert(CurrentObjectFile);
-    return *CurrentObjectFile;
+  /// Access the currently owned ObjectFile with architecture \p T. As
+  /// successfull call to GetObjectFiles() or GetFilesAs() must have
+  /// been performed before calling this.
+  ErrorOr<const object::ObjectFile &> Get(const Triple &T) {
+    return getObjfileForArch(T);
   }
 
-  /// \brief Access to a derived version of the currently owned
+  /// Access to a derived version of the currently owned
   /// ObjectFile. The conversion must be known to be valid.
-  template <typename ObjectFileType> const ObjectFileType &GetAs() {
-    return cast<ObjectFileType>(*CurrentObjectFile);
+  template <typename ObjectFileType>
+  ErrorOr<const ObjectFileType &> GetAs(const Triple &T) {
+    auto ErrOrObj = Get(T);
+    if (auto Err = ErrOrObj.getError())
+      return Err;
+    return cast<ObjectFileType>(*ErrOrObj);
   }
+
+  static Triple getTriple(const object::MachOObjectFile &Obj);
 };
 }
 }