[libc] Implement locale variants for 'stdlib.h' functions (#105718)

Summary:
This provides the `_l` variants for the `stdlib.h` functions. These are
just copies of the same entrypoint and don't do anything with the locale
information.
This commit is contained in:
Joseph Huber 2024-08-29 14:18:37 -05:00 committed by GitHub
parent a0441ced7a
commit a87105121d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 532 additions and 0 deletions

View File

@ -173,12 +173,19 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.rand
libc.src.stdlib.srand
libc.src.stdlib.strtod
libc.src.stdlib.strtod_l
libc.src.stdlib.strtof
libc.src.stdlib.strtof_l
libc.src.stdlib.strtol
libc.src.stdlib.strtol_l
libc.src.stdlib.strtold
libc.src.stdlib.strtold_l
libc.src.stdlib.strtoll
libc.src.stdlib.strtoll_l
libc.src.stdlib.strtoul
libc.src.stdlib.strtoul_l
libc.src.stdlib.strtoull
libc.src.stdlib.strtoull_l
libc.src.stdlib.at_quick_exit
libc.src.stdlib.quick_exit
libc.src.stdlib.getenv

View File

@ -800,6 +800,15 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.ctype.tolower_l
libc.src.ctype.toupper_l
# stdlib.h entrypoints
libc.src.stdlib.strtod_l
libc.src.stdlib.strtof_l
libc.src.stdlib.strtol_l
libc.src.stdlib.strtold_l
libc.src.stdlib.strtoll_l
libc.src.stdlib.strtoul_l
libc.src.stdlib.strtoull_l
# assert.h entrypoints
libc.src.assert.__assert_fail

View File

@ -17,6 +17,11 @@
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#ifndef MB_CUR_MAX
// We only support the "C" locale right now, so this is a constant byte.
#define MB_CUR_MAX 1
#endif // MB_CUR_MAX
#define RAND_MAX 2147483647
#endif // LLVM_LIBC_MACROS_STDLIB_MACROS_H

View File

@ -10,6 +10,7 @@
#define LLVM_LIBC_STDLIB_H
#include "__llvm-libc-common.h"
#include "llvm-libc-types/locale_t.h"
#include "llvm-libc-macros/stdlib-macros.h"
%%public_api()

View File

@ -273,3 +273,63 @@ functions:
- type: const char *__restrict
- type: char **__restrict
- type: int
- name: strtod_l
standards:
- stdc
return_type: double
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: locale_t
- name: strtof_l
standards:
- stdc
return_type: float
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: locale_t
- name: strtol_l
standards:
- stdc
return_type: long
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: int
- type: locale_t
- name: strtold_l
standards:
- stdc
return_type: long double
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: locale_t
- name: strtoll_l
standards:
- stdc
return_type: long long
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: int
- type: locale_t
- name: strtoul_l
standards:
- stdc
return_type: unsigned long
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: int
- type: locale_t
- name: strtoull_l
standards:
- stdc
return_type: unsigned long long
arguments:
- type: const char *__restrict
- type: char **__restrict
- type: int
- type: locale_t

View File

@ -1308,6 +1308,14 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtof", RetValSpec<FloatType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtod", RetValSpec<DoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtold", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtol", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>, ArgSpec<LocaleT>]>,
FunctionSpec<"malloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>]>,
FunctionSpec<"calloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>, ArgSpec<SizeTType>]>,
FunctionSpec<"realloc", RetValSpec<VoidPtr>, [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]>,

View File

@ -428,6 +428,83 @@ if(NOT LLVM_LIBC_FULL_BUILD)
return()
endif()
add_entrypoint_object(
strtof_l
SRCS
strtof_l.cpp
HDRS
strtof_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_float
)
add_entrypoint_object(
strtod_l
SRCS
strtod_l.cpp
HDRS
strtod_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_float
)
add_entrypoint_object(
strtold_l
SRCS
strtold_l.cpp
HDRS
strtold_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_float
)
add_entrypoint_object(
strtol_l
SRCS
strtol_l.cpp
HDRS
strtol_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_integer
)
add_entrypoint_object(
strtoll_l
SRCS
strtoll_l.cpp
HDRS
strtoll_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_integer
)
add_entrypoint_object(
strtoul_l
SRCS
strtoul_l.cpp
HDRS
strtoul_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_integer
)
add_entrypoint_object(
strtoull_l
SRCS
strtoull_l.cpp
HDRS
strtoull_l.h
DEPENDS
libc.src.errno.errno
libc.src.__support.str_to_integer
)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtod_l ----------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtod_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_float.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(double, strtod_l,
(const char *__restrict str, char **__restrict str_end,
locale_t)) {
auto result = internal::strtofloatingpoint<double>(str);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtod_l ----------------------*- 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_STDLIB_STRTOD_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOD_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
double strtod_l(const char *__restrict str, char **__restrict str_end,
locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOD_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtof_l ----------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtof_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_float.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, strtof_l,
(const char *__restrict str, char **__restrict str_end,
locale_t)) {
auto result = internal::strtofloatingpoint<float>(str);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtof_l ----------------------*- 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_STDLIB_STRTOF_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOF_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
float strtof_l(const char *__restrict str, char **__restrict str_end,
locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOF_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtol_l ----------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtol_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long, strtol_l,
(const char *__restrict str, char **__restrict str_end,
int base, locale_t)) {
auto result = internal::strtointeger<long>(str, base);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtol_l ----------------------*- 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_STDLIB_STRTOL_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOL_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
long strtol_l(const char *__restrict str, char **__restrict str_end, int base,
locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOL_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtold_l ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtold_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_float.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long double, strtold_l,
(const char *__restrict str, char **__restrict str_end,
locale_t)) {
auto result = internal::strtofloatingpoint<long double>(str);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result.value;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtold_l ---------------------*- 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_STDLIB_STRTOLD_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
long double strtold_l(const char *__restrict str, char **__restrict str_end,
locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOLD_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtoll_l ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtoll_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long long, strtoll_l,
(const char *__restrict str, char **__restrict str_end,
int base, locale_t)) {
auto result = internal::strtointeger<long long>(str, base);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtoll_l ---------------------*- 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_STDLIB_STRTOLL_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
long long strtoll_l(const char *__restrict str, char **__restrict str_end,
int base, locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOLL_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtoul_l ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtoul_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(unsigned long, strtoul_l,
(const char *__restrict str, char **__restrict str_end,
int base, locale_t)) {
auto result = internal::strtointeger<unsigned long>(str, base);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,22 @@
//===-- Implementation header for strtoul_l ---------------------*- 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_STDLIB_STRTOUL_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOUL_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
unsigned long strtoul_l(const char *__restrict str, char **__restrict str_end,
int base, locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOUL_L_H

View File

@ -0,0 +1,30 @@
//===-- Implementation of strtoull_l --------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/strtoull_l.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(unsigned long long, strtoull_l,
(const char *__restrict str, char **__restrict str_end,
int base, locale_t)) {
auto result = internal::strtointeger<unsigned long long>(str, base);
if (result.has_error())
libc_errno = result.error;
if (str_end != nullptr)
*str_end = const_cast<char *>(str + result.parsed_len);
return result;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@ -0,0 +1,23 @@
//===-- Implementation header for strtoull_l --------------------*- 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_STDLIB_STRTOULL_L_H
#define LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H
#include "include/llvm-libc-types/locale_t.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
unsigned long long strtoull_l(const char *__restrict str,
char **__restrict str_end, int base,
locale_t locale);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STDLIB_STRTOULL_L_H