[libcxx-commits] [libcxx] 88ffc72 - [libc++] Add a libc++ configuration that does not support localization

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 27 11:57:46 PDT 2020


Author: Louis Dionne
Date: 2020-10-27T14:56:30-04:00
New Revision: 88ffc72717c3b66b185caf8efcb0c19f32c355cd

URL: https://github.com/llvm/llvm-project/commit/88ffc72717c3b66b185caf8efcb0c19f32c355cd
DIFF: https://github.com/llvm/llvm-project/commit/88ffc72717c3b66b185caf8efcb0c19f32c355cd.diff

LOG: [libc++] Add a libc++ configuration that does not support localization

When porting libc++ to embedded systems, it can be useful to drop support
for localization, which these systems don't implement or care about.

Differential Revision: https://reviews.llvm.org/D90072

Added: 
    libcxx/cmake/caches/Generic-no-localization.cmake
    libcxx/test/libcxx/input.output/file.streams/lit.local.cfg
    libcxx/test/libcxx/input.output/iostream.format/lit.local.cfg
    libcxx/test/libcxx/input.output/iostream.objects/lit.local.cfg
    libcxx/test/libcxx/input.output/iostreams.base/lit.local.cfg
    libcxx/test/libcxx/input.output/stream.buffers/lit.local.cfg
    libcxx/test/libcxx/input.output/string.streams/lit.local.cfg
    libcxx/test/libcxx/localization/lit.local.cfg
    libcxx/test/std/depr/depr.ios.members/lit.local.cfg
    libcxx/test/std/depr/depr.str.strstreams/lit.local.cfg
    libcxx/test/std/input.output/file.streams/lit.local.cfg
    libcxx/test/std/input.output/input.output.general/lit.local.cfg
    libcxx/test/std/input.output/iostream.format/lit.local.cfg
    libcxx/test/std/input.output/iostream.forward/lit.local.cfg
    libcxx/test/std/input.output/iostream.objects/lit.local.cfg
    libcxx/test/std/input.output/iostreams.base/lit.local.cfg
    libcxx/test/std/input.output/iostreams.requirements/lit.local.cfg
    libcxx/test/std/input.output/stream.buffers/lit.local.cfg
    libcxx/test/std/input.output/string.streams/lit.local.cfg
    libcxx/test/std/iterators/stream.iterators/lit.local.cfg
    libcxx/test/std/localization/lit.local.cfg
    libcxx/test/std/re/lit.local.cfg
    libcxx/test/std/strings/basic.string/string.nonmembers/string.io/lit.local.cfg

Modified: 
    libcxx/CMakeLists.txt
    libcxx/include/__config_site.in
    libcxx/include/__locale
    libcxx/include/complex
    libcxx/include/filesystem
    libcxx/src/CMakeLists.txt
    libcxx/test/libcxx/depr/depr.str.strstreams/version.pass.cpp
    libcxx/test/libcxx/double_include.sh.cpp
    libcxx/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
    libcxx/test/libcxx/fuzzing/regex.pass.cpp
    libcxx/test/libcxx/min_max_macros.compile.pass.cpp
    libcxx/test/libcxx/modules/cinttypes_exports.compile.pass.cpp
    libcxx/test/libcxx/modules/clocale_exports.compile.pass.cpp
    libcxx/test/libcxx/modules/cstdint_exports.compile.pass.cpp
    libcxx/test/libcxx/modules/inttypes_h_exports.compile.pass.cpp
    libcxx/test/libcxx/modules/stdint_h_exports.compile.pass.cpp
    libcxx/test/libcxx/modules/stds_include.sh.cpp
    libcxx/test/libcxx/no_assert_include.compile.pass.cpp
    libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.nonmembers/stream_inserter.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp
    libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp
    libcxx/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
    libcxx/test/std/namespace/addressable_functions.sh.cpp
    libcxx/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
    libcxx/test/std/numerics/complex.number/complex.ops/stream_output.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_sseq.pass.cpp
    libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.discrete/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/io.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp
    libcxx/test/std/strings/string.view/string.view.io/stream_insert.pass.cpp
    libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp
    libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
    libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp
    libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.io/io.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp
    libcxx/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
    libcxx/utils/ci/buildkite-pipeline.yml
    libcxx/utils/ci/run-buildbot.sh
    libcxx/utils/generate_feature_test_macro_components.py
    libcxx/utils/libcxx/test/features.py

Removed: 
    


################################################################################
diff  --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 015a359bfb48..ee8ba4543340 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -115,6 +115,12 @@ option(LIBCXX_ENABLE_RANDOM_DEVICE
    a source of randomness, such as some embedded platforms. When this is not
    supported, most of <random> will still be available, but std::random_device
    will not." ON)
+option(LIBCXX_ENABLE_LOCALIZATION
+  "Whether to include support for localization in the library. Disabling
+   localization can be useful when porting to platforms that don't support
+   the C locale API (e.g. embedded). When localization is not supported,
+   several parts of the library will be disabled: <iostream>, <regex>, <locale>
+   will be completely unusable, and other parts may be only partly available." ON)
 option(LIBCXX_TEST_GDB_PRETTY_PRINTERS "Test gdb pretty printers." OFF)
 set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/legacy.cfg.in" CACHE STRING
     "The Lit testing configuration to use when running the tests.")
@@ -843,6 +849,7 @@ config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
 config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
 config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS)
 config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
+config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
 
 if (LIBCXX_ABI_DEFINES)
   set(abi_defines)

diff  --git a/libcxx/cmake/caches/Generic-no-localization.cmake b/libcxx/cmake/caches/Generic-no-localization.cmake
new file mode 100644
index 000000000000..79d6b44c7139
--- /dev/null
+++ b/libcxx/cmake/caches/Generic-no-localization.cmake
@@ -0,0 +1 @@
+set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")

diff  --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index 908fb1e674ce..8141d3c419f4 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -33,6 +33,7 @@
 #cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
 #cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS
 #cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
+#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION
 
 @_LIBCPP_ABI_DEFINES@
 

diff  --git a/libcxx/include/__locale b/libcxx/include/__locale
index 4721a00337ef..48e7b642f884 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -11,6 +11,11 @@
 #define _LIBCPP___LOCALE
 
 #include <__config>
+
+#if defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   error "Localization is not supported by this configuration of libc++"
+#endif
+
 #include <string>
 #include <memory>
 #include <utility>

diff  --git a/libcxx/include/complex b/libcxx/include/complex
index ec35f8ab27c3..ed84cd4cd39f 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -236,9 +236,12 @@ template<class T> complex<T> tanh (const complex<T>&);
 #include <stdexcept>
 #include <cmath>
 #include <iosfwd>
-#include <sstream>
 #include <version>
 
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <sstream> // for std::basic_ostringstream
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -1430,6 +1433,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
     return __is;
 }
 
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 template<class _Tp, class _CharT, class _Traits>
 basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
@@ -1441,6 +1445,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
     __s << '(' << __x.real() << ',' << __x.imag() << ')';
     return __os << __s.str();
 }
+#endif // !_LIBCPP_HAS_NO_LOCALIZATION
 
 #if _LIBCPP_STD_VER > 11
 // Literal suffix for complex number literals [complex.literals]

diff  --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index 86fff6ce60b7..5783ed3560ba 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -235,16 +235,19 @@
 #include <chrono>
 #include <iterator>
 #include <iosfwd>
-#include <locale>
 #include <memory>
 #include <stack>
 #include <string>
 #include <system_error>
 #include <utility>
-#include <iomanip> // for quoted
 #include <string_view>
 #include <version>
 
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <locale>
+# include <iomanip> // for quoted
+#endif
+
 #include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -661,6 +664,10 @@ struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
 template <class _Tp>
 struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
 
+template <class _ECharT>
+struct _PathCVT;
+
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 template <class _ECharT>
 struct _PathCVT {
   static_assert(__can_convert_char<_ECharT>::value,
@@ -703,6 +710,7 @@ struct _PathCVT {
                    _Traits::__range_end(__s));
   }
 };
+#endif // !_LIBCPP_HAS_NO_LOCALIZATION
 
 template <>
 struct _PathCVT<char> {
@@ -779,12 +787,14 @@ public:
     _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
   }
 
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
   // TODO Implement locale conversions.
   template <class _Source, class = _EnableIfPathable<_Source, void> >
   path(const _Source& __src, const locale& __loc, format = format::auto_format);
   template <class _InputIt>
   path(_InputIt __first, _InputIt _last, const locale& __loc,
        format = format::auto_format);
+#endif
 
   _LIBCPP_INLINE_VISIBILITY
   ~path() = default;
@@ -983,6 +993,10 @@ public:
 
   _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
 
+  _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
+  _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
+
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
   template <class _ECharT, class _Traits = char_traits<_ECharT>,
             class _Allocator = allocator<_ECharT> >
   basic_string<_ECharT, _Traits, _Allocator>
@@ -995,19 +1009,22 @@ public:
     return __s;
   }
 
-  _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
   _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const {
     return string<wchar_t>();
   }
-  _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
   _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const {
     return string<char16_t>();
   }
   _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const {
     return string<char32_t>();
   }
+#endif
 
   // generic format observers
+  std::string generic_string() const { return __pn_; }
+  std::string generic_u8string() const { return __pn_; }
+
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
   template <class _ECharT, class _Traits = char_traits<_ECharT>,
             class _Allocator = allocator<_ECharT> >
   basic_string<_ECharT, _Traits, _Allocator>
@@ -1015,11 +1032,10 @@ public:
     return string<_ECharT, _Traits, _Allocator>(__a);
   }
 
-  std::string generic_string() const { return __pn_; }
   std::wstring generic_wstring() const { return string<wchar_t>(); }
-  std::string generic_u8string() const { return __pn_; }
   std::u16string generic_u16string() const { return string<char16_t>(); }
   std::u32string generic_u32string() const { return string<char32_t>(); }
+#endif
 
 private:
   int __compare(__string_view) const;
@@ -1123,6 +1139,7 @@ public:
   iterator begin() const;
   iterator end() const;
 
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
   template <class _CharT, class _Traits>
   _LIBCPP_INLINE_VISIBILITY friend
       typename enable_if<is_same<_CharT, char>::value &&
@@ -1151,6 +1168,7 @@ public:
     __p = __tmp;
     return __is;
   }
+#endif // !_LIBCPP_HAS_NO_LOCALIZATION
 
   friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
     return __lhs.compare(__rhs) == 0;

diff  --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 95dd520d1e3e..d0e7255f5f60 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -19,20 +19,15 @@ set(LIBCXX_SOURCES
   include/atomic_support.h
   include/config_elast.h
   include/refstring.h
-  ios.cpp
-  iostream.cpp
-  locale.cpp
   memory.cpp
   mutex.cpp
   mutex_destructor.cpp
   new.cpp
   optional.cpp
   random_shuffle.cpp
-  regex.cpp
   shared_mutex.cpp
   stdexcept.cpp
   string.cpp
-  strstream.cpp
   support/runtime/exception_fallback.ipp
   support/runtime/exception_glibcxx.ipp
   support/runtime/exception_libcxxabi.ipp
@@ -66,6 +61,16 @@ if (LIBCXX_ENABLE_RANDOM_DEVICE)
     )
 endif()
 
+if (LIBCXX_ENABLE_LOCALIZATION)
+  list(APPEND LIBCXX_SOURCES
+    ios.cpp
+    iostream.cpp
+    locale.cpp
+    regex.cpp
+    strstream.cpp
+    )
+endif()
+
 if(WIN32)
   list(APPEND LIBCXX_SOURCES
     support/win32/locale_win32.cpp

diff  --git a/libcxx/test/libcxx/depr/depr.str.strstreams/version.pass.cpp b/libcxx/test/libcxx/depr/depr.str.strstreams/version.pass.cpp
index 59279f7ac6c2..ac7268969c92 100644
--- a/libcxx/test/libcxx/depr/depr.str.strstreams/version.pass.cpp
+++ b/libcxx/test/libcxx/depr/depr.str.strstreams/version.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <strstream>
 
 #include <strstream>

diff  --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp
index 42a437bbdbe1..838437130176 100644
--- a/libcxx/test/libcxx/double_include.sh.cpp
+++ b/libcxx/test/libcxx/double_include.sh.cpp
@@ -49,7 +49,6 @@
 #include <climits>
 #include <clocale>
 #include <cmath>
-#include <codecvt>
 #include <compare>
 #include <complex>
 #include <complex.h>
@@ -77,23 +76,17 @@
 #include <filesystem>
 #include <float.h>
 #include <forward_list>
-#include <fstream>
 #include <functional>
 #ifndef _LIBCPP_HAS_NO_THREADS
 #include <future>
 #endif
 #include <initializer_list>
 #include <inttypes.h>
-#include <iomanip>
-#include <ios>
 #include <iosfwd>
-#include <iostream>
-#include <istream>
 #include <iterator>
 #include <limits>
 #include <limits.h>
 #include <list>
-#include <locale>
 #include <locale.h>
 #include <map>
 #include <math.h>
@@ -105,11 +98,9 @@
 #include <numbers>
 #include <numeric>
 #include <optional>
-#include <ostream>
 #include <queue>
 #include <random>
 #include <ratio>
-#include <regex>
 #include <scoped_allocator>
 #include <set>
 #include <setjmp.h>
@@ -117,7 +108,6 @@
 #include <shared_mutex>
 #endif
 #include <span>
-#include <sstream>
 #include <stack>
 #include <stdbool.h>
 #include <stddef.h>
@@ -125,11 +115,9 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <streambuf>
 #include <string>
 #include <string.h>
 #include <string_view>
-#include <strstream>
 #include <system_error>
 #include <tgmath.h>
 #ifndef _LIBCPP_HAS_NO_THREADS
@@ -149,6 +137,24 @@
 #include <wchar.h>
 #include <wctype.h>
 
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#   include <codecvt>
+#   include <fstream>
+#   include <iomanip>
+#   include <ios>
+#   include <iostream>
+#   include <istream>
+#   include <locale>
+#   include <ostream>
+#   include <regex>
+#   include <sstream>
+#   include <streambuf>
+#   include <strstream>
+#   if __cplusplus >= 201103L
+#       include <experimental/regex>
+#   endif
+#endif
+
 // experimental headers
 #if __cplusplus >= 201103L
 #include <experimental/algorithm>
@@ -164,7 +170,6 @@
 #include <experimental/map>
 #include <experimental/memory_resource>
 #include <experimental/propagate_const>
-#include <experimental/regex>
 #include <experimental/simd>
 #include <experimental/set>
 #include <experimental/string>

diff  --git a/libcxx/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp b/libcxx/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
index 0d6d97a7c28e..ca63a212dbc7 100644
--- a/libcxx/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
+++ b/libcxx/test/libcxx/experimental/memory/memory.resource.aliases/header_regex_libcpp_version.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/regex>
 

diff  --git a/libcxx/test/libcxx/fuzzing/regex.pass.cpp b/libcxx/test/libcxx/fuzzing/regex.pass.cpp
index b027dd0a0fa4..fca7a9accf2c 100644
--- a/libcxx/test/libcxx/fuzzing/regex.pass.cpp
+++ b/libcxx/test/libcxx/fuzzing/regex.pass.cpp
@@ -8,6 +8,7 @@
 
 // UNSUPPORTED: c++03, c++11
 // UNSUPPORTED: no-exceptions
+// UNSUPPORTED: libcpp-has-no-localization
 
 #include <cstddef>
 #include <cstdint>

diff  --git a/libcxx/test/libcxx/input.output/file.streams/lit.local.cfg b/libcxx/test/libcxx/input.output/file.streams/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/file.streams/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/input.output/iostream.format/lit.local.cfg b/libcxx/test/libcxx/input.output/iostream.format/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/iostream.format/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/input.output/iostream.objects/lit.local.cfg b/libcxx/test/libcxx/input.output/iostream.objects/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/iostream.objects/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/input.output/iostreams.base/lit.local.cfg b/libcxx/test/libcxx/input.output/iostreams.base/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/iostreams.base/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/input.output/stream.buffers/lit.local.cfg b/libcxx/test/libcxx/input.output/stream.buffers/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/stream.buffers/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/input.output/string.streams/lit.local.cfg b/libcxx/test/libcxx/input.output/string.streams/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/string.streams/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/localization/lit.local.cfg b/libcxx/test/libcxx/localization/lit.local.cfg
new file mode 100644
index 000000000000..1fc6b7941603
--- /dev/null
+++ b/libcxx/test/libcxx/localization/lit.local.cfg
@@ -0,0 +1,4 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+localConfig = os.path.realpath(__file__).replace('/test/libcxx/', '/test/std/')
+config.load_from_path(localConfig, lit_config)

diff  --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
index 9e9edb86e791..3347f6f9f6ea 100644
--- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
@@ -61,8 +61,6 @@ TEST_MACROS();
 TEST_MACROS();
 #include <cmath>
 TEST_MACROS();
-#include <codecvt>
-TEST_MACROS();
 #include <complex>
 TEST_MACROS();
 #include <complex.h>
@@ -109,8 +107,6 @@ TEST_MACROS();
 TEST_MACROS();
 #include <forward_list>
 TEST_MACROS();
-#include <fstream>
-TEST_MACROS();
 #include <functional>
 TEST_MACROS();
 #ifndef _LIBCPP_HAS_NO_THREADS
@@ -121,16 +117,8 @@ TEST_MACROS();
 TEST_MACROS();
 #include <inttypes.h>
 TEST_MACROS();
-#include <iomanip>
-TEST_MACROS();
-#include <ios>
-TEST_MACROS();
 #include <iosfwd>
 TEST_MACROS();
-#include <iostream>
-TEST_MACROS();
-#include <istream>
-TEST_MACROS();
 #include <iterator>
 TEST_MACROS();
 #include <limits>
@@ -139,8 +127,6 @@ TEST_MACROS();
 TEST_MACROS();
 #include <list>
 TEST_MACROS();
-#include <locale>
-TEST_MACROS();
 #include <locale.h>
 TEST_MACROS();
 #include <map>
@@ -159,16 +145,12 @@ TEST_MACROS();
 TEST_MACROS();
 #include <optional>
 TEST_MACROS();
-#include <ostream>
-TEST_MACROS();
 #include <queue>
 TEST_MACROS();
 #include <random>
 TEST_MACROS();
 #include <ratio>
 TEST_MACROS();
-#include <regex>
-TEST_MACROS();
 #include <scoped_allocator>
 TEST_MACROS();
 #include <set>
@@ -181,8 +163,6 @@ TEST_MACROS();
 #endif
 #include <span>
 TEST_MACROS();
-#include <sstream>
-TEST_MACROS();
 #include <stack>
 TEST_MACROS();
 #include <stdbool.h>
@@ -197,16 +177,12 @@ TEST_MACROS();
 TEST_MACROS();
 #include <stdlib.h>
 TEST_MACROS();
-#include <streambuf>
-TEST_MACROS();
 #include <string>
 TEST_MACROS();
 #include <string.h>
 TEST_MACROS();
 #include <string_view>
 TEST_MACROS();
-#include <strstream>
-TEST_MACROS();
 #include <system_error>
 TEST_MACROS();
 #include <tgmath.h>
@@ -240,6 +216,37 @@ TEST_MACROS();
 #include <wctype.h>
 TEST_MACROS();
 
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#   include <codecvt>
+    TEST_MACROS();
+#   include <fstream>
+    TEST_MACROS();
+#   include <iomanip>
+    TEST_MACROS();
+#   include <ios>
+    TEST_MACROS();
+#   include <iostream>
+    TEST_MACROS();
+#   include <istream>
+    TEST_MACROS();
+#   include <locale>
+    TEST_MACROS();
+#   include <ostream>
+    TEST_MACROS();
+#   include <regex>
+    TEST_MACROS();
+#   include <sstream>
+    TEST_MACROS();
+#   include <streambuf>
+    TEST_MACROS();
+#   include <strstream>
+    TEST_MACROS();
+#   if __cplusplus >= 201103L
+#       include <experimental/regex>
+        TEST_MACROS();
+#   endif
+#endif
+
 // experimental headers
 #if __cplusplus >= 201103L
 #include <experimental/algorithm>
@@ -262,8 +269,6 @@ TEST_MACROS();
 TEST_MACROS();
 #include <experimental/propagate_const>
 TEST_MACROS();
-#include <experimental/regex>
-TEST_MACROS();
 #include <experimental/set>
 TEST_MACROS();
 #include <experimental/string>

diff  --git a/libcxx/test/libcxx/modules/cinttypes_exports.compile.pass.cpp b/libcxx/test/libcxx/modules/cinttypes_exports.compile.pass.cpp
index 57a5ba5c55cb..ec5c8de3f01b 100644
--- a/libcxx/test/libcxx/modules/cinttypes_exports.compile.pass.cpp
+++ b/libcxx/test/libcxx/modules/cinttypes_exports.compile.pass.cpp
@@ -10,9 +10,10 @@
 // are not modular
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // REQUIRES: modules-support
 // ADDITIONAL_COMPILE_FLAGS: -fmodules

diff  --git a/libcxx/test/libcxx/modules/clocale_exports.compile.pass.cpp b/libcxx/test/libcxx/modules/clocale_exports.compile.pass.cpp
index 9220f8e1af02..a460c6e884ff 100644
--- a/libcxx/test/libcxx/modules/clocale_exports.compile.pass.cpp
+++ b/libcxx/test/libcxx/modules/clocale_exports.compile.pass.cpp
@@ -10,9 +10,10 @@
 // are not modular
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // UNSUPPORTED: c++03
 

diff  --git a/libcxx/test/libcxx/modules/cstdint_exports.compile.pass.cpp b/libcxx/test/libcxx/modules/cstdint_exports.compile.pass.cpp
index 0887b597b5bf..c106bf68e86c 100644
--- a/libcxx/test/libcxx/modules/cstdint_exports.compile.pass.cpp
+++ b/libcxx/test/libcxx/modules/cstdint_exports.compile.pass.cpp
@@ -10,9 +10,10 @@
 // are not modular
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // Test that <cstdint> re-exports <stdint.h>
 

diff  --git a/libcxx/test/libcxx/modules/inttypes_h_exports.compile.pass.cpp b/libcxx/test/libcxx/modules/inttypes_h_exports.compile.pass.cpp
index 0add4e1a00ca..59b0d6256d7e 100644
--- a/libcxx/test/libcxx/modules/inttypes_h_exports.compile.pass.cpp
+++ b/libcxx/test/libcxx/modules/inttypes_h_exports.compile.pass.cpp
@@ -10,9 +10,10 @@
 // are not modular
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // Test that intypes.h re-exports stdint.h
 

diff  --git a/libcxx/test/libcxx/modules/stdint_h_exports.compile.pass.cpp b/libcxx/test/libcxx/modules/stdint_h_exports.compile.pass.cpp
index b83e99bcc9c6..830a2515be03 100644
--- a/libcxx/test/libcxx/modules/stdint_h_exports.compile.pass.cpp
+++ b/libcxx/test/libcxx/modules/stdint_h_exports.compile.pass.cpp
@@ -6,9 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // Test that int8_t and the like are exported from stdint.h, not inttypes.h
 

diff  --git a/libcxx/test/libcxx/modules/stds_include.sh.cpp b/libcxx/test/libcxx/modules/stds_include.sh.cpp
index 12d2899cf4ce..5235c7b05432 100644
--- a/libcxx/test/libcxx/modules/stds_include.sh.cpp
+++ b/libcxx/test/libcxx/modules/stds_include.sh.cpp
@@ -15,9 +15,10 @@
 // are not modular
 // XFAIL: LIBCXX-WINDOWS-FIXME
 
-// FIXME: The <atomic> header is not supported for single-threaded systems,
-// but still gets built as part of the 'std' module, which breaks the build.
-// XFAIL: libcpp-has-no-threads
+// Some headers are not available when these features are disabled, but they
+// still get built as part of the 'std' module, which breaks the build.
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // REQUIRES: modules-support
 

diff  --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
index 3cb58cd5ca56..182a1f31777d 100644
--- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
+++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
@@ -39,7 +39,6 @@
 #include <climits>
 #include <clocale>
 #include <cmath>
-#include <codecvt>
 #include <compare>
 #include <complex>
 #include <complex.h>
@@ -66,23 +65,17 @@
 #include <filesystem>
 #include <float.h>
 #include <forward_list>
-#include <fstream>
 #include <functional>
 #ifndef _LIBCPP_HAS_NO_THREADS
 #include <future>
 #endif
 #include <initializer_list>
 #include <inttypes.h>
-#include <iomanip>
-#include <ios>
 #include <iosfwd>
-#include <iostream>
-#include <istream>
 #include <iterator>
 #include <limits>
 #include <limits.h>
 #include <list>
-#include <locale>
 #include <locale.h>
 #include <map>
 #include <math.h>
@@ -93,11 +86,9 @@
 #include <new>
 #include <numeric>
 #include <optional>
-#include <ostream>
 #include <queue>
 #include <random>
 #include <ratio>
-#include <regex>
 #include <scoped_allocator>
 #include <set>
 #include <setjmp.h>
@@ -105,7 +96,6 @@
 #include <shared_mutex>
 #endif
 #include <span>
-#include <sstream>
 #include <stack>
 #include <stdbool.h>
 #include <stddef.h>
@@ -113,11 +103,9 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <streambuf>
 #include <string>
 #include <string.h>
 #include <string_view>
-#include <strstream>
 #include <system_error>
 #include <tgmath.h>
 #ifndef _LIBCPP_HAS_NO_THREADS
@@ -137,6 +125,24 @@
 #include <wchar.h>
 #include <wctype.h>
 
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#   include <codecvt>
+#   include <fstream>
+#   include <iomanip>
+#   include <ios>
+#   include <iostream>
+#   include <istream>
+#   include <locale>
+#   include <ostream>
+#   include <regex>
+#   include <sstream>
+#   include <streambuf>
+#   include <strstream>
+#   if __cplusplus >= 201103L
+#       include <experimental/regex>
+#   endif
+#endif
+
 // experimental headers
 #if __cplusplus >= 201103L
 #include <experimental/algorithm>
@@ -152,7 +158,6 @@
 #include <experimental/map>
 #include <experimental/memory_resource>
 #include <experimental/propagate_const>
-#include <experimental/regex>
 #include <experimental/simd>
 #include <experimental/set>
 #include <experimental/string>

diff  --git a/libcxx/test/std/depr/depr.ios.members/lit.local.cfg b/libcxx/test/std/depr/depr.ios.members/lit.local.cfg
new file mode 100644
index 000000000000..ebbd06ec931c
--- /dev/null
+++ b/libcxx/test/std/depr/depr.ios.members/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/depr/depr.str.strstreams/lit.local.cfg b/libcxx/test/std/depr/depr.str.strstreams/lit.local.cfg
new file mode 100644
index 000000000000..ebbd06ec931c
--- /dev/null
+++ b/libcxx/test/std/depr/depr.str.strstreams/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.nonmembers/stream_inserter.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.nonmembers/stream_inserter.pass.cpp
index 78f1ca7da52c..2ba88489d452 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.nonmembers/stream_inserter.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.nonmembers/stream_inserter.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <system_error>
 
 // class error_code

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp
index c5972fe18237..429388c277a5 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.cons/ostream_joiner.cons.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp
index 6e86ce781e7d..ed58745d79f0 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.creation/make_ostream_joiner.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp
index aac14fccf06e..bf9add9a13bc 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.assign.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp
index 57debaebca24..9d9457bafdf2 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.postincrement.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp
index a3773766d1d5..f03fbb0e98d5 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.pretincrement.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp
index ca18de3d5c45..6e54879fe64e 100644
--- a/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp
+++ b/libcxx/test/std/experimental/iterator/ostream.joiner/ostream.joiner.ops/ostream_joiner.op.star.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/iterator>
 //

diff  --git a/libcxx/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp
index 8f8dea1acc51..faa67a4be599 100644
--- a/libcxx/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp
+++ b/libcxx/test/std/experimental/memory/memory.resource.aliases/header_regex_synop.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <experimental/regex>
 

diff  --git a/libcxx/test/std/input.output/file.streams/lit.local.cfg b/libcxx/test/std/input.output/file.streams/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/file.streams/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
index 465959ba87e3..e787f5dc1b8b 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
index e66df6e302a2..606a8167d14e 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/source.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
index 234ad4be984c..8d02be832d22 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
index ee4d2fe15262..9e4a882186d1 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/source.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
index b51ea93fce92..c57ca6ebbaec 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
index 7d385c20bb73..bd32eda4c351 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
index 970bc0cf632d..12cda192b8e8 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/named_overloads.pass.cpp
@@ -8,6 +8,9 @@
 
 // UNSUPPORTED: c++03
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
index 091ea3140773..cf403925b965 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
@@ -9,6 +9,9 @@
 // UNSUPPORTED: c++03
 // REQUIRES: libc++
 
+// These tests require locale for non-char paths
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <filesystem>
 
 // class path

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
index 982a7a97fe04..7c60ae208a58 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/path.io.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <filesystem>
 

diff  --git a/libcxx/test/std/input.output/input.output.general/lit.local.cfg b/libcxx/test/std/input.output/input.output.general/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/input.output.general/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/iostream.format/lit.local.cfg b/libcxx/test/std/input.output/iostream.format/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/iostream.format/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/iostream.forward/lit.local.cfg b/libcxx/test/std/input.output/iostream.forward/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/iostream.forward/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/iostream.objects/lit.local.cfg b/libcxx/test/std/input.output/iostream.objects/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/iostream.objects/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/iostreams.base/lit.local.cfg b/libcxx/test/std/input.output/iostreams.base/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/iostreams.base/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/iostreams.requirements/lit.local.cfg b/libcxx/test/std/input.output/iostreams.requirements/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/iostreams.requirements/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/stream.buffers/lit.local.cfg b/libcxx/test/std/input.output/stream.buffers/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/stream.buffers/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/input.output/string.streams/lit.local.cfg b/libcxx/test/std/input.output/string.streams/lit.local.cfg
new file mode 100644
index 000000000000..cebfbadef2a0
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/iterators/stream.iterators/lit.local.cfg b/libcxx/test/std/iterators/stream.iterators/lit.local.cfg
new file mode 100644
index 000000000000..4d0904117654
--- /dev/null
+++ b/libcxx/test/std/iterators/stream.iterators/lit.local.cfg
@@ -0,0 +1,3 @@
+# stream iterators rely on the streams library, which requires localization
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
index 23378e0e2e3c..0b1b4ea3e106 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
@@ -9,6 +9,8 @@
 // WARNING: This test was generated by generate_feature_test_macro_components.py
 // and should not be edited manually.
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <iomanip>
 
 // Test the feature test macros defined by <iomanip>

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
index 3d8fb7a4cf9c..967173ea61a1 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
@@ -9,6 +9,8 @@
 // WARNING: This test was generated by generate_feature_test_macro_components.py
 // and should not be edited manually.
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <istream>
 
 // Test the feature test macros defined by <istream>

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
index eeea5390afd8..43156342555f 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
@@ -9,6 +9,8 @@
 // WARNING: This test was generated by generate_feature_test_macro_components.py
 // and should not be edited manually.
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <locale>
 
 // Test the feature test macros defined by <locale>

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
index d3ba25867d05..bb0737583ba4 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
@@ -9,6 +9,8 @@
 // WARNING: This test was generated by generate_feature_test_macro_components.py
 // and should not be edited manually.
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <ostream>
 
 // Test the feature test macros defined by <ostream>

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
index 66becadbbfb8..a73d936dd4ab 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
@@ -9,6 +9,8 @@
 // WARNING: This test was generated by generate_feature_test_macro_components.py
 // and should not be edited manually.
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <regex>
 
 // Test the feature test macros defined by <regex>

diff  --git a/libcxx/test/std/localization/lit.local.cfg b/libcxx/test/std/localization/lit.local.cfg
new file mode 100644
index 000000000000..ed0331c463d6
--- /dev/null
+++ b/libcxx/test/std/localization/lit.local.cfg
@@ -0,0 +1,3 @@
+# <locale> tests are obviously not supported when localization support is disabled
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/namespace/addressable_functions.sh.cpp b/libcxx/test/std/namespace/addressable_functions.sh.cpp
index 9b5e80ec1b01..de44ba42fb84 100644
--- a/libcxx/test/std/namespace/addressable_functions.sh.cpp
+++ b/libcxx/test/std/namespace/addressable_functions.sh.cpp
@@ -17,6 +17,9 @@
 // RUN: %{cxx} %t.tu1.o %t.tu2.o %{flags} %{link_flags} -o %t.exe
 // RUN: %{exec} %t.exe
 
+// The functions checked below come from <iostream> & friends
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <cassert>
 #include <ios>
 #include <istream>

diff  --git a/libcxx/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
index 5c78fe98dd13..344caa2841c1 100644
--- a/libcxx/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
+++ b/libcxx/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <complex>
 
 // template<class T, class charT, class traits>

diff  --git a/libcxx/test/std/numerics/complex.number/complex.ops/stream_output.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/stream_output.pass.cpp
index 690a16b800ee..9d9f4011b1dc 100644
--- a/libcxx/test/std/numerics/complex.number/complex.ops/stream_output.pass.cpp
+++ b/libcxx/test/std/numerics/complex.number/complex.ops/stream_output.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <complex>
 
 // template<class T, class charT, class traits>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp
index c3f781209fd4..68e5d8d0e4fa 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp
@@ -13,6 +13,9 @@
 
 // explicit discard_block_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp
index 3cb9df560d53..2e598664ea9d 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp
@@ -13,6 +13,9 @@
 
 // template<class Sseq> explicit discard_block_engine(Sseq& q);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp
index 9336b29a3c55..c5acba18e5d1 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class Engine, size_t p, size_t r>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp
index 27f408f4af41..b54aa24a42c5 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp
@@ -13,6 +13,9 @@
 
 // explicit independent_bits_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp
index 37ca482ee0b7..791ba3c1c675 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp
@@ -13,6 +13,9 @@
 
 // template<class Sseq> explicit independent_bits_engine(Sseq& q);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp
index 0fb967acfb43..f7cc60961fae 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class Engine, size_t w, class UIntType>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_result_type.pass.cpp
index e80553863017..b02022919582 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_result_type.pass.cpp
@@ -13,6 +13,9 @@
 
 // explicit shuffle_order_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_sseq.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_sseq.pass.cpp
index 22823ea91396..3ab141e79927 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_sseq.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/ctor_sseq.pass.cpp
@@ -13,6 +13,9 @@
 
 // template<class Sseq> explicit shuffle_order_engine(Sseq& q);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/io.pass.cpp
index 6bf4c8a00bdd..2970c1a2215c 100644
--- a/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.adapt/rand.adapt.shuf/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class Engine, size_t k>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/io.pass.cpp
index 68e050aab580..b55c7b2da079 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // class bernoulli_distribution

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp
index 875e501837e9..c54127422325 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp
@@ -15,6 +15,9 @@
 
 // Test the fix for https://llvm.org/PR44847.
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <numeric>
 #include <vector>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/io.pass.cpp
index 7edf05fae8bc..accc6c3aea73 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/io.pass.cpp
index 6cb22c8df459..c8b47227d6c5 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp
index e0e43d1a2db7..a8ca74c23ca2 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/io.pass.cpp
index 2f6bace070e9..2873aefae570 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/io.pass.cpp
index 06d7b4e4320e..8a2c3805d729 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/io.pass.cpp
index 76d4a48ec02f..a6aca373767a 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/io.pass.cpp
index cd67c03b6a23..92abb3a49a5f 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/io.pass.cpp
index ae58744d558d..fc136a3be38c 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/io.pass.cpp
index 2d172dc149c0..1e5e9f693eaa 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/io.pass.cpp
index f634f3efe2a2..0cf3a5bf95dd 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/io.pass.cpp
index a3434d854469..19ac0ea02f3a 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/io.pass.cpp
index ee9f20f563fa..c5cb803a77e6 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/io.pass.cpp
index afd77131ddc2..e5e634af2dbb 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/io.pass.cpp
index 56b25275e71a..06b3325b9f95 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.discrete/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.discrete/io.pass.cpp
index f4576e37202f..3b21092069e6 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.discrete/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.discrete/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/io.pass.cpp
index 6256e59d5574..7c761c045caf 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.pconst/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/io.pass.cpp
index 92f4d7666481..f01b38b93c51 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.samp/rand.dist.samp.plinear/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/io.pass.cpp
index f3b921afec3c..a52b253a6b26 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class _IntType = int>

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/io.pass.cpp
index e5abad268fdd..7935e6c2c8d0 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class RealType = double>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp
index a27361246005..0d84604f2744 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp
@@ -13,6 +13,9 @@
 
 // explicit linear_congruential_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/io.pass.cpp
index 6a93427f8e52..f9e9b2d19b2a 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template <class UIntType, UIntType a, UIntType c, UIntType m>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp
index a1f367f6aab5..be8ae17222fc 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp
@@ -15,6 +15,9 @@
 
 // explicit mersenne_twister_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq.pass.cpp
index 9c98e77ace74..a820468f1f93 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq.pass.cpp
@@ -15,6 +15,9 @@
 
 // template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/io.pass.cpp
index 6cd1e34f2b57..cdb71638ff68 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template <class UIntType, size_t w, size_t n, size_t m, size_t r,

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp
index 0a4c536aa811..b63d2e0afc8f 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp
@@ -13,6 +13,9 @@
 
 // explicit subtract_with_carry_engine(result_type s = default_seed);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp
index 08c7a3f6251f..0a8d7e661b4d 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp
@@ -13,6 +13,9 @@
 
 // template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
 
+// Serializing/deserializing the state of the RNG requires iostreams
+// UNSUPPORTED: libcpp-has-no-localization
+
 #include <random>
 #include <sstream>
 #include <cassert>

diff  --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp
index d5222842294d..472ed2dc2571 100644
--- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <random>
 
 // template<class UIntType, size_t w, size_t s, size_t r>

diff  --git a/libcxx/test/std/re/lit.local.cfg b/libcxx/test/std/re/lit.local.cfg
new file mode 100644
index 000000000000..a2664746cc18
--- /dev/null
+++ b/libcxx/test/std/re/lit.local.cfg
@@ -0,0 +1,3 @@
+# Unfortunately, <regex> uses locales in regex_traits
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/lit.local.cfg b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/lit.local.cfg
new file mode 100644
index 000000000000..8f204af4a58c
--- /dev/null
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/lit.local.cfg
@@ -0,0 +1,3 @@
+# These std::string functions require iostreams, which requires localization
+if 'libcpp-has-no-localization' in config.available_features:
+  config.unsupported = True

diff  --git a/libcxx/test/std/strings/string.view/string.view.io/stream_insert.pass.cpp b/libcxx/test/std/strings/string.view/string.view.io/stream_insert.pass.cpp
index c427e4a84403..8ba444dc2cea 100644
--- a/libcxx/test/std/strings/string.view/string.view.io/stream_insert.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.io/stream_insert.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <string>
 
 // template<class charT, class traits, class Allocator>

diff  --git a/libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp b/libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp
index c70d342ddd0b..3ad9ae22a95d 100644
--- a/libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <iomanip>
 

diff  --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
index 9f1f18dd6647..f04a0ebdf299 100644
--- a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -5,8 +5,9 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
+
 // UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <thread>
 

diff  --git a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp
index e63cf4e2388a..583ca60e7681 100644
--- a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp
+++ b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp
@@ -6,8 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Because we don't have a functioning decltype in C++03
 // UNSUPPORTED: c++03
-//  Because we don't have a functioning decltype in C++03
+
+// UNSUPPORTED: libcpp-has-no-localization
 
 // <memory>
 

diff  --git a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp
index dd1a9f7fa3c5..d09e029878b0 100644
--- a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp
+++ b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp
@@ -9,6 +9,8 @@
 // UNSUPPORTED: c++03
 //  Because we don't have a functioning decltype in C++03
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <memory>
 
 // unique_ptr

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.io/io.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.io/io.pass.cpp
index 8903b75ae4e2..6c3c9e47f105 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.io/io.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.io/io.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // <memory>
 
 // shared_ptr

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp
index 0127b75160ba..e2667e537987 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // test:
 
 // template <class charT, class traits, size_t N>

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp
index 3ef0eb8bf9bf..79621e25cc5a 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: libcpp-has-no-localization
+
 // test:
 
 // template <class charT, class traits, size_t N>

diff  --git a/libcxx/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp b/libcxx/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
index 2b1e224ad434..d53c67c492d9 100644
--- a/libcxx/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
+++ b/libcxx/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
@@ -5,7 +5,9 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+
 // UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-has-no-localization
 // XFAIL: *
 
 // <chrono>

diff  --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
index 3400083fb404..925a944811da 100644
--- a/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -113,6 +113,13 @@ steps:
     agents:
       queue: "libcxx-builders"
 
+  - label: "No locale"
+    command: "libcxx/utils/ci/run-buildbot.sh generic-no-localization"
+    artifact_paths:
+      - "**/test-results.xml"
+    agents:
+      queue: "libcxx-builders"
+
   - label: "MacOS C++20"
     command: "libcxx/utils/ci/run-buildbot.sh generic-cxx2a"
     artifact_paths:

diff  --git a/libcxx/utils/ci/run-buildbot.sh b/libcxx/utils/ci/run-buildbot.sh
index 31035a4dd4fa..1f0b3c7c71b3 100755
--- a/libcxx/utils/ci/run-buildbot.sh
+++ b/libcxx/utils/ci/run-buildbot.sh
@@ -143,6 +143,12 @@ generic-no-random_device)
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake"
     check-cxx-cxxabi
 ;;
+generic-no-localization)
+    export CC=clang
+    export CXX=clang++
+    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
+    check-cxx-cxxabi
+;;
 x86_64-apple-system)
     export CC=clang
     export CXX=clang++

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index be4bfe475667..6fef8ea85606 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -493,6 +493,11 @@ def add_version_header(tc):
   "atomic": ["UNSUPPORTED: libcpp-has-no-threads"],
   "shared_mutex": ["UNSUPPORTED: libcpp-has-no-threads"],
   "thread": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "iomanip": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "istream": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "locale": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "ostream": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "regex": ["UNSUPPORTED: libcpp-has-no-localization"],
 }
 
 def get_std_dialects():

diff  --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 47cfa7da67f8..53509d95ae21 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -75,6 +75,7 @@
   '_LIBCPP_ABI_VERSION': 'libcpp-abi-version',
   '_LIBCPP_ABI_UNSTABLE': 'libcpp-abi-unstable',
   '_LIBCPP_HAS_NO_RANDOM_DEVICE': 'libcpp-has-no-random-device',
+  '_LIBCPP_HAS_NO_LOCALIZATION': 'libcpp-has-no-localization',
 }
 for macro, feature in macros.items():
   DEFAULT_FEATURES += [


        


More information about the libcxx-commits mailing list