1e4446923SMichael J. Spencer //===- Error.cpp - system_error extensions for Object -----------*- C++ -*-===// 2e4446923SMichael J. Spencer // 3e4446923SMichael J. Spencer // The LLVM Compiler Infrastructure 4e4446923SMichael J. Spencer // 5e4446923SMichael J. Spencer // This file is distributed under the University of Illinois Open Source 6e4446923SMichael J. Spencer // License. See LICENSE.TXT for details. 7e4446923SMichael J. Spencer // 8e4446923SMichael J. Spencer //===----------------------------------------------------------------------===// 9e4446923SMichael J. Spencer // 10e4446923SMichael J. Spencer // This defines a new error_category for the Object library. 11e4446923SMichael J. Spencer // 12e4446923SMichael J. Spencer //===----------------------------------------------------------------------===// 13e4446923SMichael J. Spencer 14e4446923SMichael J. Spencer #include "llvm/Object/Error.h" 15e4446923SMichael J. Spencer #include "llvm/Support/ErrorHandling.h" 16684981e4SChris Bieneman #include "llvm/Support/ManagedStatic.h" 17e4446923SMichael J. Spencer 18e4446923SMichael J. Spencer using namespace llvm; 19e4446923SMichael J. Spencer using namespace object; 20e4446923SMichael J. Spencer 21e4446923SMichael J. Spencer namespace { 224718f8b5SPeter Collingbourne // FIXME: This class is only here to support the transition to llvm::Error. It 234718f8b5SPeter Collingbourne // will be removed once this transition is complete. Clients should prefer to 244718f8b5SPeter Collingbourne // deal with the Error value directly, rather than converting to error_code. 2525188c95SRafael Espindola class _object_error_category : public std::error_category { 26e4446923SMichael J. Spencer public: 27*990504e6SReid Kleckner const char* name() const noexcept override; 28e3bfdc4eSJustin Bogner std::string message(int ev) const override; 29e4446923SMichael J. Spencer }; 30e4446923SMichael J. Spencer } 31e4446923SMichael J. Spencer 32*990504e6SReid Kleckner const char *_object_error_category::name() const noexcept { 33e4446923SMichael J. Spencer return "llvm.object"; 34e4446923SMichael J. Spencer } 35e4446923SMichael J. Spencer 36e00fec8fSRafael Espindola std::string _object_error_category::message(int EV) const { 37e00fec8fSRafael Espindola object_error E = static_cast<object_error>(EV); 38e107ade3SRafael Espindola switch (E) { 39e6388e62SAlexey Samsonov case object_error::arch_not_found: 40e6388e62SAlexey Samsonov return "No object file for requested architecture"; 41e4446923SMichael J. Spencer case object_error::invalid_file_type: 42e4446923SMichael J. Spencer return "The file was not recognized as a valid object file"; 43e4446923SMichael J. Spencer case object_error::parse_failed: 44e4446923SMichael J. Spencer return "Invalid data was encountered while parsing the file"; 451d6167fdSMichael J. Spencer case object_error::unexpected_eof: 461d6167fdSMichael J. Spencer return "The end of the file was unexpectedly encountered"; 476a1bfb2fSRafael Espindola case object_error::string_table_non_null_end: 486a1bfb2fSRafael Espindola return "String table must end with a null terminator"; 496def3042SRafael Espindola case object_error::invalid_section_index: 506def3042SRafael Espindola return "Invalid section index"; 5110039c02SPeter Collingbourne case object_error::bitcode_section_not_found: 5210039c02SPeter Collingbourne return "Bitcode section not found in object file"; 53e107ade3SRafael Espindola } 54e4446923SMichael J. Spencer llvm_unreachable("An enumerator of object_error does not have a message " 55e4446923SMichael J. Spencer "defined."); 56e4446923SMichael J. Spencer } 57e4446923SMichael J. Spencer 589e964f37SLang Hames char BinaryError::ID = 0; 599e964f37SLang Hames char GenericBinaryError::ID = 0; 609e964f37SLang Hames 61d4e075beSKevin Enderby GenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {} 629e964f37SLang Hames 63d4e075beSKevin Enderby GenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride) 64d4e075beSKevin Enderby : Msg(Msg.str()) { 659e964f37SLang Hames setErrorCode(make_error_code(ECOverride)); 669e964f37SLang Hames } 679e964f37SLang Hames 689e964f37SLang Hames void GenericBinaryError::log(raw_ostream &OS) const { 69d4e075beSKevin Enderby OS << Msg; 709e964f37SLang Hames } 719e964f37SLang Hames 72684981e4SChris Bieneman static ManagedStatic<_object_error_category> error_category; 73684981e4SChris Bieneman 7425188c95SRafael Espindola const std::error_category &object::object_category() { 75684981e4SChris Bieneman return *error_category; 76e4446923SMichael J. Spencer } 778a63b2afSLang Hames 788a63b2afSLang Hames llvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) { 798a63b2afSLang Hames if (auto Err2 = 808a63b2afSLang Hames handleErrors(std::move(Err), 818a63b2afSLang Hames [](std::unique_ptr<ECError> M) { 828a63b2afSLang Hames // Try to handle 'M'. If successful, return a success value from 838a63b2afSLang Hames // the handler. 848a63b2afSLang Hames if (M->convertToErrorCode() == object_error::invalid_file_type) 858a63b2afSLang Hames return Error::success(); 868a63b2afSLang Hames 878a63b2afSLang Hames // We failed to handle 'M' - return it from the handler. 888a63b2afSLang Hames // This value will be passed back from catchErrors and 898a63b2afSLang Hames // wind up in Err2, where it will be returned from this function. 908a63b2afSLang Hames return Error(std::move(M)); 918a63b2afSLang Hames })) 928a63b2afSLang Hames return Err2; 938a63b2afSLang Hames return Err; 948a63b2afSLang Hames } 95