1//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lld/Core/Error.h" 10#include "llvm/ADT/Twine.h" 11#include "llvm/Support/ErrorHandling.h" 12#include <mutex> 13#include <string> 14#include <vector> 15 16using namespace lld; 17 18namespace { 19class _YamlReaderErrorCategory : public std::error_category { 20public: 21 const char* name() const noexcept override { 22 return "lld.yaml.reader"; 23 } 24 25 std::string message(int ev) const override { 26 switch (static_cast<YamlReaderError>(ev)) { 27 case YamlReaderError::unknown_keyword: 28 return "Unknown keyword found in yaml file"; 29 case YamlReaderError::illegal_value: 30 return "Bad value found in yaml file"; 31 } 32 llvm_unreachable("An enumerator of YamlReaderError does not have a " 33 "message defined."); 34 } 35}; 36} // end anonymous namespace 37 38const std::error_category &lld::YamlReaderCategory() { 39 static _YamlReaderErrorCategory o; 40 return o; 41} 42 43namespace lld { 44 45/// Temporary class to enable make_dynamic_error_code() until 46/// llvm::ErrorOr<> is updated to work with error encapsulations 47/// other than error_code. 48class dynamic_error_category : public std::error_category { 49public: 50 ~dynamic_error_category() override = default; 51 52 const char *name() const noexcept override { 53 return "lld.dynamic_error"; 54 } 55 56 std::string message(int ev) const override { 57 assert(ev >= 0); 58 assert(ev < (int)_messages.size()); 59 // The value is an index into the string vector. 60 return _messages[ev]; 61 } 62 63 int add(std::string msg) { 64 std::lock_guard<std::recursive_mutex> lock(_mutex); 65 // Value zero is always the success value. 66 if (_messages.empty()) 67 _messages.push_back("Success"); 68 _messages.push_back(msg); 69 // Return the index of the string just appended. 70 return _messages.size() - 1; 71 } 72 73private: 74 std::vector<std::string> _messages; 75 std::recursive_mutex _mutex; 76}; 77 78static dynamic_error_category categorySingleton; 79 80std::error_code make_dynamic_error_code(StringRef msg) { 81 return std::error_code(categorySingleton.add(std::string(msg)), 82 categorySingleton); 83} 84 85char GenericError::ID = 0; 86 87GenericError::GenericError(Twine Msg) : Msg(Msg.str()) { } 88 89void GenericError::log(raw_ostream &OS) const { 90 OS << Msg; 91} 92 93} // namespace lld 94