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 16 using namespace lld; 17 18 namespace { 19 class _YamlReaderErrorCategory : public std::error_category { 20 public: name() const21 const char* name() const noexcept override { 22 return "lld.yaml.reader"; 23 } 24 message(int ev) const25 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 YamlReaderCategory()38const std::error_category &lld::YamlReaderCategory() { 39 static _YamlReaderErrorCategory o; 40 return o; 41 } 42 43 namespace 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. 48 class dynamic_error_category : public std::error_category { 49 public: 50 ~dynamic_error_category() override = default; 51 name() const52 const char *name() const noexcept override { 53 return "lld.dynamic_error"; 54 } 55 message(int ev) const56 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 add(std::string msg)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 73 private: 74 std::vector<std::string> _messages; 75 std::recursive_mutex _mutex; 76 }; 77 78 static dynamic_error_category categorySingleton; 79 make_dynamic_error_code(StringRef msg)80std::error_code make_dynamic_error_code(StringRef msg) { 81 return std::error_code(categorySingleton.add(std::string(msg)), 82 categorySingleton); 83 } 84 85 char GenericError::ID = 0; 86 GenericError(Twine Msg)87GenericError::GenericError(Twine Msg) : Msg(Msg.str()) { } 88 log(raw_ostream & OS) const89void GenericError::log(raw_ostream &OS) const { 90 OS << Msg; 91 } 92 93 } // namespace lld 94