forked from OSchip/llvm-project
COFF: Remove `void error()` functions and use fatal instead.
This change makes the control flow more explicit. llvm-svn: 275504
This commit is contained in:
parent
f0b0127f60
commit
0d09a865c6
|
@ -62,7 +62,8 @@ static std::string getOutputPath(StringRef Path) {
|
||||||
// Newly created memory buffers are owned by this driver.
|
// Newly created memory buffers are owned by this driver.
|
||||||
MemoryBufferRef LinkerDriver::openFile(StringRef Path) {
|
MemoryBufferRef LinkerDriver::openFile(StringRef Path) {
|
||||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||||
check(MBOrErr, "Could not open " + Path);
|
if (auto EC = MBOrErr.getError())
|
||||||
|
fatal(EC, "Could not open " + Path);
|
||||||
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
||||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||||
OwningMBs.push_back(std::move(MB)); // take ownership
|
OwningMBs.push_back(std::move(MB)); // take ownership
|
||||||
|
@ -683,7 +684,8 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
|
||||||
if (auto *Arg = Args.getLastArg(OPT_lldmap)) {
|
if (auto *Arg = Args.getLastArg(OPT_lldmap)) {
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
llvm::raw_fd_ostream Out(Arg->getValue(), EC, OpenFlags::F_Text);
|
llvm::raw_fd_ostream Out(Arg->getValue(), EC, OpenFlags::F_Text);
|
||||||
check(EC, "Could not create the symbol map");
|
if (EC)
|
||||||
|
fatal(EC, "Could not create the symbol map");
|
||||||
Symtab.printMap(Out);
|
Symtab.printMap(Out);
|
||||||
}
|
}
|
||||||
// Call exit to avoid calling destructors.
|
// Call exit to avoid calling destructors.
|
||||||
|
|
|
@ -50,7 +50,8 @@ public:
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
ErrorOr<std::string> ExeOrErr = llvm::sys::findProgramByName(Prog);
|
ErrorOr<std::string> ExeOrErr = llvm::sys::findProgramByName(Prog);
|
||||||
check(ExeOrErr, "unable to find " + Prog + " in PATH: ");
|
if (auto EC = ExeOrErr.getError())
|
||||||
|
fatal(EC, "unable to find " + Prog + " in PATH: ");
|
||||||
const char *Exe = Saver.save(*ExeOrErr);
|
const char *Exe = Saver.save(*ExeOrErr);
|
||||||
Args.insert(Args.begin(), Exe);
|
Args.insert(Args.begin(), Exe);
|
||||||
Args.push_back(nullptr);
|
Args.push_back(nullptr);
|
||||||
|
@ -282,12 +283,14 @@ static void quoteAndPrint(raw_ostream &Out, StringRef S) {
|
||||||
static std::string createDefaultXml() {
|
static std::string createDefaultXml() {
|
||||||
// Create a temporary file.
|
// Create a temporary file.
|
||||||
SmallString<128> Path;
|
SmallString<128> Path;
|
||||||
std::error_code EC = sys::fs::createTemporaryFile("tmp", "manifest", Path);
|
if (auto EC = sys::fs::createTemporaryFile("tmp", "manifest", Path))
|
||||||
check(EC, "cannot create a temporary file");
|
fatal(EC, "cannot create a temporary file");
|
||||||
|
|
||||||
// Open the temporary file for writing.
|
// Open the temporary file for writing.
|
||||||
|
std::error_code EC;
|
||||||
llvm::raw_fd_ostream OS(Path, EC, sys::fs::F_Text);
|
llvm::raw_fd_ostream OS(Path, EC, sys::fs::F_Text);
|
||||||
check(EC, "failed to open " + Path);
|
if (EC)
|
||||||
|
fatal(EC, "failed to open " + Path);
|
||||||
|
|
||||||
// Emit the XML. Note that we do *not* verify that the XML attributes are
|
// Emit the XML. Note that we do *not* verify that the XML attributes are
|
||||||
// syntactically correct. This is intentional for link.exe compatibility.
|
// syntactically correct. This is intentional for link.exe compatibility.
|
||||||
|
@ -318,7 +321,8 @@ static std::string createDefaultXml() {
|
||||||
|
|
||||||
static std::string readFile(StringRef Path) {
|
static std::string readFile(StringRef Path) {
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path);
|
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path);
|
||||||
check(BufOrErr, "Could not open " + Path);
|
if (auto EC = BufOrErr.getError())
|
||||||
|
fatal(EC, "Could not open " + Path);
|
||||||
std::unique_ptr<MemoryBuffer> Buf(std::move(*BufOrErr));
|
std::unique_ptr<MemoryBuffer> Buf(std::move(*BufOrErr));
|
||||||
return Buf->getBuffer();
|
return Buf->getBuffer();
|
||||||
}
|
}
|
||||||
|
@ -332,8 +336,8 @@ static std::string createManifestXml() {
|
||||||
// If manifest files are supplied by the user using /MANIFESTINPUT
|
// If manifest files are supplied by the user using /MANIFESTINPUT
|
||||||
// option, we need to merge them with the default manifest.
|
// option, we need to merge them with the default manifest.
|
||||||
SmallString<128> Path2;
|
SmallString<128> Path2;
|
||||||
std::error_code EC = sys::fs::createTemporaryFile("tmp", "manifest", Path2);
|
if (auto EC = sys::fs::createTemporaryFile("tmp", "manifest", Path2))
|
||||||
check(EC, "cannot create a temporary file");
|
fatal(EC, "cannot create a temporary file");
|
||||||
FileRemover Remover1(Path1);
|
FileRemover Remover1(Path1);
|
||||||
FileRemover Remover2(Path2);
|
FileRemover Remover2(Path2);
|
||||||
|
|
||||||
|
@ -354,13 +358,15 @@ static std::string createManifestXml() {
|
||||||
std::unique_ptr<MemoryBuffer> createManifestRes() {
|
std::unique_ptr<MemoryBuffer> createManifestRes() {
|
||||||
// Create a temporary file for the resource script file.
|
// Create a temporary file for the resource script file.
|
||||||
SmallString<128> RCPath;
|
SmallString<128> RCPath;
|
||||||
std::error_code EC = sys::fs::createTemporaryFile("tmp", "rc", RCPath);
|
if (auto EC = sys::fs::createTemporaryFile("tmp", "rc", RCPath))
|
||||||
check(EC, "cannot create a temporary file");
|
fatal(EC, "cannot create a temporary file");
|
||||||
FileRemover RCRemover(RCPath);
|
FileRemover RCRemover(RCPath);
|
||||||
|
|
||||||
// Open the temporary file for writing.
|
// Open the temporary file for writing.
|
||||||
|
std::error_code EC;
|
||||||
llvm::raw_fd_ostream Out(RCPath, EC, sys::fs::F_Text);
|
llvm::raw_fd_ostream Out(RCPath, EC, sys::fs::F_Text);
|
||||||
check(EC, "failed to open " + RCPath);
|
if (EC)
|
||||||
|
fatal(EC, "failed to open " + RCPath);
|
||||||
|
|
||||||
// Write resource script to the RC file.
|
// Write resource script to the RC file.
|
||||||
Out << "#define LANG_ENGLISH 9\n"
|
Out << "#define LANG_ENGLISH 9\n"
|
||||||
|
@ -375,8 +381,8 @@ std::unique_ptr<MemoryBuffer> createManifestRes() {
|
||||||
|
|
||||||
// Create output resource file.
|
// Create output resource file.
|
||||||
SmallString<128> ResPath;
|
SmallString<128> ResPath;
|
||||||
EC = sys::fs::createTemporaryFile("tmp", "res", ResPath);
|
if (auto EC = sys::fs::createTemporaryFile("tmp", "res", ResPath))
|
||||||
check(EC, "cannot create a temporary file");
|
fatal(EC, "cannot create a temporary file");
|
||||||
|
|
||||||
Executor E("rc.exe");
|
Executor E("rc.exe");
|
||||||
E.add("/fo");
|
E.add("/fo");
|
||||||
|
@ -385,7 +391,8 @@ std::unique_ptr<MemoryBuffer> createManifestRes() {
|
||||||
E.add(RCPath.str());
|
E.add(RCPath.str());
|
||||||
E.run();
|
E.run();
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(ResPath);
|
ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(ResPath);
|
||||||
check(Ret, "Could not open " + ResPath);
|
if (auto EC = Ret.getError())
|
||||||
|
fatal(EC, "Could not open " + ResPath);
|
||||||
return std::move(*Ret);
|
return std::move(*Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +402,8 @@ void createSideBySideManifest() {
|
||||||
Path = Config->OutputFile + ".manifest";
|
Path = Config->OutputFile + ".manifest";
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
llvm::raw_fd_ostream Out(Path, EC, llvm::sys::fs::F_Text);
|
llvm::raw_fd_ostream Out(Path, EC, llvm::sys::fs::F_Text);
|
||||||
check(EC, "failed to create manifest");
|
if (EC)
|
||||||
|
fatal(EC, "failed to create manifest");
|
||||||
Out << createManifestXml();
|
Out << createManifestXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +573,8 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
|
||||||
E.add(MB.getBufferIdentifier());
|
E.add(MB.getBufferIdentifier());
|
||||||
E.run();
|
E.run();
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(Path);
|
ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(Path);
|
||||||
check(Ret, "Could not open " + Path);
|
if (auto EC = Ret.getError())
|
||||||
|
fatal(EC, "Could not open " + Path);
|
||||||
return std::move(*Ret);
|
return std::move(*Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Error.h"
|
#include "Error.h"
|
||||||
|
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
@ -20,18 +21,12 @@ void fatal(const Twine &Msg) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(std::error_code EC, const Twine &Prefix) {
|
void fatal(std::error_code EC, const Twine &Msg) {
|
||||||
if (!EC)
|
fatal(Msg + ": " + EC.message());
|
||||||
return;
|
|
||||||
fatal(Prefix + ": " + EC.message());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(llvm::Error E, const Twine &Prefix) {
|
void fatal(llvm::Error &Err, const Twine &Msg) {
|
||||||
if (!E)
|
fatal(errorToErrorCode(std::move(Err)), Msg);
|
||||||
return;
|
|
||||||
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
|
|
||||||
fatal(Prefix + ": " + EIB.message());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace coff
|
} // namespace coff
|
||||||
|
|
|
@ -17,18 +17,18 @@ namespace lld {
|
||||||
namespace coff {
|
namespace coff {
|
||||||
|
|
||||||
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
|
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
|
||||||
void check(std::error_code EC, const Twine &Prefix);
|
LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
|
||||||
void check(llvm::Error E, const Twine &Prefix);
|
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);
|
||||||
|
|
||||||
template <typename T> void check(const ErrorOr<T> &V, const Twine &Prefix) {
|
template <typename T> void check(const ErrorOr<T> &V, const Twine &Prefix) {
|
||||||
check(V.getError(), Prefix);
|
if (auto EC = V.getError())
|
||||||
|
fatal(EC, Prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T check(Expected<T> E, const Twine &Prefix) {
|
template <class T> T check(Expected<T> E, const Twine &Prefix) {
|
||||||
if (E)
|
if (E)
|
||||||
return std::move(*E);
|
return std::move(*E);
|
||||||
fatal(E.takeError(), Prefix);
|
fatal(E.takeError(), Prefix);
|
||||||
return T();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace coff
|
} // namespace coff
|
||||||
|
|
|
@ -64,8 +64,8 @@ std::string InputFile::getShortName() {
|
||||||
void ArchiveFile::parse() {
|
void ArchiveFile::parse() {
|
||||||
// Parse a MemoryBufferRef as an archive file.
|
// Parse a MemoryBufferRef as an archive file.
|
||||||
auto ArchiveOrErr = Archive::create(MB);
|
auto ArchiveOrErr = Archive::create(MB);
|
||||||
check(errorToErrorCode(ArchiveOrErr.takeError()),
|
if (auto Err = ArchiveOrErr.takeError())
|
||||||
"Failed to parse static library");
|
fatal(Err, "Failed to parse static library");
|
||||||
File = std::move(*ArchiveOrErr);
|
File = std::move(*ArchiveOrErr);
|
||||||
|
|
||||||
// Allocate a buffer for Lazy objects.
|
// Allocate a buffer for Lazy objects.
|
||||||
|
@ -82,31 +82,33 @@ void ArchiveFile::parse() {
|
||||||
Error Err;
|
Error Err;
|
||||||
for (auto &Child : File->children(Err))
|
for (auto &Child : File->children(Err))
|
||||||
Seen[Child.getChildOffset()].clear();
|
Seen[Child.getChildOffset()].clear();
|
||||||
check(std::move(Err), "Failed to parse static library");
|
if (Err)
|
||||||
|
fatal(Err, "Failed to parse static library");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a buffer pointing to a member file containing a given symbol.
|
// Returns a buffer pointing to a member file containing a given symbol.
|
||||||
// This function is thread-safe.
|
// This function is thread-safe.
|
||||||
MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
|
MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
|
||||||
auto COrErr = Sym->getMember();
|
auto COrErr = Sym->getMember();
|
||||||
check(COrErr, "Could not get the member for symbol " + Sym->getName());
|
if (auto EC = COrErr.getError())
|
||||||
|
fatal(EC, "Could not get the member for symbol " + Sym->getName());
|
||||||
const Archive::Child &C = *COrErr;
|
const Archive::Child &C = *COrErr;
|
||||||
|
|
||||||
// Return an empty buffer if we have already returned the same buffer.
|
// Return an empty buffer if we have already returned the same buffer.
|
||||||
if (Seen[C.getChildOffset()].test_and_set())
|
if (Seen[C.getChildOffset()].test_and_set())
|
||||||
return MemoryBufferRef();
|
return MemoryBufferRef();
|
||||||
ErrorOr<MemoryBufferRef> Ret = C.getMemoryBufferRef();
|
ErrorOr<MemoryBufferRef> Ret = C.getMemoryBufferRef();
|
||||||
check(Ret, "Could not get the buffer for the member defining symbol " +
|
if (auto EC = Ret.getError())
|
||||||
Sym->getName());
|
fatal(EC, "Could not get the buffer for the member defining symbol " +
|
||||||
|
Sym->getName());
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFile::parse() {
|
void ObjectFile::parse() {
|
||||||
// Parse a memory buffer as a COFF file.
|
// Parse a memory buffer as a COFF file.
|
||||||
auto BinOrErr = createBinary(MB);
|
auto BinOrErr = createBinary(MB);
|
||||||
if (!BinOrErr)
|
if (auto Err = BinOrErr.takeError())
|
||||||
check(errorToErrorCode(BinOrErr.takeError()),
|
fatal(Err, "Failed to parse object file");
|
||||||
"Failed to parse object file");
|
|
||||||
std::unique_ptr<Binary> Bin = std::move(*BinOrErr);
|
std::unique_ptr<Binary> Bin = std::move(*BinOrErr);
|
||||||
|
|
||||||
if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
|
if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
|
||||||
|
@ -129,10 +131,10 @@ void ObjectFile::initializeChunks() {
|
||||||
for (uint32_t I = 1; I < NumSections + 1; ++I) {
|
for (uint32_t I = 1; I < NumSections + 1; ++I) {
|
||||||
const coff_section *Sec;
|
const coff_section *Sec;
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
std::error_code EC = COFFObj->getSection(I, Sec);
|
if (auto EC = COFFObj->getSection(I, Sec))
|
||||||
check(EC, "getSection failed: #" + Twine(I));
|
fatal(EC, "getSection failed: #" + Twine(I));
|
||||||
EC = COFFObj->getSectionName(Sec, Name);
|
if (auto EC = COFFObj->getSectionName(Sec, Name))
|
||||||
check(EC, "getSectionName failed: #" + Twine(I));
|
fatal(EC, "getSectionName failed: #" + Twine(I));
|
||||||
if (Name == ".sxdata") {
|
if (Name == ".sxdata") {
|
||||||
SXData = Sec;
|
SXData = Sec;
|
||||||
continue;
|
continue;
|
||||||
|
@ -167,7 +169,8 @@ void ObjectFile::initializeSymbols() {
|
||||||
for (uint32_t I = 0; I < NumSymbols; ++I) {
|
for (uint32_t I = 0; I < NumSymbols; ++I) {
|
||||||
// Get a COFFSymbolRef object.
|
// Get a COFFSymbolRef object.
|
||||||
auto SymOrErr = COFFObj->getSymbol(I);
|
auto SymOrErr = COFFObj->getSymbol(I);
|
||||||
check(SymOrErr, "broken object file: " + getName());
|
if (auto EC = SymOrErr.getError())
|
||||||
|
fatal(EC, "broken object file: " + getName());
|
||||||
|
|
||||||
COFFSymbolRef Sym = *SymOrErr;
|
COFFSymbolRef Sym = *SymOrErr;
|
||||||
|
|
||||||
|
@ -334,7 +337,8 @@ void BitcodeFile::parse() {
|
||||||
Context.enableDebugTypeODRUniquing();
|
Context.enableDebugTypeODRUniquing();
|
||||||
ErrorOr<std::unique_ptr<LTOModule>> ModOrErr = LTOModule::createFromBuffer(
|
ErrorOr<std::unique_ptr<LTOModule>> ModOrErr = LTOModule::createFromBuffer(
|
||||||
Context, MB.getBufferStart(), MB.getBufferSize(), llvm::TargetOptions());
|
Context, MB.getBufferStart(), MB.getBufferSize(), llvm::TargetOptions());
|
||||||
check(ModOrErr, "Could not create lto module");
|
if (auto EC = ModOrErr.getError())
|
||||||
|
fatal(EC, "Could not create lto module");
|
||||||
M = std::move(*ModOrErr);
|
M = std::move(*ModOrErr);
|
||||||
|
|
||||||
llvm::StringSaver Saver(Alloc);
|
llvm::StringSaver Saver(Alloc);
|
||||||
|
|
|
@ -484,5 +484,6 @@ void lld::coff::writeImportLibrary() {
|
||||||
std::pair<StringRef, std::error_code> Result =
|
std::pair<StringRef, std::error_code> Result =
|
||||||
writeArchive(Path, Members, /*WriteSymtab*/ true, object::Archive::K_GNU,
|
writeArchive(Path, Members, /*WriteSymtab*/ true, object::Archive::K_GNU,
|
||||||
/*Deterministic*/ true, /*Thin*/ false);
|
/*Deterministic*/ true, /*Thin*/ false);
|
||||||
check(Result.second, Twine("Failed to write ") + Path);
|
if (auto EC = Result.second)
|
||||||
|
fatal(EC, Twine("Failed to write ") + Path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ void lld::coff::createPDB(StringRef Path) {
|
||||||
size_t FileSize = PageSize * 3;
|
size_t FileSize = PageSize * 3;
|
||||||
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
||||||
FileOutputBuffer::create(Path, FileSize);
|
FileOutputBuffer::create(Path, FileSize);
|
||||||
check(BufferOrErr, "failed to open " + Path);
|
if (auto EC = BufferOrErr.getError())
|
||||||
|
fatal(EC, "failed to open " + Path);
|
||||||
std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
|
std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
|
||||||
|
|
||||||
// Write the file header.
|
// Write the file header.
|
||||||
|
|
|
@ -239,7 +239,8 @@ void Writer::run() {
|
||||||
fixSafeSEHSymbols();
|
fixSafeSEHSymbols();
|
||||||
writeSections();
|
writeSections();
|
||||||
sortExceptionTable();
|
sortExceptionTable();
|
||||||
check(Buffer->commit(), "Failed to write the output file");
|
if (auto EC = Buffer->commit())
|
||||||
|
fatal(EC, "Failed to write the output file");
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef getOutputSection(StringRef Name) {
|
static StringRef getOutputSection(StringRef Name) {
|
||||||
|
@ -653,7 +654,8 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
||||||
void Writer::openFile(StringRef Path) {
|
void Writer::openFile(StringRef Path) {
|
||||||
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
||||||
FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable);
|
FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable);
|
||||||
check(BufferOrErr, "failed to open " + Path);
|
if (auto EC = BufferOrErr.getError())
|
||||||
|
fatal(EC, "failed to open " + Path);
|
||||||
Buffer = std::move(*BufferOrErr);
|
Buffer = std::move(*BufferOrErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue