OSDN Git Service

This is the first step in adding sane error handling support to LLVMSystem.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 16 Nov 2010 18:31:52 +0000 (18:31 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 16 Nov 2010 18:31:52 +0000 (18:31 +0000)
The system API's will be shifted over to returning an error_code, and returning
other return values as out parameters to the function.

Code that needs to check error conditions will use the errc enum values which
are the same as the posix_errno defines (EBADF, E2BIG, etc...), and are
compatable with the error codes in WinError.h due to some magic in system_error.

An example would be:

if (error_code ec = KillEvil("Java")) { // error_code can be converted to bool.
  handle_error(ec);
}

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119360 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/system_error.h [moved from utils/KillTheDoctor/system_error.h with 88% similarity]
lib/System/CMakeLists.txt
lib/System/Unix/system_error.inc [new file with mode: 0644]
lib/System/Win32/system_error.inc [new file with mode: 0644]
lib/System/system_error.cpp [new file with mode: 0644]
utils/KillTheDoctor/CMakeLists.txt
utils/KillTheDoctor/KillTheDoctor.cpp
utils/KillTheDoctor/system_error.cpp [deleted file]

similarity index 88%
rename from utils/KillTheDoctor/system_error.h
rename to include/llvm/System/system_error.h
index 55faa1b..db89efe 100644 (file)
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This was lifted from libc++ and modified for C++03.
+// This was lifted from libc++ and modified for C++03. This is called
+// system_error even though it does not define that class because that's what
+// it's called in C++0x. We don't define system_error because it is only used
+// for exception handling, which we don't use in LLVM.
 //
 //===----------------------------------------------------------------------===//
 
@@ -224,6 +227,8 @@ template <> struct hash<std::error_code>;
 #include <cerrno>
 #include <string>
 
+// This must be here instead of a .inc file because it is used in the definition
+// of the enum values below.
 #ifdef LLVM_ON_WIN32
   // VS 2008 needs this for some of the defines below.
 # include <WinSock2.h>
@@ -691,7 +696,7 @@ inline error_condition make_error_condition(errc _e) {
 
 inline bool operator<(const error_condition& _x, const error_condition& _y) {
   return _x.category() < _y.category()
-      || _x.category() == _y.category() && _x.value() < _y.value();
+      || (_x.category() == _y.category() && _x.value() < _y.value());
 }
 
 // error_code
@@ -750,7 +755,7 @@ inline error_code make_error_code(errc _e) {
 
 inline bool operator<(const error_code& _x, const error_code& _y) {
   return _x.category() < _y.category()
-      || _x.category() == _y.category() && _x.value() < _y.value();
+      || (_x.category() == _y.category() && _x.value() < _y.value());
 }
 
 inline bool operator==(const error_code& _x, const error_code& _y) {
@@ -788,97 +793,73 @@ inline bool operator!=(const error_condition& _x, const error_condition& _y) {
 
 // system_error
 
-class system_error : public std::runtime_error {
-  error_code _ec_;
-public:
-  system_error(error_code _ec, const std::string& _what_arg);
-  system_error(error_code _ec, const char* _what_arg);
-  system_error(error_code _ec);
-  system_error(int _ev, const error_category& _ecat,
-               const std::string& _what_arg);
-  system_error(int _ev, const error_category& _ecat, const char* _what_arg);
-  system_error(int _ev, const error_category& _ecat);
-  ~system_error() throw();
-
-  const error_code& code() const throw() {return _ec_;}
-
-private:
-  static std::string _init(const error_code&, std::string);
-};
-
-void _throw_system_error(int ev, const char* what_arg);
-
 } // end namespace llvm
 
+// This needs to stay here for KillTheDoctor.
 #ifdef LLVM_ON_WIN32
 #include <Windows.h>
 #include <WinError.h>
 
 namespace llvm {
 
-//  To construct an error_code after a API error:
+//  To construct an error_code after an API error:
 //
 //      error_code( ::GetLastError(), system_category() )
 struct windows_error {
 enum _ {
   success = 0,
   // These names and values are based on Windows winerror.h
-  invalid_function = ERROR_INVALID_FUNCTION,
-  file_not_found = ERROR_FILE_NOT_FOUND,
-  path_not_found = ERROR_PATH_NOT_FOUND,
-  too_many_open_files = ERROR_TOO_MANY_OPEN_FILES,
-  access_denied = ERROR_ACCESS_DENIED,
-  invalid_handle = ERROR_INVALID_HANDLE,
-  arena_trashed = ERROR_ARENA_TRASHED,
-  not_enough_memory = ERROR_NOT_ENOUGH_MEMORY,
-  invalid_block = ERROR_INVALID_BLOCK,
-  bad_environment = ERROR_BAD_ENVIRONMENT,
-  bad_format = ERROR_BAD_FORMAT,
-  invalid_access = ERROR_INVALID_ACCESS,
-  outofmemory = ERROR_OUTOFMEMORY,
-  invalid_drive = ERROR_INVALID_DRIVE,
-  current_directory = ERROR_CURRENT_DIRECTORY,
-  not_same_device = ERROR_NOT_SAME_DEVICE,
-  no_more_files = ERROR_NO_MORE_FILES,
-  write_protect = ERROR_WRITE_PROTECT,
-  bad_unit = ERROR_BAD_UNIT,
-  not_ready = ERROR_NOT_READY,
-  bad_command = ERROR_BAD_COMMAND,
-  crc = ERROR_CRC,
-  bad_length = ERROR_BAD_LENGTH,
-  seek = ERROR_SEEK,
-  not_dos_disk = ERROR_NOT_DOS_DISK,
-  sector_not_found = ERROR_SECTOR_NOT_FOUND,
-  out_of_paper = ERROR_OUT_OF_PAPER,
-  write_fault = ERROR_WRITE_FAULT,
-  read_fault = ERROR_READ_FAULT,
-  gen_failure = ERROR_GEN_FAILURE,
-  sharing_violation = ERROR_SHARING_VIOLATION,
-  lock_violation = ERROR_LOCK_VIOLATION,
-  wrong_disk = ERROR_WRONG_DISK,
+  // This is not a complete list.
+  invalid_function        = ERROR_INVALID_FUNCTION,
+  file_not_found          = ERROR_FILE_NOT_FOUND,
+  path_not_found          = ERROR_PATH_NOT_FOUND,
+  too_many_open_files     = ERROR_TOO_MANY_OPEN_FILES,
+  access_denied           = ERROR_ACCESS_DENIED,
+  invalid_handle          = ERROR_INVALID_HANDLE,
+  arena_trashed           = ERROR_ARENA_TRASHED,
+  not_enough_memory       = ERROR_NOT_ENOUGH_MEMORY,
+  invalid_block           = ERROR_INVALID_BLOCK,
+  bad_environment         = ERROR_BAD_ENVIRONMENT,
+  bad_format              = ERROR_BAD_FORMAT,
+  invalid_access          = ERROR_INVALID_ACCESS,
+  outofmemory             = ERROR_OUTOFMEMORY,
+  invalid_drive           = ERROR_INVALID_DRIVE,
+  current_directory       = ERROR_CURRENT_DIRECTORY,
+  not_same_device         = ERROR_NOT_SAME_DEVICE,
+  no_more_files           = ERROR_NO_MORE_FILES,
+  write_protect           = ERROR_WRITE_PROTECT,
+  bad_unit                = ERROR_BAD_UNIT,
+  not_ready               = ERROR_NOT_READY,
+  bad_command             = ERROR_BAD_COMMAND,
+  crc                     = ERROR_CRC,
+  bad_length              = ERROR_BAD_LENGTH,
+  seek                    = ERROR_SEEK,
+  not_dos_disk            = ERROR_NOT_DOS_DISK,
+  sector_not_found        = ERROR_SECTOR_NOT_FOUND,
+  out_of_paper            = ERROR_OUT_OF_PAPER,
+  write_fault             = ERROR_WRITE_FAULT,
+  read_fault              = ERROR_READ_FAULT,
+  gen_failure             = ERROR_GEN_FAILURE,
+  sharing_violation       = ERROR_SHARING_VIOLATION,
+  lock_violation          = ERROR_LOCK_VIOLATION,
+  wrong_disk              = ERROR_WRONG_DISK,
   sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED,
-  handle_eof = ERROR_HANDLE_EOF,
-  handle_disk_full= ERROR_HANDLE_DISK_FULL,
-  rem_not_list = ERROR_REM_NOT_LIST,
-  dup_name = ERROR_DUP_NAME,
-  bad_net_path = ERROR_BAD_NETPATH,
-  network_busy = ERROR_NETWORK_BUSY,
-  // ...
-  file_exists = ERROR_FILE_EXISTS,
-  cannot_make = ERROR_CANNOT_MAKE,
-  // ...
-  broken_pipe = ERROR_BROKEN_PIPE,
-  open_failed = ERROR_OPEN_FAILED,
-  buffer_overflow = ERROR_BUFFER_OVERFLOW,
-  disk_full= ERROR_DISK_FULL,
-  // ...
-  lock_failed = ERROR_LOCK_FAILED,
-  busy = ERROR_BUSY,
-  cancel_violation = ERROR_CANCEL_VIOLATION,
-  already_exists = ERROR_ALREADY_EXISTS
-  // ...
-
-  // TODO: add more Windows errors
+  handle_eof              = ERROR_HANDLE_EOF,
+  handle_disk_full        = ERROR_HANDLE_DISK_FULL,
+  rem_not_list            = ERROR_REM_NOT_LIST,
+  dup_name                = ERROR_DUP_NAME,
+  bad_net_path            = ERROR_BAD_NETPATH,
+  network_busy            = ERROR_NETWORK_BUSY,
+  file_exists             = ERROR_FILE_EXISTS,
+  cannot_make             = ERROR_CANNOT_MAKE,
+  broken_pipe             = ERROR_BROKEN_PIPE,
+  open_failed             = ERROR_OPEN_FAILED,
+  buffer_overflow         = ERROR_BUFFER_OVERFLOW,
+  disk_full               = ERROR_DISK_FULL,
+  lock_failed             = ERROR_LOCK_FAILED,
+  busy                    = ERROR_BUSY,
+  cancel_violation        = ERROR_CANCEL_VIOLATION,
+  already_exists          = ERROR_ALREADY_EXISTS
 };
   _ v_;
 
index ac2830e..16612ad 100644 (file)
@@ -19,6 +19,7 @@ add_llvm_library(LLVMSystem
   RWMutex.cpp
   SearchForAddressOfSpecialSymbol.cpp
   Signals.cpp
+  system_error.cpp
   ThreadLocal.cpp
   Threading.cpp
   TimeValue.cpp
@@ -32,6 +33,7 @@ add_llvm_library(LLVMSystem
   Unix/Program.inc
   Unix/RWMutex.inc
   Unix/Signals.inc
+  Unix/system_error.inc
   Unix/ThreadLocal.inc
   Unix/TimeValue.inc
   Win32/Alarm.inc
@@ -44,6 +46,7 @@ add_llvm_library(LLVMSystem
   Win32/Program.inc
   Win32/RWMutex.inc
   Win32/Signals.inc
+  Win32/system_error.inc
   Win32/ThreadLocal.inc
   Win32/TimeValue.inc
   )
diff --git a/lib/System/Unix/system_error.inc b/lib/System/Unix/system_error.inc
new file mode 100644 (file)
index 0000000..a382214
--- /dev/null
@@ -0,0 +1,34 @@
+//===- llvm/System/Unix/system_error.inc - Unix error_code ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Unix specific implementation of the error_code
+// and error_condition classes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+
+std::string
+_system_error_category::message(int ev) const {
+  return _do_message::message(ev);
+}
+
+error_condition
+_system_error_category::default_error_condition(int ev) const {
+#ifdef ELAST
+  if (ev > ELAST)
+    return error_condition(ev, system_category());
+#endif  // ELAST
+  return error_condition(ev, generic_category());
+}
diff --git a/lib/System/Win32/system_error.inc b/lib/System/Win32/system_error.inc
new file mode 100644 (file)
index 0000000..db02582
--- /dev/null
@@ -0,0 +1,140 @@
+//===- llvm/System/Win32/system_error.inc - Windows error_code --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Windows specific implementation of the error_code
+// and error_condition classes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Windows code that
+//===          is guaranteed to work on *all* Windows variants.
+//===----------------------------------------------------------------------===//
+
+#include <Windows.h>
+#include <WinError.h>
+
+using namespace llvm;
+
+std::string
+_system_error_category::message(int ev) const {
+  LPVOID lpMsgBuf = 0;
+  DWORD retval = ::FormatMessageA(
+    FORMAT_MESSAGE_ALLOCATE_BUFFER |
+    FORMAT_MESSAGE_FROM_SYSTEM |
+    FORMAT_MESSAGE_IGNORE_INSERTS,
+    NULL,
+    ev,
+    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+    (LPSTR) &lpMsgBuf,
+    0,
+    NULL);
+  if (retval == 0) {
+    ::LocalFree(lpMsgBuf);
+    return std::string("Unknown error");
+  }
+
+  std::string str( static_cast<LPCSTR>(lpMsgBuf) );
+  ::LocalFree(lpMsgBuf);
+
+  while (str.size()
+     && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r'))
+    str.erase( str.size()-1 );
+  if (str.size() && str[str.size()-1] == '.')
+    str.erase( str.size()-1 );
+  return str;
+}
+
+// I'd rather not double the line count of the following.
+#define MAP_ERR_TO_COND(x, y) case x: return make_error_condition(errc::y)
+
+error_condition
+_system_error_category::default_error_condition(int ev) const {
+  switch (ev) {
+  MAP_ERR_TO_COND(0, success);
+  // Windows system -> posix_errno decode table  ---------------------------//
+  // see WinError.h comments for descriptions of errors
+  MAP_ERR_TO_COND(ERROR_ACCESS_DENIED,       permission_denied);
+  MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS,      file_exists);
+  MAP_ERR_TO_COND(ERROR_BAD_UNIT,            no_such_device);
+  MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW,     filename_too_long);
+  MAP_ERR_TO_COND(ERROR_BUSY,                device_or_resource_busy);
+  MAP_ERR_TO_COND(ERROR_BUSY_DRIVE,          device_or_resource_busy);
+  MAP_ERR_TO_COND(ERROR_CANNOT_MAKE,         permission_denied);
+  MAP_ERR_TO_COND(ERROR_CANTOPEN,            io_error);
+  MAP_ERR_TO_COND(ERROR_CANTREAD,            io_error);
+  MAP_ERR_TO_COND(ERROR_CANTWRITE,           io_error);
+  MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY,   permission_denied);
+  MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST,       no_such_device);
+  MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE,       device_or_resource_busy);
+  MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY,       directory_not_empty);
+  MAP_ERR_TO_COND(ERROR_DIRECTORY,           invalid_argument);
+  MAP_ERR_TO_COND(ERROR_DISK_FULL,           no_space_on_device);
+  MAP_ERR_TO_COND(ERROR_FILE_EXISTS,         file_exists);
+  MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND,      no_such_file_or_directory);
+  MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL,    no_space_on_device);
+  MAP_ERR_TO_COND(ERROR_INVALID_ACCESS,      permission_denied);
+  MAP_ERR_TO_COND(ERROR_INVALID_DRIVE,       no_such_device);
+  MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION,    function_not_supported);
+  MAP_ERR_TO_COND(ERROR_INVALID_HANDLE,      invalid_argument);
+  MAP_ERR_TO_COND(ERROR_INVALID_NAME,        invalid_argument);
+  MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION,      no_lock_available);
+  MAP_ERR_TO_COND(ERROR_LOCKED,              no_lock_available);
+  MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK,       invalid_argument);
+  MAP_ERR_TO_COND(ERROR_NOACCESS,            permission_denied);
+  MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY,   not_enough_memory);
+  MAP_ERR_TO_COND(ERROR_NOT_READY,           resource_unavailable_try_again);
+  MAP_ERR_TO_COND(ERROR_NOT_SAME_DEVICE,     cross_device_link);
+  MAP_ERR_TO_COND(ERROR_OPEN_FAILED,         io_error);
+  MAP_ERR_TO_COND(ERROR_OPEN_FILES,          device_or_resource_busy);
+  MAP_ERR_TO_COND(ERROR_OPERATION_ABORTED,   operation_canceled);
+  MAP_ERR_TO_COND(ERROR_OUTOFMEMORY,         not_enough_memory);
+  MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND,      no_such_file_or_directory);
+  MAP_ERR_TO_COND(ERROR_READ_FAULT,          io_error);
+  MAP_ERR_TO_COND(ERROR_RETRY,               resource_unavailable_try_again);
+  MAP_ERR_TO_COND(ERROR_SEEK,                io_error);
+  MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION,   permission_denied);
+  MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open);
+  MAP_ERR_TO_COND(ERROR_WRITE_FAULT,         io_error);
+  MAP_ERR_TO_COND(ERROR_WRITE_PROTECT,       permission_denied);
+  MAP_ERR_TO_COND(ERROR_SEM_TIMEOUT,         timed_out);
+  MAP_ERR_TO_COND(WSAEACCES,                 permission_denied);
+  MAP_ERR_TO_COND(WSAEADDRINUSE,             address_in_use);
+  MAP_ERR_TO_COND(WSAEADDRNOTAVAIL,          address_not_available);
+  MAP_ERR_TO_COND(WSAEAFNOSUPPORT,           address_family_not_supported);
+  MAP_ERR_TO_COND(WSAEALREADY,               connection_already_in_progress);
+  MAP_ERR_TO_COND(WSAEBADF,                  bad_file_descriptor);
+  MAP_ERR_TO_COND(WSAECONNABORTED,           connection_aborted);
+  MAP_ERR_TO_COND(WSAECONNREFUSED,           connection_refused);
+  MAP_ERR_TO_COND(WSAECONNRESET,             connection_reset);
+  MAP_ERR_TO_COND(WSAEDESTADDRREQ,           destination_address_required);
+  MAP_ERR_TO_COND(WSAEFAULT,                 bad_address);
+  MAP_ERR_TO_COND(WSAEHOSTUNREACH,           host_unreachable);
+  MAP_ERR_TO_COND(WSAEINPROGRESS,            operation_in_progress);
+  MAP_ERR_TO_COND(WSAEINTR,                  interrupted);
+  MAP_ERR_TO_COND(WSAEINVAL,                 invalid_argument);
+  MAP_ERR_TO_COND(WSAEISCONN,                already_connected);
+  MAP_ERR_TO_COND(WSAEMFILE,                 too_many_files_open);
+  MAP_ERR_TO_COND(WSAEMSGSIZE,               message_size);
+  MAP_ERR_TO_COND(WSAENAMETOOLONG,           filename_too_long);
+  MAP_ERR_TO_COND(WSAENETDOWN,               network_down);
+  MAP_ERR_TO_COND(WSAENETRESET,              network_reset);
+  MAP_ERR_TO_COND(WSAENETUNREACH,            network_unreachable);
+  MAP_ERR_TO_COND(WSAENOBUFS,                no_buffer_space);
+  MAP_ERR_TO_COND(WSAENOPROTOOPT,            no_protocol_option);
+  MAP_ERR_TO_COND(WSAENOTCONN,               not_connected);
+  MAP_ERR_TO_COND(WSAENOTSOCK,               not_a_socket);
+  MAP_ERR_TO_COND(WSAEOPNOTSUPP,             operation_not_supported);
+  MAP_ERR_TO_COND(WSAEPROTONOSUPPORT,        protocol_not_supported);
+  MAP_ERR_TO_COND(WSAEPROTOTYPE,             wrong_protocol_type);
+  MAP_ERR_TO_COND(WSAETIMEDOUT,              timed_out);
+  MAP_ERR_TO_COND(WSAEWOULDBLOCK,            operation_would_block);
+  default: return error_condition(ev, system_category());
+  }
+}
diff --git a/lib/System/system_error.cpp b/lib/System/system_error.cpp
new file mode 100644 (file)
index 0000000..e7de852
--- /dev/null
@@ -0,0 +1,121 @@
+//===---------------------- system_error.cpp ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This was lifted from libc++ and modified for C++03.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/system_error.h"
+#include "llvm/System/Errno.h"
+#include <string>
+#include <cstring>
+
+namespace llvm {
+
+// class error_category
+
+error_category::error_category() {
+}
+
+error_category::~error_category() {
+}
+
+error_condition
+error_category::default_error_condition(int ev) const {
+  return error_condition(ev, *this);
+}
+
+bool
+error_category::equivalent(int code, const error_condition& condition) const {
+  return default_error_condition(code) == condition;
+}
+
+bool
+error_category::equivalent(const error_code& code, int condition) const {
+  return *this == code.category() && code.value() == condition;
+}
+
+std::string
+_do_message::message(int ev) const {
+  return std::string(sys::StrError(ev));
+}
+
+class _generic_error_category : public _do_message {
+public:
+  virtual const char* name() const;
+  virtual std::string message(int ev) const;
+};
+
+const char*
+_generic_error_category::name() const {
+  return "generic";
+}
+
+std::string
+_generic_error_category::message(int ev) const {
+#ifdef ELAST
+  if (ev > ELAST)
+    return std::string("unspecified generic_category error");
+#endif  // ELAST
+  return _do_message::message(ev);
+}
+
+const error_category&
+generic_category() {
+  static _generic_error_category s;
+  return s;
+}
+
+class _system_error_category : public _do_message {
+public:
+  virtual const char* name() const;
+  virtual std::string message(int ev) const;
+  virtual error_condition default_error_condition(int ev) const;
+};
+
+const char*
+_system_error_category::name() const {
+  return "system";
+}
+
+// std::string _system_error_category::message(int ev) const {
+// Is in Platform/system_error.inc
+
+// error_condition _system_error_category::default_error_condition(int ev) const
+// Is in Platform/system_error.inc
+
+const error_category&
+system_category() {
+  static _system_error_category s;
+  return s;
+}
+
+// error_condition
+
+std::string
+error_condition::message() const {
+  return _cat_->message(_val_);
+}
+
+// error_code
+
+std::string
+error_code::message() const {
+  return _cat_->message(_val_);
+}
+
+} // end namespace llvm
+
+// Include the truly platform-specific parts of this class.
+#if defined(LLVM_ON_UNIX)
+#include "Unix/system_error.inc"
+#endif
+#if defined(LLVM_ON_WIN32)
+#include "Win32/system_error.inc"
+#endif
index 32e481c..fc6fa9b 100644 (file)
@@ -1,6 +1,5 @@
 add_executable(KillTheDoctor
   KillTheDoctor.cpp
-  system_error.cpp
   )
 
 target_link_libraries(KillTheDoctor LLVMSupport LLVMSystem)
index c0bf437..28b1c0a 100644 (file)
@@ -42,7 +42,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/type_traits.h"
 #include "llvm/System/Signals.h"
-#include "system_error.h"
+#include "llvm/System/system_error.h"
 #include <algorithm>
 #include <cerrno>
 #include <cstdlib>
diff --git a/utils/KillTheDoctor/system_error.cpp b/utils/KillTheDoctor/system_error.cpp
deleted file mode 100644 (file)
index 0e78fb3..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-//===---------------------- system_error.cpp ------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This was lifted from libc++ and modified for C++03.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "system_error.h"
-#include <string>
-#include <cstring>
-
-namespace llvm {
-
-// class error_category
-
-error_category::error_category() {
-}
-
-error_category::~error_category() {
-}
-
-error_condition
-error_category::default_error_condition(int ev) const {
-  return error_condition(ev, *this);
-}
-
-bool
-error_category::equivalent(int code, const error_condition& condition) const {
-  return default_error_condition(code) == condition;
-}
-
-bool
-error_category::equivalent(const error_code& code, int condition) const {
-  return *this == code.category() && code.value() == condition;
-}
-
-std::string
-_do_message::message(int ev) const {
-  return std::string(std::strerror(ev));
-}
-
-class _generic_error_category : public _do_message {
-public:
-  virtual const char* name() const;
-  virtual std::string message(int ev) const;
-};
-
-const char*
-_generic_error_category::name() const {
-  return "generic";
-}
-
-std::string
-_generic_error_category::message(int ev) const {
-#ifdef ELAST
-  if (ev > ELAST)
-    return std::string("unspecified generic_category error");
-#endif  // ELAST
-  return _do_message::message(ev);
-}
-
-const error_category&
-generic_category() {
-  static _generic_error_category s;
-  return s;
-}
-
-class _system_error_category : public _do_message {
-public:
-  virtual const char* name() const;
-  virtual std::string message(int ev) const;
-  virtual error_condition default_error_condition(int ev) const;
-};
-
-const char*
-_system_error_category::name() const {
-  return "system";
-}
-
-// std::string _system_error_category::message(int ev) const {
-// Is in Platform/system_error.inc
-
-// error_condition _system_error_category::default_error_condition(int ev) const
-// Is in Platform/system_error.inc
-
-const error_category&
-system_category() {
-  static _system_error_category s;
-  return s;
-}
-
-// error_condition
-
-std::string
-error_condition::message() const {
-  return _cat_->message(_val_);
-}
-
-// error_code
-
-std::string
-error_code::message() const {
-  return _cat_->message(_val_);
-}
-
-// system_error
-
-std::string
-system_error::_init(const error_code& ec, std::string what_arg) {
-  if (ec)
-  {
-    if (!what_arg.empty())
-      what_arg += ": ";
-    what_arg += ec.message();
-  }
-  return what_arg;
-}
-
-system_error::system_error(error_code ec, const std::string& what_arg)
-  : runtime_error(_init(ec, what_arg)), _ec_(ec) {
-}
-
-system_error::system_error(error_code ec, const char* what_arg)
-  : runtime_error(_init(ec, what_arg)), _ec_(ec) {
-}
-
-system_error::system_error(error_code ec)
-  : runtime_error(_init(ec, "")), _ec_(ec) {
-}
-
-system_error::system_error(int ev, const error_category& ecat,
-                           const std::string& what_arg)
-  : runtime_error(_init(error_code(ev, ecat), what_arg))
-  , _ec_(error_code(ev, ecat)) {
-}
-
-system_error::system_error(int ev, const error_category& ecat,
-                           const char* what_arg)
-  : runtime_error(_init(error_code(ev, ecat), what_arg))
-  , _ec_(error_code(ev, ecat)) {
-}
-
-system_error::system_error(int ev, const error_category& ecat)
-  : runtime_error(_init(error_code(ev, ecat), "")), _ec_(error_code(ev, ecat)) {
-}
-
-system_error::~system_error() throw() {
-}
-
-void
-_throw_system_error(int ev, const char* what_arg) {
-  throw system_error(error_code(ev, system_category()), what_arg);
-}
-
-} // end namespace llvm
-
-#ifdef LLVM_ON_WIN32
-#include <Windows.h>
-#include <WinError.h>
-
-namespace llvm {
-
-std::string
-_system_error_category::message(int ev) const {
-  LPVOID lpMsgBuf = 0;
-  DWORD retval = ::FormatMessageA(
-    FORMAT_MESSAGE_ALLOCATE_BUFFER |
-    FORMAT_MESSAGE_FROM_SYSTEM |
-    FORMAT_MESSAGE_IGNORE_INSERTS,
-    NULL,
-    ev,
-    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-    (LPSTR) &lpMsgBuf,
-    0,
-    NULL);
-  if (retval == 0) {
-    ::LocalFree(lpMsgBuf);
-    return std::string("Unknown error");
-  }
-
-  std::string str( static_cast<LPCSTR>(lpMsgBuf) );
-  ::LocalFree(lpMsgBuf);
-
-  while (str.size()
-     && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r'))
-    str.erase( str.size()-1 );
-  if (str.size() && str[str.size()-1] == '.')
-    str.erase( str.size()-1 );
-  return str;
-}
-
-error_condition
-_system_error_category::default_error_condition(int ev) const {
-  switch (ev)
-  {
-  case 0: return make_error_condition(errc::success);
-  // Windows system -> posix_errno decode table  ---------------------------//
-  // see WinError.h comments for descriptions of errors
-  case ERROR_ACCESS_DENIED: return make_error_condition(errc::permission_denied);
-  case ERROR_ALREADY_EXISTS: return make_error_condition(errc::file_exists);
-  case ERROR_BAD_UNIT: return make_error_condition(errc::no_such_device);
-  case ERROR_BUFFER_OVERFLOW: return make_error_condition(errc::filename_too_long);
-  case ERROR_BUSY: return make_error_condition(errc::device_or_resource_busy);
-  case ERROR_BUSY_DRIVE: return make_error_condition(errc::device_or_resource_busy);
-  case ERROR_CANNOT_MAKE: return make_error_condition(errc::permission_denied);
-  case ERROR_CANTOPEN: return make_error_condition(errc::io_error);
-  case ERROR_CANTREAD: return make_error_condition(errc::io_error);
-  case ERROR_CANTWRITE: return make_error_condition(errc::io_error);
-  case ERROR_CURRENT_DIRECTORY: return make_error_condition(errc::permission_denied);
-  case ERROR_DEV_NOT_EXIST: return make_error_condition(errc::no_such_device);
-  case ERROR_DEVICE_IN_USE: return make_error_condition(errc::device_or_resource_busy);
-  case ERROR_DIR_NOT_EMPTY: return make_error_condition(errc::directory_not_empty);
-  case ERROR_DIRECTORY: return make_error_condition(errc::invalid_argument);
-  case ERROR_DISK_FULL: return make_error_condition(errc::no_space_on_device);
-  case ERROR_FILE_EXISTS: return make_error_condition(errc::file_exists);
-  case ERROR_FILE_NOT_FOUND: return make_error_condition(errc::no_such_file_or_directory);
-  case ERROR_HANDLE_DISK_FULL: return make_error_condition(errc::no_space_on_device);
-  case ERROR_INVALID_ACCESS: return make_error_condition(errc::permission_denied);
-  case ERROR_INVALID_DRIVE: return make_error_condition(errc::no_such_device);
-  case ERROR_INVALID_FUNCTION: return make_error_condition(errc::function_not_supported);
-  case ERROR_INVALID_HANDLE: return make_error_condition(errc::invalid_argument);
-  case ERROR_INVALID_NAME: return make_error_condition(errc::invalid_argument);
-  case ERROR_LOCK_VIOLATION: return make_error_condition(errc::no_lock_available);
-  case ERROR_LOCKED: return make_error_condition(errc::no_lock_available);
-  case ERROR_NEGATIVE_SEEK: return make_error_condition(errc::invalid_argument);
-  case ERROR_NOACCESS: return make_error_condition(errc::permission_denied);
-  case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition(errc::not_enough_memory);
-  case ERROR_NOT_READY: return make_error_condition(errc::resource_unavailable_try_again);
-  case ERROR_NOT_SAME_DEVICE: return make_error_condition(errc::cross_device_link);
-  case ERROR_OPEN_FAILED: return make_error_condition(errc::io_error);
-  case ERROR_OPEN_FILES: return make_error_condition(errc::device_or_resource_busy);
-  case ERROR_OPERATION_ABORTED: return make_error_condition(errc::operation_canceled);
-  case ERROR_OUTOFMEMORY: return make_error_condition(errc::not_enough_memory);
-  case ERROR_PATH_NOT_FOUND: return make_error_condition(errc::no_such_file_or_directory);
-  case ERROR_READ_FAULT: return make_error_condition(errc::io_error);
-  case ERROR_RETRY: return make_error_condition(errc::resource_unavailable_try_again);
-  case ERROR_SEEK: return make_error_condition(errc::io_error);
-  case ERROR_SHARING_VIOLATION: return make_error_condition(errc::permission_denied);
-  case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition(errc::too_many_files_open);
-  case ERROR_WRITE_FAULT: return make_error_condition(errc::io_error);
-  case ERROR_WRITE_PROTECT: return make_error_condition(errc::permission_denied);
-  case ERROR_SEM_TIMEOUT: return make_error_condition(errc::timed_out);
-  case WSAEACCES: return make_error_condition(errc::permission_denied);
-  case WSAEADDRINUSE: return make_error_condition(errc::address_in_use);
-  case WSAEADDRNOTAVAIL: return make_error_condition(errc::address_not_available);
-  case WSAEAFNOSUPPORT: return make_error_condition(errc::address_family_not_supported);
-  case WSAEALREADY: return make_error_condition(errc::connection_already_in_progress);
-  case WSAEBADF: return make_error_condition(errc::bad_file_descriptor);
-  case WSAECONNABORTED: return make_error_condition(errc::connection_aborted);
-  case WSAECONNREFUSED: return make_error_condition(errc::connection_refused);
-  case WSAECONNRESET: return make_error_condition(errc::connection_reset);
-  case WSAEDESTADDRREQ: return make_error_condition(errc::destination_address_required);
-  case WSAEFAULT: return make_error_condition(errc::bad_address);
-  case WSAEHOSTUNREACH: return make_error_condition(errc::host_unreachable);
-  case WSAEINPROGRESS: return make_error_condition(errc::operation_in_progress);
-  case WSAEINTR: return make_error_condition(errc::interrupted);
-  case WSAEINVAL: return make_error_condition(errc::invalid_argument);
-  case WSAEISCONN: return make_error_condition(errc::already_connected);
-  case WSAEMFILE: return make_error_condition(errc::too_many_files_open);
-  case WSAEMSGSIZE: return make_error_condition(errc::message_size);
-  case WSAENAMETOOLONG: return make_error_condition(errc::filename_too_long);
-  case WSAENETDOWN: return make_error_condition(errc::network_down);
-  case WSAENETRESET: return make_error_condition(errc::network_reset);
-  case WSAENETUNREACH: return make_error_condition(errc::network_unreachable);
-  case WSAENOBUFS: return make_error_condition(errc::no_buffer_space);
-  case WSAENOPROTOOPT: return make_error_condition(errc::no_protocol_option);
-  case WSAENOTCONN: return make_error_condition(errc::not_connected);
-  case WSAENOTSOCK: return make_error_condition(errc::not_a_socket);
-  case WSAEOPNOTSUPP: return make_error_condition(errc::operation_not_supported);
-  case WSAEPROTONOSUPPORT: return make_error_condition(errc::protocol_not_supported);
-  case WSAEPROTOTYPE: return make_error_condition(errc::wrong_protocol_type);
-  case WSAETIMEDOUT: return make_error_condition(errc::timed_out);
-  case WSAEWOULDBLOCK: return make_error_condition(errc::operation_would_block);
-  default: return error_condition(ev, system_category());
-  }
-}
-
-} // end namespace llvm
-
-#endif // LLVM_ON_WIN32