aboutsummaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/CMakeLists.txt2
-rw-r--r--libc/config/linux/x86_64/exclude.txt8
-rw-r--r--libc/include/llvm-libc-types/__barrier_type.h2
-rw-r--r--libc/include/llvm-libc-types/pthread_barrierattr_t.h2
-rw-r--r--libc/include/locale.yaml2
-rw-r--r--libc/include/stdio.yaml2
-rw-r--r--libc/include/stdlib.yaml2
-rw-r--r--libc/include/string.yaml2
-rw-r--r--libc/include/time.yaml2
-rw-r--r--libc/include/wchar.yaml12
-rw-r--r--libc/src/__support/CMakeLists.txt12
-rw-r--r--libc/src/__support/str_to_integer.h98
-rw-r--r--libc/src/__support/wcs_to_integer.h155
-rw-r--r--libc/src/fenv/CMakeLists.txt32
-rw-r--r--libc/src/math/amdgpu/CMakeLists.txt70
-rw-r--r--libc/src/math/generic/CMakeLists.txt28
-rw-r--r--libc/src/math/nvptx/CMakeLists.txt58
-rw-r--r--libc/src/time/strftime.cpp2
-rw-r--r--libc/src/time/strftime_l.cpp2
-rw-r--r--libc/src/wchar/CMakeLists.txt8
-rw-r--r--libc/src/wchar/wcstol.cpp4
-rw-r--r--libc/src/wchar/wcstoll.cpp4
-rw-r--r--libc/src/wchar/wcstoul.cpp4
-rw-r--r--libc/src/wchar/wcstoull.cpp4
-rw-r--r--libc/test/src/__support/CMakeLists.txt2
-rw-r--r--libc/test/src/__support/str_to_integer_test.cpp6
-rw-r--r--libc/test/src/__support/wcs_to_integer_test.cpp102
-rw-r--r--libc/test/src/time/strftime_test.cpp21
-rw-r--r--libc/utils/hdrgen/hdrgen/enumeration.py16
-rw-r--r--libc/utils/hdrgen/hdrgen/function.py16
-rw-r--r--libc/utils/hdrgen/hdrgen/header.py81
-rw-r--r--libc/utils/hdrgen/hdrgen/macro.py16
-rwxr-xr-xlibc/utils/hdrgen/hdrgen/main.py1
-rw-r--r--libc/utils/hdrgen/hdrgen/object.py16
-rw-r--r--libc/utils/hdrgen/hdrgen/symbol.py41
-rw-r--r--libc/utils/hdrgen/hdrgen/type.py20
-rw-r--r--libc/utils/hdrgen/hdrgen/yaml_to_classes.py2
-rw-r--r--libc/utils/hdrgen/tests/expected_output/custom.h21
-rw-r--r--libc/utils/hdrgen/tests/expected_output/sorting.h24
-rw-r--r--libc/utils/hdrgen/tests/expected_output/test_header.h1
-rw-r--r--libc/utils/hdrgen/tests/expected_output/test_small.json1
-rw-r--r--libc/utils/hdrgen/tests/input/custom-common.yaml6
-rw-r--r--libc/utils/hdrgen/tests/input/custom.yaml13
-rw-r--r--libc/utils/hdrgen/tests/input/sorting.yaml20
-rw-r--r--libc/utils/hdrgen/tests/test_integration.py14
45 files changed, 412 insertions, 545 deletions
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 14718e2..ae555a25 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -363,7 +363,7 @@ elseif(LLVM_LIBC_FULL_BUILD)
message(FATAL_ERROR "${LIBC_CONFIG_PATH}/headers.txt file not found and fullbuild requested.")
endif()
-# Check exclude.txt that appends to LIBC_EXCLUDE_ENTRYPOINTS list
+# Check exclude.txt that appends to TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS list
if(EXISTS "${LIBC_CONFIG_PATH}/exclude.txt")
include("${LIBC_CONFIG_PATH}/exclude.txt")
endif()
diff --git a/libc/config/linux/x86_64/exclude.txt b/libc/config/linux/x86_64/exclude.txt
index 2c218b7..a068631 100644
--- a/libc/config/linux/x86_64/exclude.txt
+++ b/libc/config/linux/x86_64/exclude.txt
@@ -19,3 +19,11 @@ if(NOT has_sys_random)
)
endif()
endif()
+
+include(CheckSymbolExists)
+check_symbol_exists(SYS_faccessat2 "sys/syscall.h" HAVE_SYS_FACCESSAT2)
+if(NOT HAVE_SYS_FACCESSAT2)
+ list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS
+ libc.src.unistd.faccessat
+ )
+endif()
diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h
index 5971261..5752f83 100644
--- a/libc/include/llvm-libc-types/__barrier_type.h
+++ b/libc/include/llvm-libc-types/__barrier_type.h
@@ -9,6 +9,8 @@
#ifndef LLVM_LIBC_TYPES__BARRIER_TYPE_H
#define LLVM_LIBC_TYPES__BARRIER_TYPE_H
+#include <stdbool.h>
+
typedef struct __attribute__((aligned(8 /* alignof (Barrier) */))) {
unsigned expected;
unsigned waiting;
diff --git a/libc/include/llvm-libc-types/pthread_barrierattr_t.h b/libc/include/llvm-libc-types/pthread_barrierattr_t.h
index 064be5b..b62fdc0 100644
--- a/libc/include/llvm-libc-types/pthread_barrierattr_t.h
+++ b/libc/include/llvm-libc-types/pthread_barrierattr_t.h
@@ -9,6 +9,8 @@
#ifndef LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H
#define LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H
+#include <stdbool.h>
+
typedef struct {
bool pshared;
} pthread_barrierattr_t;
diff --git a/libc/include/locale.yaml b/libc/include/locale.yaml
index 4566984..3c3998e 100644
--- a/libc/include/locale.yaml
+++ b/libc/include/locale.yaml
@@ -1,7 +1,7 @@
header: locale.h
header_template: locale.h.def
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: locale_t
diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml
index 394437b..c50b4ec 100644
--- a/libc/include/stdio.yaml
+++ b/libc/include/stdio.yaml
@@ -1,7 +1,7 @@
header: stdio.h
header_template: stdio.h.def
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
- macro_name: stdout
macro_value: stdout
diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml
index 3b2ff13..495eb7e 100644
--- a/libc/include/stdlib.yaml
+++ b/libc/include/stdlib.yaml
@@ -5,7 +5,7 @@ standards:
merge_yaml_files:
- stdlib-malloc.yaml
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: __atexithandler_t
diff --git a/libc/include/string.yaml b/libc/include/string.yaml
index 0bf297e..22010f4 100644
--- a/libc/include/string.yaml
+++ b/libc/include/string.yaml
@@ -2,7 +2,7 @@ header: string.h
standards:
- stdc
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: locale_t
diff --git a/libc/include/time.yaml b/libc/include/time.yaml
index 2f80242..88e50d1 100644
--- a/libc/include/time.yaml
+++ b/libc/include/time.yaml
@@ -1,7 +1,7 @@
header: time.h
header_template: time.h.def
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: struct_timeval
diff --git a/libc/include/wchar.yaml b/libc/include/wchar.yaml
index b8a0a74..fb5b19b 100644
--- a/libc/include/wchar.yaml
+++ b/libc/include/wchar.yaml
@@ -1,11 +1,15 @@
header: wchar.h
header_template: wchar.h.def
macros:
- - macro_name: NULL
+ - macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: FILE
- type_name: size_t
+ # TODO: Remove this once we have a function declaration using "struct tm"
+ # (wcsftime). We're declaring it here now, since libc++ expects
+ # forward-declaration of "struct tm" in the <wchar.h> header.
+ - type_name: struct_tm
- type_name: wint_t
- type_name: wchar_t
- type_name: mbstate_t
@@ -188,8 +192,8 @@ functions:
standards:
- stdc
return_type: wchar_t *
- arguments:
- - type: wchar_t *__restrict
+ arguments:
+ - type: wchar_t *__restrict
- type: const wchar_t *__restrict
- type: size_t
- name: wmemmove
@@ -212,7 +216,7 @@ functions:
standards:
- stdc
return_type: wchar_t *
- arguments:
+ arguments:
- type: wchar_t *__restrict
- type: const wchar_t *__restrict
- name: wcslcat
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 0ef09a9..b7af751 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -179,19 +179,7 @@ add_header_library(
DEPENDS
.ctype_utils
.str_to_num_result
- libc.hdr.errno_macros
- libc.src.__support.CPP.limits
- libc.src.__support.CPP.type_traits
- libc.src.__support.common
-)
-
-add_header_library(
- wcs_to_integer
- HDRS
- wcs_to_integer.h
- DEPENDS
.wctype_utils
- .str_to_num_result
libc.hdr.errno_macros
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
diff --git a/libc/src/__support/str_to_integer.h b/libc/src/__support/str_to_integer.h
index d332c92..ba3f49f 100644
--- a/libc/src/__support/str_to_integer.h
+++ b/libc/src/__support/str_to_integer.h
@@ -25,36 +25,63 @@
#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())
+// character (as determined by isspace() / iswspace())
+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])) {
+ while (src_cur < src_len) {
+ if constexpr (cpp::is_same_v<CharType, char>) {
+ if (!internal::isspace(src[src_cur]))
+ break;
+ } else {
+ if (!internal::iswspace(src[src_cur]))
+ break;
+ }
++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 constexpr (cpp::is_same_v<CharType, char>) {
+ return (src[0] == '+') ? 1 : (src[0] == '-' ? -1 : 0);
+ } else {
+ return (src[0] == L'+') ? 1 : (src[0] == L'-' ? -1 : 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;
+ if constexpr (cpp::is_same_v<CharType, char>) {
+ return src[0] == '0' && tolower(src[1]) == 'x' && isalnum(src[2]) &&
+ b36_char_to_int(src[2]) < 16;
+ } else {
+ return src[0] == L'0' && towlower(src[1]) == L'x' && iswalnum(src[2]) &&
+ b36_wchar_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 +90,15 @@ 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')
- return 8;
+ if (src_len > 0) {
+ if constexpr (cpp::is_same_v<CharType, char>) {
+ if (src[0] == '0')
+ return 8;
+ } else {
+ if (src[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 +111,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 +139,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,8 +147,21 @@ strtointeger(const char *__restrict src, int base,
ResultType const abs_max_div_by_base =
abs_max / static_cast<ResultType>(base);
- while (src_cur < src_len && isalnum(src[src_cur])) {
- int cur_digit = b36_char_to_int(src[src_cur]);
+ bool is_number = false;
+ int error_val = 0;
+ ResultType result = 0;
+ while (src_cur < src_len) {
+ int cur_digit;
+ if constexpr (cpp::is_same_v<CharType, char>) {
+ if (!isalnum(src[src_cur]))
+ break;
+ cur_digit = b36_char_to_int(src[src_cur]);
+ } else {
+ if (!iswalnum(src[src_cur]))
+ break;
+ cur_digit = b36_wchar_to_int(src[src_cur]);
+ }
+
if (cur_digit >= base)
break;
diff --git a/libc/src/__support/wcs_to_integer.h b/libc/src/__support/wcs_to_integer.h
deleted file mode 100644
index 4254bd8..0000000
--- a/libc/src/__support/wcs_to_integer.h
+++ /dev/null
@@ -1,155 +0,0 @@
-//===-- Widechar string to integer conversion utils -------------*- 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_WCS_TO_INTEGER_H
-#define LLVM_LIBC_SRC___SUPPORT_WCS_TO_INTEGER_H
-
-#include "hdr/errno_macros.h" // For ERANGE
-#include "src/__support/CPP/limits.h"
-#include "src/__support/CPP/type_traits.h"
-#include "src/__support/CPP/type_traits/make_unsigned.h"
-#include "src/__support/big_int.h"
-#include "src/__support/common.h"
-#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 of the first character in src that is not a whitespace
-// character (as determined by iswspace())
-LIBC_INLINE size_t
-first_non_whitespace(const wchar_t *__restrict src,
- size_t src_len = cpp::numeric_limits<size_t>::max()) {
- size_t src_cur = 0;
- while (src_cur < src_len && internal::iswspace(src[src_cur])) {
- ++src_cur;
- }
- return src_cur;
-}
-
-// 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 wchar_t *__restrict src,
- size_t src_len = cpp::numeric_limits<size_t>::max()) {
- if (src_len < 3)
- return false;
- return *src == L'0' && towlower(*(src + 1)) == L'x' && iswalnum(*(src + 2)) &&
- b36_wchar_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 wchar_t *__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)
- if (is_hex_start(src, src_len))
- return 16;
- // 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] == 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;
-}
-
-template <class T>
-LIBC_INLINE StrToNumResult<T>
-wcstointeger(const wchar_t *__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);
-
- wchar_t result_sign = L'+';
- if (src[src_cur] == L'+' || src[src_cur] == L'-') {
- result_sign = src[src_cur];
- ++src_cur;
- }
-
- if (base == 0)
- base = infer_base(src + src_cur, src_len - src_cur);
-
- if (base == 16 && is_hex_start(src + src_cur, src_len - src_cur))
- src_cur = src_cur + 2;
-
- constexpr bool IS_UNSIGNED = cpp::is_unsigned_v<T>;
- const bool is_positive = (result_sign == L'+');
-
- ResultType constexpr NEGATIVE_MAX =
- !IS_UNSIGNED ? static_cast<ResultType>(cpp::numeric_limits<T>::max()) + 1
- : cpp::numeric_limits<T>::max();
- ResultType const abs_max =
- (is_positive ? cpp::numeric_limits<T>::max() : NEGATIVE_MAX);
- ResultType const abs_max_div_by_base =
- abs_max / static_cast<ResultType>(base);
-
- while (src_cur < src_len && iswalnum(src[src_cur])) {
- int cur_digit = b36_wchar_to_int(src[src_cur]);
- if (cur_digit >= base)
- break;
-
- is_number = true;
- ++src_cur;
-
- // If the number has already hit the maximum value for the current type then
- // the result cannot change, but we still need to advance src to the end of
- // the number.
- if (result == abs_max) {
- error_val = ERANGE;
- continue;
- }
-
- if (result > abs_max_div_by_base) {
- result = abs_max;
- error_val = ERANGE;
- } else {
- result = result * static_cast<ResultType>(base);
- }
- if (result > abs_max - static_cast<ResultType>(cur_digit)) {
- result = abs_max;
- error_val = ERANGE;
- } else {
- result = result + static_cast<ResultType>(cur_digit);
- }
- }
-
- ptrdiff_t str_len = is_number ? static_cast<ptrdiff_t>(src_cur) : 0;
-
- if (error_val == ERANGE) {
- if (is_positive || IS_UNSIGNED)
- return {cpp::numeric_limits<T>::max(), str_len, error_val};
- else // T is signed and there is a negative overflow
- return {cpp::numeric_limits<T>::min(), str_len, error_val};
- }
-
- return {static_cast<T>(is_positive ? result : -result), str_len, error_val};
-}
-
-} // namespace internal
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_WCS_TO_INTEGER_H
diff --git a/libc/src/fenv/CMakeLists.txt b/libc/src/fenv/CMakeLists.txt
index c5431b1..f368845 100644
--- a/libc/src/fenv/CMakeLists.txt
+++ b/libc/src/fenv/CMakeLists.txt
@@ -6,8 +6,6 @@ add_entrypoint_object(
fegetround.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -18,8 +16,6 @@ add_entrypoint_object(
fesetround.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -30,8 +26,6 @@ add_entrypoint_object(
feclearexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -42,8 +36,6 @@ add_entrypoint_object(
feraiseexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -54,8 +46,6 @@ add_entrypoint_object(
fetestexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -67,8 +57,6 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.fexcept_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -80,8 +68,6 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -93,8 +79,6 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -107,8 +91,6 @@ add_entrypoint_object(
libc.hdr.fenv_macros
libc.hdr.types.fexcept_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -119,8 +101,6 @@ add_entrypoint_object(
fesetexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -133,8 +113,6 @@ add_entrypoint_object(
libc.hdr.fenv_macros
libc.hdr.types.fexcept_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -147,8 +125,6 @@ add_entrypoint_object(
libc.hdr.fenv_macros
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -161,8 +137,6 @@ add_entrypoint_object(
libc.hdr.fenv_macros
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -173,8 +147,6 @@ add_entrypoint_object(
feenableexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -185,8 +157,6 @@ add_entrypoint_object(
fedisableexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -197,6 +167,4 @@ add_entrypoint_object(
fegetexcept.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
- COMPILE_OPTIONS
- -O2
)
diff --git a/libc/src/math/amdgpu/CMakeLists.txt b/libc/src/math/amdgpu/CMakeLists.txt
index e2cd3b9..d05d519 100644
--- a/libc/src/math/amdgpu/CMakeLists.txt
+++ b/libc/src/math/amdgpu/CMakeLists.txt
@@ -4,8 +4,6 @@ add_entrypoint_object(
ceil.cpp
HDRS
../ceil.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -14,8 +12,6 @@ add_entrypoint_object(
ceilf.cpp
HDRS
../ceilf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -24,8 +20,6 @@ add_entrypoint_object(
copysign.cpp
HDRS
../copysign.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -34,8 +28,6 @@ add_entrypoint_object(
copysignf.cpp
HDRS
../copysignf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -44,8 +36,6 @@ add_entrypoint_object(
fabs.cpp
HDRS
../fabs.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -54,8 +44,6 @@ add_entrypoint_object(
fabsf.cpp
HDRS
../fabsf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -64,8 +52,6 @@ add_entrypoint_object(
floor.cpp
HDRS
../floor.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -74,8 +60,6 @@ add_entrypoint_object(
floorf.cpp
HDRS
../floorf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -84,8 +68,6 @@ add_entrypoint_object(
fma.cpp
HDRS
../fma.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -94,8 +76,6 @@ add_entrypoint_object(
fmaf.cpp
HDRS
../fmaf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -104,8 +84,6 @@ add_entrypoint_object(
fmax.cpp
HDRS
../fmax.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -114,8 +92,6 @@ add_entrypoint_object(
fmaxf.cpp
HDRS
../fmaxf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -124,8 +100,6 @@ add_entrypoint_object(
fmin.cpp
HDRS
../fmin.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -134,8 +108,6 @@ add_entrypoint_object(
fminf.cpp
HDRS
../fminf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -144,8 +116,6 @@ add_entrypoint_object(
fmod.cpp
HDRS
../fmod.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -154,8 +124,6 @@ add_entrypoint_object(
fmodf.cpp
HDRS
../fmodf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -164,8 +132,6 @@ add_entrypoint_object(
nearbyint.cpp
HDRS
../nearbyint.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -174,8 +140,6 @@ add_entrypoint_object(
nearbyintf.cpp
HDRS
../nearbyintf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -184,8 +148,6 @@ add_entrypoint_object(
remainder.cpp
HDRS
../remainder.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -194,8 +156,6 @@ add_entrypoint_object(
remainderf.cpp
HDRS
../remainderf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -204,8 +164,6 @@ add_entrypoint_object(
rint.cpp
HDRS
../rint.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -214,8 +172,6 @@ add_entrypoint_object(
rintf.cpp
HDRS
../rintf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -224,8 +180,6 @@ add_entrypoint_object(
round.cpp
HDRS
../round.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -234,8 +188,6 @@ add_entrypoint_object(
sqrt.cpp
HDRS
../sqrt.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -244,8 +196,6 @@ add_entrypoint_object(
sqrtf.cpp
HDRS
../sqrtf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -254,8 +204,6 @@ add_entrypoint_object(
trunc.cpp
HDRS
../trunc.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -264,8 +212,6 @@ add_entrypoint_object(
truncf.cpp
HDRS
../truncf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -274,8 +220,6 @@ add_entrypoint_object(
frexp.cpp
HDRS
../frexp.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -284,8 +228,6 @@ add_entrypoint_object(
frexpf.cpp
HDRS
../frexpf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -294,8 +236,6 @@ add_entrypoint_object(
scalbn.cpp
HDRS
../scalbn.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -304,8 +244,6 @@ add_entrypoint_object(
scalbnf.cpp
HDRS
../scalbnf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -314,8 +252,6 @@ add_entrypoint_object(
ldexp.cpp
HDRS
../ldexp.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -324,8 +260,6 @@ add_entrypoint_object(
ldexpf.cpp
HDRS
../ldexpf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -336,7 +270,6 @@ add_entrypoint_object(
../tgamma.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -347,7 +280,6 @@ add_entrypoint_object(
../tgammaf.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -358,7 +290,6 @@ add_entrypoint_object(
../lgamma.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -369,5 +300,4 @@ add_entrypoint_object(
../lgamma_r.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 6068c36..c048a64 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2662,8 +2662,6 @@ add_entrypoint_object(
../fmaximum_mag.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2674,8 +2672,6 @@ add_entrypoint_object(
../fmaximum_magf.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2686,8 +2682,6 @@ add_entrypoint_object(
../fmaximum_magl.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2735,8 +2729,6 @@ add_entrypoint_object(
../fmaximum_mag_num.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2747,8 +2739,6 @@ add_entrypoint_object(
../fmaximum_mag_numf.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2759,8 +2749,6 @@ add_entrypoint_object(
../fmaximum_mag_numl.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2954,8 +2942,6 @@ add_entrypoint_object(
../fminimum_mag.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2966,8 +2952,6 @@ add_entrypoint_object(
../fminimum_magf.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -2978,8 +2962,6 @@ add_entrypoint_object(
../fminimum_magl.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -3027,8 +3009,6 @@ add_entrypoint_object(
../fminimum_mag_num.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -3039,8 +3019,6 @@ add_entrypoint_object(
../fminimum_mag_numf.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -3051,8 +3029,6 @@ add_entrypoint_object(
../fminimum_mag_numl.h
DEPENDS
libc.src.__support.FPUtil.basic_operations
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -4306,7 +4282,7 @@ add_entrypoint_object(
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
@@ -4546,8 +4522,6 @@ add_entrypoint_object(
atan.cpp
HDRS
../atan.h
- COMPILE_OPTIONS
- -O3
DEPENDS
libc.src.__support.math.atan
)
diff --git a/libc/src/math/nvptx/CMakeLists.txt b/libc/src/math/nvptx/CMakeLists.txt
index fcb2870..e27c316 100644
--- a/libc/src/math/nvptx/CMakeLists.txt
+++ b/libc/src/math/nvptx/CMakeLists.txt
@@ -4,8 +4,6 @@ add_entrypoint_object(
ceil.cpp
HDRS
../ceil.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -14,8 +12,6 @@ add_entrypoint_object(
ceilf.cpp
HDRS
../ceilf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -24,8 +20,6 @@ add_entrypoint_object(
copysign.cpp
HDRS
../copysign.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -34,8 +28,6 @@ add_entrypoint_object(
copysignf.cpp
HDRS
../copysignf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -44,8 +36,6 @@ add_entrypoint_object(
fabs.cpp
HDRS
../fabs.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -54,8 +44,6 @@ add_entrypoint_object(
fabsf.cpp
HDRS
../fabsf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -64,8 +52,6 @@ add_entrypoint_object(
floor.cpp
HDRS
../floor.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -74,8 +60,6 @@ add_entrypoint_object(
floorf.cpp
HDRS
../floorf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -84,8 +68,6 @@ add_entrypoint_object(
fma.cpp
HDRS
../fma.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -94,8 +76,6 @@ add_entrypoint_object(
fmaf.cpp
HDRS
../fmaf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -104,8 +84,6 @@ add_entrypoint_object(
fmax.cpp
HDRS
../fmax.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -114,8 +92,6 @@ add_entrypoint_object(
fmaxf.cpp
HDRS
../fmaxf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -124,8 +100,6 @@ add_entrypoint_object(
fmin.cpp
HDRS
../fmin.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -134,8 +108,6 @@ add_entrypoint_object(
fminf.cpp
HDRS
../fminf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -144,8 +116,6 @@ add_entrypoint_object(
fmod.cpp
HDRS
../fmod.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -154,8 +124,6 @@ add_entrypoint_object(
fmodf.cpp
HDRS
../fmodf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -164,8 +132,6 @@ add_entrypoint_object(
nearbyint.cpp
HDRS
../nearbyint.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -174,8 +140,6 @@ add_entrypoint_object(
nearbyintf.cpp
HDRS
../nearbyintf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -184,8 +148,6 @@ add_entrypoint_object(
remainder.cpp
HDRS
../remainder.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -194,8 +156,6 @@ add_entrypoint_object(
remainderf.cpp
HDRS
../remainderf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -204,8 +164,6 @@ add_entrypoint_object(
rint.cpp
HDRS
../rint.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -214,8 +172,6 @@ add_entrypoint_object(
rintf.cpp
HDRS
../rintf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -224,8 +180,6 @@ add_entrypoint_object(
round.cpp
HDRS
../round.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -234,8 +188,6 @@ add_entrypoint_object(
sqrt.cpp
HDRS
../sqrt.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -244,8 +196,6 @@ add_entrypoint_object(
sqrtf.cpp
HDRS
../sqrtf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -254,8 +204,6 @@ add_entrypoint_object(
trunc.cpp
HDRS
../trunc.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -264,8 +212,6 @@ add_entrypoint_object(
truncf.cpp
HDRS
../truncf.h
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -276,7 +222,6 @@ add_entrypoint_object(
../tgamma.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -287,7 +232,6 @@ add_entrypoint_object(
../tgammaf.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -298,7 +242,6 @@ add_entrypoint_object(
../lgamma.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
add_entrypoint_object(
@@ -309,5 +252,4 @@ add_entrypoint_object(
../lgamma_r.h
COMPILE_OPTIONS
${bitcode_link_flags}
- -O2
)
diff --git a/libc/src/time/strftime.cpp b/libc/src/time/strftime.cpp
index f36091b..89b7d9b 100644
--- a/libc/src/time/strftime.cpp
+++ b/libc/src/time/strftime.cpp
@@ -26,7 +26,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime,
int ret = strftime_core::strftime_main(&writer, format, timeptr);
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
wb.buff[wb.buff_cur] = '\0';
- return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
+ return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/strftime_l.cpp b/libc/src/time/strftime_l.cpp
index 201b85d..409f868 100644
--- a/libc/src/time/strftime_l.cpp
+++ b/libc/src/time/strftime_l.cpp
@@ -29,7 +29,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime_l,
int ret = strftime_core::strftime_main(&writer, format, timeptr);
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
wb.buff[wb.buff_cur] = '\0';
- return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
+ return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt
index adde382..ba27cd7 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -63,7 +63,7 @@ add_entrypoint_object(
wcstol.h
DEPENDS
libc.src.errno.errno
- libc.src.__support.wcs_to_integer
+ libc.src.__support.str_to_integer
)
add_entrypoint_object(
@@ -74,7 +74,7 @@ add_entrypoint_object(
wcstoll.h
DEPENDS
libc.src.errno.errno
- libc.src.__support.wcs_to_integer
+ libc.src.__support.str_to_integer
)
add_entrypoint_object(
@@ -85,7 +85,7 @@ add_entrypoint_object(
wcstoul.h
DEPENDS
libc.src.errno.errno
- libc.src.__support.wcs_to_integer
+ libc.src.__support.str_to_integer
)
add_entrypoint_object(
@@ -96,7 +96,7 @@ add_entrypoint_object(
wcstoull.h
DEPENDS
libc.src.errno.errno
- libc.src.__support.wcs_to_integer
+ libc.src.__support.str_to_integer
)
add_entrypoint_object(
diff --git a/libc/src/wchar/wcstol.cpp b/libc/src/wchar/wcstol.cpp
index a05718f..a56b5f9 100644
--- a/libc/src/wchar/wcstol.cpp
+++ b/libc/src/wchar/wcstol.cpp
@@ -10,14 +10,14 @@
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/__support/wcs_to_integer.h"
+#include "src/__support/str_to_integer.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long, wcstol,
(const wchar_t *__restrict str, wchar_t **__restrict str_end,
int base)) {
- auto result = internal::wcstointeger<long>(str, base);
+ auto result = internal::strtointeger<long>(str, base);
if (result.has_error())
libc_errno = result.error;
diff --git a/libc/src/wchar/wcstoll.cpp b/libc/src/wchar/wcstoll.cpp
index de1299d..6229d24 100644
--- a/libc/src/wchar/wcstoll.cpp
+++ b/libc/src/wchar/wcstoll.cpp
@@ -10,14 +10,14 @@
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/__support/wcs_to_integer.h"
+#include "src/__support/str_to_integer.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long long, wcstoll,
(const wchar_t *__restrict str, wchar_t **__restrict str_end,
int base)) {
- auto result = internal::wcstointeger<long long>(str, base);
+ auto result = internal::strtointeger<long long>(str, base);
if (result.has_error())
libc_errno = result.error;
diff --git a/libc/src/wchar/wcstoul.cpp b/libc/src/wchar/wcstoul.cpp
index 79b8c9b..c5639be 100644
--- a/libc/src/wchar/wcstoul.cpp
+++ b/libc/src/wchar/wcstoul.cpp
@@ -10,14 +10,14 @@
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/__support/wcs_to_integer.h"
+#include "src/__support/str_to_integer.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(unsigned long, wcstoul,
(const wchar_t *__restrict str, wchar_t **__restrict str_end,
int base)) {
- auto result = internal::wcstointeger<unsigned long>(str, base);
+ auto result = internal::strtointeger<unsigned long>(str, base);
if (result.has_error())
libc_errno = result.error;
diff --git a/libc/src/wchar/wcstoull.cpp b/libc/src/wchar/wcstoull.cpp
index 768e03c..2ab24e9 100644
--- a/libc/src/wchar/wcstoull.cpp
+++ b/libc/src/wchar/wcstoull.cpp
@@ -10,14 +10,14 @@
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/__support/wcs_to_integer.h"
+#include "src/__support/str_to_integer.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(unsigned long long, wcstoull,
(const wchar_t *__restrict str, wchar_t **__restrict str_end,
int base)) {
- auto result = internal::wcstointeger<unsigned long long>(str, base);
+ auto result = internal::strtointeger<unsigned long long>(str, base);
if (result.has_error())
libc_errno = result.error;
diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index a025141..138866b 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -151,7 +151,7 @@ add_libc_test(
wcs_to_integer_test.cpp
DEPENDS
libc.src.__support.integer_literals
- libc.src.__support.wcs_to_integer
+ libc.src.__support.str_to_integer
)
add_libc_test(
diff --git a/libc/test/src/__support/str_to_integer_test.cpp b/libc/test/src/__support/str_to_integer_test.cpp
index 1ec882b..e5ac1d6 100644
--- a/libc/test/src/__support/str_to_integer_test.cpp
+++ b/libc/test/src/__support/str_to_integer_test.cpp
@@ -49,12 +49,14 @@ TEST(LlvmLibcStrToIntegerTest, LeadingSpaces) {
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 12);
- result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 5);
+ // Use a non-null-terminated buffer to test for possible OOB access.
+ char buf[5] = {' ', ' ', ' ', ' ', ' '};
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 5);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
diff --git a/libc/test/src/__support/wcs_to_integer_test.cpp b/libc/test/src/__support/wcs_to_integer_test.cpp
index 4554968..38af778 100644
--- a/libc/test/src/__support/wcs_to_integer_test.cpp
+++ b/libc/test/src/__support/wcs_to_integer_test.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/wcs_to_integer.h"
+#include "src/__support/str_to_integer.h"
#include <stddef.h>
#include "test/UnitTest/Test.h"
@@ -14,224 +14,226 @@
// This file is for testing the src_len argument and other internal interface
// features. Primary testing is done through the public interface.
-TEST(LlvmLibcStrToIntegerTest, SimpleLength) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 10);
+TEST(LlvmLibcWcsToIntegerTest, SimpleLength) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
ASSERT_EQ(result.value, 12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 2);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 2);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(2));
ASSERT_EQ(result.value, 12);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, LeadingSpaces) {
+TEST(LlvmLibcWcsToIntegerTest, LeadingSpaces) {
auto result =
- LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 15);
+ LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 15);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
ASSERT_EQ(result.value, 12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 10);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
ASSERT_EQ(result.value, 12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 7);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 7);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 12);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 5);
+ // Use a non-null-terminated buffer to test for possible OOB access.
+ wchar_t buf[5] = {L' ', L' ', L' ', L' ', L' '};
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 5);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, LeadingSign) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 10);
+TEST(LlvmLibcWcsToIntegerTest, LeadingSign) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 10);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, -12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 6);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 6);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 6);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 6);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, -12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 3);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 3);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(3));
ASSERT_EQ(result.value, 12);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 3);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 3);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(3));
ASSERT_EQ(result.value, -12);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 1);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 1);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 1);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 1);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, Base16PrefixAutoSelect) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 10);
+TEST(LlvmLibcWcsToIntegerTest, Base16PrefixAutoSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 0x12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 7);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 7);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 0x12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 5);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 5);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
ASSERT_EQ(result.value, 0x123);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 2);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 2);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, Base16PrefixManualSelect) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 10);
+TEST(LlvmLibcWcsToIntegerTest, Base16PrefixManualSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 0x12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 7);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 7);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(7));
ASSERT_EQ(result.value, 0x12345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 5);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 5);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(5));
ASSERT_EQ(result.value, 0x123);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 2);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 2);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, Base8PrefixAutoSelect) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 10);
+TEST(LlvmLibcWcsToIntegerTest, Base8PrefixAutoSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 012345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 6);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 6);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 012345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 4);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 4);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(4));
ASSERT_EQ(result.value, 0123);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 1);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 1);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, Base8PrefixManualSelect) {
- auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 10);
+TEST(LlvmLibcWcsToIntegerTest, Base8PrefixManualSelect) {
+ auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 012345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 6);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 6);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 012345);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 4);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 4);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(4));
ASSERT_EQ(result.value, 0123);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 1);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 1);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(1));
ASSERT_EQ(result.value, 0);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 0);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 0);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(0));
ASSERT_EQ(result.value, 0);
}
-TEST(LlvmLibcStrToIntegerTest, CombinedTests) {
+TEST(LlvmLibcWcsToIntegerTest, CombinedTests) {
auto result =
- LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 10);
+ LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 10);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(10));
ASSERT_EQ(result.value, -0x123);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 8);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 8);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(8));
ASSERT_EQ(result.value, -0x1);
- result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 7);
+ result = LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 7);
EXPECT_FALSE(result.has_error());
EXPECT_EQ(result.parsed_len, ptrdiff_t(6));
ASSERT_EQ(result.value, 0);
diff --git a/libc/test/src/time/strftime_test.cpp b/libc/test/src/time/strftime_test.cpp
index cac7560..52221527 100644
--- a/libc/test/src/time/strftime_test.cpp
+++ b/libc/test/src/time/strftime_test.cpp
@@ -2326,3 +2326,24 @@ TEST(LlvmLibcStrftimeTest, TimeFormatFullDateTime) {
// size_t written = 0;
// SimplePaddedNum spn;
// }
+
+TEST(LlvmLibcStrftimeTest, BufferTooSmall) {
+ struct tm time;
+ char tiny_buffer[1];
+
+ time.tm_year = get_adjusted_year(2025);
+ time.tm_mon = 10;
+ time.tm_mday = 24;
+
+ size_t written =
+ LIBC_NAMESPACE::strftime(tiny_buffer, sizeof(tiny_buffer), "%F", &time);
+ EXPECT_EQ(written, size_t{0});
+
+ char small_buffer[10];
+
+ // The string "2025-11-24" is 10 chars,
+ // so strftime needs 10 + 1 bytes to write the string and the null terminator.
+ written =
+ LIBC_NAMESPACE::strftime(small_buffer, sizeof(small_buffer), "%F", &time);
+ EXPECT_EQ(written, size_t{0});
+}
diff --git a/libc/utils/hdrgen/hdrgen/enumeration.py b/libc/utils/hdrgen/hdrgen/enumeration.py
index 19872082..1e0f64a 100644
--- a/libc/utils/hdrgen/hdrgen/enumeration.py
+++ b/libc/utils/hdrgen/hdrgen/enumeration.py
@@ -6,24 +6,14 @@
#
# ==-------------------------------------------------------------------------==#
-from functools import total_ordering
+from hdrgen.symbol import Symbol
-@total_ordering
-class Enumeration:
+class Enumeration(Symbol):
def __init__(self, name, value):
- self.name = name
+ super().__init__(name)
self.value = value
- def __eq__(self, other):
- return self.name == other.name
-
- def __lt__(self, other):
- return self.name < other.name
-
- def __hash__(self):
- return self.name.__hash__()
-
def __str__(self):
if self.value != None:
return f"{self.name} = {self.value}"
diff --git a/libc/utils/hdrgen/hdrgen/function.py b/libc/utils/hdrgen/hdrgen/function.py
index f039996..4de3406 100644
--- a/libc/utils/hdrgen/hdrgen/function.py
+++ b/libc/utils/hdrgen/hdrgen/function.py
@@ -7,7 +7,7 @@
# ==-------------------------------------------------------------------------==#
import re
-from functools import total_ordering
+from hdrgen.symbol import Symbol
from hdrgen.type import Type
@@ -37,14 +37,13 @@ KEYWORDS = [
NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+")
-@total_ordering
-class Function:
+class Function(Symbol):
def __init__(
self, return_type, name, arguments, standards, guard=None, attributes=[]
):
+ super().__init__(name)
assert return_type
self.return_type = return_type
- self.name = name
self.arguments = [
arg if isinstance(arg, str) else arg["type"] for arg in arguments
]
@@ -53,15 +52,6 @@ class Function:
self.guard = guard
self.attributes = attributes or []
- def __eq__(self, other):
- return self.name == other.name
-
- def __lt__(self, other):
- return self.name < other.name
-
- def __hash__(self):
- return self.name.__hash__()
-
def signature_types(self):
def collapse(type_string):
assert type_string
diff --git a/libc/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py
index 715d4b7..f592327 100644
--- a/libc/utils/hdrgen/hdrgen/header.py
+++ b/libc/utils/hdrgen/hdrgen/header.py
@@ -35,6 +35,13 @@ NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+")
COMMON_HEADER = PurePosixPath("__llvm-libc-common.h")
+# These "attributes" are known macros defined in COMMON_HEADER.
+# Others are found in "llvm-libc-macros/{name}.h".
+COMMON_ATTRIBUTES = {
+ "_Noreturn",
+ "_Returns_twice",
+}
+
# All the canonical identifiers are in lowercase for easy maintenance.
# This maps them to the pretty descriptions to generate in header comments.
LIBRARY_DESCRIPTIONS = {
@@ -50,9 +57,7 @@ LIBRARY_DESCRIPTIONS = {
HEADER_TEMPLATE = """\
//===-- {library} header <{header}> --===//
//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+{license_lines}
//
//===---------------------------------------------------------------------===//
@@ -64,6 +69,12 @@ HEADER_TEMPLATE = """\
#endif // {guard}
"""
+LLVM_LICENSE_TEXT = [
+ "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",
+]
+
class HeaderFile:
def __init__(self, name):
@@ -74,8 +85,10 @@ class HeaderFile:
self.enumerations = []
self.objects = []
self.functions = []
+ self.extra_standards = {}
self.standards = []
self.merge_yaml_files = []
+ self.license_text = []
def add_macro(self, macro):
self.macros.append(macro)
@@ -98,6 +111,11 @@ class HeaderFile:
self.enumerations = sorted(set(self.enumerations) | set(other.enumerations))
self.objects = sorted(set(self.objects) | set(other.objects))
self.functions = sorted(set(self.functions) | set(other.functions))
+ self.extra_standards |= other.extra_standards
+ if self.license_text:
+ assert not other.license_text, "only one `license_text` allowed"
+ else:
+ self.license_text = other.license_text
def all_types(self):
return reduce(
@@ -106,6 +124,13 @@ class HeaderFile:
set(self.types),
)
+ def all_attributes(self):
+ return reduce(
+ lambda a, b: a | b,
+ [set(f.attributes) for f in self.functions],
+ set(),
+ )
+
def all_standards(self):
# FIXME: Only functions have the "standard" field, but all the entity
# types should have one too.
@@ -114,16 +139,24 @@ class HeaderFile:
)
def includes(self):
- return {
- PurePosixPath("llvm-libc-macros") / macro.header
- for macro in self.macros
- if macro.header is not None
- } | {
- COMPILER_HEADER_TYPES.get(
- typ.type_name, PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h"
- )
- for typ in self.all_types()
- }
+ return (
+ {
+ PurePosixPath("llvm-libc-macros") / macro.header
+ for macro in self.macros
+ if macro.header is not None
+ }
+ | {
+ COMPILER_HEADER_TYPES.get(
+ typ.name,
+ PurePosixPath("llvm-libc-types") / f"{typ.name}.h",
+ )
+ for typ in self.all_types()
+ }
+ | {
+ PurePosixPath("llvm-libc-macros") / f"{attr}.h"
+ for attr in self.all_attributes() - COMMON_ATTRIBUTES
+ }
+ )
def header_guard(self):
return "_LLVM_LIBC_" + "_".join(
@@ -131,24 +164,29 @@ class HeaderFile:
)
def library_description(self):
+ descriptions = LIBRARY_DESCRIPTIONS | self.extra_standards
# If the header itself is in standard C, just call it that.
if "stdc" in self.standards:
- return LIBRARY_DESCRIPTIONS["stdc"]
+ return descriptions["stdc"]
# If the header itself is in POSIX, just call it that.
if "posix" in self.standards:
- return LIBRARY_DESCRIPTIONS["posix"]
+ return descriptions["posix"]
# Otherwise, consider the standards for each symbol as well.
standards = self.all_standards()
# Otherwise, it's described by all those that apply, but ignoring
# "stdc" and "posix" since this is not a "stdc" or "posix" header.
return " / ".join(
sorted(
- LIBRARY_DESCRIPTIONS[standard]
+ descriptions[standard]
for standard in standards
if standard not in {"stdc", "posix"}
)
)
+ def license_lines(self):
+ lines = self.license_text or LLVM_LICENSE_TEXT
+ return "\n".join([f"// {line}" for line in lines])
+
def template(self, dir, files_read):
if self.template_file is not None:
# There's a custom template file, so just read it in and record
@@ -162,6 +200,7 @@ class HeaderFile:
library=self.library_description(),
header=self.name,
guard=self.header_guard(),
+ license_lines=self.license_lines(),
)
def public_api(self):
@@ -188,7 +227,7 @@ class HeaderFile:
)
]
- for macro in self.macros:
+ for macro in sorted(self.macros):
# When there is nothing to define, the Macro object converts to str
# as an empty string. Don't emit a blank line for those cases.
if str(macro):
@@ -203,7 +242,12 @@ class HeaderFile:
content.append("\n__BEGIN_C_DECLS\n")
current_guard = None
- for function in self.functions:
+ last_name = None
+ for function in sorted(self.functions):
+ # If the last function's name was the same after underscores,
+ # elide the blank line between the declarations.
+ if last_name == function.name_without_underscores():
+ content.pop()
if function.guard == None and current_guard == None:
content.append(str(function) + " __NOEXCEPT;")
content.append("")
@@ -225,6 +269,7 @@ class HeaderFile:
content.append(f"#ifdef {current_guard}")
content.append(str(function) + " __NOEXCEPT;")
content.append("")
+ last_name = function.name_without_underscores()
if current_guard != None:
content.pop()
content.append(f"#endif // {current_guard}")
diff --git a/libc/utils/hdrgen/hdrgen/macro.py b/libc/utils/hdrgen/hdrgen/macro.py
index e42e828..4664d9f 100644
--- a/libc/utils/hdrgen/hdrgen/macro.py
+++ b/libc/utils/hdrgen/hdrgen/macro.py
@@ -6,25 +6,15 @@
#
# ==-------------------------------------------------------------------------==#
-from functools import total_ordering
+from hdrgen.symbol import Symbol
-@total_ordering
-class Macro:
+class Macro(Symbol):
def __init__(self, name, value=None, header=None):
- self.name = name
+ super().__init__(name)
self.value = value
self.header = header
- def __eq__(self, other):
- return self.name == other.name
-
- def __lt__(self, other):
- return self.name < other.name
-
- def __hash__(self):
- return self.name.__hash__()
-
def __str__(self):
if self.header != None:
return ""
diff --git a/libc/utils/hdrgen/hdrgen/main.py b/libc/utils/hdrgen/hdrgen/main.py
index 25df41e..c12e89e 100755
--- a/libc/utils/hdrgen/hdrgen/main.py
+++ b/libc/utils/hdrgen/hdrgen/main.py
@@ -105,6 +105,7 @@ def main():
return 2
header.merge(merge_from_header)
+ assert header.name, f"`header: name.h` line is required in {yaml_file}"
return header
if args.json:
diff --git a/libc/utils/hdrgen/hdrgen/object.py b/libc/utils/hdrgen/hdrgen/object.py
index a311c37..a2ab496b 100644
--- a/libc/utils/hdrgen/hdrgen/object.py
+++ b/libc/utils/hdrgen/hdrgen/object.py
@@ -6,23 +6,13 @@
#
# ==-------------------------------------------------------------------------==#
-from functools import total_ordering
+from hdrgen.symbol import Symbol
-@total_ordering
-class Object:
+class Object(Symbol):
def __init__(self, name, type):
- self.name = name
+ super().__init__(name)
self.type = type
- def __eq__(self, other):
- return self.name == other.name
-
- def __lt__(self, other):
- return self.name < other.name
-
- def __hash__(self):
- return self.name.__hash__()
-
def __str__(self):
return f"extern {self.type} {self.name};"
diff --git a/libc/utils/hdrgen/hdrgen/symbol.py b/libc/utils/hdrgen/hdrgen/symbol.py
new file mode 100644
index 0000000..28e9def
--- /dev/null
+++ b/libc/utils/hdrgen/hdrgen/symbol.py
@@ -0,0 +1,41 @@
+# ====-- Symbol class for libc function headers----------------*- python -*--==#
+#
+# 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
+#
+# ==-------------------------------------------------------------------------==#
+
+from functools import total_ordering
+
+
+@total_ordering
+class Symbol:
+ """
+ Symbol is the common superclass for each kind of entity named by an
+ identifier. It provides the name field, and defines sort ordering,
+ hashing, and equality based only on the name. The sorting is pretty
+ presentation order for identifiers, which is to say it first sorts
+ lexically but ignores leading underscores and secondarily sorts with the
+ fewest underscores first.
+ """
+
+ def __init__(self, name):
+ assert name
+ self.name = name
+
+ def __eq__(self, other):
+ return self.name == other.name
+
+ def __hash__(self):
+ return self.name.__hash__()
+
+ def name_without_underscores(self):
+ return self.name.lstrip("_")
+
+ def name_sort_key(self):
+ ident = self.name_without_underscores()
+ return ident, len(self.name) - len(ident)
+
+ def __lt__(self, other):
+ return self.name_sort_key() < other.name_sort_key()
diff --git a/libc/utils/hdrgen/hdrgen/type.py b/libc/utils/hdrgen/hdrgen/type.py
index 0c0af85..20c1881 100644
--- a/libc/utils/hdrgen/hdrgen/type.py
+++ b/libc/utils/hdrgen/hdrgen/type.py
@@ -6,20 +6,10 @@
#
# ==-------------------------------------------------------------------------==#
-from functools import total_ordering
+from hdrgen.symbol import Symbol
-@total_ordering
-class Type:
- def __init__(self, type_name):
- assert type_name
- self.type_name = type_name
-
- def __eq__(self, other):
- return self.type_name == other.type_name
-
- def __lt__(self, other):
- return self.type_name < other.type_name
-
- def __hash__(self):
- return self.type_name.__hash__()
+class Type(Symbol):
+ # A type so far carries no specific information beyond its name.
+ def __init__(self, name):
+ super().__init__(name)
diff --git a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
index ebe7781d..9eddbe6 100644
--- a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
+++ b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
@@ -37,6 +37,8 @@ def yaml_to_classes(yaml_data, header_class, entry_points=None):
header = header_class(header_name)
header.template_file = yaml_data.get("header_template")
header.standards = yaml_data.get("standards", [])
+ header.extra_standards = yaml_data.get("extra_standards", {})
+ header.license_text = yaml_data.get("license_text", [])
header.merge_yaml_files = yaml_data.get("merge_yaml_files", [])
for macro_data in yaml_data.get("macros", []):
diff --git a/libc/utils/hdrgen/tests/expected_output/custom.h b/libc/utils/hdrgen/tests/expected_output/custom.h
new file mode 100644
index 0000000..5f9ed23
--- /dev/null
+++ b/libc/utils/hdrgen/tests/expected_output/custom.h
@@ -0,0 +1,21 @@
+//===-- Wile E. Coyote header <custom.h> --===//
+//
+// Caveat emptor.
+// I never studied law.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LLVM_LIBC_CUSTOM_H
+#define _LLVM_LIBC_CUSTOM_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-types/meep.h"
+#include "llvm-libc-types/road.h"
+
+__BEGIN_C_DECLS
+
+road runner(meep, meep) __NOEXCEPT;
+
+__END_C_DECLS
+
+#endif // _LLVM_LIBC_CUSTOM_H
diff --git a/libc/utils/hdrgen/tests/expected_output/sorting.h b/libc/utils/hdrgen/tests/expected_output/sorting.h
new file mode 100644
index 0000000..a091a42
--- /dev/null
+++ b/libc/utils/hdrgen/tests/expected_output/sorting.h
@@ -0,0 +1,24 @@
+//===-- Standard C header <sorting.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_SORTING_H
+#define _LLVM_LIBC_SORTING_H
+
+#include "__llvm-libc-common.h"
+
+__BEGIN_C_DECLS
+
+void func_with_aliases(int) __NOEXCEPT;
+void _func_with_aliases(int) __NOEXCEPT;
+void __func_with_aliases(int) __NOEXCEPT;
+
+void gunk(const char *) __NOEXCEPT;
+
+__END_C_DECLS
+
+#endif // _LLVM_LIBC_SORTING_H
diff --git a/libc/utils/hdrgen/tests/expected_output/test_header.h b/libc/utils/hdrgen/tests/expected_output/test_header.h
index 748c098..49112a3 100644
--- a/libc/utils/hdrgen/tests/expected_output/test_header.h
+++ b/libc/utils/hdrgen/tests/expected_output/test_header.h
@@ -12,6 +12,7 @@
#include "__llvm-libc-common.h"
#include "llvm-libc-macros/float16-macros.h"
+#include "llvm-libc-macros/CONST_FUNC_A.h"
#include "llvm-libc-macros/test_more-macros.h"
#include "llvm-libc-macros/test_small-macros.h"
#include "llvm-libc-types/float128.h"
diff --git a/libc/utils/hdrgen/tests/expected_output/test_small.json b/libc/utils/hdrgen/tests/expected_output/test_small.json
index 9cc73d0..8502df2 100644
--- a/libc/utils/hdrgen/tests/expected_output/test_small.json
+++ b/libc/utils/hdrgen/tests/expected_output/test_small.json
@@ -4,6 +4,7 @@
"standards": [],
"includes": [
"__llvm-libc-common.h",
+ "llvm-libc-macros/CONST_FUNC_A.h",
"llvm-libc-macros/test_more-macros.h",
"llvm-libc-macros/test_small-macros.h",
"llvm-libc-types/float128.h",
diff --git a/libc/utils/hdrgen/tests/input/custom-common.yaml b/libc/utils/hdrgen/tests/input/custom-common.yaml
new file mode 100644
index 0000000..909a3ba
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/custom-common.yaml
@@ -0,0 +1,6 @@
+license_text:
+ - Caveat emptor.
+ - I never studied law.
+
+extra_standards:
+ acme: Wile E. Coyote
diff --git a/libc/utils/hdrgen/tests/input/custom.yaml b/libc/utils/hdrgen/tests/input/custom.yaml
new file mode 100644
index 0000000..7d3ff8e
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/custom.yaml
@@ -0,0 +1,13 @@
+merge_yaml_files:
+ - custom-common.yaml
+
+header: custom.h
+standards:
+ - acme
+
+functions:
+ - name: runner
+ return_type: road
+ arguments:
+ - type: meep
+ - type: meep
diff --git a/libc/utils/hdrgen/tests/input/sorting.yaml b/libc/utils/hdrgen/tests/input/sorting.yaml
new file mode 100644
index 0000000..3c26cde
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/sorting.yaml
@@ -0,0 +1,20 @@
+header: sorting.h
+standards:
+ - stdc
+functions:
+ - name: gunk
+ return_type: void
+ arguments:
+ - type: const char *
+ - name: _func_with_aliases
+ return_type: void
+ arguments:
+ - type: int
+ - name: func_with_aliases
+ return_type: void
+ arguments:
+ - type: int
+ - name: __func_with_aliases
+ return_type: void
+ arguments:
+ - type: int
diff --git a/libc/utils/hdrgen/tests/test_integration.py b/libc/utils/hdrgen/tests/test_integration.py
index bf393d2..b975d8f 100644
--- a/libc/utils/hdrgen/tests/test_integration.py
+++ b/libc/utils/hdrgen/tests/test_integration.py
@@ -59,6 +59,13 @@ class TestHeaderGenIntegration(unittest.TestCase):
self.run_script(yaml_file, output_file)
self.compare_files(output_file, expected_output_file)
+ def test_custom_license_and_standards(self):
+ yaml_file = self.source_dir / "input" / "custom.yaml"
+ expected_output_file = self.source_dir / "expected_output" / "custom.h"
+ output_file = self.output_dir / "custom.h"
+ self.run_script(yaml_file, output_file)
+ self.compare_files(output_file, expected_output_file)
+
def test_generate_json(self):
yaml_file = self.source_dir / "input/test_small.yaml"
expected_output_file = self.source_dir / "expected_output/test_small.json"
@@ -68,6 +75,13 @@ class TestHeaderGenIntegration(unittest.TestCase):
self.compare_files(output_file, expected_output_file)
+ def test_sorting(self):
+ yaml_file = self.source_dir / "input" / "sorting.yaml"
+ expected_output_file = self.source_dir / "expected_output" / "sorting.h"
+ output_file = self.output_dir / "sorting.h"
+ self.run_script(yaml_file, output_file)
+ self.compare_files(output_file, expected_output_file)
+
def main():
parser = argparse.ArgumentParser(description="TestHeaderGenIntegration arguments")