#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
exit(1);
}
-static void failIfError(error_code EC, Twine Context = "") {
+static void failIfError(std::error_code EC, Twine Context = "") {
if (!EC)
return;
int FD;
failIfError(
- sys::fs::openFileForWrite(Storage.c_str(), FD, sys::fs::F_Binary, Mode),
+ sys::fs::openFileForWrite(Storage.c_str(), FD, sys::fs::F_None, Mode),
Storage.c_str());
{
for (object::Archive::child_iterator I = OldArchive->child_begin(),
E = OldArchive->child_end();
I != E; ++I) {
- StringRef Name;
- failIfError(I->getName(Name));
+ ErrorOr<StringRef> NameOrErr = I->getName();
+ failIfError(NameOrErr.getError());
+ StringRef Name = NameOrErr.get();
if (!Members.empty() &&
std::find(Members.begin(), Members.end(), Name) == Members.end())
// Linux cannot open directories with open(2), although
// cygwin and *bsd can.
if (NewStatus.type() == sys::fs::file_type::directory_file)
- failIfError(error_code(errc::is_a_directory, posix_category()),
- NewFilename);
+ failIfError(make_error_code(errc::is_a_directory), NewFilename);
return NewFD;
}
Members[Pos] = NI;
}
-namespace {
-class HasName {
- StringRef Name;
-
-public:
- HasName(StringRef Name) : Name(Name) {}
- bool operator()(StringRef Path) { return Name == sys::path::filename(Path); }
-};
-}
-
enum InsertAction {
IA_AddOldMember,
IA_AddNewMeber,
if (Operation == QuickAppend || Members.empty())
return IA_AddOldMember;
- std::vector<std::string>::iterator MI =
- std::find_if(Members.begin(), Members.end(), HasName(Name));
+ std::vector<std::string>::iterator MI = std::find_if(
+ Members.begin(), Members.end(),
+ [Name](StringRef Path) { return Name == sys::path::filename(Path); });
if (MI == Members.end())
return IA_AddOldMember;
// We could try to optimize this to a fstat, but it is not a common
// operation.
sys::fs::file_status Status;
- failIfError(sys::fs::status(*MI, Status));
+ failIfError(sys::fs::status(*MI, Status), *MI);
if (Status.getLastModificationTime() < I->getLastModified()) {
if (PosName.empty())
return IA_AddOldMember;
E = OldArchive->child_end();
I != E; ++I) {
int Pos = Ret.size();
- StringRef Name;
- failIfError(I->getName(Name));
+ ErrorOr<StringRef> NameOrErr = I->getName();
+ failIfError(NameOrErr.getError());
+ StringRef Name = NameOrErr.get();
if (Name == PosName) {
assert(AddAfter || AddBefore);
if (AddBefore)
Out.seek(Pos);
}
-static void writeSymbolTable(
- raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
- ArrayRef<MemoryBuffer *> Buffers,
- std::vector<std::pair<unsigned, unsigned> > &MemberOffsetRefs) {
+static void
+writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
+ MutableArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
+ std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) {
unsigned StartOffset = 0;
unsigned MemberNum = 0;
- std::vector<StringRef> SymNames;
- std::vector<object::ObjectFile *> DeleteIt;
+ std::string NameBuf;
+ raw_string_ostream NameOS(NameBuf);
+ unsigned NumSyms = 0;
+ LLVMContext &Context = getGlobalContext();
for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
E = Members.end();
I != E; ++I, ++MemberNum) {
- MemoryBuffer *MemberBuffer = Buffers[MemberNum];
- ErrorOr<object::ObjectFile *> ObjOrErr =
- object::ObjectFile::createObjectFile(MemberBuffer, false,
- sys::fs::file_magic::unknown);
+ std::unique_ptr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum];
+ ErrorOr<object::SymbolicFile *> ObjOrErr =
+ object::SymbolicFile::createSymbolicFile(
+ MemberBuffer, sys::fs::file_magic::unknown, &Context);
if (!ObjOrErr)
continue; // FIXME: check only for "not an object file" errors.
- object::ObjectFile *Obj = ObjOrErr.get();
+ std::unique_ptr<object::SymbolicFile> Obj(ObjOrErr.get());
- DeleteIt.push_back(Obj);
if (!StartOffset) {
printMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
StartOffset = Out.tell();
print32BE(Out, 0);
}
- error_code Err;
- for (object::symbol_iterator I = Obj->begin_symbols(),
- E = Obj->end_symbols();
- I != E; I.increment(Err), failIfError(Err)) {
- uint32_t Symflags;
- failIfError(I->getFlags(Symflags));
+ for (const object::BasicSymbolRef &S : Obj->symbols()) {
+ uint32_t Symflags = S.getFlags();
if (Symflags & object::SymbolRef::SF_FormatSpecific)
continue;
if (!(Symflags & object::SymbolRef::SF_Global))
continue;
if (Symflags & object::SymbolRef::SF_Undefined)
continue;
- StringRef Name;
- failIfError(I->getName(Name));
- SymNames.push_back(Name);
+ failIfError(S.printName(NameOS));
+ NameOS << '\0';
+ ++NumSyms;
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0);
}
+ MemberBuffer.reset(Obj->releaseBuffer());
}
- for (std::vector<StringRef>::iterator I = SymNames.begin(),
- E = SymNames.end();
- I != E; ++I) {
- Out << *I;
- Out << '\0';
- }
-
- for (std::vector<object::ObjectFile *>::iterator I = DeleteIt.begin(),
- E = DeleteIt.end();
- I != E; ++I) {
- object::ObjectFile *O = *I;
- delete O;
- }
+ Out << NameOS.str();
if (StartOffset == 0)
return;
Out.seek(StartOffset - 12);
printWithSpacePadding(Out, Pos - StartOffset, 10);
Out.seek(StartOffset);
- print32BE(Out, SymNames.size());
+ print32BE(Out, NumSyms);
Out.seek(Pos);
}
std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
- std::vector<MemoryBuffer *> MemberBuffers;
+ std::vector<std::unique_ptr<MemoryBuffer>> MemberBuffers;
MemberBuffers.resize(NewMembers.size());
for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) {
- OwningPtr<MemoryBuffer> MemberBuffer;
+ std::unique_ptr<MemoryBuffer> MemberBuffer;
NewArchiveIterator &Member = NewMembers[I];
if (Member.isNewMember()) {
const char *Filename = Member.getNew();
int FD = Member.getFD();
const sys::fs::file_status &Status = Member.getStatus();
- failIfError(MemoryBuffer::getOpenFile(FD, Filename, MemberBuffer,
- Status.getSize(), false),
- Filename);
-
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
+ MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false);
+ failIfError(MemberBufferOrErr.getError(), Filename);
+ MemberBuffer = std::move(MemberBufferOrErr.get());
} else {
object::Archive::child_iterator OldMember = Member.getOld();
- failIfError(OldMember->getMemoryBuffer(MemberBuffer));
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
+ OldMember->getMemoryBuffer();
+ failIfError(MemberBufferOrErr.getError());
+ MemberBuffer = std::move(MemberBufferOrErr.get());
}
- MemberBuffers[I] = MemberBuffer.take();
+ MemberBuffers[I].reset(MemberBuffer.release());
}
if (Symtab) {
}
Out.seek(Pos);
- const MemoryBuffer *File = MemberBuffers[MemberNum];
+ const MemoryBuffer *File = MemberBuffers[MemberNum].get();
if (I->isNewMember()) {
const char *FileName = I->getNew();
const sys::fs::file_status &Status = I->getStatus();
Out << '\n';
}
- for (unsigned I = 0, N = MemberBuffers.size(); I < N; ++I) {
- delete MemberBuffers[I];
- }
-
Output.keep();
Out.close();
sys::fs::rename(TemporaryOutput, ArchiveName);
- TemporaryOutput = NULL;
+ TemporaryOutput = nullptr;
}
static void createSymbolTable(object::Archive *OldArchive) {
" This program archives bitcode files into single libraries\n"
);
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+
StringRef Stem = sys::path::stem(ToolName);
if (Stem.find("ar") != StringRef::npos)
return ar_main(argv);
static int performOperation(ArchiveOperation Operation) {
// Create or open the archive object.
- OwningPtr<MemoryBuffer> Buf;
- error_code EC = MemoryBuffer::getFile(ArchiveName, Buf, -1, false);
- if (EC && EC != llvm::errc::no_such_file_or_directory) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
+ MemoryBuffer::getFile(ArchiveName, -1, false);
+ std::error_code EC = Buf.getError();
+ if (EC && EC != errc::no_such_file_or_directory) {
errs() << ToolName << ": error opening '" << ArchiveName
<< "': " << EC.message() << "!\n";
return 1;
}
if (!EC) {
- object::Archive Archive(Buf.take(), EC);
+ object::Archive Archive(std::move(Buf.get()), EC);
if (EC) {
errs() << ToolName << ": error loading '" << ArchiveName
return 0;
}
- assert(EC == llvm::errc::no_such_file_or_directory);
+ assert(EC == errc::no_such_file_or_directory);
if (!shouldCreateArchive(Operation)) {
failIfError(EC, Twine("error loading '") + ArchiveName + "'");
}
}
- performOperation(Operation, NULL);
+ performOperation(Operation, nullptr);
return 0;
}