mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 05:44:47 +01:00
llvm-libc: update to LLVM 22
This commit is contained in:
parent
e5ede37983
commit
1576e4181c
37 changed files with 1542 additions and 281 deletions
278
lib/libcxx/libc/LICENSE.TXT
vendored
Normal file
278
lib/libcxx/libc/LICENSE.TXT
vendored
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
==============================================================================
|
||||
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
|
||||
==============================================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
---- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
==============================================================================
|
||||
Software from third parties included in the LLVM Project:
|
||||
==============================================================================
|
||||
The LLVM Project contains third party software which is under different license
|
||||
terms. All such code will be identified clearly using at least one of two
|
||||
mechanisms:
|
||||
1) It will be in a separate directory tree with its own `LICENSE.txt` or
|
||||
`LICENSE` file at the top containing the specific license and restrictions
|
||||
which apply to that software, or
|
||||
2) It will contain specific license and restriction terms at the top of every
|
||||
file.
|
||||
|
||||
==============================================================================
|
||||
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
|
||||
==============================================================================
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2007-2019 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
4
lib/libcxx/libc/hdr/errno_macros.h
vendored
4
lib/libcxx/libc/hdr/errno_macros.h
vendored
|
|
@ -15,7 +15,9 @@
|
|||
#include <linux/errno.h>
|
||||
|
||||
#include "include/llvm-libc-macros/error-number-macros.h"
|
||||
#else // __linux__
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/errno.h>
|
||||
#else // __APPLE__
|
||||
#include "include/llvm-libc-macros/generic-error-number-macros.h"
|
||||
#endif
|
||||
|
||||
|
|
|
|||
18
lib/libcxx/libc/hdr/stdint_proxy.h
vendored
Normal file
18
lib/libcxx/libc/hdr/stdint_proxy.h
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//===-- stdint.h ----------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_STDINT_PROXY_H
|
||||
#define LLVM_LIBC_HDR_STDINT_PROXY_H
|
||||
|
||||
// This target is to make sure we have correct build order in full build mode,
|
||||
// that is `libc.include.stdint` is added to the dependency of all targets
|
||||
// that use <stdint.h> header.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#endif // LLVM_LIBC_HDR_STDINT_PROXY_H
|
||||
23
lib/libcxx/libc/hdr/types/wchar_t.h
vendored
Normal file
23
lib/libcxx/libc/hdr/types/wchar_t.h
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//===-- Definition of wchar_t.h -------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_WCHAR_T_H
|
||||
#define LLVM_LIBC_HDR_TYPES_WCHAR_T_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/wchar_t.h"
|
||||
|
||||
#else // overlay mode
|
||||
|
||||
#include "hdr/wchar_overlay.h"
|
||||
|
||||
#endif // LLVM_LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_WCHAR_T_H
|
||||
69
lib/libcxx/libc/hdr/wchar_overlay.h
vendored
Normal file
69
lib/libcxx/libc/hdr/wchar_overlay.h
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
//===-- Including wchar.h in overlay mode ---------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_WCHAR_OVERLAY_H
|
||||
#define LLVM_LIBC_HDR_WCHAR_OVERLAY_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
#error "This header should only be included in overlay mode"
|
||||
#endif
|
||||
|
||||
// Overlay mode
|
||||
|
||||
// glibc <wchar.h> header might provide extern inline definitions for few
|
||||
// functions, causing external alias errors. They are guarded by
|
||||
// `__USE_EXTERN_INLINES` macro. We temporarily disable `__USE_EXTERN_INLINES`
|
||||
// macro by defining `__NO_INLINE__` before including <wchar.h>.
|
||||
// And the same with `__USE_FORTIFY_LEVEL`, which will be temporarily disabled
|
||||
// with `_FORTIFY_SOURCE`.
|
||||
|
||||
#ifdef _FORTIFY_SOURCE
|
||||
#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE
|
||||
#undef _FORTIFY_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef __NO_INLINE__
|
||||
#define __NO_INLINE__ 1
|
||||
#define LIBC_SET_NO_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __USE_EXTERN_INLINES
|
||||
#define LIBC_OLD_USE_EXTERN_INLINES
|
||||
#undef __USE_EXTERN_INLINES
|
||||
#endif
|
||||
|
||||
#ifdef __USE_FORTIFY_LEVEL
|
||||
#define LIBC_OLD_USE_FORTIFY_LEVEL __USE_FORTIFY_LEVEL
|
||||
#undef __USE_FORTIFY_LEVEL
|
||||
#define __USE_FORTIFY_LEVEL 0
|
||||
#endif
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef LIBC_OLD_FORTIFY_SOURCE
|
||||
#define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE
|
||||
#undef LIBC_OLD_FORTIFY_SOURCE
|
||||
#endif
|
||||
|
||||
#ifdef LIBC_SET_NO_INLINE
|
||||
#undef __NO_INLINE__
|
||||
#undef LIBC_SET_NO_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef LIBC_OLD_USE_FORTIFY_LEVEL
|
||||
#undef __USE_FORTIFY_LEVEL
|
||||
#define __USE_FORTIFY_LEVEL LIBC_OLD_USE_FORTIFY_LEVEL
|
||||
#undef LIBC_OLD_USE_FORTIFY_LEVEL
|
||||
#endif
|
||||
|
||||
#ifdef LIBC_OLD_USE_EXTERN_INLINES
|
||||
#define __USE_EXTERN_INLINES
|
||||
#undef LIBC_OLD_USE_EXTERN_INLINES
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_HDR_WCHAR_OVERLAY_H
|
||||
41
lib/libcxx/libc/include/llvm-libc-macros/cfloat128-macros.h
vendored
Normal file
41
lib/libcxx/libc/include/llvm-libc-macros/cfloat128-macros.h
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//===-- Detection of _Complex _Float128 compiler builtin type -------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_MACROS_CFLOAT128_MACROS_H
|
||||
#define LLVM_LIBC_MACROS_CFLOAT128_MACROS_H
|
||||
|
||||
#include "float-macros.h" // LDBL_MANT_DIG
|
||||
|
||||
// Currently, the complex variant of C23 `_Float128` type is only defined as a
|
||||
// built-in type in GCC 7 or later, for C and in GCC 13 or later, for C++. For
|
||||
// clang, the complex variant of `__float128` is defined instead, and only on
|
||||
// x86-64 targets for clang 11 or later.
|
||||
//
|
||||
// TODO: Update the complex variant of C23 `_Float128` type detection again when
|
||||
// clang supports it.
|
||||
#ifdef __clang__
|
||||
#if (__clang_major__ >= 11) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
// Use _Complex __float128 type. clang uses __SIZEOF_FLOAT128__ or __FLOAT128__
|
||||
// macro to notify the availability of __float128 type:
|
||||
// https://reviews.llvm.org/D15120
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (defined(__STDC_IEC_60559_COMPLEX__) || defined(__SIZEOF_FLOAT128__)) && \
|
||||
(__GNUC__ >= 13 || (!defined(__cplusplus)))
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LIBC_TYPES_HAS_CFLOAT128) && (LDBL_MANT_DIG == 113)
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
#define LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_MACROS_CFLOAT128_MACROS_H
|
||||
20
lib/libcxx/libc/include/llvm-libc-macros/cfloat16-macros.h
vendored
Normal file
20
lib/libcxx/libc/include/llvm-libc-macros/cfloat16-macros.h
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Detection of _Complex _Float16 compiler builtin type --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_MACROS_CFLOAT16_MACROS_H
|
||||
#define LLVM_LIBC_MACROS_CFLOAT16_MACROS_H
|
||||
|
||||
#if defined(__FLT16_MANT_DIG__) && \
|
||||
(!defined(__GNUC__) || __GNUC__ >= 13 || \
|
||||
(defined(__clang__) && __clang_major__ >= 14)) && \
|
||||
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
|
||||
!defined(_WIN32)
|
||||
#define LIBC_TYPES_HAS_CFLOAT16
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_MACROS_CFLOAT16_MACROS_H
|
||||
|
|
@ -9,36 +9,19 @@
|
|||
#ifndef LLVM_LIBC_TYPES_CFLOAT128_H
|
||||
#define LLVM_LIBC_TYPES_CFLOAT128_H
|
||||
|
||||
#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
|
||||
#include "../llvm-libc-macros/cfloat128-macros.h"
|
||||
|
||||
// Currently, the complex variant of C23 `_Float128` type is only defined as a
|
||||
// built-in type in GCC 7 or later, for C and in GCC 13 or later, for C++. For
|
||||
// clang, the complex variant of `__float128` is defined instead, and only on
|
||||
// x86-64 targets for clang 11 or later.
|
||||
//
|
||||
// TODO: Update the complex variant of C23 `_Float128` type detection again when
|
||||
// clang supports it.
|
||||
#ifdef __clang__
|
||||
#if (__clang_major__ >= 11) && \
|
||||
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
|
||||
// Use _Complex __float128 type. clang uses __SIZEOF_FLOAT128__ or __FLOAT128__
|
||||
// macro to notify the availability of __float128 type:
|
||||
// https://reviews.llvm.org/D15120
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
#ifdef LIBC_TYPES_HAS_CFLOAT128
|
||||
#ifndef LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
// Remove the workaround when https://gcc.gnu.org/PR32187 gets fixed.
|
||||
typedef __typeof__(_Complex __float128) cfloat128;
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
typedef _Complex __float128 cfloat128;
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (defined(__STDC_IEC_60559_COMPLEX__) || defined(__SIZEOF_FLOAT128__)) && \
|
||||
(__GNUC__ >= 13 || (!defined(__cplusplus)))
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
typedef _Complex _Float128 cfloat128;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LIBC_TYPES_HAS_CFLOAT128) && (LDBL_MANT_DIG == 113)
|
||||
#define LIBC_TYPES_HAS_CFLOAT128
|
||||
#define LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
|
||||
#endif // ^^^ no workaround ^^^
|
||||
#else
|
||||
typedef _Complex long double cfloat128;
|
||||
#endif
|
||||
#endif // LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
|
||||
#endif // LIBC_TYPES_HAS_CFLOAT128
|
||||
|
||||
#endif // LLVM_LIBC_TYPES_CFLOAT128_H
|
||||
|
|
|
|||
|
|
@ -9,13 +9,10 @@
|
|||
#ifndef LLVM_LIBC_TYPES_CFLOAT16_H
|
||||
#define LLVM_LIBC_TYPES_CFLOAT16_H
|
||||
|
||||
#if defined(__FLT16_MANT_DIG__) && \
|
||||
(!defined(__GNUC__) || __GNUC__ >= 13 || \
|
||||
(defined(__clang__) && __clang_major__ >= 14)) && \
|
||||
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
|
||||
!defined(_WIN32)
|
||||
#define LIBC_TYPES_HAS_CFLOAT16
|
||||
#include "../llvm-libc-macros/cfloat16-macros.h"
|
||||
|
||||
#ifdef LIBC_TYPES_HAS_CFLOAT16
|
||||
typedef _Complex _Float16 cfloat16;
|
||||
#endif
|
||||
#endif // LIBC_TYPES_HAS_CFLOAT16
|
||||
|
||||
#endif // LLVM_LIBC_TYPES_CFLOAT16_H
|
||||
|
|
|
|||
19
lib/libcxx/libc/include/llvm-libc-types/wchar_t.h
vendored
Normal file
19
lib/libcxx/libc/include/llvm-libc-types/wchar_t.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//===-- Definition of wchar_t types ---------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_TYPES_WCHAR_T_H
|
||||
#define LLVM_LIBC_TYPES_WCHAR_T_H
|
||||
|
||||
// wchar_t is a fundamental type in C++.
|
||||
#ifndef __cplusplus
|
||||
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_TYPES_WCHAR_T_H
|
||||
5
lib/libcxx/libc/shared/libc_common.h
vendored
5
lib/libcxx/libc/shared/libc_common.h
vendored
|
|
@ -19,6 +19,11 @@
|
|||
#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE
|
||||
#endif // LIBC_ERRNO_MODE
|
||||
|
||||
// Use system fenv functions in math implementations.
|
||||
#ifndef LIBC_MATH_USE_SYSTEM_FENV
|
||||
#define LIBC_MATH_USE_SYSTEM_FENV
|
||||
#endif // LIBC_MATH_USE_SYSTEM_FENV
|
||||
|
||||
#ifndef LIBC_NAMESPACE
|
||||
#define LIBC_NAMESPACE __llvm_libc
|
||||
#endif // LIBC_NAMESPACE
|
||||
|
|
|
|||
62
lib/libcxx/libc/src/__support/CPP/bit.h
vendored
62
lib/libcxx/libc/src/__support/CPP/bit.h
vendored
|
|
@ -11,14 +11,14 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/CPP/limits.h" // numeric_limits
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/compiler.h"
|
||||
#include "src/__support/macros/sanitizer.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
|
|
@ -26,6 +26,16 @@ namespace cpp {
|
|||
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
|
||||
#endif
|
||||
|
||||
template <unsigned N>
|
||||
LIBC_INLINE static void inline_copy(const char *from, char *to) {
|
||||
#if __has_builtin(__builtin_memcpy_inline)
|
||||
__builtin_memcpy_inline(to, from, N);
|
||||
#else
|
||||
for (unsigned i = 0; i < N; ++i)
|
||||
to[i] = from[i];
|
||||
#endif // __has_builtin(__builtin_memcpy_inline)
|
||||
}
|
||||
|
||||
// This implementation of bit_cast requires trivially-constructible To, to avoid
|
||||
// UB in the implementation.
|
||||
template <typename To, typename From>
|
||||
|
|
@ -37,22 +47,32 @@ LIBC_INLINE constexpr cpp::enable_if_t<
|
|||
To>
|
||||
bit_cast(const From &from) {
|
||||
MSAN_UNPOISON(&from, sizeof(From));
|
||||
#if __has_builtin(__builtin_bit_cast)
|
||||
#if __has_builtin(__builtin_bit_cast) || defined(LIBC_COMPILER_IS_MSVC)
|
||||
return __builtin_bit_cast(To, from);
|
||||
#else
|
||||
To to;
|
||||
To to{};
|
||||
char *dst = reinterpret_cast<char *>(&to);
|
||||
const char *src = reinterpret_cast<const char *>(&from);
|
||||
#if __has_builtin(__builtin_memcpy_inline)
|
||||
__builtin_memcpy_inline(dst, src, sizeof(To));
|
||||
#else
|
||||
for (unsigned i = 0; i < sizeof(To); ++i)
|
||||
dst[i] = src[i];
|
||||
#endif // __has_builtin(__builtin_memcpy_inline)
|
||||
inline_copy<sizeof(From)>(src, dst);
|
||||
return to;
|
||||
#endif // __has_builtin(__builtin_bit_cast)
|
||||
}
|
||||
|
||||
// The following simple bit copy from a smaller type to maybe-larger type.
|
||||
template <typename To, typename From>
|
||||
LIBC_INLINE constexpr cpp::enable_if_t<
|
||||
(sizeof(To) >= sizeof(From)) &&
|
||||
cpp::is_trivially_constructible<To>::value &&
|
||||
cpp::is_trivially_copyable<To>::value &&
|
||||
cpp::is_trivially_copyable<From>::value,
|
||||
void>
|
||||
bit_copy(const From &from, To &to) {
|
||||
MSAN_UNPOISON(&from, sizeof(From));
|
||||
char *dst = reinterpret_cast<char *>(&to);
|
||||
const char *src = reinterpret_cast<const char *>(&from);
|
||||
inline_copy<sizeof(From)>(src, dst);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
|
||||
bool>
|
||||
|
|
@ -105,10 +125,16 @@ countr_zero(T value) {
|
|||
}
|
||||
#if __has_builtin(__builtin_ctzs)
|
||||
ADD_SPECIALIZATION(countr_zero, unsigned short, __builtin_ctzs)
|
||||
#endif
|
||||
#endif // __has_builtin(__builtin_ctzs)
|
||||
#if __has_builtin(__builtin_ctz)
|
||||
ADD_SPECIALIZATION(countr_zero, unsigned int, __builtin_ctz)
|
||||
#endif // __has_builtin(__builtin_ctz)
|
||||
#if __has_builtin(__builtin_ctzl)
|
||||
ADD_SPECIALIZATION(countr_zero, unsigned long, __builtin_ctzl)
|
||||
#endif // __has_builtin(__builtin_ctzl)
|
||||
#if __has_builtin(__builtin_ctzll)
|
||||
ADD_SPECIALIZATION(countr_zero, unsigned long long, __builtin_ctzll)
|
||||
#endif // __has_builtin(__builtin_ctzll)
|
||||
#endif // __has_builtin(__builtin_ctzg)
|
||||
|
||||
/// Count number of 0's from the most significant bit to the least
|
||||
|
|
@ -144,10 +170,16 @@ countl_zero(T value) {
|
|||
}
|
||||
#if __has_builtin(__builtin_clzs)
|
||||
ADD_SPECIALIZATION(countl_zero, unsigned short, __builtin_clzs)
|
||||
#endif
|
||||
#endif // __has_builtin(__builtin_clzs)
|
||||
#if __has_builtin(__builtin_clz)
|
||||
ADD_SPECIALIZATION(countl_zero, unsigned int, __builtin_clz)
|
||||
#endif // __has_builtin(__builtin_clz)
|
||||
#if __has_builtin(__builtin_clzl)
|
||||
ADD_SPECIALIZATION(countl_zero, unsigned long, __builtin_clzl)
|
||||
#endif // __has_builtin(__builtin_clzl)
|
||||
#if __has_builtin(__builtin_clzll)
|
||||
ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll)
|
||||
#endif // __has_builtin(__builtin_clzll)
|
||||
#endif // __has_builtin(__builtin_clzg)
|
||||
|
||||
#undef ADD_SPECIALIZATION
|
||||
|
|
@ -284,11 +316,17 @@ popcount(T value) {
|
|||
[[nodiscard]] LIBC_INLINE constexpr int popcount<TYPE>(TYPE value) { \
|
||||
return BUILTIN(value); \
|
||||
}
|
||||
#if __has_builtin(__builtin_popcount)
|
||||
ADD_SPECIALIZATION(unsigned char, __builtin_popcount)
|
||||
ADD_SPECIALIZATION(unsigned short, __builtin_popcount)
|
||||
ADD_SPECIALIZATION(unsigned, __builtin_popcount)
|
||||
#endif // __builtin_popcount
|
||||
#if __has_builtin(__builtin_popcountl)
|
||||
ADD_SPECIALIZATION(unsigned long, __builtin_popcountl)
|
||||
#endif // __builtin_popcountl
|
||||
#if __has_builtin(__builtin_popcountll)
|
||||
ADD_SPECIALIZATION(unsigned long long, __builtin_popcountll)
|
||||
#endif // __builtin_popcountll
|
||||
#endif // __builtin_popcountg
|
||||
#undef ADD_SPECIALIZATION
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,17 @@
|
|||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
// LIBC_TYPES_HAS_CFLOAT16 && LIBC_TYPES_HAS_CFLOAT128
|
||||
#include "src/__support/macros/properties/compiler.h"
|
||||
#include "src/__support/macros/properties/complex_types.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
// is_complex
|
||||
#ifdef LIBC_COMPILER_IS_MSVC
|
||||
// TODO: Add support for complex types with MSVC.
|
||||
template <typename T> struct is_complex : false_type {};
|
||||
#else
|
||||
template <typename T> struct is_complex {
|
||||
private:
|
||||
template <typename Head, typename... Args>
|
||||
|
|
@ -40,6 +45,8 @@ public:
|
|||
#endif
|
||||
>();
|
||||
};
|
||||
#endif // LIBC_COMPILER_IS_MSVC
|
||||
|
||||
template <typename T>
|
||||
LIBC_INLINE_VAR constexpr bool is_complex_v = is_complex<T>::value;
|
||||
template <typename T1, typename T2>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/__support/CPP/type_traits/remove_all_extents.h"
|
||||
#include "src/__support/CPP/type_traits/true_type.h"
|
||||
#include "src/__support/CPP/type_traits/type_identity.h"
|
||||
#include "src/__support/CPP/utility/declval.h"
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
|
|
@ -22,7 +23,7 @@ namespace LIBC_NAMESPACE_DECL {
|
|||
namespace cpp {
|
||||
|
||||
// is_destructible
|
||||
#if __has_builtin(__is_destructible)
|
||||
#if __has_builtin(__is_destructible) || defined(LIBC_COMPILER_IS_MSVC)
|
||||
template <typename T>
|
||||
struct is_destructible : bool_constant<__is_destructible(T)> {};
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
|
|
@ -46,6 +48,10 @@ public:
|
|||
LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
|
||||
};
|
||||
#endif // LIBC_COMPILER_HAS_FIXED_POINT
|
||||
#if LIBC_HAS_VECTOR_TYPE
|
||||
template <typename T, size_t N>
|
||||
struct is_unsigned<T [[clang::ext_vector_type(N)]]> : bool_constant<false> {};
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_INTEGER_SEQUENCE_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_INTEGER_SEQUENCE_H
|
||||
|
||||
#include "src/__support/CPP/type_traits/is_integral.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
|
|
@ -34,6 +37,13 @@ template <typename T, int N>
|
|||
using make_integer_sequence =
|
||||
typename detail::make_integer_sequence<T, N - 1>::type;
|
||||
|
||||
// index sequence
|
||||
template <size_t... Ints>
|
||||
using index_sequence = integer_sequence<size_t, Ints...>;
|
||||
template <int N>
|
||||
using make_index_sequence =
|
||||
typename detail::make_integer_sequence<size_t, N - 1>::type;
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
13
lib/libcxx/libc/src/__support/FPUtil/FPBits.h
vendored
13
lib/libcxx/libc/src/__support/FPUtil/FPBits.h
vendored
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/CPP/bit.h"
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
#include "src/__support/common.h"
|
||||
|
|
@ -26,8 +27,6 @@
|
|||
#include "src/__support/sign.h" // Sign
|
||||
#include "src/__support/uint128.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace fputil {
|
||||
|
||||
|
|
@ -790,16 +789,16 @@ struct FPRep : public FPRepImpl<fp_type, FPRep<fp_type>> {
|
|||
// Returns the FPType corresponding to C++ type T on the host.
|
||||
template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
|
||||
using UnqualT = cpp::remove_cv_t<T>;
|
||||
if constexpr (cpp::is_same_v<UnqualT, float> && __FLT_MANT_DIG__ == 24)
|
||||
if constexpr (cpp::is_same_v<UnqualT, float> && FLT_MANT_DIG == 24)
|
||||
return FPType::IEEE754_Binary32;
|
||||
else if constexpr (cpp::is_same_v<UnqualT, double> && __DBL_MANT_DIG__ == 53)
|
||||
else if constexpr (cpp::is_same_v<UnqualT, double> && DBL_MANT_DIG == 53)
|
||||
return FPType::IEEE754_Binary64;
|
||||
else if constexpr (cpp::is_same_v<UnqualT, long double>) {
|
||||
if constexpr (__LDBL_MANT_DIG__ == 53)
|
||||
if constexpr (LDBL_MANT_DIG == 53)
|
||||
return FPType::IEEE754_Binary64;
|
||||
else if constexpr (__LDBL_MANT_DIG__ == 64)
|
||||
else if constexpr (LDBL_MANT_DIG == 64)
|
||||
return FPType::X86_Binary80;
|
||||
else if constexpr (__LDBL_MANT_DIG__ == 113)
|
||||
else if constexpr (LDBL_MANT_DIG == 113)
|
||||
return FPType::IEEE754_Binary128;
|
||||
}
|
||||
#if defined(LIBC_TYPES_HAS_FLOAT16)
|
||||
|
|
|
|||
|
|
@ -10,18 +10,21 @@
|
|||
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_ROUNDING_MODE_H
|
||||
|
||||
#include "hdr/fenv_macros.h"
|
||||
#include "src/__support/CPP/type_traits.h" // is_constant_evaluated
|
||||
#include "src/__support/macros/attributes.h" // LIBC_INLINE
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace fputil {
|
||||
|
||||
namespace generic {
|
||||
|
||||
// Quick free-standing test whether fegetround() == FE_UPWARD.
|
||||
// Using the following observation:
|
||||
// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
|
||||
// = 0x1.000002f for FE_UPWARD.
|
||||
LIBC_INLINE bool fenv_is_round_up() {
|
||||
volatile float x = 0x1.0p-25f;
|
||||
static volatile float x = 0x1.0p-25f;
|
||||
return (1.0f + x != 1.0f);
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +33,7 @@ LIBC_INLINE bool fenv_is_round_up() {
|
|||
// -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO
|
||||
// = -0x1.000002f for FE_DOWNWARD.
|
||||
LIBC_INLINE bool fenv_is_round_down() {
|
||||
volatile float x = 0x1.0p-25f;
|
||||
static volatile float x = 0x1.0p-25f;
|
||||
return (-1.0f - x != -1.0f);
|
||||
}
|
||||
|
||||
|
|
@ -42,8 +45,8 @@ LIBC_INLINE bool fenv_is_round_down() {
|
|||
// = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO
|
||||
LIBC_INLINE bool fenv_is_round_to_nearest() {
|
||||
static volatile float x = 0x1.0p-24f;
|
||||
float y = x;
|
||||
return (1.5f + y == 1.5f - y);
|
||||
float y = 1.5f + x;
|
||||
return (y == 1.5f - x);
|
||||
}
|
||||
|
||||
// Quick free-standing test whether fegetround() == FE_TOWARDZERO.
|
||||
|
|
@ -75,6 +78,49 @@ LIBC_INLINE int quick_get_round() {
|
|||
return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD;
|
||||
}
|
||||
|
||||
} // namespace generic
|
||||
|
||||
LIBC_INLINE static constexpr bool fenv_is_round_up() {
|
||||
if (cpp::is_constant_evaluated()) {
|
||||
return false;
|
||||
} else {
|
||||
return generic::fenv_is_round_up();
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool fenv_is_round_down() {
|
||||
if (cpp::is_constant_evaluated()) {
|
||||
return false;
|
||||
} else {
|
||||
return generic::fenv_is_round_down();
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
|
||||
if (cpp::is_constant_evaluated()) {
|
||||
return true;
|
||||
} else {
|
||||
return generic::fenv_is_round_to_nearest();
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool fenv_is_round_to_zero() {
|
||||
if (cpp::is_constant_evaluated()) {
|
||||
return false;
|
||||
} else {
|
||||
return generic::fenv_is_round_to_zero();
|
||||
}
|
||||
}
|
||||
|
||||
// Quick free standing get rounding mode based on the above observations.
|
||||
LIBC_INLINE static constexpr int quick_get_round() {
|
||||
if (cpp::is_constant_evaluated()) {
|
||||
return FE_TONEAREST;
|
||||
} else {
|
||||
return generic::quick_get_round();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fputil
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
28
lib/libcxx/libc/src/__support/big_int.h
vendored
28
lib/libcxx/libc/src/__support/big_int.h
vendored
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/CPP/array.h"
|
||||
#include "src/__support/CPP/bit.h" // countl_zero
|
||||
#include "src/__support/CPP/limits.h"
|
||||
|
|
@ -23,7 +24,6 @@
|
|||
#include "src/__support/number_pair.h"
|
||||
|
||||
#include <stddef.h> // For size_t
|
||||
#include <stdint.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
@ -95,10 +95,10 @@ LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) {
|
|||
#endif
|
||||
else {
|
||||
using half_word = half_width_t<word>;
|
||||
const auto shiftl = [](word value) -> word {
|
||||
constexpr auto shiftl = [](word value) -> word {
|
||||
return value << cpp::numeric_limits<half_word>::digits;
|
||||
};
|
||||
const auto shiftr = [](word value) -> word {
|
||||
constexpr auto shiftr = [](word value) -> word {
|
||||
return value >> cpp::numeric_limits<half_word>::digits;
|
||||
};
|
||||
// Here we do a one digit multiplication where 'a' and 'b' are of type
|
||||
|
|
@ -111,19 +111,19 @@ LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) {
|
|||
// c result
|
||||
// We convert 'lo' and 'hi' from 'half_word' to 'word' so multiplication
|
||||
// doesn't overflow.
|
||||
const word a_lo = lo(a);
|
||||
const word b_lo = lo(b);
|
||||
const word a_hi = hi(a);
|
||||
const word b_hi = hi(b);
|
||||
const word step1 = b_lo * a_lo; // no overflow;
|
||||
const word step2 = b_lo * a_hi; // no overflow;
|
||||
const word step3 = b_hi * a_lo; // no overflow;
|
||||
const word step4 = b_hi * a_hi; // no overflow;
|
||||
word a_lo = lo(a);
|
||||
word b_lo = lo(b);
|
||||
word a_hi = hi(a);
|
||||
word b_hi = hi(b);
|
||||
word step1 = b_lo * a_lo; // no overflow;
|
||||
word step2 = b_lo * a_hi; // no overflow;
|
||||
word step3 = b_hi * a_lo; // no overflow;
|
||||
word step4 = b_hi * a_hi; // no overflow;
|
||||
word lo_digit = step1;
|
||||
word hi_digit = step4;
|
||||
const word no_carry = 0;
|
||||
word carry;
|
||||
word _; // unused carry variable.
|
||||
word no_carry = 0;
|
||||
word carry = 0;
|
||||
[[maybe_unused]] word _ = 0; // unused carry variable.
|
||||
lo_digit = add_with_carry<word>(lo_digit, shiftl(step2), no_carry, carry);
|
||||
hi_digit = add_with_carry<word>(hi_digit, shiftr(step2), carry, _);
|
||||
lo_digit = add_with_carry<word>(lo_digit, shiftl(step3), no_carry, carry);
|
||||
|
|
|
|||
5
lib/libcxx/libc/src/__support/common.h
vendored
5
lib/libcxx/libc/src/__support/common.h
vendored
|
|
@ -16,6 +16,7 @@
|
|||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/architectures.h"
|
||||
#include "src/__support/macros/properties/compiler.h"
|
||||
|
||||
#ifndef LLVM_LIBC_FUNCTION_ATTR
|
||||
#define LLVM_LIBC_FUNCTION_ATTR
|
||||
|
|
@ -41,12 +42,12 @@
|
|||
// to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C
|
||||
// symbol `func`. So for public packaging on MacOS, we will only export the C
|
||||
// symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`.
|
||||
#if defined(LIBC_COPT_PUBLIC_PACKAGING)
|
||||
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && !defined(LIBC_COMPILER_IS_MSVC)
|
||||
#ifndef __APPLE__
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \
|
||||
LLVM_LIBC_ATTR(name) \
|
||||
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
|
||||
__##name##_impl__ __asm__(#name); \
|
||||
__##name##_impl__ asm(#name); \
|
||||
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
|
||||
type __##name##_impl__ arglist
|
||||
#else // __APPLE__
|
||||
|
|
|
|||
31
lib/libcxx/libc/src/__support/ctype_utils.h
vendored
31
lib/libcxx/libc/src/__support/ctype_utils.h
vendored
|
|
@ -27,7 +27,7 @@ namespace internal {
|
|||
// as well as a way to support non-ASCII character encodings.
|
||||
|
||||
// Similarly, do not change these functions to use case ranges. e.g.
|
||||
// bool islower(int ch) {
|
||||
// bool islower(char ch) {
|
||||
// switch(ch) {
|
||||
// case 'a'...'z':
|
||||
// return true;
|
||||
|
|
@ -37,7 +37,7 @@ namespace internal {
|
|||
// EBCDIC. Technically we could use some smaller ranges, but that's even harder
|
||||
// to read.
|
||||
|
||||
LIBC_INLINE static constexpr bool islower(int ch) {
|
||||
LIBC_INLINE static constexpr bool islower(char ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
|
|
@ -71,7 +71,7 @@ LIBC_INLINE static constexpr bool islower(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isupper(int ch) {
|
||||
LIBC_INLINE static constexpr bool isupper(char ch) {
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
case 'B':
|
||||
|
|
@ -105,7 +105,7 @@ LIBC_INLINE static constexpr bool isupper(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isdigit(int ch) {
|
||||
LIBC_INLINE static constexpr bool isdigit(char ch) {
|
||||
switch (ch) {
|
||||
case '0':
|
||||
case '1':
|
||||
|
|
@ -123,7 +123,7 @@ LIBC_INLINE static constexpr bool isdigit(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr int tolower(int ch) {
|
||||
LIBC_INLINE static constexpr char tolower(char ch) {
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
return 'a';
|
||||
|
|
@ -182,7 +182,7 @@ LIBC_INLINE static constexpr int tolower(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr int toupper(int ch) {
|
||||
LIBC_INLINE static constexpr char toupper(char ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
return 'A';
|
||||
|
|
@ -241,7 +241,7 @@ LIBC_INLINE static constexpr int toupper(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isalpha(int ch) {
|
||||
LIBC_INLINE static constexpr bool isalpha(char ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
|
|
@ -301,7 +301,7 @@ LIBC_INLINE static constexpr bool isalpha(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isalnum(int ch) {
|
||||
LIBC_INLINE static constexpr bool isalnum(char ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
|
|
@ -371,7 +371,7 @@ LIBC_INLINE static constexpr bool isalnum(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr int b36_char_to_int(int ch) {
|
||||
LIBC_INLINE static constexpr int b36_char_to_int(char ch) {
|
||||
switch (ch) {
|
||||
case '0':
|
||||
return 0;
|
||||
|
|
@ -476,7 +476,7 @@ LIBC_INLINE static constexpr int b36_char_to_int(int ch) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr int int_to_b36_char(int num) {
|
||||
LIBC_INLINE static constexpr char int_to_b36_char(int num) {
|
||||
// Can't actually use LIBC_ASSERT here because it depends on integer_to_string
|
||||
// which depends on this.
|
||||
|
||||
|
|
@ -559,7 +559,7 @@ LIBC_INLINE static constexpr int int_to_b36_char(int num) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isspace(int ch) {
|
||||
LIBC_INLINE static constexpr bool isspace(char ch) {
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
|
|
@ -574,10 +574,17 @@ LIBC_INLINE static constexpr bool isspace(int ch) {
|
|||
}
|
||||
|
||||
// not yet encoding independent.
|
||||
LIBC_INLINE static constexpr bool isgraph(int ch) {
|
||||
LIBC_INLINE static constexpr bool isgraph(char ch) {
|
||||
return 0x20 < ch && ch < 0x7f;
|
||||
}
|
||||
|
||||
// An overload which provides a way to compare input with specific character
|
||||
// values, when input can be of a regular or a wide character type.
|
||||
LIBC_INLINE static constexpr bool is_char_or_wchar(char ch, char c_value,
|
||||
[[maybe_unused]] wchar_t) {
|
||||
return (ch == c_value);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_DETAILED_POWERS_OF_TEN_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_DETAILED_POWERS_OF_TEN_H
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/CPP/limits.h"
|
||||
#include "src/__support/ctype_utils.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/str_to_integer.h"
|
||||
#include <stdint.h>
|
||||
#include "src/__support/wctype_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
|
@ -38,6 +39,24 @@ struct LShiftTableEntry {
|
|||
// TODO: Figure out where to put this.
|
||||
enum class RoundDirection { Up, Down, Nearest };
|
||||
|
||||
// These constants are used in both this file and in the main str_to_float.h.
|
||||
// TODO: Figure out where to put this.
|
||||
template <typename CharType> struct constants;
|
||||
template <> struct constants<char> {
|
||||
static constexpr char DECIMAL_POINT = '.';
|
||||
static constexpr char DECIMAL_EXPONENT_MARKER = 'e';
|
||||
static constexpr char HEX_EXPONENT_MARKER = 'p';
|
||||
static constexpr char INF_STRING[] = "infinity";
|
||||
static constexpr char NAN_STRING[] = "nan";
|
||||
};
|
||||
template <> struct constants<wchar_t> {
|
||||
static constexpr wchar_t DECIMAL_POINT = L'.';
|
||||
static constexpr wchar_t DECIMAL_EXPONENT_MARKER = L'e';
|
||||
static constexpr wchar_t HEX_EXPONENT_MARKER = L'p';
|
||||
static constexpr wchar_t INF_STRING[] = L"infinity";
|
||||
static constexpr wchar_t NAN_STRING[] = L"nan";
|
||||
};
|
||||
|
||||
// This is based on the HPD data structure described as part of the Simple
|
||||
// Decimal Conversion algorithm by Nigel Tao, described at this link:
|
||||
// https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
|
||||
|
|
@ -314,9 +333,9 @@ private:
|
|||
public:
|
||||
// num_string is assumed to be a string of numeric characters. It doesn't
|
||||
// handle leading spaces.
|
||||
LIBC_INLINE
|
||||
HighPrecisionDecimal(
|
||||
const char *__restrict num_string,
|
||||
template <typename CharType>
|
||||
LIBC_INLINE HighPrecisionDecimal(
|
||||
const CharType *__restrict num_string,
|
||||
const size_t num_len = cpp::numeric_limits<size_t>::max()) {
|
||||
bool saw_dot = false;
|
||||
size_t num_cur = 0;
|
||||
|
|
@ -324,25 +343,26 @@ public:
|
|||
// them all.
|
||||
uint32_t total_digits = 0;
|
||||
while (num_cur < num_len &&
|
||||
(isdigit(num_string[num_cur]) || num_string[num_cur] == '.')) {
|
||||
if (num_string[num_cur] == '.') {
|
||||
(isdigit(num_string[num_cur]) ||
|
||||
num_string[num_cur] == constants<CharType>::DECIMAL_POINT)) {
|
||||
if (num_string[num_cur] == constants<CharType>::DECIMAL_POINT) {
|
||||
if (saw_dot) {
|
||||
break;
|
||||
}
|
||||
this->decimal_point = static_cast<int32_t>(total_digits);
|
||||
saw_dot = true;
|
||||
} else {
|
||||
if (num_string[num_cur] == '0' && this->num_digits == 0) {
|
||||
int digit = b36_char_to_int(num_string[num_cur]);
|
||||
if (digit == 0 && this->num_digits == 0) {
|
||||
--this->decimal_point;
|
||||
++num_cur;
|
||||
continue;
|
||||
}
|
||||
++total_digits;
|
||||
if (this->num_digits < MAX_NUM_DIGITS) {
|
||||
this->digits[this->num_digits] = static_cast<uint8_t>(
|
||||
internal::b36_char_to_int(num_string[num_cur]));
|
||||
this->digits[this->num_digits] = static_cast<uint8_t>(digit);
|
||||
++this->num_digits;
|
||||
} else if (num_string[num_cur] != '0') {
|
||||
} else if (digit != 0) {
|
||||
this->truncated = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -352,11 +372,10 @@ public:
|
|||
if (!saw_dot)
|
||||
this->decimal_point = static_cast<int32_t>(total_digits);
|
||||
|
||||
if (num_cur < num_len &&
|
||||
(num_string[num_cur] == 'e' || num_string[num_cur] == 'E')) {
|
||||
if (num_cur < num_len && tolower(num_string[num_cur]) ==
|
||||
constants<CharType>::DECIMAL_EXPONENT_MARKER) {
|
||||
++num_cur;
|
||||
if (isdigit(num_string[num_cur]) || num_string[num_cur] == '+' ||
|
||||
num_string[num_cur] == '-') {
|
||||
if (isdigit(num_string[num_cur]) || get_sign(num_string + num_cur) != 0) {
|
||||
auto result =
|
||||
strtointeger<int32_t>(num_string + num_cur, 10, num_len - num_cur);
|
||||
if (result.has_error()) {
|
||||
|
|
|
|||
2
lib/libcxx/libc/src/__support/libc_assert.h
vendored
2
lib/libcxx/libc/src/__support/libc_assert.h
vendored
|
|
@ -14,9 +14,11 @@
|
|||
// The build is configured to just use the public <assert.h> API
|
||||
// for libc's internal assertions.
|
||||
|
||||
#ifndef LIBC_ASSERT
|
||||
#include <assert.h>
|
||||
|
||||
#define LIBC_ASSERT(COND) assert(COND)
|
||||
#endif // LIBC_ASSERT
|
||||
|
||||
#else // Not LIBC_COPT_USE_C_ASSERT
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
|
||||
|
||||
#include "config.h"
|
||||
#include "properties/architectures.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
|
|
@ -28,7 +29,32 @@
|
|||
#define LIBC_INLINE_ASM __asm__ __volatile__
|
||||
#define LIBC_UNUSED __attribute__((unused))
|
||||
|
||||
#ifdef LIBC_TARGET_ARCH_IS_GPU
|
||||
// Uses the platform specific specialization
|
||||
#define LIBC_THREAD_MODE_PLATFORM 0
|
||||
|
||||
// Mutex guards nothing, used in single-threaded implementations
|
||||
#define LIBC_THREAD_MODE_SINGLE 1
|
||||
|
||||
// Vendor provides implementation
|
||||
#define LIBC_THREAD_MODE_EXTERNAL 2
|
||||
|
||||
// libcxx doesn't define LIBC_THREAD_MODE, unless that is passed in the command
|
||||
// line in the CMake invocation. This defaults to the original implementation
|
||||
// (before changes in https://github.com/llvm/llvm-project/pull/145358)
|
||||
#ifndef LIBC_THREAD_MODE
|
||||
#define LIBC_THREAD_MODE LIBC_THREAD_MODE_PLATFORM
|
||||
#endif // LIBC_THREAD_MODE
|
||||
|
||||
#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \
|
||||
LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \
|
||||
LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL
|
||||
#error LIBC_THREAD_MODE must be one of the following values: \
|
||||
LIBC_THREAD_MODE_PLATFORM, \
|
||||
LIBC_THREAD_MODE_SINGLE, \
|
||||
LIBC_THREAD_MODE_EXTERNAL.
|
||||
#endif
|
||||
|
||||
#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE
|
||||
#define LIBC_THREAD_LOCAL
|
||||
#else
|
||||
#define LIBC_THREAD_LOCAL thread_local
|
||||
|
|
@ -48,4 +74,21 @@
|
|||
#define LIBC_PREFERED_TYPE(TYPE)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(ext_vector_type) && \
|
||||
LIBC_HAS_FEATURE(ext_vector_type_boolean)
|
||||
#define LIBC_HAS_VECTOR_TYPE 1
|
||||
#else
|
||||
#define LIBC_HAS_VECTOR_TYPE 0
|
||||
#endif
|
||||
|
||||
#if __has_attribute(no_sanitize)
|
||||
// Disable regular and hardware-supported ASan for functions that may
|
||||
// intentionally make out-of-bounds access. Disable TSan as well, as it detects
|
||||
// out-of-bounds accesses to heap memory.
|
||||
#define LIBC_NO_SANITIZE_OOB_ACCESS \
|
||||
__attribute__((no_sanitize("address", "hwaddress", "thread")))
|
||||
#else
|
||||
#define LIBC_NO_SANITIZE_OOB_ACCESS
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
|
||||
|
|
|
|||
23
lib/libcxx/libc/src/__support/macros/config.h
vendored
23
lib/libcxx/libc/src/__support/macros/config.h
vendored
|
|
@ -13,6 +13,13 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
|
||||
|
||||
#include "src/__support/macros/properties/architectures.h"
|
||||
#include "src/__support/macros/properties/compiler.h"
|
||||
|
||||
#ifdef LIBC_COMPILER_IS_MSVC
|
||||
#include <intrin.h>
|
||||
#endif // LIBC_COMPILER_IS_MSVC
|
||||
|
||||
// Workaround for compilers that do not support builtin detection.
|
||||
// FIXME: This is only required for the GPU portion which should be moved.
|
||||
#ifndef __has_builtin
|
||||
|
|
@ -27,6 +34,22 @@
|
|||
#define LIBC_HAS_FEATURE(f) 0
|
||||
#endif
|
||||
|
||||
#ifdef LIBC_COMPILER_IS_MSVC
|
||||
|
||||
// __builtin_trap replacement
|
||||
#ifdef LIBC_TARGET_ARCH_IS_X86
|
||||
#define __builtin_trap __ud2
|
||||
#else // arm64
|
||||
#define __builtin_trap() __break(1)
|
||||
#endif
|
||||
|
||||
#define __builtin_expect(value, expectation) (value)
|
||||
#define __builtin_unreachable() __assume(0)
|
||||
|
||||
#define __builtin_prefetch(X, Y, Z)
|
||||
|
||||
#endif // LIBC_COMPILER_IS_MSVC
|
||||
|
||||
#ifdef __clang__
|
||||
// Declare a LIBC_NAMESPACE with hidden visibility. `namespace
|
||||
// LIBC_NAMESPACE_DECL {` should be used around all declarations and definitions
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@
|
|||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h"
|
||||
#include "src/__support/macros/sanitizer.h"
|
||||
|
||||
#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
|
||||
#if defined(LIBC_ADD_NULL_CHECKS)
|
||||
#define LIBC_CRASH_ON_NULLPTR(ptr) \
|
||||
do { \
|
||||
if (LIBC_UNLIKELY((ptr) == nullptr)) \
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
|
|||
#elif defined(LIBC_COMPILER_IS_GCC)
|
||||
#define LIBC_LOOP_NOUNROLL _Pragma("GCC unroll 0")
|
||||
#define LIBC_LOOP_UNROLL _Pragma("GCC unroll 2048")
|
||||
#elif defined(LIBC_COMPILER_IS_MSVC)
|
||||
#define LIBC_LOOP_NOUNROLL
|
||||
#define LIBC_LOOP_UNROLL
|
||||
#else
|
||||
#error "Unhandled compiler"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#define LIBC_TARGET_ARCH_IS_GPU
|
||||
#endif
|
||||
|
||||
#if defined(__pnacl__) || defined(__CLR_VER) || defined(LIBC_TARGET_ARCH_IS_GPU)
|
||||
#if defined(__CLR_VER) || defined(LIBC_TARGET_ARCH_IS_GPU)
|
||||
#define LIBC_TARGET_ARCH_IS_VM
|
||||
#endif
|
||||
|
||||
|
|
@ -41,6 +41,10 @@
|
|||
#define LIBC_TARGET_ARCH_IS_ARM
|
||||
#endif
|
||||
|
||||
#if defined(__wasm__)
|
||||
#define LIBC_TARGET_ARCH_IS_WASM
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
|
||||
#define LIBC_TARGET_ARCH_IS_AARCH64
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,10 +34,15 @@
|
|||
#define LIBC_COMPILER_GCC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define LIBC_COMPILER_IS_MSC
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define LIBC_COMPILER_IS_MSVC
|
||||
// https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros
|
||||
#define LIBC_COMPILER_MSC_VER (_MSC_VER)
|
||||
#define LIBC_COMPILER_MSVC_VER (_MSC_VER)
|
||||
#ifdef _M_X64
|
||||
#define LIBC_COMPILER_IS_MSVC_X64
|
||||
#else
|
||||
#define LIBC_COMPILER_IS_MSVC_X86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_COMPILER_H
|
||||
|
|
|
|||
|
|
@ -18,6 +18,18 @@
|
|||
#define LIBC_TARGET_CPU_HAS_FULLFP16
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_SVE)
|
||||
#define LIBC_TARGET_CPU_HAS_SVE
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_SVE2)
|
||||
#define LIBC_TARGET_CPU_HAS_SVE2
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_MOPS)
|
||||
#define LIBC_TARGET_CPU_HAS_MOPS
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#define LIBC_TARGET_CPU_HAS_SSE2
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
|
||||
|
|
@ -59,6 +71,10 @@
|
|||
#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
|
||||
#endif // __ARM_FP
|
||||
|
||||
#if defined(__ARM_NEON)
|
||||
#define LIBC_TARGET_CPU_HAS_ARM_NEON
|
||||
#endif
|
||||
|
||||
#if defined(__riscv_flen)
|
||||
// https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc
|
||||
#if defined(__riscv_zfhmin)
|
||||
|
|
@ -81,7 +97,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_FMA) || (defined(__AVX2__) && defined(__FMA__)) || \
|
||||
defined(__NVPTX__) || defined(__AMDGPU__) || defined(__LIBC_RISCV_USE_FMA)
|
||||
defined(__NVPTX__) || defined(__AMDGPU__) || defined(__riscv_flen)
|
||||
#define LIBC_TARGET_CPU_HAS_FMA
|
||||
// Provide a more fine-grained control of FMA instruction for ARM targets.
|
||||
#if defined(LIBC_TARGET_CPU_HAS_FPU_HALF)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
|
||||
|
||||
#include "hdr/float_macros.h" // LDBL_MANT_DIG
|
||||
#include "hdr/float_macros.h" // LDBL_MANT_DIG
|
||||
#include "hdr/stdint_proxy.h" // UINT64_MAX, __SIZEOF_INT128__
|
||||
#include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16
|
||||
#include "include/llvm-libc-types/float128.h" // float128
|
||||
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
|
||||
|
|
@ -19,8 +20,6 @@
|
|||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
#include "src/__support/macros/properties/os.h"
|
||||
|
||||
#include <stdint.h> // UINT64_MAX, __SIZEOF_INT128__
|
||||
|
||||
// 'long double' properties.
|
||||
#if (LDBL_MANT_DIG == 53)
|
||||
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
|
||||
|
|
|
|||
10
lib/libcxx/libc/src/__support/macros/sanitizer.h
vendored
10
lib/libcxx/libc/src/__support/macros/sanitizer.h
vendored
|
|
@ -23,16 +23,6 @@
|
|||
#define LIBC_HAS_MEMORY_SANITIZER
|
||||
#endif
|
||||
|
||||
#if LIBC_HAS_FEATURE(undefined_behavior_sanitizer)
|
||||
#define LIBC_HAS_UNDEFINED_BEHAVIOR_SANITIZER
|
||||
#endif
|
||||
|
||||
#if defined(LIBC_HAS_ADDRESS_SANITIZER) || \
|
||||
defined(LIBC_HAS_MEMORY_SANITIZER) || \
|
||||
defined(LIBC_HAS_UNDEFINED_BEHAVIOR_SANITIZER)
|
||||
#define LIBC_HAS_SANITIZER
|
||||
#endif
|
||||
|
||||
#ifdef LIBC_HAS_MEMORY_SANITIZER
|
||||
// Only perform MSAN unpoison in non-constexpr context.
|
||||
#include <sanitizer/msan_interface.h>
|
||||
|
|
|
|||
24
lib/libcxx/libc/src/__support/math_extras.h
vendored
24
lib/libcxx/libc/src/__support/math_extras.h
vendored
|
|
@ -25,7 +25,13 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
|
|||
mask_trailing_ones() {
|
||||
constexpr unsigned T_BITS = CHAR_BIT * sizeof(T);
|
||||
static_assert(count <= T_BITS && "Invalid bit index");
|
||||
return count == 0 ? 0 : (T(-1) >> (T_BITS - count));
|
||||
// MSVC complains about out of range shifts.
|
||||
if constexpr (count == 0)
|
||||
return 0;
|
||||
else if constexpr (count >= T_BITS)
|
||||
return T(-1);
|
||||
else
|
||||
return T(-1) >> (T_BITS - count);
|
||||
}
|
||||
|
||||
// Create a bitmask with the count left-most bits set to 1, and all other bits
|
||||
|
|
@ -55,18 +61,28 @@ mask_leading_zeros() {
|
|||
// Returns whether 'a + b' overflows, the result is stored in 'res'.
|
||||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr bool add_overflow(T a, T b, T &res) {
|
||||
#if __has_builtin(__builtin_add_overflow)
|
||||
return __builtin_add_overflow(a, b, &res);
|
||||
#else
|
||||
res = a + b;
|
||||
return (res < a) || (res < b);
|
||||
#endif // __builtin_add_overflow
|
||||
}
|
||||
|
||||
// Returns whether 'a - b' overflows, the result is stored in 'res'.
|
||||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr bool sub_overflow(T a, T b, T &res) {
|
||||
#if __has_builtin(__builtin_sub_overflow)
|
||||
return __builtin_sub_overflow(a, b, &res);
|
||||
#else
|
||||
res = a - b;
|
||||
return (res > a);
|
||||
#endif // __builtin_sub_overflow
|
||||
}
|
||||
|
||||
#define RETURN_IF(TYPE, BUILTIN) \
|
||||
if constexpr (cpp::is_same_v<T, TYPE>) \
|
||||
return BUILTIN(a, b, carry_in, carry_out);
|
||||
return BUILTIN(a, b, carry_in, &carry_out);
|
||||
|
||||
// Returns the result of 'a + b' taking into account 'carry_in'.
|
||||
// The carry out is stored in 'carry_out' it not 'nullptr', dropped otherwise.
|
||||
|
|
@ -74,7 +90,7 @@ template <typename T>
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
|
||||
add_with_carry(T a, T b, T carry_in, T &carry_out) {
|
||||
if constexpr (!cpp::is_constant_evaluated()) {
|
||||
if (!cpp::is_constant_evaluated()) {
|
||||
#if __has_builtin(__builtin_addcb)
|
||||
RETURN_IF(unsigned char, __builtin_addcb)
|
||||
#elif __has_builtin(__builtin_addcs)
|
||||
|
|
@ -100,7 +116,7 @@ add_with_carry(T a, T b, T carry_in, T &carry_out) {
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
|
||||
sub_with_borrow(T a, T b, T carry_in, T &carry_out) {
|
||||
if constexpr (!cpp::is_constant_evaluated()) {
|
||||
if (!cpp::is_constant_evaluated()) {
|
||||
#if __has_builtin(__builtin_subcb)
|
||||
RETURN_IF(unsigned char, __builtin_subcb)
|
||||
#elif __has_builtin(__builtin_subcs)
|
||||
|
|
|
|||
223
lib/libcxx/libc/src/__support/str_to_float.h
vendored
223
lib/libcxx/libc/src/__support/str_to_float.h
vendored
|
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
|
||||
|
||||
#include "hdr/errno_macros.h" // For ERANGE
|
||||
#include "hdr/stdint_proxy.h"
|
||||
#include "src/__support/CPP/bit.h"
|
||||
#include "src/__support/CPP/limits.h"
|
||||
#include "src/__support/CPP/optional.h"
|
||||
|
|
@ -32,8 +33,7 @@
|
|||
#include "src/__support/str_to_integer.h"
|
||||
#include "src/__support/str_to_num_result.h"
|
||||
#include "src/__support/uint128.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include "src/__support/wctype_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
|
@ -335,9 +335,9 @@ constexpr int32_t NUM_POWERS_OF_TWO =
|
|||
// the Eisel-Lemire algorithm fails, it's slower but more accurate. It's based
|
||||
// on the Simple Decimal Conversion algorithm by Nigel Tao, described at this
|
||||
// link: https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
|
||||
template <class T>
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE FloatConvertReturn<T> simple_decimal_conversion(
|
||||
const char *__restrict numStart,
|
||||
const CharType *__restrict numStart,
|
||||
const size_t num_len = cpp::numeric_limits<size_t>::max(),
|
||||
RoundDirection round = RoundDirection::Nearest) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
|
|
@ -677,12 +677,11 @@ template <> LIBC_INLINE constexpr int32_t get_lower_bound<double>() {
|
|||
// Takes a mantissa and base 10 exponent and converts it into its closest
|
||||
// floating point type T equivalient. First we try the Eisel-Lemire algorithm,
|
||||
// then if that fails then we fall back to a more accurate algorithm for
|
||||
// accuracy. The resulting mantissa and exponent are placed in outputMantissa
|
||||
// and outputExp2.
|
||||
template <class T>
|
||||
// accuracy.
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE FloatConvertReturn<T> decimal_exp_to_float(
|
||||
ExpandedFloat<T> init_num, bool truncated, RoundDirection round,
|
||||
const char *__restrict numStart,
|
||||
const CharType *__restrict numStart,
|
||||
const size_t num_len = cpp::numeric_limits<size_t>::max()) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
|
@ -861,36 +860,42 @@ LIBC_INLINE FloatConvertReturn<T> binary_exp_to_float(ExpandedFloat<T> init_num,
|
|||
return output;
|
||||
}
|
||||
|
||||
// checks if the next 4 characters of the string pointer are the start of a
|
||||
// Checks if the first characters of the string pointer are the start of a
|
||||
// hexadecimal floating point number. Does not advance the string pointer.
|
||||
LIBC_INLINE bool is_float_hex_start(const char *__restrict src,
|
||||
const char decimalPoint) {
|
||||
if (!(src[0] == '0' && tolower(src[1]) == 'x')) {
|
||||
template <typename CharType>
|
||||
LIBC_INLINE static bool is_float_hex_start(const CharType *__restrict src) {
|
||||
if (!is_char_or_wchar(src[0], '0', L'0') ||
|
||||
!is_char_or_wchar(tolower(src[1]), 'x', L'x')) {
|
||||
return false;
|
||||
}
|
||||
size_t first_digit = 2;
|
||||
if (src[2] == decimalPoint) {
|
||||
if (src[2] == constants<CharType>::DECIMAL_POINT) {
|
||||
++first_digit;
|
||||
}
|
||||
return isalnum(src[first_digit]) && b36_char_to_int(src[first_digit]) < 16;
|
||||
}
|
||||
|
||||
// Takes the start of a string representing a decimal float, as well as the
|
||||
// local decimalPoint. It returns if it suceeded in parsing any digits, and if
|
||||
// the return value is true then the outputs are pointer to the end of the
|
||||
// number, and the mantissa and exponent for the closest float T representation.
|
||||
// If the return value is false, then it is assumed that there is no number
|
||||
// here.
|
||||
template <class T>
|
||||
LIBC_INLINE StrToNumResult<ExpandedFloat<T>>
|
||||
decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
||||
RoundDirection round) {
|
||||
// Verifies that first prefix_len characters of str, when lowercased, match the
|
||||
// specified prefix.
|
||||
template <typename CharType>
|
||||
LIBC_INLINE static bool tolower_starts_with(const CharType *str,
|
||||
size_t prefix_len,
|
||||
const CharType *prefix) {
|
||||
for (size_t i = 0; i < prefix_len; ++i) {
|
||||
if (tolower(str[i]) != prefix[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempts parsing a decimal floating point number at the start of the string.
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE static StrToNumResult<ExpandedFloat<T>>
|
||||
decimal_string_to_float(const CharType *__restrict src, RoundDirection round) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
||||
constexpr uint32_t BASE = 10;
|
||||
constexpr char EXPONENT_MARKER = 'e';
|
||||
|
||||
bool truncated = false;
|
||||
bool seen_digit = false;
|
||||
bool after_decimal = false;
|
||||
|
|
@ -927,7 +932,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
|||
++index;
|
||||
continue;
|
||||
}
|
||||
if (src[index] == DECIMAL_POINT) {
|
||||
if (src[index] == constants<CharType>::DECIMAL_POINT) {
|
||||
if (after_decimal) {
|
||||
break; // this means that src[index] points to a second decimal point,
|
||||
// ending the number.
|
||||
|
|
@ -944,13 +949,10 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
|||
return output;
|
||||
|
||||
// TODO: When adding max length argument, handle the case of a trailing
|
||||
// EXPONENT MARKER, see scanf for more details.
|
||||
if (tolower(src[index]) == EXPONENT_MARKER) {
|
||||
bool has_sign = false;
|
||||
if (src[index + 1] == '+' || src[index + 1] == '-') {
|
||||
has_sign = true;
|
||||
}
|
||||
if (isdigit(src[index + 1 + static_cast<size_t>(has_sign)])) {
|
||||
// exponent marker, see scanf for more details.
|
||||
if (tolower(src[index]) == constants<CharType>::DECIMAL_EXPONENT_MARKER) {
|
||||
int sign = get_sign(src + index + 1);
|
||||
if (isdigit(src[index + 1 + static_cast<size_t>(sign != 0)])) {
|
||||
++index;
|
||||
auto result = strtointeger<int32_t>(src + index, 10);
|
||||
if (result.has_error())
|
||||
|
|
@ -986,22 +988,16 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
|||
return output;
|
||||
}
|
||||
|
||||
// Takes the start of a string representing a hexadecimal float, as well as the
|
||||
// local decimal point. It returns if it suceeded in parsing any digits, and if
|
||||
// the return value is true then the outputs are pointer to the end of the
|
||||
// number, and the mantissa and exponent for the closest float T representation.
|
||||
// If the return value is false, then it is assumed that there is no number
|
||||
// here.
|
||||
template <class T>
|
||||
LIBC_INLINE StrToNumResult<ExpandedFloat<T>>
|
||||
hexadecimal_string_to_float(const char *__restrict src,
|
||||
const char DECIMAL_POINT, RoundDirection round) {
|
||||
// Attempts parsing a hexadecimal floating point number at the start of the
|
||||
// string.
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE static StrToNumResult<ExpandedFloat<T>>
|
||||
hexadecimal_string_to_float(const CharType *__restrict src,
|
||||
RoundDirection round) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
||||
constexpr uint32_t BASE = 16;
|
||||
constexpr char EXPONENT_MARKER = 'p';
|
||||
|
||||
bool truncated = false;
|
||||
bool seen_digit = false;
|
||||
bool after_decimal = false;
|
||||
|
|
@ -1039,7 +1035,7 @@ hexadecimal_string_to_float(const char *__restrict src,
|
|||
++index;
|
||||
continue;
|
||||
}
|
||||
if (src[index] == DECIMAL_POINT) {
|
||||
if (src[index] == constants<CharType>::DECIMAL_POINT) {
|
||||
if (after_decimal) {
|
||||
break; // this means that src[index] points to a second decimal point,
|
||||
// ending the number.
|
||||
|
|
@ -1058,12 +1054,9 @@ hexadecimal_string_to_float(const char *__restrict src,
|
|||
// Convert the exponent from having a base of 16 to having a base of 2.
|
||||
exponent *= 4;
|
||||
|
||||
if (tolower(src[index]) == EXPONENT_MARKER) {
|
||||
bool has_sign = false;
|
||||
if (src[index + 1] == '+' || src[index + 1] == '-') {
|
||||
has_sign = true;
|
||||
}
|
||||
if (isdigit(src[index + 1 + static_cast<size_t>(has_sign)])) {
|
||||
if (tolower(src[index]) == constants<CharType>::HEX_EXPONENT_MARKER) {
|
||||
int sign = get_sign(src + index + 1);
|
||||
if (isdigit(src[index + 1 + static_cast<size_t>(sign != 0)])) {
|
||||
++index;
|
||||
auto result = strtointeger<int32_t>(src + index, 10);
|
||||
if (result.has_error())
|
||||
|
|
@ -1099,21 +1092,21 @@ hexadecimal_string_to_float(const char *__restrict src,
|
|||
return output;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE typename fputil::FPBits<T>::StorageType
|
||||
nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) {
|
||||
nan_mantissa_from_ncharseq(const CharType *str, size_t len) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
||||
StorageType nan_mantissa = 0;
|
||||
|
||||
if (ncharseq.data() != nullptr && isdigit(ncharseq[0])) {
|
||||
if (len > 0 && isdigit(str[0])) {
|
||||
StrToNumResult<StorageType> strtoint_result =
|
||||
strtointeger<StorageType>(ncharseq.data(), 0);
|
||||
strtointeger<StorageType>(str, 0, len);
|
||||
if (!strtoint_result.has_error())
|
||||
nan_mantissa = strtoint_result.value;
|
||||
|
||||
if (strtoint_result.parsed_len != static_cast<ptrdiff_t>(ncharseq.size()))
|
||||
if (strtoint_result.parsed_len != static_cast<ptrdiff_t>(len))
|
||||
nan_mantissa = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1124,59 +1117,44 @@ nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) {
|
|||
// is used as the backend for all of the string to float functions.
|
||||
// TODO: Add src_len member to match strtointeger.
|
||||
// TODO: Next, move from char* and length to string_view
|
||||
template <class T>
|
||||
LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE StrToNumResult<T>
|
||||
strtofloatingpoint(const CharType *__restrict src) {
|
||||
using FPBits = typename fputil::FPBits<T>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
||||
FPBits result = FPBits();
|
||||
bool seen_digit = false;
|
||||
char sign = '+';
|
||||
|
||||
int error = 0;
|
||||
|
||||
size_t index = first_non_whitespace(src);
|
||||
int sign = get_sign(src + index);
|
||||
bool is_positive = (sign >= 0);
|
||||
index += (sign != 0);
|
||||
|
||||
if (src[index] == '+' || src[index] == '-') {
|
||||
sign = src[index];
|
||||
++index;
|
||||
}
|
||||
|
||||
if (sign == '-') {
|
||||
if (sign < 0) {
|
||||
result.set_sign(Sign::NEG);
|
||||
}
|
||||
|
||||
static constexpr char DECIMAL_POINT = '.';
|
||||
static const char *inf_string = "infinity";
|
||||
static const char *nan_string = "nan";
|
||||
|
||||
if (isdigit(src[index]) || src[index] == DECIMAL_POINT) { // regular number
|
||||
if (isdigit(src[index]) ||
|
||||
src[index] == constants<CharType>::DECIMAL_POINT) { // regular number
|
||||
int base = 10;
|
||||
if (is_float_hex_start(src + index, DECIMAL_POINT)) {
|
||||
if (is_float_hex_start(src + index)) {
|
||||
base = 16;
|
||||
index += 2;
|
||||
seen_digit = true;
|
||||
}
|
||||
|
||||
RoundDirection round_direction = RoundDirection::Nearest;
|
||||
|
||||
switch (fputil::quick_get_round()) {
|
||||
case FE_TONEAREST:
|
||||
round_direction = RoundDirection::Nearest;
|
||||
break;
|
||||
case FE_UPWARD:
|
||||
if (sign == '+') {
|
||||
round_direction = RoundDirection::Up;
|
||||
} else {
|
||||
round_direction = RoundDirection::Down;
|
||||
}
|
||||
round_direction = is_positive ? RoundDirection::Up : RoundDirection::Down;
|
||||
break;
|
||||
case FE_DOWNWARD:
|
||||
if (sign == '+') {
|
||||
round_direction = RoundDirection::Down;
|
||||
} else {
|
||||
round_direction = RoundDirection::Up;
|
||||
}
|
||||
round_direction = is_positive ? RoundDirection::Down : RoundDirection::Up;
|
||||
break;
|
||||
case FE_TOWARDZERO:
|
||||
round_direction = RoundDirection::Down;
|
||||
|
|
@ -1185,58 +1163,53 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
|
|||
|
||||
StrToNumResult<ExpandedFloat<T>> parse_result({0, 0});
|
||||
if (base == 16) {
|
||||
parse_result = hexadecimal_string_to_float<T>(src + index, DECIMAL_POINT,
|
||||
round_direction);
|
||||
parse_result =
|
||||
hexadecimal_string_to_float<T>(src + index, round_direction);
|
||||
} else { // base is 10
|
||||
parse_result = decimal_string_to_float<T>(src + index, DECIMAL_POINT,
|
||||
round_direction);
|
||||
parse_result = decimal_string_to_float<T>(src + index, round_direction);
|
||||
}
|
||||
seen_digit = parse_result.parsed_len != 0;
|
||||
result.set_mantissa(parse_result.value.mantissa);
|
||||
result.set_biased_exponent(parse_result.value.exponent);
|
||||
index += parse_result.parsed_len;
|
||||
error = parse_result.error;
|
||||
} else if (tolower(src[index]) == 'n') { // NaN
|
||||
if (tolower(src[index + 1]) == nan_string[1] &&
|
||||
tolower(src[index + 2]) == nan_string[2]) {
|
||||
seen_digit = true;
|
||||
index += 3;
|
||||
StorageType nan_mantissa = 0;
|
||||
// this handles the case of `NaN(n-character-sequence)`, where the
|
||||
// n-character-sequence is made of 0 or more letters, numbers, or
|
||||
// underscore characters in any order.
|
||||
if (src[index] == '(') {
|
||||
size_t left_paren = index;
|
||||
} else if (tolower_starts_with(src + index, 3,
|
||||
constants<CharType>::NAN_STRING)) {
|
||||
// NAN
|
||||
seen_digit = true;
|
||||
index += 3;
|
||||
StorageType nan_mantissa = 0;
|
||||
// this handles the case of `NaN(n-character-sequence)`, where the
|
||||
// n-character-sequence is made of 0 or more letters, numbers, or
|
||||
// underscore characters in any order.
|
||||
if (is_char_or_wchar(src[index], '(', L'(')) {
|
||||
size_t left_paren = index;
|
||||
++index;
|
||||
while (isalnum(src[index]) || is_char_or_wchar(src[index], '_', L'_'))
|
||||
++index;
|
||||
while (isalnum(src[index]) || src[index] == '_')
|
||||
++index;
|
||||
if (src[index] == ')') {
|
||||
++index;
|
||||
nan_mantissa = nan_mantissa_from_ncharseq<T>(
|
||||
cpp::string_view(src + (left_paren + 1), index - left_paren - 2));
|
||||
} else {
|
||||
index = left_paren;
|
||||
}
|
||||
}
|
||||
result = FPBits(result.quiet_nan(result.sign(), nan_mantissa));
|
||||
}
|
||||
} else if (tolower(src[index]) == 'i') { // INF
|
||||
if (tolower(src[index + 1]) == inf_string[1] &&
|
||||
tolower(src[index + 2]) == inf_string[2]) {
|
||||
seen_digit = true;
|
||||
result = FPBits(result.inf(result.sign()));
|
||||
if (tolower(src[index + 3]) == inf_string[3] &&
|
||||
tolower(src[index + 4]) == inf_string[4] &&
|
||||
tolower(src[index + 5]) == inf_string[5] &&
|
||||
tolower(src[index + 6]) == inf_string[6] &&
|
||||
tolower(src[index + 7]) == inf_string[7]) {
|
||||
// if the string is "INFINITY" then consume 8 characters.
|
||||
index += 8;
|
||||
if (is_char_or_wchar(src[index], ')', L')')) {
|
||||
++index;
|
||||
nan_mantissa = nan_mantissa_from_ncharseq<T>(src + (left_paren + 1),
|
||||
index - left_paren - 2);
|
||||
} else {
|
||||
index += 3;
|
||||
index = left_paren;
|
||||
}
|
||||
}
|
||||
result = FPBits(result.quiet_nan(result.sign(), nan_mantissa));
|
||||
} else if (tolower_starts_with(src + index, 8,
|
||||
constants<CharType>::INF_STRING)) {
|
||||
// INFINITY
|
||||
seen_digit = true;
|
||||
result = FPBits(result.inf(result.sign()));
|
||||
index += 8;
|
||||
} else if (tolower_starts_with(src + index, 3,
|
||||
constants<CharType>::INF_STRING)) {
|
||||
// INF
|
||||
seen_digit = true;
|
||||
result = FPBits(result.inf(result.sign()));
|
||||
index += 3;
|
||||
}
|
||||
|
||||
if (!seen_digit) { // If there is nothing to actually parse, then return 0.
|
||||
return {T(0), 0, error};
|
||||
}
|
||||
|
|
@ -1263,7 +1236,7 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
|
|||
++index;
|
||||
|
||||
if (arg[index] == '\0')
|
||||
nan_mantissa = nan_mantissa_from_ncharseq<T>(cpp::string_view(arg, index));
|
||||
nan_mantissa = nan_mantissa_from_ncharseq<T>(arg, index);
|
||||
|
||||
result = FPBits::quiet_nan(Sign::POS, nan_mantissa);
|
||||
return {result.get_val(), 0, error};
|
||||
|
|
|
|||
66
lib/libcxx/libc/src/__support/str_to_integer.h
vendored
66
lib/libcxx/libc/src/__support/str_to_integer.h
vendored
|
|
@ -25,36 +25,51 @@
|
|||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/str_to_num_result.h"
|
||||
#include "src/__support/uint128.h"
|
||||
#include "src/__support/wctype_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
||||
// Returns the idx to the first character in src that is not a whitespace
|
||||
// character (as determined by isspace())
|
||||
template <typename CharType>
|
||||
LIBC_INLINE size_t
|
||||
first_non_whitespace(const char *__restrict src,
|
||||
first_non_whitespace(const CharType *__restrict src,
|
||||
size_t src_len = cpp::numeric_limits<size_t>::max()) {
|
||||
size_t src_cur = 0;
|
||||
while (src_cur < src_len && internal::isspace(src[src_cur])) {
|
||||
++src_cur;
|
||||
}
|
||||
for (; src_cur < src_len && internal::isspace(src[src_cur]); ++src_cur)
|
||||
;
|
||||
return src_cur;
|
||||
}
|
||||
|
||||
// Returns +1, -1, or 0 if 'src' starts with (respectively)
|
||||
// plus sign, minus sign, or neither.
|
||||
template <typename CharType>
|
||||
LIBC_INLINE static int get_sign(const CharType *__restrict src) {
|
||||
if (is_char_or_wchar(src[0], '+', L'+'))
|
||||
return 1;
|
||||
if (is_char_or_wchar(src[0], '-', L'-'))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// checks if the next 3 characters of the string pointer are the start of a
|
||||
// hexadecimal number. Does not advance the string pointer.
|
||||
LIBC_INLINE bool
|
||||
is_hex_start(const char *__restrict src,
|
||||
size_t src_len = cpp::numeric_limits<size_t>::max()) {
|
||||
template <typename CharType>
|
||||
LIBC_INLINE static bool is_hex_start(const CharType *__restrict src,
|
||||
size_t src_len) {
|
||||
if (src_len < 3)
|
||||
return false;
|
||||
return *src == '0' && tolower(*(src + 1)) == 'x' && isalnum(*(src + 2)) &&
|
||||
b36_char_to_int(*(src + 2)) < 16;
|
||||
return is_char_or_wchar(src[0], '0', L'0') &&
|
||||
is_char_or_wchar(tolower(src[1]), 'x', L'x') && isalnum(src[2]) &&
|
||||
b36_char_to_int(src[2]) < 16;
|
||||
}
|
||||
|
||||
// Takes the address of the string pointer and parses the base from the start of
|
||||
// it.
|
||||
LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) {
|
||||
template <typename CharType>
|
||||
LIBC_INLINE static int infer_base(const CharType *__restrict src,
|
||||
size_t src_len) {
|
||||
// A hexadecimal number is defined as "the prefix 0x or 0X followed by a
|
||||
// sequence of the decimal digits and the letters a (or A) through f (or F)
|
||||
// with values 10 through 15 respectively." (C standard 6.4.4.1)
|
||||
|
|
@ -63,8 +78,9 @@ LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) {
|
|||
// An octal number is defined as "the prefix 0 optionally followed by a
|
||||
// sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any
|
||||
// number that starts with 0, including just 0, is an octal number.
|
||||
if (src_len > 0 && src[0] == '0')
|
||||
if (src_len > 0 && is_char_or_wchar(src[0], '0', L'0')) {
|
||||
return 8;
|
||||
}
|
||||
// A decimal number is defined as beginning "with a nonzero digit and
|
||||
// consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1)
|
||||
return 10;
|
||||
|
|
@ -77,32 +93,27 @@ LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) {
|
|||
// -----------------------------------------------------------------------------
|
||||
// Takes a pointer to a string and the base to convert to. This function is used
|
||||
// as the backend for all of the string to int functions.
|
||||
template <class T>
|
||||
template <typename T, typename CharType>
|
||||
LIBC_INLINE StrToNumResult<T>
|
||||
strtointeger(const char *__restrict src, int base,
|
||||
strtointeger(const CharType *__restrict src, int base,
|
||||
const size_t src_len = cpp::numeric_limits<size_t>::max()) {
|
||||
using ResultType = make_integral_or_big_int_unsigned_t<T>;
|
||||
|
||||
ResultType result = 0;
|
||||
|
||||
bool is_number = false;
|
||||
size_t src_cur = 0;
|
||||
int error_val = 0;
|
||||
|
||||
if (src_len == 0)
|
||||
return {0, 0, 0};
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
return {0, 0, EINVAL};
|
||||
|
||||
src_cur = first_non_whitespace(src, src_len);
|
||||
|
||||
char result_sign = '+';
|
||||
if (src[src_cur] == '+' || src[src_cur] == '-') {
|
||||
result_sign = src[src_cur];
|
||||
++src_cur;
|
||||
size_t src_cur = first_non_whitespace(src, src_len);
|
||||
if (src_cur == src_len) {
|
||||
return {0, 0, 0};
|
||||
}
|
||||
|
||||
int sign = get_sign(src + src_cur);
|
||||
bool is_positive = (sign >= 0);
|
||||
src_cur += (sign != 0);
|
||||
|
||||
if (base == 0)
|
||||
base = infer_base(src + src_cur, src_len - src_cur);
|
||||
|
||||
|
|
@ -110,8 +121,6 @@ strtointeger(const char *__restrict src, int base,
|
|||
src_cur = src_cur + 2;
|
||||
|
||||
constexpr bool IS_UNSIGNED = cpp::is_unsigned_v<T>;
|
||||
const bool is_positive = (result_sign == '+');
|
||||
|
||||
ResultType constexpr NEGATIVE_MAX =
|
||||
!IS_UNSIGNED ? static_cast<ResultType>(cpp::numeric_limits<T>::max()) + 1
|
||||
: cpp::numeric_limits<T>::max();
|
||||
|
|
@ -120,6 +129,9 @@ strtointeger(const char *__restrict src, int base,
|
|||
ResultType const abs_max_div_by_base =
|
||||
abs_max / static_cast<ResultType>(base);
|
||||
|
||||
bool is_number = false;
|
||||
int error_val = 0;
|
||||
ResultType result = 0;
|
||||
while (src_cur < src_len && isalnum(src[src_cur])) {
|
||||
int cur_digit = b36_char_to_int(src[src_cur]);
|
||||
if (cur_digit >= base)
|
||||
|
|
|
|||
588
lib/libcxx/libc/src/__support/wctype_utils.h
vendored
Normal file
588
lib/libcxx/libc/src/__support/wctype_utils.h
vendored
Normal file
|
|
@ -0,0 +1,588 @@
|
|||
//===-- Collection of utils for implementing wide char 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
|
||||
|
||||
#include "hdr/types/wchar_t.h"
|
||||
#include "src/__support/macros/attributes.h" // LIBC_INLINE
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ****************** WARNING ******************
|
||||
// ****************** DO NOT TRY TO OPTIMIZE THESE FUNCTIONS! ******************
|
||||
// -----------------------------------------------------------------------------
|
||||
// This switch/case form is easier for the compiler to understand, and is
|
||||
// optimized into a form that is almost always the same as or better than
|
||||
// versions written by hand (see https://godbolt.org/z/qvrebqvvr). Also this
|
||||
// form makes these functions encoding independent. If you want to rewrite these
|
||||
// functions, make sure you have benchmarks to show your new solution is faster,
|
||||
// as well as a way to support non-ASCII character encodings.
|
||||
|
||||
// Similarly, do not change these fumarks to show your new solution is faster,
|
||||
// as well as a way to support non-Anctions to use case ranges. e.g.
|
||||
// bool islower(wchar_t ch) {
|
||||
// switch(ch) {
|
||||
// case L'a'...L'z':
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// This assumes the character ranges are contiguous, which they aren't in
|
||||
// EBCDIC. Technically we could use some smaller ranges, but that's even harder
|
||||
// to read.
|
||||
|
||||
LIBC_INLINE static constexpr bool islower(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'a':
|
||||
case L'b':
|
||||
case L'c':
|
||||
case L'd':
|
||||
case L'e':
|
||||
case L'f':
|
||||
case L'g':
|
||||
case L'h':
|
||||
case L'i':
|
||||
case L'j':
|
||||
case L'k':
|
||||
case L'l':
|
||||
case L'm':
|
||||
case L'n':
|
||||
case L'o':
|
||||
case L'p':
|
||||
case L'q':
|
||||
case L'r':
|
||||
case L's':
|
||||
case L't':
|
||||
case L'u':
|
||||
case L'v':
|
||||
case L'w':
|
||||
case L'x':
|
||||
case L'y':
|
||||
case L'z':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isupper(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'A':
|
||||
case L'B':
|
||||
case L'C':
|
||||
case L'D':
|
||||
case L'E':
|
||||
case L'F':
|
||||
case L'G':
|
||||
case L'H':
|
||||
case L'I':
|
||||
case L'J':
|
||||
case L'K':
|
||||
case L'L':
|
||||
case L'M':
|
||||
case L'N':
|
||||
case L'O':
|
||||
case L'P':
|
||||
case L'Q':
|
||||
case L'R':
|
||||
case L'S':
|
||||
case L'T':
|
||||
case L'U':
|
||||
case L'V':
|
||||
case L'W':
|
||||
case L'X':
|
||||
case L'Y':
|
||||
case L'Z':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isdigit(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'0':
|
||||
case L'1':
|
||||
case L'2':
|
||||
case L'3':
|
||||
case L'4':
|
||||
case L'5':
|
||||
case L'6':
|
||||
case L'7':
|
||||
case L'8':
|
||||
case L'9':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr wchar_t tolower(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'A':
|
||||
return L'a';
|
||||
case L'B':
|
||||
return L'b';
|
||||
case L'C':
|
||||
return L'c';
|
||||
case L'D':
|
||||
return L'd';
|
||||
case L'E':
|
||||
return L'e';
|
||||
case L'F':
|
||||
return L'f';
|
||||
case L'G':
|
||||
return L'g';
|
||||
case L'H':
|
||||
return L'h';
|
||||
case L'I':
|
||||
return L'i';
|
||||
case L'J':
|
||||
return L'j';
|
||||
case L'K':
|
||||
return L'k';
|
||||
case L'L':
|
||||
return L'l';
|
||||
case L'M':
|
||||
return L'm';
|
||||
case L'N':
|
||||
return L'n';
|
||||
case L'O':
|
||||
return L'o';
|
||||
case L'P':
|
||||
return L'p';
|
||||
case L'Q':
|
||||
return L'q';
|
||||
case L'R':
|
||||
return L'r';
|
||||
case L'S':
|
||||
return L's';
|
||||
case L'T':
|
||||
return L't';
|
||||
case L'U':
|
||||
return L'u';
|
||||
case L'V':
|
||||
return L'v';
|
||||
case L'W':
|
||||
return L'w';
|
||||
case L'X':
|
||||
return L'x';
|
||||
case L'Y':
|
||||
return L'y';
|
||||
case L'Z':
|
||||
return L'z';
|
||||
default:
|
||||
return wch;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr wchar_t toupper(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'a':
|
||||
return L'A';
|
||||
case L'b':
|
||||
return L'B';
|
||||
case L'c':
|
||||
return L'C';
|
||||
case L'd':
|
||||
return L'D';
|
||||
case L'e':
|
||||
return L'E';
|
||||
case L'f':
|
||||
return L'F';
|
||||
case L'g':
|
||||
return L'G';
|
||||
case L'h':
|
||||
return L'H';
|
||||
case L'i':
|
||||
return L'I';
|
||||
case L'j':
|
||||
return L'J';
|
||||
case L'k':
|
||||
return L'K';
|
||||
case L'l':
|
||||
return L'L';
|
||||
case L'm':
|
||||
return L'M';
|
||||
case L'n':
|
||||
return L'N';
|
||||
case L'o':
|
||||
return L'O';
|
||||
case L'p':
|
||||
return L'P';
|
||||
case L'q':
|
||||
return L'Q';
|
||||
case L'r':
|
||||
return L'R';
|
||||
case L's':
|
||||
return L'S';
|
||||
case L't':
|
||||
return L'T';
|
||||
case L'u':
|
||||
return L'U';
|
||||
case L'v':
|
||||
return L'V';
|
||||
case L'w':
|
||||
return L'W';
|
||||
case L'x':
|
||||
return L'X';
|
||||
case L'y':
|
||||
return L'Y';
|
||||
case L'z':
|
||||
return L'Z';
|
||||
default:
|
||||
return wch;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isalpha(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'a':
|
||||
case L'b':
|
||||
case L'c':
|
||||
case L'd':
|
||||
case L'e':
|
||||
case L'f':
|
||||
case L'g':
|
||||
case L'h':
|
||||
case L'i':
|
||||
case L'j':
|
||||
case L'k':
|
||||
case L'l':
|
||||
case L'm':
|
||||
case L'n':
|
||||
case L'o':
|
||||
case L'p':
|
||||
case L'q':
|
||||
case L'r':
|
||||
case L's':
|
||||
case L't':
|
||||
case L'u':
|
||||
case L'v':
|
||||
case L'w':
|
||||
case L'x':
|
||||
case L'y':
|
||||
case L'z':
|
||||
case L'A':
|
||||
case L'B':
|
||||
case L'C':
|
||||
case L'D':
|
||||
case L'E':
|
||||
case L'F':
|
||||
case L'G':
|
||||
case L'H':
|
||||
case L'I':
|
||||
case L'J':
|
||||
case L'K':
|
||||
case L'L':
|
||||
case L'M':
|
||||
case L'N':
|
||||
case L'O':
|
||||
case L'P':
|
||||
case L'Q':
|
||||
case L'R':
|
||||
case L'S':
|
||||
case L'T':
|
||||
case L'U':
|
||||
case L'V':
|
||||
case L'W':
|
||||
case L'X':
|
||||
case L'Y':
|
||||
case L'Z':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isalnum(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'a':
|
||||
case L'b':
|
||||
case L'c':
|
||||
case L'd':
|
||||
case L'e':
|
||||
case L'f':
|
||||
case L'g':
|
||||
case L'h':
|
||||
case L'i':
|
||||
case L'j':
|
||||
case L'k':
|
||||
case L'l':
|
||||
case L'm':
|
||||
case L'n':
|
||||
case L'o':
|
||||
case L'p':
|
||||
case L'q':
|
||||
case L'r':
|
||||
case L's':
|
||||
case L't':
|
||||
case L'u':
|
||||
case L'v':
|
||||
case L'w':
|
||||
case L'x':
|
||||
case L'y':
|
||||
case L'z':
|
||||
case L'A':
|
||||
case L'B':
|
||||
case L'C':
|
||||
case L'D':
|
||||
case L'E':
|
||||
case L'F':
|
||||
case L'G':
|
||||
case L'H':
|
||||
case L'I':
|
||||
case L'J':
|
||||
case L'K':
|
||||
case L'L':
|
||||
case L'M':
|
||||
case L'N':
|
||||
case L'O':
|
||||
case L'P':
|
||||
case L'Q':
|
||||
case L'R':
|
||||
case L'S':
|
||||
case L'T':
|
||||
case L'U':
|
||||
case L'V':
|
||||
case L'W':
|
||||
case L'X':
|
||||
case L'Y':
|
||||
case L'Z':
|
||||
case L'0':
|
||||
case L'1':
|
||||
case L'2':
|
||||
case L'3':
|
||||
case L'4':
|
||||
case L'5':
|
||||
case L'6':
|
||||
case L'7':
|
||||
case L'8':
|
||||
case L'9':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr int b36_char_to_int(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L'0':
|
||||
return 0;
|
||||
case L'1':
|
||||
return 1;
|
||||
case L'2':
|
||||
return 2;
|
||||
case L'3':
|
||||
return 3;
|
||||
case L'4':
|
||||
return 4;
|
||||
case L'5':
|
||||
return 5;
|
||||
case L'6':
|
||||
return 6;
|
||||
case L'7':
|
||||
return 7;
|
||||
case L'8':
|
||||
return 8;
|
||||
case L'9':
|
||||
return 9;
|
||||
case L'a':
|
||||
case L'A':
|
||||
return 10;
|
||||
case L'b':
|
||||
case L'B':
|
||||
return 11;
|
||||
case L'c':
|
||||
case L'C':
|
||||
return 12;
|
||||
case L'd':
|
||||
case L'D':
|
||||
return 13;
|
||||
case L'e':
|
||||
case L'E':
|
||||
return 14;
|
||||
case L'f':
|
||||
case L'F':
|
||||
return 15;
|
||||
case L'g':
|
||||
case L'G':
|
||||
return 16;
|
||||
case L'h':
|
||||
case L'H':
|
||||
return 17;
|
||||
case L'i':
|
||||
case L'I':
|
||||
return 18;
|
||||
case L'j':
|
||||
case L'J':
|
||||
return 19;
|
||||
case L'k':
|
||||
case L'K':
|
||||
return 20;
|
||||
case L'l':
|
||||
case L'L':
|
||||
return 21;
|
||||
case L'm':
|
||||
case L'M':
|
||||
return 22;
|
||||
case L'n':
|
||||
case L'N':
|
||||
return 23;
|
||||
case L'o':
|
||||
case L'O':
|
||||
return 24;
|
||||
case L'p':
|
||||
case L'P':
|
||||
return 25;
|
||||
case L'q':
|
||||
case L'Q':
|
||||
return 26;
|
||||
case L'r':
|
||||
case L'R':
|
||||
return 27;
|
||||
case L's':
|
||||
case L'S':
|
||||
return 28;
|
||||
case L't':
|
||||
case L'T':
|
||||
return 29;
|
||||
case L'u':
|
||||
case L'U':
|
||||
return 30;
|
||||
case L'v':
|
||||
case L'V':
|
||||
return 31;
|
||||
case L'w':
|
||||
case L'W':
|
||||
return 32;
|
||||
case L'x':
|
||||
case L'X':
|
||||
return 33;
|
||||
case L'y':
|
||||
case L'Y':
|
||||
return 34;
|
||||
case L'z':
|
||||
case L'Z':
|
||||
return 35;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr wchar_t int_to_b36_wchar(int num) {
|
||||
// Can't actually use LIBC_ASSERT here because it depends on integer_to_string
|
||||
// which depends on this.
|
||||
|
||||
// LIBC_ASSERT(num < 36);
|
||||
switch (num) {
|
||||
case 0:
|
||||
return L'0';
|
||||
case 1:
|
||||
return L'1';
|
||||
case 2:
|
||||
return L'2';
|
||||
case 3:
|
||||
return L'3';
|
||||
case 4:
|
||||
return L'4';
|
||||
case 5:
|
||||
return L'5';
|
||||
case 6:
|
||||
return L'6';
|
||||
case 7:
|
||||
return L'7';
|
||||
case 8:
|
||||
return L'8';
|
||||
case 9:
|
||||
return L'9';
|
||||
case 10:
|
||||
return L'a';
|
||||
case 11:
|
||||
return L'b';
|
||||
case 12:
|
||||
return L'c';
|
||||
case 13:
|
||||
return L'd';
|
||||
case 14:
|
||||
return L'e';
|
||||
case 15:
|
||||
return L'f';
|
||||
case 16:
|
||||
return L'g';
|
||||
case 17:
|
||||
return L'h';
|
||||
case 18:
|
||||
return L'i';
|
||||
case 19:
|
||||
return L'j';
|
||||
case 20:
|
||||
return L'k';
|
||||
case 21:
|
||||
return L'l';
|
||||
case 22:
|
||||
return L'm';
|
||||
case 23:
|
||||
return L'n';
|
||||
case 24:
|
||||
return L'o';
|
||||
case 25:
|
||||
return L'p';
|
||||
case 26:
|
||||
return L'q';
|
||||
case 27:
|
||||
return L'r';
|
||||
case 28:
|
||||
return L's';
|
||||
case 29:
|
||||
return L't';
|
||||
case 30:
|
||||
return L'u';
|
||||
case 31:
|
||||
return L'v';
|
||||
case 32:
|
||||
return L'w';
|
||||
case 33:
|
||||
return L'x';
|
||||
case 34:
|
||||
return L'y';
|
||||
case 35:
|
||||
return L'z';
|
||||
default:
|
||||
return L'!';
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE static constexpr bool isspace(wchar_t wch) {
|
||||
switch (wch) {
|
||||
case L' ':
|
||||
case L'\t':
|
||||
case L'\n':
|
||||
case L'\v':
|
||||
case L'\f':
|
||||
case L'\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// An overload which provides a way to compare input with specific character
|
||||
// values, when input can be of a regular or a wide character type.
|
||||
LIBC_INLINE static constexpr bool
|
||||
is_char_or_wchar(wchar_t ch, [[maybe_unused]] char, wchar_t wc_value) {
|
||||
return (ch == wc_value);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue