File indexing completed on 2026-05-10 08:42:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 #ifndef LLD_COMMON_ERRORHANDLER_H
0069 #define LLD_COMMON_ERRORHANDLER_H
0070
0071 #include "lld/Common/LLVM.h"
0072
0073 #include "llvm/ADT/STLExtras.h"
0074 #include "llvm/ADT/SmallString.h"
0075 #include "llvm/Support/Error.h"
0076 #include "llvm/Support/FileOutputBuffer.h"
0077 #include "llvm/Support/raw_ostream.h"
0078 #include <mutex>
0079
0080 namespace llvm {
0081 class DiagnosticInfo;
0082 }
0083
0084 namespace lld {
0085
0086 llvm::raw_ostream &outs();
0087
0088 enum class ErrorTag { LibNotFound, SymbolNotFound };
0089
0090 class ErrorHandler {
0091 public:
0092 ~ErrorHandler();
0093
0094 void initialize(llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS,
0095 bool exitEarly, bool disableOutput);
0096
0097 uint64_t errorCount = 0;
0098 uint64_t errorLimit = 20;
0099 StringRef errorLimitExceededMsg = "too many errors emitted, stopping now";
0100 StringRef errorHandlingScript;
0101 StringRef logName = "lld";
0102 bool exitEarly = true;
0103 bool fatalWarnings = false;
0104 bool suppressWarnings = false;
0105 bool verbose = false;
0106 bool vsDiagnostics = false;
0107 bool disableOutput = false;
0108 std::function<void()> cleanupCallback;
0109
0110 void error(const Twine &msg);
0111 void error(const Twine &msg, ErrorTag tag, ArrayRef<StringRef> args);
0112 [[noreturn]] void fatal(const Twine &msg);
0113 void log(const Twine &msg);
0114 void message(const Twine &msg, llvm::raw_ostream &s);
0115 void warn(const Twine &msg);
0116
0117 raw_ostream &outs();
0118 raw_ostream &errs();
0119 void flushStreams();
0120
0121 std::unique_ptr<llvm::FileOutputBuffer> outputBuffer;
0122
0123 private:
0124 using Colors = raw_ostream::Colors;
0125
0126 std::string getLocation(const Twine &msg);
0127 void reportDiagnostic(StringRef location, Colors c, StringRef diagKind,
0128 const Twine &msg);
0129
0130
0131
0132 llvm::StringRef sep;
0133
0134
0135
0136
0137
0138
0139 std::mutex mu;
0140 llvm::raw_ostream *stdoutOS{};
0141 llvm::raw_ostream *stderrOS{};
0142 };
0143
0144
0145 ErrorHandler &errorHandler();
0146
0147 void error(const Twine &msg);
0148 void error(const Twine &msg, ErrorTag tag, ArrayRef<StringRef> args);
0149 [[noreturn]] void fatal(const Twine &msg);
0150 void log(const Twine &msg);
0151 void message(const Twine &msg, llvm::raw_ostream &s = outs());
0152 void warn(const Twine &msg);
0153 uint64_t errorCount();
0154
0155 enum class DiagLevel { None, Log, Msg, Warn, Err, Fatal };
0156
0157
0158
0159 class SyncStream {
0160 ErrorHandler &e;
0161 DiagLevel level;
0162 llvm::SmallString<0> buf;
0163
0164 public:
0165 mutable llvm::raw_svector_ostream os{buf};
0166 SyncStream(ErrorHandler &e, DiagLevel level) : e(e), level(level) {}
0167 SyncStream(SyncStream &&o) : e(o.e), level(o.level), buf(std::move(o.buf)) {}
0168 ~SyncStream();
0169 StringRef str() { return os.str(); }
0170 uint64_t tell() { return os.tell(); }
0171 };
0172
0173 [[noreturn]] void exitLld(int val);
0174
0175 void diagnosticHandler(const llvm::DiagnosticInfo &di);
0176 void checkError(Error e);
0177 void checkError(ErrorHandler &eh, Error e);
0178
0179
0180
0181 template <class T> T check(ErrorOr<T> e) {
0182 if (auto ec = e.getError())
0183 fatal(ec.message());
0184 return std::move(*e);
0185 }
0186
0187 template <class T> T check(Expected<T> e) {
0188 if (!e)
0189 fatal(llvm::toString(e.takeError()));
0190 return std::move(*e);
0191 }
0192
0193
0194 template <class T> T &check(Expected<T &> e) {
0195 if (!e)
0196 fatal(llvm::toString(e.takeError()));
0197 return *e;
0198 }
0199
0200 template <class T>
0201 T check2(ErrorOr<T> e, llvm::function_ref<std::string()> prefix) {
0202 if (auto ec = e.getError())
0203 fatal(prefix() + ": " + ec.message());
0204 return std::move(*e);
0205 }
0206
0207 template <class T>
0208 T check2(Expected<T> e, llvm::function_ref<std::string()> prefix) {
0209 if (!e)
0210 fatal(prefix() + ": " + toString(e.takeError()));
0211 return std::move(*e);
0212 }
0213
0214 inline std::string toString(const Twine &s) { return s.str(); }
0215
0216
0217 #define CHECK(E, S) check2((E), [&] { return toString(S); })
0218
0219 }
0220
0221 #endif