[libc-commits] [libc] 5bf8efd - [libc] Fix more inline definitions
Roland McGrath via libc-commits
libc-commits at lists.llvm.org
Fri Jun 30 14:46:46 PDT 2023
Author: Roland McGrath
Date: 2023-06-30T14:46:25-07:00
New Revision: 5bf8efd269f8b75b5be40f087f231d71f744885c
URL: https://github.com/llvm/llvm-project/commit/5bf8efd269f8b75b5be40f087f231d71f744885c
DIFF: https://github.com/llvm/llvm-project/commit/5bf8efd269f8b75b5be40f087f231d71f744885c.diff
LOG: [libc] Fix more inline definitions
Fix a bunch more instances of incorrect use of the `static`
keyword and missing use of LIBC_INLINE and LIBC_INLINE_VAR
macros. Note that even forward declarations and generic template
declarations must follow the prescribed patterns for libc code so
that they match every definition, all template specializations.
Reviewed By: Caslyn
Differential Revision: https://reviews.llvm.org/D154260
Added:
Modified:
libc/src/__support/CPP/optional.h
libc/src/__support/CPP/span.h
libc/src/__support/CPP/string_view.h
libc/src/__support/CPP/type_traits.h
libc/src/__support/StringUtil/tables/linux_extension_signals.h
libc/src/__support/StringUtil/tables/linux_platform_errors.h
libc/src/__support/StringUtil/tables/linux_platform_signals.h
libc/src/__support/StringUtil/tables/minimal_platform_errors.h
libc/src/__support/StringUtil/tables/minimal_platform_signals.h
libc/src/__support/StringUtil/tables/posix_errors.h
libc/src/__support/StringUtil/tables/posix_signals.h
libc/src/__support/StringUtil/tables/signal_table.h
libc/src/__support/StringUtil/tables/stdc_errors.h
libc/src/__support/StringUtil/tables/stdc_signals.h
libc/src/__support/UInt.h
libc/src/__support/threads/linux/thread.cpp
libc/src/stdio/printf_core/write_int_converter.h
libc/src/string/memory_utils/op_aarch64.h
libc/src/string/memory_utils/op_generic.h
libc/src/string/memory_utils/op_x86.h
libc/src/string/memory_utils/strcmp_implementations.h
libc/src/string/memory_utils/strstr_implementations.h
libc/src/string/memory_utils/utils.h
libc/src/string/string_utils.h
Removed:
################################################################################
diff --git a/libc/src/__support/CPP/optional.h b/libc/src/__support/CPP/optional.h
index 40ba858f5eaf16..8b3959514108d4 100644
--- a/libc/src/__support/CPP/optional.h
+++ b/libc/src/__support/CPP/optional.h
@@ -18,19 +18,19 @@ namespace cpp {
// Trivial in_place_t struct.
struct in_place_t {
- LIBC_INLINE explicit in_place_t() = default;
+ LIBC_INLINE_VAR explicit in_place_t() = default;
};
// Trivial nullopt_t struct.
struct nullopt_t {
- LIBC_INLINE explicit nullopt_t() = default;
+ LIBC_INLINE_VAR explicit nullopt_t() = default;
};
// nullopt that can be used and returned.
-inline constexpr nullopt_t nullopt{};
+LIBC_INLINE_VAR constexpr nullopt_t nullopt{};
// in_place that can be used in the constructor.
-inline constexpr in_place_t in_place{};
+LIBC_INLINE_VAR constexpr in_place_t in_place{};
// This is very simple implementation of the std::optional class. It makes
// several assumptions that the underlying type is trivially constructable,
diff --git a/libc/src/__support/CPP/span.h b/libc/src/__support/CPP/span.h
index dc3960e75f61f0..bc64d0d7b36d94 100644
--- a/libc/src/__support/CPP/span.h
+++ b/libc/src/__support/CPP/span.h
@@ -13,6 +13,8 @@
#include "array.h" // For array
#include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v
+#include "src/__support/macros/attributes.h"
+
namespace __llvm_libc::cpp {
// A trimmed down implementation of std::span.
@@ -25,12 +27,12 @@ namespace __llvm_libc::cpp {
// - No reverse iterators
template <typename T> class span {
template <typename U>
- inline static constexpr bool is_const_view_v =
+ LIBC_INLINE_VAR static constexpr bool is_const_view_v =
!cpp::is_const_v<U> && cpp::is_const_v<T> &&
cpp::is_same_v<U, remove_cv_t<T>>;
template <typename U>
- inline static constexpr bool is_compatible_v =
+ LIBC_INLINE_VAR static constexpr bool is_compatible_v =
cpp::is_same_v<U, T> || is_const_view_v<U>;
public:
@@ -46,61 +48,67 @@ template <typename T> class span {
static constexpr size_type dynamic_extent = -1;
- constexpr span() : span_data(nullptr), span_size(0) {}
+ LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}
- constexpr span(pointer first, size_type count)
+ LIBC_INLINE constexpr span(pointer first, size_type count)
: span_data(first), span_size(count) {}
- constexpr span(pointer first, pointer end)
+ LIBC_INLINE constexpr span(pointer first, pointer end)
: span_data(first), span_size(end - first) {}
template <typename U, size_t N,
cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}
+ LIBC_INLINE constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}
template <typename U, size_t N,
cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- constexpr span(array<U, N> &arr)
+ LIBC_INLINE constexpr span(array<U, N> &arr)
: span_data(arr.data()), span_size(arr.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- constexpr span(span<U> &s) : span_data(s.data()), span_size(s.size()) {}
+ LIBC_INLINE constexpr span(span<U> &s)
+ : span_data(s.data()), span_size(s.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- constexpr span &operator=(span<U> &s) {
+ LIBC_INLINE constexpr span &operator=(span<U> &s) {
span_data = s.data();
span_size = s.size();
return *this;
}
- ~span() = default;
- constexpr reference operator[](size_type index) const {
+ LIBC_INLINE ~span() = default;
+
+ LIBC_INLINE constexpr reference operator[](size_type index) const {
return data()[index];
}
- constexpr iterator begin() const { return data(); }
- constexpr iterator end() const { return data() + size(); }
- constexpr reference front() const { return (*this)[0]; }
- constexpr reference back() const { return (*this)[size() - 1]; }
- constexpr pointer data() const { return span_data; }
- constexpr size_type size() const { return span_size; }
- constexpr size_type size_bytes() const { return sizeof(T) * size(); }
- constexpr bool empty() const { return size() == 0; }
-
- constexpr span<element_type> subspan(size_type offset,
- size_type count = dynamic_extent) const {
+
+ LIBC_INLINE constexpr iterator begin() const { return data(); }
+ LIBC_INLINE constexpr iterator end() const { return data() + size(); }
+ LIBC_INLINE constexpr reference front() const { return (*this)[0]; }
+ LIBC_INLINE constexpr reference back() const { return (*this)[size() - 1]; }
+ LIBC_INLINE constexpr pointer data() const { return span_data; }
+ LIBC_INLINE constexpr size_type size() const { return span_size; }
+ LIBC_INLINE constexpr size_type size_bytes() const {
+ return sizeof(T) * size();
+ }
+ LIBC_INLINE constexpr bool empty() const { return size() == 0; }
+
+ LIBC_INLINE constexpr span<element_type>
+ subspan(size_type offset, size_type count = dynamic_extent) const {
return span<element_type>(data() + offset, count_to_size(offset, count));
}
- constexpr span<element_type> first(size_type count) const {
+ LIBC_INLINE constexpr span<element_type> first(size_type count) const {
return subspan(0, count);
}
- constexpr span<element_type> last(size_type count) const {
+ LIBC_INLINE constexpr span<element_type> last(size_type count) const {
return span<element_type>(data() + (size() - count), count);
}
private:
- constexpr size_type count_to_size(size_type offset, size_type count) const {
+ LIBC_INLINE constexpr size_type count_to_size(size_type offset,
+ size_type count) const {
if (count == dynamic_extent) {
return size() - offset;
}
diff --git a/libc/src/__support/CPP/string_view.h b/libc/src/__support/CPP/string_view.h
index aa31f15d97c66e..e4e3f89f933541 100644
--- a/libc/src/__support/CPP/string_view.h
+++ b/libc/src/__support/CPP/string_view.h
@@ -60,7 +60,7 @@ class string_view {
// special value equal to the maximum value representable by the type
// size_type.
- inline static constexpr size_t npos = -1;
+ LIBC_INLINE_VAR static constexpr size_t npos = -1;
LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {}
diff --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h
index 63ff10c58135bf..5808e92f6816a5 100644
--- a/libc/src/__support/CPP/type_traits.h
+++ b/libc/src/__support/CPP/type_traits.h
@@ -9,6 +9,8 @@
#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPETRAITS_H
#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPETRAITS_H
+#include "src/__support/macros/attributes.h"
+
namespace __llvm_libc {
namespace cpp {
@@ -23,7 +25,7 @@ using enable_if_t = typename enable_if<B, T>::type;
template <typename T, T v> struct integral_constant {
using value_type = T;
- static constexpr T value = v;
+ LIBC_INLINE_VAR static constexpr T value = v;
};
using true_type = cpp::integral_constant<bool, true>;
using false_type = cpp::integral_constant<bool, false>;
@@ -39,11 +41,12 @@ struct is_trivially_constructible
template <typename T, typename U> struct is_same : cpp::false_type {};
template <typename T> struct is_same<T, T> : cpp::true_type {};
template <typename T, typename U>
-inline constexpr bool is_same_v = is_same<T, U>::value;
+LIBC_INLINE_VAR constexpr bool is_same_v = is_same<T, U>::value;
template <class T> struct is_const : cpp::false_type {};
template <class T> struct is_const<const T> : cpp::true_type {};
-template <class T> inline constexpr bool is_const_v = is_const<T>::value;
+template <class T>
+LIBC_INLINE_VAR constexpr bool is_const_v = is_const<T>::value;
template <typename T> struct remove_cv : type_identity<T> {};
template <typename T> struct remove_cv<const T> : type_identity<T> {};
@@ -71,7 +74,7 @@ template <typename T, typename... Args> constexpr bool is_unqualified_any_of() {
} // namespace details
template <typename T> struct is_integral {
- static constexpr bool value = details::is_unqualified_any_of<
+ LIBC_INLINE_VAR static constexpr bool value = details::is_unqualified_any_of<
T,
#ifdef __SIZEOF_INT128__
__int128_t, __uint128_t,
@@ -80,33 +83,36 @@ template <typename T> struct is_integral {
unsigned int, long, unsigned long, long long, unsigned long long, bool>();
};
template <typename T>
-inline constexpr bool is_integral_v = is_integral<T>::value;
+LIBC_INLINE_VAR constexpr bool is_integral_v = is_integral<T>::value;
template <typename T> struct is_enum {
- static constexpr bool value = __is_enum(T);
+ LIBC_INLINE_VAR static constexpr bool value = __is_enum(T);
};
-template <typename T> inline constexpr bool is_enum_v = is_enum<T>::value;
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_enum_v = is_enum<T>::value;
template <typename T> struct is_pointer : cpp::false_type {};
template <typename T> struct is_pointer<T *> : cpp::true_type {};
template <typename T> struct is_pointer<T *const> : cpp::true_type {};
template <typename T> struct is_pointer<T *volatile> : cpp::true_type {};
template <typename T> struct is_pointer<T *const volatile> : cpp::true_type {};
-template <typename T> inline constexpr bool is_pointer_v = is_pointer<T>::value;
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_pointer_v = is_pointer<T>::value;
template <typename T> struct is_floating_point {
- static constexpr bool value =
+ LIBC_INLINE_VAR static constexpr bool value =
details::is_unqualified_any_of<T, float, double, long double>();
};
template <typename T>
-inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
+LIBC_INLINE_VAR constexpr bool is_floating_point_v =
+ is_floating_point<T>::value;
template <typename T> struct is_arithmetic {
- static constexpr bool value =
+ LIBC_INLINE_VAR static constexpr bool value =
is_integral<T>::value || is_floating_point<T>::value;
};
template <typename T>
-inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
+LIBC_INLINE_VAR constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
namespace details {
template <typename T, bool = is_arithmetic<T>::value>
@@ -119,19 +125,20 @@ template <typename T> struct is_unsigned<T, false> : false_type {};
} // namespace details
template <typename T> struct is_signed {
- static constexpr bool value = details::is_signed<T>::value;
- constexpr operator bool() const { return value; }
- constexpr bool operator()() const { return value; }
+ LIBC_INLINE_VAR static constexpr bool value = details::is_signed<T>::value;
+ LIBC_INLINE constexpr operator bool() const { return value; }
+ LIBC_INLINE constexpr bool operator()() const { return value; }
};
-template <typename T> inline constexpr bool is_signed_v = is_signed<T>::value;
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value;
template <typename T> struct is_unsigned {
- static constexpr bool value = details::is_unsigned<T>::value;
- constexpr operator bool() const { return value; }
- constexpr bool operator()() const { return value; }
+ LIBC_INLINE_VAR static constexpr bool value = details::is_unsigned<T>::value;
+ LIBC_INLINE constexpr operator bool() const { return value; }
+ LIBC_INLINE constexpr bool operator()() const { return value; }
};
template <typename T>
-inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
+LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
template <typename T> struct make_unsigned;
template <> struct make_unsigned<char> : type_identity<unsigned char> {};
@@ -166,7 +173,8 @@ using conditional_t = typename conditional<B, T, F>::type;
template <typename T>
struct is_void : is_same<void, typename remove_cv<T>::type> {};
-template <typename T> inline constexpr bool is_void_v = is_void<T>::value;
+template <typename T>
+LIBC_INLINE_VAR constexpr bool is_void_v = is_void<T>::value;
template <class T> T declval();
// Compile time checks on implicit conversions.
@@ -176,10 +184,12 @@ template <typename T> void convertible_to_helper(T);
} // namespace details
template <typename F, typename T, typename = void>
-inline constexpr bool is_convertible_v = false;
+LIBC_INLINE_VAR constexpr bool is_convertible_v = false;
+// FIXME: This should use LIBC_INLINE_VAR, but clang buggily complains about
+// this when LIBC_INLINE_VAR uses [[clang::internal_linkage]].
template <typename F, typename T>
-inline constexpr bool
+constexpr bool
is_convertible_v<F, T,
details::void_t<decltype(details::convertible_to_helper<T>(
declval<F>()))>> = true;
diff --git a/libc/src/__support/StringUtil/tables/linux_extension_signals.h b/libc/src/__support/StringUtil/tables/linux_extension_signals.h
index 7e310096086876..8da3731e398722 100644
--- a/libc/src/__support/StringUtil/tables/linux_extension_signals.h
+++ b/libc/src/__support/StringUtil/tables/linux_extension_signals.h
@@ -18,7 +18,7 @@ namespace __llvm_libc {
// The array being larger than necessary isn't a problem. The MsgMappings will
// be set to their default state which maps 0 to an empty string. This will get
// filtered out in the MessageMapper building stage.
-inline constexpr const MsgTable<3> LINUX_SIGNALS = {
+LIBC_INLINE_VAR constexpr const MsgTable<3> LINUX_SIGNALS = {
#ifdef SIGSTKFLT
MsgMapping(SIGSTKFLT, "Stack fault"), // unused
#endif
diff --git a/libc/src/__support/StringUtil/tables/linux_platform_errors.h b/libc/src/__support/StringUtil/tables/linux_platform_errors.h
index e6d20106f25268..49e4b1bd2a4286 100644
--- a/libc/src/__support/StringUtil/tables/linux_platform_errors.h
+++ b/libc/src/__support/StringUtil/tables/linux_platform_errors.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-inline constexpr auto PLATFORM_ERRORS =
+LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS =
STDC_ERRORS + POSIX_ERRORS + LINUX_ERRORS;
} // namespace __llvm_libc
diff --git a/libc/src/__support/StringUtil/tables/linux_platform_signals.h b/libc/src/__support/StringUtil/tables/linux_platform_signals.h
index 7f98a241f9c40c..b21b0ccf89aef0 100644
--- a/libc/src/__support/StringUtil/tables/linux_platform_signals.h
+++ b/libc/src/__support/StringUtil/tables/linux_platform_signals.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-inline constexpr auto PLATFORM_SIGNALS =
+LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS =
STDC_SIGNALS + POSIX_SIGNALS + LINUX_SIGNALS;
} // namespace __llvm_libc
diff --git a/libc/src/__support/StringUtil/tables/minimal_platform_errors.h b/libc/src/__support/StringUtil/tables/minimal_platform_errors.h
index 9fa75d5c9a76ad..950b84be204994 100644
--- a/libc/src/__support/StringUtil/tables/minimal_platform_errors.h
+++ b/libc/src/__support/StringUtil/tables/minimal_platform_errors.h
@@ -13,7 +13,7 @@
namespace __llvm_libc {
-inline constexpr auto PLATFORM_ERRORS = STDC_ERRORS;
+LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS = STDC_ERRORS;
} // namespace __llvm_libc
diff --git a/libc/src/__support/StringUtil/tables/minimal_platform_signals.h b/libc/src/__support/StringUtil/tables/minimal_platform_signals.h
index 758dfc8263da2b..e1a77803895f1a 100644
--- a/libc/src/__support/StringUtil/tables/minimal_platform_signals.h
+++ b/libc/src/__support/StringUtil/tables/minimal_platform_signals.h
@@ -13,7 +13,7 @@
namespace __llvm_libc {
-inline constexpr auto PLATFORM_SIGNALS = STDC_SIGNALS;
+LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS = STDC_SIGNALS;
} // namespace __llvm_libc
diff --git a/libc/src/__support/StringUtil/tables/posix_errors.h b/libc/src/__support/StringUtil/tables/posix_errors.h
index 43b1d9dec562e9..01a0f223d6679a 100644
--- a/libc/src/__support/StringUtil/tables/posix_errors.h
+++ b/libc/src/__support/StringUtil/tables/posix_errors.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-inline constexpr MsgTable<76> POSIX_ERRORS = {
+LIBC_INLINE_VAR constexpr MsgTable<76> POSIX_ERRORS = {
MsgMapping(EPERM, "Operation not permitted"),
MsgMapping(ENOENT, "No such file or directory"),
MsgMapping(ESRCH, "No such process"),
diff --git a/libc/src/__support/StringUtil/tables/posix_signals.h b/libc/src/__support/StringUtil/tables/posix_signals.h
index b34035d367e88d..a7e681b92449c3 100644
--- a/libc/src/__support/StringUtil/tables/posix_signals.h
+++ b/libc/src/__support/StringUtil/tables/posix_signals.h
@@ -16,7 +16,7 @@
namespace __llvm_libc {
-inline constexpr MsgTable<22> POSIX_SIGNALS = {
+LIBC_INLINE_VAR constexpr MsgTable<22> POSIX_SIGNALS = {
MsgMapping(SIGHUP, "Hangup"),
MsgMapping(SIGQUIT, "Quit"),
MsgMapping(SIGTRAP, "Trace/breakpoint trap"),
diff --git a/libc/src/__support/StringUtil/tables/signal_table.h b/libc/src/__support/StringUtil/tables/signal_table.h
index c2b1b36df659c0..6e198a60c9b32e 100644
--- a/libc/src/__support/StringUtil/tables/signal_table.h
+++ b/libc/src/__support/StringUtil/tables/signal_table.h
@@ -26,7 +26,7 @@
namespace __llvm_libc::internal {
-inline constexpr auto PLATFORM_SIGNALS = []() {
+LIBC_INLINE_VAR constexpr auto PLATFORM_SIGNALS = []() {
if constexpr (USE_LINUX_PLATFORM_SIGNALS) {
return STDC_SIGNALS + POSIX_SIGNALS + LINUX_SIGNALS;
} else {
diff --git a/libc/src/__support/StringUtil/tables/stdc_errors.h b/libc/src/__support/StringUtil/tables/stdc_errors.h
index 42b934f1ba9c3d..42d370583d7536 100644
--- a/libc/src/__support/StringUtil/tables/stdc_errors.h
+++ b/libc/src/__support/StringUtil/tables/stdc_errors.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-inline constexpr const MsgTable<4> STDC_ERRORS = {
+LIBC_INLINE_VAR constexpr const MsgTable<4> STDC_ERRORS = {
MsgMapping(0, "Success"),
MsgMapping(EDOM, "Numerical argument out of domain"),
MsgMapping(ERANGE, "Numerical result out of range"),
diff --git a/libc/src/__support/StringUtil/tables/stdc_signals.h b/libc/src/__support/StringUtil/tables/stdc_signals.h
index 3de4318ed8f6f0..13b1aeda124bd7 100644
--- a/libc/src/__support/StringUtil/tables/stdc_signals.h
+++ b/libc/src/__support/StringUtil/tables/stdc_signals.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-inline constexpr const MsgTable<6> STDC_SIGNALS = {
+LIBC_INLINE_VAR constexpr const MsgTable<6> STDC_SIGNALS = {
MsgMapping(SIGINT, "Interrupt"),
MsgMapping(SIGILL, "Illegal instruction"),
MsgMapping(SIGABRT, "Aborted"),
diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index 74b72b59e1ddd9..a748d47cd06cc8 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -27,20 +27,20 @@ template <size_t Bits, bool Signed> struct BigInt {
static_assert(Bits > 0 && Bits % 64 == 0,
"Number of bits in BigInt should be a multiple of 64.");
- static constexpr size_t WORDCOUNT = Bits / 64;
+ static LIBC_INLINE_VAR constexpr size_t WORDCOUNT = Bits / 64;
uint64_t val[WORDCOUNT]{};
- static constexpr uint64_t MASK32 = 0xFFFFFFFFu;
+ static LIBC_INLINE_VAR constexpr uint64_t MASK32 = 0xFFFFFFFFu;
- static constexpr uint64_t low(uint64_t v) { return v & MASK32; }
- static constexpr uint64_t high(uint64_t v) { return (v >> 32) & MASK32; }
+ static LIBC_INLINE constexpr uint64_t low(uint64_t v) { return v & MASK32; }
+ static LIBC_INLINE constexpr uint64_t high(uint64_t v) { return (v >> 32) & MASK32; }
- constexpr BigInt() = default;
+ LIBC_INLINE constexpr BigInt() = default;
- constexpr BigInt(const BigInt<Bits, Signed> &other) = default;
+ LIBC_INLINE constexpr BigInt(const BigInt<Bits, Signed> &other) = default;
template <size_t OtherBits, bool OtherSigned>
- constexpr BigInt(const BigInt<OtherBits, OtherSigned> &other) {
+ LIBC_INLINE constexpr BigInt(const BigInt<OtherBits, OtherSigned> &other) {
if (OtherBits >= Bits) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] = other[i];
@@ -60,7 +60,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Construct a BigInt from a C array.
template <size_t N, enable_if_t<N <= WORDCOUNT, int> = 0>
- constexpr BigInt(const uint64_t (&nums)[N]) {
+ LIBC_INLINE constexpr BigInt(const uint64_t (&nums)[N]) {
size_t min_wordcount = N < WORDCOUNT ? N : WORDCOUNT;
size_t i = 0;
for (; i < min_wordcount; ++i)
@@ -74,7 +74,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Initialize the first word to |v| and the rest to 0.
template <typename T,
typename = cpp::enable_if_t<is_integral_v<T> && sizeof(T) <= 16>>
- constexpr BigInt(T v) {
+ LIBC_INLINE constexpr BigInt(T v) {
val[0] = static_cast<uint64_t>(v);
if constexpr (Bits == 64)
@@ -93,7 +93,7 @@ template <size_t Bits, bool Signed> struct BigInt {
}
}
- constexpr explicit BigInt(const cpp::array<uint64_t, WORDCOUNT> &words) {
+ LIBC_INLINE constexpr explicit BigInt(const cpp::array<uint64_t, WORDCOUNT> &words) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] = words[i];
}
@@ -101,7 +101,7 @@ template <size_t Bits, bool Signed> struct BigInt {
template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> &&
sizeof(T) <= 16 &&
!cpp::is_same_v<T, bool>>>
- constexpr explicit operator T() const {
+ LIBC_INLINE constexpr explicit operator T() const {
if constexpr (sizeof(T) <= 8)
return static_cast<T>(val[0]);
@@ -120,11 +120,11 @@ template <size_t Bits, bool Signed> struct BigInt {
}
}
- constexpr explicit operator bool() const { return !is_zero(); }
+ LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); }
BigInt<Bits, Signed> &operator=(const BigInt<Bits, Signed> &other) = default;
- constexpr bool is_zero() const {
+ LIBC_INLINE constexpr bool is_zero() const {
for (size_t i = 0; i < WORDCOUNT; ++i) {
if (val[i] != 0)
return false;
@@ -134,7 +134,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Add x to this number and store the result in this number.
// Returns the carry value produced by the addition operation.
- constexpr uint64_t add(const BigInt<Bits, Signed> &x) {
+ LIBC_INLINE constexpr uint64_t add(const BigInt<Bits, Signed> &x) {
SumCarry<uint64_t> s{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
s = add_with_carry_const(val[i], x.val[i], s.carry);
@@ -143,7 +143,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return s.carry;
}
- BigInt<Bits, Signed> operator+(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
SumCarry<uint64_t> s{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -155,7 +155,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// This will only apply when initializing a variable from constant values, so
// it will always use the constexpr version of add_with_carry.
- constexpr BigInt<Bits, Signed> operator+(BigInt<Bits, Signed> &&other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(BigInt<Bits, Signed> &&other) const {
BigInt<Bits, Signed> result;
SumCarry<uint64_t> s{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -165,7 +165,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator+=(const BigInt<Bits, Signed> &other) {
add(other); // Returned carry value is ignored.
return *this;
@@ -173,7 +173,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Subtract x to this number and store the result in this number.
// Returns the carry value produced by the subtraction operation.
- constexpr uint64_t sub(const BigInt<Bits, Signed> &x) {
+ LIBC_INLINE constexpr uint64_t sub(const BigInt<Bits, Signed> &x) {
DiffBorrow<uint64_t> d{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
d = sub_with_borrow_const(val[i], x.val[i], d.borrow);
@@ -182,7 +182,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return d.borrow;
}
- BigInt<Bits, Signed> operator-(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE BigInt<Bits, Signed> operator-(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
DiffBorrow<uint64_t> d{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -192,7 +192,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> operator-(BigInt<Bits, Signed> &&other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator-(BigInt<Bits, Signed> &&other) const {
BigInt<Bits, Signed> result;
DiffBorrow<uint64_t> d{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -202,7 +202,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator-=(const BigInt<Bits, Signed> &other) {
// TODO(lntue): Set overflow flag / errno when carry is true.
sub(other);
@@ -215,7 +215,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// the operations using 64-bit numbers. This ensures that we don't lose the
// carry bits.
// Returns the carry value produced by the multiplication operation.
- constexpr uint64_t mul(uint64_t x) {
+ LIBC_INLINE constexpr uint64_t mul(uint64_t x) {
BigInt<128, Signed> partial_sum(0);
uint64_t carry = 0;
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -230,7 +230,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return partial_sum.val[1];
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator*(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
BigInt<Bits, false> a(*this);
@@ -271,7 +271,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Return the full product, only unsigned for now.
template <size_t OtherBits>
- constexpr BigInt<Bits + OtherBits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits + OtherBits, Signed>
ful_mul(const BigInt<OtherBits, Signed> &other) const {
BigInt<Bits + OtherBits, Signed> result(0);
BigInt<128, Signed> partial_sum(0);
@@ -317,7 +317,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// 256 4 16 10 3
// 512 8 64 36 7
constexpr BigInt<Bits, Signed>
- quick_mul_hi(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE quick_mul_hi(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result(0);
BigInt<128, Signed> partial_sum(0);
uint64_t carry = 0;
@@ -346,7 +346,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// pow takes a power and sets this to its starting value to that power. Zero
// to the zeroth power returns 1.
- constexpr void pow_n(uint64_t power) {
+ LIBC_INLINE constexpr void pow_n(uint64_t power) {
BigInt<Bits, Signed> result = 1;
BigInt<Bits, Signed> cur_power = *this;
@@ -364,7 +364,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// div takes another BigInt of the same size and divides this by it. The value
// of this will be set to the quotient, and the return value is the remainder.
- constexpr optional<BigInt<Bits, Signed>>
+ LIBC_INLINE constexpr optional<BigInt<Bits, Signed>>
div(const BigInt<Bits, Signed> &other) {
BigInt<Bits, Signed> remainder(0);
if (*this < other) {
@@ -407,7 +407,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// Since the remainder of each division step < x < 2^32, the computation of
// each step is now properly contained within uint64_t.
// And finally we perform some extra alignment steps for the remaining bits.
- constexpr optional<BigInt<Bits, Signed>> div_uint32_times_pow_2(uint32_t x,
+ LIBC_INLINE constexpr optional<BigInt<Bits, Signed>> div_uint32_times_pow_2(uint32_t x,
size_t e) {
BigInt<Bits, Signed> remainder(0);
@@ -515,32 +515,32 @@ template <size_t Bits, bool Signed> struct BigInt {
return remainder;
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator/(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result(*this);
result.div(other);
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator/=(const BigInt<Bits, Signed> &other) {
div(other);
return *this;
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator%(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result(*this);
return *result.div(other);
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator*=(const BigInt<Bits, Signed> &other) {
*this = *this * other;
return *this;
}
- constexpr uint64_t clz() {
+ LIBC_INLINE constexpr uint64_t clz() {
uint64_t leading_zeroes = 0;
for (size_t i = WORDCOUNT; i > 0; --i) {
if (val[i - 1] == 0) {
@@ -553,7 +553,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return leading_zeroes;
}
- constexpr void shift_left(size_t s) {
+ LIBC_INLINE constexpr void shift_left(size_t s) {
#ifdef __SIZEOF_INT128__
if constexpr (Bits == 128) {
// Use builtin 128 bits if available;
@@ -596,18 +596,18 @@ template <size_t Bits, bool Signed> struct BigInt {
}
}
- constexpr BigInt<Bits, Signed> operator<<(size_t s) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator<<(size_t s) const {
BigInt<Bits, Signed> result(*this);
result.shift_left(s);
return result;
}
- constexpr BigInt<Bits, Signed> &operator<<=(size_t s) {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &operator<<=(size_t s) {
shift_left(s);
return *this;
}
- constexpr void shift_right(size_t s) {
+ LIBC_INLINE constexpr void shift_right(size_t s) {
#ifdef __SIZEOF_INT128__
if constexpr (Bits == 128) {
// Use builtin 128 bits if available;
@@ -660,18 +660,18 @@ template <size_t Bits, bool Signed> struct BigInt {
}
}
- constexpr BigInt<Bits, Signed> operator>>(size_t s) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator>>(size_t s) const {
BigInt<Bits, Signed> result(*this);
result.shift_right(s);
return result;
}
- constexpr BigInt<Bits, Signed> &operator>>=(size_t s) {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &operator>>=(size_t s) {
shift_right(s);
return *this;
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator&(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
for (size_t i = 0; i < WORDCOUNT; ++i)
@@ -679,14 +679,14 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator&=(const BigInt<Bits, Signed> &other) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] &= other.val[i];
return *this;
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator|(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
for (size_t i = 0; i < WORDCOUNT; ++i)
@@ -694,14 +694,14 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator|=(const BigInt<Bits, Signed> &other) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] |= other.val[i];
return *this;
}
- constexpr BigInt<Bits, Signed>
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
operator^(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
for (size_t i = 0; i < WORDCOUNT; ++i)
@@ -709,27 +709,27 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- constexpr BigInt<Bits, Signed> &
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &
operator^=(const BigInt<Bits, Signed> &other) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] ^= other.val[i];
return *this;
}
- constexpr BigInt<Bits, Signed> operator~() const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator~() const {
BigInt<Bits, Signed> result;
for (size_t i = 0; i < WORDCOUNT; ++i)
result.val[i] = ~val[i];
return result;
}
- constexpr BigInt<Bits, Signed> operator-() const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator-() const {
BigInt<Bits, Signed> result = ~(*this);
result.add(BigInt<Bits, Signed>(1));
return result;
}
- constexpr bool operator==(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator==(const BigInt<Bits, Signed> &other) const {
for (size_t i = 0; i < WORDCOUNT; ++i) {
if (val[i] != other.val[i])
return false;
@@ -737,7 +737,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return true;
}
- constexpr bool operator!=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator!=(const BigInt<Bits, Signed> &other) const {
for (size_t i = 0; i < WORDCOUNT; ++i) {
if (val[i] != other.val[i])
return true;
@@ -745,7 +745,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- constexpr bool operator>(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator>(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for
diff erent signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -766,7 +766,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- constexpr bool operator>=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator>=(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for
diff erent signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -787,7 +787,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return true;
}
- constexpr bool operator<(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator<(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for
diff erent signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -809,7 +809,7 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- constexpr bool operator<=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool operator<=(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for
diff erent signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -830,26 +830,26 @@ template <size_t Bits, bool Signed> struct BigInt {
return true;
}
- constexpr BigInt<Bits, Signed> &operator++() {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &operator++() {
BigInt<Bits, Signed> one(1);
add(one);
return *this;
}
- constexpr BigInt<Bits, Signed> operator++(int) {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator++(int) {
BigInt<Bits, Signed> oldval(*this);
BigInt<Bits, Signed> one(1);
add(one);
return oldval;
}
- constexpr BigInt<Bits, Signed> &operator--() {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> &operator--() {
BigInt<Bits, Signed> one(1);
sub(one);
return *this;
}
- constexpr BigInt<Bits, Signed> operator--(int) {
+ LIBC_INLINE constexpr BigInt<Bits, Signed> operator--(int) {
BigInt<Bits, Signed> oldval(*this);
BigInt<Bits, Signed> one(1);
sub(one);
@@ -857,14 +857,14 @@ template <size_t Bits, bool Signed> struct BigInt {
}
// Return the i-th 64-bit word of the number.
- constexpr const uint64_t &operator[](size_t i) const { return val[i]; }
+ LIBC_INLINE constexpr const uint64_t &operator[](size_t i) const { return val[i]; }
// Return the i-th 64-bit word of the number.
- constexpr uint64_t &operator[](size_t i) { return val[i]; }
+ LIBC_INLINE constexpr uint64_t &operator[](size_t i) { return val[i]; }
- uint64_t *data() { return val; }
+ LIBC_INLINE uint64_t *data() { return val; }
- const uint64_t *data() const { return val; }
+ LIBC_INLINE const uint64_t *data() const { return val; }
};
template <size_t Bits> using UInt = BigInt<Bits, false>;
@@ -874,7 +874,7 @@ template <size_t Bits> using Int = BigInt<Bits, true>;
// Provides limits of U/Int<128>.
template <> class numeric_limits<UInt<128>> {
public:
- static constexpr UInt<128> max() {
+ LIBC_INLINE static constexpr UInt<128> max() {
return UInt<128>({0xffff'ffff'ffff'ffff, 0xffff'ffff'ffff'ffff});
}
static constexpr UInt<128> min() { return UInt<128>(0); }
@@ -882,10 +882,10 @@ template <> class numeric_limits<UInt<128>> {
template <> class numeric_limits<Int<128>> {
public:
- static constexpr Int<128> max() {
+ LIBC_INLINE static constexpr Int<128> max() {
return Int<128>({0xffff'ffff'ffff'ffff, 0x7fff'ffff'ffff'ffff});
}
- static constexpr Int<128> min() {
+ LIBC_INLINE static constexpr Int<128> min() {
return Int<128>({0, 0x8000'0000'0000'0000});
}
};
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 60baff5e8998bf..994057aa949ab5 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -120,7 +120,7 @@ LIBC_INLINE ErrorOr<void *> alloc_stack(size_t stacksize, size_t guardsize) {
// This must always be inlined as we may be freeing the calling threads stack in
// which case a normal return from the top the stack would cause an invalid
// memory read.
-static __attribute__((always_inline)) inline void
+[[gnu::always_inline]] LIBC_INLINE void
free_stack(void *stack, size_t stacksize, size_t guardsize) {
uintptr_t stackaddr = reinterpret_cast<uintptr_t>(stack);
stackaddr -= guardsize;
@@ -144,7 +144,7 @@ struct alignas(STACK_ALIGNMENT) StartArgs {
// This must always be inlined as we may be freeing the calling threads stack in
// which case a normal return from the top the stack would cause an invalid
// memory read.
-static __attribute__((always_inline)) inline void
+[[gnu::always_inline]] LIBC_INLINE void
cleanup_thread_resources(ThreadAttributes *attrib) {
// Cleanup the TLS before the stack as the TLS information is stored on
// the stack.
@@ -153,7 +153,7 @@ cleanup_thread_resources(ThreadAttributes *attrib) {
free_stack(attrib->stack, attrib->stacksize, attrib->guardsize);
}
-__attribute__((always_inline)) inline uintptr_t get_start_args_addr() {
+[[gnu::always_inline]] LIBC_INLINE uintptr_t get_start_args_addr() {
// NOTE: For __builtin_frame_address to work reliably across compilers,
// architectures and various optimization levels, the TU including this file
// should be compiled with -fno-omit-frame-pointer.
@@ -176,7 +176,7 @@ __attribute__((always_inline)) inline uintptr_t get_start_args_addr() {
#endif
}
-__attribute__((noinline)) static void start_thread() {
+[[gnu::noinline]] LIBC_INLINE void start_thread() {
auto *start_args = reinterpret_cast<StartArgs *>(get_start_args_addr());
auto *attrib = start_args->thread_attrib;
self.attrib = attrib;
diff --git a/libc/src/stdio/printf_core/write_int_converter.h b/libc/src/stdio/printf_core/write_int_converter.h
index b270127afbd5db..a88665c517ab5e 100644
--- a/libc/src/stdio/printf_core/write_int_converter.h
+++ b/libc/src/stdio/printf_core/write_int_converter.h
@@ -19,7 +19,8 @@
namespace __llvm_libc {
namespace printf_core {
-int inline convert_write_int(Writer *writer, const FormatSection &to_conv) {
+LIBC_INLINE int convert_write_int(Writer *writer,
+ const FormatSection &to_conv) {
// This is an additional check added by LLVM-libc. The reason it returns -3 is
// because printf uses negative return values for errors, and -1 and -2 are
diff --git a/libc/src/string/memory_utils/op_aarch64.h b/libc/src/string/memory_utils/op_aarch64.h
index afe2b7302c3597..29d3b822a4e2a5 100644
--- a/libc/src/string/memory_utils/op_aarch64.h
+++ b/libc/src/string/memory_utils/op_aarch64.h
@@ -26,7 +26,7 @@
namespace __llvm_libc::aarch64 {
-static inline constexpr bool kNeon = LLVM_LIBC_IS_DEFINED(__ARM_NEON);
+LIBC_INLINE_VAR constexpr bool kNeon = LLVM_LIBC_IS_DEFINED(__ARM_NEON);
namespace neon {
@@ -52,7 +52,7 @@ struct BzeroCacheLine {
}
};
-LIBC_INLINE static bool hasZva() {
+LIBC_INLINE bool hasZva() {
uint64_t zva_val;
asm("mrs %[zva_val], dczid_el0" : [zva_val] "=r"(zva_val));
// DC ZVA is permitted if DZP, bit [4] is zero.
diff --git a/libc/src/string/memory_utils/op_generic.h b/libc/src/string/memory_utils/op_generic.h
index b2c8fa2c599a9b..999b7a6b541678 100644
--- a/libc/src/string/memory_utils/op_generic.h
+++ b/libc/src/string/memory_utils/op_generic.h
@@ -318,24 +318,24 @@ template <typename T> struct Memmove {
// Same as load above but with an offset to the pointer.
// Making the offset explicit hints the compiler to use relevant addressing mode
// consistently.
-template <typename T> LIBC_INLINE static T load(CPtr ptr, size_t offset) {
+template <typename T> LIBC_INLINE T load(CPtr ptr, size_t offset) {
return ::__llvm_libc::load<T>(ptr + offset);
}
// Same as above but also makes sure the loaded value is in big endian format.
// This is useful when implementing lexicograhic comparisons as big endian
// scalar comparison directly maps to lexicographic byte comparisons.
-template <typename T> LIBC_INLINE static T load_be(CPtr ptr, size_t offset) {
+template <typename T> LIBC_INLINE T load_be(CPtr ptr, size_t offset) {
return Endian::to_big_endian(load<T>(ptr, offset));
}
// Equality: returns true iff values at locations (p1 + offset) and (p2 +
// offset) compare equal.
-template <typename T> static bool eq(CPtr p1, CPtr p2, size_t offset);
+template <typename T> LIBC_INLINE bool eq(CPtr p1, CPtr p2, size_t offset);
// Not equals: returns non-zero iff values at locations (p1 + offset) and (p2 +
// offset)
diff er.
-template <typename T> static uint32_t neq(CPtr p1, CPtr p2, size_t offset);
+template <typename T> LIBC_INLINE uint32_t neq(CPtr p1, CPtr p2, size_t offset);
// Lexicographic comparison:
// - returns 0 iff values at locations (p1 + offset) and (p2 + offset) compare
@@ -345,7 +345,7 @@ template <typename T> static uint32_t neq(CPtr p1, CPtr p2, size_t offset);
// - returns a positive value if value at location (p1 + offset) is
// lexicographically greater than value at (p2 + offset).
template <typename T>
-static MemcmpReturnType cmp(CPtr p1, CPtr p2, size_t offset);
+LIBC_INLINE MemcmpReturnType cmp(CPtr p1, CPtr p2, size_t offset);
// Lexicographic comparison of non-equal values:
// - returns a negative value if value at location (p1 + offset) is
@@ -353,7 +353,7 @@ static MemcmpReturnType cmp(CPtr p1, CPtr p2, size_t offset);
// - returns a positive value if value at location (p1 + offset) is
// lexicographically greater than value at (p2 + offset).
template <typename T>
-static MemcmpReturnType cmp_neq(CPtr p1, CPtr p2, size_t offset);
+LIBC_INLINE MemcmpReturnType cmp_neq(CPtr p1, CPtr p2, size_t offset);
///////////////////////////////////////////////////////////////////////////////
// Memcmp implementation
@@ -563,6 +563,7 @@ LIBC_INLINE MemcmpReturnType cmp<uint8_t>(CPtr p1, CPtr p2, size_t offset) {
}
template <>
LIBC_INLINE MemcmpReturnType cmp_neq<uint8_t>(CPtr p1, CPtr p2, size_t offset);
+
} // namespace __llvm_libc::generic
#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_GENERIC_H
diff --git a/libc/src/string/memory_utils/op_x86.h b/libc/src/string/memory_utils/op_x86.h
index 87585419770e76..4c526dabf42ac7 100644
--- a/libc/src/string/memory_utils/op_x86.h
+++ b/libc/src/string/memory_utils/op_x86.h
@@ -50,7 +50,7 @@ LIBC_INLINE_VAR constexpr bool kAvx512BW = LLVM_LIBC_IS_DEFINED(__AVX512BW__);
///////////////////////////////////////////////////////////////////////////////
// Memcpy repmovsb implementation
struct Memcpy {
- static void repmovsb(void *dst, const void *src, size_t count) {
+ LIBC_INLINE static void repmovsb(void *dst, const void *src, size_t count) {
asm volatile("rep movsb" : "+D"(dst), "+S"(src), "+c"(count) : : "memory");
}
};
diff --git a/libc/src/string/memory_utils/strcmp_implementations.h b/libc/src/string/memory_utils/strcmp_implementations.h
index 3a7caeef545bfe..1fc08fcd095daf 100644
--- a/libc/src/string/memory_utils/strcmp_implementations.h
+++ b/libc/src/string/memory_utils/strcmp_implementations.h
@@ -14,8 +14,8 @@
namespace __llvm_libc {
template <typename Comp>
-constexpr static int strcmp_implementation(const char *left, const char *right,
- Comp &&comp) {
+LIBC_INLINE constexpr int
+strcmp_implementation(const char *left, const char *right, Comp &&comp) {
// TODO: Look at benefits for comparing words at a time.
for (; *left && !comp(*left, *right); ++left, ++right)
;
@@ -24,8 +24,9 @@ constexpr static int strcmp_implementation(const char *left, const char *right,
}
template <typename Comp>
-constexpr static int strncmp_implementation(const char *left, const char *right,
- size_t n, Comp &&comp) {
+LIBC_INLINE constexpr int strncmp_implementation(const char *left,
+ const char *right, size_t n,
+ Comp &&comp) {
if (n == 0)
return 0;
diff --git a/libc/src/string/memory_utils/strstr_implementations.h b/libc/src/string/memory_utils/strstr_implementations.h
index d24aedd58cdbc3..3cf1a84ef415dd 100644
--- a/libc/src/string/memory_utils/strstr_implementations.h
+++ b/libc/src/string/memory_utils/strstr_implementations.h
@@ -16,8 +16,8 @@
namespace __llvm_libc {
template <typename Comp>
-constexpr static char *strstr_implementation(const char *haystack,
- const char *needle, Comp &&comp) {
+LIBC_INLINE constexpr char *
+strstr_implementation(const char *haystack, const char *needle, Comp &&comp) {
void *result = memmem_implementation(
static_cast<const void *>(haystack), internal::string_length(haystack),
static_cast<const void *>(needle), internal::string_length(needle), comp);
diff --git a/libc/src/string/memory_utils/utils.h b/libc/src/string/memory_utils/utils.h
index 93cbf15a83e71c..4356a98bda658f 100644
--- a/libc/src/string/memory_utils/utils.h
+++ b/libc/src/string/memory_utils/utils.h
@@ -24,48 +24,50 @@ namespace __llvm_libc {
// Allows compile time error reporting in `if constexpr` branches.
template <bool flag = false>
-static void deferred_static_assert(const char *msg) {
+LIBC_INLINE void deferred_static_assert(const char *msg) {
static_assert(flag, "compilation error");
(void)msg;
}
// Return whether `value` is zero or a power of two.
-static constexpr bool is_power2_or_zero(size_t value) {
+LIBC_INLINE constexpr bool is_power2_or_zero(size_t value) {
return (value & (value - 1U)) == 0;
}
// Return whether `value` is a power of two.
-static constexpr bool is_power2(size_t value) {
+LIBC_INLINE constexpr bool is_power2(size_t value) {
return value && is_power2_or_zero(value);
}
// Compile time version of log2 that handles 0.
-static constexpr size_t log2s(size_t value) {
+LIBC_INLINE constexpr size_t log2s(size_t value) {
return (value == 0 || value == 1) ? 0 : 1 + log2s(value / 2);
}
// Returns the first power of two preceding value or value if it is already a
// power of two (or 0 when value is 0).
-static constexpr size_t le_power2(size_t value) {
+LIBC_INLINE constexpr size_t le_power2(size_t value) {
return value == 0 ? value : 1ULL << log2s(value);
}
// Returns the first power of two following value or value if it is already a
// power of two (or 0 when value is 0).
-static constexpr size_t ge_power2(size_t value) {
+LIBC_INLINE constexpr size_t ge_power2(size_t value) {
return is_power2_or_zero(value) ? value : 1ULL << (log2s(value) + 1);
}
// Returns the number of bytes to substract from ptr to get to the previous
// multiple of alignment. If ptr is already aligned returns 0.
-template <size_t alignment> uintptr_t distance_to_align_down(const void *ptr) {
+template <size_t alignment>
+LIBC_INLINE uintptr_t distance_to_align_down(const void *ptr) {
static_assert(is_power2(alignment), "alignment must be a power of 2");
return reinterpret_cast<uintptr_t>(ptr) & (alignment - 1U);
}
// Returns the number of bytes to add to ptr to get to the next multiple of
// alignment. If ptr is already aligned returns 0.
-template <size_t alignment> uintptr_t distance_to_align_up(const void *ptr) {
+template <size_t alignment>
+LIBC_INLINE uintptr_t distance_to_align_up(const void *ptr) {
static_assert(is_power2(alignment), "alignment must be a power of 2");
// The logic is not straightforward and involves unsigned modulo arithmetic
// but the generated code is as fast as it can be.
@@ -75,12 +77,13 @@ template <size_t alignment> uintptr_t distance_to_align_up(const void *ptr) {
// Returns the number of bytes to add to ptr to get to the next multiple of
// alignment. If ptr is already aligned returns alignment.
template <size_t alignment>
-uintptr_t distance_to_next_aligned(const void *ptr) {
+LIBC_INLINE uintptr_t distance_to_next_aligned(const void *ptr) {
return alignment - distance_to_align_down<alignment>(ptr);
}
// Returns the same pointer but notifies the compiler that it is aligned.
-template <size_t alignment, typename T> static T *assume_aligned(T *ptr) {
+template <size_t alignment, typename T>
+LIBC_INLINE T *assume_aligned(T *ptr) {
return reinterpret_cast<T *>(__builtin_assume_aligned(ptr, alignment));
}
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h
index 572d47d639565f..da4bcb955ab473 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -225,7 +225,8 @@ LIBC_INLINE size_t strlcpy(char *__restrict dst, const char *__restrict src,
}
template <bool ReturnNull = true>
-constexpr static char *strchr_implementation(const char *src, int c) {
+LIBC_INLINE constexpr static char *strchr_implementation(const char *src,
+ int c) {
char ch = static_cast<char>(c);
for (; *src && *src != ch; ++src)
;
@@ -233,7 +234,8 @@ constexpr static char *strchr_implementation(const char *src, int c) {
return *src == ch ? const_cast<char *>(src) : ret;
}
-constexpr static char *strrchr_implementation(const char *src, int c) {
+LIBC_INLINE constexpr static char *strrchr_implementation(const char *src,
+ int c) {
char ch = static_cast<char>(c);
char *last_occurrence = nullptr;
for (; *src; ++src) {
More information about the libc-commits
mailing list