Pass a std::unique_ptr& to the create??? methods is lib/Object.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 23 Jun 2014 22:00:37 +0000 (22:00 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 23 Jun 2014 22:00:37 +0000 (22:00 +0000)
This makes the buffer ownership on error conditions very natural. The buffer
is only moved out of the argument if an object is constructed that now
owns the buffer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211546 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
include/llvm/Object/Binary.h
include/llvm/Object/ObjectFile.h
include/llvm/Object/SymbolicFile.h
lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
lib/Object/Archive.cpp
lib/Object/Binary.cpp
lib/Object/ELFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
lib/Object/MachOUniversal.cpp
lib/Object/Object.cpp
lib/Object/ObjectFile.cpp
lib/Object/SymbolicFile.cpp
tools/llvm-ar/llvm-ar.cpp
tools/llvm-dwarfdump/llvm-dwarfdump.cpp
tools/llvm-nm/llvm-nm.cpp
tools/llvm-objdump/MachODump.cpp

index a87a0064509c1698641e14751ff1e27ae751d867..258a885d4f6ec0a80a552d1e9f7032c9853f35c9 100644 (file)
@@ -128,7 +128,7 @@ public:
 /// @param Source The data to create the Binary from. Ownership is transferred
 ///        to the Binary if successful. If an error is returned,
 ///        Source is destroyed by createBinary before returning.
-ErrorOr<Binary *> createBinary(MemoryBuffer *Source,
+ErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> &Source,
                                LLVMContext *Context = nullptr);
 
 ErrorOr<Binary *> createBinary(StringRef Path);
index 62c5b9b77196d5b2b130dd96c43ab79bef3355a4..56799eb6814721290def8dffa734c2dadf024c61 100644 (file)
@@ -333,9 +333,11 @@ public:
   ///        return true.
   /// @brief Create ObjectFile from path.
   static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
-  static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
-                                                sys::fs::file_magic Type);
-  static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
+  static ErrorOr<ObjectFile *>
+  createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+                   sys::fs::file_magic Type);
+  static ErrorOr<ObjectFile *>
+  createObjectFile(std::unique_ptr<MemoryBuffer> &Object) {
     return createObjectFile(Object, sys::fs::file_magic::unknown);
   }
 
@@ -346,8 +348,10 @@ public:
 
 public:
   static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object);
-  static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object);
-  static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object);
+  static ErrorOr<ObjectFile *>
+  createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object);
+  static ErrorOr<ObjectFile *>
+  createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object);
 };
 
 // Inline function definitions.
index 5c2d956d695839a38ef06f0d6eda7c531eba8376..24908cde193e35b499a542928a5a393537ae2cde 100644 (file)
@@ -145,11 +145,12 @@ public:
   static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
                                                     LLVMContext &Context);
 
-  static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
-                                                    sys::fs::file_magic Type,
-                                                    LLVMContext *Context);
+  static ErrorOr<SymbolicFile *>
+  createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
+                     sys::fs::file_magic Type, LLVMContext *Context);
 
-  static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
+  static ErrorOr<SymbolicFile *>
+  createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) {
     return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
   }
   static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
index 4917b93a96e5fea1b343afdc5dcbd6b219ec610d..c3a21823bbc844422e719da5e35e1edf9b5808ae 100644 (file)
@@ -48,7 +48,8 @@ public:
   {
     // FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
     // and should probably be checked for failure.
-    ObjFile.reset(object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get());
+    std::unique_ptr<MemoryBuffer> Buf(Buffer->getMemBuffer());
+    ObjFile.reset(object::ObjectFile::createObjectFile(Buf).get());
   }
   ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)
   : ObjectImage(nullptr), ObjFile(std::move(Input))  {}
index cd8924920a87bcb2cecf428348bc3bb70daaad0a..cdf987a32086ff5f41fbd1f444518916c4bc932d 100644 (file)
@@ -183,10 +183,7 @@ Archive::Child::getAsBinary(LLVMContext *Context) const {
     return EC;
 
   std::unique_ptr<MemoryBuffer> Buff(BuffOrErr.get().release());
-  ErrorOr<std::unique_ptr<Binary>> Ret = createBinary(Buff.get(), Context);
-  if (!Ret.getError())
-    Buff.release();
-  return Ret;
+  return createBinary(Buff, Context);
 }
 
 ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
index 785b3d2318b3e331105b4d4aae5f6f2d09a1bb0d..ee6f58cd7500570e3770e1003e94b3153745cc11 100644 (file)
@@ -38,13 +38,13 @@ StringRef Binary::getFileName() const {
   return Data->getBufferIdentifier();
 }
 
-ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
+ErrorOr<Binary *> object::createBinary(std::unique_ptr<MemoryBuffer> &Buffer,
                                        LLVMContext *Context) {
   sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer());
 
   switch (Type) {
     case sys::fs::file_magic::archive:
-      return Archive::create(Buffer);
+      return Archive::create(Buffer.release());
     case sys::fs::file_magic::elf_relocatable:
     case sys::fs::file_magic::elf_executable:
     case sys::fs::file_magic::elf_shared_object:
@@ -65,7 +65,7 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
     case sys::fs::file_magic::bitcode:
       return ObjectFile::createSymbolicFile(Buffer, Type, Context);
     case sys::fs::file_magic::macho_universal_binary:
-      return MachOUniversalBinary::create(Buffer);
+      return MachOUniversalBinary::create(Buffer.release());
     case sys::fs::file_magic::unknown:
     case sys::fs::file_magic::windows_resource:
       // Unrecognized object file format.
@@ -78,5 +78,5 @@ ErrorOr<Binary *> object::createBinary(StringRef Path) {
   std::unique_ptr<MemoryBuffer> File;
   if (std::error_code EC = MemoryBuffer::getFileOrSTDIN(Path, File))
     return EC;
-  return createBinary(File.release());
+  return createBinary(File);
 }
index 295cb111c38acb781918a79e04fb12787febd085..a9165af79d6493678d57e744d1f2b9078cad072f 100644 (file)
@@ -17,8 +17,9 @@
 namespace llvm {
 using namespace object;
 
-ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
-  std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
+ErrorOr<ObjectFile *>
+ObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) {
+  std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj.get());
   std::size_t MaxAlignment =
     1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
 
@@ -27,41 +28,49 @@ ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 4)
-      R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(
+          Obj.release(), EC));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(
+          Obj.release(), EC));
     else
       return object_error::parse_failed;
   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 4)
-      R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj.release(),
+                                                                 EC));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj.release(),
+                                                                 EC));
     else
       return object_error::parse_failed;
   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 8)
-      R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(Obj, EC));
+      R.reset(
+          new ELFObjectFile<ELFType<support::big, 8, true>>(Obj.release(), EC));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(Obj, EC));
+      R.reset(
+          new ELFObjectFile<ELFType<support::big, 2, true>>(Obj.release(), EC));
     else
       return object_error::parse_failed;
   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 8)
-      R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(
+          Obj.release(), EC));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(
+          Obj.release(), EC));
     else
       return object_error::parse_failed;
   }
index 7fc02fb893f932096892d98481326c36ef507515..45fc5ea735ac03caafbf778d15b438b44273c52c 100644 (file)
@@ -1811,22 +1811,21 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
   }
 }
 
-ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
+ErrorOr<ObjectFile *>
+ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
   StringRef Magic = Buffer->getBuffer().slice(0, 4);
   std::error_code EC;
   std::unique_ptr<MachOObjectFile> Ret;
   if (Magic == "\xFE\xED\xFA\xCE")
-    Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
+    Ret.reset(new MachOObjectFile(Buffer.release(), false, false, EC));
   else if (Magic == "\xCE\xFA\xED\xFE")
-    Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
+    Ret.reset(new MachOObjectFile(Buffer.release(), true, false, EC));
   else if (Magic == "\xFE\xED\xFA\xCF")
-    Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
+    Ret.reset(new MachOObjectFile(Buffer.release(), false, true, EC));
   else if (Magic == "\xCF\xFA\xED\xFE")
-    Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
-  else {
-    delete Buffer;
+    Ret.reset(new MachOObjectFile(Buffer.release(), true, true, EC));
+  else
     return object_error::parse_failed;
-  }
 
   if (EC)
     return EC;
index 1f867046eba256bac4d5f0f1fe5e6a12ba3f0978..330454ac5a7b450e13ab4b82d1548e0841681759 100644 (file)
@@ -73,8 +73,8 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
     StringRef ParentData = Parent->getData();
     StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
     std::string ObjectName = Parent->getFileName().str();
-    MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
-        ObjectData, ObjectName, false);
+    std::unique_ptr<MemoryBuffer> ObjBuffer(
+        MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false));
     return ObjectFile::createMachOObjectFile(ObjBuffer);
   }
   return object_error::parse_failed;
index 7282f468b084508017a81185816d4a27078e1a85..567d87f7a0e56509f5c6d6add7a2173d9f4b61ed 100644 (file)
@@ -59,7 +59,9 @@ wrap(const relocation_iterator *SI) {
 
 // ObjectFile creation
 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
-  ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
+  std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
+  ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buf));
+  Buf.release();
   ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : nullptr;
   return wrap(Obj);
 }
index 738ea5fbb92b25c9aaa386183da562f0568ea300..ee2680e6ba040d293cf32e2456820a2b64a4db63 100644 (file)
@@ -45,8 +45,9 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
   return section_iterator(SectionRef(Sec, this));
 }
 
-ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
-                                                   sys::fs::file_magic Type) {
+ErrorOr<ObjectFile *>
+ObjectFile::createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+                             sys::fs::file_magic Type) {
   if (Type == sys::fs::file_magic::unknown)
     Type = sys::fs::identify_magic(Object->getBuffer());
 
@@ -76,7 +77,7 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
   case sys::fs::file_magic::coff_object:
   case sys::fs::file_magic::coff_import_library:
   case sys::fs::file_magic::pecoff_executable:
-    return createCOFFObjectFile(Object);
+    return createCOFFObjectFile(Object.release());
   }
   llvm_unreachable("Unexpected Object File Type");
 }
@@ -85,5 +86,5 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(StringRef ObjectPath) {
   std::unique_ptr<MemoryBuffer> File;
   if (std::error_code EC = MemoryBuffer::getFile(ObjectPath, File))
     return EC;
-  return createObjectFile(File.release());
+  return createObjectFile(File);
 }
index 48fea0256ef3b81e5c3c6121039bd27ac8b72075..46aba3cf059e50aa7030b3e63edc81f345bb44a2 100644 (file)
@@ -25,7 +25,8 @@ SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source)
 SymbolicFile::~SymbolicFile() {}
 
 ErrorOr<SymbolicFile *>
-SymbolicFile::createSymbolicFile(MemoryBuffer *Object, sys::fs::file_magic Type,
+SymbolicFile::createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
+                                 sys::fs::file_magic Type,
                                  LLVMContext *Context) {
   if (Type == sys::fs::file_magic::unknown)
     Type = sys::fs::identify_magic(Object->getBuffer());
@@ -33,7 +34,7 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, sys::fs::file_magic Type,
   switch (Type) {
   case sys::fs::file_magic::bitcode:
     if (Context)
-      return IRObjectFile::createIRObjectFile(Object, *Context);
+      return IRObjectFile::createIRObjectFile(Object.release(), *Context);
   // Fallthrough
   case sys::fs::file_magic::unknown:
   case sys::fs::file_magic::archive:
index a58ab8bce0e6dacc281bdd362cb6f7f2b0dc2aeb..3ca1a910740bb41b10d51e3f9b0df2c5f0a9965a 100644 (file)
@@ -685,7 +685,7 @@ static void writeStringTable(raw_fd_ostream &Out,
 
 static void
 writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
-                 ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
+                 MutableArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
                  std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) {
   unsigned StartOffset = 0;
   unsigned MemberNum = 0;
@@ -696,7 +696,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
   for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
                                               E = Members.end();
        I != E; ++I, ++MemberNum) {
-    MemoryBuffer *MemberBuffer = Buffers[MemberNum].get();
+    std::unique_ptr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum];
     ErrorOr<object::SymbolicFile *> ObjOrErr =
         object::SymbolicFile::createSymbolicFile(
             MemberBuffer, sys::fs::file_magic::unknown, &Context);
@@ -724,7 +724,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
       MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
       print32BE(Out, 0);
     }
-    Obj->releaseBuffer();
+    MemberBuffer.reset(Obj->releaseBuffer());
   }
   Out << NameOS.str();
 
index 29f0c8707a5b6ad7d8cbf58ef1b96dc503ab942c..0eb6e4f4304eb61f0681d527e9a51264a8b4159e 100644 (file)
@@ -73,7 +73,7 @@ static void DumpInput(const StringRef &Filename) {
     return;
   }
 
-  ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(Buff.release()));
+  ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buff));
   if (std::error_code EC = ObjOrErr.getError()) {
     errs() << Filename << ": " << EC.message() << '\n';
     return;
index fef3d5cbea1d469e8d8049664fa33c89ed5e99a7..a08f25a737dc104dd88496956784200b798b17c8 100644 (file)
@@ -726,7 +726,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
     return;
 
   LLVMContext &Context = getGlobalContext();
-  ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.get(), &Context);
+  ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context);
   if (error(BinaryOrErr.getError(), Filename))
     return;
   Buffer.release();
index 21c4c96d4c22f1a21462d9d3f1e6937b08c8b5ca..74fdfef67ceb220177018f5ce113ee8873a3e2ff 100644 (file)
@@ -203,7 +203,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
   }
 
   std::unique_ptr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>(
-      ObjectFile::createMachOObjectFile(Buff.release()).get()));
+      ObjectFile::createMachOObjectFile(Buff).get()));
 
   DisassembleInputMachO2(Filename, MachOOF.get());
 }
@@ -293,7 +293,7 @@ static void DisassembleInputMachO2(StringRef Filename,
         errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
         return;
       }
-      DbgObj = ObjectFile::createMachOObjectFile(Buf.release()).get();
+      DbgObj = ObjectFile::createMachOObjectFile(Buf).get();
     }
 
     // Setup the DIContext