aboutsummaryrefslogtreecommitdiff
path: root/libsupport/include/CoreLib/Error/ErrorHandling.h
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-01 02:12:34 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-01 02:12:34 +0800
commit02b615c8704aeda9a94cf5457c9c78de847c911a (patch)
tree3257dd23e643ae732cb0abf14d62ab70b64893be /libsupport/include/CoreLib/Error/ErrorHandling.h
parent2850abdb23a2ba4fde6268ea4191f4d062b9a01f (diff)
downloadrcc-project-master.tar.gz
rcc-project-master.tar.xz
Move support code into CoreLibHEADmaster
Diffstat (limited to 'libsupport/include/CoreLib/Error/ErrorHandling.h')
-rw-r--r--libsupport/include/CoreLib/Error/ErrorHandling.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/libsupport/include/CoreLib/Error/ErrorHandling.h b/libsupport/include/CoreLib/Error/ErrorHandling.h
new file mode 100644
index 0000000..5ab5a9e
--- /dev/null
+++ b/libsupport/include/CoreLib/Error/ErrorHandling.h
@@ -0,0 +1,217 @@
+/*
+ RCC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option) any
+ later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ RCC-Project; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>.
+ */
+
+//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an API used to indicate fatal error conditions. Non-fatal
+// errors (most of them) should be handled through LLVMContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_SUPPORT_ERRORHANDLING_H
+#define RCC_SUPPORT_ERRORHANDLING_H
+
+#include "CoreLib/Compiler/Compiler.h"
+
+namespace rcc
+{
+class StringRef;
+class Twine;
+
+/// An error handler callback.
+using fatal_error_handler_t = void (*) (void *user_data, const char *reason,
+ bool gen_crash_diag);
+
+/// install_fatal_error_handler - Installs a new error handler to be used
+/// whenever a serious (non-recoverable) error is encountered by LLVM.
+///
+/// If no error handler is installed the default is to print the error message
+/// to stderr, and call exit(1). If an error handler is installed then it is
+/// the handler's responsibility to log the message, it will no longer be
+/// printed to stderr. If the error handler returns, then exit(1) will be
+/// called.
+///
+/// It is dangerous to naively use an error handler which throws an exception.
+/// Even though some applications desire to gracefully recover from arbitrary
+/// faults, blindly throwing exceptions through unfamiliar code isn't a way to
+/// achieve this.
+///
+/// \param user_data - An argument which will be passed to the install error
+/// handler.
+RCC_ABI void
+install_fatal_error_handler (fatal_error_handler_t handler,
+ void *user_data = nullptr);
+
+/// Restores default error handling behaviour.
+RCC_ABI void
+remove_fatal_error_handler ();
+
+/// ScopedFatalErrorHandler - This is a simple helper class which just
+/// calls install_fatal_error_handler in its constructor and
+/// remove_fatal_error_handler in its destructor.
+struct ScopedFatalErrorHandler
+{
+ explicit ScopedFatalErrorHandler (fatal_error_handler_t handler,
+ void *user_data = nullptr)
+ {
+ install_fatal_error_handler (handler, user_data);
+ }
+
+ ~ScopedFatalErrorHandler ()
+ {
+ remove_fatal_error_handler ();
+ }
+};
+
+/// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
+/// instead.
+[[noreturn]] RCC_ABI void
+report_fatal_error (const char *reason, bool gen_crash_diag = true);
+[[noreturn]] RCC_ABI void
+report_fatal_error (StringRef reason, bool gen_crash_diag = true);
+[[noreturn]] RCC_ABI void
+report_fatal_error (const Twine &reason, bool gen_crash_diag = true);
+
+/// Report a fatal error that likely indicates a bug in LLVM. It serves a
+/// similar purpose as an assertion, but is always enabled, regardless of the
+/// value of NDEBUG.
+///
+/// This will call installed error handlers (or print the message by default)
+/// and then abort. This will produce a crash trace and *will* ask users to
+/// report an LLVM bug.
+[[noreturn]] RCC_ABI void
+reportFatalInternalError (const char *reason);
+[[noreturn]] RCC_ABI void
+reportFatalInternalError (StringRef reason);
+[[noreturn]] RCC_ABI void
+reportFatalInternalError (const Twine &reason);
+
+/// Report a fatal error that does not indicate a bug in LLVM.
+///
+/// This can be used in contexts where a proper error reporting mechanism
+/// (such as Error/Expected or DiagnosticInfo) is currently not supported, and
+/// would be too involved to introduce at the moment.
+///
+/// Examples where this function should be used instead of
+/// reportFatalInternalError() include invalid inputs or options, but also
+/// environment error conditions outside LLVM's control. It should also be used
+/// for known unsupported/unimplemented functionality.
+///
+/// This will call installed error handlers (or print the message by default)
+/// and then exit with code 1. It will not produce a crash trace and will
+/// *not* ask users to report an LLVM bug.
+[[noreturn]] RCC_ABI void
+reportFatalUsageError (const char *reason);
+[[noreturn]] RCC_ABI void
+reportFatalUsageError (StringRef reason);
+[[noreturn]] RCC_ABI void
+reportFatalUsageError (const Twine &reason);
+
+/// Installs a new bad alloc error handler that should be used whenever a
+/// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM.
+///
+/// The user can install a bad alloc handler, in order to define the behavior
+/// in case of failing allocations, e.g. throwing an exception. Note that this
+/// handler must not trigger any additional allocations itself.
+///
+/// If no error handler is installed the default is to print the error message
+/// to stderr, and call exit(1). If an error handler is installed then it is
+/// the handler's responsibility to log the message, it will no longer be
+/// printed to stderr. If the error handler returns, then exit(1) will be
+/// called.
+///
+///
+/// \param user_data - An argument which will be passed to the installed error
+/// handler.
+RCC_ABI void
+install_bad_alloc_error_handler (fatal_error_handler_t handler,
+ void *user_data = nullptr);
+
+/// Restores default bad alloc error handling behavior.
+RCC_ABI void
+remove_bad_alloc_error_handler ();
+
+RCC_ABI void
+install_out_of_memory_new_handler ();
+
+/// Reports a bad alloc error, calling any user defined bad alloc
+/// error handler. In contrast to the generic 'report_fatal_error'
+/// functions, this function might not terminate, e.g. the user
+/// defined error handler throws an exception, but it won't return.
+///
+/// Note: When throwing an exception in the bad alloc handler, make sure that
+/// the following unwind succeeds, e.g. do not trigger additional allocations
+/// in the unwind chain.
+///
+/// If no error handler is installed (default), throws a bad_alloc exception
+/// if LLVM is compiled with exception support. Otherwise prints the error
+/// to standard error and calls abort().
+[[noreturn]] RCC_ABI void
+report_bad_alloc_error (const char *Reason, bool GenCrashDiag = true);
+
+/// This function calls abort(), and prints the optional message to stderr.
+/// Use the llvm_unreachable macro (that adds location info), instead of
+/// calling this function directly.
+[[noreturn]] RCC_ABI void
+rcc_unreachable_internal (const char *msg = nullptr, const char *file = nullptr,
+ unsigned line = 0);
+} // namespace rcc
+
+/// Marks that the current location is not supposed to be reachable.
+/// In !NDEBUG builds, prints the message and location info to stderr.
+/// In NDEBUG builds, if the platform does not support a builtin unreachable
+/// then we call an internal LLVM runtime function. Otherwise the behavior is
+/// controlled by the CMake flag
+/// -DLLVM_UNREACHABLE_OPTIMIZE
+/// * When "ON" (default) llvm_unreachable() becomes an optimizer hint
+/// that the current location is not supposed to be reachable: the hint
+/// turns such code path into undefined behavior. On compilers that don't
+/// support such hints, prints a reduced message instead and aborts the
+/// program.
+/// * When "OFF", a builtin_trap is emitted instead of an
+// optimizer hint or printing a reduced message.
+///
+/// Use this instead of assert(0). It conveys intent more clearly, suppresses
+/// diagnostics for unreachable code paths, and allows compilers to omit
+/// unnecessary code.
+#ifndef NDEBUG
+#define rcc_unreachable(msg) \
+ ::rcc::rcc_unreachable_internal (msg, __FILE__, __LINE__)
+#elif !defined(RCC_BUILTIN_UNREACHABLE)
+#define rcc_unreachable(msg) ::rcc::rcc_unreachable_internal ()
+#elif RCC_UNREACHABLE_OPTIMIZE
+#define rcc_unreachable(msg) RCC_BUILTIN_UNREACHABLE
+#else
+#define rcc_unreachable(msg) \
+ do \
+ { \
+ RCC_BUILTIN_TRAP; \
+ RCC_BUILTIN_UNREACHABLE; \
+ } while (false)
+#endif
+
+#endif