mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
libcxxabi: Update to Clang 20.
This commit is contained in:
parent
a89b343256
commit
7ab01c9a42
18 changed files with 344 additions and 124 deletions
6
lib/libcxxabi/include/__cxxabi_config.h
vendored
6
lib/libcxxabi/include/__cxxabi_config.h
vendored
|
|
@ -103,4 +103,10 @@
|
||||||
#define _LIBCXXABI_DTOR_FUNC
|
#define _LIBCXXABI_DTOR_FUNC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus < 201103L
|
||||||
|
# define _LIBCXXABI_NOEXCEPT throw()
|
||||||
|
#else
|
||||||
|
# define _LIBCXXABI_NOEXCEPT noexcept
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // ____CXXABI_CONFIG_H
|
#endif // ____CXXABI_CONFIG_H
|
||||||
|
|
|
||||||
28
lib/libcxxabi/include/cxxabi.h
vendored
28
lib/libcxxabi/include/cxxabi.h
vendored
|
|
@ -43,16 +43,16 @@ extern "C" {
|
||||||
|
|
||||||
// 2.4.2 Allocating the Exception Object
|
// 2.4.2 Allocating the Exception Object
|
||||||
extern _LIBCXXABI_FUNC_VIS void *
|
extern _LIBCXXABI_FUNC_VIS void *
|
||||||
__cxa_allocate_exception(size_t thrown_size) throw();
|
__cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void
|
extern _LIBCXXABI_FUNC_VIS void
|
||||||
__cxa_free_exception(void *thrown_exception) throw();
|
__cxa_free_exception(void *thrown_exception) _LIBCXXABI_NOEXCEPT;
|
||||||
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
|
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
|
||||||
extern _LIBCXXABI_FUNC_VIS __cxa_exception*
|
extern _LIBCXXABI_FUNC_VIS __cxa_exception*
|
||||||
#ifdef __wasm__
|
#ifdef __wasm__
|
||||||
// In Wasm, a destructor returns its argument
|
// In Wasm, a destructor returns its argument
|
||||||
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw();
|
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
|
||||||
#else
|
#else
|
||||||
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw();
|
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 2.4.3 Throwing the Exception Object
|
// 2.4.3 Throwing the Exception Object
|
||||||
|
|
@ -66,13 +66,13 @@ __cxa_throw(void *thrown_exception, std::type_info *tinfo,
|
||||||
|
|
||||||
// 2.5.3 Exception Handlers
|
// 2.5.3 Exception Handlers
|
||||||
extern _LIBCXXABI_FUNC_VIS void *
|
extern _LIBCXXABI_FUNC_VIS void *
|
||||||
__cxa_get_exception_ptr(void *exceptionObject) throw();
|
__cxa_get_exception_ptr(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void *
|
extern _LIBCXXABI_FUNC_VIS void *
|
||||||
__cxa_begin_catch(void *exceptionObject) throw();
|
__cxa_begin_catch(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
|
extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
|
||||||
#if defined(_LIBCXXABI_ARM_EHABI)
|
#if defined(_LIBCXXABI_ARM_EHABI)
|
||||||
extern _LIBCXXABI_FUNC_VIS bool
|
extern _LIBCXXABI_FUNC_VIS bool
|
||||||
__cxa_begin_cleanup(void *exceptionObject) throw();
|
__cxa_begin_cleanup(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
|
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
|
||||||
#endif
|
#endif
|
||||||
extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
|
extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
|
||||||
|
|
@ -80,7 +80,7 @@ extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
|
||||||
// GNU extension
|
// GNU extension
|
||||||
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
|
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
|
||||||
// throws an exception inside a try/catch block and doesn't catch it.
|
// throws an exception inside a try/catch block and doesn't catch it.
|
||||||
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_call_terminate(void*) throw();
|
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_call_terminate(void*) _LIBCXXABI_NOEXCEPT;
|
||||||
|
|
||||||
// 2.5.4 Rethrowing Exceptions
|
// 2.5.4 Rethrowing Exceptions
|
||||||
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
|
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
|
||||||
|
|
@ -168,23 +168,23 @@ extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
|
||||||
|
|
||||||
// Apple additions to support C++ 0x exception_ptr class
|
// Apple additions to support C++ 0x exception_ptr class
|
||||||
// These are primitives to wrap a smart pointer around an exception object
|
// These are primitives to wrap a smart pointer around an exception object
|
||||||
extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw();
|
extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void
|
extern _LIBCXXABI_FUNC_VIS void
|
||||||
__cxa_rethrow_primary_exception(void *primary_exception);
|
__cxa_rethrow_primary_exception(void *primary_exception);
|
||||||
extern _LIBCXXABI_FUNC_VIS void
|
extern _LIBCXXABI_FUNC_VIS void
|
||||||
__cxa_increment_exception_refcount(void *primary_exception) throw();
|
__cxa_increment_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS void
|
extern _LIBCXXABI_FUNC_VIS void
|
||||||
__cxa_decrement_exception_refcount(void *primary_exception) throw();
|
__cxa_decrement_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
|
||||||
|
|
||||||
// Apple extension to support std::uncaught_exception()
|
// Apple extension to support std::uncaught_exception()
|
||||||
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw();
|
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _LIBCXXABI_NOEXCEPT;
|
||||||
extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw();
|
extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _LIBCXXABI_NOEXCEPT;
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__Fuchsia__)
|
#if defined(__linux__) || defined(__Fuchsia__)
|
||||||
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
|
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
|
||||||
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
|
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
|
||||||
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
|
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
|
||||||
void *) throw();
|
void *) _LIBCXXABI_NOEXCEPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
||||||
18
lib/libcxxabi/src/abort_message.cpp
vendored
18
lib/libcxxabi/src/abort_message.cpp
vendored
|
|
@ -12,13 +12,8 @@
|
||||||
#include "abort_message.h"
|
#include "abort_message.h"
|
||||||
|
|
||||||
#ifdef __BIONIC__
|
#ifdef __BIONIC__
|
||||||
# include <android/api-level.h>
|
# include <syslog.h>
|
||||||
# if __ANDROID_API__ >= 21
|
extern "C" void android_set_abort_message(const char* msg);
|
||||||
# include <syslog.h>
|
|
||||||
extern "C" void android_set_abort_message(const char* msg);
|
|
||||||
# else
|
|
||||||
# include <assert.h>
|
|
||||||
# endif // __ANDROID_API__ >= 21
|
|
||||||
#endif // __BIONIC__
|
#endif // __BIONIC__
|
||||||
|
|
||||||
#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
|
#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
|
||||||
|
|
@ -26,7 +21,7 @@
|
||||||
# define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
|
# define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void abort_message(const char* format, ...)
|
void __abort_message(const char* format, ...)
|
||||||
{
|
{
|
||||||
// Write message to stderr. We do this before formatting into a
|
// Write message to stderr. We do this before formatting into a
|
||||||
// variable-size buffer so that we still get some information if
|
// variable-size buffer so that we still get some information if
|
||||||
|
|
@ -59,7 +54,6 @@ void abort_message(const char* format, ...)
|
||||||
vasprintf(&buffer, format, list);
|
vasprintf(&buffer, format, list);
|
||||||
va_end(list);
|
va_end(list);
|
||||||
|
|
||||||
# if __ANDROID_API__ >= 21
|
|
||||||
// Show error in tombstone.
|
// Show error in tombstone.
|
||||||
android_set_abort_message(buffer);
|
android_set_abort_message(buffer);
|
||||||
|
|
||||||
|
|
@ -67,12 +61,6 @@ void abort_message(const char* format, ...)
|
||||||
openlog("libc++abi", 0, 0);
|
openlog("libc++abi", 0, 0);
|
||||||
syslog(LOG_CRIT, "%s", buffer);
|
syslog(LOG_CRIT, "%s", buffer);
|
||||||
closelog();
|
closelog();
|
||||||
# else
|
|
||||||
// The good error reporting wasn't available in Android until L. Since we're
|
|
||||||
// about to abort anyway, just call __assert2, which will log _somewhere_
|
|
||||||
// (tombstone and/or logcat) in older releases.
|
|
||||||
__assert2(__FILE__, __LINE__, __func__, buffer);
|
|
||||||
# endif // __ANDROID_API__ >= 21
|
|
||||||
#endif // __BIONIC__
|
#endif // __BIONIC__
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
|
|
|
||||||
4
lib/libcxxabi/src/abort_message.h
vendored
4
lib/libcxxabi/src/abort_message.h
vendored
|
|
@ -12,7 +12,7 @@
|
||||||
#include "cxxabi.h"
|
#include "cxxabi.h"
|
||||||
|
|
||||||
extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
|
extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
|
||||||
abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
__abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
|
||||||
#ifndef _LIBCXXABI_ASSERT
|
#ifndef _LIBCXXABI_ASSERT
|
||||||
// zig patch: respect NDEBUG. Otherwise the file path makes it into the binary,
|
// zig patch: respect NDEBUG. Otherwise the file path makes it into the binary,
|
||||||
|
|
@ -24,7 +24,7 @@ abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||||
do { \
|
do { \
|
||||||
if (!(expr)) { \
|
if (!(expr)) { \
|
||||||
char const* __msg = (msg); \
|
char const* __msg = (msg); \
|
||||||
::abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
|
::__abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
|
||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
|
|
||||||
39
lib/libcxxabi/src/cxa_default_handlers.cpp
vendored
39
lib/libcxxabi/src/cxa_default_handlers.cpp
vendored
|
|
@ -10,8 +10,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <memory>
|
#include <new>
|
||||||
#include <stdlib.h>
|
|
||||||
#include "abort_message.h"
|
#include "abort_message.h"
|
||||||
#include "cxxabi.h"
|
#include "cxxabi.h"
|
||||||
#include "cxa_handlers.h"
|
#include "cxa_handlers.h"
|
||||||
|
|
@ -23,17 +22,7 @@
|
||||||
|
|
||||||
static constinit const char* cause = "uncaught";
|
static constinit const char* cause = "uncaught";
|
||||||
|
|
||||||
#ifndef _LIBCXXABI_NO_EXCEPTIONS
|
# ifndef _LIBCXXABI_NO_EXCEPTIONS
|
||||||
// Demangle the given string, or return the string as-is in case of an error.
|
|
||||||
static std::unique_ptr<char const, void (*)(char const*)> demangle(char const* str)
|
|
||||||
{
|
|
||||||
#if !defined(LIBCXXABI_NON_DEMANGLING_TERMINATE)
|
|
||||||
if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
|
|
||||||
return {result, [](char const* p) { std::free(const_cast<char*>(p)); }};
|
|
||||||
#endif
|
|
||||||
return {str, [](char const*) { /* nothing to free */ }};
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
static void demangling_terminate_handler()
|
static void demangling_terminate_handler()
|
||||||
{
|
{
|
||||||
|
|
@ -42,18 +31,18 @@ static void demangling_terminate_handler()
|
||||||
|
|
||||||
// If there is no uncaught exception, just note that we're terminating
|
// If there is no uncaught exception, just note that we're terminating
|
||||||
if (!globals)
|
if (!globals)
|
||||||
abort_message("terminating");
|
__abort_message("terminating");
|
||||||
|
|
||||||
__cxa_exception* exception_header = globals->caughtExceptions;
|
__cxa_exception* exception_header = globals->caughtExceptions;
|
||||||
if (!exception_header)
|
if (!exception_header)
|
||||||
abort_message("terminating");
|
__abort_message("terminating");
|
||||||
|
|
||||||
_Unwind_Exception* unwind_exception =
|
_Unwind_Exception* unwind_exception =
|
||||||
reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
|
reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
|
||||||
|
|
||||||
// If we're terminating due to a foreign exception
|
// If we're terminating due to a foreign exception
|
||||||
if (!__isOurExceptionClass(unwind_exception))
|
if (!__isOurExceptionClass(unwind_exception))
|
||||||
abort_message("terminating due to %s foreign exception", cause);
|
__abort_message("terminating due to %s foreign exception", cause);
|
||||||
|
|
||||||
void* thrown_object =
|
void* thrown_object =
|
||||||
__getExceptionClass(unwind_exception) == kOurDependentExceptionClass ?
|
__getExceptionClass(unwind_exception) == kOurDependentExceptionClass ?
|
||||||
|
|
@ -61,7 +50,17 @@ static void demangling_terminate_handler()
|
||||||
exception_header + 1;
|
exception_header + 1;
|
||||||
const __shim_type_info* thrown_type =
|
const __shim_type_info* thrown_type =
|
||||||
static_cast<const __shim_type_info*>(exception_header->exceptionType);
|
static_cast<const __shim_type_info*>(exception_header->exceptionType);
|
||||||
auto name = demangle(thrown_type->name());
|
|
||||||
|
auto name = [str = thrown_type->name()] {
|
||||||
|
# ifndef LIBCXXABI_NON_DEMANGLING_TERMINATE
|
||||||
|
if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
|
||||||
|
// We're about to abort(), this memory can never be freed; so it's fine
|
||||||
|
// to just return a raw pointer
|
||||||
|
return result;
|
||||||
|
# endif
|
||||||
|
return str;
|
||||||
|
}();
|
||||||
|
|
||||||
// If the uncaught exception can be caught with std::exception&
|
// If the uncaught exception can be caught with std::exception&
|
||||||
const __shim_type_info* catch_type =
|
const __shim_type_info* catch_type =
|
||||||
static_cast<const __shim_type_info*>(&typeid(std::exception));
|
static_cast<const __shim_type_info*>(&typeid(std::exception));
|
||||||
|
|
@ -69,19 +68,19 @@ static void demangling_terminate_handler()
|
||||||
{
|
{
|
||||||
// Include the what() message from the exception
|
// Include the what() message from the exception
|
||||||
const std::exception* e = static_cast<const std::exception*>(thrown_object);
|
const std::exception* e = static_cast<const std::exception*>(thrown_object);
|
||||||
abort_message("terminating due to %s exception of type %s: %s", cause, name.get(), e->what());
|
__abort_message("terminating due to %s exception of type %s: %s", cause, name, e->what());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Else just note that we're terminating due to an exception
|
// Else just note that we're terminating due to an exception
|
||||||
abort_message("terminating due to %s exception of type %s", cause, name.get());
|
__abort_message("terminating due to %s exception of type %s", cause, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // !_LIBCXXABI_NO_EXCEPTIONS
|
#else // !_LIBCXXABI_NO_EXCEPTIONS
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
static void demangling_terminate_handler()
|
static void demangling_terminate_handler()
|
||||||
{
|
{
|
||||||
abort_message("terminating");
|
__abort_message("terminating");
|
||||||
}
|
}
|
||||||
#endif // !_LIBCXXABI_NO_EXCEPTIONS
|
#endif // !_LIBCXXABI_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
|
|
||||||
4
lib/libcxxabi/src/cxa_demangle.cpp
vendored
4
lib/libcxxabi/src/cxa_demangle.cpp
vendored
|
|
@ -28,10 +28,6 @@
|
||||||
|
|
||||||
using namespace itanium_demangle;
|
using namespace itanium_demangle;
|
||||||
|
|
||||||
constexpr const char *itanium_demangle::FloatData<float>::spec;
|
|
||||||
constexpr const char *itanium_demangle::FloatData<double>::spec;
|
|
||||||
constexpr const char *itanium_demangle::FloatData<long double>::spec;
|
|
||||||
|
|
||||||
// <discriminator> := _ <non-negative number> # when number < 10
|
// <discriminator> := _ <non-negative number> # when number < 10
|
||||||
// := __ <non-negative number> _ # when number >= 10
|
// := __ <non-negative number> _ # when number >= 10
|
||||||
// extension := decimal-digit+ # at the end of string
|
// extension := decimal-digit+ # at the end of string
|
||||||
|
|
|
||||||
12
lib/libcxxabi/src/cxa_exception_storage.cpp
vendored
12
lib/libcxxabi/src/cxa_exception_storage.cpp
vendored
|
|
@ -56,17 +56,17 @@ extern "C" {
|
||||||
namespace __cxxabiv1 {
|
namespace __cxxabiv1 {
|
||||||
namespace {
|
namespace {
|
||||||
std::__libcpp_tls_key key_;
|
std::__libcpp_tls_key key_;
|
||||||
std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
|
constinit std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
|
||||||
|
|
||||||
void _LIBCPP_TLS_DESTRUCTOR_CC destruct_(void *p) {
|
void _LIBCPP_TLS_DESTRUCTOR_CC destruct_(void *p) {
|
||||||
__free_with_fallback(p);
|
__free_with_fallback(p);
|
||||||
if (0 != std::__libcpp_tls_set(key_, NULL))
|
if (0 != std::__libcpp_tls_set(key_, NULL))
|
||||||
abort_message("cannot zero out thread value for __cxa_get_globals()");
|
__abort_message("cannot zero out thread value for __cxa_get_globals()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct_() {
|
void construct_() {
|
||||||
if (0 != std::__libcpp_tls_create(&key_, destruct_))
|
if (0 != std::__libcpp_tls_create(&key_, destruct_))
|
||||||
abort_message("cannot create thread specific key for __cxa_get_globals()");
|
__abort_message("cannot create thread specific key for __cxa_get_globals()");
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
@ -80,9 +80,9 @@ extern "C" {
|
||||||
retVal = static_cast<__cxa_eh_globals*>(
|
retVal = static_cast<__cxa_eh_globals*>(
|
||||||
__calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
|
__calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
|
||||||
if (NULL == retVal)
|
if (NULL == retVal)
|
||||||
abort_message("cannot allocate __cxa_eh_globals");
|
__abort_message("cannot allocate __cxa_eh_globals");
|
||||||
if (0 != std::__libcpp_tls_set(key_, retVal))
|
if (0 != std::__libcpp_tls_set(key_, retVal))
|
||||||
abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
|
__abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +94,7 @@ extern "C" {
|
||||||
__cxa_eh_globals *__cxa_get_globals_fast() {
|
__cxa_eh_globals *__cxa_get_globals_fast() {
|
||||||
// First time through, create the key.
|
// First time through, create the key.
|
||||||
if (0 != std::__libcpp_execute_once(&flag_, construct_))
|
if (0 != std::__libcpp_execute_once(&flag_, construct_))
|
||||||
abort_message("execute once failure in __cxa_get_globals_fast()");
|
__abort_message("execute once failure in __cxa_get_globals_fast()");
|
||||||
return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
|
return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
|
||||||
}
|
}
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
||||||
10
lib/libcxxabi/src/cxa_guard_impl.h
vendored
10
lib/libcxxabi/src/cxa_guard_impl.h
vendored
|
|
@ -91,7 +91,7 @@
|
||||||
// the former.
|
// the former.
|
||||||
#ifdef BUILDING_CXA_GUARD
|
#ifdef BUILDING_CXA_GUARD
|
||||||
# include "abort_message.h"
|
# include "abort_message.h"
|
||||||
# define ABORT_WITH_MESSAGE(...) ::abort_message(__VA_ARGS__)
|
# define ABORT_WITH_MESSAGE(...) ::__abort_message(__VA_ARGS__)
|
||||||
#elif defined(TESTING_CXA_GUARD)
|
#elif defined(TESTING_CXA_GUARD)
|
||||||
# define ABORT_WITH_MESSAGE(...) ::abort()
|
# define ABORT_WITH_MESSAGE(...) ::abort()
|
||||||
#else
|
#else
|
||||||
|
|
@ -156,12 +156,12 @@ private:
|
||||||
// PlatformGetThreadID
|
// PlatformGetThreadID
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
#if defined(__APPLE__) && _LIBCPP_HAS_THREAD_API_PTHREAD
|
||||||
uint32_t PlatformThreadID() {
|
uint32_t PlatformThreadID() {
|
||||||
static_assert(sizeof(mach_port_t) == sizeof(uint32_t), "");
|
static_assert(sizeof(mach_port_t) == sizeof(uint32_t), "");
|
||||||
return static_cast<uint32_t>(pthread_mach_thread_np(std::__libcpp_thread_get_current_id()));
|
return static_cast<uint32_t>(pthread_mach_thread_np(std::__libcpp_thread_get_current_id()));
|
||||||
}
|
}
|
||||||
#elif defined(SYS_gettid) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
#elif defined(SYS_gettid) && _LIBCPP_HAS_THREAD_API_PTHREAD
|
||||||
uint32_t PlatformThreadID() {
|
uint32_t PlatformThreadID() {
|
||||||
static_assert(sizeof(pid_t) == sizeof(uint32_t), "");
|
static_assert(sizeof(pid_t) == sizeof(uint32_t), "");
|
||||||
return static_cast<uint32_t>(syscall(SYS_gettid));
|
return static_cast<uint32_t>(syscall(SYS_gettid));
|
||||||
|
|
@ -676,8 +676,8 @@ static_assert(CurrentImplementation != Implementation::Futex || PlatformSupports
|
||||||
|
|
||||||
using SelectedImplementation = SelectImplementation<CurrentImplementation>::type;
|
using SelectedImplementation = SelectImplementation<CurrentImplementation>::type;
|
||||||
|
|
||||||
} // end namespace
|
} // namespace
|
||||||
} // end namespace __cxxabiv1
|
} // namespace __cxxabiv1
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
# pragma clang diagnostic pop
|
# pragma clang diagnostic pop
|
||||||
|
|
|
||||||
6
lib/libcxxabi/src/cxa_handlers.cpp
vendored
6
lib/libcxxabi/src/cxa_handlers.cpp
vendored
|
|
@ -33,7 +33,7 @@ __unexpected(unexpected_handler func)
|
||||||
{
|
{
|
||||||
func();
|
func();
|
||||||
// unexpected handler should not return
|
// unexpected handler should not return
|
||||||
abort_message("unexpected_handler unexpectedly returned");
|
__abort_message("unexpected_handler unexpectedly returned");
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
|
|
@ -58,13 +58,13 @@ __terminate(terminate_handler func) noexcept
|
||||||
#endif // _LIBCXXABI_NO_EXCEPTIONS
|
#endif // _LIBCXXABI_NO_EXCEPTIONS
|
||||||
func();
|
func();
|
||||||
// handler should not return
|
// handler should not return
|
||||||
abort_message("terminate_handler unexpectedly returned");
|
__abort_message("terminate_handler unexpectedly returned");
|
||||||
#ifndef _LIBCXXABI_NO_EXCEPTIONS
|
#ifndef _LIBCXXABI_NO_EXCEPTIONS
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// handler should not throw exception
|
// handler should not throw exception
|
||||||
abort_message("terminate_handler unexpectedly threw an exception");
|
__abort_message("terminate_handler unexpectedly threw an exception");
|
||||||
}
|
}
|
||||||
#endif // _LIBCXXABI_NO_EXCEPTIONS
|
#endif // _LIBCXXABI_NO_EXCEPTIONS
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
lib/libcxxabi/src/cxa_personality.cpp
vendored
2
lib/libcxxabi/src/cxa_personality.cpp
vendored
|
|
@ -167,7 +167,7 @@ uintptr_t readPointerHelper(const uint8_t*& p) {
|
||||||
return static_cast<uintptr_t>(value);
|
return static_cast<uintptr_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // namespace
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
|
||||||
2
lib/libcxxabi/src/cxa_thread_atexit.cpp
vendored
2
lib/libcxxabi/src/cxa_thread_atexit.cpp
vendored
|
|
@ -89,7 +89,7 @@ namespace {
|
||||||
// __cxa_thread_atexit() may be called arbitrarily late (for example, from
|
// __cxa_thread_atexit() may be called arbitrarily late (for example, from
|
||||||
// global destructors or atexit() handlers).
|
// global destructors or atexit() handlers).
|
||||||
if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) {
|
if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) {
|
||||||
abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
|
__abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
lib/libcxxabi/src/cxa_vector.cpp
vendored
2
lib/libcxxabi/src/cxa_vector.cpp
vendored
|
|
@ -121,7 +121,7 @@ void throw_bad_array_new_length() {
|
||||||
#ifndef _LIBCXXABI_NO_EXCEPTIONS
|
#ifndef _LIBCXXABI_NO_EXCEPTIONS
|
||||||
throw std::bad_array_new_length();
|
throw std::bad_array_new_length();
|
||||||
#else
|
#else
|
||||||
abort_message("__cxa_vec_new failed to allocate memory");
|
__abort_message("__cxa_vec_new failed to allocate memory");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
lib/libcxxabi/src/cxa_virtual.cpp
vendored
4
lib/libcxxabi/src/cxa_virtual.cpp
vendored
|
|
@ -13,12 +13,12 @@ namespace __cxxabiv1 {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
|
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
|
||||||
void __cxa_pure_virtual(void) {
|
void __cxa_pure_virtual(void) {
|
||||||
abort_message("Pure virtual function called!");
|
__abort_message("Pure virtual function called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
|
_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN
|
||||||
void __cxa_deleted_virtual(void) {
|
void __cxa_deleted_virtual(void) {
|
||||||
abort_message("Deleted virtual function called!");
|
__abort_message("Deleted virtual function called!");
|
||||||
}
|
}
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // abi
|
} // abi
|
||||||
|
|
|
||||||
2
lib/libcxxabi/src/demangle/DemangleConfig.h
vendored
2
lib/libcxxabi/src/demangle/DemangleConfig.h
vendored
|
|
@ -15,7 +15,7 @@
|
||||||
// build systems to override this value.
|
// build systems to override this value.
|
||||||
// https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode
|
// https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode
|
||||||
#ifndef _LIBCPP_VERBOSE_ABORT
|
#ifndef _LIBCPP_VERBOSE_ABORT
|
||||||
#define _LIBCPP_VERBOSE_ABORT(...) abort_message(__VA_ARGS__)
|
#define _LIBCPP_VERBOSE_ABORT(...) __abort_message(__VA_ARGS__)
|
||||||
#include "../abort_message.h"
|
#include "../abort_message.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
294
lib/libcxxabi/src/demangle/ItaniumDemangle.h
vendored
294
lib/libcxxabi/src/demangle/ItaniumDemangle.h
vendored
|
|
@ -19,7 +19,6 @@
|
||||||
#include "DemangleConfig.h"
|
#include "DemangleConfig.h"
|
||||||
#include "StringViewExtras.h"
|
#include "StringViewExtras.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
#include <__cxxabi_config.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
@ -31,7 +30,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _LIBCXXABI_COMPILER_CLANG
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wunused-template"
|
#pragma clang diagnostic ignored "-Wunused-template"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -157,6 +156,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NodeArray;
|
||||||
|
|
||||||
// Base class of all AST nodes. The AST is built by the parser, then is
|
// Base class of all AST nodes. The AST is built by the parser, then is
|
||||||
// traversed by the printLeft/Right functions to produce a demangled string.
|
// traversed by the printLeft/Right functions to produce a demangled string.
|
||||||
class Node {
|
class Node {
|
||||||
|
|
@ -200,8 +201,7 @@ private:
|
||||||
|
|
||||||
Prec Precedence : 6;
|
Prec Precedence : 6;
|
||||||
|
|
||||||
// FIXME: Make these protected.
|
protected:
|
||||||
public:
|
|
||||||
/// Tracks if this node has a component on its right side, in which case we
|
/// Tracks if this node has a component on its right side, in which case we
|
||||||
/// need to call printRight.
|
/// need to call printRight.
|
||||||
Cache RHSComponentCache : 2;
|
Cache RHSComponentCache : 2;
|
||||||
|
|
@ -255,6 +255,9 @@ public:
|
||||||
Kind getKind() const { return K; }
|
Kind getKind() const { return K; }
|
||||||
|
|
||||||
Prec getPrecedence() const { return Precedence; }
|
Prec getPrecedence() const { return Precedence; }
|
||||||
|
Cache getRHSComponentCache() const { return RHSComponentCache; }
|
||||||
|
Cache getArrayCache() const { return ArrayCache; }
|
||||||
|
Cache getFunctionCache() const { return FunctionCache; }
|
||||||
|
|
||||||
virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
|
virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
|
||||||
virtual bool hasArraySlow(OutputBuffer &) const { return false; }
|
virtual bool hasArraySlow(OutputBuffer &) const { return false; }
|
||||||
|
|
@ -292,6 +295,13 @@ public:
|
||||||
// implementation.
|
// implementation.
|
||||||
virtual void printRight(OutputBuffer &) const {}
|
virtual void printRight(OutputBuffer &) const {}
|
||||||
|
|
||||||
|
// Print an initializer list of this type. Returns true if we printed a custom
|
||||||
|
// representation, false if nothing has been printed and the default
|
||||||
|
// representation should be used.
|
||||||
|
virtual bool printInitListAsType(OutputBuffer &, const NodeArray &) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string_view getBaseName() const { return {}; }
|
virtual std::string_view getBaseName() const { return {}; }
|
||||||
|
|
||||||
// Silence compiler warnings, this dtor will never be called.
|
// Silence compiler warnings, this dtor will never be called.
|
||||||
|
|
@ -338,6 +348,10 @@ public:
|
||||||
FirstElement = false;
|
FirstElement = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print an array of integer literals as a string literal. Returns whether we
|
||||||
|
// could do so.
|
||||||
|
bool printAsString(OutputBuffer &OB) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NodeArrayNode : Node {
|
struct NodeArrayNode : Node {
|
||||||
|
|
@ -424,8 +438,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QualType(const Node *Child_, Qualifiers Quals_)
|
QualType(const Node *Child_, Qualifiers Quals_)
|
||||||
: Node(KQualType, Child_->RHSComponentCache,
|
: Node(KQualType, Child_->getRHSComponentCache(), Child_->getArrayCache(),
|
||||||
Child_->ArrayCache, Child_->FunctionCache),
|
Child_->getFunctionCache()),
|
||||||
Quals(Quals_), Child(Child_) {}
|
Quals(Quals_), Child(Child_) {}
|
||||||
|
|
||||||
Qualifiers getQuals() const { return Quals; }
|
Qualifiers getQuals() const { return Quals; }
|
||||||
|
|
@ -554,8 +568,8 @@ struct AbiTagAttr : Node {
|
||||||
std::string_view Tag;
|
std::string_view Tag;
|
||||||
|
|
||||||
AbiTagAttr(Node *Base_, std::string_view Tag_)
|
AbiTagAttr(Node *Base_, std::string_view Tag_)
|
||||||
: Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
|
: Node(KAbiTagAttr, Base_->getRHSComponentCache(), Base_->getArrayCache(),
|
||||||
Base_->FunctionCache),
|
Base_->getFunctionCache()),
|
||||||
Base(Base_), Tag(Tag_) {}
|
Base(Base_), Tag(Tag_) {}
|
||||||
|
|
||||||
template<typename Fn> void match(Fn F) const { F(Base, Tag); }
|
template<typename Fn> void match(Fn F) const { F(Base, Tag); }
|
||||||
|
|
@ -615,7 +629,7 @@ class PointerType final : public Node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PointerType(const Node *Pointee_)
|
PointerType(const Node *Pointee_)
|
||||||
: Node(KPointerType, Pointee_->RHSComponentCache),
|
: Node(KPointerType, Pointee_->getRHSComponentCache()),
|
||||||
Pointee(Pointee_) {}
|
Pointee(Pointee_) {}
|
||||||
|
|
||||||
const Node *getPointee() const { return Pointee; }
|
const Node *getPointee() const { return Pointee; }
|
||||||
|
|
@ -699,7 +713,7 @@ class ReferenceType : public Node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReferenceType(const Node *Pointee_, ReferenceKind RK_)
|
ReferenceType(const Node *Pointee_, ReferenceKind RK_)
|
||||||
: Node(KReferenceType, Pointee_->RHSComponentCache),
|
: Node(KReferenceType, Pointee_->getRHSComponentCache()),
|
||||||
Pointee(Pointee_), RK(RK_) {}
|
Pointee(Pointee_), RK(RK_) {}
|
||||||
|
|
||||||
template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
|
template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
|
||||||
|
|
@ -742,7 +756,7 @@ class PointerToMemberType final : public Node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
|
PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
|
||||||
: Node(KPointerToMemberType, MemberType_->RHSComponentCache),
|
: Node(KPointerToMemberType, MemberType_->getRHSComponentCache()),
|
||||||
ClassType(ClassType_), MemberType(MemberType_) {}
|
ClassType(ClassType_), MemberType(MemberType_) {}
|
||||||
|
|
||||||
template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
|
template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
|
||||||
|
|
@ -795,6 +809,15 @@ public:
|
||||||
OB += "]";
|
OB += "]";
|
||||||
Base->printRight(OB);
|
Base->printRight(OB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool printInitListAsType(OutputBuffer &OB,
|
||||||
|
const NodeArray &Elements) const override {
|
||||||
|
if (Base->getKind() == KNameType &&
|
||||||
|
static_cast<const NameType *>(Base)->getName() == "char") {
|
||||||
|
return Elements.printAsString(OB);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FunctionType final : public Node {
|
class FunctionType final : public Node {
|
||||||
|
|
@ -1383,16 +1406,14 @@ class ParameterPack final : public Node {
|
||||||
public:
|
public:
|
||||||
ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
|
ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
|
||||||
ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
|
ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
|
||||||
if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
|
if (std::all_of(Data.begin(), Data.end(),
|
||||||
return P->ArrayCache == Cache::No;
|
[](Node *P) { return P->getArrayCache() == Cache::No; }))
|
||||||
}))
|
|
||||||
ArrayCache = Cache::No;
|
ArrayCache = Cache::No;
|
||||||
if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
|
if (std::all_of(Data.begin(), Data.end(),
|
||||||
return P->FunctionCache == Cache::No;
|
[](Node *P) { return P->getFunctionCache() == Cache::No; }))
|
||||||
}))
|
|
||||||
FunctionCache = Cache::No;
|
FunctionCache = Cache::No;
|
||||||
if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
|
if (std::all_of(Data.begin(), Data.end(), [](Node *P) {
|
||||||
return P->RHSComponentCache == Cache::No;
|
return P->getRHSComponentCache() == Cache::No;
|
||||||
}))
|
}))
|
||||||
RHSComponentCache = Cache::No;
|
RHSComponentCache = Cache::No;
|
||||||
}
|
}
|
||||||
|
|
@ -2056,17 +2077,23 @@ public:
|
||||||
class CallExpr : public Node {
|
class CallExpr : public Node {
|
||||||
const Node *Callee;
|
const Node *Callee;
|
||||||
NodeArray Args;
|
NodeArray Args;
|
||||||
|
bool IsParen; // (func)(args ...) ?
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
|
CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
|
||||||
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
|
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
|
||||||
|
IsParen(IsParen_) {}
|
||||||
|
|
||||||
template <typename Fn> void match(Fn F) const {
|
template <typename Fn> void match(Fn F) const {
|
||||||
F(Callee, Args, getPrecedence());
|
F(Callee, Args, IsParen, getPrecedence());
|
||||||
}
|
}
|
||||||
|
|
||||||
void printLeft(OutputBuffer &OB) const override {
|
void printLeft(OutputBuffer &OB) const override {
|
||||||
|
if (IsParen)
|
||||||
|
OB.printOpen();
|
||||||
Callee->print(OB);
|
Callee->print(OB);
|
||||||
|
if (IsParen)
|
||||||
|
OB.printClose();
|
||||||
OB.printOpen();
|
OB.printOpen();
|
||||||
Args.printWithComma(OB);
|
Args.printWithComma(OB);
|
||||||
OB.printClose();
|
OB.printClose();
|
||||||
|
|
@ -2226,8 +2253,11 @@ public:
|
||||||
template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
|
template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
|
||||||
|
|
||||||
void printLeft(OutputBuffer &OB) const override {
|
void printLeft(OutputBuffer &OB) const override {
|
||||||
if (Ty)
|
if (Ty) {
|
||||||
|
if (Ty->printInitListAsType(OB, Inits))
|
||||||
|
return;
|
||||||
Ty->print(OB);
|
Ty->print(OB);
|
||||||
|
}
|
||||||
OB += '{';
|
OB += '{';
|
||||||
Inits.printWithComma(OB);
|
Inits.printWithComma(OB);
|
||||||
OB += '}';
|
OB += '}';
|
||||||
|
|
@ -2434,6 +2464,8 @@ public:
|
||||||
if (Type.size() <= 3)
|
if (Type.size() <= 3)
|
||||||
OB += Type;
|
OB += Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view value() const { return Value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class RequiresExpr : public Node {
|
class RequiresExpr : public Node {
|
||||||
|
|
@ -2605,6 +2637,94 @@ template<typename NodeT> struct NodeKind;
|
||||||
};
|
};
|
||||||
#include "ItaniumNodes.def"
|
#include "ItaniumNodes.def"
|
||||||
|
|
||||||
|
inline bool NodeArray::printAsString(OutputBuffer &OB) const {
|
||||||
|
auto StartPos = OB.getCurrentPosition();
|
||||||
|
auto Fail = [&OB, StartPos] {
|
||||||
|
OB.setCurrentPosition(StartPos);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
OB += '"';
|
||||||
|
bool LastWasNumericEscape = false;
|
||||||
|
for (const Node *Element : *this) {
|
||||||
|
if (Element->getKind() != Node::KIntegerLiteral)
|
||||||
|
return Fail();
|
||||||
|
int integer_value = 0;
|
||||||
|
for (char c : static_cast<const IntegerLiteral *>(Element)->value()) {
|
||||||
|
if (c < '0' || c > '9' || integer_value > 25)
|
||||||
|
return Fail();
|
||||||
|
integer_value *= 10;
|
||||||
|
integer_value += c - '0';
|
||||||
|
}
|
||||||
|
if (integer_value > 255)
|
||||||
|
return Fail();
|
||||||
|
|
||||||
|
// Insert a `""` to avoid accidentally extending a numeric escape.
|
||||||
|
if (LastWasNumericEscape) {
|
||||||
|
if ((integer_value >= '0' && integer_value <= '9') ||
|
||||||
|
(integer_value >= 'a' && integer_value <= 'f') ||
|
||||||
|
(integer_value >= 'A' && integer_value <= 'F')) {
|
||||||
|
OB += "\"\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LastWasNumericEscape = false;
|
||||||
|
|
||||||
|
// Determine how to print this character.
|
||||||
|
switch (integer_value) {
|
||||||
|
case '\a':
|
||||||
|
OB += "\\a";
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
OB += "\\b";
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
OB += "\\f";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
OB += "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
OB += "\\r";
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
OB += "\\t";
|
||||||
|
break;
|
||||||
|
case '\v':
|
||||||
|
OB += "\\v";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
OB += "\\\"";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
OB += "\\\\";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// We assume that the character is ASCII, and use a numeric escape for all
|
||||||
|
// remaining non-printable ASCII characters.
|
||||||
|
if (integer_value < 32 || integer_value == 127) {
|
||||||
|
constexpr char Hex[] = "0123456789ABCDEF";
|
||||||
|
OB += '\\';
|
||||||
|
if (integer_value > 7)
|
||||||
|
OB += 'x';
|
||||||
|
if (integer_value >= 16)
|
||||||
|
OB += Hex[integer_value >> 4];
|
||||||
|
OB += Hex[integer_value & 0xF];
|
||||||
|
LastWasNumericEscape = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume all remaining characters are directly printable.
|
||||||
|
OB += (char)integer_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OB += '"';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||||
const char *First;
|
const char *First;
|
||||||
const char *Last;
|
const char *Last;
|
||||||
|
|
@ -2678,7 +2798,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||||
|
|
||||||
bool TryToParseTemplateArgs = true;
|
bool TryToParseTemplateArgs = true;
|
||||||
bool PermitForwardTemplateReferences = false;
|
bool PermitForwardTemplateReferences = false;
|
||||||
bool InConstraintExpr = false;
|
bool HasIncompleteTemplateParameterTracking = false;
|
||||||
size_t ParsingLambdaParamsAtLevel = (size_t)-1;
|
size_t ParsingLambdaParamsAtLevel = (size_t)-1;
|
||||||
|
|
||||||
unsigned NumSyntheticTemplateParameters[3] = {};
|
unsigned NumSyntheticTemplateParameters[3] = {};
|
||||||
|
|
@ -3240,9 +3360,12 @@ const typename AbstractManglingParser<
|
||||||
"operator co_await"},
|
"operator co_await"},
|
||||||
{"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
|
{"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
|
||||||
{"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
|
{"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
|
||||||
{"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
|
{"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
|
||||||
|
"operator()"},
|
||||||
{"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
|
{"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
|
||||||
{"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
|
{"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
|
||||||
|
{"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
|
||||||
|
"operator()"},
|
||||||
{"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
|
{"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
|
||||||
{"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
|
{"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
|
||||||
{"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
|
{"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
|
||||||
|
|
@ -3319,7 +3442,7 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// We can't use lower_bound as that can link to symbols in the C++ library,
|
// We can't use lower_bound as that can link to symbols in the C++ library,
|
||||||
// and this must remain independant of that.
|
// and this must remain independent of that.
|
||||||
size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
|
size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
|
||||||
while (upper != lower) {
|
while (upper != lower) {
|
||||||
size_t middle = (upper + lower) / 2;
|
size_t middle = (upper + lower) / 2;
|
||||||
|
|
@ -4207,9 +4330,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
|
||||||
case 'h':
|
case 'h':
|
||||||
First += 2;
|
First += 2;
|
||||||
return make<NameType>("half");
|
return make<NameType>("half");
|
||||||
// ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
|
// ::= DF16b # C++23 std::bfloat16_t
|
||||||
|
// ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
|
||||||
case 'F': {
|
case 'F': {
|
||||||
First += 2;
|
First += 2;
|
||||||
|
if (consumeIf("16b"))
|
||||||
|
return make<NameType>("std::bfloat16_t");
|
||||||
Node *DimensionNumber = make<NameType>(parseNumber());
|
Node *DimensionNumber = make<NameType>(parseNumber());
|
||||||
if (!DimensionNumber)
|
if (!DimensionNumber)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -4217,6 +4343,101 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return make<BinaryFPType>(DimensionNumber);
|
return make<BinaryFPType>(DimensionNumber);
|
||||||
}
|
}
|
||||||
|
// ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
|
||||||
|
// ::= [DS] DR # N1169 fixed-point [_Sat] T _Frac
|
||||||
|
// <fixed-point-size>
|
||||||
|
// ::= s # short
|
||||||
|
// ::= t # unsigned short
|
||||||
|
// ::= i # plain
|
||||||
|
// ::= j # unsigned
|
||||||
|
// ::= l # long
|
||||||
|
// ::= m # unsigned long
|
||||||
|
case 'A': {
|
||||||
|
char c = look(2);
|
||||||
|
First += 3;
|
||||||
|
switch (c) {
|
||||||
|
case 's':
|
||||||
|
return make<NameType>("short _Accum");
|
||||||
|
case 't':
|
||||||
|
return make<NameType>("unsigned short _Accum");
|
||||||
|
case 'i':
|
||||||
|
return make<NameType>("_Accum");
|
||||||
|
case 'j':
|
||||||
|
return make<NameType>("unsigned _Accum");
|
||||||
|
case 'l':
|
||||||
|
return make<NameType>("long _Accum");
|
||||||
|
case 'm':
|
||||||
|
return make<NameType>("unsigned long _Accum");
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'R': {
|
||||||
|
char c = look(2);
|
||||||
|
First += 3;
|
||||||
|
switch (c) {
|
||||||
|
case 's':
|
||||||
|
return make<NameType>("short _Fract");
|
||||||
|
case 't':
|
||||||
|
return make<NameType>("unsigned short _Fract");
|
||||||
|
case 'i':
|
||||||
|
return make<NameType>("_Fract");
|
||||||
|
case 'j':
|
||||||
|
return make<NameType>("unsigned _Fract");
|
||||||
|
case 'l':
|
||||||
|
return make<NameType>("long _Fract");
|
||||||
|
case 'm':
|
||||||
|
return make<NameType>("unsigned long _Fract");
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'S': {
|
||||||
|
First += 2;
|
||||||
|
if (look() != 'D')
|
||||||
|
return nullptr;
|
||||||
|
if (look(1) == 'A') {
|
||||||
|
char c = look(2);
|
||||||
|
First += 3;
|
||||||
|
switch (c) {
|
||||||
|
case 's':
|
||||||
|
return make<NameType>("_Sat short _Accum");
|
||||||
|
case 't':
|
||||||
|
return make<NameType>("_Sat unsigned short _Accum");
|
||||||
|
case 'i':
|
||||||
|
return make<NameType>("_Sat _Accum");
|
||||||
|
case 'j':
|
||||||
|
return make<NameType>("_Sat unsigned _Accum");
|
||||||
|
case 'l':
|
||||||
|
return make<NameType>("_Sat long _Accum");
|
||||||
|
case 'm':
|
||||||
|
return make<NameType>("_Sat unsigned long _Accum");
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (look(1) == 'R') {
|
||||||
|
char c = look(2);
|
||||||
|
First += 3;
|
||||||
|
switch (c) {
|
||||||
|
case 's':
|
||||||
|
return make<NameType>("_Sat short _Fract");
|
||||||
|
case 't':
|
||||||
|
return make<NameType>("_Sat unsigned short _Fract");
|
||||||
|
case 'i':
|
||||||
|
return make<NameType>("_Sat _Fract");
|
||||||
|
case 'j':
|
||||||
|
return make<NameType>("_Sat unsigned _Fract");
|
||||||
|
case 'l':
|
||||||
|
return make<NameType>("_Sat long _Fract");
|
||||||
|
case 'm':
|
||||||
|
return make<NameType>("_Sat unsigned long _Fract");
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
// ::= DB <number> _ # C23 signed _BitInt(N)
|
// ::= DB <number> _ # C23 signed _BitInt(N)
|
||||||
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
|
// ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
|
||||||
// ::= DU <number> _ # C23 unsigned _BitInt(N)
|
// ::= DU <number> _ # C23 unsigned _BitInt(N)
|
||||||
|
|
@ -4337,6 +4558,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
|
||||||
// parse them, take the second production.
|
// parse them, take the second production.
|
||||||
|
|
||||||
if (TryToParseTemplateArgs && look() == 'I') {
|
if (TryToParseTemplateArgs && look() == 'I') {
|
||||||
|
Subs.push_back(Result);
|
||||||
Node *TA = getDerived().parseTemplateArgs();
|
Node *TA = getDerived().parseTemplateArgs();
|
||||||
if (TA == nullptr)
|
if (TA == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -4819,7 +5041,8 @@ template <typename Derived, typename Alloc>
|
||||||
Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
|
Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
|
||||||
// Within this expression, all enclosing template parameter lists are in
|
// Within this expression, all enclosing template parameter lists are in
|
||||||
// scope.
|
// scope.
|
||||||
ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
|
ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
|
||||||
|
HasIncompleteTemplateParameterTracking, true);
|
||||||
return getDerived().parseExpr();
|
return getDerived().parseExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4888,6 +5111,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
|
||||||
// ::= <binary operator-name> <expression> <expression>
|
// ::= <binary operator-name> <expression> <expression>
|
||||||
// ::= <ternary operator-name> <expression> <expression> <expression>
|
// ::= <ternary operator-name> <expression> <expression> <expression>
|
||||||
// ::= cl <expression>+ E # call
|
// ::= cl <expression>+ E # call
|
||||||
|
// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
|
||||||
// ::= cv <type> <expression> # conversion with one argument
|
// ::= cv <type> <expression> # conversion with one argument
|
||||||
// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
|
// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
|
||||||
// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
|
// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
|
||||||
|
|
@ -5023,7 +5247,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
||||||
Names.push_back(E);
|
Names.push_back(E);
|
||||||
}
|
}
|
||||||
return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
|
return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
|
||||||
Op->getPrecedence());
|
/*IsParen=*/Op->getFlag(), Op->getPrecedence());
|
||||||
}
|
}
|
||||||
case OperatorInfo::CCast: {
|
case OperatorInfo::CCast: {
|
||||||
// C Cast: (type)expr
|
// C Cast: (type)expr
|
||||||
|
|
@ -5210,7 +5434,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
|
return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
|
||||||
Node::Prec::Postfix);
|
/*IsParen=*/false, Node::Prec::Postfix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only unresolved names remain.
|
// Only unresolved names remain.
|
||||||
|
|
@ -5677,7 +5901,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
|
||||||
// substitute them all within a <constraint-expression>, so print the
|
// substitute them all within a <constraint-expression>, so print the
|
||||||
// parameter numbering instead for now.
|
// parameter numbering instead for now.
|
||||||
// TODO: Track all enclosing template parameters and substitute them here.
|
// TODO: Track all enclosing template parameters and substitute them here.
|
||||||
if (InConstraintExpr) {
|
if (HasIncompleteTemplateParameterTracking) {
|
||||||
return make<NameType>(std::string_view(Begin, First - 1 - Begin));
|
return make<NameType>(std::string_view(Begin, First - 1 - Begin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5738,6 +5962,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consumeIf("Tk")) {
|
if (consumeIf("Tk")) {
|
||||||
|
// We don't track enclosing template parameter levels well enough to
|
||||||
|
// reliably demangle template parameter substitutions, so print an arbitrary
|
||||||
|
// string in place of a parameter for now.
|
||||||
|
// TODO: Track all enclosing template parameters and demangle substitutions.
|
||||||
|
ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
|
||||||
|
HasIncompleteTemplateParameterTracking, true);
|
||||||
Node *Constraint = getDerived().parseName();
|
Node *Constraint = getDerived().parseName();
|
||||||
if (!Constraint)
|
if (!Constraint)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -5948,7 +6178,7 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
|
||||||
|
|
||||||
DEMANGLE_NAMESPACE_END
|
DEMANGLE_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef _LIBCXXABI_COMPILER_CLANG
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
4
lib/libcxxabi/src/fallback_malloc.cpp
vendored
4
lib/libcxxabi/src/fallback_malloc.cpp
vendored
|
|
@ -259,7 +259,7 @@ void* __aligned_malloc_with_fallback(size_t size) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
|
if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
|
||||||
return dest;
|
return dest;
|
||||||
#elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
|
#elif !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
|
||||||
if (void* dest = ::malloc(size))
|
if (void* dest = ::malloc(size))
|
||||||
return dest;
|
return dest;
|
||||||
#else
|
#else
|
||||||
|
|
@ -286,7 +286,7 @@ void __aligned_free_with_fallback(void* ptr) {
|
||||||
if (is_fallback_ptr(ptr))
|
if (is_fallback_ptr(ptr))
|
||||||
fallback_free(ptr);
|
fallback_free(ptr);
|
||||||
else {
|
else {
|
||||||
#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
|
#if !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
|
||||||
::free(ptr);
|
::free(ptr);
|
||||||
#else
|
#else
|
||||||
std::__libcpp_aligned_free(ptr);
|
std::__libcpp_aligned_free(ptr);
|
||||||
|
|
|
||||||
11
lib/libcxxabi/src/private_typeinfo.cpp
vendored
11
lib/libcxxabi/src/private_typeinfo.cpp
vendored
|
|
@ -41,9 +41,11 @@
|
||||||
// Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls
|
// Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls
|
||||||
// is_equal() with use_strcmp=false so the string names are not compared.
|
// is_equal() with use_strcmp=false so the string names are not compared.
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "abort_message.h"
|
#include "abort_message.h"
|
||||||
|
|
||||||
#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
|
#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
|
||||||
|
|
@ -589,10 +591,9 @@ __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
|
||||||
// .. and reset the pointer.
|
// .. and reset the pointer.
|
||||||
adjustedPtr = nullptr;
|
adjustedPtr = nullptr;
|
||||||
}
|
}
|
||||||
__base_type->has_unambiguous_public_base(
|
__base_type->has_unambiguous_public_base(
|
||||||
info,
|
info, reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(adjustedPtr) + offset_to_base),
|
||||||
static_cast<char*>(adjustedPtr) + offset_to_base,
|
(__offset_flags & __public_mask) ? path_below : not_public_path);
|
||||||
(__offset_flags & __public_mask) ? path_below : not_public_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
20
lib/libcxxabi/src/stdlib_new_delete.cpp
vendored
20
lib/libcxxabi/src/stdlib_new_delete.cpp
vendored
|
|
@ -24,22 +24,22 @@
|
||||||
# error The _LIBCPP_WEAK macro should be already defined by libc++
|
# error The _LIBCPP_WEAK macro should be already defined by libc++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS)
|
#if defined(_LIBCXXABI_NO_EXCEPTIONS) != !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# error libc++ and libc++abi seem to disagree on whether exceptions are enabled
|
# error libc++ and libc++abi seem to disagree on whether exceptions are enabled
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void __throw_bad_alloc_shim() {
|
inline void __throw_bad_alloc_shim() {
|
||||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
#if _LIBCPP_HAS_EXCEPTIONS
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
#else
|
#else
|
||||||
abort_message("bad_alloc was thrown in -fno-exceptions mode");
|
__abort_message("bad_alloc was thrown in -fno-exceptions mode");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _LIBCPP_ASSERT_SHIM(expr, str) \
|
#define _LIBCPP_ASSERT_SHIM(expr, str) \
|
||||||
do { \
|
do { \
|
||||||
if (!expr) \
|
if (!expr) \
|
||||||
abort_message(str); \
|
__abort_message(str); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
// ------------------ BEGIN COPY ------------------
|
// ------------------ BEGIN COPY ------------------
|
||||||
|
|
@ -71,7 +71,7 @@ _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
|
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
|
||||||
#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
|
#if !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
||||||
_LIBCPP_ASSERT_SHIM(
|
_LIBCPP_ASSERT_SHIM(
|
||||||
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
|
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
|
||||||
|
|
@ -99,7 +99,7 @@ _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](s
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
|
_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
|
||||||
#ifdef _LIBCPP_HAS_NO_EXCEPTIONS
|
#if !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
||||||
_LIBCPP_ASSERT_SHIM(
|
_LIBCPP_ASSERT_SHIM(
|
||||||
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
|
!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
|
||||||
|
|
@ -134,7 +134,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept {
|
||||||
|
|
||||||
_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
|
_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
|
#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
|
||||||
|
|
||||||
static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
|
static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -165,7 +165,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
|
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
|
||||||
# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
|
# if !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
||||||
_LIBCPP_ASSERT_SHIM(
|
_LIBCPP_ASSERT_SHIM(
|
||||||
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
|
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
|
||||||
|
|
@ -194,7 +194,7 @@ operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
|
_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
|
||||||
# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
|
# if !_LIBCPP_HAS_EXCEPTIONS
|
||||||
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
|
||||||
_LIBCPP_ASSERT_SHIM(
|
_LIBCPP_ASSERT_SHIM(
|
||||||
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
|
!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
|
||||||
|
|
@ -240,5 +240,5 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignmen
|
||||||
::operator delete[](ptr, alignment);
|
::operator delete[](ptr, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
|
#endif // _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
|
||||||
// ------------------ END COPY ------------------
|
// ------------------ END COPY ------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue