[lld] r316624 - [lld] unified COFF and ELF error handling on new Common/ErrorHandler
Bob Haarman via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 25 15:28:39 PDT 2017
Author: inglorion
Date: Wed Oct 25 15:28:38 2017
New Revision: 316624
URL: http://llvm.org/viewvc/llvm-project?rev=316624&view=rev
Log:
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
Added:
lld/trunk/Common/ErrorHandler.cpp
lld/trunk/include/lld/Common/ErrorHandler.h
Removed:
lld/trunk/COFF/Error.cpp
lld/trunk/COFF/Error.h
lld/trunk/ELF/Error.cpp
lld/trunk/ELF/Error.h
Modified:
lld/trunk/COFF/CMakeLists.txt
lld/trunk/COFF/Chunks.cpp
lld/trunk/COFF/Config.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/DriverUtils.cpp
lld/trunk/COFF/ICF.cpp
lld/trunk/COFF/InputFiles.cpp
lld/trunk/COFF/LTO.cpp
lld/trunk/COFF/MapFile.cpp
lld/trunk/COFF/MinGW.cpp
lld/trunk/COFF/PDB.cpp
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/Symbols.cpp
lld/trunk/COFF/Writer.cpp
lld/trunk/Common/CMakeLists.txt
lld/trunk/ELF/Arch/AArch64.cpp
lld/trunk/ELF/Arch/AMDGPU.cpp
lld/trunk/ELF/Arch/ARM.cpp
lld/trunk/ELF/Arch/AVR.cpp
lld/trunk/ELF/Arch/Mips.cpp
lld/trunk/ELF/Arch/MipsArchTree.cpp
lld/trunk/ELF/Arch/PPC.cpp
lld/trunk/ELF/Arch/PPC64.cpp
lld/trunk/ELF/Arch/SPARCV9.cpp
lld/trunk/ELF/Arch/X86.cpp
lld/trunk/ELF/Arch/X86_64.cpp
lld/trunk/ELF/CMakeLists.txt
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/DriverUtils.cpp
lld/trunk/ELF/EhFrame.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputFiles.h
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/LTO.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/ScriptLexer.cpp
lld/trunk/ELF/ScriptParser.cpp
lld/trunk/ELF/Strings.cpp
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Thunks.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/COFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/CMakeLists.txt?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/CMakeLists.txt (original)
+++ lld/trunk/COFF/CMakeLists.txt Wed Oct 25 15:28:38 2017
@@ -11,7 +11,6 @@ add_lld_library(lldCOFF
DLL.cpp
Driver.cpp
DriverUtils.cpp
- Error.cpp
ICF.cpp
InputFiles.cpp
LTO.cpp
Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Wed Oct 25 15:28:38 2017
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#include "Chunks.h"
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Wed Oct 25 15:28:38 2017
@@ -84,13 +84,10 @@ struct Configuration {
bool NoEntry = false;
std::string OutputFile;
std::string ImportName;
- bool ColorDiagnostics;
bool DoGC = true;
bool DoICF = true;
- uint64_t ErrorLimit = 20;
bool Relocatable = true;
bool Force = false;
- bool FatalWarnings = false;
bool Debug = false;
bool WriteSymtab = true;
unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Oct 25 15:28:38 2017
@@ -9,7 +9,6 @@
#include "Driver.h"
#include "Config.h"
-#include "Error.h"
#include "InputFiles.h"
#include "Memory.h"
#include "MinGW.h"
@@ -17,6 +16,7 @@
#include "Symbols.h"
#include "Writer.h"
#include "lld/Common/Driver.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
@@ -55,12 +55,14 @@ StringSaver Saver{BAlloc};
std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;
bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
- ErrorCount = 0;
- ErrorOS = &Diag;
-
+ errorHandler().LogName = Args[0];
+ errorHandler().ErrorOS = &Diag;
+ errorHandler().ColorDiagnostics = Diag.has_colors();
+ errorHandler().ErrorLimitExceededMsg =
+ "too many errors emitted, stopping now"
+ " (use /ERRORLIMIT:0 to see all errors)";
Config = make<Configuration>();
Config->Argv = {Args.begin(), Args.end()};
- Config->ColorDiagnostics = ErrorOS->has_colors();
Config->CanExitEarly = CanExitEarly;
Symtab = make<SymbolTable>();
@@ -70,10 +72,10 @@ bool link(ArrayRef<const char *> Args, b
// Call exit() if we can to avoid calling destructors.
if (CanExitEarly)
- exitLld(ErrorCount ? 1 : 0);
+ exitLld(errorCount() ? 1 : 0);
freeArena();
- return !ErrorCount;
+ return !errorCount();
}
// Drop directory components and replace extension with ".exe" or ".dll".
@@ -212,8 +214,8 @@ void LinkerDriver::enqueueArchiveMember(
enqueueTask([=]() {
auto MBOrErr = Future->get();
if (MBOrErr.second)
- fatal(MBOrErr.second,
- "could not get the buffer for the member defining " + SymName);
+ fatal("could not get the buffer for the member defining " + SymName +
+ ": " + MBOrErr.second.message());
Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
ParentName);
});
@@ -619,7 +621,7 @@ filterBitcodeFiles(StringRef Path, std::
SmallString<128> S;
if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path),
".lib", S))
- fatal(EC, "cannot create a temporary file");
+ fatal("cannot create a temporary file: " + EC.message());
std::string Temp = S.str();
TemporaryFiles.push_back(Temp);
@@ -648,7 +650,7 @@ void LinkerDriver::invokeMSVC(opt::Input
int Fd;
if (auto EC = sys::fs::createTemporaryFile(
"lld-" + sys::path::filename(Obj->ParentName), ".obj", Fd, S))
- fatal(EC, "cannot create a temporary file");
+ fatal("cannot create a temporary file: " + EC.message());
raw_fd_ostream OS(Fd, /*shouldClose*/ true);
OS << Obj->MB.getBuffer();
Temps.push_back(S.str());
@@ -736,7 +738,7 @@ void LinkerDriver::link(ArrayRef<const c
StringRef S = Arg->getValue();
if (S.getAsInteger(10, N))
error(Arg->getSpelling() + " number expected, but got " + S);
- Config->ErrorLimit = N;
+ errorHandler().ErrorLimit = N;
}
// Handle /help
@@ -792,6 +794,7 @@ void LinkerDriver::link(ArrayRef<const c
// Handle /verbose
if (Args.hasArg(OPT_verbose))
Config->Verbose = true;
+ errorHandler().Verbose = Config->Verbose;
// Handle /force or /force:unresolved
if (Args.hasArg(OPT_force) || Args.hasArg(OPT_force_unresolved))
@@ -1010,7 +1013,7 @@ void LinkerDriver::link(ArrayRef<const c
Config->MapFile = getMapFile(Args);
- if (ErrorCount)
+ if (errorCount())
return;
bool WholeArchiveFlag = Args.hasArg(OPT_wholearchive_flag);
@@ -1191,7 +1194,7 @@ void LinkerDriver::link(ArrayRef<const c
addUndefined(mangle("_load_config_used"));
} while (run());
- if (ErrorCount)
+ if (errorCount())
return;
// If /msvclto is given, we use the MSVC linker to link LTO output files.
@@ -1208,7 +1211,7 @@ void LinkerDriver::link(ArrayRef<const c
// Make sure we have resolved all symbols.
Symtab->reportRemainingUndefines();
- if (ErrorCount)
+ if (errorCount())
return;
// Windows specific -- if no /subsystem is given, we need to infer
@@ -1224,7 +1227,7 @@ void LinkerDriver::link(ArrayRef<const c
for (ObjFile *File : ObjFile::Instances)
if (!File->SEHCompat)
error("/safeseh: " + File->getName() + " is not compatible with SEH");
- if (ErrorCount)
+ if (errorCount())
return;
}
Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Wed Oct 25 15:28:38 2017
@@ -15,9 +15,9 @@
#include "Config.h"
#include "Driver.h"
-#include "Error.h"
#include "Memory.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/COFF.h"
@@ -57,7 +57,7 @@ public:
void run() {
ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog);
if (auto EC = ExeOrErr.getError())
- fatal(EC, "unable to find " + Prog + " in PATH");
+ fatal("unable to find " + Prog + " in PATH: " + EC.message());
StringRef Exe = Saver.save(*ExeOrErr);
Args.insert(Args.begin(), Exe);
@@ -288,14 +288,14 @@ public:
TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") {
SmallString<128> S;
if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S))
- fatal(EC, "cannot create a temporary file");
+ fatal("cannot create a temporary file: " + EC.message());
Path = S.str();
if (!Contents.empty()) {
std::error_code EC;
raw_fd_ostream OS(Path, EC, sys::fs::F_None);
if (EC)
- fatal(EC, "failed to open " + Path);
+ fatal("failed to open " + Path + ": " + EC.message());
OS << Contents;
}
}
@@ -363,13 +363,15 @@ static std::string createManifestXmlWith
windows_manifest::WindowsManifestMerger Merger;
if (auto E = Merger.merge(*DefaultXmlCopy.get()))
- fatal(E, "internal manifest tool failed on default xml");
+ fatal("internal manifest tool failed on default xml: " +
+ toString(std::move(E)));
for (StringRef Filename : Config->ManifestInput) {
std::unique_ptr<MemoryBuffer> Manifest =
check(MemoryBuffer::getFile(Filename));
if (auto E = Merger.merge(*Manifest.get()))
- fatal(E, "internal manifest tool failed on file " + Filename);
+ fatal("internal manifest tool failed on file " + Filename + ": " +
+ toString(std::move(E)));
}
return Merger.getMergedManifest().get()->getBuffer();
@@ -381,7 +383,7 @@ static std::string createManifestXmlWith
std::error_code EC;
raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text);
if (EC)
- fatal(EC, "failed to open " + Default.Path);
+ fatal("failed to open " + Default.Path + ": " + EC.message());
OS << DefaultXml;
OS.close();
@@ -482,7 +484,7 @@ void createSideBySideManifest() {
std::error_code EC;
raw_fd_ostream Out(Path, EC, sys::fs::F_Text);
if (EC)
- fatal(EC, "failed to create manifest");
+ fatal("failed to create manifest: " + EC.message());
Out << createManifestXml();
}
@@ -649,13 +651,13 @@ MemoryBufferRef convertResToCOFF(const s
if (!RF)
fatal("cannot compile non-resource file as resource");
if (auto EC = Parser.parse(RF))
- fatal(EC, "failed to parse .res file");
+ fatal("failed to parse .res file: " + toString(std::move(EC)));
}
Expected<std::unique_ptr<MemoryBuffer>> E =
llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
if (!E)
- fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF");
+ fatal("failed to write .res to COFF: " + toString(E.takeError()));
MemoryBufferRef MBRef = **E;
make<std::unique_ptr<MemoryBuffer>>(std::move(*E)); // take ownership
@@ -739,7 +741,7 @@ opt::InputArgList ArgParser::parse(Array
}
// Handle /WX early since it converts missing argument warnings to errors.
- Config->FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false);
+ errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false);
if (MissingCount)
fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
Removed: lld/trunk/COFF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Error.cpp?rev=316623&view=auto
==============================================================================
--- lld/trunk/COFF/Error.cpp (original)
+++ lld/trunk/COFF/Error.cpp (removed)
@@ -1,120 +0,0 @@
-//===- Error.cpp ----------------------------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Error.h"
-#include "Config.h"
-
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/raw_ostream.h"
-#include <mutex>
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#endif
-
-using namespace llvm;
-
-namespace lld {
-// The functions defined in this file can be called from multiple threads,
-// but outs() or errs() are not thread-safe. We protect them using a mutex.
-static std::mutex Mu;
-
-namespace coff {
-uint64_t ErrorCount;
-raw_ostream *ErrorOS;
-
-LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
- // Dealloc/destroy ManagedStatic variables before calling
- // _exit(). In a non-LTO build, this is a nop. In an LTO
- // build allows us to get the output of -time-passes.
- llvm_shutdown();
-
- outs().flush();
- errs().flush();
- _exit(Val);
-}
-
-static void print(StringRef S, raw_ostream::Colors C) {
- *ErrorOS << Config->Argv[0] << ": ";
- if (Config->ColorDiagnostics) {
- ErrorOS->changeColor(C, true);
- *ErrorOS << S;
- ErrorOS->resetColor();
- } else {
- *ErrorOS << S;
- }
-}
-
-void log(const Twine &Msg) {
- if (Config->Verbose) {
- std::lock_guard<std::mutex> Lock(Mu);
- outs() << Config->Argv[0] << ": " << Msg << "\n";
- outs().flush();
- }
-}
-
-void message(const Twine &Msg) {
- std::lock_guard<std::mutex> Lock(Mu);
- outs() << Msg << "\n";
- outs().flush();
-}
-
-void error(const Twine &Msg) {
- std::lock_guard<std::mutex> Lock(Mu);
-
- if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
- print("error: ", raw_ostream::RED);
- *ErrorOS << Msg << "\n";
- } else if (ErrorCount == Config->ErrorLimit) {
- print("error: ", raw_ostream::RED);
- *ErrorOS << "too many errors emitted, stopping now"
- << " (use /ERRORLIMIT:0 to see all errors)\n";
- if (Config->CanExitEarly)
- exitLld(1);
- }
-
- ++ErrorCount;
-}
-
-void fatal(const Twine &Msg) {
- if (Config->ColorDiagnostics) {
- errs().changeColor(raw_ostream::RED, /*bold=*/true);
- errs() << "error: ";
- errs().resetColor();
- } else {
- errs() << "error: ";
- }
- errs() << Msg << "\n";
- exitLld(1);
-}
-
-void fatal(std::error_code EC, const Twine &Msg) {
- fatal(Msg + ": " + EC.message());
-}
-
-void fatal(llvm::Error &Err, const Twine &Msg) {
- fatal(errorToErrorCode(std::move(Err)), Msg);
-}
-
-void warn(const Twine &Msg) {
- if (Config->FatalWarnings) {
- error(Msg);
- return;
- }
-
- std::lock_guard<std::mutex> Lock(Mu);
- print("warning: ", raw_ostream::MAGENTA);
- *ErrorOS << Msg << "\n";
-}
-
-} // namespace coff
-} // namespace lld
Removed: lld/trunk/COFF/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Error.h?rev=316623&view=auto
==============================================================================
--- lld/trunk/COFF/Error.h (original)
+++ lld/trunk/COFF/Error.h (removed)
@@ -1,64 +0,0 @@
-//===- Error.h --------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_COFF_ERROR_H
-#define LLD_COFF_ERROR_H
-
-#include "lld/Common/LLVM.h"
-#include "llvm/Support/Error.h"
-
-namespace lld {
-namespace coff {
-
-extern uint64_t ErrorCount;
-extern llvm::raw_ostream *ErrorOS;
-
-void log(const Twine &Msg);
-void message(const Twine &Msg);
-void warn(const Twine &Msg);
-void error(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
-LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);
-
-LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
-
-template <class T> T check(ErrorOr<T> V, const Twine &Prefix) {
- if (auto EC = V.getError())
- fatal(EC, Prefix);
- return std::move(*V);
-}
-
-template <class T> T check(Expected<T> E, const Twine &Prefix) {
- if (llvm::Error Err = E.takeError())
- fatal(Err, Prefix);
- return std::move(*E);
-}
-
-template <class T> T check(ErrorOr<T> EO) {
- if (!EO)
- fatal(EO.getError().message());
- return std::move(*EO);
-}
-
-template <class T> T check(Expected<T> E) {
- if (!E) {
- std::string Buf;
- llvm::raw_string_ostream OS(Buf);
- logAllUnhandledErrors(E.takeError(), OS, "");
- OS.flush();
- fatal(Buf);
- }
- return std::move(*E);
-}
-
-} // namespace coff
-} // namespace lld
-
-#endif
Modified: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Wed Oct 25 15:28:38 2017
@@ -19,8 +19,8 @@
//===----------------------------------------------------------------------===//
#include "Chunks.h"
-#include "Error.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Parallel.h"
Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Wed Oct 25 15:28:38 2017
@@ -11,10 +11,10 @@
#include "Chunks.h"
#include "Config.h"
#include "Driver.h"
-#include "Error.h"
#include "Memory.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm-c/lto.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
@@ -127,9 +127,9 @@ void ObjFile::initializeChunks() {
const coff_section *Sec;
StringRef Name;
if (auto EC = COFFObj->getSection(I, Sec))
- fatal(EC, "getSection failed: #" + Twine(I));
+ fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
if (auto EC = COFFObj->getSectionName(Sec, Name))
- fatal(EC, "getSectionName failed: #" + Twine(I));
+ fatal("getSectionName failed: #" + Twine(I) + ": " + EC.message());
if (Name == ".sxdata") {
SXData = Sec;
continue;
@@ -179,7 +179,6 @@ void ObjFile::initializeSymbols() {
int32_t LastSectionNumber = 0;
for (uint32_t I = 0; I < NumSymbols; ++I) {
- // Get a COFFSymbolRef object.
COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
const void *AuxP = nullptr;
Modified: lld/trunk/COFF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/LTO.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/LTO.cpp (original)
+++ lld/trunk/COFF/LTO.cpp Wed Oct 25 15:28:38 2017
@@ -9,9 +9,9 @@
#include "LTO.h"
#include "Config.h"
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
Modified: lld/trunk/COFF/MapFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MapFile.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/MapFile.cpp (original)
+++ lld/trunk/COFF/MapFile.cpp Wed Oct 25 15:28:38 2017
@@ -20,11 +20,11 @@
//===----------------------------------------------------------------------===//
#include "MapFile.h"
-#include "Error.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/raw_ostream.h"
Modified: lld/trunk/COFF/MinGW.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MinGW.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/MinGW.cpp (original)
+++ lld/trunk/COFF/MinGW.cpp Wed Oct 25 15:28:38 2017
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "MinGW.h"
-#include "Error.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Wed Oct 25 15:28:38 2017
@@ -11,10 +11,10 @@
#include "Chunks.h"
#include "Config.h"
#include "Driver.h"
-#include "Error.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
@@ -188,7 +188,7 @@ maybeReadTypeServerRecord(CVTypeArray &T
return None;
TypeServer2Record TS;
if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))
- fatal(EC, "error reading type server record");
+ fatal("error reading type server record: " + toString(std::move(EC)));
return std::move(TS);
}
@@ -202,7 +202,7 @@ const CVIndexMap &PDBLinker::mergeDebugT
CVTypeArray Types;
BinaryStreamReader Reader(Stream);
if (auto EC = Reader.readArray(Types, Reader.getLength()))
- fatal(EC, "Reader::readArray failed");
+ fatal("Reader::readArray failed: " + toString(std::move(EC)));
// Look through type servers. If we've already seen this type server, don't
// merge any type information.
@@ -213,7 +213,8 @@ const CVIndexMap &PDBLinker::mergeDebugT
// ObjectIndexMap.
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
ObjectIndexMap.TPIMap, Types))
- fatal(Err, "codeview::mergeTypeAndIdRecords failed");
+ fatal("codeview::mergeTypeAndIdRecords failed: " +
+ toString(std::move(Err)));
return ObjectIndexMap;
}
@@ -275,23 +276,23 @@ const CVIndexMap &PDBLinker::maybeMergeT
ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
}
if (auto E = ExpectedSession.takeError())
- fatal(E, "Type server PDB was not found");
+ fatal("Type server PDB was not found: " + toString(std::move(E)));
// Merge TPI first, because the IPI stream will reference type indices.
auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
if (auto E = ExpectedTpi.takeError())
- fatal(E, "Type server does not have TPI stream");
+ fatal("Type server does not have TPI stream: " + toString(std::move(E)));
if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray()))
- fatal(Err, "codeview::mergeTypeRecords failed");
+ fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
// Merge IPI.
auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
if (auto E = ExpectedIpi.takeError())
- fatal(E, "Type server does not have TPI stream");
+ fatal("Type server does not have TPI stream: " + toString(std::move(E)));
if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
ExpectedIpi->typeArray()))
- fatal(Err, "codeview::mergeIdRecords failed");
+ fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
return IndexMap;
}
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Oct 25 15:28:38 2017
@@ -10,10 +10,10 @@
#include "SymbolTable.h"
#include "Config.h"
#include "Driver.h"
-#include "Error.h"
#include "LTO.h"
#include "Memory.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
Modified: lld/trunk/COFF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.cpp (original)
+++ lld/trunk/COFF/Symbols.cpp Wed Oct 25 15:28:38 2017
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#include "Symbols.h"
-#include "Error.h"
#include "InputFiles.h"
#include "Memory.h"
#include "Strings.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Oct 25 15:28:38 2017
@@ -10,13 +10,13 @@
#include "Writer.h"
#include "Config.h"
#include "DLL.h"
-#include "Error.h"
#include "InputFiles.h"
#include "MapFile.h"
#include "Memory.h"
#include "PDB.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -316,7 +316,7 @@ void Writer::run() {
writeMapFile(OutputSections);
if (auto EC = Buffer->commit())
- fatal(EC, "failed to write the output file");
+ fatal("failed to write the output file: " + EC.message());
}
static StringRef getOutputSection(StringRef Name) {
Modified: lld/trunk/Common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/Common/CMakeLists.txt?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/Common/CMakeLists.txt (original)
+++ lld/trunk/Common/CMakeLists.txt Wed Oct 25 15:28:38 2017
@@ -3,6 +3,7 @@ if(NOT LLD_BUILT_STANDALONE)
endif()
add_lld_library(lldCommon
+ ErrorHandler.cpp
Reproduce.cpp
TargetOptionsCommandFlags.cpp
Threads.cpp
Added: lld/trunk/Common/ErrorHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/Common/ErrorHandler.cpp?rev=316624&view=auto
==============================================================================
--- lld/trunk/Common/ErrorHandler.cpp (added)
+++ lld/trunk/Common/ErrorHandler.cpp Wed Oct 25 15:28:38 2017
@@ -0,0 +1,122 @@
+//===- ErrorHandler.cpp ---------------------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/Common/ErrorHandler.h"
+
+#include "lld/Common/Threads.h"
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <mutex>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#endif
+
+using namespace llvm;
+
+using namespace lld;
+
+// The functions defined in this file can be called from multiple threads,
+// but outs() or errs() are not thread-safe. We protect them using a mutex.
+static std::mutex Mu;
+
+// Prints "\n" or does nothing, depending on Msg contents of
+// the previous call of this function.
+static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
+ // True if the previous error message contained "\n".
+ // We want to separate multi-line error messages with a newline.
+ static bool Flag;
+
+ if (Flag)
+ *ErrorOS << "\n";
+ Flag = StringRef(Msg.str()).contains('\n');
+}
+
+namespace lld {
+
+ErrorHandler &errorHandler() {
+ static ErrorHandler Handler;
+ return Handler;
+}
+
+void exitLld(int Val) {
+ waitForBackgroundThreads();
+ // Dealloc/destroy ManagedStatic variables before calling
+ // _exit(). In a non-LTO build, this is a nop. In an LTO
+ // build allows us to get the output of -time-passes.
+ llvm_shutdown();
+
+ outs().flush();
+ errs().flush();
+ _exit(Val);
+}
+
+void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
+ *ErrorOS << LogName << ": ";
+ if (ColorDiagnostics) {
+ ErrorOS->changeColor(C, true);
+ *ErrorOS << S;
+ ErrorOS->resetColor();
+ } else {
+ *ErrorOS << S;
+ }
+}
+
+void ErrorHandler::log(const Twine &Msg) {
+ if (Verbose) {
+ std::lock_guard<std::mutex> Lock(Mu);
+ outs() << LogName << ": " << Msg << "\n";
+ outs().flush();
+ }
+}
+
+void ErrorHandler::message(const Twine &Msg) {
+ std::lock_guard<std::mutex> Lock(Mu);
+ outs() << Msg << "\n";
+ outs().flush();
+}
+
+void ErrorHandler::warn(const Twine &Msg) {
+ if (FatalWarnings) {
+ error(Msg);
+ return;
+ }
+
+ std::lock_guard<std::mutex> Lock(Mu);
+ newline(ErrorOS, Msg);
+ print("warning: ", raw_ostream::MAGENTA);
+ *ErrorOS << Msg << "\n";
+}
+
+void ErrorHandler::error(const Twine &Msg) {
+ std::lock_guard<std::mutex> Lock(Mu);
+ newline(ErrorOS, Msg);
+
+ if (ErrorLimit == 0 || ErrorCount < ErrorLimit) {
+ print("error: ", raw_ostream::RED);
+ *ErrorOS << Msg << "\n";
+ } else if (ErrorCount == ErrorLimit) {
+ print("error: ", raw_ostream::RED);
+ *ErrorOS << ErrorLimitExceededMsg << "\n";
+ if (ExitEarly)
+ exitLld(1);
+ }
+
+ ++ErrorCount;
+}
+
+void ErrorHandler::fatal(const Twine &Msg) {
+ error(Msg);
+ exitLld(1);
+}
+
+} // end namespace lld
Modified: lld/trunk/ELF/Arch/AArch64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AArch64.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AArch64.cpp (original)
+++ lld/trunk/ELF/Arch/AArch64.cpp Wed Oct 25 15:28:38 2017
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Arch/AMDGPU.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AMDGPU.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AMDGPU.cpp (original)
+++ lld/trunk/ELF/Arch/AMDGPU.cpp Wed Oct 25 15:28:38 2017
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Wed Oct 25 15:28:38 2017
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Arch/AVR.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AVR.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AVR.cpp (original)
+++ lld/trunk/ELF/Arch/AVR.cpp Wed Oct 25 15:28:38 2017
@@ -26,10 +26,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Wed Oct 25 15:28:38 2017
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Arch/MipsArchTree.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/MipsArchTree.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/MipsArchTree.cpp (original)
+++ lld/trunk/ELF/Arch/MipsArchTree.cpp Wed Oct 25 15:28:38 2017
@@ -11,11 +11,11 @@
//
//===---------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "SymbolTable.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/MipsABIFlags.h"
Modified: lld/trunk/ELF/Arch/PPC.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC.cpp (original)
+++ lld/trunk/ELF/Arch/PPC.cpp Wed Oct 25 15:28:38 2017
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "Symbols.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Wed Oct 25 15:28:38 2017
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
Modified: lld/trunk/ELF/Arch/SPARCV9.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/SPARCV9.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/SPARCV9.cpp (original)
+++ lld/trunk/ELF/Arch/SPARCV9.cpp Wed Oct 25 15:28:38 2017
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
Modified: lld/trunk/ELF/Arch/X86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86.cpp (original)
+++ lld/trunk/ELF/Arch/X86.cpp Wed Oct 25 15:28:38 2017
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
Modified: lld/trunk/ELF/Arch/X86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86_64.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86_64.cpp (original)
+++ lld/trunk/ELF/Arch/X86_64.cpp Wed Oct 25 15:28:38 2017
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/CMakeLists.txt (original)
+++ lld/trunk/ELF/CMakeLists.txt Wed Oct 25 15:28:38 2017
@@ -21,7 +21,6 @@ add_lld_library(lldELF
Driver.cpp
DriverUtils.cpp
EhFrame.cpp
- Error.cpp
Filesystem.cpp
GdbIndex.cpp
ICF.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Oct 25 15:28:38 2017
@@ -108,7 +108,6 @@ struct Configuration {
bool AsNeeded = false;
bool Bsymbolic;
bool BsymbolicFunctions;
- bool ColorDiagnostics = false;
bool CompressDebugSections;
bool DefineCommon;
bool Demangle = true;
@@ -117,7 +116,6 @@ struct Configuration {
bool EmitRelocs;
bool EnableNewDtags;
bool ExportDynamic;
- bool FatalWarnings;
bool GcSections;
bool GdbIndex;
bool GnuHash = false;
@@ -167,7 +165,6 @@ struct Configuration {
ELFKind EKind = ELFNoneKind;
uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
uint16_t EMachine = llvm::ELF::EM_NONE;
- uint64_t ErrorLimit = 20;
llvm::Optional<uint64_t> ImageBase;
uint64_t MaxPageSize;
uint64_t ZStackSize;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Oct 25 15:28:38 2017
@@ -25,7 +25,6 @@
#include "Driver.h"
#include "Config.h"
-#include "Error.h"
#include "Filesystem.h"
#include "ICF.h"
#include "InputFiles.h"
@@ -40,6 +39,7 @@
#include "Target.h"
#include "Writer.h"
#include "lld/Common/Driver.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/StringExtras.h"
@@ -72,8 +72,12 @@ static void setConfigs();
bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
raw_ostream &Error) {
- ErrorCount = 0;
- ErrorOS = &Error;
+ errorHandler().LogName = Args[0];
+ errorHandler().ErrorLimitExceededMsg =
+ "too many errors emitted, stopping now (use "
+ "-error-limit=0 to see all errors)";
+ errorHandler().ErrorOS = &Error;
+ errorHandler().ColorDiagnostics = Error.has_colors();
InputSections.clear();
OutputSections.clear();
Tar = nullptr;
@@ -95,10 +99,10 @@ bool elf::link(ArrayRef<const char *> Ar
// This saves time because the overhead of calling destructors
// for all globally-allocated objects is not negligible.
if (Config->ExitEarly)
- exitLld(ErrorCount ? 1 : 0);
+ exitLld(errorCount() ? 1 : 0);
freeArena();
- return !ErrorCount;
+ return !errorCount();
}
// Parses a linker -m option.
@@ -332,7 +336,7 @@ void LinkerDriver::main(ArrayRef<const c
opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
// Interpret this flag early because error() depends on them.
- Config->ErrorLimit = getInteger(Args, OPT_error_limit, 20);
+ errorHandler().ErrorLimit = getInteger(Args, OPT_error_limit, 20);
// Handle -help
if (Args.hasArg(OPT_help)) {
@@ -365,6 +369,7 @@ void LinkerDriver::main(ArrayRef<const c
return;
Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown);
+ errorHandler().ExitEarly = Config->ExitEarly;
if (const char *Path = getReproduceOption(Args)) {
// Note that --reproduce is a debug option so you can ignore it
@@ -388,7 +393,7 @@ void LinkerDriver::main(ArrayRef<const c
inferMachineType();
setConfigs();
checkOptions(Args);
- if (ErrorCount)
+ if (errorCount())
return;
switch (Config->EKind) {
@@ -645,7 +650,7 @@ void LinkerDriver::readConfigs(opt::Inpu
Config->Entry = Args.getLastArgValue(OPT_entry);
Config->ExportDynamic =
Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
- Config->FatalWarnings =
+ errorHandler().FatalWarnings =
Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
Config->FilterList = getArgs(Args, OPT_filter);
Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
@@ -694,6 +699,7 @@ void LinkerDriver::readConfigs(opt::Inpu
Config->Undefined = getArgs(Args, OPT_undefined);
Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
Config->Verbose = Args.hasArg(OPT_verbose);
+ errorHandler().Verbose = Config->Verbose;
Config->WarnCommon = Args.hasArg(OPT_warn_common);
Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
Config->ZExecstack = hasZOption(Args, "execstack");
@@ -881,7 +887,7 @@ void LinkerDriver::createFiles(opt::Inpu
}
}
- if (Files.empty() && ErrorCount == 0)
+ if (Files.empty() && errorCount() == 0)
error("no input files");
}
@@ -1009,7 +1015,7 @@ template <class ELFT> void LinkerDriver:
error("cannot open output file " + Config->OutputFile + ": " + E.message());
if (auto E = tryCreateFile(Config->MapFile))
error("cannot open map file " + Config->MapFile + ": " + E.message());
- if (ErrorCount)
+ if (errorCount())
return;
// Use default entry point name if no name was given via the command
@@ -1053,7 +1059,7 @@ template <class ELFT> void LinkerDriver:
Symtab->fetchIfLazy<ELFT>(Config->Entry);
// Return if there were name resolution errors.
- if (ErrorCount)
+ if (errorCount())
return;
// Handle undefined symbols in DSOs.
@@ -1075,7 +1081,7 @@ template <class ELFT> void LinkerDriver:
Symtab->addSymbolAlias<ELFT>(Def.first, Def.second);
Symtab->addCombinedLTOObject<ELFT>();
- if (ErrorCount)
+ if (errorCount())
return;
// Apply symbol renames for -wrap and -defsym
Modified: lld/trunk/ELF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DriverUtils.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/DriverUtils.cpp (original)
+++ lld/trunk/ELF/DriverUtils.cpp Wed Oct 25 15:28:38 2017
@@ -14,8 +14,8 @@
//===----------------------------------------------------------------------===//
#include "Driver.h"
-#include "Error.h"
#include "Memory.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Reproduce.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/Optional.h"
@@ -51,25 +51,26 @@ static const opt::OptTable::Info OptInfo
ELFOptTable::ELFOptTable() : OptTable(OptInfo) {}
-// Parse -color-diagnostics={auto,always,never} or -no-color-diagnostics.
-static bool getColorDiagnostics(opt::InputArgList &Args) {
+// Set color diagnostics according to -color-diagnostics={auto,always,never}
+// or -no-color-diagnostics flags.
+static void handleColorDiagnostics(opt::InputArgList &Args) {
auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
OPT_no_color_diagnostics);
if (!Arg)
- return ErrorOS->has_colors();
- if (Arg->getOption().getID() == OPT_color_diagnostics)
- return true;
- if (Arg->getOption().getID() == OPT_no_color_diagnostics)
- return false;
-
- StringRef S = Arg->getValue();
- if (S == "auto")
- return ErrorOS->has_colors();
- if (S == "always")
- return true;
- if (S != "never")
- error("unknown option: -color-diagnostics=" + S);
- return false;
+ return;
+ else if (Arg->getOption().getID() == OPT_color_diagnostics)
+ errorHandler().ColorDiagnostics = true;
+ else if (Arg->getOption().getID() == OPT_no_color_diagnostics)
+ errorHandler().ColorDiagnostics = false;
+ else {
+ StringRef S = Arg->getValue();
+ if (S == "always")
+ errorHandler().ColorDiagnostics = true;
+ else if (S == "never")
+ errorHandler().ColorDiagnostics = false;
+ else if (S != "auto")
+ error("unknown option: -color-diagnostics=" + S);
+ }
}
static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
@@ -103,9 +104,7 @@ opt::InputArgList ELFOptTable::parse(Arr
cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec);
Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
- // Interpret -color-diagnostics early so that error messages
- // for unknown flags are colored.
- Config->ColorDiagnostics = getColorDiagnostics(Args);
+ handleColorDiagnostics(Args);
if (MissingCount)
error(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
Modified: lld/trunk/ELF/EhFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/EhFrame.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/EhFrame.cpp (original)
+++ lld/trunk/ELF/EhFrame.cpp Wed Oct 25 15:28:38 2017
@@ -17,11 +17,11 @@
//===----------------------------------------------------------------------===//
#include "EhFrame.h"
-#include "Error.h"
#include "InputSection.h"
#include "Relocations.h"
#include "Strings.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
Removed: lld/trunk/ELF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.cpp?rev=316623&view=auto
==============================================================================
--- lld/trunk/ELF/Error.cpp (original)
+++ lld/trunk/ELF/Error.cpp (removed)
@@ -1,120 +0,0 @@
-//===- Error.cpp ----------------------------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Error.h"
-#include "Config.h"
-
-#include "lld/Common/Threads.h"
-
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/raw_ostream.h"
-#include <mutex>
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#endif
-
-using namespace llvm;
-
-using namespace lld;
-using namespace lld::elf;
-
-uint64_t elf::ErrorCount;
-raw_ostream *elf::ErrorOS;
-
-// The functions defined in this file can be called from multiple threads,
-// but outs() or errs() are not thread-safe. We protect them using a mutex.
-static std::mutex Mu;
-
-// Prints "\n" or does nothing, depending on Msg contents of
-// the previous call of this function.
-static void newline(const Twine &Msg) {
- // True if the previous error message contained "\n".
- // We want to separate multi-line error messages with a newline.
- static bool Flag;
-
- if (Flag)
- *ErrorOS << "\n";
- Flag = StringRef(Msg.str()).contains('\n');
-}
-
-static void print(StringRef S, raw_ostream::Colors C) {
- *ErrorOS << Config->Argv[0] << ": ";
- if (Config->ColorDiagnostics) {
- ErrorOS->changeColor(C, true);
- *ErrorOS << S;
- ErrorOS->resetColor();
- } else {
- *ErrorOS << S;
- }
-}
-
-void elf::log(const Twine &Msg) {
- if (Config->Verbose) {
- std::lock_guard<std::mutex> Lock(Mu);
- outs() << Config->Argv[0] << ": " << Msg << "\n";
- outs().flush();
- }
-}
-
-void elf::message(const Twine &Msg) {
- std::lock_guard<std::mutex> Lock(Mu);
- outs() << Msg << "\n";
- outs().flush();
-}
-
-void elf::warn(const Twine &Msg) {
- if (Config->FatalWarnings) {
- error(Msg);
- return;
- }
-
- std::lock_guard<std::mutex> Lock(Mu);
- newline(Msg);
- print("warning: ", raw_ostream::MAGENTA);
- *ErrorOS << Msg << "\n";
-}
-
-void elf::error(const Twine &Msg) {
- std::lock_guard<std::mutex> Lock(Mu);
- newline(Msg);
-
- if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
- print("error: ", raw_ostream::RED);
- *ErrorOS << Msg << "\n";
- } else if (ErrorCount == Config->ErrorLimit) {
- print("error: ", raw_ostream::RED);
- *ErrorOS << "too many errors emitted, stopping now"
- << " (use -error-limit=0 to see all errors)\n";
- if (Config->ExitEarly)
- exitLld(1);
- }
-
- ++ErrorCount;
-}
-
-void elf::exitLld(int Val) {
- waitForBackgroundThreads();
-
- // Dealloc/destroy ManagedStatic variables before calling
- // _exit(). In a non-LTO build, this is a nop. In an LTO
- // build allows us to get the output of -time-passes.
- llvm_shutdown();
-
- outs().flush();
- errs().flush();
- _exit(Val);
-}
-
-void elf::fatal(const Twine &Msg) {
- error(Msg);
- exitLld(1);
-}
Removed: lld/trunk/ELF/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.h?rev=316623&view=auto
==============================================================================
--- lld/trunk/ELF/Error.h (original)
+++ lld/trunk/ELF/Error.h (removed)
@@ -1,78 +0,0 @@
-//===- Error.h --------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// In LLD, we have three levels of errors: fatal, error or warn.
-//
-// Fatal makes the program exit immediately with an error message.
-// You shouldn't use it except for reporting a corrupted input file.
-//
-// Error prints out an error message and increment a global variable
-// ErrorCount to record the fact that we met an error condition. It does
-// not exit, so it is safe for a lld-as-a-library use case. It is generally
-// useful because it can report more than one error in a single run.
-//
-// Warn doesn't do anything but printing out a given message.
-//
-// It is not recommended to use llvm::outs() or llvm::errs() directly
-// in LLD because they are not thread-safe. The functions declared in
-// this file are mutually excluded, so you want to use them instead.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_ELF_ERROR_H
-#define LLD_ELF_ERROR_H
-
-#include "lld/Common/LLVM.h"
-
-#include "llvm/Support/Error.h"
-
-namespace lld {
-namespace elf {
-
-extern uint64_t ErrorCount;
-extern llvm::raw_ostream *ErrorOS;
-
-void log(const Twine &Msg);
-void message(const Twine &Msg);
-void warn(const Twine &Msg);
-void error(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
-
-LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
-
-// check() functions are convenient functions to strip errors
-// from error-or-value objects.
-template <class T> T check(ErrorOr<T> E) {
- if (auto EC = E.getError())
- fatal(EC.message());
- return std::move(*E);
-}
-
-template <class T> T check(Expected<T> E) {
- if (!E)
- fatal(llvm::toString(E.takeError()));
- return std::move(*E);
-}
-
-template <class T> T check(ErrorOr<T> E, const Twine &Prefix) {
- if (auto EC = E.getError())
- fatal(Prefix + ": " + EC.message());
- return std::move(*E);
-}
-
-template <class T> T check(Expected<T> E, const Twine &Prefix) {
- if (!E)
- fatal(Prefix + ": " + toString(E.takeError()));
- return std::move(*E);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Oct 25 15:28:38 2017
@@ -8,13 +8,13 @@
//===----------------------------------------------------------------------===//
#include "InputFiles.h"
-#include "Error.h"
#include "InputSection.h"
#include "LinkerScript.h"
#include "Memory.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Wed Oct 25 15:28:38 2017
@@ -11,9 +11,9 @@
#define LLD_ELF_INPUT_FILES_H
#include "Config.h"
-#include "Error.h"
#include "InputSection.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Reproduce.h"
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Oct 25 15:28:38 2017
@@ -10,7 +10,6 @@
#include "InputSection.h"
#include "Config.h"
#include "EhFrame.h"
-#include "Error.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "Memory.h"
@@ -19,6 +18,7 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Wed Oct 25 15:28:38 2017
@@ -9,11 +9,11 @@
#include "LTO.h"
#include "Config.h"
-#include "Error.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Oct 25 15:28:38 2017
@@ -927,7 +927,7 @@ static void scanRelocs(InputSectionBase
Expr = fromPlt(Expr);
Expr = adjustExpr<ELFT>(Body, Expr, Type, Sec, Rel.r_offset);
- if (ErrorCount)
+ if (errorCount())
continue;
// This relocation does not require got entry, but it is relative to got and
Modified: lld/trunk/ELF/ScriptLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptLexer.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptLexer.cpp (original)
+++ lld/trunk/ELF/ScriptLexer.cpp Wed Oct 25 15:28:38 2017
@@ -33,7 +33,7 @@
//===----------------------------------------------------------------------===//
#include "ScriptLexer.h"
-#include "Error.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;
@@ -75,7 +75,7 @@ ScriptLexer::ScriptLexer(MemoryBufferRef
// We don't want to record cascading errors. Keep only the first one.
void ScriptLexer::setError(const Twine &Msg) {
- if (ErrorCount)
+ if (errorCount())
return;
std::string S = (getCurrentLocation() + ": " + Msg).str();
@@ -159,7 +159,7 @@ StringRef ScriptLexer::skipSpace(StringR
}
// An erroneous token is handled as if it were the last token before EOF.
-bool ScriptLexer::atEOF() { return ErrorCount || Tokens.size() == Pos; }
+bool ScriptLexer::atEOF() { return errorCount() || Tokens.size() == Pos; }
// Split a given string as an expression.
// This function returns "3", "*" and "5" for "3*5" for example.
@@ -207,7 +207,7 @@ static std::vector<StringRef> tokenizeEx
//
// This function may split the current token into multiple tokens.
void ScriptLexer::maybeSplitExpr() {
- if (!InExpr || ErrorCount || atEOF())
+ if (!InExpr || errorCount() || atEOF())
return;
std::vector<StringRef> V = tokenizeExpr(Tokens[Pos]);
@@ -220,7 +220,7 @@ void ScriptLexer::maybeSplitExpr() {
StringRef ScriptLexer::next() {
maybeSplitExpr();
- if (ErrorCount)
+ if (errorCount())
return "";
if (atEOF()) {
setError("unexpected EOF");
@@ -231,7 +231,7 @@ StringRef ScriptLexer::next() {
StringRef ScriptLexer::peek() {
StringRef Tok = next();
- if (ErrorCount)
+ if (errorCount())
return "";
Pos = Pos - 1;
return Tok;
@@ -260,7 +260,7 @@ bool ScriptLexer::consumeLabel(StringRef
void ScriptLexer::skip() { (void)next(); }
void ScriptLexer::expect(StringRef Expect) {
- if (ErrorCount)
+ if (errorCount())
return;
StringRef Tok = next();
if (Tok != Expect)
Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Wed Oct 25 15:28:38 2017
@@ -209,7 +209,7 @@ void ScriptParser::readVersionScriptComm
return;
}
- while (!atEOF() && !ErrorCount && peek() != "}") {
+ while (!atEOF() && !errorCount() && peek() != "}") {
StringRef VerStr = next();
if (VerStr == "{") {
setError("anonymous version definition is used in "
@@ -303,7 +303,7 @@ void ScriptParser::readAsNeeded() {
expect("(");
bool Orig = Config->AsNeeded;
Config->AsNeeded = true;
- while (!ErrorCount && !consume(")"))
+ while (!errorCount() && !consume(")"))
addFile(unquote(next()));
Config->AsNeeded = Orig;
}
@@ -319,13 +319,13 @@ void ScriptParser::readEntry() {
void ScriptParser::readExtern() {
expect("(");
- while (!ErrorCount && !consume(")"))
+ while (!errorCount() && !consume(")"))
Config->Undefined.push_back(next());
}
void ScriptParser::readGroup() {
expect("(");
- while (!ErrorCount && !consume(")")) {
+ while (!errorCount() && !consume(")")) {
if (consume("AS_NEEDED"))
readAsNeeded();
else
@@ -369,7 +369,7 @@ void ScriptParser::readOutput() {
void ScriptParser::readOutputArch() {
// OUTPUT_ARCH is ignored for now.
expect("(");
- while (!ErrorCount && !consume(")"))
+ while (!errorCount() && !consume(")"))
skip();
}
@@ -389,12 +389,12 @@ void ScriptParser::readOutputFormat() {
void ScriptParser::readPhdrs() {
expect("{");
- while (!ErrorCount && !consume("}")) {
+ while (!errorCount() && !consume("}")) {
PhdrsCommand Cmd;
Cmd.Name = next();
Cmd.Type = readPhdrType();
- while (!ErrorCount && !consume(";")) {
+ while (!errorCount() && !consume(";")) {
if (consume("FILEHDR"))
Cmd.HasFilehdr = true;
else if (consume("PHDRS"))
@@ -442,7 +442,7 @@ void ScriptParser::readSections() {
Config->SingleRoRx = true;
expect("{");
- while (!ErrorCount && !consume("}")) {
+ while (!errorCount() && !consume("}")) {
StringRef Tok = next();
BaseCommand *Cmd = readProvideOrAssignment(Tok);
if (!Cmd) {
@@ -467,7 +467,7 @@ static int precedence(StringRef Op) {
StringMatcher ScriptParser::readFilePatterns() {
std::vector<StringRef> V;
- while (!ErrorCount && !consume(")"))
+ while (!errorCount() && !consume(")"))
V.push_back(next());
return StringMatcher(V);
}
@@ -499,7 +499,7 @@ SortSectionPolicy ScriptParser::readSort
// any file but a.o, and section .baz in any file but b.o.
std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
std::vector<SectionPattern> Ret;
- while (!ErrorCount && peek() != ")") {
+ while (!errorCount() && peek() != ")") {
StringMatcher ExcludeFilePat;
if (consume("EXCLUDE_FILE")) {
expect("(");
@@ -507,7 +507,7 @@ std::vector<SectionPattern> ScriptParser
}
std::vector<StringRef> V;
- while (!ErrorCount && peek() != ")" && peek() != "EXCLUDE_FILE")
+ while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
V.push_back(next());
if (!V.empty())
@@ -534,7 +534,7 @@ ScriptParser::readInputSectionRules(Stri
auto *Cmd = make<InputSectionDescription>(FilePattern);
expect("(");
- while (!ErrorCount && !consume(")")) {
+ while (!errorCount() && !consume(")")) {
SortSectionPolicy Outer = readSortKind();
SortSectionPolicy Inner = SortSectionPolicy::Default;
std::vector<SectionPattern> V;
@@ -676,7 +676,7 @@ OutputSection *ScriptParser::readOutputS
Cmd->Constraint = ConstraintKind::ReadWrite;
expect("{");
- while (!ErrorCount && !consume("}")) {
+ while (!errorCount() && !consume("}")) {
StringRef Tok = next();
if (Tok == ";") {
// Empty commands are allowed. Do nothing here.
@@ -820,7 +820,7 @@ static Expr combine(StringRef Op, Expr L
// This is a part of the operator-precedence parser. This function
// assumes that the remaining token stream starts with an operator.
Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
- while (!atEOF() && !ErrorCount) {
+ while (!atEOF() && !errorCount()) {
// Read an operator and an expression.
if (consume("?"))
return readTernary(Lhs);
@@ -1098,7 +1098,7 @@ Expr ScriptParser::readParenExpr() {
std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
std::vector<StringRef> Phdrs;
- while (!ErrorCount && peek().startswith(":")) {
+ while (!errorCount() && peek().startswith(":")) {
StringRef Tok = next();
Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
}
@@ -1201,7 +1201,7 @@ ScriptParser::readSymbols() {
std::vector<SymbolVersion> Globals;
std::vector<SymbolVersion> *V = &Globals;
- while (!ErrorCount) {
+ while (!errorCount()) {
if (consume("}"))
break;
if (consumeLabel("local")) {
@@ -1235,7 +1235,7 @@ std::vector<SymbolVersion> ScriptParser:
expect("{");
std::vector<SymbolVersion> Ret;
- while (!ErrorCount && peek() != "}") {
+ while (!errorCount() && peek() != "}") {
StringRef Tok = next();
bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
@@ -1262,7 +1262,7 @@ uint64_t ScriptParser::readMemoryAssignm
// MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
void ScriptParser::readMemory() {
expect("{");
- while (!ErrorCount && !consume("}")) {
+ while (!errorCount() && !consume("}")) {
StringRef Name = next();
uint32_t Flags = 0;
Modified: lld/trunk/ELF/Strings.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Strings.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Strings.cpp (original)
+++ lld/trunk/ELF/Strings.cpp Wed Oct 25 15:28:38 2017
@@ -9,7 +9,7 @@
#include "Strings.h"
#include "Config.h"
-#include "Error.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Oct 25 15:28:38 2017
@@ -16,10 +16,10 @@
#include "SymbolTable.h"
#include "Config.h"
-#include "Error.h"
#include "LinkerScript.h"
#include "Memory.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/STLExtras.h"
using namespace llvm;
@@ -91,7 +91,7 @@ template <class ELFT> void SymbolTable::
if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
// DSOs are uniquified not by filename but by soname.
F->parseSoName();
- if (ErrorCount || !SoNames.insert(F->SoName).second)
+ if (errorCount() || !SoNames.insert(F->SoName).second)
return;
SharedFiles.push_back(F);
F->parseRest();
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Oct 25 15:28:38 2017
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "Symbols.h"
-#include "Error.h"
#include "InputFiles.h"
#include "InputSection.h"
#include "OutputSections.h"
@@ -17,6 +16,7 @@
#include "Target.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Path.h"
#include <cstring>
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Oct 25 15:28:38 2017
@@ -16,7 +16,6 @@
#include "SyntheticSections.h"
#include "Config.h"
-#include "Error.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "Memory.h"
@@ -25,6 +24,7 @@
#include "SymbolTable.h"
#include "Target.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/BinaryFormat/Dwarf.h"
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Oct 25 15:28:38 2017
@@ -25,11 +25,11 @@
//===----------------------------------------------------------------------===//
#include "Target.h"
-#include "Error.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
using namespace llvm;
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Oct 25 15:28:38 2017
@@ -10,8 +10,8 @@
#ifndef LLD_ELF_TARGET_H
#define LLD_ELF_TARGET_H
-#include "Error.h"
#include "InputSection.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
namespace lld {
Modified: lld/trunk/ELF/Thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.cpp (original)
+++ lld/trunk/ELF/Thunks.cpp Wed Oct 25 15:28:38 2017
@@ -23,13 +23,13 @@
#include "Thunks.h"
#include "Config.h"
-#include "Error.h"
#include "InputSection.h"
#include "Memory.h"
#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=316624&r1=316623&r2=316624&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Oct 25 15:28:38 2017
@@ -188,7 +188,7 @@ template <class ELFT> void Writer<ELFT>:
// to the string table, and add entries to .got and .plt.
// finalizeSections does that.
finalizeSections();
- if (ErrorCount)
+ if (errorCount())
return;
// If -compressed-debug-sections is specified, we need to compress
@@ -218,11 +218,11 @@ template <class ELFT> void Writer<ELFT>:
}
// It does not make sense try to open the file if we have error already.
- if (ErrorCount)
+ if (errorCount())
return;
// Write the result down to a file.
openFile();
- if (ErrorCount)
+ if (errorCount())
return;
if (!Config->OFormatBinary) {
@@ -236,12 +236,12 @@ template <class ELFT> void Writer<ELFT>:
// Backfill .note.gnu.build-id section content. This is done at last
// because the content is usually a hash value of the entire output file.
writeBuildId();
- if (ErrorCount)
+ if (errorCount())
return;
// Handle -Map option.
writeMapFile<ELFT>();
- if (ErrorCount)
+ if (errorCount())
return;
if (auto EC = Buffer->commit())
@@ -1287,7 +1287,7 @@ template <class ELFT> void Writer<ELFT>:
}
// Do not proceed if there was an undefined symbol.
- if (ErrorCount)
+ if (errorCount())
return;
addPredefinedSections();
Added: lld/trunk/include/lld/Common/ErrorHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Common/ErrorHandler.h?rev=316624&view=auto
==============================================================================
--- lld/trunk/include/lld/Common/ErrorHandler.h (added)
+++ lld/trunk/include/lld/Common/ErrorHandler.h Wed Oct 25 15:28:38 2017
@@ -0,0 +1,101 @@
+//===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// In LLD, we have three levels of errors: fatal, error or warn.
+//
+// Fatal makes the program exit immediately with an error message.
+// You shouldn't use it except for reporting a corrupted input file.
+//
+// Error prints out an error message and increment a global variable
+// ErrorCount to record the fact that we met an error condition. It does
+// not exit, so it is safe for a lld-as-a-library use case. It is generally
+// useful because it can report more than one error in a single run.
+//
+// Warn doesn't do anything but printing out a given message.
+//
+// It is not recommended to use llvm::outs() or llvm::errs() directly
+// in LLD because they are not thread-safe. The functions declared in
+// this file are mutually excluded, so you want to use them instead.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_COMMON_ERRORHANDLER_H
+#define LLD_COMMON_ERRORHANDLER_H
+
+#include "lld/Common/LLVM.h"
+
+#include "llvm/Support/Error.h"
+
+namespace lld {
+
+class ErrorHandler {
+public:
+ uint64_t ErrorCount = 0;
+ uint64_t ErrorLimit = 20;
+ StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now";
+ StringRef LogName = "lld";
+ llvm::raw_ostream *ErrorOS = &llvm::errs();
+ bool ColorDiagnostics = llvm::errs().has_colors();
+ bool ExitEarly = true;
+ bool FatalWarnings = false;
+ bool Verbose = false;
+
+ void error(const Twine &Msg);
+ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
+ void log(const Twine &Msg);
+ void message(const Twine &Msg);
+ void warn(const Twine &Msg);
+
+private:
+ void print(StringRef S, raw_ostream::Colors C);
+};
+
+/// Returns the default error handler.
+ErrorHandler &errorHandler();
+
+inline void error(const Twine &Msg) { errorHandler().error(Msg); }
+inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
+ errorHandler().fatal(Msg);
+}
+inline void log(const Twine &Msg) { errorHandler().log(Msg); }
+inline void message(const Twine &Msg) { errorHandler().message(Msg); }
+inline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
+inline uint64_t errorCount() { return errorHandler().ErrorCount; }
+
+LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
+
+// check() functions are convenient functions to strip errors
+// from error-or-value objects.
+template <class T> T check(ErrorOr<T> E) {
+ if (auto EC = E.getError())
+ fatal(EC.message());
+ return std::move(*E);
+}
+
+template <class T> T check(Expected<T> E) {
+ if (!E)
+ fatal(llvm::toString(E.takeError()));
+ return std::move(*E);
+}
+
+template <class T> T check(ErrorOr<T> E, const Twine &Prefix) {
+ if (auto EC = E.getError())
+ fatal(Prefix + ": " + EC.message());
+ return std::move(*E);
+}
+
+template <class T> T check(Expected<T> E, const Twine &Prefix) {
+ if (!E)
+ fatal(Prefix + ": " + toString(E.takeError()));
+ return std::move(*E);
+}
+
+} // namespace lld
+
+#endif
More information about the llvm-commits
mailing list