aboutsummaryrefslogtreecommitdiff
path: root/rcc
diff options
context:
space:
mode:
Diffstat (limited to 'rcc')
-rw-r--r--rcc/CMakeLists.txt2
-rw-r--r--rcc/include/rcc/ADT/STLFunctionalExtras.h112
-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
-rw-r--r--rcc/lib/CMakeLists.txt7
-rw-r--r--rcc/lib/Support/Errno.cc79
-rw-r--r--rcc/lib/Support/MathExtras.cc97
9 files changed, 1 insertions, 2641 deletions
diff --git a/rcc/CMakeLists.txt b/rcc/CMakeLists.txt
index 86f1c80..3825e8a 100644
--- a/rcc/CMakeLists.txt
+++ b/rcc/CMakeLists.txt
@@ -66,7 +66,7 @@ install(DIRECTORY "${RCC_BINARY_DIR}/include/rcc" DESTINATION "${CMAKE_INSTALL_I
FILES_MATCHING PATTERN "*.h" PATTERN "*.inc" PATTERN "*.def"
PATTERN "CMakeFiles" EXCLUDE PATTERN "config.h" EXCLUDE)
-add_subdirectory(lib)
+add_subdirectory("${RCC_SOURCE_DIR}/../libsupport" "${CMAKE_CURRENT_BINARY_DIR}/libsupport")
add_subdirectory(tools)
foreach(rccProject IN LISTS RCC_ENABLE_PROJECTS)
if(NOT rccProject STREQUAL "cfront")
diff --git a/rcc/include/rcc/ADT/STLFunctionalExtras.h b/rcc/include/rcc/ADT/STLFunctionalExtras.h
deleted file mode 100644
index 71a5b85..0000000
--- a/rcc/include/rcc/ADT/STLFunctionalExtras.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- 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/Support/Compiler.h b/rcc/include/rcc/Support/Compiler.h
deleted file mode 100644
index 511c4cd..0000000
--- a/rcc/include/rcc/Support/Compiler.h
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- 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
deleted file mode 100644
index 21d8d78..0000000
--- a/rcc/include/rcc/Support/Errno.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- 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
deleted file mode 100644
index 0e17822..0000000
--- a/rcc/include/rcc/Support/ErrorOr.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- 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
deleted file mode 100644
index 6ea2a1f..0000000
--- a/rcc/include/rcc/Support/MathExtras.h
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
- 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
diff --git a/rcc/lib/CMakeLists.txt b/rcc/lib/CMakeLists.txt
deleted file mode 100644
index 6ab18c4..0000000
--- a/rcc/lib/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-add_rcc_library(RCCSupport
- STATIC
- Support/Errno.cc
- Support/MathExtras.cc
-)
diff --git a/rcc/lib/Support/Errno.cc b/rcc/lib/Support/Errno.cc
deleted file mode 100644
index f0161a6..0000000
--- a/rcc/lib/Support/Errno.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- 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/lib/Support/Errno.cpp.
-
-#include "rcc/Support/Errno.h"
-#include "rcc/Config/config.h"
-
-#include <cstring>
-#include <errno.h>
-
-namespace rcc
-{
-namespace sys
-{
-
-std::string
-StrError ()
-{
- return StrError (errno);
-}
-
-std::string
-StrError (int errnum)
-{
- std::string str;
- if (errnum == 0)
- {
- return str;
- }
-
-#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
- const int maxErrStrLen = 2000;
- char buffer[maxErrStrLen];
- buffer[0] = '\0';
-#endif
-
-#ifdef HAVE_STRERROR_R
- // strerror_r is thread-safe.
-#if defined(__GLIBC__) && defined(_GNU_SOURCE)
- // glibc defines its own incompatible version of strerror_r which may not
- // use the buffer supplied.
- str = strerror_r (errnum, buffer, maxErrStrLen - 1);
-#else
- strerror_r (errnum, buffer, maxErrStrLen - 1);
- str = buffer;
-#endif
-#elif HAVE_DECL_STRERROR_S
- // Windows Secure API.
- strerror_s (buffer, maxErrStrLen - 1, errnum);
- str = buffer;
-#else
- // Copy the thread-unsafe result of strerror into the buffer as fast as
- // possible to minimize the impact of collisions in multiple threads.
- str = strerror (errnum);
-#endif
- return str;
-}
-
-} // namespace sys
-} // namespace rcc
diff --git a/rcc/lib/Support/MathExtras.cc b/rcc/lib/Support/MathExtras.cc
deleted file mode 100644
index f0db3a4..0000000
--- a/rcc/lib/Support/MathExtras.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- 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/>.
-*/
-
-//===-- MathExtras.cpp - Implement the MathExtras header --------------===//
-//
-// 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 implements the MathExtras.h header
-//
-//===----------------------------------------------------------------------===//
-
-#include "rcc/Support/MathExtras.h"
-
-#ifdef _MSC_VER
-#include <limits>
-#else
-#include <cmath>
-#endif
-
-namespace rcc
-{
-
-#if defined(_MSC_VER)
-// Visual Studio defines the HUGE_VAL class of macros using purposeful
-// constant arithmetic overflow, which it then warns on when encountered.
-const float huge_valf = std::numeric_limits<float>::infinity ();
-#else
-const float huge_valf = HUGE_VALF;
-#endif
-
-/// Returns the number of digits in the given integer.
-int
-NumDigitsBase10 (uint64_t X)
-{
- static constexpr struct ConstexprData
- {
- uint8_t AtLeast[65] = {};
- uint64_t Boundaries[20] = {};
- static constexpr int
- NumDigitsConstexpr (uint64_t N)
- {
- int res = 1;
- while (N >= 10)
- {
- res++;
- N /= 10;
- }
- return res;
- }
- constexpr ConstexprData ()
- {
- uint64_t Val = ~0ull;
- for (uint64_t i = 0; i <= 64; i++)
- {
- uint64_t Digits = NumDigitsConstexpr (Val) - 1;
- AtLeast[i] = Digits;
- Val >>= 1;
- }
- // Special case because X=0 should return 1 and not 0
- Boundaries[0] = 0;
- Val = 10;
- for (uint64_t i = 1; i < 20; i++)
- {
- Boundaries[i] = Val;
- Val *= 10;
- }
- }
- } Data;
-
- uint64_t Base2 = X ? std::countl_zero (X) : 64;
- uint64_t Digits = Data.AtLeast[Base2];
- return Digits + (X >= Data.Boundaries[Digits]);
-}
-
-} // namespace rcc