aboutsummaryrefslogtreecommitdiff
path: root/rcc/include
diff options
context:
space:
mode:
Diffstat (limited to 'rcc/include')
-rw-r--r--rcc/include/rcc/ADT/STLFunctionalExtras.h112
-rw-r--r--rcc/include/rcc/Config/config.h.cmake291
-rw-r--r--rcc/include/rcc/Config/rcc-config.h.cmake158
-rw-r--r--rcc/include/rcc/DataTypes.h105
-rw-r--r--rcc/include/rcc/Support/Compiler.h853
-rw-r--r--rcc/include/rcc/Support/Errno.h64
-rw-r--r--rcc/include/rcc/Support/ErrorOr.h378
-rw-r--r--rcc/include/rcc/Support/MathExtras.h1050
8 files changed, 3011 insertions, 0 deletions
diff --git a/rcc/include/rcc/ADT/STLFunctionalExtras.h b/rcc/include/rcc/ADT/STLFunctionalExtras.h
new file mode 100644
index 0000000..71a5b85
--- /dev/null
+++ b/rcc/include/rcc/ADT/STLFunctionalExtras.h
@@ -0,0 +1,112 @@
+/*
+ R *CC-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/ADT/STLFunctionalExtras.h - Extras for <functional> -*- 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 contains some extension to <functional>.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_ADT_STLFUNCTIONALEXTRAS_H
+#define RCC_ADT_STLFUNCTIONALEXTRAS_H
+
+#include "rcc/Support/Compiler.h"
+
+#include <cstddef
+#include <cstdint>
+#include <type_traits>
+#include <utility>
+
+namespace rcc
+{
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+/// An efficient, type-erasing, non-owning reference to a callable. This is
+/// intended for use as the type of a function parameter that is not used
+/// after the function in question returns.
+///
+/// This class does not own the callable, so it is not in general safe to store
+/// a function_ref.
+template <typename Fn> class function_ref;
+
+template <typename Ret, typename... Params>
+class RCC_GSL_POINTER function_ref<Ret (Params...)>
+{
+ Ret (*callback) (intptr_t callable, Params... params) = nullptr;
+ intptr_t callable = 0;
+
+ template <typename Callable>
+ static Ret
+ callback_fn (intptr_t callable, Params... params)
+ {
+ return (*reinterpret_cast<Callable *> (callable)) (
+ std::forward<Params> (params)...);
+ }
+
+public:
+ function_ref () = default;
+ function_ref (std::nullptr_t)
+ {
+ }
+
+ template <typename Callable>
+ function_ref (
+ Callable &&callable RCC_LIFETIME_BOUND,
+ // This is not the copy-constructor.
+ std::enable_if_t<!std::is_same<std::remove_cvref_t<Callable>,
+ function_ref>::value> * = nullptr,
+ // Functor must be callable and return a suitable type.
+ std::enable_if_t<std::is_void<Ret>::value ||
+ std::is_convertible<decltype (std::declval<Callable> () (
+ std::declval<Params> ()...)),
+ Ret>::value> * = nullptr)
+ : callback (callback_fn<std::remove_reference_t<Callable>>),
+ callable (reinterpret_cast<intptr_t> (&callable))
+ {
+ }
+
+ Ret
+ operator() (Params... params) const
+ {
+ return callback (callable, std::forward<Params> (params)...);
+ }
+
+ explicit
+ operator bool () const
+ {
+ return callback;
+ }
+};
+
+} // end namespace rcc
+
+#endif // RCC_ADT_STLFUNCTIONALEXTRAS_H
diff --git a/rcc/include/rcc/Config/config.h.cmake b/rcc/include/rcc/Config/config.h.cmake
new file mode 100644
index 0000000..32761c1
--- /dev/null
+++ b/rcc/include/rcc/Config/config.h.cmake
@@ -0,0 +1,291 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+// Include this header only under the rcc source tree.
+// This is a private header.
+
+/* Exported configuration */
+#include "rcc/Config/rcc-config.h"
+
+/* Bug report URL. */
+#define BUG_REPORT_URL "${BUG_REPORT_URL}"
+
+/* Define to 1 to enable backtraces, and to 0 otherwise. */
+#cmakedefine01 ENABLE_BACKTRACES
+
+/* Define to 1 to enable crash overrides, and to 0 otherwise. */
+#cmakedefine01 ENABLE_CRASH_OVERRIDES
+
+/* Define to 1 to enable crash memory dumps, and to 0 otherwise. */
+#cmakedefine01 RCC_ENABLE_CRASH_DUMPS
+
+/* Define to 1 to prefer forward slashes on Windows, and to 0 prefer
+ backslashes. */
+#cmakedefine01 RCC_WINDOWS_PREFER_FORWARD_SLASH
+
+/* Define to 1 if you have the `backtrace' function. */
+#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE}
+
+#define BACKTRACE_HEADER <${BACKTRACE_HEADER}>
+
+/* can use __crashreporter_info__ */
+#cmakedefine01 HAVE_CRASHREPORTER_INFO
+
+/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
+ don't. */
+#cmakedefine01 HAVE_DECL_ARC4RANDOM
+
+/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
+ don't. */
+#cmakedefine01 HAVE_DECL_STRERROR_S
+
+/* Define if dlopen() is available on this platform. */
+#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
+
+/* Define to 1 if we can register EH frames on this platform. */
+#cmakedefine HAVE_REGISTER_FRAME ${HAVE_REGISTER_FRAME}
+
+/* Define to 1 if we can deregister EH frames on this platform. */
+#cmakedefine HAVE_DEREGISTER_FRAME ${HAVE_DEREGISTER_FRAME}
+
+/* Define if __unw_add_dynamic_fde() is available on this platform. */
+#cmakedefine HAVE_UNW_ADD_DYNAMIC_FDE ${HAVE_UNW_ADD_DYNAMIC_FDE}
+
+/* Define if libffi is available on this platform. */
+#cmakedefine HAVE_FFI_CALL ${HAVE_FFI_CALL}
+
+/* Define to 1 if you have the <ffi/ffi.h> header file. */
+#cmakedefine HAVE_FFI_FFI_H ${HAVE_FFI_FFI_H}
+
+/* Define to 1 if you have the <ffi.h> header file. */
+#cmakedefine HAVE_FFI_H ${HAVE_FFI_H}
+
+/* Define to 1 if you have the `futimens' function. */
+#cmakedefine HAVE_FUTIMENS ${HAVE_FUTIMENS}
+
+/* Define to 1 if you have the `futimes' function. */
+#cmakedefine HAVE_FUTIMES ${HAVE_FUTIMES}
+
+/* Define to 1 if you have the `getpagesize' function. */
+#cmakedefine HAVE_GETPAGESIZE ${HAVE_GETPAGESIZE}
+
+/* Define to 1 if you have the `getrusage' function. */
+#cmakedefine HAVE_GETRUSAGE ${HAVE_GETRUSAGE}
+
+/* Define to 1 if you have the `isatty' function. */
+#cmakedefine HAVE_ISATTY 1
+
+/* Define to 1 if you have the `edit' library (-ledit). */
+#cmakedefine HAVE_LIBEDIT ${HAVE_LIBEDIT}
+
+/* Define to 1 if you have the `pfm' library (-lpfm). */
+#cmakedefine HAVE_LIBPFM ${HAVE_LIBPFM}
+
+/* Define to 1 if the `perf_branch_entry' struct has field cycles. */
+#cmakedefine LIBPFM_HAS_FIELD_CYCLES ${LIBPFM_HAS_FIELD_CYCLES}
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+#cmakedefine HAVE_LIBPSAPI ${HAVE_LIBPSAPI}
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#cmakedefine HAVE_LIBPTHREAD ${HAVE_LIBPTHREAD}
+
+/* Define to 1 if you have the `pthread_getname_np' function. */
+#cmakedefine HAVE_PTHREAD_GETNAME_NP ${HAVE_PTHREAD_GETNAME_NP}
+
+/* Define to 1 if you have the `pthread_setname_np' function. */
+#cmakedefine HAVE_PTHREAD_SETNAME_NP ${HAVE_PTHREAD_SETNAME_NP}
+
+/* Define to 1 if you have the `pthread_get_name_np' function. */
+#cmakedefine HAVE_PTHREAD_GET_NAME_NP ${HAVE_PTHREAD_GET_NAME_NP}
+
+/* Define to 1 if you have the `pthread_set_name_np' function. */
+#cmakedefine HAVE_PTHREAD_SET_NAME_NP ${HAVE_PTHREAD_SET_NAME_NP}
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+#cmakedefine HAVE_MACH_MACH_H ${HAVE_MACH_MACH_H}
+
+/* Define to 1 if you have the `mallctl' function. */
+#cmakedefine HAVE_MALLCTL ${HAVE_MALLCTL}
+
+/* Define to 1 if you have the `mallinfo' function. */
+#cmakedefine HAVE_MALLINFO ${HAVE_MALLINFO}
+
+/* Define to 1 if you have the `mallinfo2' function. */
+#cmakedefine HAVE_MALLINFO2 ${HAVE_MALLINFO2}
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+#cmakedefine HAVE_MALLOC_MALLOC_H ${HAVE_MALLOC_MALLOC_H}
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+#cmakedefine HAVE_MALLOC_ZONE_STATISTICS ${HAVE_MALLOC_ZONE_STATISTICS}
+
+/* Define to 1 if you have the `posix_spawn' function. */
+#cmakedefine HAVE_POSIX_SPAWN ${HAVE_POSIX_SPAWN}
+
+/* Define to 1 if you have the `pread' function. */
+#cmakedefine HAVE_PREAD ${HAVE_PREAD}
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#cmakedefine HAVE_PTHREAD_H ${HAVE_PTHREAD_H}
+
+/* Have pthread_rwlock_init */
+#cmakedefine HAVE_PTHREAD_RWLOCK_INIT ${HAVE_PTHREAD_RWLOCK_INIT}
+
+/* Define to 1 if you have the `sbrk' function. */
+#cmakedefine HAVE_SBRK ${HAVE_SBRK}
+
+/* Define to 1 if you have the `setenv' function. */
+#cmakedefine HAVE_SETENV ${HAVE_SETENV}
+
+/* Define to 1 if you have the `sigaltstack' function. */
+#cmakedefine HAVE_SIGALTSTACK ${HAVE_SIGALTSTACK}
+
+/* Define to 1 if you have the `strerror_r' function. */
+#cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R}
+
+/* Define to 1 if you have the `sysconf' function. */
+#cmakedefine HAVE_SYSCONF ${HAVE_SYSCONF}
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#cmakedefine HAVE_SYS_MMAN_H ${HAVE_SYS_MMAN_H}
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H}
+
+/* Define to 1 if stat struct has st_mtimespec member .*/
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC}
+
+/* Define to 1 if stat struct has st_mtim member. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC}
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
+
+/* Have host's _alloca */
+#cmakedefine HAVE__ALLOCA ${HAVE__ALLOCA}
+
+/* Define to 1 if you have the `_chsize_s' function. */
+#cmakedefine HAVE__CHSIZE_S ${HAVE__CHSIZE_S}
+
+/* Define to 1 if you have the `_Unwind_Backtrace' function. */
+#cmakedefine HAVE__UNWIND_BACKTRACE ${HAVE__UNWIND_BACKTRACE}
+
+/* Have host's __alloca */
+#cmakedefine HAVE___ALLOCA ${HAVE___ALLOCA}
+
+/* Have host's __ashldi3 */
+#cmakedefine HAVE___ASHLDI3 ${HAVE___ASHLDI3}
+
+/* Have host's __ashrdi3 */
+#cmakedefine HAVE___ASHRDI3 ${HAVE___ASHRDI3}
+
+/* Have host's __chkstk */
+#cmakedefine HAVE___CHKSTK ${HAVE___CHKSTK}
+
+/* Have host's __chkstk_ms */
+#cmakedefine HAVE___CHKSTK_MS ${HAVE___CHKSTK_MS}
+
+/* Have host's __cmpdi2 */
+#cmakedefine HAVE___CMPDI2 ${HAVE___CMPDI2}
+
+/* Have host's __divdi3 */
+#cmakedefine HAVE___DIVDI3 ${HAVE___DIVDI3}
+
+/* Have host's __fixdfdi */
+#cmakedefine HAVE___FIXDFDI ${HAVE___FIXDFDI}
+
+/* Have host's __fixsfdi */
+#cmakedefine HAVE___FIXSFDI ${HAVE___FIXSFDI}
+
+/* Have host's __floatdidf */
+#cmakedefine HAVE___FLOATDIDF ${HAVE___FLOATDIDF}
+
+/* Have host's __lshrdi3 */
+#cmakedefine HAVE___LSHRDI3 ${HAVE___LSHRDI3}
+
+/* Have host's __main */
+#cmakedefine HAVE___MAIN ${HAVE___MAIN}
+
+/* Have host's __moddi3 */
+#cmakedefine HAVE___MODDI3 ${HAVE___MODDI3}
+
+/* Have host's __udivdi3 */
+#cmakedefine HAVE___UDIVDI3 ${HAVE___UDIVDI3}
+
+/* Have host's __umoddi3 */
+#cmakedefine HAVE___UMODDI3 ${HAVE___UMODDI3}
+
+/* Have host's ___chkstk */
+#cmakedefine HAVE____CHKSTK ${HAVE____CHKSTK}
+
+/* Have host's ___chkstk_ms */
+#cmakedefine HAVE____CHKSTK_MS ${HAVE____CHKSTK_MS}
+
+/* Define if ICU library is available */
+#cmakedefine01 HAVE_ICU
+
+/* Define if Windows vendored ICU is available */
+#cmakedefine01 HAVE_WINDOWS_ICU
+
+/* Define if iconv library is available */
+#cmakedefine01 HAVE_ICONV
+
+/* Linker version detected at compile time. */
+#cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}"
+
+/* Define if overriding target triple is enabled */
+#cmakedefine RCC_TARGET_TRIPLE_ENV "${RCC_TARGET_TRIPLE_ENV}"
+
+/* Whether tools show host and target info when invoked with --version */
+#cmakedefine01 RCC_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
+
+/* Whether tools show optional build config flags when invoked with --version */
+#cmakedefine01 RCC_VERSION_PRINTER_SHOW_BUILD_CONFIG
+
+/* Define if libxml2 is supported on this platform. */
+#cmakedefine RCC_ENABLE_LIBXML2 ${RCC_ENABLE_LIBXML2}
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#cmakedefine LTDL_SHLIB_EXT "${LTDL_SHLIB_EXT}"
+
+/* Define to the extension used for plugin libraries, say, ".so". */
+#cmakedefine RCC_PLUGIN_EXT "${RCC_PLUGIN_EXT}"
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}"
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}"
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}"
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}"
+
+/* Define to the vendor of this package. */
+#cmakedefine PACKAGE_VENDOR "${PACKAGE_VENDOR}"
+
+/* Define to a function implementing stricmp */
+#cmakedefine stricmp ${stricmp}
+
+/* Define to a function implementing strdup */
+#cmakedefine strdup ${strdup}
+
+/* Whether GlobalISel rule coverage is being collected */
+#cmakedefine01 RCC_GISEL_COV_ENABLED
+
+/* Define to the default GlobalISel coverage file prefix */
+#cmakedefine RCC_GISEL_COV_PREFIX "${RCC_GISEL_COV_PREFIX}"
+
+/* Whether Timers signpost passes in Xcode Instruments */
+#cmakedefine01 RCC_SUPPORT_XCODE_SIGNPOSTS
+
+#cmakedefine HAVE_PROC_PID_RUSAGE 1
+
+#cmakedefine HAVE_BUILTIN_THREAD_POINTER ${HAVE_BUILTIN_THREAD_POINTER}
+
+#cmakedefine HAVE_GETAUXVAL ${HAVE_GETAUXVAL}
+
+#endif
diff --git a/rcc/include/rcc/Config/rcc-config.h.cmake b/rcc/include/rcc/Config/rcc-config.h.cmake
new file mode 100644
index 0000000..9c0ba18
--- /dev/null
+++ b/rcc/include/rcc/Config/rcc-config.h.cmake
@@ -0,0 +1,158 @@
+/*===------- rcc/Config/rcc-config.h - RCC configuration -------*- 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 enumerates variables from the RCC configuration so that they
+ can be in exported headers and won't override package specific directives.
+ This is a C header that can be included in the RCC C headers. */
+
+#ifndef RCC_CONFIG_H
+#define RCC_CONFIG_H
+
+/* Define if RCC_ENABLE_DUMP is enabled */
+#cmakedefine RCC_ENABLE_DUMP
+
+/* Target triple RCC will generate code for by default */
+/* Doesn't use `cmakedefine` because it is allowed to be empty. */
+#define RCC_DEFAULT_TARGET_TRIPLE "${RCC_DEFAULT_TARGET_TRIPLE}"
+
+/* Define if threads enabled */
+#cmakedefine01 RCC_ENABLE_THREADS
+
+/* Has gcc/MSVC atomic intrinsics */
+#cmakedefine01 RCC_HAS_ATOMICS
+
+/* Host triple RCC will be executed on */
+#cmakedefine RCC_HOST_TRIPLE "${RCC_HOST_TRIPLE}"
+
+/* RCC architecture name for the native architecture, if available */
+#cmakedefine RCC_NATIVE_ARCH ${RCC_NATIVE_ARCH}
+
+/* RCC name for the native AsmParser init function, if available */
+#cmakedefine RCC_NATIVE_ASMPARSER RCCInitialize${RCC_NATIVE_ARCH}AsmParser
+
+/* RCC name for the native AsmPrinter init function, if available */
+#cmakedefine RCC_NATIVE_ASMPRINTER RCCInitialize${RCC_NATIVE_ARCH}AsmPrinter
+
+/* RCC name for the native Disassembler init function, if available */
+#cmakedefine RCC_NATIVE_DISASSEMBLER RCCInitialize${RCC_NATIVE_ARCH}Disassembler
+
+/* RCC name for the native Target init function, if available */
+#cmakedefine RCC_NATIVE_TARGET RCCInitialize${RCC_NATIVE_ARCH}Target
+
+/* RCC name for the native TargetInfo init function, if available */
+#cmakedefine RCC_NATIVE_TARGETINFO RCCInitialize${RCC_NATIVE_ARCH}TargetInfo
+
+/* RCC name for the native target MC init function, if available */
+#cmakedefine RCC_NATIVE_TARGETMC RCCInitialize${RCC_NATIVE_ARCH}TargetMC
+
+/* RCC name for the native target MCA init function, if available */
+#cmakedefine RCC_NATIVE_TARGETMCA RCCInitialize${RCC_NATIVE_ARCH}TargetMCA
+
+/* Define if this is Unixish platform */
+#cmakedefine RCC_ON_UNIX ${RCC_ON_UNIX}
+
+/* Define if we have the Intel JIT API runtime support library */
+#cmakedefine01 RCC_USE_INTEL_JITEVENTS
+
+/* Define if we have the oprofile JIT-support library */
+#cmakedefine01 RCC_USE_OPROFILE
+
+/* Define if we have the perf JIT-support library */
+#cmakedefine01 RCC_USE_PERF
+
+/* Major version of the RCC API */
+#define RCC_VERSION_MAJOR ${RCC_VERSION_MAJOR}
+
+/* Minor version of the RCC API */
+#define RCC_VERSION_MINOR ${RCC_VERSION_MINOR}
+
+/* Patch version of the RCC API */
+#define RCC_VERSION_PATCH ${RCC_VERSION_PATCH}
+
+/* RCC version string */
+#define RCC_VERSION_STRING "${PACKAGE_VERSION}"
+
+/* Whether RCC records statistics for use with GetStatistics(),
+ * PrintStatistics() or PrintStatisticsJSON()
+ */
+#cmakedefine01 RCC_FORCE_ENABLE_STATS
+
+/* Define if we have z3 and want to build it */
+#cmakedefine RCC_WITH_Z3 ${RCC_WITH_Z3}
+
+/* Define if we have curl and want to use it */
+#cmakedefine RCC_ENABLE_CURL ${RCC_ENABLE_CURL}
+
+/* Define if we have cpp-httplib and want to use it */
+#cmakedefine RCC_ENABLE_HTTPLIB ${RCC_ENABLE_HTTPLIB}
+
+/* Define if zlib compression is available */
+#cmakedefine01 RCC_ENABLE_ZLIB
+
+/* Define if zstd compression is available */
+#cmakedefine01 RCC_ENABLE_ZSTD
+
+/* Define if xz (lzma) decompression is available */
+#cmakedefine01 RCC_ENABLE_LZMA
+
+/* Define if RCC is using tflite */
+#cmakedefine RCC_HAVE_TFLITE
+
+/* Define if we want to check profile consistency in lit tests */
+#cmakedefine RCC_ENABLE_PROFCHECK
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#cmakedefine HAVE_SYSEXITS_H ${HAVE_SYSEXITS_H}
+
+/* Define if building libRCC shared library */
+#cmakedefine RCC_BUILD_RCC_DYLIB
+
+/* Define if building RCC with BUILD_SHARED_LIBS */
+#cmakedefine RCC_BUILD_SHARED_LIBS
+
+/* Define if exporting RCC public interface for shared library */
+#cmakedefine RCC_ENABLE_RCC_EXPORT_ANNOTATIONS
+
+/* Define if exporting RCC-C public interface for shared library */
+#cmakedefine RCC_ENABLE_RCC_C_EXPORT_ANNOTATIONS
+
+/* Define if building RCC with RCC_FORCE_USE_OLD_TOOLCHAIN_LIBS */
+#cmakedefine RCC_FORCE_USE_OLD_TOOLCHAIN ${RCC_FORCE_USE_OLD_TOOLCHAIN}
+
+/* Define if rcc_unreachable should be optimized with undefined behavior
+ * in non assert builds */
+#cmakedefine01 RCC_UNREACHABLE_OPTIMIZE
+
+/* Define if building RCC with RCC_ENABLE_IO_SANDBOX */
+#cmakedefine01 RCC_ENABLE_IO_SANDBOX
+
+/* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */
+#cmakedefine01 RCC_ENABLE_DIA_SDK
+
+/* Define if plugins enabled */
+#cmakedefine RCC_ENABLE_PLUGINS
+
+/* Define if logf128 is available */
+#cmakedefine RCC_HAS_LOGF128
+
+/* Define if building RCC with RCC_ENABLE_TELEMETRY */
+#cmakedefine01 RCC_ENABLE_TELEMETRY
+
+/* Define to 1 to enable expensive checks for debug location coverage checking,
+ and to 0 otherwise. */
+#cmakedefine01 RCC_ENABLE_DEBUGLOC_TRACKING_COVERAGE
+
+/* Define to 1 to enable expensive tracking of the origin of debug location
+ coverage bugs, and to 0 otherwise. */
+#cmakedefine01 RCC_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+
+/* Define to 1 to enable RCC OnDisk Content Addressable Storage */
+#cmakedefine01 RCC_ENABLE_ONDISK_CAS
+
+#endif
diff --git a/rcc/include/rcc/DataTypes.h b/rcc/include/rcc/DataTypes.h
new file mode 100644
index 0000000..59e9b75
--- /dev/null
+++ b/rcc/include/rcc/DataTypes.h
@@ -0,0 +1,105 @@
+/*
+ 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, 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/>.
+*/
+
+// This implementation is based on include/llvm-c/DataTypes.h
+/*===-- include/llvm-c/DataTypes.h - Define fixed size types ------*- 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 contains definitions to figure out the size of _HOST_ data
+ types.*|
+ |* This file is important because different host OS's define different
+ macros,*|
+ |* which makes portability tough. This file exports the following *|
+ |* definitions: *|
+ |* *|
+ |* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system
+ types*|
+ |* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+ |* *|
+ |* No library is required when using these functions. *|
+ |* *|
+ |*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+#ifndef RCC_DATATYPES_H
+#define RCC_DATATYPES_H
+
+#include <inttypes.h>
+#include <stdint.h>
+
+#ifndef _MSC_VER
+
+#if !defined(UINT32_MAX)
+#error "The standard header <cstdint> is not C++11 compliant. Must #define "\
+ "__STDC_LIMIT_MACROS before #including llvm-c/DataTypes.h"
+#endif
+
+#if !defined(UINT32_C)
+#error "The standard header <cstdint> is not C++11 compliant. Must #define "\
+ "__STDC_CONSTANT_MACROS before #including llvm-c/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#include <sys/types.h>
+
+#ifdef _AIX
+// GCC is strict about defining large constants: they must have LL modifier.
+#undef INT64_MAX
+#undef INT64_MIN
+#endif
+
+#else /* _MSC_VER */
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdlib>
+#else
+#include <stddef.h>
+#include <stdlib.h>
+#endif
+#include <sys/types.h>
+
+#if defined(_WIN64)
+typedef signed __int64 ssize_t;
+#else
+typedef signed int ssize_t;
+#endif /* _WIN64 */
+
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+#define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+#define INT64_MIN ((-INT64_MAX) - 1)
+#endif
+#if !defined(UINT64_MAX)
+#define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#endif
diff --git a/rcc/include/rcc/Support/Compiler.h b/rcc/include/rcc/Support/Compiler.h
new file mode 100644
index 0000000..511c4cd
--- /dev/null
+++ b/rcc/include/rcc/Support/Compiler.h
@@ -0,0 +1,853 @@
+/*
+ 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/Compiler.h - Compiler abstraction support --*- 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 several macros, based on the current compiler. This allows
+// use of compiler-specific features in a way that remains portable. This header
+// can be included from either C or C++.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_SUPPORT_COMPILER_H
+#define RCC_SUPPORT_COMPILER_H
+
+#include "rcc/Config/rcc-config.h"
+
+#include <stddef.h>
+
+#if defined(_MSC_VER)
+#include <sal.h>
+#endif
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#ifndef __has_extension
+#define __has_extension(x) 0
+#endif
+
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#ifndef __has_warning
+#define __has_warning(x) 0
+#endif
+
+// Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in
+// C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid.
+#ifndef RCC_HAS_CPP_ATTRIBUTE
+#if defined(__cplusplus) && defined(__has_cpp_attribute)
+#define RCC_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute (x)
+#else
+#define RCC_HAS_CPP_ATTRIBUTE(x) 0
+#endif
+#endif
+
+/// \macro RCC_GNUC_PREREQ
+/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
+/// available.
+#ifndef RCC_GNUC_PREREQ
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+#define RCC_GNUC_PREREQ(maj, min, patch) \
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
+ ((maj) << 20) + ((min) << 10) + (patch))
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define RCC_GNUC_PREREQ(maj, min, patch) \
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
+#else
+#define RCC_GNUC_PREREQ(maj, min, patch) 0
+#endif
+#endif
+
+/// \macro RCC_MSC_PREREQ
+/// Is the compiler MSVC of at least the specified version?
+/// The common \param version values to check for are:
+/// * 1910: VS2017, version 15.1 & 15.2
+/// * 1911: VS2017, version 15.3 & 15.4
+/// * 1912: VS2017, version 15.5
+/// * 1913: VS2017, version 15.6
+/// * 1914: VS2017, version 15.7
+/// * 1915: VS2017, version 15.8
+/// * 1916: VS2017, version 15.9
+/// * 1920: VS2019, version 16.0
+/// * 1921: VS2019, version 16.1
+/// * 1922: VS2019, version 16.2
+/// * 1923: VS2019, version 16.3
+/// * 1924: VS2019, version 16.4
+/// * 1925: VS2019, version 16.5
+/// * 1926: VS2019, version 16.6
+/// * 1927: VS2019, version 16.7
+/// * 1928: VS2019, version 16.8 + 16.9
+/// * 1929: VS2019, version 16.10 + 16.11
+/// * 1930: VS2022, version 17.0
+#ifdef _MSC_VER
+#define RCC_MSC_PREREQ(version) (_MSC_VER >= (version))
+
+// We require at least VS 2019.
+#if !defined(RCC_FORCE_USE_OLD_TOOLCHAIN)
+#if !RCC_MSC_PREREQ(1920)
+#error RCC requires at least VS 2019.
+#endif
+#endif
+
+#else
+#define RCC_MSC_PREREQ(version) 0
+#endif
+
+/// RCC_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
+/// into a shared library, then the class should be private to the library and
+/// not accessible from outside it. Can also be used to mark variables and
+/// functions, making them private to any shared library they are linked into.
+/// On PE/COFF targets, library visibility is the default, so this isn't needed.
+///
+/// RCC_EXTERNAL_VISIBILITY - classes, functions, and variables marked with
+/// this attribute will be made public and visible outside of any shared library
+/// they are linked in to.
+
+#if RCC_HAS_CPP_ATTRIBUTE(gnu::visibility) && defined(__GNUC__) && \
+ !defined(__clang__)
+#define RCC_ATTRIBUTE_VISIBILITY_HIDDEN [[gnu::visibility ("hidden")]]
+#define RCC_ATTRIBUTE_VISIBILITY_DEFAULT [[gnu::visibility ("default")]]
+#elif __has_attribute(visibility)
+#define RCC_ATTRIBUTE_VISIBILITY_HIDDEN __attribute__ ((visibility ("hidden")))
+#define RCC_ATTRIBUTE_VISIBILITY_DEFAULT \
+ __attribute__ ((visibility ("default")))
+#else
+#define RCC_ATTRIBUTE_VISIBILITY_HIDDEN
+#define RCC_ATTRIBUTE_VISIBILITY_DEFAULT
+#endif
+
+#if defined(RCC_BUILD_RCC_DYLIB) || defined(RCC_BUILD_SHARED_LIBS)
+#define RCC_EXTERNAL_VISIBILITY RCC_ATTRIBUTE_VISIBILITY_DEFAULT
+#else
+#define RCC_EXTERNAL_VISIBILITY
+#endif
+
+#if (!(defined(_WIN32) || defined(__CYGWIN__)) || \
+ ((defined(__MINGW32__) || defined(__CYGWIN__)) && defined(__clang__)))
+#define RCC_LIBRARY_VISIBILITY RCC_ATTRIBUTE_VISIBILITY_HIDDEN
+// Clang compilers older then 15 do not support gnu style attributes on
+// namespaces.
+#if defined(__clang__) && __clang_major__ < 15
+#define RCC_LIBRARY_VISIBILITY_NAMESPACE [[gnu::visibility ("hidden")]]
+#else
+#define RCC_LIBRARY_VISIBILITY_NAMESPACE RCC_ATTRIBUTE_VISIBILITY_HIDDEN
+#endif
+#define RCC_ALWAYS_EXPORT RCC_ATTRIBUTE_VISIBILITY_DEFAULT
+#elif defined(_WIN32)
+#define RCC_ALWAYS_EXPORT __declspec (dllexport)
+#define RCC_LIBRARY_VISIBILITY
+#define RCC_LIBRARY_VISIBILITY_NAMESPACE
+#else
+#define RCC_LIBRARY_VISIBILITY
+#define RCC_ALWAYS_EXPORT
+#define RCC_LIBRARY_VISIBILITY_NAMESPACE
+#endif
+
+/// RCC_ABI is the main export/visibility macro to mark something as explicitly
+/// exported when rcc is built as a shared library with everything else that is
+/// unannotated will have internal visibility.
+///
+/// RCC_ABI_EXPORT is for the special case for things like plugin symbol
+/// declarations or definitions where we don't want the macro to be switching
+/// between dllexport and dllimport on windows based on what codebase is being
+/// built, it will only be dllexport. For non windows platforms this macro
+/// behaves the same as RCC_ABI.
+///
+/// RCC_EXPORT_TEMPLATE is used on explicit template instantiations in source
+/// files that were declared extern in a header. This macro is only set as a
+/// compiler export attribute on windows, on other platforms it does nothing.
+///
+/// RCC_TEMPLATE_ABI is for annotating extern template declarations in headers
+/// for both functions and classes. On windows its turned in to dllimport for
+/// library consumers, for other platforms its a default visibility attribute.
+///
+/// RCC_ABI_FOR_TEST is for annotating symbols that are exported from a
+/// library-internal header solely so that unit tests can link against them.
+/// Symbols in RCC's public headers are part of the RCC public interface and
+/// should use RCC_ABI. RCC_ABI_FOR_TEST is reserved for internal headers,
+/// whose symbols could be conditionally excluded when not building tests in the
+/// future.
+///
+#ifndef RCC_ABI_GENERATING_ANNOTATIONS
+// Marker to add to classes or functions in public headers that should not have
+// export macros added to them by the clang tool
+#define RCC_ABI_NOT_EXPORTED
+// TODO(https://github.com/rcc/rcc-project/issues/145406): eliminate need for
+// two preprocessor definitions to gate RCC_ABI macro definitions.
+#if defined(RCC_ENABLE_RCC_EXPORT_ANNOTATIONS) && !defined(RCC_BUILD_STATIC)
+#if defined(_WIN32) && !defined(__MINGW32__)
+#if defined(RCC_EXPORTS)
+#define RCC_ABI __declspec (dllexport)
+#define RCC_TEMPLATE_ABI
+#define RCC_EXPORT_TEMPLATE __declspec (dllexport)
+#else
+#define RCC_ABI __declspec (dllimport)
+#define RCC_TEMPLATE_ABI __declspec (dllimport)
+#define RCC_EXPORT_TEMPLATE
+#endif
+#define RCC_ABI_EXPORT __declspec (dllexport)
+#elif __has_attribute(visibility)
+#if defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \
+ defined(__MVS__) || defined(__CYGWIN__)
+#define RCC_ABI __attribute__ ((visibility ("default")))
+#define RCC_TEMPLATE_ABI RCC_ABI
+#define RCC_EXPORT_TEMPLATE
+#define RCC_ABI_EXPORT RCC_ABI
+#elif defined(__MACH__) || defined(__wasm__) || defined(__EMSCRIPTEN__)
+#define RCC_ABI __attribute__ ((visibility ("default")))
+#define RCC_TEMPLATE_ABI
+#define RCC_EXPORT_TEMPLATE
+#define RCC_ABI_EXPORT RCC_ABI
+#endif
+#endif
+#endif
+#if !defined(RCC_ABI)
+#define RCC_ABI
+#define RCC_TEMPLATE_ABI
+#define RCC_EXPORT_TEMPLATE
+#define RCC_ABI_EXPORT
+#endif
+#define RCC_ABI_FOR_TEST RCC_ABI
+#endif
+
+#if defined(__GNUC__)
+#define RCC_PREFETCH(addr, rw, locality) __builtin_prefetch (addr, rw, locality)
+#else
+#define RCC_PREFETCH(addr, rw, locality)
+#endif
+
+#if __has_attribute(uninitialized)
+#define RCC_ATTRIBUTE_UNINITIALIZED __attribute__ ((uninitialized))
+#else
+#define RCC_ATTRIBUTE_UNINITIALIZED
+#endif
+
+#if __has_attribute(used)
+#define RCC_ATTRIBUTE_USED __attribute__ ((__used__))
+#else
+#define RCC_ATTRIBUTE_USED
+#endif
+
+#if __has_attribute(warn_unused)
+#define RCC_ATTRIBUTE_WARN_UNUSED __attribute__ ((warn_unused))
+#else
+#define RCC_ATTRIBUTE_WARN_UNUSED
+#endif
+
+// Only enabled for clang:
+// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587
+// GCC may produce "warning: 'retain' attribute ignored" (despite
+// __has_attribute(retain) being 1).
+#if defined(__clang__) && __has_attribute(retain)
+#define RCC_ATTRIBUTE_RETAIN __attribute__ ((__retain__))
+#else
+#define RCC_ATTRIBUTE_RETAIN
+#endif
+
+// For deprecations that are not a simple rename, use [[deprecated(MSG)]]
+// instead.
+#if defined(__clang__)
+#define RCC_DEPRECATED_WITH_FIXIT(MSG, FIX) \
+ __attribute__ ((deprecated (MSG, FIX)))
+#else
+#define RCC_DEPRECATED_WITH_FIXIT(MSG, FIX) [[deprecated (MSG)]]
+#endif
+
+// clang-format off
+#if defined(__clang__) || defined(__GNUC__)
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_POP \
+ _Pragma("GCC diagnostic pop")
+#elif defined(_MSC_VER)
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH \
+ __pragma(warning(push)) \
+ __pragma(warning(disable : 4996))
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_POP \
+ __pragma(warning(pop))
+#else
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH
+#define RCC_SUPPRESS_DEPRECATED_DECLARATIONS_POP
+#endif
+// clang-format on
+
+// Indicate that a non-static, non-const C++ member function reinitializes
+// the entire object to a known state, independent of the previous state of
+// the object.
+//
+// The clang-tidy check bugprone-use-after-move recognizes this attribute as a
+// marker that a moved-from object has left the indeterminate state and can be
+// reused.
+#if RCC_HAS_CPP_ATTRIBUTE(clang::reinitializes)
+#define RCC_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
+#else
+#define RCC_ATTRIBUTE_REINITIALIZES
+#endif
+
+// Some compilers warn about unused functions. When a function is sometimes
+// used or not depending on build settings (e.g. a function only called from
+// within "assert"), this attribute can be used to suppress such warnings.
+//
+// However, it shouldn't be used for unused *variables*, as those have a much
+// more portable solution:
+// (void)unused_var_name;
+// Prefer cast-to-void wherever it is sufficient.
+#if __has_attribute(unused)
+#define RCC_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#else
+#define RCC_ATTRIBUTE_UNUSED
+#endif
+
+// FIXME: Provide this for PE/COFF targets.
+#if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) && \
+ !defined(_WIN32)
+#define RCC_HAS_ATTRIBUTE_WEAK 1
+#else
+#define RCC_HAS_ATTRIBUTE_WEAK 0
+#endif
+#if RCC_HAS_ATTRIBUTE_WEAK
+#define RCC_ATTRIBUTE_WEAK __attribute__ ((__weak__))
+#else
+#define RCC_ATTRIBUTE_WEAK
+#endif
+
+// Prior to clang 3.2, clang did not accept any spelling of
+// __has_attribute(const), so assume it is supported.
+#if defined(__clang__) || defined(__GNUC__)
+// aka 'CONST' but following RCC Conventions.
+#define RCC_READNONE __attribute__ ((__const__))
+#else
+#define RCC_READNONE
+#endif
+
+#if __has_attribute(pure) || defined(__GNUC__)
+// aka 'PURE' but following RCC Conventions.
+#define RCC_READONLY __attribute__ ((__pure__))
+#else
+#define RCC_READONLY
+#endif
+
+#if __has_attribute(minsize)
+#define RCC_ATTRIBUTE_MINSIZE __attribute__ ((minsize))
+#else
+#define RCC_ATTRIBUTE_MINSIZE
+#endif
+
+#if __has_builtin(__builtin_expect) || defined(__GNUC__)
+#define RCC_LIKELY(EXPR) __builtin_expect ((bool)(EXPR), true)
+#define RCC_UNLIKELY(EXPR) __builtin_expect ((bool)(EXPR), false)
+#else
+#define RCC_LIKELY(EXPR) (EXPR)
+#define RCC_UNLIKELY(EXPR) (EXPR)
+#endif
+
+/// RCC_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+/// mark a method "not for inlining".
+#if __has_attribute(noinline)
+#define RCC_ATTRIBUTE_NOINLINE __attribute__ ((noinline))
+#elif defined(_MSC_VER)
+#define RCC_ATTRIBUTE_NOINLINE __declspec (noinline)
+#else
+#define RCC_ATTRIBUTE_NOINLINE
+#endif
+
+/// RCC_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+/// so, mark a method "always inline" because it is performance sensitive.
+#if __has_attribute(always_inline)
+#define RCC_ATTRIBUTE_ALWAYS_INLINE inline __attribute__ ((always_inline))
+#elif defined(_MSC_VER)
+#define RCC_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define RCC_ATTRIBUTE_ALWAYS_INLINE inline
+#endif
+
+/// RCC_ATTRIBUTE_ALWAYS_INLINE_UNLESS_DEBUG - Like
+/// RCC_ATTRIBUTE_ALWAYS_INLINE but disabled in debug builds to avoid stack
+/// overflow with deep recursion.
+#if defined(NDEBUG)
+#define RCC_ATTRIBUTE_ALWAYS_INLINE_UNLESS_DEBUG RCC_ATTRIBUTE_ALWAYS_INLINE
+#else
+#define RCC_ATTRIBUTE_ALWAYS_INLINE_UNLESS_DEBUG inline
+#endif
+
+/// RCC_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do
+/// so, mark a method "no debug" because debug info makes the debugger
+/// experience worse.
+#if __has_attribute(nodebug)
+#define RCC_ATTRIBUTE_NODEBUG __attribute__ ((nodebug))
+#else
+#define RCC_ATTRIBUTE_NODEBUG
+#endif
+
+#if __has_attribute(returns_nonnull)
+#define RCC_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((returns_nonnull))
+#elif defined(_MSC_VER)
+#define RCC_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
+#else
+#define RCC_ATTRIBUTE_RETURNS_NONNULL
+#endif
+
+/// RCC_ATTRIBUTE_RESTRICT - Annotates a pointer to tell the compiler that
+/// it is not aliased in the current scope.
+#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+#define RCC_ATTRIBUTE_RESTRICT __restrict
+#else
+#define RCC_ATTRIBUTE_RESTRICT
+#endif
+
+/// \macro RCC_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
+/// pointer that does not alias any other valid pointer.
+#ifdef __GNUC__
+#define RCC_ATTRIBUTE_RETURNS_NOALIAS __attribute__ ((__malloc__))
+#elif defined(_MSC_VER)
+#define RCC_ATTRIBUTE_RETURNS_NOALIAS __declspec (restrict)
+#else
+#define RCC_ATTRIBUTE_RETURNS_NOALIAS
+#endif
+
+/// RCC_FALLTHROUGH - Mark fallthrough cases in switch statements.
+#if defined(__cplusplus) && __cplusplus > 201402L && \
+ RCC_HAS_CPP_ATTRIBUTE(fallthrough)
+#define RCC_FALLTHROUGH [[fallthrough]]
+#elif RCC_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
+#define RCC_FALLTHROUGH [[gnu::fallthrough]]
+#elif __has_attribute(fallthrough)
+#define RCC_FALLTHROUGH __attribute__ ((fallthrough))
+#elif RCC_HAS_CPP_ATTRIBUTE(clang::fallthrough)
+#define RCC_FALLTHROUGH [[clang::fallthrough]]
+#else
+#define RCC_FALLTHROUGH
+#endif
+
+/// RCC_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
+/// they are constant initialized.
+#if RCC_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization)
+#define RCC_REQUIRE_CONSTANT_INITIALIZATION \
+ [[clang::require_constant_initialization]]
+#else
+#define RCC_REQUIRE_CONSTANT_INITIALIZATION
+#endif
+
+/// RCC_GSL_OWNER - Apply this to owning classes like SmallVector to enable
+/// lifetime warnings.
+#if RCC_HAS_CPP_ATTRIBUTE(gsl::Owner)
+#define RCC_GSL_OWNER [[gsl::Owner]]
+#else
+#define RCC_GSL_OWNER
+#endif
+
+/// RCC_GSL_POINTER - Apply this to non-owning classes like
+/// StringRef to enable lifetime warnings.
+#if RCC_HAS_CPP_ATTRIBUTE(gsl::Pointer)
+#define RCC_GSL_POINTER [[gsl::Pointer]]
+#else
+#define RCC_GSL_POINTER
+#endif
+
+#if RCC_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
+#define RCC_LIFETIME_BOUND [[clang::lifetimebound]]
+#else
+#define RCC_LIFETIME_BOUND
+#endif
+
+#if RCC_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
+#define RCC_CTOR_NODISCARD [[nodiscard]]
+#else
+#define RCC_CTOR_NODISCARD
+#endif
+
+// Macro to suppress the MSVC warning C4848:
+// "support for attribute [[msvc::no_unique_address]] in C++17 and earlier
+// is a vendor extension".
+// This warning is removed in versions >= 19.43.
+#if !defined(_MSC_VER) || _MSC_VER >= 1943 || defined(__clang__)
+#define RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_PUSH
+#define RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_POP
+#else // MSVC < 19.43
+#define RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_PUSH \
+ __pragma (warning (push)) __pragma (warning (disable : 4848))
+#define RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_POP __pragma (warning (pop))
+#endif
+
+#if RCC_HAS_CPP_ATTRIBUTE(no_unique_address)
+#define RCC_NO_UNIQUE_ADDRESS [[no_unique_address]]
+#elif RCC_HAS_CPP_ATTRIBUTE(msvc::no_unique_address)
+#define RCC_NO_UNIQUE_ADDRESS \
+ RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_PUSH \
+ [[msvc::no_unique_address]] RCC_SUPPRESS_MSVC_ATTR_IS_VENDOR_EXT_POP
+#else
+#define RCC_NO_UNIQUE_ADDRESS
+#endif
+
+/// RCC_EXTENSION - Support compilers where we have a keyword to suppress
+/// pedantic diagnostics.
+#ifdef __GNUC__
+#define RCC_EXTENSION __extension__
+#else
+#define RCC_EXTENSION
+#endif
+
+/// RCC_BUILTIN_UNREACHABLE - On compilers which support it, expands
+/// to an expression which states that it is undefined behavior for the
+/// compiler to reach this point. Otherwise is not defined.
+///
+/// '#else' is intentionally left out so that other macro logic (e.g.,
+/// RCC_ASSUME_ALIGNED and rcc_unreachable()) can detect whether
+/// RCC_BUILTIN_UNREACHABLE has a definition.
+#if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
+#define RCC_BUILTIN_UNREACHABLE __builtin_unreachable ()
+#elif defined(_MSC_VER)
+#define RCC_BUILTIN_UNREACHABLE __assume (false)
+#endif
+
+/// RCC_BUILTIN_TRAP - On compilers which support it, expands to an expression
+/// which causes the program to exit abnormally.
+#if __has_builtin(__builtin_trap) || defined(__GNUC__)
+#define RCC_BUILTIN_TRAP __builtin_trap ()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC, does not require forward
+// declarations involving platform-specific typedefs (unlike RaiseException),
+// results in a call to vectored exception handlers, and encodes to a short
+// instruction that still causes the trapping behavior we want.
+#define RCC_BUILTIN_TRAP __debugbreak ()
+#else
+#define RCC_BUILTIN_TRAP *(volatile int *)0x11 = 0
+#endif
+
+/// RCC_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
+/// an expression which causes the program to break while running
+/// under a debugger.
+#if __has_builtin(__builtin_debugtrap)
+#define RCC_BUILTIN_DEBUGTRAP __builtin_debugtrap ()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC and breaks while
+// running under the debugger, and also supports invoking a debugger
+// when the OS is configured appropriately.
+#define RCC_BUILTIN_DEBUGTRAP __debugbreak ()
+#else
+// Just continue execution when built with compilers that have no
+// support. This is a debugging aid and not intended to force the
+// program to abort if encountered.
+#define RCC_BUILTIN_DEBUGTRAP
+#endif
+
+/// \macro RCC_ASSUME_ALIGNED
+/// Returns a pointer with an assumed alignment.
+#if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__)
+#define RCC_ASSUME_ALIGNED(p, a) __builtin_assume_aligned (p, a)
+#elif defined(RCC_BUILTIN_UNREACHABLE)
+#define RCC_ASSUME_ALIGNED(p, a) \
+ (((uintptr_t (p) % (a)) == 0) ? (p) : (RCC_BUILTIN_UNREACHABLE, (p)))
+#else
+#define RCC_ASSUME_ALIGNED(p, a) (p)
+#endif
+
+/// \macro RCC_PACKED
+/// Used to specify a packed structure.
+/// RCC_PACKED(
+/// struct A {
+/// int i;
+/// int j;
+/// int k;
+/// long long l;
+/// });
+///
+/// RCC_PACKED_START
+/// struct B {
+/// int i;
+/// int j;
+/// int k;
+/// long long l;
+/// };
+/// RCC_PACKED_END
+#ifdef _MSC_VER
+#define RCC_PACKED(d) __pragma (pack (push, 1)) d __pragma (pack (pop))
+#define RCC_PACKED_START __pragma (pack (push, 1))
+#define RCC_PACKED_END __pragma (pack (pop))
+#else
+#define RCC_PACKED(d) d __attribute__ ((packed))
+#define RCC_PACKED_START _Pragma ("pack(push, 1)")
+#define RCC_PACKED_END _Pragma ("pack(pop)")
+#endif
+
+/// \macro RCC_MEMORY_SANITIZER_BUILD
+/// Whether RCC itself is built with MemorySanitizer instrumentation.
+#if __has_feature(memory_sanitizer)
+#define RCC_MEMORY_SANITIZER_BUILD 1
+#include <sanitizer/msan_interface.h>
+#define RCC_NO_SANITIZE_MEMORY_ATTRIBUTE __attribute__ ((no_sanitize_memory))
+#else
+#define RCC_MEMORY_SANITIZER_BUILD 0
+#define __msan_allocated_memory(p, size)
+#define __msan_unpoison(p, size)
+#define RCC_NO_SANITIZE_MEMORY_ATTRIBUTE
+#endif
+
+/// \macro RCC_ADDRESS_SANITIZER_BUILD
+/// Whether RCC itself is built with AddressSanitizer instrumentation.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+#define RCC_ADDRESS_SANITIZER_BUILD 1
+#if __has_include(<sanitizer/asan_interface.h>)
+#include <sanitizer/asan_interface.h>
+#else
+// These declarations exist to support ASan with MSVC. If MSVC eventually ships
+// asan_interface.h in their headers, then we can remove this.
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ void
+ __asan_poison_memory_region (void const volatile *addr, size_t size);
+ void
+ __asan_unpoison_memory_region (void const volatile *addr, size_t size);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif
+#else
+#define RCC_ADDRESS_SANITIZER_BUILD 0
+#define __asan_poison_memory_region(p, size)
+#define __asan_unpoison_memory_region(p, size)
+#endif
+
+/// \macro RCC_HWADDRESS_SANITIZER_BUILD
+/// Whether RCC itself is built with HWAddressSanitizer instrumentation.
+#if __has_feature(hwaddress_sanitizer)
+#define RCC_HWADDRESS_SANITIZER_BUILD 1
+#else
+#define RCC_HWADDRESS_SANITIZER_BUILD 0
+#endif
+
+/// \macro RCC_THREAD_SANITIZER_BUILD
+/// Whether RCC itself is built with ThreadSanitizer instrumentation.
+#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
+#define RCC_THREAD_SANITIZER_BUILD 1
+#else
+#define RCC_THREAD_SANITIZER_BUILD 0
+#endif
+
+#if RCC_THREAD_SANITIZER_BUILD
+// Thread Sanitizer is a tool that finds races in code.
+// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
+// tsan detects these exact functions by name.
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ void
+ AnnotateHappensAfter (const char *file, int line, const volatile void *cv);
+ void
+ AnnotateHappensBefore (const char *file, int line, const volatile void *cv);
+ void
+ AnnotateIgnoreWritesBegin (const char *file, int line);
+ void
+ AnnotateIgnoreWritesEnd (const char *file, int line);
+#ifdef __cplusplus
+}
+#endif
+
+// This marker is used to define a happens-before arc. The race detector will
+// infer an arc from the begin to the end when they share the same pointer
+// argument.
+#define TsanHappensBefore(cv) AnnotateHappensBefore (__FILE__, __LINE__, cv)
+
+// This marker defines the destination of a happens-before arc.
+#define TsanHappensAfter(cv) AnnotateHappensAfter (__FILE__, __LINE__, cv)
+
+// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
+#define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin (__FILE__, __LINE__)
+
+// Resume checking for racy writes.
+#define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd (__FILE__, __LINE__)
+#else
+#define TsanHappensBefore(cv)
+#define TsanHappensAfter(cv)
+#define TsanIgnoreWritesBegin()
+#define TsanIgnoreWritesEnd()
+#endif
+
+/// \macro RCC_NO_SANITIZE
+/// Disable a particular sanitizer for a function.
+#if __has_attribute(no_sanitize)
+#define RCC_NO_SANITIZE(KIND) __attribute__ ((no_sanitize (KIND)))
+#else
+#define RCC_NO_SANITIZE(KIND)
+#endif
+
+/// Mark debug helper function definitions like dump() that should not be
+/// stripped from debug builds.
+/// Note that you should also surround dump() functions with
+/// `#if !defined(NDEBUG) || defined(RCC_ENABLE_DUMP)` so they do always
+/// get stripped in release builds.
+// FIXME: Move this to a private config.h as it's not usable in public headers.
+#if !defined(NDEBUG) || defined(RCC_ENABLE_DUMP)
+#define RCC_DUMP_METHOD \
+ RCC_ATTRIBUTE_NOINLINE RCC_ATTRIBUTE_USED RCC_ATTRIBUTE_RETAIN
+#else
+#define RCC_DUMP_METHOD RCC_ATTRIBUTE_NOINLINE
+#endif
+
+/// \macro RCC_PRETTY_FUNCTION
+/// Gets a user-friendly looking function signature for the current scope
+/// using the best available method on each platform. The exact format of the
+/// resulting string is implementation specific and non-portable, so this should
+/// only be used, for example, for logging or diagnostics.
+#if defined(_MSC_VER)
+#define RCC_PRETTY_FUNCTION __FUNCSIG__
+#elif defined(__GNUC__) || defined(__clang__)
+#define RCC_PRETTY_FUNCTION __PRETTY_FUNCTION__
+#else
+#define RCC_PRETTY_FUNCTION __func__
+#endif
+
+/// \macro RCC_THREAD_LOCAL
+/// A thread-local storage specifier which can be used with globals,
+/// extern globals, and static globals.
+///
+/// This is essentially an extremely restricted analog to C++11's thread_local
+/// support. It uses thread_local if available, falling back on gcc __thread
+/// if not. __thread doesn't support many of the C++11 thread_local's
+/// features. You should only use this for PODs that you can statically
+/// initialize to some constant value. In almost all circumstances this is most
+/// appropriate for use with a pointer, integer, or small aggregation of
+/// pointers and integers.
+#if RCC_ENABLE_THREADS
+#if __has_feature(cxx_thread_local) || defined(_MSC_VER)
+#define RCC_THREAD_LOCAL thread_local
+#else
+// Clang, GCC, and other compatible compilers used __thread prior to C++11 and
+// we only need the restricted functionality that provides.
+#define RCC_THREAD_LOCAL __thread
+#endif
+#else // !RCC_ENABLE_THREADS
+// If threading is disabled entirely, this compiles to nothing and you get
+// a normal global variable.
+#define RCC_THREAD_LOCAL
+#endif
+
+/// \macro RCC_ENABLE_EXCEPTIONS
+/// Whether RCC is built with exception support.
+#if __has_feature(cxx_exceptions)
+#define RCC_ENABLE_EXCEPTIONS 1
+#elif defined(__GNUC__) && defined(__EXCEPTIONS)
+#define RCC_ENABLE_EXCEPTIONS 1
+#elif defined(_MSC_VER) && defined(_CPPUNWIND)
+#define RCC_ENABLE_EXCEPTIONS 1
+#endif
+
+/// \macro RCC_NO_PROFILE_INSTRUMENT_FUNCTION
+/// Disable the profile instrument for a function.
+#if __has_attribute(no_profile_instrument_function)
+#define RCC_NO_PROFILE_INSTRUMENT_FUNCTION \
+ __attribute__ ((no_profile_instrument_function))
+#else
+#define RCC_NO_PROFILE_INSTRUMENT_FUNCTION
+#endif
+
+/// \macro RCC_PREFERRED_TYPE
+/// Adjust type of bit-field in debug info.
+#if __has_attribute(preferred_type)
+#define RCC_PREFERRED_TYPE(T) __attribute__ ((preferred_type (T)))
+#else
+#define RCC_PREFERRED_TYPE(T)
+#endif
+
+#if RCC_HAS_CPP_ATTRIBUTE(clang::ptrauth_vtable_pointer) && \
+ (defined(__PTRAUTH__) || __has_feature(ptrauth_calls))
+#define RCC_MOVABLE_POLYMORPHIC_TYPE \
+ [[clang::ptrauth_vtable_pointer (default_key, no_address_discrimination, \
+ default_extra_discrimination)]]
+#else
+#define RCC_MOVABLE_POLYMORPHIC_TYPE
+#endif
+
+/// \macro RCC_VIRTUAL_ANCHOR_FUNCTION
+/// This macro is used to adhere to RCC's policy that each class with a vtable
+/// must have at least one out-of-line virtual function. This macro allows us
+/// to declare such a function in `final` classes without triggering a warning.
+// clang-format off
+// Autoformatting makes this look awful.
+#if defined(__clang__)
+ // Make sure this is only parsed if __clang__ is defined
+ #if __has_warning("-Wunnecessary-virtual-specifier")
+ #define RCC_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wunnecessary-virtual-specifier\"") \
+ virtual void anchor() \
+ _Pragma("clang diagnostic pop")
+ #else // __has_warning
+ #define RCC_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
+ virtual void anchor()
+ #endif
+#else // defined(__clang__)
+ #define RCC_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
+ virtual void anchor()
+#endif
+// clang-format on
+
+/// \macro RCC_IS_X86
+/// Whether the target architecture is x86 / x86-64.
+#if defined(__x86_64__) || defined(__i386__)
+#define RCC_IS_X86 1
+#else
+#define RCC_IS_X86 0
+#endif
+
+/// \macro RCC_TARGET_SSE42
+/// Function attribute to compile a function with SSE4.2 enabled.
+#if defined(__has_attribute) && __has_attribute(target)
+#define RCC_TARGET_SSE42 __attribute__ ((target ("sse4.2")))
+#else
+#define RCC_TARGET_SSE42
+#endif
+
+#if __has_builtin(__builtin_cpu_supports) && \
+ (defined(__linux__) || defined(__APPLE__))
+#define RCC_CPU_SUPPORTS(feature) __builtin_cpu_supports (feature)
+#else
+#define RCC_CPU_SUPPORTS(feature) 0
+#endif
+
+/// \macro RCC_CPU_SUPPORTS_SSE42
+/// Expands to true if the runtime cpu supports SSE4.2, or if compiled with
+/// SSE4.2 enabled.
+#if defined(__SSE4_2__)
+#define RCC_CPU_SUPPORTS_SSE42 1
+#else
+#define RCC_CPU_SUPPORTS_SSE42 RCC_CPU_SUPPORTS ("sse4.2")
+#endif
+
+#endif
diff --git a/rcc/include/rcc/Support/Errno.h b/rcc/include/rcc/Support/Errno.h
new file mode 100644
index 0000000..21d8d78
--- /dev/null
+++ b/rcc/include/rcc/Support/Errno.h
@@ -0,0 +1,64 @@
+/*
+ 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/>.
+*/
+
+// This implementation is based on llvm/include/llvm/Support/Errno.h.
+
+#ifndef RCC_SUPPORT_ERRNO_H
+#define RCC_SUPPORT_ERRNO_H
+
+#include "rcc/Support/Compiler.h"
+
+#include <cerrno>
+#include <string>
+
+namespace rcc
+{
+namespace sys
+{
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available. Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+RCC_ABI std::string
+StrError ();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+RCC_ABI std::string
+StrError (int errnum);
+
+template <typename FailT, typename Fun, typename... Args>
+inline decltype (auto)
+RetryAfterSignal (const FailT &Fail, const Fun &F, const Args &...As)
+{
+ decltype (F (As...)) Res;
+ do
+ {
+ errno = 0;
+ Res = F (As...);
+ } while (Res == Fail && errno == EINTR);
+ return Res;
+}
+
+} // namespace sys
+} // namespace rcc
+
+#endif // RCC_SUPPORT_ERRNO_H
diff --git a/rcc/include/rcc/Support/ErrorOr.h b/rcc/include/rcc/Support/ErrorOr.h
new file mode 100644
index 0000000..0e17822
--- /dev/null
+++ b/rcc/include/rcc/Support/ErrorOr.h
@@ -0,0 +1,378 @@
+/*
+ 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/ErrorOr.h - Error Smart Pointer -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Provides ErrorOr<T> smart pointer.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_SUPPORT_ERROROR_H
+#define RCC_SUPPORT_ERROROR_H
+
+#include <cassert>
+#include <functional> // for std::reference_wrapper
+#include <system_error>
+#include <type_traits>
+#include <utility>
+
+namespace rcc
+{
+
+/// Represents either an error or a value T.
+///
+/// ErrorOr<T> is a pointer-like class that represents the result of an
+/// operation. The result is either an error, or a value of type T. This is
+/// designed to emulate the usage of returning a pointer where nullptr indicates
+/// failure. However instead of just knowing that the operation failed, we also
+/// have an error_code that describes why it failed.
+///
+/// It is used like the following.
+/// \code
+/// ErrorOr<Buffer> getBuffer();
+///
+/// auto buffer = getBuffer();
+/// if (error_code ec = buffer.getError())
+/// return ec;
+/// buffer->write("adena");
+/// \endcode
+///
+///
+/// Implicit conversion to bool returns true if there is a usable value. The
+/// unary * and -> operators provide pointer like access to the value. Accessing
+/// the value when there is an error has undefined behavior.
+///
+/// When T is a reference type the behavior is slightly different. The reference
+/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
+/// there is special handling to make operator -> work as if T was not a
+/// reference.
+///
+/// T cannot be a rvalue reference.
+template <class T> class ErrorOr
+{
+ template <class OtherT> friend class ErrorOr;
+
+ static constexpr bool isRef = std::is_reference_v<T>;
+
+ using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
+
+public:
+ using storage_type = std::conditional_t<isRef, wrap, T>;
+
+private:
+ using reference = std::remove_reference_t<T> &;
+ using const_reference = const std::remove_reference_t<T> &;
+ using pointer = std::remove_reference_t<T> *;
+ using const_pointer = const std::remove_reference_t<T> *;
+
+public:
+ template <class E>
+ ErrorOr (E ErrorCode,
+ std::enable_if_t<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ void *> = nullptr)
+ : HasError (true)
+ {
+ new (getErrorStorage ()) std::error_code (make_error_code (ErrorCode));
+ }
+
+ ErrorOr (std::error_code EC) : HasError (true)
+ {
+ new (getErrorStorage ()) std::error_code (EC);
+ }
+
+ template <class OtherT>
+ ErrorOr (OtherT &&Val,
+ std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
+ : HasError (false)
+ {
+ new (getStorage ()) storage_type (std::forward<OtherT> (Val));
+ }
+
+ ErrorOr (const ErrorOr &Other)
+ {
+ copyConstruct (Other);
+ }
+
+ template <class OtherT>
+ ErrorOr (const ErrorOr<OtherT> &Other,
+ std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
+ {
+ copyConstruct (Other);
+ }
+
+ template <class OtherT>
+ explicit ErrorOr (
+ const ErrorOr<OtherT> &Other,
+ std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * = nullptr)
+ {
+ copyConstruct (Other);
+ }
+
+ ErrorOr (ErrorOr &&Other)
+ {
+ moveConstruct (std::move (Other));
+ }
+
+ template <class OtherT>
+ ErrorOr (ErrorOr<OtherT> &&Other,
+ std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
+ {
+ moveConstruct (std::move (Other));
+ }
+
+ // This might eventually need SFINAE but it's more complex than is_convertible
+ // & I'm too lazy to write it right now.
+ template <class OtherT>
+ explicit ErrorOr (
+ ErrorOr<OtherT> &&Other,
+ std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr)
+ {
+ moveConstruct (std::move (Other));
+ }
+
+ ErrorOr &
+ operator= (const ErrorOr &Other)
+ {
+ copyAssign (Other);
+ return *this;
+ }
+
+ ErrorOr &
+ operator= (ErrorOr &&Other)
+ {
+ moveAssign (std::move (Other));
+ return *this;
+ }
+
+ ~ErrorOr ()
+ {
+ if (!HasError)
+ {
+ getStorage ()->~storage_type ();
+ }
+ }
+
+ /// Return false if there is an error.
+ explicit
+ operator bool () const
+ {
+ return !HasError;
+ }
+
+ reference
+ get ()
+ {
+ return *getStorage ();
+ }
+ const_reference
+ get () const
+ {
+ return const_cast<ErrorOr<T> *> (this)->get ();
+ }
+
+ std::error_code
+ getError () const
+ {
+ return HasError ? *getErrorStorage () : std::error_code ();
+ }
+
+ pointer
+ operator->()
+ {
+ return toPointer (getStorage ());
+ }
+
+ const_pointer
+ operator->() const
+ {
+ return toPointer (getStorage ());
+ }
+
+ reference
+ operator* ()
+ {
+ return *getStorage ();
+ }
+
+ const_reference
+ operator* () const
+ {
+ return *getStorage ();
+ }
+
+private:
+ template <class OtherT>
+ void
+ copyConstruct (const ErrorOr<OtherT> &Other)
+ {
+ if (!Other.HasError)
+ {
+ // Get the other value.
+ HasError = false;
+ new (getStorage ()) storage_type (*Other.getStorage ());
+ }
+ else
+ {
+ // Get other's error.
+ HasError = true;
+ new (getErrorStorage ()) std::error_code (Other.getError ());
+ }
+ }
+
+ template <class T1>
+ static bool
+ compareThisIfSameType (const T1 &a, const T1 &b)
+ {
+ return &a == &b;
+ }
+
+ template <class T1, class T2>
+ static bool
+ compareThisIfSameType (const T1 &, const T2 &)
+ {
+ return false;
+ }
+
+ template <class OtherT>
+ void
+ copyAssign (const ErrorOr<OtherT> &Other)
+ {
+ if (compareThisIfSameType (*this, Other))
+ {
+ return;
+ }
+
+ this->~ErrorOr ();
+ new (this) ErrorOr (Other);
+ }
+
+ template <class OtherT>
+ void
+ moveConstruct (ErrorOr<OtherT> &&Other)
+ {
+ if (!Other.HasError)
+ {
+ // Get the other value.
+ HasError = false;
+ new (getStorage ()) storage_type (std::move (*Other.getStorage ()));
+ }
+ else
+ {
+ // Get other's error.
+ HasError = true;
+ new (getErrorStorage ()) std::error_code (Other.getError ());
+ }
+ }
+
+ template <class OtherT>
+ void
+ moveAssign (ErrorOr<OtherT> &&Other)
+ {
+ if (compareThisIfSameType (*this, Other))
+ {
+ return;
+ }
+
+ this->~ErrorOr ();
+ new (this) ErrorOr (std::move (Other));
+ }
+
+ pointer
+ toPointer (pointer Val)
+ {
+ return Val;
+ }
+
+ const_pointer
+ toPointer (const_pointer Val) const
+ {
+ return Val;
+ }
+
+ pointer
+ toPointer (wrap *Val)
+ {
+ return &Val->get ();
+ }
+
+ const_pointer
+ toPointer (const wrap *Val) const
+ {
+ return &Val->get ();
+ }
+
+ storage_type *
+ getStorage ()
+ {
+ assert (!HasError && "Cannot get value when an error exists!");
+ return &TStorage;
+ }
+
+ const storage_type *
+ getStorage () const
+ {
+ assert (!HasError && "Cannot get value when an error exists!");
+ return &TStorage;
+ }
+
+ std::error_code *
+ getErrorStorage ()
+ {
+ assert (HasError && "Cannot get error when a value exists!");
+ return &ErrorStorage;
+ }
+
+ const std::error_code *
+ getErrorStorage () const
+ {
+ assert (HasError && "Cannot get error when a value exists!");
+ return &ErrorStorage;
+ }
+
+ union
+ {
+ storage_type TStorage;
+ std::error_code ErrorStorage;
+ };
+ bool HasError : 1;
+};
+
+template <class T, class E>
+std::enable_if_t<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ bool>
+operator== (const ErrorOr<T> &Err, E Code)
+{
+ return Err.getError () == Code;
+}
+
+} // end namespace rcc
+
+#endif // RCC_SUPPORT_ERROROR_H
diff --git a/rcc/include/rcc/Support/MathExtras.h b/rcc/include/rcc/Support/MathExtras.h
new file mode 100644
index 0000000..6ea2a1f
--- /dev/null
+++ b/rcc/include/rcc/Support/MathExtras.h
@@ -0,0 +1,1050 @@
+/*
+ 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/MathExtras.h - Useful math functions -------*- 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 contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_SUPPORT_MATHEXTRAS_H
+#define RCC_SUPPORT_MATHEXTRAS_H
+
+#include "rcc/Support/Compiler.h"
+#include <bit>
+#include <cassert>
+#include <climits>
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <numbers>
+#include <type_traits>
+#include <utility>
+
+namespace rcc
+{
+/// Some template parameter helpers to optimize for bitwidth, for functions that
+/// take multiple arguments.
+
+// We can't verify signedness, since callers rely on implicit coercions to
+// signed/unsigned.
+template <typename T, typename U>
+using enableif_int =
+ std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>;
+
+// Use std::common_type_t to widen only up to the widest argument.
+template <typename T, typename U, typename = enableif_int<T, U>>
+using common_uint =
+ std::common_type_t<std::make_unsigned_t<T>, std::make_unsigned_t<U>>;
+template <typename T, typename U, typename = enableif_int<T, U>>
+using common_sint =
+ std::common_type_t<std::make_signed_t<T>, std::make_signed_t<U>>;
+
+/// Mathematical constants.
+namespace numbers
+{
+// clang-format off
+inline constexpr float ef = std::numbers::e_v<float>;
+inline constexpr float egammaf = std::numbers::egamma_v<float>;
+inline constexpr float ln2f = std::numbers::ln2_v<float>;
+inline constexpr float ln10f = std::numbers::ln10_v<float>;
+inline constexpr float log2ef = std::numbers::log2e_v<float>;
+inline constexpr float log10ef = std::numbers::log10e_v<float>;
+inline constexpr float pif = std::numbers::pi_v<float>;
+inline constexpr float inv_pif = std::numbers::inv_pi_v<float>;
+inline constexpr float inv_sqrtpif = std::numbers::inv_sqrtpi_v<float>;
+inline constexpr float sqrt2f = std::numbers::sqrt2_v<float>;
+inline constexpr float inv_sqrt2f = 1.0f / std::numbers::sqrt2_v<float>;
+inline constexpr float sqrt3f = std::numbers::sqrt3_v<float>;
+inline constexpr float inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
+inline constexpr float phif = std::numbers::phi_v<float>;
+
+// sqrtpi is not in C++20 std::numbers.
+template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
+inline constexpr T sqrtpi_v = T(0x1.c5bf891b4ef6bP+0); // (1.7724538509055160273) https://oeis.org/A002161
+inline constexpr double sqrtpi = sqrtpi_v<double>;
+inline constexpr float sqrtpif = sqrtpi_v<float>;
+
+// These string literals are taken from below:
+// https://github.com/bminor/glibc/blob/8543577b04ded6d979ffcc5a818930e4d74d0645/math/math.h#L1215-L1229
+constexpr const char *pis = "3.141592653589793238462643383279502884",
+ *inv_pis = "0.318309886183790671537767526745028724";
+// clang-format on
+} // namespace numbers
+
+/// Create a bitmask with the N right-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T>
+constexpr T
+maskTrailingOnes (unsigned N)
+{
+ static_assert (std::is_unsigned_v<T>, "Invalid type!");
+ const unsigned Bits = CHAR_BIT * sizeof (T);
+ assert (N <= Bits && "Invalid bit index");
+ if (N == 0)
+ {
+ return 0;
+ }
+ return T (-1) >> (Bits - N);
+}
+
+/// Create a bitmask with the N left-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T>
+constexpr T
+maskLeadingOnes (unsigned N)
+{
+ return ~maskTrailingOnes<T> (CHAR_BIT * sizeof (T) - N);
+}
+
+/// Create a bitmask with the N right-most bits set to 0, and all other
+/// bits set to 1. Only unsigned types are allowed.
+template <typename T>
+constexpr T
+maskTrailingZeros (unsigned N)
+{
+ return maskLeadingOnes<T> (CHAR_BIT * sizeof (T) - N);
+}
+
+/// Create a bitmask with the N left-most bits set to 0, and all other
+/// bits set to 1. Only unsigned types are allowed.
+template <typename T>
+constexpr T
+maskLeadingZeros (unsigned N)
+{
+ return maskTrailingOnes<T> (CHAR_BIT * sizeof (T) - N);
+}
+
+/// Macro compressed bit reversal table for 256 bits.
+///
+/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
+static const unsigned char BitReverseTable256[256] = {
+#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64
+#define R4(n) R2 (n), R2 (n + 2 * 16), R2 (n + 1 * 16), R2 (n + 3 * 16)
+#define R6(n) R4 (n), R4 (n + 2 * 4), R4 (n + 1 * 4), R4 (n + 3 * 4)
+ R6 (0), R6 (2), R6 (1), R6 (3)
+#undef R2
+#undef R4
+#undef R6
+};
+
+/// Reverse the bits in \p Val.
+template <typename T>
+constexpr T
+reverseBits (T Val)
+{
+#if __has_builtin(__builtin_bitreverse8)
+ if constexpr (std::is_same_v<T, uint8_t>)
+ {
+ return __builtin_bitreverse8 (Val);
+ }
+#endif
+#if __has_builtin(__builtin_bitreverse16)
+ if constexpr (std::is_same_v<T, uint16_t>)
+ {
+ return __builtin_bitreverse16 (Val);
+ }
+#endif
+#if __has_builtin(__builtin_bitreverse32)
+ if constexpr (std::is_same_v<T, uint32_t>)
+ {
+ return __builtin_bitreverse32 (Val);
+ }
+#endif
+#if __has_builtin(__builtin_bitreverse64)
+ if constexpr (std::is_same_v<T, uint64_t>)
+ {
+ return __builtin_bitreverse64 (Val);
+ }
+#endif
+
+ unsigned char in[sizeof (Val)];
+ unsigned char out[sizeof (Val)];
+ std::memcpy (in, &Val, sizeof (Val));
+ for (unsigned i = 0; i < sizeof (Val); ++i)
+ {
+ out[(sizeof (Val) - i) - 1] = BitReverseTable256[in[i]];
+ }
+ std::memcpy (&Val, out, sizeof (Val));
+ return Val;
+}
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Return the high 32 bits of a 64 bit value.
+constexpr uint32_t
+Hi_32 (uint64_t Value)
+{
+ return static_cast<uint32_t> (Value >> 32);
+}
+
+/// Return the low 32 bits of a 64 bit value.
+constexpr uint32_t
+Lo_32 (uint64_t Value)
+{
+ return static_cast<uint32_t> (Value);
+}
+
+/// Make a 64-bit integer from a high / low pair of 32-bit integers.
+constexpr uint64_t
+Make_64 (uint32_t High, uint32_t Low)
+{
+ return ((uint64_t)High << 32) | (uint64_t)Low;
+}
+
+/// Checks if an integer fits into the given bit width.
+template <unsigned N>
+constexpr bool
+isInt (int64_t x)
+{
+ if constexpr (N == 0)
+ {
+ return 0 == x;
+ }
+ if constexpr (N == 8)
+ {
+ return static_cast<int8_t> (x) == x;
+ }
+ if constexpr (N == 16)
+ {
+ return static_cast<int16_t> (x) == x;
+ }
+ if constexpr (N == 32)
+ {
+ return static_cast<int32_t> (x) == x;
+ }
+ if constexpr (N < 64)
+ {
+ return -(INT64_C (1) << (N - 1)) <= x && x < (INT64_C (1) << (N - 1));
+ }
+ (void)x; // MSVC v19.25 warns that x is unused.
+ return true;
+}
+
+/// Checks if a signed integer is an N bit number shifted left by S.
+template <unsigned N, unsigned S>
+constexpr bool
+isShiftedInt (int64_t x)
+{
+ static_assert (S < 64, "isShiftedInt<N, S> with S >= 64 is too much.");
+ static_assert (N + S <= 64,
+ "isShiftedInt<N, S> with N + S > 64 is too wide.");
+ return isInt<N + S> (x) && (x % (UINT64_C (1) << S) == 0);
+}
+
+/// Checks if an unsigned integer fits into the given bit width.
+template <unsigned N>
+constexpr bool
+isUInt (uint64_t x)
+{
+ if constexpr (N < 64)
+ {
+ return (x >> N) == 0;
+ }
+ (void)x; // MSVC v19.25 warns that x is unused.
+ return true;
+}
+
+/// Checks if a unsigned integer is an N bit number shifted left by S.
+template <unsigned N, unsigned S>
+constexpr bool
+isShiftedUInt (uint64_t x)
+{
+ static_assert (S < 64, "isShiftedUInt<N, S> with S >= 64 is too much.");
+ static_assert (N + S <= 64,
+ "isShiftedUInt<N, S> with N + S > 64 is too wide.");
+ // S must be strictly less than 64. So 1 << S is not undefined behavior.
+ return isUInt<N + S> (x) && (x % (UINT64_C (1) << S) == 0);
+}
+
+/// Gets the maximum value for a N-bit unsigned integer.
+inline constexpr uint64_t
+maxUIntN (uint64_t N)
+{
+ assert (N <= 64 && "integer width out of range");
+
+ // uint64_t(1) << 64 is undefined behavior, so we can't do
+ // (uint64_t(1) << N) - 1
+ // without checking first that N != 64. But this works and doesn't have a
+ // branch for N != 0.
+ // Unfortunately, shifting a uint64_t right by 64 bit is undefined
+ // behavior, so the condition on N == 0 is necessary. Fortunately, most
+ // optimizers do not emit branches for this check.
+ if (N == 0)
+ {
+ return 0;
+ }
+ return UINT64_MAX >> (64 - N);
+}
+
+/// Gets the minimum value for a N-bit signed integer.
+inline constexpr int64_t
+minIntN (int64_t N)
+{
+ assert (N <= 64 && "integer width out of range");
+
+ if (N == 0)
+ {
+ return 0;
+ }
+ return UINT64_MAX << (N - 1);
+}
+
+/// Gets the maximum value for a N-bit signed integer.
+inline constexpr int64_t
+maxIntN (int64_t N)
+{
+ assert (N <= 64 && "integer width out of range");
+
+ // This relies on two's complement wraparound when N == 64, so we convert to
+ // int64_t only at the very end to avoid UB.
+ if (N == 0)
+ {
+ return 0;
+ }
+ return (UINT64_C (1) << (N - 1)) - 1;
+}
+
+/// Checks if an unsigned integer fits into the given (dynamic) bit width.
+inline constexpr bool
+isUIntN (unsigned N, uint64_t x)
+{
+ return N >= 64 || (x >> N) == 0;
+}
+
+/// Checks if an signed integer fits into the given (dynamic) bit width.
+inline constexpr bool
+isIntN (unsigned N, int64_t x)
+{
+ return N >= 64 || (minIntN (N) <= x && x <= maxIntN (N));
+}
+
+/// Return true if the argument is a non-empty sequence of ones starting at the
+/// least significant bit with the remainder zero (32 bit version).
+/// Ex. isMask_32(0x0000FFFFU) == true.
+constexpr bool
+isMask_32 (uint32_t Value)
+{
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// Return true if the argument is a non-empty sequence of ones starting at the
+/// least significant bit with the remainder zero (64 bit version).
+constexpr bool
+isMask_64 (uint64_t Value)
+{
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
+constexpr bool
+isShiftedMask_32 (uint32_t Value)
+{
+ return Value && isMask_32 ((Value - 1) | Value);
+}
+
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (64 bit version.)
+constexpr bool
+isShiftedMask_64 (uint64_t Value)
+{
+ return Value && isMask_64 ((Value - 1) | Value);
+}
+
+/// Return true if the argument is a power of two > 0.
+/// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+constexpr bool
+isPowerOf2_32 (uint32_t Value)
+{
+ return std::has_single_bit (Value);
+}
+
+/// Return true if the argument is a power of two > 0 (64 bit edition.)
+constexpr bool
+isPowerOf2_64 (uint64_t Value)
+{
+ return std::has_single_bit (Value);
+}
+
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
+/// If true, \p MaskIdx will specify the index of the lowest set bit and \p
+/// MaskLen is updated to specify the length of the mask, else neither are
+/// updated.
+inline bool
+isShiftedMask_32 (uint32_t Value, unsigned &MaskIdx, unsigned &MaskLen)
+{
+ if (!isShiftedMask_32 (Value))
+ {
+ return false;
+ }
+ MaskIdx = std::countr_zero (Value);
+ MaskLen = std::popcount (Value);
+ return true;
+}
+
+/// Return true if the argument contains a non-empty sequence of ones with the
+/// remainder zero (64 bit version.) If true, \p MaskIdx will specify the index
+/// of the lowest set bit and \p MaskLen is updated to specify the length of the
+/// mask, else neither are updated.
+inline bool
+isShiftedMask_64 (uint64_t Value, unsigned &MaskIdx, unsigned &MaskLen)
+{
+ if (!isShiftedMask_64 (Value))
+ {
+ return false;
+ }
+ MaskIdx = std::countr_zero (Value);
+ MaskLen = std::popcount (Value);
+ return true;
+}
+
+/// Compile time Log2.
+/// Valid only for positive powers of two.
+template <size_t kValue>
+constexpr size_t
+ConstantLog2 ()
+{
+ static_assert (rcc::isPowerOf2_64 (kValue),
+ "Value is not a valid power of 2");
+ return std::countr_zero (kValue);
+}
+
+/// Return the floor log base 2 of the specified value, -1 if the value is zero.
+/// (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+inline unsigned
+Log2_32 (uint32_t Value)
+{
+ return 31 - std::countl_zero (Value);
+}
+
+/// Return the floor log base 2 of the specified value, -1 if the value is zero.
+/// (64 bit edition.)
+inline unsigned
+Log2_64 (uint64_t Value)
+{
+ return 63 - std::countl_zero (Value);
+}
+
+/// Return the ceil log base 2 of the specified value, 32 if the value is zero.
+/// (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+inline unsigned
+Log2_32_Ceil (uint32_t Value)
+{
+ return 32 - std::countl_zero (Value - 1);
+}
+
+/// Return the ceil log base 2 of the specified value, 64 if the value is zero.
+/// (64 bit edition.)
+inline unsigned
+Log2_64_Ceil (uint64_t Value)
+{
+ return 64 - std::countl_zero (Value - 1);
+}
+
+/// A and B are either alignments or offsets. Return the minimum alignment that
+/// may be assumed after adding the two together.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+MinAlign (U A, V B)
+{
+ // The largest power of 2 that divides both A and B.
+ //
+ // Replace "-Value" by "1+~Value" in the following commented code to avoid
+ // MSVC warning C4146
+ // return (A | B) & -(A | B);
+ return (A | B) & (1 + ~(A | B));
+}
+
+/// Fallback when arguments aren't integral.
+constexpr uint64_t
+MinAlign (uint64_t A, uint64_t B)
+{
+ return (A | B) & (1 + ~(A | B));
+}
+
+/// Returns the next power of two (in 64-bits) that is strictly greater than A.
+/// Returns zero on overflow.
+constexpr uint64_t
+NextPowerOf2 (uint64_t A)
+{
+ A |= (A >> 1);
+ A |= (A >> 2);
+ A |= (A >> 4);
+ A |= (A >> 8);
+ A |= (A >> 16);
+ A |= (A >> 32);
+ return A + 1;
+}
+
+/// Returns the power of two which is greater than or equal to the given value.
+/// Essentially, it is a ceil operation across the domain of powers of two.
+inline uint64_t
+PowerOf2Ceil (uint64_t A)
+{
+ if (!A || A > UINT64_MAX / 2)
+ {
+ return 0;
+ }
+ return UINT64_C (1) << Log2_64_Ceil (A);
+}
+
+/// Returns the integer ceil(Numerator / Denominator). Unsigned version.
+/// Guaranteed to never overflow.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+divideCeil (U Numerator, V Denominator)
+{
+ assert (Denominator && "Division by zero");
+ T Bias = (Numerator != 0);
+ return (Numerator - Bias) / Denominator + Bias;
+}
+
+/// Fallback when arguments aren't integral.
+constexpr uint64_t
+divideCeil (uint64_t Numerator, uint64_t Denominator)
+{
+ assert (Denominator && "Division by zero");
+ uint64_t Bias = (Numerator != 0);
+ return (Numerator - Bias) / Denominator + Bias;
+}
+
+// Check whether divideCeilSigned or divideFloorSigned would overflow. This
+// happens only when Numerator = INT_MIN and Denominator = -1.
+template <typename U, typename V>
+constexpr bool
+divideSignedWouldOverflow (U Numerator, V Denominator)
+{
+ return Numerator == std::numeric_limits<U>::min () && Denominator == -1;
+}
+
+/// Returns the integer ceil(Numerator / Denominator). Signed version.
+/// Overflow is explicitly forbidden with an assert.
+template <typename U, typename V, typename T = common_sint<U, V>>
+constexpr T
+divideCeilSigned (U Numerator, V Denominator)
+{
+ assert (Denominator && "Division by zero");
+ assert (!divideSignedWouldOverflow (Numerator, Denominator) &&
+ "Divide would overflow");
+ if (!Numerator)
+ {
+ return 0;
+ }
+ // C's integer division rounds towards 0.
+ T Bias = Denominator >= 0 ? 1 : -1;
+ bool SameSign = (Numerator >= 0) == (Denominator >= 0);
+ return SameSign ? (Numerator - Bias) / Denominator + 1
+ : Numerator / Denominator;
+}
+
+/// Returns the integer floor(Numerator / Denominator). Signed version.
+/// Overflow is explicitly forbidden with an assert.
+template <typename U, typename V, typename T = common_sint<U, V>>
+constexpr T
+divideFloorSigned (U Numerator, V Denominator)
+{
+ assert (Denominator && "Division by zero");
+ assert (!divideSignedWouldOverflow (Numerator, Denominator) &&
+ "Divide would overflow");
+ if (!Numerator)
+ {
+ return 0;
+ }
+ // C's integer division rounds towards 0.
+ T Bias = Denominator >= 0 ? -1 : 1;
+ bool SameSign = (Numerator >= 0) == (Denominator >= 0);
+ return SameSign ? Numerator / Denominator
+ : (Numerator - Bias) / Denominator - 1;
+}
+
+/// Returns the remainder of the Euclidean division of LHS by RHS. Result is
+/// always non-negative.
+template <typename U, typename V, typename T = common_sint<U, V>>
+constexpr T
+mod (U Numerator, V Denominator)
+{
+ assert (Denominator >= 1 && "Mod by non-positive number");
+ T Mod = Numerator % Denominator;
+ return Mod < 0 ? Mod + Denominator : Mod;
+}
+
+/// Returns (Numerator / Denominator) rounded by round-half-up. Guaranteed to
+/// never overflow.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+divideNearest (U Numerator, V Denominator)
+{
+ assert (Denominator && "Division by zero");
+ T Mod = Numerator % Denominator;
+ return (Numerator / Denominator) +
+ (Mod > (static_cast<T> (Denominator) - 1) / 2);
+}
+
+/// Returns the next integer (mod 2**nbits) that is greater than or equal to
+/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
+///
+/// Examples:
+/// \code
+/// alignTo(5, 8) = 8
+/// alignTo(17, 8) = 24
+/// alignTo(~0LL, 8) = 0
+/// alignTo(321, 255) = 510
+/// \endcode
+///
+/// Will overflow only if result is not representable in T.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+alignTo (U Value, V Align)
+{
+ assert (Align != 0u && "Align can't be 0.");
+ T CeilDiv = divideCeil (Value, Align);
+ return CeilDiv * Align;
+}
+
+/// Fallback when arguments aren't integral.
+constexpr uint64_t
+alignTo (uint64_t Value, uint64_t Align)
+{
+ assert (Align != 0u && "Align can't be 0.");
+ uint64_t CeilDiv = divideCeil (Value, Align);
+ return CeilDiv * Align;
+}
+
+/// Will overflow only if result is not representable in T.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+alignToPowerOf2 (U Value, V Align)
+{
+ assert (Align != 0 && (Align & (Align - 1)) == 0 &&
+ "Align must be a power of 2");
+ T NegAlign = static_cast<T> (0) - Align;
+ return (Value + (Align - 1)) & NegAlign;
+}
+
+/// Fallback when arguments aren't integral.
+constexpr uint64_t
+alignToPowerOf2 (uint64_t Value, uint64_t Align)
+{
+ assert (Align != 0 && (Align & (Align - 1)) == 0 &&
+ "Align must be a power of 2");
+ uint64_t NegAlign = 0 - Align;
+ return (Value + (Align - 1)) & NegAlign;
+}
+
+/// If non-zero \p Skew is specified, the return value will be a minimal integer
+/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for
+/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p
+/// Skew mod \p A'. \p Align must be non-zero.
+///
+/// Examples:
+/// \code
+/// alignTo(5, 8, 7) = 7
+/// alignTo(17, 8, 1) = 17
+/// alignTo(~0LL, 8, 3) = 3
+/// alignTo(321, 255, 42) = 552
+/// \endcode
+///
+/// May overflow.
+template <typename U, typename V, typename W,
+ typename T = common_uint<common_uint<U, V>, W>>
+constexpr T
+alignTo (U Value, V Align, W Skew)
+{
+ assert (Align != 0u && "Align can't be 0.");
+ Skew %= Align;
+ return alignTo (Value - Skew, Align) + Skew;
+}
+
+/// Returns the next integer (mod 2**nbits) that is greater than or equal to
+/// \p Value and is a multiple of \c Align. \c Align must be non-zero.
+///
+/// Will overflow only if result is not representable in T.
+template <auto Align, typename V, typename T = common_uint<decltype (Align), V>>
+constexpr T
+alignTo (V Value)
+{
+ static_assert (Align != 0u, "Align must be non-zero");
+ T CeilDiv = divideCeil (Value, Align);
+ return CeilDiv * Align;
+}
+
+/// Returns the largest unsigned integer less than or equal to \p Value and is
+/// \p Skew mod \p Align. \p Align must be non-zero. Guaranteed to never
+/// overflow.
+template <typename U, typename V, typename W = uint8_t,
+ typename T = common_uint<common_uint<U, V>, W>>
+constexpr T
+alignDown (U Value, V Align, W Skew = 0)
+{
+ assert (Align != 0u && "Align can't be 0.");
+ Skew %= Align;
+ return (Value - Skew) / Align * Align + Skew;
+}
+
+/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
+/// Requires B <= 32.
+template <unsigned B>
+constexpr int32_t
+SignExtend32 (uint32_t X)
+{
+ static_assert (B <= 32, "Bit width out of range.");
+ if constexpr (B == 0)
+ {
+ return 0;
+ }
+ return int32_t (X << (32 - B)) >> (32 - B);
+}
+
+/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
+/// Requires B <= 32.
+inline int32_t
+SignExtend32 (uint32_t X, unsigned B)
+{
+ assert (B <= 32 && "Bit width out of range.");
+ if (B == 0)
+ {
+ return 0;
+ }
+ return int32_t (X << (32 - B)) >> (32 - B);
+}
+
+/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
+/// Requires B <= 64.
+template <unsigned B>
+constexpr int64_t
+SignExtend64 (uint64_t x)
+{
+ static_assert (B <= 64, "Bit width out of range.");
+ if constexpr (B == 0)
+ {
+ return 0;
+ }
+ return int64_t (x << (64 - B)) >> (64 - B);
+}
+
+/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
+/// Requires B <= 64.
+inline int64_t
+SignExtend64 (uint64_t X, unsigned B)
+{
+ assert (B <= 64 && "Bit width out of range.");
+ if (B == 0)
+ {
+ return 0;
+ }
+ return int64_t (X << (64 - B)) >> (64 - B);
+}
+
+/// Return the absolute value of a signed integer, converted to the
+/// corresponding unsigned integer type. Avoids undefined behavior in std::abs
+/// when you pass it INT_MIN or similar.
+template <typename T, typename U = std::make_unsigned_t<T>>
+constexpr U
+AbsoluteValue (T X)
+{
+ // If X is negative, cast it to the unsigned type _before_ negating it.
+ return X < 0 ? -static_cast<U> (X) : X;
+}
+
+/// Subtract two unsigned integers, X and Y, of type T and return the absolute
+/// value of the result.
+template <typename U, typename V, typename T = common_uint<U, V>>
+constexpr T
+AbsoluteDifference (U X, V Y)
+{
+ return X > Y ? (X - Y) : (Y - X);
+}
+
+/// Add two unsigned integers, X and Y, of type T. Clamp the result to the
+/// maximum representable value of T on overflow. ResultOverflowed indicates if
+/// the result is larger than the maximum representable value of type T.
+template <typename T>
+std::enable_if_t<std::is_unsigned_v<T>, T>
+SaturatingAdd (T X, T Y, bool *ResultOverflowed = nullptr)
+{
+ bool Dummy;
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
+ // Hacker's Delight, p. 29
+ T Z = X + Y;
+ Overflowed = (Z < X || Z < Y);
+ if (Overflowed)
+ {
+ return std::numeric_limits<T>::max ();
+ }
+ else
+ {
+ return Z;
+ }
+}
+
+/// Add multiple unsigned integers of type T. Clamp the result to the
+/// maximum representable value of T on overflow.
+template <class T, class... Ts>
+std::enable_if_t<std::is_unsigned_v<T>, T>
+SaturatingAdd (T X, T Y, T Z, Ts... Args)
+{
+ bool Overflowed = false;
+ T XY = SaturatingAdd (X, Y, &Overflowed);
+ if (Overflowed)
+ {
+ return SaturatingAdd (std::numeric_limits<T>::max (), T (1), Args...);
+ }
+ return SaturatingAdd (XY, Z, Args...);
+}
+
+/// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the
+/// maximum representable value of T on overflow. ResultOverflowed indicates if
+/// the result is larger than the maximum representable value of type T.
+template <typename T>
+std::enable_if_t<std::is_unsigned_v<T>, T>
+SaturatingMultiply (T X, T Y, bool *ResultOverflowed = nullptr)
+{
+ bool Dummy;
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
+
+ // Hacker's Delight, p. 30 has a different algorithm, but we don't use that
+ // because it fails for uint16_t (where multiplication can have undefined
+ // behavior due to promotion to int), and requires a division in addition
+ // to the multiplication.
+
+ Overflowed = false;
+
+ // Log2(Z) would be either Log2Z or Log2Z + 1.
+ // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
+ // will necessarily be less than Log2Max as desired.
+ int Log2Z = Log2_64 (X) + Log2_64 (Y);
+ const T Max = std::numeric_limits<T>::max ();
+ int Log2Max = Log2_64 (Max);
+ if (Log2Z < Log2Max)
+ {
+ return X * Y;
+ }
+ if (Log2Z > Log2Max)
+ {
+ Overflowed = true;
+ return Max;
+ }
+
+ // We're going to use the top bit, and maybe overflow one
+ // bit past it. Multiply all but the bottom bit then add
+ // that on at the end.
+ T Z = (X >> 1) * Y;
+ if (Z & ~(Max >> 1))
+ {
+ Overflowed = true;
+ return Max;
+ }
+ Z <<= 1;
+ if (X & 1)
+ {
+ return SaturatingAdd (Z, Y, ResultOverflowed);
+ }
+
+ return Z;
+}
+
+/// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to
+/// the product. Clamp the result to the maximum representable value of T on
+/// overflow. ResultOverflowed indicates if the result is larger than the
+/// maximum representable value of type T.
+template <typename T>
+std::enable_if_t<std::is_unsigned_v<T>, T>
+SaturatingMultiplyAdd (T X, T Y, T A, bool *ResultOverflowed = nullptr)
+{
+ bool Dummy;
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
+
+ T Product = SaturatingMultiply (X, Y, &Overflowed);
+ if (Overflowed)
+ {
+ return Product;
+ }
+
+ return SaturatingAdd (A, Product, &Overflowed);
+}
+
+/// Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
+RCC_ABI extern const float huge_valf;
+
+/// Add two signed integers, computing the two's complement truncated result,
+/// returning a pair {result, overflow}, where "overflow" is a boolean value
+/// indicating whether an overflow occurred.
+template <typename T>
+constexpr std::enable_if_t<std::is_signed_v<T>, std::pair<T, bool>>
+AddOverflow (T X, T Y)
+{
+ // Perform the unsigned addition.
+ using U = std::make_unsigned_t<T>;
+ const U UX = static_cast<U> (X);
+ const U UY = static_cast<U> (Y);
+ const U UResult = UX + UY;
+
+ // Convert to signed.
+ auto Result = static_cast<T> (UResult);
+
+ // Adding two positive numbers should result in a positive number.
+ if (X > 0 && Y > 0)
+ {
+ return {Result, Result <= 0};
+ }
+ // Adding two negatives should result in a negative number.
+ if (X < 0 && Y < 0)
+ {
+ return {Result, Result >= 0};
+ }
+ return {Result, false};
+}
+
+/// Add two signed integers, computing the two's complement truncated result,
+/// returning true if overflow occurred.
+template <typename T>
+std::enable_if_t<std::is_signed_v<T>, bool>
+AddOverflow (T X, T Y, T &Result)
+{
+#if __has_builtin(__builtin_add_overflow)
+ return __builtin_add_overflow (X, Y, &Result);
+#else
+ auto [Res, Ovf] = AddOverflow (X, Y);
+ Result = Res;
+ return Ovf;
+#endif
+}
+
+/// Subtract two signed integers, computing the two's complement truncated
+/// result, returning a pair {result, overflow}, where "overflow" is a
+/// boolean value indicating whether an overflow occurred.
+template <typename T>
+constexpr std::enable_if_t<std::is_signed_v<T>, std::pair<T, bool>>
+SubOverflow (T X, T Y)
+{
+ // Perform the unsigned addition.
+ using U = std::make_unsigned_t<T>;
+ const U UX = static_cast<U> (X);
+ const U UY = static_cast<U> (Y);
+ const U UResult = UX - UY;
+
+ // Convert to signed.
+ auto Result = static_cast<T> (UResult);
+
+ // Subtracting a positive number from a negative results in a negative number.
+ if (X <= 0 && Y > 0)
+ {
+ return {Result, Result >= 0};
+ }
+ // Subtracting a negative number from a positive results in a positive number.
+ if (X >= 0 && Y < 0)
+ {
+ return {Result, Result <= 0};
+ }
+ return {Result, false};
+}
+
+/// Subtract two signed integers, computing the two's complement truncated
+/// result, returning true if an overflow occurred.
+template <typename T>
+std::enable_if_t<std::is_signed_v<T>, bool>
+SubOverflow (T X, T Y, T &Result)
+{
+#if __has_builtin(__builtin_sub_overflow)
+ return __builtin_sub_overflow (X, Y, &Result);
+#else
+ auto [Res, Ovf] = SubOverflow (X, Y);
+ Result = Res;
+ return Ovf;
+#endif
+}
+
+/// Multiply two signed integers, computing the two's complement truncated
+/// result, returning a pair {result, overflow}, where "overflow" is a
+/// boolean value indicating whether an overflow occurred.
+template <typename T>
+constexpr std::enable_if_t<std::is_signed_v<T>, std::pair<T, bool>>
+MulOverflow (T X, T Y)
+{
+ // Perform the unsigned multiplication on absolute values.
+ using U = std::make_unsigned_t<T>;
+ const U UX = X < 0 ? (0 - static_cast<U> (X)) : static_cast<U> (X);
+ const U UY = Y < 0 ? (0 - static_cast<U> (Y)) : static_cast<U> (Y);
+ const U UResult = UX * UY;
+
+ // Convert to signed.
+ const bool IsNegative = (X < 0) ^ (Y < 0);
+ auto Result = IsNegative ? (0 - UResult) : UResult;
+
+ // If any of the args was 0, result is 0 and no overflow occurs.
+ if (UX == 0 || UY == 0)
+ {
+ return {Result, false};
+ }
+
+ // UX and UY are in [1, 2^n], where n is the number of digits.
+ // Check how the max allowed absolute value (2^n for negative, 2^(n-1) for
+ // positive) divided by an argument compares to the other.
+ bool Overflow =
+ IsNegative
+ ? UX > (static_cast<U> (std::numeric_limits<T>::max ()) + U (1)) / UY
+ : UX > (static_cast<U> (std::numeric_limits<T>::max ())) / UY;
+
+ return {Result, Overflow};
+}
+
+/// Multiply two signed integers, computing the two's complement truncated
+/// result, returning true if an overflow occurred.
+template <typename T>
+std::enable_if_t<std::is_signed_v<T>, bool>
+MulOverflow (T X, T Y, T &Result)
+{
+#if __has_builtin(__builtin_mul_overflow)
+ return __builtin_mul_overflow (X, Y, &Result);
+#else
+ auto [Res, Ovf] = MulOverflow (X, Y);
+ Result = Res;
+ return Ovf;
+#endif
+}
+
+/// Type to force float point values onto the stack, so that x86 doesn't add
+/// hidden precision, avoiding rounding differences on various platforms.
+#if defined(__i386__) || defined(_M_IX86)
+using stack_float_t = volatile float;
+#else
+using stack_float_t = float;
+#endif
+
+/// Returns the number of digits in the given integer.
+RCC_ABI int
+NumDigitsBase10 (uint64_t X);
+
+} // namespace rcc
+
+#endif