[libcxx] [llvm] Debug windows failures for localization changes (PR #114228)

Louis Dionne via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 30 10:56:10 PDT 2024


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/114228

>From 144286f0f6c21690b54d5472ff9e4939875c4aea Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:26:24 -0400
Subject: [PATCH 01/19] WIP: original patch

---
 libcxx/include/__locale_dir/locale_base_api.h |   8 ++
 .../locale_base_api/bsd_locale_defaults.h     | 107 +++++++++++++++---
 .../locale_base_api/bsd_locale_fallbacks.h    |   4 +-
 libcxx/include/locale                         |  12 +-
 .../test/libcxx/clang_modules_include.gen.py  |   8 ++
 5 files changed, 113 insertions(+), 26 deletions(-)

diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index b6c80255b4d199..64615b96b784f8 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -9,6 +9,8 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 
+#include <__config>
+
 #if defined(_LIBCPP_MSVCRT_LIKE)
 #  include <__locale_dir/locale_base_api/win32.h>
 #elif defined(_AIX) || defined(__MVS__)
@@ -27,6 +29,12 @@
 #  include <__locale_dir/locale_base_api/freebsd.h>
 #endif
 
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+#  include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
+#else
+#  include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
index e88eb4fa41d7af..faf974df37e8f2 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
@@ -14,23 +14,102 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  include <wchar.h>
+#endif
+
+// <xlocale.h> must come after the includes above since the functions it includes depend on
+// what headers have been included up to that point.
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#  include <xlocale.h>
+#endif
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__std_mbstate_t.h>
+#include <__utility/forward.h>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
-#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
-#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
-#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
-#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
-#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
-#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
-#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
-#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
-#define __libcpp_localeconv_l(l) localeconv_l(l)
-#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
-#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
-#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
-#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __loc) { return MB_CUR_MAX_L(__loc); }
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_btowc_l(int __c, locale_t __loc) { return ::btowc_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wctob_l(wint_t __c, locale_t __loc) { return ::wctob_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsnrtombs_l(
+    char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcrtomb_l(char* __s, wchar_t __wc, mbstate_t* __ps, locale_t __loc) {
+  return ::wcrtomb_l(__s, __wc, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbsnrtowcs_l(
+    wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__libcpp_mbrtowc_l(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
+  return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mbtowc_l(wchar_t* __pwc, const char* __pmb, size_t __max, locale_t __loc) {
+  return ::mbtowc_l(__pwc, __pmb, __max, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
+  return ::mbrlen_l(__s, __n, __ps, __loc);
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); }
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
+}
+#endif
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int
+__libcpp_snprintf_l(char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int __libcpp_asprintf_l(char** __s, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int __libcpp_sscanf_l(const char* __s, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+_LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index ae2db6ae70bebc..53336a35ffaf33 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -13,9 +13,11 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 
+#include <locale.h>
+
 #include <__locale_dir/locale_guard.h>
-#include <cstdio>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 782475ea7e0eb8..4706515b0a6c86 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -215,7 +215,7 @@ template <class charT> class messages_byname;
 #  include <streambuf>
 #  include <version>
 
-// TODO: Fix __bsd_locale_defaults.h
+// TODO: Properly qualify calls now that __bsd_locale_defaults.h defines functions instead of macros
 // NOLINTBEGIN(libcpp-robust-against-adl)
 
 #  if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
@@ -230,16 +230,6 @@ template <class charT> class messages_byname;
 #    define _LIBCPP_HAS_CATOPEN 0
 #  endif
 
-#  ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-#    include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
-#  else
-#    include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
-#  endif
-
-#  if defined(__APPLE__) || defined(__FreeBSD__)
-#    include <xlocale.h>
-#  endif
-
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py
index bc028f2a0809aa..ffbdf4a1e3194e 100644
--- a/libcxx/test/libcxx/clang_modules_include.gen.py
+++ b/libcxx/test/libcxx/clang_modules_include.gen.py
@@ -24,6 +24,10 @@
 //--- {header}.compile.pass.cpp
 // RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
 
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 
@@ -52,6 +56,10 @@
 
 // REQUIRES: clang-modules-build
 
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 

>From aade6a7ee0f292bd727e646ae53e22356a3e1eb1 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:27:35 -0400
Subject: [PATCH 02/19] Disable non-windows bots for testing

---
 .github/workflows/libcxx-build-and-test.yaml | 204 +------------------
 1 file changed, 8 insertions(+), 196 deletions(-)

diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index 184fed2268e818..58427421a3739d 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -47,209 +47,21 @@ env:
 
 
 jobs:
-  stage1:
-    if: github.repository_owner == 'llvm'
-    runs-on: libcxx-runners-8-set
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      matrix:
-        config: [
-          'generic-cxx03',
-          'generic-cxx26',
-          'generic-modules'
-        ]
-        cc: [  'clang-19' ]
-        cxx: [ 'clang++-19' ]
-        include:
-          - config: 'generic-gcc'
-            cc: 'gcc-14'
-            cxx: 'g++-14'
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}.${{ matrix.cxx }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: ${{ matrix.cc }}
-          CXX: ${{ matrix.cxx }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()
-        with:
-          name: ${{ matrix.config }}-${{ matrix.cxx }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-  stage2:
-    if: github.repository_owner == 'llvm'
-    runs-on: libcxx-runners-8-set
-    needs: [ stage1 ]
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      matrix:
-        config: [
-          'generic-cxx11',
-          'generic-cxx14',
-          'generic-cxx17',
-          'generic-cxx20',
-          'generic-cxx23'
-        ]
-        cc: [ 'clang-19' ]
-        cxx: [ 'clang++-19' ]
-        include:
-          - config: 'generic-gcc-cxx11'
-            cc: 'gcc-14'
-            cxx: 'g++-14'
-          - config: 'generic-cxx23'
-            cc: 'clang-17'
-            cxx: 'clang++-17'
-          - config: 'generic-cxx26'
-            cc: 'clang-18'
-            cxx: 'clang++-18'
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: ${{ matrix.cc }}
-          CXX: ${{ matrix.cxx }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()  # Upload artifacts even if the build or test suite fails
-        with:
-          name: ${{ matrix.config }}-${{ matrix.cxx }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-  stage3:
-    if: github.repository_owner == 'llvm'
-    needs: [ stage1, stage2 ]
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      max-parallel: 8
-      matrix:
-        config: [
-          'generic-abi-unstable',
-          'generic-hardening-mode-debug',
-          'generic-hardening-mode-extensive',
-          'generic-hardening-mode-fast',
-          'generic-hardening-mode-fast-with-abi-breaks',
-          'generic-merged',
-          'generic-modules-lsv',
-          'generic-no-exceptions',
-          'generic-no-experimental',
-          'generic-no-filesystem',
-          'generic-no-localization',
-          'generic-no-terminal',
-          'generic-no-random_device',
-          'generic-no-threads',
-          'generic-no-tzdb',
-          'generic-no-unicode',
-          'generic-no-wide-characters',
-          'generic-no-rtti',
-          'generic-optimized-speed',
-          'generic-static',
-          # TODO Find a better place for the benchmark and bootstrapping builds to live. They're either very expensive
-          # or don't provide much value since the benchmark run results are too noise on the bots.
-          'benchmarks',
-          'bootstrapping-build'
-        ]
-        machine: [ 'libcxx-runners-8-set' ]
-        include:
-        - config: 'generic-cxx26'
-          machine: libcxx-runners-8-set
-        - config: 'generic-asan'
-          machine: libcxx-runners-8-set
-        - config: 'generic-tsan'
-          machine: libcxx-runners-8-set
-        - config: 'generic-ubsan'
-          machine: libcxx-runners-8-set
-        # Use a larger machine for MSAN to avoid timeout and memory allocation issues.
-        - config: 'generic-msan'
-          machine: libcxx-runners-8-set
-    runs-on: ${{ matrix.machine }}
-    steps:
-      - uses: actions/checkout at v4
-      - name: ${{ matrix.config }}
-        run: libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-        env:
-          CC: clang-19
-          CXX: clang++-19
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()
-        with:
-          name: ${{ matrix.config }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-
-  macos:
-    needs: [ stage1 ]
-    strategy:
-      fail-fast: false
-      matrix:
-        include:
-        - config: generic-cxx03
-          os: macos-latest
-        - config: generic-cxx23
-          os: macos-latest
-        - config: generic-modules
-          os: macos-latest
-        - config: apple-configuration
-          os: macos-latest
-        - config: apple-system
-          os: macos-13
-        - config: apple-system-hardened
-          os: macos-13
-    runs-on: ${{ matrix.os }}
-    steps:
-      - uses: actions/checkout at v4
-      - uses: maxim-lobanov/setup-xcode at v1
-        with:
-          xcode-version: 'latest'
-      - uses: seanmiddleditch/gha-setup-ninja at master
-      - name: Build and test
-        run: |
-          python3 -m venv .venv
-          source .venv/bin/activate
-          python -m pip install psutil
-          bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}
-      - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
-        if: always()  # Upload artifacts even if the build or test suite fails
-        with:
-          name: macos-${{ matrix.config }}-results
-          path: |
-            **/test-results.xml
-            **/*.abilist
-            **/CMakeError.log
-            **/CMakeOutput.log
-            **/crash_diagnostics/*
-
   windows:
     runs-on: windows-2022
-    needs: [ stage1 ]
     strategy:
       fail-fast: false
       matrix:
         include:
         - { config: clang-cl-dll, mingw: false }
-        - { config: clang-cl-static, mingw: false }
-        - { config: clang-cl-no-vcruntime, mingw: false }
-        - { config: clang-cl-debug, mingw: false }
-        - { config: clang-cl-static-crt, mingw: false }
-        - { config: mingw-dll, mingw: true }
-        - { config: mingw-static, mingw: true }
-        - { config: mingw-dll-i686, mingw: true }
-        - { config: mingw-incomplete-sysroot, mingw: true }
+        # - { config: clang-cl-static, mingw: false }
+        # - { config: clang-cl-no-vcruntime, mingw: false }
+        # - { config: clang-cl-debug, mingw: false }
+        # - { config: clang-cl-static-crt, mingw: false }
+        # - { config: mingw-dll, mingw: true }
+        # - { config: mingw-static, mingw: true }
+        # - { config: mingw-dll-i686, mingw: true }
+        # - { config: mingw-incomplete-sysroot, mingw: true }
     steps:
       - uses: actions/checkout at v4
       - name: Install dependencies

>From 8746ce1b1d60d5686c721f802e95d3fad7654d1c Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:28:44 -0400
Subject: [PATCH 03/19] Run only one failing test

---
 libcxx/utils/ci/run-buildbot | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 0b72f8c4031031..8b1466445151af 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -700,8 +700,11 @@ clang-cl-dll)
     # anyway), thus just disable the experimental library. Remove this
     # setting when cmake and the test driver does the right thing automatically.
     generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False"
-    step "Running the libc++ tests"
-    ${NINJA} -vC "${BUILD_DIR}" check-cxx
+    step "Building dependencies"
+    ${NINJA} -vC "${BUILD_DIR}" cxx-test-depends
+
+    step "Running tests"
+    ./libcxx/utils/libcxx-lit "${BUILD_DIR}" --show-all libcxx/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp
 ;;
 clang-cl-static)
     clean

>From 0ff4e7ac127ac4fdb089c59155375dfa0e9167fd Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:30:34 -0400
Subject: [PATCH 04/19] Disable buildkite pipeline

---
 libcxx/utils/ci/buildkite-pipeline.yml | 103 +------------------------
 1 file changed, 1 insertion(+), 102 deletions(-)

diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
index d1465721cf1648..1c5c7cad336768 100644
--- a/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -40,109 +40,8 @@ steps:
 - group: ARM
   steps:
   - label: AArch64
-    command: libcxx/utils/ci/run-buildbot aarch64
+    command: true
     agents:
       queue: libcxx-builders-linaro-arm
       arch: aarch64
     <<: *common
-
-  - label: AArch64 -fno-exceptions
-    command: libcxx/utils/ci/run-buildbot aarch64-no-exceptions
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: aarch64
-    <<: *common
-
-  - label: Armv8
-    command: libcxx/utils/ci/run-buildbot armv8
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: armv8l
-    <<: *common
-
-  - label: Armv8 -fno-exceptions
-    command: libcxx/utils/ci/run-buildbot armv8-no-exceptions
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: armv8l
-    <<: *common
-
-  - label: Armv7
-    command: libcxx/utils/ci/run-buildbot armv7
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: armv8l
-    <<: *common
-
-  - label: Armv7 -fno-exceptions
-    command: libcxx/utils/ci/run-buildbot armv7-no-exceptions
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: armv8l
-    <<: *common
-
-  - label: Armv7-M picolibc
-    command: libcxx/utils/ci/run-buildbot armv7m-picolibc
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: aarch64
-    <<: *common
-
-  - label: Armv7-M picolibc -fno-exceptions
-    command: libcxx/utils/ci/run-buildbot armv7m-picolibc-no-exceptions
-    agents:
-      queue: libcxx-builders-linaro-arm
-      arch: aarch64
-    <<: *common
-
-- group: AIX
-  steps:
-  - label: AIX (32-bit)
-    command: libcxx/utils/ci/run-buildbot aix
-    env:
-      CC: clang
-      CXX: clang++
-      OBJECT_MODE: '32'
-    agents:
-      queue: libcxx-builders
-      os: aix
-    <<: *common
-
-  - label: AIX (64-bit)
-    command: libcxx/utils/ci/run-buildbot aix
-    env:
-      CC: clang
-      CXX: clang++
-      OBJECT_MODE: '64'
-    agents:
-      queue: libcxx-builders
-      os: aix
-    <<: *common
-
-- group: ':freebsd: FreeBSD'
-  steps:
-  - label: FreeBSD 13 amd64
-    command: libcxx/utils/ci/run-buildbot generic-cxx26
-    env:
-      CC: clang17
-      CXX: clang++17
-    agents:
-      queue: libcxx-builders
-      os: freebsd
-    <<: *common
-
-- group: ':android: Android'
-  steps:
-  - label: Android 5.0, x86 NDK
-    command: libcxx/utils/ci/run-buildbot android-ndk-21-def-x86
-    agents:
-      queue: libcxx-builders
-      os: android
-    <<: *common
-
-  - label: Android 13, x86_64 NDK
-    command: libcxx/utils/ci/run-buildbot android-ndk-33-goog-x86_64
-    agents:
-      queue: libcxx-builders
-      os: android
-    <<: *common

>From de4102e22950b287f4a508341b29c11c72d11fe8 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:42:43 -0400
Subject: [PATCH 05/19] Use regex test instead

---
 libcxx/utils/ci/run-buildbot | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 8b1466445151af..6b87a019f4534d 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -704,7 +704,7 @@ clang-cl-dll)
     ${NINJA} -vC "${BUILD_DIR}" cxx-test-depends
 
     step "Running tests"
-    ./libcxx/utils/libcxx-lit "${BUILD_DIR}" --show-all libcxx/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.assign/assign.pass.cpp
+    ./libcxx/utils/libcxx-lit "${BUILD_DIR}" --show-all libcxx/test/std/re/re.traits/getloc.pass.cpp
 ;;
 clang-cl-static)
     clean

>From 4b4a919aaba5571ce89d17f62b993690d7e996be Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:43:08 -0400
Subject: [PATCH 06/19] Reduce regex test

---
 libcxx/test/std/re/re.traits/getloc.pass.cpp | 43 ++++++++------------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/libcxx/test/std/re/re.traits/getloc.pass.cpp b/libcxx/test/std/re/re.traits/getloc.pass.cpp
index 55820cc0cc6113..c3034601fdc15b 100644
--- a/libcxx/test/std/re/re.traits/getloc.pass.cpp
+++ b/libcxx/test/std/re/re.traits/getloc.pass.cpp
@@ -16,34 +16,27 @@
 
 #include <regex>
 #include <cassert>
+#include <cstdio>
 
 #include "test_macros.h"
 #include "platform_support.h" // locale name macros
 
-int main(int, char**)
-{
-    {
-        std::regex_traits<char> t;
-        assert(t.getloc().name() == "C");
-    }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-    {
-        std::regex_traits<wchar_t> t;
-        assert(t.getloc().name() == "C");
-    }
-#endif
-    {
-        std::locale::global(std::locale(LOCALE_en_US_UTF_8));
-        std::regex_traits<char> t;
-        assert(t.getloc().name() == LOCALE_en_US_UTF_8);
-    }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-    {
-        std::locale::global(std::locale(LOCALE_en_US_UTF_8));
-        std::regex_traits<wchar_t> t;
-        assert(t.getloc().name() == LOCALE_en_US_UTF_8);
-    }
-#endif
-
+int main(int, char**) {
+  std::fprintf(stderr, "Entering main()\n");
+  {
+    std::regex_traits<char> t;
+    std::fprintf(stderr, "Running t.getloc()\n");
+    assert(t.getloc().name() == "C");
+  }
+  {
+    std::fprintf(stderr, "Creating locale\n");
+    std::locale loc(LOCALE_en_US_UTF_8);
+
+    std::fprintf(stderr, "Setting locale globally\n");
+    std::locale::global(loc);
+    std::regex_traits<char> t;
+    std::fprintf(stderr, "Running t.getloc()\n");
+    assert(t.getloc().name() == LOCALE_en_US_UTF_8);
+  }
   return 0;
 }

>From 36eac25d239f091c46f5387af050f7a6dd135f93 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 09:56:06 -0400
Subject: [PATCH 07/19] Use other means to run only the test we want

---
 libcxx/utils/ci/run-buildbot       | 7 ++-----
 libcxx/utils/libcxx/test/format.py | 3 +++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 6b87a019f4534d..0b72f8c4031031 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -700,11 +700,8 @@ clang-cl-dll)
     # anyway), thus just disable the experimental library. Remove this
     # setting when cmake and the test driver does the right thing automatically.
     generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False"
-    step "Building dependencies"
-    ${NINJA} -vC "${BUILD_DIR}" cxx-test-depends
-
-    step "Running tests"
-    ./libcxx/utils/libcxx-lit "${BUILD_DIR}" --show-all libcxx/test/std/re/re.traits/getloc.pass.cpp
+    step "Running the libc++ tests"
+    ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 clang-cl-static)
     clean
diff --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py
index 7e5281c0b74064..47d04627e43965 100644
--- a/libcxx/utils/libcxx/test/format.py
+++ b/libcxx/utils/libcxx/test/format.py
@@ -287,6 +287,9 @@ def execute(self, test, litConfig):
         supportsVerify = "verify-support" in test.config.available_features
         filename = test.path_in_suite[-1]
 
+        if filename != 'getloc.pass.cpp':
+            return lit.Test.Result(lit.Test.UNSUPPORTED, "not the test we're looking for")
+
         if re.search("[.]sh[.][^.]+$", filename):
             steps = []  # The steps are already in the script
             return self._executeShTest(test, litConfig, steps)

>From ef85b0eb1edb0bb4a30cf92ed83166caede4e2bb Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 10:04:38 -0400
Subject: [PATCH 08/19] Simplify test even more

---
 libcxx/test/std/re/re.traits/getloc.pass.cpp | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/libcxx/test/std/re/re.traits/getloc.pass.cpp b/libcxx/test/std/re/re.traits/getloc.pass.cpp
index c3034601fdc15b..bc02d5ac075c4c 100644
--- a/libcxx/test/std/re/re.traits/getloc.pass.cpp
+++ b/libcxx/test/std/re/re.traits/getloc.pass.cpp
@@ -23,20 +23,10 @@
 
 int main(int, char**) {
   std::fprintf(stderr, "Entering main()\n");
-  {
-    std::regex_traits<char> t;
-    std::fprintf(stderr, "Running t.getloc()\n");
-    assert(t.getloc().name() == "C");
-  }
   {
     std::fprintf(stderr, "Creating locale\n");
-    std::locale loc(LOCALE_en_US_UTF_8);
-
-    std::fprintf(stderr, "Setting locale globally\n");
-    std::locale::global(loc);
-    std::regex_traits<char> t;
-    std::fprintf(stderr, "Running t.getloc()\n");
-    assert(t.getloc().name() == LOCALE_en_US_UTF_8);
+    std::locale loc("en_US.UTF-8");
+    (void)loc;
   }
   return 0;
 }

>From 969236c60170026bf3a4599392a514baac0432f8 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 10:11:06 -0400
Subject: [PATCH 09/19] More printf debugging

---
 libcxx/src/locale.cpp | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index 99a2d50f207ed1..3c173a8d1541be 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -219,13 +219,19 @@ locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), name_("C") {
 }
 
 locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N), name_(name) {
+  std::fprintf(stderr, "Entering __imp(string const&) constructor\n");
 #if _LIBCPP_HAS_EXCEPTIONS
   try {
 #endif // _LIBCPP_HAS_EXCEPTIONS
+    std::fprintf(stderr, "Calling locale::classic()\n");
     facets_ = locale::classic().__locale_->facets_;
+
+    std::fprintf(stderr, "Calling __add_shared() on facets\n");
     for (unsigned i = 0; i < facets_.size(); ++i)
       if (facets_[i])
         facets_[i]->__add_shared();
+
+    std::fprintf(stderr, "Installing locales\n");
     install(new collate_byname<char>(name_));
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
     install(new collate_byname<wchar_t>(name_));
@@ -270,12 +276,15 @@ locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N),
 #endif
 #if _LIBCPP_HAS_EXCEPTIONS
   } catch (...) {
+    std::fprintf(stderr, "Releasing facets in catch block\n");
     for (unsigned i = 0; i < facets_.size(); ++i)
       if (facets_[i])
         facets_[i]->__release_shared();
     throw;
   }
 #endif // _LIBCPP_HAS_EXCEPTIONS
+
+  std::fprintf(stderr, "Done installing locales\n");
 }
 
 locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {
@@ -533,8 +542,15 @@ const locale& locale::operator=(const locale& other) noexcept {
   return *this;
 }
 
-locale::locale(const char* name)
-    : __locale_(name ? new __imp(name) : (__throw_runtime_error("locale constructed with null"), nullptr)) {
+locale::locale(const char* name) {
+  std::fprintf(stderr, "Entering locale(char const*) constructor\n");
+  if (name == nullptr)
+    std::__throw_runtime_error("locale constructed with null");
+
+  std::fprintf(stderr, "Running new __imp(name);\n");
+  __locale_ = new __imp(name);
+
+  std::fprintf(stderr, "Running locale_->acquire()\n");
   __locale_->acquire();
 }
 

>From 627d6c926a9df0d200d3164b177f73e446a85fb1 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 10:24:33 -0400
Subject: [PATCH 10/19] More printf

---
 libcxx/src/locale.cpp | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index 3c173a8d1541be..63177cd64c3716 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -150,7 +150,13 @@ class _LIBCPP_HIDDEN locale::__imp : public facet {
   void install(facet* f, long id);
   template <class F>
   void install(F* f) {
-    install(f, f->id.__get());
+    std::fprintf(stderr, "Entering install(Facet*)\n");
+
+    std::fprintf(stderr, "Getting id for locale\n");
+    long id = f->id.__get();
+
+    std::fprintf(stderr, "Calling install(Facet*, long id)\n");
+    install(f, id);
   }
   template <class F>
   void install_from(const __imp& other);
@@ -231,8 +237,13 @@ locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N),
       if (facets_[i])
         facets_[i]->__add_shared();
 
-    std::fprintf(stderr, "Installing locales\n");
-    install(new collate_byname<char>(name_));
+    {
+      std::fprintf(stderr, "Creating collate_byname<char>\n");
+      auto* byname = new collate_byname<char>(name_);
+
+      std::fprintf(stderr, "Installing collate_byname<char>\n");
+      install(byname);
+    }
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
     install(new collate_byname<wchar_t>(name_));
 #endif
@@ -480,12 +491,25 @@ locale::__imp::~__imp() {
 }
 
 void locale::__imp::install(facet* f, long id) {
+  std::fprintf(stderr, "Entering install(facet*, long id)\n");
+
+  std::fprintf(stderr, "Calling facet->__add_shared()\n");
   f->__add_shared();
+
+  std::fprintf(stderr, "Creating unique_ptr to hold facet\n");
   unique_ptr<facet, releaser> hold(f);
-  if (static_cast<size_t>(id) >= facets_.size())
+
+  if (static_cast<size_t>(id) >= facets_.size()) {
+    std::fprintf(stderr, "Resizing facets vector\n");
     facets_.resize(static_cast<size_t>(id + 1));
-  if (facets_[static_cast<size_t>(id)])
+  }
+
+  if (facets_[static_cast<size_t>(id)]) {
+    std::fprintf(stderr, "Releasing facets[id]\n");
     facets_[static_cast<size_t>(id)]->__release_shared();
+  }
+
+  std::fprintf(stderr, "Releasing unique_ptr\n");
   facets_[static_cast<size_t>(id)] = hold.release();
 }
 

>From 1074d336ce915830a5bd2efcdbdb670fd82eef3a Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 10:36:57 -0400
Subject: [PATCH 11/19] Add printf for all facets

---
 libcxx/src/locale.cpp | 59 +++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 28 deletions(-)

diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index 63177cd64c3716..fe4affb10df916 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -237,53 +237,56 @@ locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N),
       if (facets_[i])
         facets_[i]->__add_shared();
 
-    {
-      std::fprintf(stderr, "Creating collate_byname<char>\n");
-      auto* byname = new collate_byname<char>(name_);
-
-      std::fprintf(stderr, "Installing collate_byname<char>\n");
-      install(byname);
-    }
+#define _DOIT(...)                                            \
+    do {                                                      \
+      std::fprintf(stderr, "Creating " #__VA_ARGS__ "\n");    \
+      auto* the_facet = new __VA_ARGS__(name_);               \
+                                                              \
+      std::fprintf(stderr, "Installing " #__VA_ARGS__ "\n");  \
+      install(the_facet);                                     \
+    } while (false)
+
+    _DOIT(collate_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new collate_byname<wchar_t>(name_));
+    _DOIT(collate_byname<wchar_t>);
 #endif
-    install(new ctype_byname<char>(name_));
+    _DOIT(ctype_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new ctype_byname<wchar_t>(name_));
+    _DOIT(ctype_byname<wchar_t>);
 #endif
-    install(new codecvt_byname<char, char, mbstate_t>(name_));
+    _DOIT(codecvt_byname<char, char, mbstate_t>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
+    _DOIT(codecvt_byname<wchar_t, char, mbstate_t>);
 #endif
     _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-    install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
-    install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
+    _DOIT(codecvt_byname<char16_t, char, mbstate_t>);
+    _DOIT(codecvt_byname<char32_t, char, mbstate_t>);
     _LIBCPP_SUPPRESS_DEPRECATED_POP
 #if _LIBCPP_HAS_CHAR8_T
-    install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
-    install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
+    _DOIT(codecvt_byname<char16_t, char8_t, mbstate_t>);
+    _DOIT(codecvt_byname<char32_t, char8_t, mbstate_t>);
 #endif
-    install(new numpunct_byname<char>(name_));
+    _DOIT(numpunct_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new numpunct_byname<wchar_t>(name_));
+    _DOIT(numpunct_byname<wchar_t>);
 #endif
-    install(new moneypunct_byname<char, false>(name_));
-    install(new moneypunct_byname<char, true>(name_));
+    _DOIT(moneypunct_byname<char, false>);
+    _DOIT(moneypunct_byname<char, true>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new moneypunct_byname<wchar_t, false>(name_));
-    install(new moneypunct_byname<wchar_t, true>(name_));
+    _DOIT(moneypunct_byname<wchar_t, false>);
+    _DOIT(moneypunct_byname<wchar_t, true>);
 #endif
-    install(new time_get_byname<char>(name_));
+    _DOIT(time_get_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new time_get_byname<wchar_t>(name_));
+    _DOIT(time_get_byname<wchar_t>);
 #endif
-    install(new time_put_byname<char>(name_));
+    _DOIT(time_put_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new time_put_byname<wchar_t>(name_));
+    _DOIT(time_put_byname<wchar_t>);
 #endif
-    install(new messages_byname<char>(name_));
+    _DOIT(messages_byname<char>);
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    install(new messages_byname<wchar_t>(name_));
+    _DOIT(messages_byname<wchar_t>);
 #endif
 #if _LIBCPP_HAS_EXCEPTIONS
   } catch (...) {

>From 469a77026e985aa67d85e64b6e8b8a99216c8673 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 11:00:17 -0400
Subject: [PATCH 12/19] Narrow down

---
 libcxx/src/locale.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index fe4affb10df916..9553027cc0e609 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -151,8 +151,6 @@ class _LIBCPP_HIDDEN locale::__imp : public facet {
   template <class F>
   void install(F* f) {
     std::fprintf(stderr, "Entering install(Facet*)\n");
-
-    std::fprintf(stderr, "Getting id for locale\n");
     long id = f->id.__get();
 
     std::fprintf(stderr, "Calling install(Facet*, long id)\n");
@@ -229,10 +227,8 @@ locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N),
 #if _LIBCPP_HAS_EXCEPTIONS
   try {
 #endif // _LIBCPP_HAS_EXCEPTIONS
-    std::fprintf(stderr, "Calling locale::classic()\n");
     facets_ = locale::classic().__locale_->facets_;
 
-    std::fprintf(stderr, "Calling __add_shared() on facets\n");
     for (unsigned i = 0; i < facets_.size(); ++i)
       if (facets_[i])
         facets_[i]->__add_shared();
@@ -298,7 +294,7 @@ locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N),
   }
 #endif // _LIBCPP_HAS_EXCEPTIONS
 
-  std::fprintf(stderr, "Done installing locales\n");
+  std::fprintf(stderr, "Done installing facets\n");
 }
 
 locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {
@@ -4097,6 +4093,7 @@ numpunct_byname<char>::~numpunct_byname() {}
 void numpunct_byname<char>::__init(const char* nm) {
   typedef numpunct<char> base;
   if (strcmp(nm, "C") != 0) {
+    std::fprintf(stderr, "Creating __libcpp_unique_locale\n");
     __libcpp_unique_locale loc(nm);
     if (!loc)
       __throw_runtime_error(
@@ -4105,6 +4102,7 @@ void numpunct_byname<char>::__init(const char* nm) {
            string(nm))
               .c_str());
 
+    std::fprintf(stderr, "Calling __libcpp_localeconv_l()\n");
     lconv* lc = __libcpp_localeconv_l(loc.get());
     if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point, loc.get()))
       __decimal_point_ = base::do_decimal_point();

>From 869ebf835c91bc1d929bca7960f39435ba090ad0 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 12:40:52 -0400
Subject: [PATCH 13/19] Add debugging

---
 libcxx/src/support/win32/locale_win32.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index 2a08e97b8645b4..a2e431852b521d 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -30,7 +30,12 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L(locale_t __l) {
 }
 
 lconv* localeconv_l(locale_t& loc) {
+  std::fprintf(stderr, "Entering localeconv_l in locale_win32.cpp\n");
+
+  std::fprintf(stderr, "Creating locale_guard in locale_win32.cpp\n");
   std::__locale_guard __current(loc);
+
+  std::fprintf(stderr, "Calling localeconv() in locale_win32.cpp\n");
   lconv* lc = localeconv();
   if (!lc)
     return lc;

>From ccb5e32848fe12248490699ac5900b3fa44cc196 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 12:41:06 -0400
Subject: [PATCH 14/19] Add missing include

---
 libcxx/src/support/win32/locale_win32.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index a2e431852b521d..cdef5417b2732f 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -10,6 +10,7 @@
 #include <locale>
 #include <memory>
 #include <type_traits>
+#include <cstdio>
 
 #include <__locale_dir/locale_guard.h>
 

>From 7dfae2ca2b99949f374264906923d230306c27e5 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 12:49:12 -0400
Subject: [PATCH 15/19] Add debug

---
 .../include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h  | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index 53336a35ffaf33..6d8ebdc772ced8 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -81,6 +81,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
 inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __l) {
+  fprintf(stderr, "Entering __libcpp_localeconv_l() in bsd_locale_fallbacks.h\n");
   __locale_guard __current(__l);
   return localeconv();
 }

>From 74cfe92b89514a7b453b7c2a918173b9e641107a Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 13:30:33 -0400
Subject: [PATCH 16/19] Force fail the test

---
 libcxx/test/std/re/re.traits/getloc.pass.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/re/re.traits/getloc.pass.cpp b/libcxx/test/std/re/re.traits/getloc.pass.cpp
index bc02d5ac075c4c..7ceb117fe4fd58 100644
--- a/libcxx/test/std/re/re.traits/getloc.pass.cpp
+++ b/libcxx/test/std/re/re.traits/getloc.pass.cpp
@@ -28,5 +28,5 @@ int main(int, char**) {
     std::locale loc("en_US.UTF-8");
     (void)loc;
   }
-  return 0;
+  return 1;
 }

>From 946e56f7607a06dfa4d4de7429d3af085f7f238c Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 13:29:55 -0400
Subject: [PATCH 17/19] Revert "WIP: original patch"

This reverts commit 144286f0f6c21690b54d5472ff9e4939875c4aea.
---
 libcxx/include/__locale_dir/locale_base_api.h |   8 --
 .../locale_base_api/bsd_locale_defaults.h     | 107 +++---------------
 .../locale_base_api/bsd_locale_fallbacks.h    |   4 +-
 libcxx/include/locale                         |  12 +-
 .../test/libcxx/clang_modules_include.gen.py  |   8 --
 5 files changed, 26 insertions(+), 113 deletions(-)

diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 64615b96b784f8..b6c80255b4d199 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -9,8 +9,6 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 
-#include <__config>
-
 #if defined(_LIBCPP_MSVCRT_LIKE)
 #  include <__locale_dir/locale_base_api/win32.h>
 #elif defined(_AIX) || defined(__MVS__)
@@ -29,12 +27,6 @@
 #  include <__locale_dir/locale_base_api/freebsd.h>
 #endif
 
-#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-#  include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
-#else
-#  include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
index faf974df37e8f2..e88eb4fa41d7af 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
@@ -14,102 +14,23 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-#  include <wchar.h>
-#endif
-
-// <xlocale.h> must come after the includes above since the functions it includes depend on
-// what headers have been included up to that point.
-#if defined(__APPLE__) || defined(__FreeBSD__)
-#  include <xlocale.h>
-#endif
-
-#include <__config>
-#include <__cstddef/size_t.h>
-#include <__std_mbstate_t.h>
-#include <__utility/forward.h>
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __loc) { return MB_CUR_MAX_L(__loc); }
-
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_btowc_l(int __c, locale_t __loc) { return ::btowc_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wctob_l(wint_t __c, locale_t __loc) { return ::wctob_l(__c, __loc); }
-
-inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsnrtombs_l(
-    char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, locale_t __loc) {
-  return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcrtomb_l(char* __s, wchar_t __wc, mbstate_t* __ps, locale_t __loc) {
-  return ::wcrtomb_l(__s, __wc, __ps, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbsnrtowcs_l(
-    wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, locale_t __loc) {
-  return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI size_t
-__libcpp_mbrtowc_l(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
-  return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mbtowc_l(wchar_t* __pwc, const char* __pmb, size_t __max, locale_t __loc) {
-  return ::mbtowc_l(__pwc, __pmb, __max, __loc);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
-  return ::mbrlen_l(__s, __n, __ps, __loc);
-}
-#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-
-inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); }
-
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI size_t
-__libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, locale_t __loc) {
-  return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
-}
-#endif
-
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI int
-__libcpp_snprintf_l(char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) {
-  _LIBCPP_DIAGNOSTIC_PUSH
-  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
-  _LIBCPP_DIAGNOSTIC_POP
-}
-
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI int __libcpp_asprintf_l(char** __s, locale_t __loc, const char* __format, _Args&&... __args) {
-  _LIBCPP_DIAGNOSTIC_PUSH
-  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
-  _LIBCPP_DIAGNOSTIC_POP
-}
-
-template <class... _Args>
-_LIBCPP_HIDE_FROM_ABI int __libcpp_sscanf_l(const char* __s, locale_t __loc, const char* __format, _Args&&... __args) {
-  _LIBCPP_DIAGNOSTIC_PUSH
-  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
-  return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
-  _LIBCPP_DIAGNOSTIC_POP
-}
-
-_LIBCPP_END_NAMESPACE_STD
+#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
+#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
+#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
+#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
+#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
+#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
+#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
+#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
+#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
+#define __libcpp_localeconv_l(l) localeconv_l(l)
+#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
+#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
+#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
+#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
 
 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index 6d8ebdc772ced8..e5195bed228fb6 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -13,11 +13,9 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 
-#include <locale.h>
-
 #include <__locale_dir/locale_guard.h>
+#include <cstdio>
 #include <stdarg.h>
-#include <stdio.h>
 #include <stdlib.h>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 4706515b0a6c86..782475ea7e0eb8 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -215,7 +215,7 @@ template <class charT> class messages_byname;
 #  include <streambuf>
 #  include <version>
 
-// TODO: Properly qualify calls now that __bsd_locale_defaults.h defines functions instead of macros
+// TODO: Fix __bsd_locale_defaults.h
 // NOLINTBEGIN(libcpp-robust-against-adl)
 
 #  if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
@@ -230,6 +230,16 @@ template <class charT> class messages_byname;
 #    define _LIBCPP_HAS_CATOPEN 0
 #  endif
 
+#  ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+#    include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
+#  else
+#    include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
+#  endif
+
+#  if defined(__APPLE__) || defined(__FreeBSD__)
+#    include <xlocale.h>
+#  endif
+
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py
index ffbdf4a1e3194e..bc028f2a0809aa 100644
--- a/libcxx/test/libcxx/clang_modules_include.gen.py
+++ b/libcxx/test/libcxx/clang_modules_include.gen.py
@@ -24,10 +24,6 @@
 //--- {header}.compile.pass.cpp
 // RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
 
-// Older macOS SDKs were not properly modularized, which causes issues with localization.
-// This feature should instead be based on the SDK version.
-// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
-
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 
@@ -56,10 +52,6 @@
 
 // REQUIRES: clang-modules-build
 
-// Older macOS SDKs were not properly modularized, which causes issues with localization.
-// This feature should instead be based on the SDK version.
-// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
-
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 

>From b079f46c5fba3e772f747c808d94ac549ed1684a Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 13:40:31 -0400
Subject: [PATCH 18/19] Reapply original patch.

---
 libcxx/include/__locale_dir/locale_base_api.h |   8 ++
 .../locale_base_api/bsd_locale_defaults.h     | 107 +++++++++++++++---
 .../locale_base_api/bsd_locale_fallbacks.h    |   4 +-
 libcxx/include/locale                         |  12 +-
 .../test/libcxx/clang_modules_include.gen.py  |   8 ++
 5 files changed, 113 insertions(+), 26 deletions(-)

diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index b6c80255b4d199..64615b96b784f8 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -9,6 +9,8 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
 
+#include <__config>
+
 #if defined(_LIBCPP_MSVCRT_LIKE)
 #  include <__locale_dir/locale_base_api/win32.h>
 #elif defined(_AIX) || defined(__MVS__)
@@ -27,6 +29,12 @@
 #  include <__locale_dir/locale_base_api/freebsd.h>
 #endif
 
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+#  include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
+#else
+#  include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
index e88eb4fa41d7af..faf974df37e8f2 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
@@ -14,23 +14,102 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
 
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+#  include <wchar.h>
+#endif
+
+// <xlocale.h> must come after the includes above since the functions it includes depend on
+// what headers have been included up to that point.
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#  include <xlocale.h>
+#endif
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__std_mbstate_t.h>
+#include <__utility/forward.h>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
-#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
-#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
-#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
-#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
-#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
-#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
-#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
-#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
-#define __libcpp_localeconv_l(l) localeconv_l(l)
-#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
-#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
-#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
-#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __loc) { return MB_CUR_MAX_L(__loc); }
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_btowc_l(int __c, locale_t __loc) { return ::btowc_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wctob_l(wint_t __c, locale_t __loc) { return ::wctob_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsnrtombs_l(
+    char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcrtomb_l(char* __s, wchar_t __wc, mbstate_t* __ps, locale_t __loc) {
+  return ::wcrtomb_l(__s, __wc, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbsnrtowcs_l(
+    wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__libcpp_mbrtowc_l(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
+  return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mbtowc_l(wchar_t* __pwc, const char* __pmb, size_t __max, locale_t __loc) {
+  return ::mbtowc_l(__pwc, __pmb, __max, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
+  return ::mbrlen_l(__s, __n, __ps, __loc);
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); }
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, locale_t __loc) {
+  return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
+}
+#endif
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int
+__libcpp_snprintf_l(char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int __libcpp_asprintf_l(char** __s, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI int __libcpp_sscanf_l(const char* __s, locale_t __loc, const char* __format, _Args&&... __args) {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+  return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  _LIBCPP_DIAGNOSTIC_POP
+}
+
+_LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index e5195bed228fb6..6d8ebdc772ced8 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -13,9 +13,11 @@
 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
 
+#include <locale.h>
+
 #include <__locale_dir/locale_guard.h>
-#include <cstdio>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 782475ea7e0eb8..4706515b0a6c86 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -215,7 +215,7 @@ template <class charT> class messages_byname;
 #  include <streambuf>
 #  include <version>
 
-// TODO: Fix __bsd_locale_defaults.h
+// TODO: Properly qualify calls now that __bsd_locale_defaults.h defines functions instead of macros
 // NOLINTBEGIN(libcpp-robust-against-adl)
 
 #  if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
@@ -230,16 +230,6 @@ template <class charT> class messages_byname;
 #    define _LIBCPP_HAS_CATOPEN 0
 #  endif
 
-#  ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-#    include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
-#  else
-#    include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
-#  endif
-
-#  if defined(__APPLE__) || defined(__FreeBSD__)
-#    include <xlocale.h>
-#  endif
-
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py
index bc028f2a0809aa..ffbdf4a1e3194e 100644
--- a/libcxx/test/libcxx/clang_modules_include.gen.py
+++ b/libcxx/test/libcxx/clang_modules_include.gen.py
@@ -24,6 +24,10 @@
 //--- {header}.compile.pass.cpp
 // RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
 
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 
@@ -52,6 +56,10 @@
 
 // REQUIRES: clang-modules-build
 
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
 // GCC doesn't support -fcxx-modules
 // UNSUPPORTED: gcc
 

>From a435dff435b6d2cbd4d00ae96f50ad0085932d57 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 30 Oct 2024 13:52:56 -0400
Subject: [PATCH 19/19] Add printf

---
 .../__locale_dir/locale_base_api/bsd_locale_defaults.h       | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
index faf974df37e8f2..8c61a2cf30fb65 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h
@@ -73,7 +73,10 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __
 }
 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); }
+inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) {
+    fprintf(stderr, "Entering __libcpp_localeconv_l inside bsd_locale_defaults.h\n");
+    return ::localeconv_l(__loc);
+}
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 inline _LIBCPP_HIDE_FROM_ABI size_t



More information about the llvm-commits mailing list