diff --git a/MODULE.bazel b/MODULE.bazel index 2d42157a..e3e9188d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -41,6 +41,7 @@ llvm_project_overlay.configure( "@rules_ll//patches:rules_ll_overlay_patch.diff", "@rules_ll//patches:clang_new_offload_driver.diff", "@rules_ll//patches:llvm_use_zlib-ng.diff", + "@rules_ll//patches:std_modules.diff", ], ) diff --git a/examples/std_module_example/BUILD.bazel b/examples/std_module_example/BUILD.bazel new file mode 100644 index 00000000..c7ec956a --- /dev/null +++ b/examples/std_module_example/BUILD.bazel @@ -0,0 +1,8 @@ +load("@rules_ll//ll:defs.bzl", "ll_binary") + +ll_binary( + name = "std_module_example", + srcs = ["main.cpp"], + compile_flags = ["-std=c++2b"], + visibility = ["@//:__pkg__"], +) diff --git a/examples/std_module_example/main.cpp b/examples/std_module_example/main.cpp new file mode 100644 index 00000000..a192e6ac --- /dev/null +++ b/examples/std_module_example/main.cpp @@ -0,0 +1,6 @@ +import std; + +auto main() -> int { + std::cout << "Hello, World!" << std::endl; + return 0; +} diff --git a/ll/args.bzl b/ll/args.bzl index d05c48f3..f17ae6b2 100644 --- a/ll/args.bzl +++ b/ll/args.bzl @@ -372,6 +372,13 @@ def compile_object_args( omit_if_empty = True, ) + if ctx.attr.compilation_mode != "bootstrap": + args.add_all( + toolchain.cpp_stdmodules, + map_each = _create_module_import, + format_each = "-fmodule-file=%s", + ) + # Input file. args.add(in_file) diff --git a/ll/inputs.bzl b/ll/inputs.bzl index 45ce394c..0c13062c 100644 --- a/ll/inputs.bzl +++ b/ll/inputs.bzl @@ -69,7 +69,7 @@ def compile_object_inputs( toolchain.unwind_library + toolchain.cpp_abihdrs + toolchain.compiler_runtime - ) + ) + [module.bmi for module in toolchain.cpp_stdmodules] if config == "cpp": pass @@ -120,7 +120,7 @@ def link_executable_inputs(ctx, in_files): ctx.files.deps + ctx.files.libraries + ctx.files.data - ) + ) + [module.bmi for module in toolchain.cpp_stdmodules] if config == "bootstrap": return depset(direct) diff --git a/ll/toolchain.bzl b/ll/toolchain.bzl index e6d39eeb..9229c3ff 100644 --- a/ll/toolchain.bzl +++ b/ll/toolchain.bzl @@ -4,6 +4,7 @@ This file declares the `ll_toolchain` rule. """ load("//ll:attributes.bzl", "LL_TOOLCHAIN_ATTRS") +load("//ll:providers.bzl", "LlInfo") def _ll_toolchain_impl(ctx): # We always need to invoke lld via an ld.lld -> lld symlink. @@ -20,6 +21,10 @@ def _ll_toolchain_impl(ctx): ]) llvm_project_artifacts = ctx.files.llvm_project_deps + std_modules = [] + for target in ctx.attr.cpp_stdlib: + std_modules += target[LlInfo].exposed_bmis.to_list() + return [ platform_common.ToolchainInfo( c_driver = ctx.executable.c_driver, @@ -42,6 +47,7 @@ def _ll_toolchain_impl(ctx): builtin_includes = ctx.files.builtin_includes, cpp_stdlib = ctx.files.cpp_stdlib, cpp_stdhdrs = ctx.files.cpp_stdhdrs, + cpp_stdmodules = std_modules, cpp_abilib = ctx.files.cpp_abilib, cpp_abihdrs = ctx.files.cpp_abihdrs, compiler_runtime = ctx.files.compiler_runtime, diff --git a/llvm-project-overlay/libcxx/BUILD.bazel b/llvm-project-overlay/libcxx/BUILD.bazel index c1b167e4..c103a1dc 100644 --- a/llvm-project-overlay/libcxx/BUILD.bazel +++ b/llvm-project-overlay/libcxx/BUILD.bazel @@ -1,6 +1,115 @@ load("@rules_ll//ll:defs.bzl", "ll_library") load("@bazel_skylib//rules:expand_template.bzl", "expand_template") +STD_PARTITIONS = [ + "algorithm", + "any", + "array", + "atomic", + "barrier", + "bit", + "bitset", + "cassert", + "cctype", + "cerrno", + "cfenv", + "cfloat", + "charconv", + "chrono", + "cinttypes", + "climits", + "clocale", + "cmath", + "codecvt", + "compare", + "complex", + "concepts", + "condition_variable", + "coroutine", + "csetjmp", + "csignal", + "cstdarg", + "cstddef", + "cstdio", + "cstdlib", + "cstring", + "ctime", + "cuchar", + "cwchar", + "cwctype", + "deque", + "exception", + "execution", + "expected", + "filesystem", + "flat_map", + "flat_set", + "format", + "forward_list", + "fstream", + "functional", + "future", + "generator", + "initializer_list", + "iomanip", + "ios", + "iosfwd", + "iostream", + "istream", + "iterator", + "latch", + "limits", + "list", + "locale", + "map", + "mdspan", + # "memory", # Bugged? + "memory_resource", + "mutex", + # "new", # Needs special treatment. Module is called __new. + "numbers", + "numeric", + "optional", + "ostream", + "print", + "queue", + "random", + "ranges", + "ratio", + "regex", + "scoped_allocator", + "semaphore", + "set", + "shared_mutex", + "source_location", + "span", + "spanstream", + "sstream", + "stack", + "stacktrace", + "stdexcept", + "stdfloat", + "stop_token", + "streambuf", + "string", + "string_view", + "strstream", + "syncstream", + "system_error", + "thread", + "tuple", + "typeindex", + "typeinfo", + "type_traits", + "unordered_map", + "unordered_set", + "utility", + "valarray", + "variant", + "vector", + "version", +] + expand_template( name = "module_modulemap_gen", out = "include/module.modulemap", @@ -152,7 +261,7 @@ ll_library( ], compilation_mode = "bootstrap", compile_flags = [ - "-std=c++20", + "-std=c++2b", "-faligned-allocation", "-fno-omit-frame-pointer", "-funwind-tables", @@ -178,9 +287,18 @@ ll_library( exposed_hdrs = [ "//libcxx:headers", ], + exposed_interfaces = { + "modules/std.cppm": "std", + }, includes = [ "libcxx/src", ], + interfaces = { + "modules/std/{}.cppm".format(name): "std:{}".format(name) + for name in STD_PARTITIONS + } | { + "modules/std/new.cppm": "std:__new", + }, visibility = ["//visibility:public"], deps = ["//libcxxabi"], ) diff --git a/patches/rules_ll_overlay_patch.diff b/patches/rules_ll_overlay_patch.diff index d666d9f4..2adb3d38 100644 --- a/patches/rules_ll_overlay_patch.diff +++ b/patches/rules_ll_overlay_patch.diff @@ -1270,13 +1270,122 @@ index 000000000000..8ad56ad46df6 +) diff --git a/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel new file mode 100644 -index 000000000000..c1b167e454c6 +index 000000000000..c103a1dcdff7 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel -@@ -0,0 +1,186 @@ +@@ -0,0 +1,304 @@ +load("@rules_ll//ll:defs.bzl", "ll_library") +load("@bazel_skylib//rules:expand_template.bzl", "expand_template") + ++STD_PARTITIONS = [ ++ "algorithm", ++ "any", ++ "array", ++ "atomic", ++ "barrier", ++ "bit", ++ "bitset", ++ "cassert", ++ "cctype", ++ "cerrno", ++ "cfenv", ++ "cfloat", ++ "charconv", ++ "chrono", ++ "cinttypes", ++ "climits", ++ "clocale", ++ "cmath", ++ "codecvt", ++ "compare", ++ "complex", ++ "concepts", ++ "condition_variable", ++ "coroutine", ++ "csetjmp", ++ "csignal", ++ "cstdarg", ++ "cstddef", ++ "cstdio", ++ "cstdlib", ++ "cstring", ++ "ctime", ++ "cuchar", ++ "cwchar", ++ "cwctype", ++ "deque", ++ "exception", ++ "execution", ++ "expected", ++ "filesystem", ++ "flat_map", ++ "flat_set", ++ "format", ++ "forward_list", ++ "fstream", ++ "functional", ++ "future", ++ "generator", ++ "initializer_list", ++ "iomanip", ++ "ios", ++ "iosfwd", ++ "iostream", ++ "istream", ++ "iterator", ++ "latch", ++ "limits", ++ "list", ++ "locale", ++ "map", ++ "mdspan", ++ # "memory", # Bugged? ++ "memory_resource", ++ "mutex", ++ # "new", # Needs special treatment. Module is called __new. ++ "numbers", ++ "numeric", ++ "optional", ++ "ostream", ++ "print", ++ "queue", ++ "random", ++ "ranges", ++ "ratio", ++ "regex", ++ "scoped_allocator", ++ "semaphore", ++ "set", ++ "shared_mutex", ++ "source_location", ++ "span", ++ "spanstream", ++ "sstream", ++ "stack", ++ "stacktrace", ++ "stdexcept", ++ "stdfloat", ++ "stop_token", ++ "streambuf", ++ "string", ++ "string_view", ++ "strstream", ++ "syncstream", ++ "system_error", ++ "thread", ++ "tuple", ++ "typeindex", ++ "typeinfo", ++ "type_traits", ++ "unordered_map", ++ "unordered_set", ++ "utility", ++ "valarray", ++ "variant", ++ "vector", ++ "version", ++] ++ +expand_template( + name = "module_modulemap_gen", + out = "include/module.modulemap", @@ -1428,7 +1537,7 @@ index 000000000000..c1b167e454c6 + ], + compilation_mode = "bootstrap", + compile_flags = [ -+ "-std=c++20", ++ "-std=c++2b", + "-faligned-allocation", + "-fno-omit-frame-pointer", + "-funwind-tables", @@ -1454,9 +1563,18 @@ index 000000000000..c1b167e454c6 + exposed_hdrs = [ + "//libcxx:headers", + ], ++ exposed_interfaces = { ++ "modules/std.cppm": "std", ++ }, + includes = [ + "libcxx/src", + ], ++ interfaces = { ++ "modules/std/{}.cppm".format(name): "std:{}".format(name) ++ for name in STD_PARTITIONS ++ } | { ++ "modules/std/new.cppm": "std:__new", ++ }, + visibility = ["//visibility:public"], + deps = ["//libcxxabi"], +) diff --git a/patches/std_modules.diff b/patches/std_modules.diff new file mode 100644 index 00000000..592916c4 --- /dev/null +++ b/patches/std_modules.diff @@ -0,0 +1,12438 @@ +diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt +index cf572af74bd1..c594d423d4d9 100644 +--- a/libcxx/CMakeLists.txt ++++ b/libcxx/CMakeLists.txt +@@ -106,6 +106,10 @@ option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS + the shared library they shipped should turn this on and see `include/__availability` + for more details." OFF) + option(LIBCXX_ENABLE_CLANG_TIDY "Whether to compile and run clang-tidy checks" OFF) ++option(LIBCXX_ENABLE_STD_MODULE ++ "Whether to enable the building the C++23 std module. This feature is experimental ++ and far from usable. Only enable this when interested in testing and developing ++ this module." OFF) + + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") +@@ -159,6 +163,7 @@ option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS + set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING + "Define suffix of library directory name (32/64)") + option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) ++option(LIBCXX_INSTALL_MODULES "Install the libc++ modules." ON) + option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON) + cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY + "Install the static libc++ library." ON +@@ -402,8 +407,14 @@ endif () + # TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR + # instead of hard-coding include/c++/v1. + ++# TODO MODULES: CMAKE_INSTALL_MODULEDIR does not exist therefore generate one ++# based on the include dir name. ++string(REPLACE "include" "modules" CMAKE_INSTALL_MODULEDIR ${CMAKE_INSTALL_INCLUDEDIR}) ++ + set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH + "Path where target-agnostic libc++ headers should be installed.") ++set(LIBCXX_INSTALL_MODULE_DIR "${CMAKE_INSTALL_MODULEDIR}/c++/v1" CACHE PATH ++ "Path where target-agnostic libc++ modules should be installed.") + set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH + "Path where built libc++ runtime libraries should be installed.") + +@@ -413,6 +424,7 @@ set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static lib + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") ++ set(LIBCXX_GENERATED_MODULE_DIR "${LLVM_BINARY_DIR}/modules/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++ libraries should be installed.") +@@ -426,9 +438,11 @@ else() + if(LLVM_LIBRARY_OUTPUT_INTDIR) + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") ++ set(LIBCXX_GENERATED_MODULE_DIR "${LLVM_BINARY_DIR}/modules/c++/v1") + else() + set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") ++ set(LIBCXX_GENERATED_MODULE_DIR "${CMAKE_BINARY_DIR}/modules/c++/v1") + endif() + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH +@@ -860,6 +874,9 @@ endfunction() + add_subdirectory(include) + add_subdirectory(src) + add_subdirectory(utils) ++if (LIBCXX_ENABLE_STD_MODULE) ++ add_subdirectory(modules) ++endif() + + set(LIBCXX_TEST_DEPS "cxx_experimental") + +@@ -871,6 +888,10 @@ if (LIBCXX_ENABLE_CLANG_TIDY) + list(APPEND LIBCXX_TEST_DEPS cxx-tidy) + endif() + ++if (LIBCXX_ENABLE_STD_MODULE) ++ list(APPEND LIBCXX_TEST_DEPS generate-cxx-modules) ++endif() ++ + if (LIBCXX_INCLUDE_BENCHMARKS) + add_subdirectory(benchmarks) + endif() +diff --git a/libcxx/cmake/caches/Generic-module-std-compat.cmake b/libcxx/cmake/caches/Generic-module-std-compat.cmake +new file mode 100644 +index 000000000000..8d826508d127 +--- /dev/null ++++ b/libcxx/cmake/caches/Generic-module-std-compat.cmake +@@ -0,0 +1,3 @@ ++set(LIBCXX_ENABLE_STD_MODULE ON CACHE BOOL "") ++set(LIBCXX_TEST_PARAMS "enable_modules=std.compat" CACHE STRING "") ++set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") +diff --git a/libcxx/cmake/caches/Generic-module-std.cmake b/libcxx/cmake/caches/Generic-module-std.cmake +new file mode 100644 +index 000000000000..96819ad32bbd +--- /dev/null ++++ b/libcxx/cmake/caches/Generic-module-std.cmake +@@ -0,0 +1,4 @@ ++set(LIBCXX_ENABLE_STD_MODULE ON CACHE BOOL "") ++set(LIBCXX_TEST_PARAMS "enable_modules=std" CACHE STRING "") ++set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") ++ +diff --git a/libcxx/docs/Modules.rst b/libcxx/docs/Modules.rst +new file mode 100644 +index 000000000000..4053e65a5873 +--- /dev/null ++++ b/libcxx/docs/Modules.rst +@@ -0,0 +1,235 @@ ++.. _ModulesInLibcxx: ++ ++================= ++Modules in libc++ ++================= ++ ++This page contains information regarding C++23 module support in libc++. ++There are two kinds of modules available in Clang ++ ++ * `Clang specific modules `_ ++ * `C++ modules `_ ++ ++This page mainly discusses the C++ modules. In C++ there are also header units, ++these are not in this patch. ++ ++This information is mainly to describe some of the features of this work in ++progress patch. It is not intended to be committed in this form. ++ ++Overview ++======== ++ ++The module sources are stored in ``.cppm`` files. These need to be available as ++BMIs, which are ``.pcm`` files for Clang. These files are not portable, they ++depend on the compiler used and its compilation flags. Therefore there needs to ++be a way to distribute the ``.cppm`` files to the user and offer a way for them ++to build and use the ``.pcm`` files. ++ ++What works ++~~~~~~~~~~ ++ ++ * Building BMIs ++ * Running tests using modules, not all tests pass yet ++ * Using the ``std`` module in external projects ++ * Using the ``std.compat`` module in external projects ++ * Installing libc++ (the installation location is still being discussed) ++ * The following "parts disabled configuration options are supported ++ ++ * ``LIBCXX_ENABLE_LOCALIZATION`` ++ * ``LIBCXX_ENABLE_WIDE_CHARACTERS`` ++ ++Some of the current limitations ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ ++ * For now everything requires CMake. ++ * The ``.pcm`` files are regenerated when running a ``lit`` invocation. ++ * There is no Buildkite CI job yet. Work on this has started, but the CI Docker ++ image is not updated yet. (There are issues with the official CI image which ++ need to be resolved before adding new features.) ++ * The ``std`` should be complete, but there are not tests to verify that. ++ * The ``std.compat`` should be complete, but there are not tests to verify that. ++ * The modules are not tested. ++ * The modules are not reviewed for correctness. ++ * Requires CMake 3.26 ++ * Requires Ninja 1.11 ++ * Requires Clang 17 (Clang 16 should work, but is not tested) ++ * The path to the compiler may not be a symlink, ``clang-scan-deps`` does ++ not handle that case properly. ++ * Configurations with "parts disable" that are not explicitly allowed will ++ fail to build a ``.pcm``. ++ ++Blockers ++~~~~~~~~ ++ ++ * libc++ ++ ++ * Tests depend on ``uint32_t``, ``size_t`` in the global namespace. ++ Fixing this is WIP. ++ * There are a lot of failing tests, this needs to be investigated after ++ the global namespace issues have been fixed. ++ Currently 222 of the 7243 test in the directory ``libcxx/test/std`` fail ++ when using the ``std.compat`` module. ++ * CMake 3.26 doesn't work with ``libunwind``. For ``libc++`` and ++ ``libc++abi`` it ignores a lot of compilation flags. ++ `Patch `__ ++ * The ``-pthread`` flag is not used a compile flag. This flag affects ++ the preprocessor so it should be a compile and linker flag. ++ There is a WIP patch. ++ * There are symbols with internal linkage in the header. ++ ++ * Due to older language versions don't support ``inline constexpr``. ++ `Patch `__ ++ ++ * Clang ++ ++ * ``__synth_three_way_result`` does not work. There is a work-around in libc++. ++ ++ * `bug report `__ ++ * `clang patch `__ ++ * `libc++ patch /`__ ++ ++ * The ranges Niebloids don't work properly. There is no bug report, this ++ might be related to ``__synth_three_way_result``. Changing ++ ``inline constexpr auto foo = foo_t{}`` to ++ ``inline constexpr foo_t foo{}`` seems to fix it in libc++. ++ ++ * Including headers after importing the ``std`` module may fail. This is ++ hard to solve and there is a work-around by first including all headers. ++ `bug report `__ ++ ++Discussion points ++~~~~~~~~~~~~~~~~~ ++ ++ * The ``std`` module is a C++23 feature, currently it's available in both ++ ``C++20`` and ``C++23``. The simple reason is that this allows testing with ++ different language versions. (This will be needed once the first ``C++26`` ++ features become available.) Does libc++ want to retroactively supply the ++ module in ``C++20`` or restrict it to ``C++23`` and later? ++ Since ``C++20`` was far from complete it has been removed. The testing with ++ different language version is replaced by testing with different parts enabled, ++ this is something libc++ needs to support. ++ * Do we want the feature behind a configuration flag or not? Louis already ++ mentioned he prefers it generally available. Then we need to restrict it on ++ the CMake version used. ++ * I'm not too unhappy with the generic approach for user project. I am quite ++ unhappy with how we need to do tests. I have some ideas how we can improve ++ this, basically by caching multiple configurations. However it would be good ++ to discuss that approach before spending effort in it. ++ * The current approach to make the tests work with modules add a ``#ifdef`` ++ to select between including headers or importing the module ``std``. ++ This works great for testing during development, however the libc++ ++ maintainers need to decide to keep using this approach in production or ++ that a different solution needs to be used. ++ ++ ++Design choices ++============== ++ ++Shipping ++-------- ++ ++Since BMIs are not portable libc++ will ship its ``.cppm`` files. Users need to ++compile them to BMIs. Since the feature is under heavy development there is no ++support for build tools. For that reason a CMake file will be shipped. Once ++build tool vendors have support for libc++'s modules this support file will be ++removed. (This file is used for the libc++ tests too, so maybe it remains build ++it will not longer be shipped.) ++ ++The modules will shipped in a directory structure similar to the include. ++Includes are stored in ``/includes/c++/v1`` modules will be stored in ++``/modules/c++/v1/``. ++ ++To make it easy for build tool vendors the directory ++``/modules/c++/v1/`` will have the following contents ++ ++ * ``std.cppm`` the main ``std`` module source. ++ * ``std/`` all other sources for the ``std`` module. Using this directory ++ makes it easy for vendors to glob all files belonging the the ``std`` ++ module. ++ * ``std.compat.cppm`` the main ``std.compat`` module source. ++ * ``std.compat/`` like ``std/`` but for the ``std.compat`` module. ++ ++If in the future the C++ Standard defines more modules they will get a similar ++treatment. (For example modules for experimental library features.) ++ ++.. note:: This matches the current proposal on `discourse ++ `__ ++ so it may still change. That discussion starts to move to ++ ``/share/c++/modules/v1/`` instead of the original location. ++ ++Testing ++------- ++ ++To properly test all tests with modules all tests need to be converted. The ++script ``libcxx/utils/use_modules_in_test.py`` can do this conversion. Since not ++all developers are happy with the output this script will be executed in the CI ++and then the CI will run on the modified sources. ++ ++Running tests ++============= ++ ++In order to run the tests with C++23 modules the libc++ needs to be build with ++the following configuration option in CMake ``LIBCXX_ENABLE_STD_MODULE``. ++ ++The tests are executed like ++ ++.. code-block:: bash ++ ++ $ /bin/llvm-lit -sv libcxx/test/std/containers # Run the tests without modules ++ $ /bin/llvm-lit -sv -Denable_modules=clang libcxx/test/std/containers # Run the tests with Clang modules ++ $ /bin/llvm-lit -sv -Denable_modules=std libcxx/test/std/containers # Run the tests with Standard std module ++ $ /bin/llvm-lit -sv -Denable_modules=std.compat libcxx/test/std/containers # Run the tests with Standard std.compat module ++ ++The Clang modules are the modules that have been available for many libc++ releases. ++The Standard modules are the new feature. ++ ++Using in external projects ++========================== ++ ++Users need to be able to build their own BMI files. ++ ++.. note:: The requirements for users to build their own BMI files will remain ++ true for the forseeable future. For now this needs to be done manually. ++ Once libc++'s implementation is more mature we will reach out to build ++ system vendors, with the goal that the building of the BMI files will be ++ done by the build system. ++ ++Currently this requires a local build of libc++ with modules enabled. ++"Importing" libc++ is a project can be done with the following CMake code. ++ ++.. code-block:: cmake ++ ++ include(FetchContent) ++ FetchContent_Declare( ++ std ++ URL file:///include/c++/modules/ ++ DOWNLOAD_EXTRACT_TIMESTAMP TRUE ++ ) ++ FetchContent_GetProperties(std) ++ if(NOT std_POPULATED) ++ # The C++ version used in your project must match the version used here. ++ set(CMAKE_CXX_STANDARD 23) ++ # These compiler flags must match the flags used in your project. ++ # When they don't match the generated BMIs can't be used in your project. ++ set(CMAKE_CXX_FLAGS "-fexperimental-library") ++ FetchContent_Populate(std) ++ add_subdirectory(${std_SOURCE_DIR} ${std_BINARY_DIR} EXCLUDE_FROM_ALL) ++ endif() ++ ++The libraries and/or executables that use the ``std`` module need to link ++against the ``std`` library. This is needed for CMake to get the proper module ++dependencies. Similar for the ``std.compat`` module. ++ ++.. warning:: There is a bug in Clang where including headers after an import ++ may fail. Instead include all headers first and then include the module. ++ ++ ++.. code-block:: cmake ++ ++ #include ++ ++ #include "A header that may include other headers.h" ++ ++ import std; ++ ++ ... +diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst +index abcdeabec487..a811e94a3d2d 100644 +--- a/libcxx/docs/index.rst ++++ b/libcxx/docs/index.rst +@@ -39,6 +39,7 @@ Getting Started with libc++ + BuildingLibcxx + TestingLibcxx + Contributing ++ Modules + Status/Cxx14 + Status/Cxx17 + Status/Cxx20 +diff --git a/libcxx/include/tuple b/libcxx/include/tuple +index abfd441e6c59..cf5197f3f17d 100644 +--- a/libcxx/include/tuple ++++ b/libcxx/include/tuple +@@ -1501,9 +1501,10 @@ struct __ignore_t + const __ignore_t& operator=(_Tp&&) const {return *this;} + }; + +-namespace { +- constexpr __ignore_t ignore = __ignore_t(); +-} // namespace ++// SEPARATE REVIEW NEEDS TO USE NEW INLINE CONSTEXPR MACRO ++//namespace { ++ inline constexpr __ignore_t ignore = __ignore_t(); ++//} // namespace + + template + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +diff --git a/libcxx/modules/.clang-format b/libcxx/modules/.clang-format +new file mode 100644 +index 000000000000..69dcdadf00fa +--- /dev/null ++++ b/libcxx/modules/.clang-format +@@ -0,0 +1,3 @@ ++BasedOnStyle: InheritParentConfig ++ ++NamespaceIndentation: All +diff --git a/libcxx/modules/CMakeLists.txt b/libcxx/modules/CMakeLists.txt +new file mode 100644 +index 000000000000..d7546aeb15a8 +--- /dev/null ++++ b/libcxx/modules/CMakeLists.txt +@@ -0,0 +1,194 @@ ++ ++# The headers of Table 24: C++ library headers [tab:headers.cpp] ++# and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] ++set(LIBCXX_SOURCES_MODULE_STD ++ std.cppm ++ std/algorithm.cppm ++ std/any.cppm ++ std/array.cppm ++ std/atomic.cppm ++ std/barrier.cppm ++ std/bit.cppm ++ std/bitset.cppm ++ std/cassert.cppm ++ std/cctype.cppm ++ std/cerrno.cppm ++ std/cfenv.cppm ++ std/cfloat.cppm ++ std/charconv.cppm ++ std/chrono.cppm ++ std/cinttypes.cppm ++ std/climits.cppm ++ std/clocale.cppm ++ std/cmath.cppm ++ std/codecvt.cppm ++ std/compare.cppm ++ std/complex.cppm ++ std/concepts.cppm ++ std/condition_variable.cppm ++ std/coroutine.cppm ++ std/csetjmp.cppm ++ std/csignal.cppm ++ std/cstdarg.cppm ++ std/cstddef.cppm ++ std/cstdio.cppm ++ std/cstdlib.cppm ++ std/cstdlib.cppm ++ std/cstring.cppm ++ std/ctime.cppm ++ std/cuchar.cppm ++ std/cwchar.cppm ++ std/cwctype.cppm ++ std/deque.cppm ++ std/exception.cppm ++ std/execution.cppm ++ std/expected.cppm ++ std/filesystem.cppm ++ std/flat_map.cppm ++ std/flat_set.cppm ++ std/format.cppm ++ std/forward_list.cppm ++ std/fstream.cppm ++ std/functional.cppm ++ std/future.cppm ++ std/generator.cppm ++ std/initializer_list.cppm ++ std/iomanip.cppm ++ std/ios.cppm ++ std/iosfwd.cppm ++ std/iostream.cppm ++ std/iostream.cppm ++ std/istream.cppm ++ std/iterator.cppm ++ std/latch.cppm ++ std/limits.cppm ++ std/list.cppm ++ std/locale.cppm ++ std/map.cppm ++ std/mdspan.cppm ++ std/memory.cppm ++ std/memory_resource.cppm ++ std/mutex.cppm ++ std/new.cppm ++ std/numbers.cppm ++ std/numeric.cppm ++ std/optional.cppm ++ std/ostream.cppm ++ std/print.cppm ++ std/queue.cppm ++ std/random.cppm ++ std/ranges.cppm ++ std/ratio.cppm ++ std/regex.cppm ++ std/scoped_allocator.cppm ++ std/semaphore.cppm ++ std/set.cppm ++ std/shared_mutex.cppm ++ std/source_location.cppm ++ std/span.cppm ++ std/spanstream.cppm ++ std/sstream.cppm ++ std/stack.cppm ++ std/stacktrace.cppm ++ std/stdexcept.cppm ++ std/stdexcept.cppm ++ std/stdfloat.cppm ++ std/stop_token.cppm ++ std/streambuf.cppm ++ std/string.cppm ++ std/string_view.cppm ++ std/strstream.cppm ++ std/syncstream.cppm ++ std/system_error.cppm ++ std/thread.cppm ++ std/tuple.cppm ++ std/type_traits.cppm ++ std/typeindex.cppm ++ std/typeinfo.cppm ++ std/unordered_map.cppm ++ std/unordered_set.cppm ++ std/utility.cppm ++ std/valarray.cppm ++ std/variant.cppm ++ std/vector.cppm ++ std/version.cppm ++) ++ ++# The headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] ++set(LIBCXX_SOURCES_MODULE_STD_COMPAT ++ std.compat.cppm ++ std.compat/cassert.cppm ++ std.compat/cctype.cppm ++ std.compat/cerrno.cppm ++ std.compat/cfenv.cppm ++ std.compat/cfloat.cppm ++ std.compat/cinttypes.cppm ++ std.compat/climits.cppm ++ std.compat/clocale.cppm ++ std.compat/cmath.cppm ++ std.compat/csetjmp.cppm ++ std.compat/csignal.cppm ++ std.compat/cstdarg.cppm ++ std.compat/cstddef.cppm ++ std.compat/cstdint.cppm ++ std.compat/cstdio.cppm ++ std.compat/cstdlib.cppm ++ std.compat/cstring.cppm ++ std.compat/ctime.cppm ++ std.compat/cuchar.cppm ++ std.compat/cwchar.cppm ++ std.compat/cwctype.cppm ++) ++ ++# TODO MODULES the CMakeLists.txt in the install directory is only temporary ++# When that is removed the configured file can use the substitution ++# LIBCXX_GENERATED_INCLUDE_TARGET_DIR avoiding this set. ++# Also clean up the parts needed to generate the install version. ++set(LIBCXX_CONFIGURED_INCLUDE_DIR ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) ++configure_file( ++ "CMakeLists.txt.in" ++ "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt" ++ @ONLY ++) ++set( ++ LIBCXX_CONFIGURED_INCLUDE_DIR ++ "${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_INCLUDE_DIR}" ++) ++configure_file( ++ "CMakeLists.txt.in" ++ "${LIBCXX_GENERATED_MODULE_DIR}/install/CMakeLists.txt" ++ @ONLY ++) ++ ++set(_all_modules "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt") ++foreach(file ${LIBCXX_SOURCES_MODULE_STD} ${LIBCXX_SOURCES_MODULE_STD_COMPAT}) ++ set(src "${CMAKE_CURRENT_SOURCE_DIR}/${file}") ++ set(dst "${LIBCXX_GENERATED_MODULE_DIR}/${file}") ++ add_custom_command(OUTPUT ${dst} ++ DEPENDS ${src} ++ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} ++ COMMENT "Copying CXX module ${file}") ++ list(APPEND _all_modules "${dst}") ++endforeach() ++ ++add_custom_target(generate-cxx-modules ++ ALL DEPENDS ++ ${_all_modules} ++) ++ ++if (LIBCXX_INSTALL_MODULES) ++ foreach(file ${LIBCXX_SOURCES_MODULE_STD} ${LIBCXX_SOURCES_MODULE_STD_COMPAT}) ++ get_filename_component(dir ${file} DIRECTORY) ++ install(FILES ${file} ++ DESTINATION "${LIBCXX_INSTALL_MODULE_DIR}/${dir}" ++ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ++ ) ++ endforeach() ++ ++ # Install the generated CMake file to the generic include dir. ++ # TODO MODULES Remove this file ++ install(FILES "${LIBCXX_GENERATED_MODULE_DIR}/install/CMakeLists.txt" ++ DESTINATION "${LIBCXX_INSTALL_MODULE_DIR}" ++ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ++ ) ++endif() +diff --git a/libcxx/modules/CMakeLists.txt.in b/libcxx/modules/CMakeLists.txt.in +new file mode 100644 +index 000000000000..fcbd51652fe0 +--- /dev/null ++++ b/libcxx/modules/CMakeLists.txt.in +@@ -0,0 +1,76 @@ ++# CMake 3.25 has modules support, but that does not work properly. ++cmake_minimum_required(VERSION 3.26) ++ ++project(libc++-std LANGUAGES CXX) ++ ++# Enable CMake's module support ++set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") ++set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) ++ ++# Default to C++ extensions being off. Clang's modules support have trouble ++# with extensions right now. ++set(CMAKE_CXX_EXTENSIONS OFF) ++ ++# Propagates the CMake options to the modules. ++# ++# This uses the std module hard-coded since the std.compat module does not ++# depend on these flags. ++macro(compile_define_if_not condition def) ++ if (NOT ${condition}) ++ target_compile_definitions(std PRIVATE ${def}) ++ endif() ++endmacro() ++macro(compile_define_if condition def) ++ if (${condition}) ++ target_compile_definitions(std PRIVATE ${def}) ++ endif() ++endmacro() ++ ++if(NOT @LIBCXX_ENABLE_THREADS@ OR NOT @LIBCXXABI_ENABLE_THREADS@ OR NOT @LIBCXX_ENABLE_MONOTONIC_CLOCK@) ++ message(FATAL_ERROR "Modules without thread support is not yet implemented.") ++endif() ++if(NOT @LIBCXX_ENABLE_FILESYSTEM@) ++ message(FATAL_ERROR "Modules without filesystem support is not yet implemented.") ++endif() ++if(NOT @LIBCXX_ENABLE_RANDOM_DEVICE@) ++ message(FATAL_ERROR "Modules without randome device support is not yet implemented.") ++endif() ++if(NOT @LIBCXX_ENABLE_FSTREAM@) ++ message(FATAL_ERROR "Modules without fstream support is not yet implemented.") ++endif() ++if(NOT @LIBCXX_ENABLE_UNICODE@) ++ message(FATAL_ERROR "Modules without Unicode support is not yet implemented.") ++endif() ++if(NOT @LIBCXX_ENABLE_EXCEPTIONS@ OR NOT @LIBCXXABI_ENABLE_EXCEPTIONS@) ++ message(FATAL_ERROR "Modules without exception support is not yet implemented.") ++endif() ++ ++add_library(std) ++target_sources(std ++ PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES ++ @LIBCXX_SOURCES_MODULE_STD@ ++) ++ ++target_compile_definitions(std PRIVATE _LIBCPP_ENABLE_EXPERIMENTAL) ++target_include_directories(std SYSTEM PRIVATE @LIBCXX_CONFIGURED_INCLUDE_DIR@) ++ ++target_compile_options(std ++ PUBLIC ++ -nostdinc++ ++ @LIBCXX_COMPILE_FLAGS@ ++) ++ ++add_library(std.compat) ++target_sources(std.compat ++ PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES ++ @LIBCXX_SOURCES_MODULE_STD_COMPAT@ ++) ++target_include_directories(std.compat SYSTEM PRIVATE @LIBCXX_CONFIGURED_INCLUDE_DIR@) ++target_compile_options(std.compat ++ PUBLIC ++ -nostdinc++ ++ # HACK to find the std module ++ -fmodule-file=std=CMakeFiles/std.dir/std.pcm ++ @LIBCXX_COMPILE_FLAGS@ ++) ++target_link_libraries(std.compat PRIVATE std) +diff --git a/libcxx/modules/std.compat.cppm b/libcxx/modules/std.compat.cppm +new file mode 100644 +index 000000000000..1e58de2c3f30 +--- /dev/null ++++ b/libcxx/modules/std.compat.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++export module std.compat; ++ ++export import std; ++// The headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] ++export import :cassert; ++export import :cctype; ++export import :cerrno; ++export import :cfenv; ++export import :cfloat; ++export import :cinttypes; ++export import :climits; ++export import :clocale; ++export import :cmath; ++export import :csetjmp; ++export import :csignal; ++export import :cstdarg; ++export import :cstddef; ++export import :cstdint; ++export import :cstdio; ++export import :cstdlib; ++export import :cstring; ++export import :ctime; ++export import :cuchar; ++export import :cwchar; ++export import :cwctype; +diff --git a/libcxx/modules/std.compat/cassert.cppm b/libcxx/modules/std.compat/cassert.cppm +new file mode 100644 +index 000000000000..e5f5898a09ec +--- /dev/null ++++ b/libcxx/modules/std.compat/cassert.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cassert; ++export { ++ // This module exports nothing. ++} // export +diff --git a/libcxx/modules/std.compat/cctype.cppm b/libcxx/modules/std.compat/cctype.cppm +new file mode 100644 +index 000000000000..bd1e4c2cbcf8 +--- /dev/null ++++ b/libcxx/modules/std.compat/cctype.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cctype; ++export { ++ using ::isalnum; ++ using ::isalpha; ++ using ::isblank; ++ using ::iscntrl; ++ using ::isdigit; ++ using ::isgraph; ++ using ::islower; ++ using ::isprint; ++ using ::ispunct; ++ using ::isspace; ++ using ::isupper; ++ using ::isxdigit; ++ using ::tolower; ++ using ::toupper; ++} // export +diff --git a/libcxx/modules/std.compat/cerrno.cppm b/libcxx/modules/std.compat/cerrno.cppm +new file mode 100644 +index 000000000000..20f521d0fc95 +--- /dev/null ++++ b/libcxx/modules/std.compat/cerrno.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cerrno; ++export { ++ // This module exports nothing. ++} // export +diff --git a/libcxx/modules/std.compat/cfenv.cppm b/libcxx/modules/std.compat/cfenv.cppm +new file mode 100644 +index 000000000000..167a5be085d1 +--- /dev/null ++++ b/libcxx/modules/std.compat/cfenv.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cfenv; ++export { ++ // types ++ using ::fenv_t; ++ using ::fexcept_t; ++ ++ // functions ++ using ::feclearexcept; ++ using ::fegetexceptflag; ++ using ::feraiseexcept; ++ using ::fesetexceptflag; ++ using ::fetestexcept; ++ ++ using ::fegetround; ++ using ::fesetround; ++ ++ using ::fegetenv; ++ using ::feholdexcept; ++ using ::fesetenv; ++ using ::feupdateenv; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cfloat.cppm b/libcxx/modules/std.compat/cfloat.cppm +new file mode 100644 +index 000000000000..dbea1b387cc6 +--- /dev/null ++++ b/libcxx/modules/std.compat/cfloat.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cfloat; ++export { ++ // This module exports nothing. ++} // export +diff --git a/libcxx/modules/std.compat/cinttypes.cppm b/libcxx/modules/std.compat/cinttypes.cppm +new file mode 100644 +index 000000000000..35822fd5f48e +--- /dev/null ++++ b/libcxx/modules/std.compat/cinttypes.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cinttypes; ++export { ++ using ::imaxdiv_t; ++ ++ using ::imaxabs; ++ using ::imaxdiv; ++ using ::strtoimax; ++ using ::strtoumax; ++ using ::wcstoimax; ++ using ::wcstoumax; ++ ++ // abs is conditionally here, but always present in cmath.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ // div is conditionally here, but always present in cstdlib.cppm. To avoid ++ // conflicing declarations omit the using here. ++} // export +diff --git a/libcxx/modules/std.compat/climits.cppm b/libcxx/modules/std.compat/climits.cppm +new file mode 100644 +index 000000000000..d486541c1b26 +--- /dev/null ++++ b/libcxx/modules/std.compat/climits.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:climits; ++export { ++ // This module exports nothing. ++} // export +diff --git a/libcxx/modules/std.compat/clocale.cppm b/libcxx/modules/std.compat/clocale.cppm +new file mode 100644 +index 000000000000..5bb5825d8a94 +--- /dev/null ++++ b/libcxx/modules/std.compat/clocale.cppm +@@ -0,0 +1,26 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std.compat:clocale; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export { ++ using ::lconv; ++ ++ using ::localeconv; ++ using ::setlocale; ++ ++} // export ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std.compat/cmath.cppm b/libcxx/modules/std.compat/cmath.cppm +new file mode 100644 +index 000000000000..e54eed0547a6 +--- /dev/null ++++ b/libcxx/modules/std.compat/cmath.cppm +@@ -0,0 +1,271 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cmath; ++export { ++ using ::acos; ++ using ::acosf; ++ using ::acosl; ++ ++ using ::asin; ++ using ::asinf; ++ using ::asinl; ++ ++ using ::atan; ++ using ::atanf; ++ using ::atanl; ++ ++ using ::atan2; ++ using ::atan2f; ++ using ::atan2l; ++ ++ using ::cos; ++ using ::cosf; ++ using ::cosl; ++ ++ using ::sin; ++ using ::sinf; ++ using ::sinl; ++ ++ using ::tan; ++ using ::tanf; ++ using ::tanl; ++ ++ using ::acosh; ++ using ::acoshf; ++ using ::acoshl; ++ ++ using ::asinh; ++ using ::asinhf; ++ using ::asinhl; ++ ++ using ::atanh; ++ using ::atanhf; ++ using ::atanhl; ++ ++ using ::cosh; ++ using ::coshf; ++ using ::coshl; ++ ++ using ::sinh; ++ using ::sinhf; ++ using ::sinhl; ++ ++ using ::tanh; ++ using ::tanhf; ++ using ::tanhl; ++ ++ using ::exp; ++ using ::expf; ++ using ::expl; ++ ++ using ::exp2; ++ using ::exp2f; ++ using ::exp2l; ++ ++ using ::expm1; ++ using ::expm1f; ++ using ::expm1l; ++ ++ using ::frexp; ++ using ::frexpf; ++ using ::frexpl; ++ ++ using ::ilogb; ++ using ::ilogbf; ++ using ::ilogbl; ++ ++ using ::ldexp; ++ using ::ldexpf; ++ using ::ldexpl; ++ ++ using ::log; ++ using ::logf; ++ using ::logl; ++ ++ using ::log10; ++ using ::log10f; ++ using ::log10l; ++ ++ using ::log1p; ++ using ::log1pf; ++ using ::log1pl; ++ ++ using ::log2; ++ using ::log2f; ++ using ::log2l; ++ ++ using ::logb; ++ using ::logbf; ++ using ::logbl; ++ ++ using ::modf; ++ using ::modff; ++ using ::modfl; ++ ++ using ::scalbn; ++ using ::scalbnf; ++ using ::scalbnl; ++ ++ using ::scalbln; ++ using ::scalblnf; ++ using ::scalblnl; ++ ++ using ::cbrt; ++ using ::cbrtf; ++ using ::cbrtl; ++ ++ // [c.math.abs], absolute values ++ using ::abs; ++ ++ using ::fabs; ++ using ::fabsf; ++ using ::fabsl; ++ ++ using ::hypot; ++ using ::hypotf; ++ using ::hypotl; ++ ++ // [c.math.hypot3], three-dimensional hypotenuse ++ using ::hypot; ++ ++ using ::pow; ++ using ::powf; ++ using ::powl; ++ ++ using ::sqrt; ++ using ::sqrtf; ++ using ::sqrtl; ++ ++ using ::erf; ++ using ::erff; ++ using ::erfl; ++ ++ using ::erfc; ++ using ::erfcf; ++ using ::erfcl; ++ ++ using ::lgamma; ++ using ::lgammaf; ++ using ::lgammal; ++ ++ using ::tgamma; ++ using ::tgammaf; ++ using ::tgammal; ++ ++ using ::ceil; ++ using ::ceilf; ++ using ::ceill; ++ ++ using ::floor; ++ using ::floorf; ++ using ::floorl; ++ ++ using ::nearbyint; ++ using ::nearbyintf; ++ using ::nearbyintl; ++ ++ using ::rint; ++ using ::rintf; ++ using ::rintl; ++ ++ using ::lrint; ++ using ::lrintf; ++ using ::lrintl; ++ ++ using ::llrint; ++ using ::llrintf; ++ using ::llrintl; ++ ++ using ::round; ++ using ::roundf; ++ using ::roundl; ++ ++ using ::lround; ++ using ::lroundf; ++ using ::lroundl; ++ ++ using ::llround; ++ using ::llroundf; ++ using ::llroundl; ++ ++ using ::trunc; ++ using ::truncf; ++ using ::truncl; ++ ++ using ::fmod; ++ using ::fmodf; ++ using ::fmodl; ++ ++ using ::remainder; ++ using ::remainderf; ++ using ::remainderl; ++ ++ using ::remquo; ++ using ::remquof; ++ using ::remquol; ++ ++ using ::copysign; ++ using ::copysignf; ++ using ::copysignl; ++ ++ using ::nan; ++ using ::nanf; ++ using ::nanl; ++ ++ using ::nextafter; ++ using ::nextafterf; ++ using ::nextafterl; ++ ++ using ::nexttoward; ++ using ::nexttowardf; ++ using ::nexttowardl; ++ ++ using ::fdim; ++ using ::fdimf; ++ using ::fdiml; ++ ++ using ::fmax; ++ using ::fmaxf; ++ using ::fmaxl; ++ ++ using ::fmin; ++ using ::fminf; ++ using ::fminl; ++ ++ using ::fma; ++ using ::fmaf; ++ using ::fmal; ++ ++ // [c.math.lerp], linear interpolation ++ // [support.c.headers.other]/1 ++ // ... placed within the global namespace scope, except for the functions ++ // described in [sf.cmath], the std::lerp function overloads ([c.math.lerp]) ++ // ... ++ ++ // [c.math.fpclass], classification / comparison functions ++ using ::fpclassify; ++ using ::isfinite; ++ using ::isgreater; ++ using ::isgreaterequal; ++ using ::isinf; ++ using ::isless; ++ using ::islessequal; ++ using ::islessgreater; ++ using ::isnan; ++ using ::isnormal; ++ using ::isunordered; ++ using ::signbit; ++ ++ // [sf.cmath], mathematical special functions ++} // export +diff --git a/libcxx/modules/std.compat/csetjmp.cppm b/libcxx/modules/std.compat/csetjmp.cppm +new file mode 100644 +index 000000000000..44343bee0d90 +--- /dev/null ++++ b/libcxx/modules/std.compat/csetjmp.cppm +@@ -0,0 +1,18 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:csetjmp; ++export { ++ using ::jmp_buf; ++ using ::longjmp; ++} // export +diff --git a/libcxx/modules/std.compat/csignal.cppm b/libcxx/modules/std.compat/csignal.cppm +new file mode 100644 +index 000000000000..7418942a6125 +--- /dev/null ++++ b/libcxx/modules/std.compat/csignal.cppm +@@ -0,0 +1,23 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:csignal; ++export { ++ using ::sig_atomic_t; ++ ++ // [support.signal], signal handlers ++ using ::signal; ++ ++ using ::raise; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cstdarg.cppm b/libcxx/modules/std.compat/cstdarg.cppm +new file mode 100644 +index 000000000000..63263724e618 +--- /dev/null ++++ b/libcxx/modules/std.compat/cstdarg.cppm +@@ -0,0 +1,15 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstdarg; ++export { using ::va_list; } // export +diff --git a/libcxx/modules/std.compat/cstddef.cppm b/libcxx/modules/std.compat/cstddef.cppm +new file mode 100644 +index 000000000000..0b386c4c4fb9 +--- /dev/null ++++ b/libcxx/modules/std.compat/cstddef.cppm +@@ -0,0 +1,27 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstddef; ++export { ++ using std::max_align_t; ++ using std::nullptr_t; ++ using std::ptrdiff_t; ++ using std::size_t; ++ ++ // [support.c.headers]/1 ++ // ... placed within the global namespace scope, except for ... the ++ // declaration of std::byte ([cstddef.syn]), and the functions and ++ // function templates described in [support.types.byteops]. ... ++ ++ // [support.types.byteops], byte type operations ++} // export +diff --git a/libcxx/modules/std.compat/cstdint.cppm b/libcxx/modules/std.compat/cstdint.cppm +new file mode 100644 +index 000000000000..683d79941fbe +--- /dev/null ++++ b/libcxx/modules/std.compat/cstdint.cppm +@@ -0,0 +1,58 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstdint; ++export { ++ // validate the list against the proper C standard ++ ++ // signed ++ using ::int8_t _LIBCPP_USING_IF_EXISTS; ++ using ::int16_t _LIBCPP_USING_IF_EXISTS; ++ using ::int32_t _LIBCPP_USING_IF_EXISTS; ++ using ::int64_t _LIBCPP_USING_IF_EXISTS; ++ ++ using ::int_fast16_t; ++ using ::int_fast32_t; ++ using ::int_fast64_t; ++ using ::int_fast8_t; ++ ++ using ::int_least16_t; ++ using ::int_least32_t; ++ using ::int_least64_t; ++ using ::int_least8_t; ++ ++ using ::intmax_t; ++ ++ using ::intptr_t _LIBCPP_USING_IF_EXISTS; ++ ++ // unsigned ++ using ::uint8_t _LIBCPP_USING_IF_EXISTS; ++ using ::uint16_t _LIBCPP_USING_IF_EXISTS; ++ using ::uint32_t _LIBCPP_USING_IF_EXISTS; ++ using ::uint64_t _LIBCPP_USING_IF_EXISTS; ++ ++ using ::uint_fast16_t; ++ using ::uint_fast32_t; ++ using ::uint_fast64_t; ++ using ::uint_fast8_t; ++ ++ using ::uint_least16_t; ++ using ::uint_least32_t; ++ using ::uint_least64_t; ++ using ::uint_least8_t; ++ ++ using ::uintmax_t; ++ ++ using ::uintptr_t _LIBCPP_USING_IF_EXISTS; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cstdio.cppm b/libcxx/modules/std.compat/cstdio.cppm +new file mode 100644 +index 000000000000..c2c14b14dea6 +--- /dev/null ++++ b/libcxx/modules/std.compat/cstdio.cppm +@@ -0,0 +1,66 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstdio; ++export { ++ using ::FILE; ++ using ::fpos_t; ++ using ::size_t; ++ ++ using ::clearerr; ++ using ::fclose; ++ using ::feof; ++ using ::ferror; ++ using ::fflush; ++ using ::fgetc; ++ using ::fgetpos; ++ using ::fgets; ++ using ::fopen; ++ using ::fprintf; ++ using ::fputc; ++ using ::fputs; ++ using ::fread; ++ using ::freopen; ++ using ::fscanf; ++ using ::fseek; ++ using ::fsetpos; ++ using ::ftell; ++ using ::fwrite; ++ using ::getc; ++ using ::getchar; ++ using ::perror; ++ using ::printf; ++ using ::putc; ++ using ::putchar; ++ using ::puts; ++ using ::remove; ++ using ::rename; ++ using ::rewind; ++ using ::scanf; ++ using ::setbuf; ++ using ::setvbuf; ++ using ::snprintf; ++ using ::sprintf; ++ using ::sscanf; ++ using ::tmpfile; ++ using ::tmpnam; ++ using ::ungetc; ++ using ::vfprintf; ++ using ::vfscanf; ++ using ::vprintf; ++ using ::vscanf; ++ using ::vsnprintf; ++ using ::vsprintf; ++ using ::vsscanf; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cstdlib.cppm b/libcxx/modules/std.compat/cstdlib.cppm +new file mode 100644 +index 000000000000..3e7e1968bb26 +--- /dev/null ++++ b/libcxx/modules/std.compat/cstdlib.cppm +@@ -0,0 +1,77 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstdlib; ++export { ++ using ::div_t; ++ using ::ldiv_t; ++ using ::lldiv_t; ++ using ::size_t; ++ ++ // [support.start.term], start and termination ++ using ::_Exit; ++ using ::abort; ++ using ::at_quick_exit; ++ using ::atexit; ++ using ::exit; ++ using ::quick_exit; ++ ++ using ::getenv; ++ using ::system; ++ ++ // [c.malloc], C library memory allocation ++ using ::aligned_alloc; ++ using ::calloc; ++ using ::free; ++ using ::malloc; ++ using ::realloc; ++ ++ using ::atof; ++ using ::atoi; ++ using ::atol; ++ using ::atoll; ++ using ::strtod; ++ using ::strtof; ++ using ::strtol; ++ using ::strtold; ++ using ::strtoll; ++ using ::strtoul; ++ using ::strtoull; ++ ++ // [c.mb.wcs], multibyte / wide string and character conversion functions ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using ::mblen; ++ using ::mbstowcs; ++ using ::mbtowc; ++ using ::wcstombs; ++ using ::wctomb; ++#endif ++ // [alg.c.library], C standard library algorithms ++ using ::bsearch; ++ using ::qsort; ++ ++ // [c.math.rand], low-quality random number generation ++ using ::rand; ++ using ::srand; ++ ++ // [c.math.abs], absolute values ++ using ::abs; ++ ++ using ::labs; ++ using ::llabs; ++ ++ using ::div; ++ using ::ldiv; ++ using ::lldiv; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cstring.cppm b/libcxx/modules/std.compat/cstring.cppm +new file mode 100644 +index 000000000000..b1d559d8c31c +--- /dev/null ++++ b/libcxx/modules/std.compat/cstring.cppm +@@ -0,0 +1,41 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cstring; ++export { ++ using ::size_t; ++ ++ using ::memchr; ++ using ::memcmp; ++ using ::memcpy; ++ using ::memmove; ++ using ::memset; ++ using ::strcat; ++ using ::strchr; ++ using ::strcmp; ++ using ::strcoll; ++ using ::strcpy; ++ using ::strcspn; ++ using ::strerror; ++ using ::strlen; ++ using ::strncat; ++ using ::strncmp; ++ using ::strncpy; ++ using ::strpbrk; ++ using ::strrchr; ++ using ::strspn; ++ using ::strstr; ++ using ::strtok; ++ using ::strxfrm; ++ ++} // export +diff --git a/libcxx/modules/std.compat/ctime.cppm b/libcxx/modules/std.compat/ctime.cppm +new file mode 100644 +index 000000000000..0e31375edc53 +--- /dev/null ++++ b/libcxx/modules/std.compat/ctime.cppm +@@ -0,0 +1,34 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:ctime; ++export { ++ using ::clock_t; ++ using ::size_t; ++ using ::time_t; ++ ++ using ::timespec; ++ using ::tm; ++ ++ using ::asctime; ++ using ::clock; ++ using ::ctime; ++ using ::difftime; ++ using ::gmtime; ++ using ::localtime; ++ using ::mktime; ++ using ::strftime; ++ using ::time; ++ using ::timespec_get; ++ ++} // export +diff --git a/libcxx/modules/std.compat/cuchar.cppm b/libcxx/modules/std.compat/cuchar.cppm +new file mode 100644 +index 000000000000..f47e74037161 +--- /dev/null ++++ b/libcxx/modules/std.compat/cuchar.cppm +@@ -0,0 +1,31 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std.compat:cuchar; ++export { ++ // Note the Standard does not mark these symbols optional, but libc++'s header ++ // does. So this seems strictly not to be conforming. ++ ++ // mbstate_t is conditionally here, but always present in cwchar.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ // size_t is conditionally here, but always present in cstddef.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ using ::mbrtoc8 _LIBCPP_USING_IF_EXISTS; ++ using ::c8rtomb _LIBCPP_USING_IF_EXISTS; ++ using ::mbrtoc16 _LIBCPP_USING_IF_EXISTS; ++ using ::c16rtomb _LIBCPP_USING_IF_EXISTS; ++ using ::mbrtoc32 _LIBCPP_USING_IF_EXISTS; ++ using ::c32rtomb _LIBCPP_USING_IF_EXISTS; ++} // export +diff --git a/libcxx/modules/std.compat/cwchar.cppm b/libcxx/modules/std.compat/cwchar.cppm +new file mode 100644 +index 000000000000..a57d3ac51c1b +--- /dev/null ++++ b/libcxx/modules/std.compat/cwchar.cppm +@@ -0,0 +1,89 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++# include ++#endif ++ ++export module std.compat:cwchar; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++export { ++ using ::mbstate_t; ++ using ::size_t; ++ using ::wint_t; ++ ++ using ::tm; ++ ++ using ::btowc; ++ using ::fgetwc; ++ using ::fgetws; ++ using ::fputwc; ++ using ::fputws; ++ using ::fwide; ++ using ::fwprintf; ++ using ::fwscanf; ++ using ::getwc; ++ using ::getwchar; ++ using ::putwc; ++ using ::putwchar; ++ using ::swprintf; ++ using ::swscanf; ++ using ::ungetwc; ++ using ::vfwprintf; ++ using ::vfwscanf; ++ using ::vswprintf; ++ using ::vswscanf; ++ using ::vwprintf; ++ using ::vwscanf; ++ using ::wcscat; ++ using ::wcschr; ++ using ::wcscmp; ++ using ::wcscoll; ++ using ::wcscpy; ++ using ::wcscspn; ++ using ::wcsftime; ++ using ::wcslen; ++ using ::wcsncat; ++ using ::wcsncmp; ++ using ::wcsncpy; ++ using ::wcspbrk; ++ using ::wcsrchr; ++ using ::wcsspn; ++ using ::wcsstr; ++ using ::wcstod; ++ using ::wcstof; ++ using ::wcstok; ++ using ::wcstol; ++ using ::wcstold; ++ using ::wcstoll; ++ using ::wcstoul; ++ using ::wcstoull; ++ using ::wcsxfrm; ++ using ::wctob; ++ using ::wmemchr; ++ using ::wmemcmp; ++ using ::wmemcpy; ++ using ::wmemmove; ++ using ::wmemset; ++ using ::wprintf; ++ using ::wscanf; ++ ++ // [c.mb.wcs], multibyte / wide string and character conversion functions ++ using ::mbrlen; ++ using ::mbrtowc; ++ using ::mbsinit; ++ using ::mbsrtowcs; ++ using ::wcrtomb; ++ using ::wcsrtombs; ++ ++} // export ++#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +diff --git a/libcxx/modules/std.compat/cwctype.cppm b/libcxx/modules/std.compat/cwctype.cppm +new file mode 100644 +index 000000000000..0e92f148a0aa +--- /dev/null ++++ b/libcxx/modules/std.compat/cwctype.cppm +@@ -0,0 +1,44 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++# include ++#endif ++ ++export module std.compat:cwctype; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++export { ++ using ::wctrans_t; ++ using ::wctype_t; ++ using ::wint_t; ++ ++ using ::iswalnum; ++ using ::iswalpha; ++ using ::iswblank; ++ using ::iswcntrl; ++ using ::iswctype; ++ using ::iswdigit; ++ using ::iswgraph; ++ using ::iswlower; ++ using ::iswprint; ++ using ::iswpunct; ++ using ::iswspace; ++ using ::iswupper; ++ using ::iswxdigit; ++ using ::towctrans; ++ using ::towlower; ++ using ::towupper; ++ using ::wctrans; ++ using ::wctype; ++ ++} // export ++#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +diff --git a/libcxx/modules/std.cppm b/libcxx/modules/std.cppm +new file mode 100644 +index 000000000000..fd2104e96a6c +--- /dev/null ++++ b/libcxx/modules/std.cppm +@@ -0,0 +1,120 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++export module std; ++ ++// The headers of Table 24: C++ library headers [tab:headers.cpp] ++// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] ++export import :__new; // Note new is a keyword and not a valid identifier ++export import :algorithm; ++export import :any; ++export import :array; ++export import :atomic; ++export import :barrier; ++export import :bit; ++export import :bitset; ++export import :cassert; ++export import :cctype; ++export import :cerrno; ++export import :cfenv; ++export import :cfloat; ++export import :charconv; ++export import :chrono; ++export import :cinttypes; ++export import :climits; ++export import :clocale; ++export import :cmath; ++export import :codecvt; ++export import :compare; ++export import :complex; ++export import :concepts; ++export import :condition_variable; ++export import :coroutine; ++export import :csetjmp; ++export import :csignal; ++export import :cstdarg; ++export import :cstddef; ++export import :cstdio; ++export import :cstdlib; ++export import :cstring; ++export import :ctime; ++export import :cuchar; ++export import :cwchar; ++export import :cwctype; ++export import :deque; ++export import :exception; ++export import :execution; ++export import :expected; ++export import :filesystem; ++export import :flat_map; ++export import :flat_set; ++export import :format; ++export import :forward_list; ++export import :fstream; ++export import :functional; ++export import :future; ++export import :generator; ++export import :initializer_list; ++export import :iomanip; ++export import :ios; ++export import :iosfwd; ++export import :iostream; ++export import :istream; ++export import :iterator; ++export import :latch; ++export import :limits; ++export import :list; ++export import :locale; ++export import :map; ++export import :mdspan; ++// export import :memory; ++export import :memory_resource; ++export import :mutex; ++export import :numbers; ++export import :numeric; ++export import :optional; ++export import :ostream; ++export import :print; ++export import :queue; ++export import :random; ++export import :ranges; ++export import :ratio; ++export import :regex; ++export import :scoped_allocator; ++export import :semaphore; ++export import :set; ++export import :shared_mutex; ++export import :source_location; ++export import :span; ++export import :spanstream; ++export import :sstream; ++export import :stack; ++export import :stacktrace; ++export import :stdexcept; ++export import :stdfloat; ++export import :stop_token; ++export import :streambuf; ++export import :string; ++export import :string_view; ++export import :strstream; ++export import :syncstream; ++export import :system_error; ++export import :thread; ++export import :tuple; ++export import :type_traits; ++export import :typeindex; ++export import :typeinfo; ++export import :unordered_map; ++export import :unordered_set; ++export import :utility; ++export import :valarray; ++export import :variant; ++export import :vector; ++export import :version; +diff --git a/libcxx/modules/std/algorithm.cppm b/libcxx/modules/std/algorithm.cppm +new file mode 100644 +index 000000000000..ac2ef138a4b1 +--- /dev/null ++++ b/libcxx/modules/std/algorithm.cppm +@@ -0,0 +1,622 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:algorithm; ++export namespace std { ++ namespace ranges { ++ // [algorithms.results], algorithm result types ++ using std::ranges::in_found_result; ++ using std::ranges::in_fun_result; ++ using std::ranges::in_in_out_result; ++ using std::ranges::in_in_result; ++ using std::ranges::in_out_out_result; ++ using std::ranges::in_out_result; ++ // using std::ranges::in_value_result; NOT IMPLEMENTED YET ++ using std::ranges::min_max_result; ++ // using std::ranges::out_value_result; NOT IMPLEMENTED YET ++ } // namespace ranges ++ ++ // [alg.nonmodifying], non-modifying sequence operations ++ // [alg.all.of], all of ++ using std::all_of; ++ namespace ranges { ++ using std::ranges::all_of; ++ } ++ ++ // [alg.any.of], any of ++ using std::any_of; ++ namespace ranges { ++ using std::ranges::any_of; ++ } ++ ++ // [alg.none.of], none of ++ using std::none_of; ++ namespace ranges { ++ using std::ranges::none_of; ++ } ++ ++ // [alg.contains], contains ++#if 0 ++ namespace ranges { ++ using std::ranges::contains; ++ using std::ranges::contains_subrange; ++ } // namespace ranges ++#endif ++ ++ // [alg.foreach], for each ++ using std::for_each; ++ ++ namespace ranges { ++ using std::ranges::for_each; ++ using std::ranges::for_each_result; ++ } // namespace ranges ++ ++ using std::for_each_n; ++ ++ namespace ranges { ++ using std::ranges::for_each_n_result; ++ ++ using std::ranges::for_each_n; ++ } // namespace ranges ++ ++ // [alg.find], find ++ using std::find; ++ using std::find_if; ++ using std::find_if_not; ++ ++ namespace ranges { ++ using std::ranges::find; ++ using std::ranges::find_if; ++ using std::ranges::find_if_not; ++ } // namespace ranges ++ ++ namespace ranges { ++#if 0 ++ using std::ranges::find_last; ++ using std::ranges::find_last_if; ++ using std::ranges::find_last_if_not; ++#endif ++ } // namespace ranges ++ ++ // [alg.find.end], find end ++ using std::find_end; ++ ++ namespace ranges { ++ using std::ranges::find_end; ++ } ++ ++ // [alg.find.first.of], find first ++ using std::find_first_of; ++ ++ namespace ranges { ++ using std::ranges::find_first_of; ++ } ++ ++ // [alg.adjacent.find], adjacent find ++ using std::adjacent_find; ++ ++ namespace ranges { ++ using std::ranges::adjacent_find; ++ } ++ ++ // [alg.count], count ++ using std::count; ++ using std::count_if; ++ ++ namespace ranges { ++ using std::ranges::count; ++ using std::ranges::count_if; ++ } // namespace ranges ++ ++ // [mismatch], mismatch ++ using std::mismatch; ++ ++ namespace ranges { ++ using std::ranges::mismatch_result; ++ ++ using std::ranges::mismatch; ++ } // namespace ranges ++ ++ // [alg.equal], equal ++ using std::equal; ++ ++ namespace ranges { ++ using std::ranges::equal; ++ } ++ ++ // [alg.is.permutation], is permutation ++ using std::is_permutation; ++ ++ namespace ranges { ++ using std::ranges::is_permutation; ++ } ++ ++ // [alg.search], search ++ using std::search; ++ ++ namespace ranges { ++ using std::ranges::search; ++ } ++ ++ using std::search_n; ++ ++ namespace ranges { ++ using std::ranges::search_n; ++ } ++ ++ namespace ranges { ++#if 0 ++ // [alg.starts.with], starts with ++ using std::ranges::starts_with; ++ ++ // [alg.ends.with], ends with ++ using std::ranges::ends_with; ++ ++ // [alg.fold], fold ++ using std::ranges::fold_left; ++ using std::ranges::fold_left_first; ++ using std::ranges::fold_right; ++ using std::ranges::fold_right_last; ++ using std::ranges::fold_left_with_iter; ++ using std::ranges::fold_left_with_iter_result; ++ using std::ranges::fold_left_with_iter; ++ using std::ranges::fold_left_first_with_iter; ++ using std::ranges::fold_left_first_with_iter; ++#endif ++ } // namespace ranges ++ ++ // [alg.modifying.operations], mutating sequence operations ++ // [alg.copy], copy ++ using std::copy; ++ ++ namespace ranges { ++ using std::ranges::copy; ++ using std::ranges::copy_result; ++ } // namespace ranges ++ ++ using std::copy_n; ++ ++ namespace ranges { ++ using std::ranges::copy_n; ++ using std::ranges::copy_n_result; ++ } // namespace ranges ++ ++ using std::copy_if; ++ ++ namespace ranges { ++ using std::ranges::copy_if; ++ using std::ranges::copy_if_result; ++ } // namespace ranges ++ ++ using std::copy_backward; ++ ++ namespace ranges { ++ using std::ranges::copy_backward; ++ using std::ranges::copy_backward_result; ++ } // namespace ranges ++ ++ // [alg.move], move ++ using std::move; ++ ++ namespace ranges { ++ using std::ranges::move; ++ using std::ranges::move_result; ++ } // namespace ranges ++ ++ using std::move_backward; ++ ++ namespace ranges { ++ using std::ranges::move_backward; ++ using std::ranges::move_backward_result; ++ } // namespace ranges ++ ++ // [alg.swap], swap ++ using std::swap_ranges; ++ ++ namespace ranges { ++ using std::ranges::swap_ranges; ++ using std::ranges::swap_ranges_result; ++ } // namespace ranges ++ ++ using std::iter_swap; ++ ++ // [alg.transform], transform ++ using std::transform; ++ ++ namespace ranges { ++ using std::ranges::binary_transform_result; ++ using std::ranges::unary_transform_result; ++ ++ using std::ranges::transform; ++ ++ } // namespace ranges ++ ++ using std::replace; ++ using std::replace_if; ++ ++ namespace ranges { ++ using std::ranges::replace; ++ using std::ranges::replace_if; ++ } // namespace ranges ++ ++ using std::replace_copy; ++ using std::replace_copy_if; ++ ++ namespace ranges { ++ using std::ranges::replace_copy; ++ using std::ranges::replace_copy_if; ++ using std::ranges::replace_copy_if_result; ++ using std::ranges::replace_copy_result; ++ } // namespace ranges ++ ++ // [alg.fill], fill ++ using std::fill; ++ using std::fill_n; ++ ++ namespace ranges { ++ using std::ranges::fill; ++ using std::ranges::fill_n; ++ } // namespace ranges ++ ++ // [alg.generate], generate ++ using std::generate; ++ using std::generate_n; ++ ++ namespace ranges { ++ using std::ranges::generate; ++ using std::ranges::generate_n; ++ } // namespace ranges ++ ++ // [alg.remove], remove ++ using std::remove; ++ using std::remove_if; ++ ++ namespace ranges { ++ using std::ranges::remove; ++ using std::ranges::remove_if; ++ } // namespace ranges ++ ++ using std::remove_copy; ++ using std::remove_copy_if; ++ namespace ranges { ++ using std::ranges::remove_copy; ++ using std::ranges::remove_copy_if; ++ using std::ranges::remove_copy_if_result; ++ using std::ranges::remove_copy_result; ++ } // namespace ranges ++ ++ // [alg.unique], unique ++ using std::unique; ++ ++ namespace ranges { ++ using std::ranges::unique; ++ } ++ ++ using std::unique_copy; ++ ++ namespace ranges { ++ using std::ranges::unique_copy; ++ using std::ranges::unique_copy_result; ++ } // namespace ranges ++ ++ // [alg.reverse], reverse ++ using std::reverse; ++ ++ namespace ranges { ++ using std::ranges::reverse; ++ } ++ ++ using std::reverse_copy; ++ ++ namespace ranges { ++ using std::ranges::reverse_copy; ++ using std::ranges::reverse_copy_result; ++ } // namespace ranges ++ ++ // [alg.rotate], rotate ++ using std::rotate; ++ ++ namespace ranges { ++ using std::ranges::rotate; ++ } ++ ++ using std::rotate_copy; ++ ++ namespace ranges { ++ using std::ranges::rotate_copy; ++ using std::ranges::rotate_copy_result; ++ } // namespace ranges ++ ++ // [alg.random.sample], sample ++ using std::sample; ++ ++ namespace ranges { ++ using std::ranges::sample; ++ } ++ ++ // [alg.random.shuffle], shuffle ++ using std::shuffle; ++ ++ namespace ranges { ++ using std::ranges::shuffle; ++ } ++ ++ // [alg.shift], shift ++ using std::shift_left; ++ ++ namespace ranges { ++ // using std::ranges::shift_left; NOT IMPLEMENTED YET ++ } ++ ++ using std::shift_right; ++ ++ namespace ranges { ++ // using std::ranges::shift_right; NOT IMPLEMENTED YET ++ } ++ ++ // [alg.sorting], sorting and related operations ++ // [alg.sort], sorting ++ using std::sort; ++ ++ namespace ranges { ++ using std::ranges::sort; ++ } ++ ++ using std::stable_sort; ++ ++ namespace ranges { ++ using std::ranges::stable_sort; ++ } ++ ++ using std::partial_sort; ++ ++ namespace ranges { ++ using std::ranges::partial_sort; ++ } ++ using std::partial_sort_copy; ++ ++ namespace ranges { ++ using std::ranges::partial_sort_copy; ++ using std::ranges::partial_sort_copy_result; ++ } // namespace ranges ++ ++ using std::is_sorted; ++ using std::is_sorted_until; ++ ++ namespace ranges { ++ using std::ranges::is_sorted; ++ using std::ranges::is_sorted_until; ++ } // namespace ranges ++ ++ // [alg.nth.element], Nth element ++ using std::nth_element; ++ ++ namespace ranges { ++ using std::ranges::nth_element; ++ } ++ ++ // [alg.binary.search], binary search ++ using std::lower_bound; ++ ++ namespace ranges { ++ using std::ranges::lower_bound; ++ } ++ ++ using std::upper_bound; ++ ++ namespace ranges { ++ using std::ranges::upper_bound; ++ } ++ ++ using std::equal_range; ++ ++ namespace ranges { ++ using std::ranges::equal_range; ++ } ++ ++ using std::binary_search; ++ ++ namespace ranges { ++ using std::ranges::binary_search; ++ } ++ ++ // [alg.partitions], partitions ++ using std::is_partitioned; ++ ++ namespace ranges { ++ using std::ranges::is_partitioned; ++ } ++ ++ using std::partition; ++ ++ namespace ranges { ++ using std::ranges::partition; ++ } ++ ++ using std::stable_partition; ++ ++ namespace ranges { ++ using std::ranges::stable_partition; ++ } ++ ++ using std::partition_copy; ++ ++ namespace ranges { ++ using std::ranges::partition_copy; ++ using std::ranges::partition_copy_result; ++ } // namespace ranges ++ ++ using std::partition_point; ++ ++ namespace ranges { ++ using std::ranges::partition_point; ++ } ++ // [alg.merge], merge ++ using std::merge; ++ namespace ranges { ++ using std::ranges::merge; ++ using std::ranges::merge_result; ++ } // namespace ranges ++ ++ using std::inplace_merge; ++ ++ namespace ranges { ++ using std::ranges::inplace_merge; ++ } ++ ++ // [alg.set.operations], set operations ++ using std::includes; ++ namespace ranges { ++ using std::ranges::includes; ++ } ++ ++ using std::set_union; ++ ++ namespace ranges { ++ using std::ranges::set_union; ++ using std::ranges::set_union_result; ++ } // namespace ranges ++ ++ using std::set_intersection; ++ namespace ranges { ++ using std::ranges::set_intersection; ++ using std::ranges::set_intersection_result; ++ } // namespace ranges ++ ++ using std::set_difference; ++ ++ namespace ranges { ++ using std::ranges::set_difference; ++ using std::ranges::set_difference_result; ++ } // namespace ranges ++ ++ using std::set_symmetric_difference; ++ ++ namespace ranges { ++ using std::ranges::set_symmetric_difference_result; ++ ++ using std::ranges::set_symmetric_difference; ++ } // namespace ranges ++ ++ // [alg.heap.operations], heap operations ++ using std::push_heap; ++ ++ namespace ranges { ++ using std::ranges::push_heap; ++ } ++ ++ using std::pop_heap; ++ ++ namespace ranges { ++ using std::ranges::pop_heap; ++ } ++ ++ using std::make_heap; ++ ++ namespace ranges { ++ using std::ranges::make_heap; ++ } ++ ++ using std::sort_heap; ++ ++ namespace ranges { ++ using std::ranges::sort_heap; ++ } ++ ++ using std::is_heap; ++ ++ namespace ranges { ++ using std::ranges::is_heap; ++ } ++ ++ using std::is_heap_until; ++ ++ namespace ranges { ++ using std::ranges::is_heap_until; ++ } ++ ++ // [alg.min.max], minimum and maximum ++ using std::min; ++ ++ namespace ranges { ++ using std::ranges::min; ++ } ++ ++ using std::max; ++ ++ namespace ranges { ++ using std::ranges::max; ++ } ++ ++ using std::minmax; ++ ++ namespace ranges { ++ using std::ranges::minmax_result; ++ ++ using std::ranges::minmax; ++ } // namespace ranges ++ ++ using std::min_element; ++ ++ namespace ranges { ++ using std::ranges::min_element; ++ } ++ ++ using std::max_element; ++ ++ namespace ranges { ++ using std::ranges::max_element; ++ } ++ ++ using std::minmax_element; ++ ++ namespace ranges { ++ using std::ranges::minmax_element_result; ++ ++ using std::ranges::minmax_element; ++ } // namespace ranges ++ // [alg.clamp], bounded value ++ using std::clamp; ++ ++ namespace ranges { ++ using std::ranges::clamp; ++ } ++ ++ // [alg.lex.comparison], lexicographical comparison ++ using std::lexicographical_compare; ++ ++ namespace ranges { ++ using std::ranges::lexicographical_compare; ++ } ++ ++ // [alg.three.way], three-way comparison algorithms ++ using std::lexicographical_compare_three_way; ++ ++ // [alg.permutation.generators], permutations ++ using std::next_permutation; ++ ++ namespace ranges { ++ using std::ranges::next_permutation_result; ++ ++ using std::ranges::next_permutation; ++ } // namespace ranges ++ ++ using std::prev_permutation; ++ ++ namespace ranges { ++ using std::ranges::prev_permutation_result; ++ ++ using std::ranges::prev_permutation; ++ } // namespace ranges ++ ++} // namespace std +diff --git a/libcxx/modules/std/any.cppm b/libcxx/modules/std/any.cppm +new file mode 100644 +index 000000000000..ed5a7f3640b3 +--- /dev/null ++++ b/libcxx/modules/std/any.cppm +@@ -0,0 +1,28 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:any; ++export namespace std { ++ ++ // [any.bad.any.cast], class bad_any_cast ++ using std::bad_any_cast; ++ ++ // [any.class], class any ++ using std::any; ++ ++ // [any.nonmembers], non-member functions ++ using std::any_cast; ++ using std::make_any; ++ using std::swap; ++ ++} // namespace std +diff --git a/libcxx/modules/std/array.cppm b/libcxx/modules/std/array.cppm +new file mode 100644 +index 000000000000..4d4a714739bc +--- /dev/null ++++ b/libcxx/modules/std/array.cppm +@@ -0,0 +1,34 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:array; ++export namespace std { ++ ++ // [array], class template array ++ using std::array; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ // [array.special], specialized algorithms ++ using std::swap; ++ ++ // [array.creation], array creation functions ++ using std::to_array; ++ ++ // [array.tuple], tuple interface ++ using std::get; ++ using std::tuple_element; ++ using std::tuple_size; ++ ++} // namespace std +diff --git a/libcxx/modules/std/atomic.cppm b/libcxx/modules/std/atomic.cppm +new file mode 100644 +index 000000000000..23e122c4ab22 +--- /dev/null ++++ b/libcxx/modules/std/atomic.cppm +@@ -0,0 +1,147 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:atomic; ++export namespace std { ++ ++ // [atomics.order], order and consistency ++ using std::memory_order; ++ using std::memory_order_acq_rel; ++ using std::memory_order_acquire; ++ using std::memory_order_consume; ++ using std::memory_order_relaxed; ++ using std::memory_order_release; ++ using std::memory_order_seq_cst; ++ ++ using std::kill_dependency; ++} // namespace std ++ ++namespace std { ++ ++ // [atomics.ref.generic], class template atomic_ref ++ // [atomics.ref.pointer], partial specialization for pointers ++ // using std::atomic_ref; ++ ++ // [atomics.types.generic], class template atomic ++ using std::atomic; ++ ++ // [atomics.nonmembers], non-member functions ++ using std::atomic_compare_exchange_strong; ++ using std::atomic_compare_exchange_strong_explicit; ++ using std::atomic_compare_exchange_weak; ++ using std::atomic_compare_exchange_weak_explicit; ++ using std::atomic_exchange; ++ using std::atomic_exchange_explicit; ++ using std::atomic_is_lock_free; ++ using std::atomic_load; ++ using std::atomic_load_explicit; ++ using std::atomic_store; ++ using std::atomic_store_explicit; ++ ++ using std::atomic_fetch_add; ++ using std::atomic_fetch_add_explicit; ++ using std::atomic_fetch_and; ++ using std::atomic_fetch_and_explicit; ++ using std::atomic_fetch_or; ++ using std::atomic_fetch_or_explicit; ++ using std::atomic_fetch_sub; ++ using std::atomic_fetch_sub_explicit; ++ using std::atomic_fetch_xor; ++ using std::atomic_fetch_xor_explicit; ++ using std::atomic_notify_all; ++ using std::atomic_notify_one; ++ using std::atomic_wait; ++ using std::atomic_wait_explicit; ++ ++ // [atomics.alias], type aliases ++ using std::atomic_bool; ++ using std::atomic_char; ++ using std::atomic_char16_t; ++ using std::atomic_char32_t; ++ using std::atomic_char8_t; ++ using std::atomic_int; ++ using std::atomic_llong; ++ using std::atomic_long; ++ using std::atomic_schar; ++ using std::atomic_short; ++ using std::atomic_uchar; ++ using std::atomic_uint; ++ using std::atomic_ullong; ++ using std::atomic_ulong; ++ using std::atomic_ushort; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::atomic_wchar_t; ++#endif ++ ++ using std::atomic_int16_t; ++ using std::atomic_int32_t; ++ using std::atomic_int64_t; ++ using std::atomic_int8_t; ++ using std::atomic_uint16_t; ++ using std::atomic_uint32_t; ++ using std::atomic_uint64_t; ++ using std::atomic_uint8_t; ++ ++ using std::atomic_int_least16_t; ++ using std::atomic_int_least32_t; ++ using std::atomic_int_least64_t; ++ using std::atomic_int_least8_t; ++ using std::atomic_uint_least16_t; ++ using std::atomic_uint_least32_t; ++ using std::atomic_uint_least64_t; ++ using std::atomic_uint_least8_t; ++ ++ using std::atomic_int_fast16_t; ++ using std::atomic_int_fast32_t; ++ using std::atomic_int_fast64_t; ++ using std::atomic_int_fast8_t; ++ using std::atomic_uint_fast16_t; ++ using std::atomic_uint_fast32_t; ++ using std::atomic_uint_fast64_t; ++ using std::atomic_uint_fast8_t; ++ ++ using std::atomic_intmax_t; ++ using std::atomic_intptr_t; ++ using std::atomic_ptrdiff_t; ++ using std::atomic_size_t; ++ using std::atomic_uintmax_t; ++ using std::atomic_uintptr_t; ++ ++ using std::atomic_signed_lock_free; ++ using std::atomic_unsigned_lock_free; ++ ++ // [atomics.flag], flag type and operations ++ using std::atomic_flag; ++ ++ using std::atomic_flag_clear; ++ using std::atomic_flag_clear_explicit; ++ using std::atomic_flag_test; ++ using std::atomic_flag_test_and_set; ++ using std::atomic_flag_test_and_set_explicit; ++ using std::atomic_flag_test_explicit; ++ ++ using std::atomic_flag_notify_all; ++ using std::atomic_flag_notify_one; ++ using std::atomic_flag_wait; ++ using std::atomic_flag_wait_explicit; ++ ++ // [atomics.fences], fences ++ // extern "C" { TODO investigate how to export ++ using std::atomic_signal_fence; ++ using std::atomic_thread_fence; ++ // } ++ ++ // [depr.atomics.nonmembers] ++ using std::atomic_init; ++ ++} // namespace std +diff --git a/libcxx/modules/std/barrier.cppm b/libcxx/modules/std/barrier.cppm +new file mode 100644 +index 000000000000..86cf095f3bfa +--- /dev/null ++++ b/libcxx/modules/std/barrier.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:barrier; ++export namespace std { ++ using std::barrier; ++} // namespace std +diff --git a/libcxx/modules/std/bit.cppm b/libcxx/modules/std/bit.cppm +new file mode 100644 +index 000000000000..fcd1075fba99 +--- /dev/null ++++ b/libcxx/modules/std/bit.cppm +@@ -0,0 +1,41 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:bit; ++export namespace std { ++ // [bit.cast], bit_cast ++ using std::bit_cast; ++ ++ // [bit.byteswap], byteswap ++ using std::byteswap; ++ ++ // [bit.pow.two], using std:: of 2 ++ using std::bit_ceil; ++ using std::bit_floor; ++ using std::bit_width; ++ using std::has_single_bit; ++ ++ // [bit.rotate], rotating ++ using std::rotl; ++ using std::rotr; ++ ++ // [bit.count], counting ++ using std::countl_one; ++ using std::countl_zero; ++ using std::countr_one; ++ using std::countr_zero; ++ using std::popcount; ++ ++ // [bit.endian], endian ++ using std::endian; ++} // namespace std +diff --git a/libcxx/modules/std/bitset.cppm b/libcxx/modules/std/bitset.cppm +new file mode 100644 +index 000000000000..c48ce46b540c +--- /dev/null ++++ b/libcxx/modules/std/bitset.cppm +@@ -0,0 +1,28 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:bitset; ++export namespace std { ++ using std::bitset; ++ ++ // [bitset.operators], bitset operators ++ using std::operator&; ++ using std::operator|; ++ using std::operator^; ++ using std::operator>>; ++ using std::operator<<; ++ ++ // [bitset.hash], hash support ++ using std::hash; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cassert.cppm b/libcxx/modules/std/cassert.cppm +new file mode 100644 +index 000000000000..2c3f58129818 +--- /dev/null ++++ b/libcxx/modules/std/cassert.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cassert; ++export namespace std { ++ // This module exports nothing. ++} // namespace std +diff --git a/libcxx/modules/std/cctype.cppm b/libcxx/modules/std/cctype.cppm +new file mode 100644 +index 000000000000..e7ae4bc4b658 +--- /dev/null ++++ b/libcxx/modules/std/cctype.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cctype; ++export namespace std { ++ using std::isalnum; ++ using std::isalpha; ++ using std::isblank; ++ using std::iscntrl; ++ using std::isdigit; ++ using std::isgraph; ++ using std::islower; ++ using std::isprint; ++ using std::ispunct; ++ using std::isspace; ++ using std::isupper; ++ using std::isxdigit; ++ using std::tolower; ++ using std::toupper; ++} // namespace std +diff --git a/libcxx/modules/std/cerrno.cppm b/libcxx/modules/std/cerrno.cppm +new file mode 100644 +index 000000000000..21c2d0da9b00 +--- /dev/null ++++ b/libcxx/modules/std/cerrno.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cerrno; ++export namespace std { ++ // This module exports nothing. ++} // namespace std +diff --git a/libcxx/modules/std/cfenv.cppm b/libcxx/modules/std/cfenv.cppm +new file mode 100644 +index 000000000000..bb25ea66bfc7 +--- /dev/null ++++ b/libcxx/modules/std/cfenv.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cfenv; ++export namespace std { ++ // types ++ using std::fenv_t; ++ using std::fexcept_t; ++ ++ // functions ++ using std::feclearexcept; ++ using std::fegetexceptflag; ++ using std::feraiseexcept; ++ using std::fesetexceptflag; ++ using std::fetestexcept; ++ ++ using std::fegetround; ++ using std::fesetround; ++ ++ using std::fegetenv; ++ using std::feholdexcept; ++ using std::fesetenv; ++ using std::feupdateenv; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cfloat.cppm b/libcxx/modules/std/cfloat.cppm +new file mode 100644 +index 000000000000..64ab89a16870 +--- /dev/null ++++ b/libcxx/modules/std/cfloat.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cfloat; ++export namespace std { ++ // This module exports nothing. ++} // namespace std +diff --git a/libcxx/modules/std/charconv.cppm b/libcxx/modules/std/charconv.cppm +new file mode 100644 +index 000000000000..54704f00870b +--- /dev/null ++++ b/libcxx/modules/std/charconv.cppm +@@ -0,0 +1,39 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:charconv; ++export namespace std { ++ ++ // floating-point format for primitive numerical conversion ++ using std::chars_format; ++ ++ // chars_format is a bitmask type. ++ // [bitmask.types] specified operators ++ using std::operator&; ++ using std::operator&=; ++ using std::operator^; ++ using std::operator^=; ++ using std::operator|; ++ using std::operator|=; ++ using std::operator~; ++ ++ // [charconv.to.chars], primitive numerical output conversion ++ using std::to_chars_result; ++ ++ using std::to_chars; ++ ++ // [charconv.from.chars], primitive numerical input conversion ++ using std::from_chars_result; ++ ++ using std::from_chars; ++} // namespace std +diff --git a/libcxx/modules/std/chrono.cppm b/libcxx/modules/std/chrono.cppm +new file mode 100644 +index 000000000000..cddd7449c182 +--- /dev/null ++++ b/libcxx/modules/std/chrono.cppm +@@ -0,0 +1,291 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:chrono; ++export namespace std { ++ ++ namespace chrono { ++ using std::chrono::duration; ++ using std::chrono::time_point; ++ ++ } // namespace chrono ++ ++ using std::common_type; ++ ++ namespace chrono { ++ ++ // [time.traits], customization traits ++ using std::chrono::treat_as_floating_point; ++ using std::chrono::treat_as_floating_point_v; ++ ++ using std::chrono::duration_values; ++ ++ // using std::chrono::is_clock; NOT IMPLEMENTEDYET ++ // using std::chrono::is_clock_v; NOT IMPLEMENTEDYET ++ ++ // [time.duration.nonmember], duration arithmetic ++ using std::chrono::operator+; ++ using std::chrono::operator-; ++ using std::chrono::operator*; ++ using std::chrono::operator/; ++ using std::chrono::operator%; ++ ++ // [time.duration.comparisons], duration comparisons ++ using std::chrono::operator==; ++ using std::chrono::operator!=; ++ using std::chrono::operator<; ++ using std::chrono::operator>; ++ using std::chrono::operator<=; ++ using std::chrono::operator>=; ++ using std::chrono::operator<=>; ++ ++ // [time.duration.cast], conversions ++ using std::chrono::ceil; ++ using std::chrono::duration_cast; ++ using std::chrono::floor; ++ using std::chrono::round; ++ ++ // [time.duration.io], duration I/O ++#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) ++ using std::chrono::operator<<; ++#endif ++ // using std::chrono::from_stream; NOT IMPLEMENTEDYET ++ ++ // convenience typedefs ++ using std::chrono::days; ++ using std::chrono::hours; ++ using std::chrono::microseconds; ++ using std::chrono::milliseconds; ++ using std::chrono::minutes; ++ using std::chrono::months; ++ using std::chrono::nanoseconds; ++ using std::chrono::seconds; ++ using std::chrono::weeks; ++ using std::chrono::years; ++ ++ // [time.point.nonmember], time_point arithmetic ++ ++ // [time.point.comparisons], time_point comparisons ++ ++ // [time.point.cast], conversions ++ using std::chrono::time_point_cast; ++ ++ // [time.duration.alg], specialized algorithms ++ using std::chrono::abs; ++ ++ // [time.clock.system], class system_clock ++ using std::chrono::system_clock; ++ ++ using std::chrono::sys_days; ++ using std::chrono::sys_seconds; ++ using std::chrono::sys_time; ++ ++#if 0 ++ // [time.clock.utc], class utc_clock ++ using std::chrono::utc_clock; ++ ++ using std::chrono::utc_seconds; ++ using std::chrono::utc_time; ++ ++ using std::chrono::leap_second_info; ++ ++ using std::chrono::get_leap_second_info; ++ // [time.clock.tai], class tai_clock ++ using std::chrono::tai_clock; ++ ++ using std::chrono::tai_seconds; ++ using std::chrono::tai_time; ++ ++ // [time.clock.gps], class gps_clock ++ using std::chrono::gps_clock; ++ ++ using std::chrono::gps_seconds; ++ using std::chrono::gps_time; ++#endif ++ // [time.clock.file], type file_clock ++ using std::chrono::file_clock; ++ ++ using std::chrono::file_time; ++ ++ // [time.clock.steady], class steady_clock ++ using std::chrono::steady_clock; ++ ++ // [time.clock.hires], class high_resolution_clock ++ using std::chrono::high_resolution_clock; ++ ++ // [time.clock.local], local time ++ using std::chrono::local_days; ++ using std::chrono::local_seconds; ++ using std::chrono::local_t; ++ using std::chrono::local_time; ++ ++ // [time.clock.cast], time_point conversions ++ // using std::chrono::clock_time_conversion; NOT IMPLEMENTED YET ++ ++ // using std::chrono::clock_cast; NOT IMPLEMENTED YET ++ ++ // [time.cal.last], class last_spec ++ using std::chrono::last_spec; ++ ++ // [time.cal.day], class day ++ using std::chrono::day; ++ ++ // [time.cal.month], class month ++ using std::chrono::month; ++ ++ // [time.cal.year], class year ++ using std::chrono::year; ++ ++ // [time.cal.wd], class weekday ++ using std::chrono::weekday; ++ ++ // [time.cal.wdidx], class weekday_indexed ++ using std::chrono::weekday_indexed; ++ ++ // [time.cal.wdlast], class weekday_last ++ using std::chrono::weekday_last; ++ ++ // [time.cal.md], class month_day ++ using std::chrono::month_day; ++ ++ // [time.cal.mdlast], class month_day_last ++ using std::chrono::month_day_last; ++ ++ // [time.cal.mwd], class month_weekday ++ using std::chrono::month_weekday; ++ ++ // [time.cal.mwdlast], class month_weekday_last ++ using std::chrono::month_weekday_last; ++ ++ // [time.cal.ym], class year_month ++ using std::chrono::year_month; ++ ++ // [time.cal.ymd], class year_month_day ++ using std::chrono::year_month_day; ++ ++ // [time.cal.ymdlast], class year_month_day_last ++ using std::chrono::year_month_day_last; ++ ++ // [time.cal.ymwd], class year_month_weekday ++ using std::chrono::year_month_weekday; ++ ++ // [time.cal.ymwdlast], class year_month_weekday_last ++ using std::chrono::year_month_weekday_last; ++ ++ // [time.cal.operators], civil calendar conventional syntax operators ++ ++ // [time.hms], class template hh_mm_ss ++ using std::chrono::hh_mm_ss; ++ ++ // [time.12], 12/24 hour functions ++ using std::chrono::is_am; ++ using std::chrono::is_pm; ++ using std::chrono::make12; ++ using std::chrono::make24; ++ ++#if 0 ++ // [time.zone.db], time zone database ++ using std::chrono::tzdb; ++ using std::chrono::tzdb_list; ++ ++ // [time.zone.db.access], time zone database access ++ using std::chrono::current_zone; ++ using std::chrono::get_tzdb; ++ using std::chrono::get_tzdb_list; ++ using std::chrono::locate_zone; ++ ++ // [time.zone.db.remote], remote time zone database support ++ using std::chrono::reload_tzdb; ++ using std::chrono::remote_version; ++ ++ // [time.zone.exception], exception classes ++ using std::chrono::ambiguous_local_time; ++ using std::chrono::nonexistent_local_time; ++ ++ // [time.zone.info], information classes ++ using std::chrono::sys_info; ++ ++ // [time.zone.timezone], class time_zone ++ using std::chrono::choose; ++ using std::chrono::time_zone; ++ ++ // [time.zone.zonedtraits], class template zoned_traits ++ using std::chrono::zoned_traits; ++ ++ // [time.zone.zonedtime], class template zoned_time ++ using std::chrono::zoned_time; ++ ++ using std::chrono::zoned_seconds; ++ ++ // [time.zone.leap], leap second support ++ using std::chrono::leap_second; ++ ++ // [time.zone.link], class time_zone_link ++ using std::chrono::time_zone_link; ++ ++ // [time.format], formatting ++ using std::chrono::local_time_format; ++#endif ++ } // namespace chrono ++ ++ using std::formatter; ++ ++ namespace chrono { ++ // using std::chrono::parse;NOT IMPLEMENTED YET ++ ++ // calendrical constants ++ using std::chrono::last; ++ ++ using std::chrono::Friday; ++ using std::chrono::Monday; ++ using std::chrono::Saturday; ++ using std::chrono::Sunday; ++ using std::chrono::Thursday; ++ using std::chrono::Tuesday; ++ using std::chrono::Wednesday; ++ ++ using std::chrono::April; ++ using std::chrono::August; ++ using std::chrono::December; ++ using std::chrono::February; ++ using std::chrono::January; ++ using std::chrono::July; ++ using std::chrono::June; ++ using std::chrono::March; ++ using std::chrono::May; ++ using std::chrono::November; ++ using std::chrono::October; ++ using std::chrono::September; ++ ++ } // namespace chrono ++ ++} // namespace std ++export namespace std::inline literals::inline chrono_literals { ++ // [time.duration.literals], suffixes for duration literals ++ using std::literals::chrono_literals::operator""h; ++ using std::literals::chrono_literals::operator""min; ++ using std::literals::chrono_literals::operator""s; ++ using std::literals::chrono_literals::operator""ms; ++ using std::literals::chrono_literals::operator""us; ++ using std::literals::chrono_literals::operator""ns; ++ ++ // [using std::literals::chrono_literals::.cal.day.nonmembers], non-member functions ++ using std::literals::chrono_literals::operator""d; ++ ++ // [using std::literals::chrono_literals::.cal.year.nonmembers], non-member functions ++ using std::literals::chrono_literals::operator""y; ++} // namespace std::inline literals::inline chrono_literals ++ ++export namespace std::chrono { ++ using namespace literals::chrono_literals; ++} +diff --git a/libcxx/modules/std/cinttypes.cppm b/libcxx/modules/std/cinttypes.cppm +new file mode 100644 +index 000000000000..21e75df97b70 +--- /dev/null ++++ b/libcxx/modules/std/cinttypes.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cinttypes; ++export namespace std { ++ using std::imaxdiv_t; ++ ++ using std::imaxabs; ++ using std::imaxdiv; ++ using std::strtoimax; ++ using std::strtoumax; ++ using std::wcstoimax; ++ using std::wcstoumax; ++ ++ // abs is conditionally here, but always present in cmath.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ // div is conditionally here, but always present in cstdlib.cppm. To avoid ++ // conflicing declarations omit the using here. ++} // namespace std +diff --git a/libcxx/modules/std/climits.cppm b/libcxx/modules/std/climits.cppm +new file mode 100644 +index 000000000000..78cbc87f1620 +--- /dev/null ++++ b/libcxx/modules/std/climits.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:climits; ++export namespace std { ++ // This module exports nothing. ++} // namespace std +diff --git a/libcxx/modules/std/clocale.cppm b/libcxx/modules/std/clocale.cppm +new file mode 100644 +index 000000000000..83cd4f439051 +--- /dev/null ++++ b/libcxx/modules/std/clocale.cppm +@@ -0,0 +1,26 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:clocale; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ using std::lconv; ++ ++ using std::localeconv; ++ using std::setlocale; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/cmath.cppm b/libcxx/modules/std/cmath.cppm +new file mode 100644 +index 000000000000..6f6c34c747fd +--- /dev/null ++++ b/libcxx/modules/std/cmath.cppm +@@ -0,0 +1,380 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cmath; ++export namespace std { ++ ++ using std::double_t; ++ using std::float_t; ++ ++ using std::acos; ++ using std::acosf; ++ using std::acosl; ++ ++ using std::asin; ++ using std::asinf; ++ using std::asinl; ++ ++ using std::atan; ++ using std::atanf; ++ using std::atanl; ++ ++ using std::atan2; ++ using std::atan2f; ++ using std::atan2l; ++ ++ using std::cos; ++ using std::cosf; ++ using std::cosl; ++ ++ using std::sin; ++ using std::sinf; ++ using std::sinl; ++ ++ using std::tan; ++ using std::tanf; ++ using std::tanl; ++ ++ using std::acosh; ++ using std::acoshf; ++ using std::acoshl; ++ ++ using std::asinh; ++ using std::asinhf; ++ using std::asinhl; ++ ++ using std::atanh; ++ using std::atanhf; ++ using std::atanhl; ++ ++ using std::cosh; ++ using std::coshf; ++ using std::coshl; ++ ++ using std::sinh; ++ using std::sinhf; ++ using std::sinhl; ++ ++ using std::tanh; ++ using std::tanhf; ++ using std::tanhl; ++ ++ using std::exp; ++ using std::expf; ++ using std::expl; ++ ++ using std::exp2; ++ using std::exp2f; ++ using std::exp2l; ++ ++ using std::expm1; ++ using std::expm1f; ++ using std::expm1l; ++ ++ using std::frexp; ++ using std::frexpf; ++ using std::frexpl; ++ ++ using std::ilogb; ++ using std::ilogbf; ++ using std::ilogbl; ++ ++ using std::ldexp; ++ using std::ldexpf; ++ using std::ldexpl; ++ ++ using std::log; ++ using std::logf; ++ using std::logl; ++ ++ using std::log10; ++ using std::log10f; ++ using std::log10l; ++ ++ using std::log1p; ++ using std::log1pf; ++ using std::log1pl; ++ ++ using std::log2; ++ using std::log2f; ++ using std::log2l; ++ ++ using std::logb; ++ using std::logbf; ++ using std::logbl; ++ ++ using std::modf; ++ using std::modff; ++ using std::modfl; ++ ++ using std::scalbn; ++ using std::scalbnf; ++ using std::scalbnl; ++ ++ using std::scalbln; ++ using std::scalblnf; ++ using std::scalblnl; ++ ++ using std::cbrt; ++ using std::cbrtf; ++ using std::cbrtl; ++ ++ // [c.math.abs], absolute values ++ using std::abs; ++ ++ using std::fabs; ++ using std::fabsf; ++ using std::fabsl; ++ ++ using std::hypot; ++ using std::hypotf; ++ using std::hypotl; ++ ++ // [c.math.hypot3], three-dimensional hypotenuse ++ using std::hypot; ++ ++ using std::pow; ++ using std::powf; ++ using std::powl; ++ ++ using std::sqrt; ++ using std::sqrtf; ++ using std::sqrtl; ++ ++ using std::erf; ++ using std::erff; ++ using std::erfl; ++ ++ using std::erfc; ++ using std::erfcf; ++ using std::erfcl; ++ ++ using std::lgamma; ++ using std::lgammaf; ++ using std::lgammal; ++ ++ using std::tgamma; ++ using std::tgammaf; ++ using std::tgammal; ++ ++ using std::ceil; ++ using std::ceilf; ++ using std::ceill; ++ ++ using std::floor; ++ using std::floorf; ++ using std::floorl; ++ ++ using std::nearbyint; ++ using std::nearbyintf; ++ using std::nearbyintl; ++ ++ using std::rint; ++ using std::rintf; ++ using std::rintl; ++ ++ using std::lrint; ++ using std::lrintf; ++ using std::lrintl; ++ ++ using std::llrint; ++ using std::llrintf; ++ using std::llrintl; ++ ++ using std::round; ++ using std::roundf; ++ using std::roundl; ++ ++ using std::lround; ++ using std::lroundf; ++ using std::lroundl; ++ ++ using std::llround; ++ using std::llroundf; ++ using std::llroundl; ++ ++ using std::trunc; ++ using std::truncf; ++ using std::truncl; ++ ++ using std::fmod; ++ using std::fmodf; ++ using std::fmodl; ++ ++ using std::remainder; ++ using std::remainderf; ++ using std::remainderl; ++ ++ using std::remquo; ++ using std::remquof; ++ using std::remquol; ++ ++ using std::copysign; ++ using std::copysignf; ++ using std::copysignl; ++ ++ using std::nan; ++ using std::nanf; ++ using std::nanl; ++ ++ using std::nextafter; ++ using std::nextafterf; ++ using std::nextafterl; ++ ++ using std::nexttoward; ++ using std::nexttowardf; ++ using std::nexttowardl; ++ ++ using std::fdim; ++ using std::fdimf; ++ using std::fdiml; ++ ++ using std::fmax; ++ using std::fmaxf; ++ using std::fmaxl; ++ ++ using std::fmin; ++ using std::fminf; ++ using std::fminl; ++ ++ using std::fma; ++ using std::fmaf; ++ using std::fmal; ++ ++ // [c.math.lerp], linear interpolation ++ using std::lerp; ++ ++ // [c.math.fpclass], classification / comparison functions ++ using std::fpclassify; ++ using std::isfinite; ++ using std::isgreater; ++ using std::isgreaterequal; ++ using std::isinf; ++ using std::isless; ++ using std::islessequal; ++ using std::islessgreater; ++ using std::isnan; ++ using std::isnormal; ++ using std::isunordered; ++ using std::signbit; ++ ++ // [sf.cmath], mathematical special functions ++#if 0 ++ // [sf.cmath.assoc.laguerre], associated Laguerre polynomials ++ using std::assoc_laguerre; ++ using std::assoc_laguerref; ++ using std::assoc_laguerrel; ++ ++ // [sf.cmath.assoc.legendre], associated Legendre functions ++ using std::assoc_legendre; ++ using std::assoc_legendref; ++ using std::assoc_legendrel; ++ ++ // [sf.cmath.beta], beta function ++ using std::beta; ++ using std::betaf; ++ using std::betal; ++ ++ // [sf.cmath.comp.ellint.1], complete elliptic integral of the first kind ++ using std::comp_ellint_1; ++ using std::comp_ellint_1f; ++ using std::comp_ellint_1l; ++ ++ // [sf.cmath.comp.ellint.2], complete elliptic integral of the second kind ++ using std::comp_ellint_2; ++ using std::comp_ellint_2f; ++ using std::comp_ellint_2l; ++ ++ // [sf.cmath.comp.ellint.3], complete elliptic integral of the third kind ++ using std::comp_ellint_3; ++ using std::comp_ellint_3f; ++ using std::comp_ellint_3l; ++ ++ // [sf.cmath.cyl.bessel.i], regular modified cylindrical Bessel functions ++ using std::cyl_bessel_i; ++ using std::cyl_bessel_if; ++ using std::cyl_bessel_il; ++ ++ // [sf.cmath.cyl.bessel.j], cylindrical Bessel functions of the first kind ++ using std::cyl_bessel_j; ++ using std::cyl_bessel_jf; ++ using std::cyl_bessel_jl; ++ ++ // [sf.cmath.cyl.bessel.k], irregular modified cylindrical Bessel functions ++ using std::cyl_bessel_k; ++ using std::cyl_bessel_kf; ++ using std::cyl_bessel_kl; ++ ++ // [sf.cmath.cyl.neumann], cylindrical Neumann functions ++ // cylindrical Bessel functions of the second kind ++ using std::cyl_neumann; ++ using std::cyl_neumannf; ++ using std::cyl_neumannl; ++ ++ // [sf.cmath.ellint.1], incomplete elliptic integral of the first kind ++ using std::ellint_1; ++ using std::ellint_1f; ++ using std::ellint_1l; ++ ++ // [sf.cmath.ellint.2], incomplete elliptic integral of the second kind ++ using std::ellint_2; ++ using std::ellint_2f; ++ using std::ellint_2l; ++ ++ // [sf.cmath.ellint.3], incomplete elliptic integral of the third kind ++ using std::ellint_3; ++ using std::ellint_3f; ++ using std::ellint_3l; ++ ++ // [sf.cmath.expint], exponential integral ++ using std::expint; ++ using std::expintf; ++ using std::expintl; ++ ++ // [sf.cmath.hermite], Hermite polynomials ++ using std::hermite; ++ using std::hermitef; ++ using std::hermitel; ++ ++ // [sf.cmath.laguerre], Laguerre polynomials ++ using std::laguerre; ++ using std::laguerref; ++ using std::laguerrel; ++ ++ // [sf.cmath.legendre], Legendre polynomials ++ using std::legendre; ++ using std::legendref; ++ using std::legendrel; ++ ++ // [sf.cmath.riemann.zeta], Riemann zeta function ++ using std::riemann_zeta; ++ using std::riemann_zetaf; ++ using std::riemann_zetal; ++ ++ // [sf.cmath.sph.bessel], spherical Bessel functions of the first kind ++ using std::sph_bessel; ++ using std::sph_besself; ++ using std::sph_bessell; ++ ++ // [sf.cmath.sph.legendre], spherical associated Legendre functions ++ using std::sph_legendre; ++ using std::sph_legendref; ++ using std::sph_legendrel; ++ ++ // [sf.cmath.sph.neumann], spherical Neumann functions; ++ // spherical Bessel functions of the second kind ++ using std::sph_neumann; ++ using std::sph_neumannf; ++ using std::sph_neumannl; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/codecvt.cppm b/libcxx/modules/std/codecvt.cppm +new file mode 100644 +index 000000000000..755dcedb9243 +--- /dev/null ++++ b/libcxx/modules/std/codecvt.cppm +@@ -0,0 +1,28 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:codecvt; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::codecvt_mode; ++ ++ using std::codecvt_utf16; ++ using std::codecvt_utf8; ++ using std::codecvt_utf8_utf16; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/compare.cppm b/libcxx/modules/std/compare.cppm +new file mode 100644 +index 000000000000..33ea9438b857 +--- /dev/null ++++ b/libcxx/modules/std/compare.cppm +@@ -0,0 +1,56 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:compare; ++export namespace std { ++ ++ // [cmp.categories], comparison category types ++ using std::partial_ordering; ++ using std::strong_ordering; ++ using std::weak_ordering; ++ ++ // named comparison functions ++ using std::is_eq; ++ using std::is_gt; ++ using std::is_gteq; ++ using std::is_lt; ++ using std::is_lteq; ++ using std::is_neq; ++ ++ // [cmp.common], common comparison category type ++ using std::common_comparison_category; ++ using std::common_comparison_category_t; ++ ++ // [cmp.concept], concept three_way_comparable ++ using std::three_way_comparable; ++ using std::three_way_comparable_with; ++ ++ // [cmp.result], result of three-way comparison ++ using std::compare_three_way_result; ++ ++ using std::compare_three_way_result_t; ++ ++ // [comparisons.three.way], class compare_three_way ++ using std::compare_three_way; ++ ++ // [cmp.alg], comparison algorithms ++ inline namespace __cpo { ++ using std::__cpo::compare_partial_order_fallback; ++ using std::__cpo::compare_strong_order_fallback; ++ using std::__cpo::compare_weak_order_fallback; ++ using std::__cpo::partial_order; ++ using std::__cpo::strong_order; ++ using std::__cpo::weak_order; ++ } // namespace __cpo ++ ++} // namespace std +diff --git a/libcxx/modules/std/complex.cppm b/libcxx/modules/std/complex.cppm +new file mode 100644 +index 000000000000..1c3386d06920 +--- /dev/null ++++ b/libcxx/modules/std/complex.cppm +@@ -0,0 +1,74 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:complex; ++export namespace std { ++ ++ // [complex], class template complex ++ using std::complex; ++ ++ // [complex.ops], operators ++ using std::operator+; ++ using std::operator-; ++ using std::operator*; ++ using std::operator/; ++ ++ using std::operator==; ++ using std::operator>>; ++ using std::operator<<; ++ ++ // [complex.value.ops], values ++ using std::imag; ++ using std::real; ++ ++ using std::abs; ++ using std::arg; ++ using std::norm; ++ ++ using std::conj; ++ using std::polar; ++ using std::proj; ++ ++ // [complex.transcendentals], transcendentals ++ using std::acos; ++ using std::asin; ++ using std::atan; ++ ++ using std::acosh; ++ using std::asinh; ++ using std::atanh; ++ ++ using std::cos; ++ using std::cosh; ++ using std::exp; ++ using std::log; ++ using std::log10; ++ ++ using std::pow; ++ ++ using std::sin; ++ using std::sinh; ++ using std::sqrt; ++ using std::tan; ++ using std::tanh; ++ ++ // [complex.literals], complex literals ++ inline namespace literals { ++ inline namespace complex_literals { ++ using std::operator""il; ++ using std::operator""i; ++ using std::operator""if; ++ } // namespace complex_literals ++ } // namespace literals ++ ++} // namespace std +diff --git a/libcxx/modules/std/concepts.cppm b/libcxx/modules/std/concepts.cppm +new file mode 100644 +index 000000000000..598ff2c0031e +--- /dev/null ++++ b/libcxx/modules/std/concepts.cppm +@@ -0,0 +1,101 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:concepts; ++export namespace std { ++ ++ // [concepts.lang], language-related concepts ++ // [concept.same], concept same_as ++ using std::same_as; ++ ++ // [concept.derived], concept derived_from ++ using std::derived_from; ++ ++ // [concept.convertible], concept convertible_to ++ using std::convertible_to; ++ ++ // [concept.commonref], concept common_reference_with ++ using std::common_reference_with; ++ ++ // [concept.common], concept common_with ++ using std::common_with; ++ ++ // [concepts.arithmetic], arithmetic concepts ++ using std::floating_point; ++ using std::integral; ++ using std::signed_integral; ++ using std::unsigned_integral; ++ ++ // [concept.assignable], concept assignable_from ++ using std::assignable_from; ++ ++ // [concept.swappable], concept swappable ++ namespace ranges { ++ inline namespace __cpo { ++ using std::ranges::__cpo::swap; ++ } ++ } // namespace ranges ++ ++ using std::swappable; ++ using std::swappable_with; ++ ++ // [concept.destructible], concept destructible ++ using std::destructible; ++ ++ // [concept.constructible], concept constructible_from ++ using std::constructible_from; ++ ++ // [concept.default.init], concept default_initializable ++ using std::default_initializable; ++ ++ // [concept.moveconstructible], concept move_constructible ++ using std::move_constructible; ++ ++ // [concept.copyconstructible], concept copy_constructible ++ using std::copy_constructible; ++ ++ // [concepts.compare], comparison concepts ++ // [concept.equalitycomparable], concept equality_comparable ++ using std::equality_comparable; ++ using std::equality_comparable_with; ++ ++ // [concept.totallyordered], concept totally_ordered ++ using std::totally_ordered; ++ using std::totally_ordered_with; ++ ++ // [concepts.object], object concepts ++ using std::copyable; ++ using std::movable; ++ using std::regular; ++ using std::semiregular; ++ ++ // [concepts.callable], callable concepts ++ // [concept.invocable], concept invocable ++ using std::invocable; ++ ++ // [concept.regularinvocable], concept regular_invocable ++ using std::regular_invocable; ++ ++ // [concept.predicate], concept predicate ++ using std::predicate; ++ ++ // [concept.relation], concept relation ++ using std::relation; ++ ++ // [concept.equiv], concept equivalence_relation ++ using std::equivalence_relation; ++ ++ // [concept.strictweakorder], concept strict_weak_order ++ using std::strict_weak_order; ++ ++} // namespace std +diff --git a/libcxx/modules/std/condition_variable.cppm b/libcxx/modules/std/condition_variable.cppm +new file mode 100644 +index 000000000000..1597009f7e2a +--- /dev/null ++++ b/libcxx/modules/std/condition_variable.cppm +@@ -0,0 +1,27 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:condition_variable; ++export namespace std { ++ ++ // [thread.condition.condvar], class condition_variable ++ using std::condition_variable; ++ // [thread.condition.condvarany], class condition_variable_any ++ using std::condition_variable_any; ++ ++ // [thread.condition.nonmember], non-member functions ++ using std::notify_all_at_thread_exit; ++ ++ using std::cv_status; ++ ++} // namespace std +diff --git a/libcxx/modules/std/coroutine.cppm b/libcxx/modules/std/coroutine.cppm +new file mode 100644 +index 000000000000..4b018dbe6f32 +--- /dev/null ++++ b/libcxx/modules/std/coroutine.cppm +@@ -0,0 +1,28 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++#include ++export module std:coroutine; ++export namespace std { ++ using std::coroutine_handle; ++ using std::coroutine_traits; ++ using std::operator==; ++ using std::operator<=>; ++ using std::noop_coroutine; ++ using std::noop_coroutine_handle; ++ using std::noop_coroutine_promise; ++ ++ using std::suspend_always; ++ using std::suspend_never; ++ ++ using std::hash; ++} // namespace std +diff --git a/libcxx/modules/std/csetjmp.cppm b/libcxx/modules/std/csetjmp.cppm +new file mode 100644 +index 000000000000..632eeb536d9a +--- /dev/null ++++ b/libcxx/modules/std/csetjmp.cppm +@@ -0,0 +1,18 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:csetjmp; ++export namespace std { ++ using std::jmp_buf; ++ using std::longjmp; ++} // namespace std +diff --git a/libcxx/modules/std/csignal.cppm b/libcxx/modules/std/csignal.cppm +new file mode 100644 +index 000000000000..d2ee53301c02 +--- /dev/null ++++ b/libcxx/modules/std/csignal.cppm +@@ -0,0 +1,23 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:csignal; ++export namespace std { ++ using std::sig_atomic_t; ++ ++ // [support.signal], signal handlers ++ using std::signal; ++ ++ using std::raise; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cstdarg.cppm b/libcxx/modules/std/cstdarg.cppm +new file mode 100644 +index 000000000000..c85432a6738b +--- /dev/null ++++ b/libcxx/modules/std/cstdarg.cppm +@@ -0,0 +1,18 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cstdarg; ++export namespace std { ++ using std::va_list; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cstddef.cppm b/libcxx/modules/std/cstddef.cppm +new file mode 100644 +index 000000000000..97f477b32847 +--- /dev/null ++++ b/libcxx/modules/std/cstddef.cppm +@@ -0,0 +1,36 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cstddef; ++export namespace std { ++ using std::max_align_t; ++ using std::nullptr_t; ++ using std::ptrdiff_t; ++ using std::size_t; ++ ++ using std::byte; ++ ++ // [support.types.byteops], byte type operations ++ using std::operator<<=; ++ using std::operator<<; ++ using std::operator>>=; ++ using std::operator>>; ++ using std::operator|=; ++ using std::operator|; ++ using std::operator&=; ++ using std::operator&; ++ using std::operator^=; ++ using std::operator^; ++ using std::operator~; ++ using std::to_integer; ++} // namespace std +diff --git a/libcxx/modules/std/cstdio.cppm b/libcxx/modules/std/cstdio.cppm +new file mode 100644 +index 000000000000..4f44857c770c +--- /dev/null ++++ b/libcxx/modules/std/cstdio.cppm +@@ -0,0 +1,66 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cstdio; ++export namespace std { ++ using std::FILE; ++ using std::fpos_t; ++ using std::size_t; ++ ++ using std::clearerr; ++ using std::fclose; ++ using std::feof; ++ using std::ferror; ++ using std::fflush; ++ using std::fgetc; ++ using std::fgetpos; ++ using std::fgets; ++ using std::fopen; ++ using std::fprintf; ++ using std::fputc; ++ using std::fputs; ++ using std::fread; ++ using std::freopen; ++ using std::fscanf; ++ using std::fseek; ++ using std::fsetpos; ++ using std::ftell; ++ using std::fwrite; ++ using std::getc; ++ using std::getchar; ++ using std::perror; ++ using std::printf; ++ using std::putc; ++ using std::putchar; ++ using std::puts; ++ using std::remove; ++ using std::rename; ++ using std::rewind; ++ using std::scanf; ++ using std::setbuf; ++ using std::setvbuf; ++ using std::snprintf; ++ using std::sprintf; ++ using std::sscanf; ++ using std::tmpfile; ++ using std::tmpnam; ++ using std::ungetc; ++ using std::vfprintf; ++ using std::vfscanf; ++ using std::vprintf; ++ using std::vscanf; ++ using std::vsnprintf; ++ using std::vsprintf; ++ using std::vsscanf; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cstdlib.cppm b/libcxx/modules/std/cstdlib.cppm +new file mode 100644 +index 000000000000..7f9589311e36 +--- /dev/null ++++ b/libcxx/modules/std/cstdlib.cppm +@@ -0,0 +1,78 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cstdlib; ++export namespace std { ++ ++ using std::div_t; ++ using std::ldiv_t; ++ using std::lldiv_t; ++ using std::size_t; ++ ++ // [support.start.term], start and termination ++ using std::_Exit; ++ using std::abort; ++ using std::at_quick_exit; ++ using std::atexit; ++ using std::exit; ++ using std::quick_exit; ++ ++ using std::getenv; ++ using std::system; ++ ++ // [c.malloc], C library memory allocation ++ using std::aligned_alloc; ++ using std::calloc; ++ using std::free; ++ using std::malloc; ++ using std::realloc; ++ ++ using std::atof; ++ using std::atoi; ++ using std::atol; ++ using std::atoll; ++ using std::strtod; ++ using std::strtof; ++ using std::strtol; ++ using std::strtold; ++ using std::strtoll; ++ using std::strtoul; ++ using std::strtoull; ++ ++ // [c.mb.wcs], multibyte / wide string and character conversion functions ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::mblen; ++ using std::mbstowcs; ++ using std::mbtowc; ++ using std::wcstombs; ++ using std::wctomb; ++#endif ++ // [alg.c.library], C standard library algorithms ++ using std::bsearch; ++ using std::qsort; ++ ++ // [c.math.rand], low-quality random number generation ++ using std::rand; ++ using std::srand; ++ ++ // [c.math.abs], absolute values ++ using std::abs; ++ ++ using std::labs; ++ using std::llabs; ++ ++ using std::div; ++ using std::ldiv; ++ using std::lldiv; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cstring.cppm b/libcxx/modules/std/cstring.cppm +new file mode 100644 +index 000000000000..5ec6ee8c0601 +--- /dev/null ++++ b/libcxx/modules/std/cstring.cppm +@@ -0,0 +1,42 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cstring; ++export namespace std { ++ ++ using std::size_t; ++ ++ using std::memchr; ++ using std::memcmp; ++ using std::memcpy; ++ using std::memmove; ++ using std::memset; ++ using std::strcat; ++ using std::strchr; ++ using std::strcmp; ++ using std::strcoll; ++ using std::strcpy; ++ using std::strcspn; ++ using std::strerror; ++ using std::strlen; ++ using std::strncat; ++ using std::strncmp; ++ using std::strncpy; ++ using std::strpbrk; ++ using std::strrchr; ++ using std::strspn; ++ using std::strstr; ++ using std::strtok; ++ using std::strxfrm; ++ ++} // namespace std +diff --git a/libcxx/modules/std/ctime.cppm b/libcxx/modules/std/ctime.cppm +new file mode 100644 +index 000000000000..50298e03c08e +--- /dev/null ++++ b/libcxx/modules/std/ctime.cppm +@@ -0,0 +1,34 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:ctime; ++export namespace std { ++ using std::clock_t; ++ using std::size_t; ++ using std::time_t; ++ ++ using std::timespec; ++ using std::tm; ++ ++ using std::asctime; ++ using std::clock; ++ using std::ctime; ++ using std::difftime; ++ using std::gmtime; ++ using std::localtime; ++ using std::mktime; ++ using std::strftime; ++ using std::time; ++ using std::timespec_get; ++ ++} // namespace std +diff --git a/libcxx/modules/std/cuchar.cppm b/libcxx/modules/std/cuchar.cppm +new file mode 100644 +index 000000000000..6b12da3ed56a +--- /dev/null ++++ b/libcxx/modules/std/cuchar.cppm +@@ -0,0 +1,32 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:cuchar; ++export namespace std { ++ ++ // Note the Standard does not mark these symbols optional, but libc++'s header ++ // does. So this seems strictly not to be conforming. ++ ++ // mbstate_t is conditionally here, but always present in cwchar.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ // size_t is conditionally here, but always present in cstddef.cppm. To avoid ++ // conflicing declarations omit the using here. ++ ++ using std::mbrtoc8 _LIBCPP_USING_IF_EXISTS; ++ using std::c8rtomb _LIBCPP_USING_IF_EXISTS; ++ using std::mbrtoc16 _LIBCPP_USING_IF_EXISTS; ++ using std::c16rtomb _LIBCPP_USING_IF_EXISTS; ++ using std::mbrtoc32 _LIBCPP_USING_IF_EXISTS; ++ using std::c32rtomb _LIBCPP_USING_IF_EXISTS; ++} // namespace std +diff --git a/libcxx/modules/std/cwchar.cppm b/libcxx/modules/std/cwchar.cppm +new file mode 100644 +index 000000000000..09b886a35b32 +--- /dev/null ++++ b/libcxx/modules/std/cwchar.cppm +@@ -0,0 +1,89 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++# include ++#endif ++ ++export module std:cwchar; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++export namespace std { ++ using std::mbstate_t; ++ using std::size_t; ++ using std::wint_t; ++ ++ using std::tm; ++ ++ using std::btowc; ++ using std::fgetwc; ++ using std::fgetws; ++ using std::fputwc; ++ using std::fputws; ++ using std::fwide; ++ using std::fwprintf; ++ using std::fwscanf; ++ using std::getwc; ++ using std::getwchar; ++ using std::putwc; ++ using std::putwchar; ++ using std::swprintf; ++ using std::swscanf; ++ using std::ungetwc; ++ using std::vfwprintf; ++ using std::vfwscanf; ++ using std::vswprintf; ++ using std::vswscanf; ++ using std::vwprintf; ++ using std::vwscanf; ++ using std::wcscat; ++ using std::wcschr; ++ using std::wcscmp; ++ using std::wcscoll; ++ using std::wcscpy; ++ using std::wcscspn; ++ using std::wcsftime; ++ using std::wcslen; ++ using std::wcsncat; ++ using std::wcsncmp; ++ using std::wcsncpy; ++ using std::wcspbrk; ++ using std::wcsrchr; ++ using std::wcsspn; ++ using std::wcsstr; ++ using std::wcstod; ++ using std::wcstof; ++ using std::wcstok; ++ using std::wcstol; ++ using std::wcstold; ++ using std::wcstoll; ++ using std::wcstoul; ++ using std::wcstoull; ++ using std::wcsxfrm; ++ using std::wctob; ++ using std::wmemchr; ++ using std::wmemcmp; ++ using std::wmemcpy; ++ using std::wmemmove; ++ using std::wmemset; ++ using std::wprintf; ++ using std::wscanf; ++ ++ // [c.mb.wcs], multibyte / wide string and character conversion functions ++ using std::mbrlen; ++ using std::mbrtowc; ++ using std::mbsinit; ++ using std::mbsrtowcs; ++ using std::wcrtomb; ++ using std::wcsrtombs; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +diff --git a/libcxx/modules/std/cwctype.cppm b/libcxx/modules/std/cwctype.cppm +new file mode 100644 +index 000000000000..21d0fd258c91 +--- /dev/null ++++ b/libcxx/modules/std/cwctype.cppm +@@ -0,0 +1,45 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++# include ++#endif ++ ++export module std:cwctype; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++export namespace std { ++ ++ using std::wctrans_t; ++ using std::wctype_t; ++ using std::wint_t; ++ ++ using std::iswalnum; ++ using std::iswalpha; ++ using std::iswblank; ++ using std::iswcntrl; ++ using std::iswctype; ++ using std::iswdigit; ++ using std::iswgraph; ++ using std::iswlower; ++ using std::iswprint; ++ using std::iswpunct; ++ using std::iswspace; ++ using std::iswupper; ++ using std::iswxdigit; ++ using std::towctrans; ++ using std::towlower; ++ using std::towupper; ++ using std::wctrans; ++ using std::wctype; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +diff --git a/libcxx/modules/std/deque.cppm b/libcxx/modules/std/deque.cppm +new file mode 100644 +index 000000000000..3d06e67dcfeb +--- /dev/null ++++ b/libcxx/modules/std/deque.cppm +@@ -0,0 +1,36 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:deque; ++export namespace std { ++ ++ // [deque], class template deque ++ using std::deque; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ ++ // [deque.erasure], erasure ++ using std::erase; ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::deque; ++ } ++ ++ // Note formatter not in synopsis ++ // TODO Test whether the ommission fails tests. ++ ++} // namespace std +diff --git a/libcxx/modules/std/exception.cppm b/libcxx/modules/std/exception.cppm +new file mode 100644 +index 000000000000..ae28302a8fce +--- /dev/null ++++ b/libcxx/modules/std/exception.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++export module std:exception; ++export namespace std { ++ using std::bad_exception; ++ using std::current_exception; ++ using std::exception; ++ using std::exception_ptr; ++ using std::get_terminate; ++ using std::make_exception_ptr; ++ using std::nested_exception; ++ using std::rethrow_exception; ++ using std::rethrow_if_nested; ++ using std::set_terminate; ++ using std::terminate; ++ using std::terminate_handler; ++ using std::throw_with_nested; ++ using std::uncaught_exception; ++ using std::uncaught_exceptions; ++} // namespace std +diff --git a/libcxx/modules/std/execution.cppm b/libcxx/modules/std/execution.cppm +new file mode 100644 +index 000000000000..3433bb294078 +--- /dev/null ++++ b/libcxx/modules/std/execution.cppm +@@ -0,0 +1,41 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:execution; ++#if 0 // TODO MODULES Enable when this feature is implemented ++export namespace std { ++ // [execpol.type], execution policy type trait ++ using std::is_execution_policy; ++ using std::is_execution_policy_v; ++} // namespace std ++ ++namespace std::execution { ++ // [execpol.seq], sequenced execution policy ++ using std::execution::sequenced_policy; ++ ++ // [execpol.par], parallel execution policy ++ using std::execution::parallel_policy; ++ ++ // [execpol.parunseq], parallel and unsequenced execution policy ++ using std::execution::parallel_unsequenced_policy; ++ ++ // [execpol.unseq], unsequenced execution policy ++ using std::execution::unsequenced_policy; ++ ++ // [execpol.objects], execution policy objects ++ using std::execution::par; ++ using std::execution::par_unseq; ++ using std::execution::seq; ++ using std::execution::unseq; ++} // namespace std::execution ++#endif +diff --git a/libcxx/modules/std/expected.cppm b/libcxx/modules/std/expected.cppm +new file mode 100644 +index 000000000000..5b8a12292ba0 +--- /dev/null ++++ b/libcxx/modules/std/expected.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include // Since C++23 ++ ++export module std:expected; ++export namespace std { ++ ++ // [expected.unexpected], class template unexpected ++ using std::unexpected; ++ ++ // [expected.bad], class template bad_expected_access ++ using std::bad_expected_access; ++ ++ // [expected.bad.void], specialization for void ++ ++ // in-place construction of unexpected values ++ using std::unexpect_t; ++ ++ using std::unexpect; ++ ++ // [expected.expected], class template expected ++ using std::expected; ++ ++ // [expected.void], partial specialization of expected for void types ++ ++} // namespace std +diff --git a/libcxx/modules/std/filesystem.cppm b/libcxx/modules/std/filesystem.cppm +new file mode 100644 +index 000000000000..a4fd47423e84 +--- /dev/null ++++ b/libcxx/modules/std/filesystem.cppm +@@ -0,0 +1,124 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:filesystem; ++export namespace std::filesystem { ++ ++ // [fs.class.path], paths ++ using std::filesystem::path; ++ ++ // [fs.path.nonmember], path non-member functions ++ using std::filesystem::hash_value; ++ using std::filesystem::swap; ++ ++ // [fs.class.filesystem.error], filesystem errors ++ using std::filesystem::filesystem_error; ++ ++ // [fs.class.directory.entry], directory entries ++ using std::filesystem::directory_entry; ++ ++ // [fs.class.directory.iterator], directory iterators ++ using std::filesystem::directory_iterator; ++ ++ // [fs.dir.itr.nonmembers], range access for directory iterators ++ using std::filesystem::begin; ++ using std::filesystem::end; ++ ++ // [fs.class.rec.dir.itr], recursive directory iterators ++ using std::filesystem::recursive_directory_iterator; ++ ++ // [fs.rec.dir.itr.nonmembers], range access for recursive directory iterators ++ using std::filesystem::begin; ++ using std::filesystem::end; ++ ++ // [fs.class.file.status], file status ++ using std::filesystem::file_status; ++ using std::filesystem::space_info; ++ ++ // [fs.enum], enumerations ++ using std::filesystem::copy_options; ++ using std::filesystem::directory_options; ++ using std::filesystem::file_type; ++ using std::filesystem::perm_options; ++ using std::filesystem::perms; ++ ++ using std::filesystem::file_time_type; ++ ++ // several of these enums are a bitmask type. ++ // [bitmask.types] specified operators ++ using std::filesystem::operator&; ++ using std::filesystem::operator&=; ++ using std::filesystem::operator^; ++ using std::filesystem::operator^=; ++ using std::filesystem::operator|; ++ using std::filesystem::operator|=; ++ using std::filesystem::operator~; ++ ++ // [fs.op.funcs], filesystem operations ++ using std::filesystem::absolute; ++ using std::filesystem::canonical; ++ using std::filesystem::copy; ++ using std::filesystem::copy_file; ++ using std::filesystem::copy_symlink; ++ using std::filesystem::create_directories; ++ using std::filesystem::create_directory; ++ using std::filesystem::create_directory_symlink; ++ using std::filesystem::create_hard_link; ++ using std::filesystem::create_symlink; ++ using std::filesystem::current_path; ++ using std::filesystem::equivalent; ++ using std::filesystem::exists; ++ using std::filesystem::file_size; ++ using std::filesystem::hard_link_count; ++ ++ using std::filesystem::is_block_file; ++ using std::filesystem::is_character_file; ++ using std::filesystem::is_directory; ++ using std::filesystem::is_empty; ++ using std::filesystem::is_fifo; ++ using std::filesystem::is_other; ++ using std::filesystem::is_regular_file; ++ using std::filesystem::is_socket; ++ using std::filesystem::is_symlink; ++ ++ using std::filesystem::last_write_time; ++ using std::filesystem::permissions; ++ using std::filesystem::proximate; ++ using std::filesystem::read_symlink; ++ using std::filesystem::relative; ++ using std::filesystem::remove; ++ ++ using std::filesystem::remove_all; ++ using std::filesystem::rename; ++ using std::filesystem::resize_file; ++ using std::filesystem::space; ++ using std::filesystem::status; ++ using std::filesystem::status_known; ++ using std::filesystem::symlink_status; ++ using std::filesystem::temp_directory_path; ++ using std::filesystem::weakly_canonical; ++ ++ // [depr.fs.path.factory] ++ using std::filesystem::u8path; ++ ++} // namespace std::filesystem ++ ++// [fs.path.hash], hash support ++namespace std { ++ using std::hash; ++} ++ ++namespace std::ranges { ++ using std::ranges::enable_borrowed_range; ++ using std::ranges::enable_view; ++} // namespace std::ranges +diff --git a/libcxx/modules/std/flat_map.cppm b/libcxx/modules/std/flat_map.cppm +new file mode 100644 +index 000000000000..73731696589b +--- /dev/null ++++ b/libcxx/modules/std/flat_map.cppm +@@ -0,0 +1,39 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:flat_map; ++export namespace std { ++#if 0 ++ // [flat.map], class template flat_­map ++ using std::flat_map; ++ ++ using std::sorted_unique; ++ using std::sorted_unique_t; ++ ++ using std::uses_allocator; ++ ++ // [flat.map.erasure], erasure for flat_­map ++ using std::erase_if; ++ ++ // [flat.multimap], class template flat_­multimap ++ using std::flat_multimap; ++ ++ using std::sorted_equivalent; ++ using std::sorted_equivalent_t; ++ ++ // [flat.multimap.erasure], erasure for flat_­multimap ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/flat_set.cppm b/libcxx/modules/std/flat_set.cppm +new file mode 100644 +index 000000000000..11eb8b0ef35a +--- /dev/null ++++ b/libcxx/modules/std/flat_set.cppm +@@ -0,0 +1,41 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:flat_set; ++export namespace std { ++#if 0 ++ // [flat.set], class template flat_­set ++ using std::flat_set; ++ ++ using std::sorted_unique; ++ using std::sorted_unique_t; ++ ++ using std::Allocator > ; ++ ++ // [flat.set.erasure], erasure for flat_­set ++ using std::erase_if; ++ ++ // [flat.multiset], class template flat_­multiset ++ using std::flat_multiset; ++ ++ using std::sorted_equivalent; ++ using std::sorted_equivalent_t; ++ ++ using std::uses_allocator; ++ ++ // [flat.multiset.erasure], erasure for flat_­multiset ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/format.cppm b/libcxx/modules/std/format.cppm +new file mode 100644 +index 000000000000..0a41cf1b0ba9 +--- /dev/null ++++ b/libcxx/modules/std/format.cppm +@@ -0,0 +1,470 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++// TODO This file is two-fold ++// - look at how we want to integrate a synopsis ++// - test whether the experimental library works properly ++ ++module; ++#include // Since C++20 ++ ++export module std:format; ++#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) ++export namespace std { ++ ++ // [format.context], class template basic_format_context ++ // template ++ // class basic_format_context; ++ using std::basic_format_context; ++ /* ++ template ++ class basic_format_context { ++ basic_format_args args_; // exposition only ++ Out out_; // exposition only ++ ++ public: ++ using iterator = Out; ++ using char_type = charT; ++ template using formatter_type = formatter; ++ ++ basic_format_arg arg(size_t id) const noexcept; ++ std::locale locale(); ++ ++ iterator out(); ++ void advance_to(iterator it); ++ }; ++ */ ++ // using format_context = basic_format_context; ++ // using wformat_context = basic_format_context; ++ using std::format_context; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wformat_context; ++# endif ++ ++ // [format.args], class template basic_format_args ++ // template ++ // class basic_format_args; ++ using std::basic_format_args; ++ /* ++ template ++ class basic_format_args { ++ size_t size_; // exposition only ++ const basic_format_arg* data_; // exposition only ++ ++ public: ++ basic_format_args() noexcept; ++ ++ template ++ basic_format_args(const format-arg-store& store) noexcept; ++ ++ basic_format_arg get(size_t i) const noexcept; ++ }; ++ */ ++ // using format_args = basic_format_args; ++ // using wformat_args = basic_format_args; ++ using std::format_args; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wformat_args; ++# endif ++ ++ // [format.fmt.string], class template basic_format_string ++ // template ++ // struct basic_format_string; ++ using std::basic_format_string; ++ ++ // template ++ // using format_string = basic_format_string...>; ++ // template ++ // using wformat_string = basic_format_string...>; ++ using std::format_string; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wformat_string; ++# endif ++ ++ // [format.functions], formatting functions ++ // template ++ // string format(format_string fmt, Args&&... args); ++ // template ++ // wstring format(wformat_string fmt, Args&&... args); ++ // template ++ // string format(const locale& loc, format_string fmt, Args&&... args); ++ // template ++ // wstring format(const locale& loc, wformat_string fmt, Args&&... args); ++ using std::format; ++ ++ // string vformat(string_view fmt, format_args args); ++ // wstring vformat(wstring_view fmt, wformat_args args); ++ // string vformat(const locale& loc, string_view fmt, format_args args); ++ // wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); ++ using std::vformat; ++ ++ // template ++ // Out format_to(Out out, format_string fmt, Args&&... args); ++ // template ++ // Out format_to(Out out, wformat_string fmt, Args&&... args); ++ // template ++ // Out format_to(Out out, const locale& loc, format_string fmt, Args&&... args); ++ // template ++ // Out format_to(Out out, const locale& loc, wformat_string fmt, Args&&... args); ++ using std::format_to; ++ ++ // template ++ // Out vformat_to(Out out, string_view fmt, format_args args); ++ // template ++ // Out vformat_to(Out out, wstring_view fmt, wformat_args args); ++ // template ++ // Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args); ++ // template ++ // Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args); ++ using std::vformat_to; ++ ++ // template ++ // struct format_to_n_result { ++ // Out out; ++ // iter_difference_t size; ++ // }; ++ using std::format_to_n_result; ++ // template ++ // format_to_n_result format_to_n(Out out, iter_difference_t n, format_string fmt, Args&&... args); ++ // template ++ // format_to_n_result format_to_n(Out out, iter_difference_t n, wformat_string fmt, Args&&... ++ // args); template format_to_n_result format_to_n(Out out, iter_difference_t n, ++ // const locale& loc, format_string fmt, Args&&... args); template ++ // format_to_n_result ++ // format_to_n(Out out, iter_difference_t n, const locale& loc, wformat_string fmt, Args&&... args); ++ using std::format_to_n; ++ ++ // template ++ // size_t formatted_size(format_string fmt, Args&&... args); ++ // template ++ // size_t formatted_size(wformat_string fmt, Args&&... args); ++ // template ++ // size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); ++ // template ++ // size_t formatted_size(const locale& loc, wformat_string fmt, Args&&... args); ++ using std::formatted_size; ++ ++ // [format.formatter], formatter ++ // template ++ // struct formatter; ++ using std::formatter; ++ ++ // [format.formattable], concept formattable ++ // template ++ // concept formattable = see below; // Since C++23 ++ using std::formattable; ++ ++ // template ++ // concept const-formattable-range = // exposition only ++ // ranges::input_range && formattable, charT>; ++ ++ // template ++ // using fmt-maybe-const = // exposition only ++ // conditional_t, const R, R>; ++ ++ // [format.parse.ctx], class template basic_format_parse_context ++ // template a ++ // class basic_format_parse_context; ++ using std::basic_format_parse_context; ++ ++ /* ++ template ++ class basic_format_parse_context { ++ public: ++ using char_type = charT; ++ using const_iterator = typename basic_string_view::const_iterator; ++ using iterator = const_iterator; ++ ++ private: ++ iterator begin_; // exposition only ++ iterator end_; // exposition only ++ enum indexing { unknown, manual, automatic }; // exposition only ++ indexing indexing_; // exposition only ++ size_t next_arg_id_; // exposition only ++ size_t num_args_; // exposition only ++ ++ public: ++ constexpr explicit basic_format_parse_context(basic_string_view fmt, ++ size_t num_args = 0) noexcept; ++ basic_format_parse_context(const basic_format_parse_context&) = delete; ++ basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; ++ ++ constexpr const_iterator begin() const noexcept; ++ constexpr const_iterator end() const noexcept; ++ constexpr void advance_to(const_iterator it); ++ ++ constexpr size_t next_arg_id(); ++ constexpr void check_arg_id(size_t id); ++ }; ++ */ ++ ++ // using format_parse_context = basic_format_parse_context; ++ // using wformat_parse_context = basic_format_parse_context; ++ using std::format_parse_context; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wformat_parse_context; ++# endif ++ ++ // [format.range], formatting of ranges ++ // [format.range.fmtkind], variable template format_kind ++ // enum class range_format { disabled, map, set, sequence, string, debug_string }; // Since C++23 ++ using std::range_format; ++ ++ // template ++ // constexpr unspecified format_kind = unspecified; ++ using std::format_kind; ++ ++ // template ++ // requires same_as> ++ // constexpr range_format format_kind = see below; ++ using std::format_kind; ++ ++ // [format.range.formatter], class template range_formatter ++ // template ++ // requires same_as, T> && formattable ++ // class range_formatter; ++ using std::range_formatter; ++ ++ /* ++ template ++ requires same_as, T> && formattable ++ class range_formatter { ++ formatter underlying_; // exposition only ++ basic_string_view separator_ = STATICALLY-WIDEN(", "); // exposition only ++ basic_string_view opening-bracket_ = STATICALLY-WIDEN("["); // exposition only ++ basic_string_view closing-bracket_ = STATICALLY-WIDEN("]"); // exposition only ++ ++ public: ++ constexpr void set_separator(basic_string_view sep); ++ constexpr void set_brackets(basic_string_view opening, ++ basic_string_view closing); ++ constexpr formatter& underlying() { return underlying_; } ++ constexpr const formatter& underlying() const { return underlying_; } ++ ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ requires formattable, charT> && ++ same_as>, T> ++ typename FormatContext::iterator ++ format(R&& r, FormatContext& ctx) const; ++ }; ++ */ ++ ++ // [format.range.fmtdef], class template range-default-formatter ++ // template ++ // struct range-default-formatter; // exposition only ++ /* ++ template ++ struct range-default-formatter { // exposition only ++ private: ++ using maybe-const-r = fmt-maybe-const; // exposition only ++ range_formatter>, ++ charT> underlying_; // exposition only ++ ++ public: ++ constexpr void set_separator(basic_string_view sep); ++ constexpr void set_brackets(basic_string_view opening, ++ basic_string_view closing); ++ ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ typename FormatContext::iterator ++ format(maybe-const-r& elems, FormatContext& ctx) const; ++ }; ++ */ ++ ++ // [format.range.fmtmap], [format.range.fmtset], [format.range.fmtstr], specializations for maps, sets, and strings ++ /* ++ template // Since C++23 ++ struct range-default-formatter { ++ private: ++ using maybe-const-map = fmt-maybe-const; // exposition only ++ using element-type = // exposition only ++ remove_cvref_t>; ++ range_formatter underlying_; // exposition only ++ ++ public: ++ constexpr range-default-formatter(); ++ ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ typename FormatContext::iterator ++ format(maybe-const-map& r, FormatContext& ctx) const; ++ }; ++ ++ template ++ struct range-default-formatter { // Since C++23 ++ private: ++ using maybe-const-set = fmt-maybe-const; // exposition only ++ range_formatter>, ++ charT> underlying_; // exposition only ++ ++ public: ++ constexpr range-default-formatter(); ++ ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ typename FormatContext::iterator ++ format(maybe-const-set& r, FormatContext& ctx) const; ++ }; ++ ++ template ++ requires (K == range_format::string || K == range_format::debug_string) ++ struct range-default-formatter { // Since C++23 ++ private: ++ formatter, charT> underlying_; // exposition only ++ ++ public: ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ typename FormatContext::iterator ++ format(see below& str, FormatContext& ctx) const; ++ }; ++ */ ++ // template ++ // requires(format_kind != range_format::disabled) && ++ // formattable, charT> ++ // struct formatter : range-default-formatter, R, charT> {}; ++ ++ // [format.arguments], arguments ++ // [format.arg], class template basic_format_arg ++ // template ++ // class basic_format_arg; ++ using std::basic_format_arg; ++ ++ /* ++ template ++ class basic_format_arg { ++ public: ++ class handle; ++ ++ private: ++ using char_type = typename Context::char_type; // exposition only ++ ++ variant, ++ const void*, handle> value; // exposition only ++ ++ template explicit basic_format_arg(T&& v) noexcept; // exposition only ++ explicit basic_format_arg(float n) noexcept; // exposition only ++ explicit basic_format_arg(double n) noexcept; // exposition only ++ explicit basic_format_arg(long double n) noexcept; // exposition only ++ explicit basic_format_arg(const char_type* s); // exposition only ++ ++ template ++ explicit basic_format_arg( ++ basic_string_view s) noexcept; // exposition only ++ ++ template ++ explicit basic_format_arg( ++ const basic_string& s) noexcept; // exposition only ++ ++ explicit basic_format_arg(nullptr_t) noexcept; // exposition only ++ ++ template ++ explicit basic_format_arg(T* p) noexcept; // exposition only ++ ++ public: ++ basic_format_arg() noexcept; ++ ++ explicit operator bool() const noexcept; ++ }; ++ ++ template ++ class basic_format_arg::handle { ++ const void* ptr_; // exposition only ++ void (*format_)(basic_format_parse_context&, ++ Context&, const void*); // exposition only ++ ++ template explicit handle(T&& val) noexcept; // exposition only ++ ++ friend class basic_format_arg; // exposition only ++ ++ public: ++ void format(basic_format_parse_context&, Context& ctx) const; ++ }; ++ */ ++ ++ // template ++ // decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); ++ using std::visit_format_arg; ++ ++ // [format.arg.store], class template format-arg-store ++ // template ++ // class format-arg-store; // exposition only ++ /* ++ template ++ class format-arg-store { // exposition only ++ array, sizeof...(Args)> args; // exposition only ++ }; ++ */ ++ ++ // template ++ // format-arg-store make_format_args(Args&&... fmt_args); ++ // template ++ // format-arg-store make_wformat_args(Args&&... args); ++ using std::make_format_args; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::make_wformat_args; ++# endif ++ ++ // [format.error], class format_error ++ // class format_error; ++ using std::format_error; ++ /* ++ class format_error : public runtime_error { ++ public: ++ explicit format_error(const string& what_arg); ++ explicit format_error(const char* what_arg); ++ }; ++ */ ++ ++ /* ++ template... Ts> ++ struct formatter, charT> { // Since C++23 ++ private: ++ tuple, charT>...> underlying_; // exposition only ++ basic_string_view separator_ = STATICALLY-WIDEN(", "); // exposition only ++ basic_string_view opening-bracket_ = STATICALLY-WIDEN("("); // exposition only ++ basic_string_view closing-bracket_ = STATICALLY-WIDEN(")"); // exposition only ++ ++ public: ++ constexpr void set_separator(basic_string_view sep); ++ constexpr void set_brackets(basic_string_view opening, ++ basic_string_view closing); ++ ++ template ++ constexpr typename ParseContext::iterator ++ parse(ParseContext& ctx); ++ ++ template ++ typename FormatContext::iterator ++ format(see below& elems, FormatContext& ctx) const; ++ }; ++ */ ++} // namespace std ++#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) +diff --git a/libcxx/modules/std/forward_list.cppm b/libcxx/modules/std/forward_list.cppm +new file mode 100644 +index 000000000000..82126abe3e0b +--- /dev/null ++++ b/libcxx/modules/std/forward_list.cppm +@@ -0,0 +1,33 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:forward_list; ++export namespace std { ++ ++ // [forward.list], class template forward_list ++ using std::forward_list; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ ++ // [forward.list.erasure], erasure ++ using std::erase; ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::forward_list; ++ } ++ ++} // namespace std +diff --git a/libcxx/modules/std/fstream.cppm b/libcxx/modules/std/fstream.cppm +new file mode 100644 +index 000000000000..4f767b8a1798 +--- /dev/null ++++ b/libcxx/modules/std/fstream.cppm +@@ -0,0 +1,51 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:fstream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::basic_filebuf; ++ ++ using std::swap; ++ ++ using std::filebuf; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wfilebuf; ++# endif ++ ++ using std::basic_ifstream; ++ ++ using std::ifstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wifstream; ++# endif ++ ++ using std::basic_ofstream; ++ ++ using std::ofstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wofstream; ++# endif ++ ++ using std::basic_fstream; ++ ++ using std::fstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wfstream; ++# endif ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/functional.cppm b/libcxx/modules/std/functional.cppm +new file mode 100644 +index 000000000000..1d12b5c6a740 +--- /dev/null ++++ b/libcxx/modules/std/functional.cppm +@@ -0,0 +1,124 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:functional; ++export namespace std { ++ // [func.invoke], invoke ++ using std::invoke_r; ++ using std::invoke_result_t; ++ ++ // [refwrap], reference_wrapper ++ using std::reference_wrapper; ++ ++ using std::cref; ++ using std::ref; ++ ++ // [arithmetic.operations], arithmetic operations ++ using std::divides; ++ using std::minus; ++ using std::modulus; ++ using std::multiplies; ++ using std::negate; ++ using std::plus; ++ // [comparisons], comparisons ++ using std::equal_to; ++ using std::greater; ++ using std::greater_equal; ++ using std::less; ++ using std::less_equal; ++ using std::not_equal_to; ++ ++ // [comparisons.three.way], class compare_three_way ++ using std::compare_three_way; ++ ++ // [logical.operations], logical operations ++ using std::logical_and; ++ using std::logical_not; ++ using std::logical_or; ++ ++ // [bitwise.operations], bitwise operations ++ using std::bit_and; ++ using std::bit_not; ++ using std::bit_or; ++ using std::bit_xor; ++ ++ // [func.identity], identity ++ using std::identity; ++ ++ // [func.not.fn], function template not_fn ++ using std::not_fn; ++ ++ // [func.bind.partial], function templates bind_front and bind_back ++ // using std::bind_back; not implemented ++ using std::bind_front; ++ ++ // [func.bind], bind ++ using std::is_bind_expression; ++ using std::is_bind_expression_v; ++ using std::is_placeholder; ++ using std::is_placeholder_v; ++ ++ using std::bind; ++ ++ // Blocked by D143797 ++#if 0 ++ namespace placeholders { ++ // M is the implementation-defined number of placeholders ++ using std::placeholders::_1; ++ using std::placeholders::_10; ++ using std::placeholders::_2; ++ using std::placeholders::_3; ++ using std::placeholders::_4; ++ using std::placeholders::_5; ++ using std::placeholders::_6; ++ using std::placeholders::_7; ++ using std::placeholders::_8; ++ using std::placeholders::_9; ++ } // namespace placeholders ++#endif ++ // [func.memfn], member function adaptors ++ using std::mem_fn; ++ ++ // [func.wrap], polymorphic function wrappers ++ using std::bad_function_call; ++ ++ using std::function; ++ ++ using std::swap; ++ ++ using std::operator==; ++ ++ // [func.wrap.move], move only wrapper ++ // using std::move_only_function; not implemented ++ ++ // [func.search], searchers ++ using std::default_searcher; ++ ++ using std::boyer_moore_searcher; ++ ++ using std::boyer_moore_horspool_searcher; ++ ++ // [unord.hash], class template hash ++ using std::hash; ++ ++ namespace ranges { ++ // [range.cmp], concept-constrained comparisons ++ using std::ranges::equal_to; ++ using std::ranges::greater; ++ using std::ranges::greater_equal; ++ using std::ranges::less; ++ using std::ranges::less_equal; ++ using std::ranges::not_equal_to; ++ } // namespace ranges ++ ++} // namespace std +diff --git a/libcxx/modules/std/future.cppm b/libcxx/modules/std/future.cppm +new file mode 100644 +index 000000000000..c49df101a7e8 +--- /dev/null ++++ b/libcxx/modules/std/future.cppm +@@ -0,0 +1,62 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:future; ++export namespace std { ++ ++ using std::future_errc; ++ using std::future_status; ++ using std::launch; ++ ++ // launch is a bitmask type. ++ // [bitmask.types] specified operators ++ using std::operator&; ++ using std::operator&=; ++ using std::operator^; ++ using std::operator^=; ++ using std::operator|; ++ using std::operator|=; ++ using std::operator~; ++ ++ // [futures.errors], error handling ++ using std::is_error_code_enum; ++ using std::make_error_code; ++ using std::make_error_condition; ++ ++ using std::future_category; ++ ++ // [futures.future.error], class future_error ++ using std::future_error; ++ ++ // [futures.promise], class template promise ++ using std::promise; ++ ++ using std::swap; ++ ++ using std::uses_allocator; ++ ++ // [futures.unique.future], class template future ++ using std::future; ++ ++ // [futures.shared.future], class template shared_future ++ using std::shared_future; ++ ++ // [futures.task], class template packaged_task ++ using std::packaged_task; ++ ++ using std::swap; ++ ++ // [futures.async], function template async ++ using std::async; ++ ++} // namespace std +diff --git a/libcxx/modules/std/generator.cppm b/libcxx/modules/std/generator.cppm +new file mode 100644 +index 000000000000..7ccbeaaf5c85 +--- /dev/null ++++ b/libcxx/modules/std/generator.cppm +@@ -0,0 +1,22 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:generator; ++export namespace std { ++#if 0 ++ using std::generator; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/initializer_list.cppm b/libcxx/modules/std/initializer_list.cppm +new file mode 100644 +index 000000000000..50dc219bc9bc +--- /dev/null ++++ b/libcxx/modules/std/initializer_list.cppm +@@ -0,0 +1,21 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:initializer_list; ++export namespace std { ++ using std::initializer_list; ++ ++ // [support.initlist.range], initializer list range access ++ using std::begin; ++ using std::end; ++} // namespace std +diff --git a/libcxx/modules/std/iomanip.cppm b/libcxx/modules/std/iomanip.cppm +new file mode 100644 +index 000000000000..361738eebe19 +--- /dev/null ++++ b/libcxx/modules/std/iomanip.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:iomanip; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::get_money; ++ using std::get_time; ++ using std::put_money; ++ using std::put_time; ++ using std::resetiosflags; ++ using std::setbase; ++ using std::setfill; ++ using std::setiosflags; ++ using std::setprecision; ++ using std::setw; ++ ++ using std::quoted; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/ios.cppm b/libcxx/modules/std/ios.cppm +new file mode 100644 +index 000000000000..8710b743b4d0 +--- /dev/null ++++ b/libcxx/modules/std/ios.cppm +@@ -0,0 +1,80 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:ios; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::fpos; ++ // based on [tab:fpos.operations] ++ using std::operator!=; // Note not affected by P1614, seems like a bug. ++ using std::operator-; ++ using std::operator==; ++ ++ using std::streamoff; ++ using std::streamsize; ++ ++ using std::basic_ios; ++ using std::ios_base; ++ ++ // [std.ios.manip], manipulators ++ using std::boolalpha; ++ using std::noboolalpha; ++ ++ using std::noshowbase; ++ using std::showbase; ++ ++ using std::noshowpoint; ++ using std::showpoint; ++ ++ using std::noshowpos; ++ using std::showpos; ++ ++ using std::noskipws; ++ using std::skipws; ++ ++ using std::nouppercase; ++ using std::uppercase; ++ ++ using std::nounitbuf; ++ using std::unitbuf; ++ ++ // [adjustfield.manip], adjustfield ++ using std::internal; ++ using std::left; ++ using std::right; ++ ++ // [basefield.manip], basefield ++ using std::dec; ++ using std::hex; ++ using std::oct; ++ ++ // [floatfield.manip], floatfield ++ using std::defaultfloat; ++ using std::fixed; ++ using std::hexfloat; ++ using std::scientific; ++ ++ // [error.reporting], error reporting ++ using std::io_errc; ++ ++ using std::iostream_category; ++ using std::is_error_code_enum; ++ using std::make_error_code; ++ using std::make_error_condition; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/iosfwd.cppm b/libcxx/modules/std/iosfwd.cppm +new file mode 100644 +index 000000000000..7c76e12fe14e +--- /dev/null ++++ b/libcxx/modules/std/iosfwd.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:iosfwd; ++export namespace std { ++ // All symbols are exported by other modules. ++} // namespace std +diff --git a/libcxx/modules/std/iostream.cppm b/libcxx/modules/std/iostream.cppm +new file mode 100644 +index 000000000000..a3d3e20257fc +--- /dev/null ++++ b/libcxx/modules/std/iostream.cppm +@@ -0,0 +1,34 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:iostream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::cerr; ++ using std::cin; ++ using std::clog; ++ using std::cout; ++ ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wcerr; ++ using std::wcin; ++ using std::wclog; ++ using std::wcout; ++# endif ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/istream.cppm b/libcxx/modules/std/istream.cppm +new file mode 100644 +index 000000000000..f3d6cd4b1883 +--- /dev/null ++++ b/libcxx/modules/std/istream.cppm +@@ -0,0 +1,40 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:istream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::basic_istream; ++ ++ using std::istream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wistream; ++# endif ++ ++ using std::basic_iostream; ++ ++ using std::iostream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wiostream; ++# endif ++ ++ using std::ws; ++ ++ using std::operator>>; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/iterator.cppm b/libcxx/modules/std/iterator.cppm +new file mode 100644 +index 000000000000..05566242bd7c +--- /dev/null ++++ b/libcxx/modules/std/iterator.cppm +@@ -0,0 +1,252 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:iterator; ++export namespace std { ++ ++ // [iterator.assoc.types], associated types ++ // [incrementable.traits], incrementable traits ++ using std::incrementable_traits; ++ using std::iter_difference_t; ++ ++ using std::indirectly_readable_traits; ++ using std::iter_value_t; ++ ++ // [iterator.traits], iterator traits ++ using std::iterator_traits; ++ ++ using std::iter_reference_t; ++ ++ namespace ranges { ++ // [iterator.cust], customization point objects ++ inline namespace __cpo { ++ // [iterator.cust.move], ranges::iter_move ++ using std::ranges::__cpo::iter_move; ++ ++ // [iterator.cust.swap], ranges::iter_swap ++ using std::ranges::__cpo::iter_swap; ++ } // namespace __cpo ++ } // namespace ranges ++ ++ using std::iter_rvalue_reference_t; ++ ++ // [iterator.concepts], iterator concepts ++ // [iterator.concept.readable], concept indirectly_readable ++ using std::indirectly_readable; ++ ++ using std::iter_common_reference_t; ++ ++ // [iterator.concept.writable], concept indirectly_writable ++ using std::indirectly_writable; ++ ++ // [iterator.concept.winc], concept weakly_incrementable ++ using std::weakly_incrementable; ++ ++ // [iterator.concept.inc], concept incrementable ++ using std::incrementable; ++ ++ // [iterator.concept.iterator], concept input_or_output_iterator ++ using std::input_or_output_iterator; ++ ++ // [iterator.concept.sentinel], concept sentinel_for ++ using std::sentinel_for; ++ ++ // [iterator.concept.sizedsentinel], concept sized_sentinel_for ++ using std::disable_sized_sentinel_for; ++ ++ using std::sized_sentinel_for; ++ ++ // [iterator.concept.input], concept input_iterator ++ using std::input_iterator; ++ ++ // [iterator.concept.output], concept output_iterator ++ using std::output_iterator; ++ ++ // [iterator.concept.forward], concept forward_iterator ++ using std::forward_iterator; ++ ++ // [iterator.concept.bidir], concept bidirectional_iterator ++ using std::bidirectional_iterator; ++ ++ // [iterator.concept.random.access], concept random_access_iterator ++ using std::random_access_iterator; ++ ++ // [iterator.concept.contiguous], concept contiguous_iterator ++ using std::contiguous_iterator; ++ ++ // [indirectcallable], indirect callable requirements ++ // [indirectcallable.indirectinvocable], indirect callables ++ using std::indirectly_unary_invocable; ++ ++ using std::indirectly_regular_unary_invocable; ++ ++ using std::indirect_unary_predicate; ++ ++ using std::indirect_binary_predicate; ++ ++ using std::indirect_equivalence_relation; ++ ++ using std::indirect_strict_weak_order; ++ ++ using std::indirect_result_t; ++ ++ // [projected], projected ++ using std::projected; ++ ++ using std::incrementable_traits; ++ ++ // [alg.req], common algorithm requirements ++ // [alg.req.ind.move], concept indirectly_movable ++ using std::indirectly_movable; ++ ++ using std::indirectly_movable_storable; ++ ++ // [alg.req.ind.copy], concept indirectly_copyable ++ using std::indirectly_copyable; ++ ++ using std::indirectly_copyable_storable; ++ ++ // [alg.req.ind.swap], concept indirectly_swappable ++ using std::indirectly_swappable; ++ ++ // [alg.req.ind.cmp], concept indirectly_comparable ++ using std::indirectly_comparable; ++ ++ // [alg.req.permutable], concept permutable ++ using std::permutable; ++ ++ // [alg.req.mergeable], concept mergeable ++ using std::mergeable; ++ ++ // [alg.req.sortable], concept sortable ++ using std::sortable; ++ ++ // [iterator.primitives], primitives ++ // [std.iterator.tags], iterator tags ++ using std::bidirectional_iterator_tag; ++ using std::contiguous_iterator_tag; ++ using std::forward_iterator_tag; ++ using std::input_iterator_tag; ++ using std::output_iterator_tag; ++ using std::random_access_iterator_tag; ++ ++ // [iterator.operations], iterator operations ++ using std::advance; ++ using std::distance; ++ using std::next; ++ using std::prev; ++ ++ // [range.iter.ops], range iterator operations ++ namespace ranges { ++ // [range.iter.op.advance], ranges​::​advance ++ using std::ranges::advance; ++ ++ // [range.iter.op.distance], ranges​::​distance ++ using std::ranges::distance; ++ ++ // [range.iter.op.next], ranges​::​next ++ using std::ranges::next; ++ ++ // [range.iter.op.prev], ranges​::​prev ++ using std::ranges::prev; ++ } // namespace ranges ++ ++ // [predef.iterators], predefined iterators and sentinels ++ // [reverse.iterators], reverse iterators ++ using std::reverse_iterator; ++ ++ using std::operator==; ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ using std::operator<=>; ++ ++ using std::operator-; ++ using std::operator+; ++ ++ using std::make_reverse_iterator; ++ ++ //using std::disable_sized_sentinel_for; ++ ++ // [insert.iterators], insert iterators ++ using std::back_insert_iterator; ++ using std::back_inserter; ++ ++ using std::front_insert_iterator; ++ using std::front_inserter; ++ ++ using std::insert_iterator; ++ using std::inserter; ++ ++ // [const.iterators], constant iterators and sentinels ++ // [const.iterators.alias], alias templates ++ // using std::const_iterator; NOT IMPLEMENTED ++ // using std::const_sentinel; NOT IMPLEMENTED ++ // using std::iter_const_reference_t; NOT IMPLEMENTED? ++ ++ // [const.iterators.iterator], class template basic_const_iterator ++ // using std::basic_const_iterator; NOT IMPLEMENTED ++ ++ using std::common_type; ++ ++ // using std::make_const_iterator; NOT IMPLEMENTED ++ ++ // [move.iterators], move iterators and sentinels ++ using std::move_iterator; // freestanding ++ ++ using std::make_move_iterator; ++ ++ using std::move_sentinel; ++ ++ using std::common_iterator; ++ ++ using std::incrementable_traits; ++ ++ // [default.sentinel], default sentinel ++ using std::default_sentinel; ++ using std::default_sentinel_t; ++ ++ // [iterators.counted], counted iterators ++ using std::counted_iterator; ++ ++ // [unreachable.sentinel], unreachable sentinel ++ using std::unreachable_sentinel; ++ using std::unreachable_sentinel_t; ++ ++ // [stream.iterators], stream iterators ++ using std::istream_iterator; ++ ++ using std::ostream_iterator; ++ ++ using std::istreambuf_iterator; ++ using std::ostreambuf_iterator; ++ ++ // [iterator.range], range access ++ using std::begin; ++ using std::cbegin; ++ using std::cend; ++ using std::crbegin; ++ using std::crend; ++ using std::end; ++ using std::rbegin; ++ using std::rend; ++ ++ using std::empty; ++ using std::size; ++ using std::ssize; ++ ++ using std::data; ++ ++} // namespace std +diff --git a/libcxx/modules/std/latch.cppm b/libcxx/modules/std/latch.cppm +new file mode 100644 +index 000000000000..e9d793c16f72 +--- /dev/null ++++ b/libcxx/modules/std/latch.cppm +@@ -0,0 +1,18 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:latch; ++export namespace std { ++ using std::latch; ++ ++} // namespace std +diff --git a/libcxx/modules/std/limits.cppm b/libcxx/modules/std/limits.cppm +new file mode 100644 +index 000000000000..cc0fffeaf4f9 +--- /dev/null ++++ b/libcxx/modules/std/limits.cppm +@@ -0,0 +1,24 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:limits; ++export namespace std { ++ ++ // [fp.style], floating-point type properties ++ using std::float_denorm_style; ++ using std::float_round_style; ++ ++ // [numeric.limits], class template numeric_­limits ++ using std::numeric_limits; ++ ++} // namespace std +diff --git a/libcxx/modules/std/list.cppm b/libcxx/modules/std/list.cppm +new file mode 100644 +index 000000000000..0f3ea8db21da +--- /dev/null ++++ b/libcxx/modules/std/list.cppm +@@ -0,0 +1,33 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:list; ++export namespace std { ++ ++ // [list], class template list ++ using std::list; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ ++ // [list.erasure], erasure ++ using std::erase; ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::list; ++ } ++ ++} // namespace std +diff --git a/libcxx/modules/std/locale.cppm b/libcxx/modules/std/locale.cppm +new file mode 100644 +index 000000000000..67f06eb0fe0b +--- /dev/null ++++ b/libcxx/modules/std/locale.cppm +@@ -0,0 +1,86 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:locale; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ // [locale], locale ++ using std::has_facet; ++ using std::locale; ++ using std::use_facet; ++ ++ // [locale.convenience], convenience interfaces ++ using std::isalnum; ++ using std::isalpha; ++ using std::isblank; ++ using std::iscntrl; ++ using std::isdigit; ++ using std::isgraph; ++ using std::islower; ++ using std::isprint; ++ using std::ispunct; ++ using std::isspace; ++ using std::isupper; ++ using std::isxdigit; ++ using std::tolower; ++ using std::toupper; ++ ++ // [category.ctype], ctype ++ using std::codecvt; ++ using std::codecvt_base; ++ using std::codecvt_byname; ++ using std::ctype; ++ using std::ctype_base; ++ using std::ctype_byname; ++ ++ // [category.numeric], numeric ++ using std::num_get; ++ using std::num_put; ++ using std::numpunct; ++ using std::numpunct_byname; ++ ++ // [category.collate], collation ++ using std::collate; ++ using std::collate_byname; ++ ++ // [category.time], date and time ++ using std::time_base; ++ using std::time_get; ++ using std::time_get_byname; ++ using std::time_put; ++ using std::time_put_byname; ++ ++ // [category.monetary], money ++ using std::money_base; ++ using std::money_get; ++ using std::money_put; ++ using std::moneypunct; ++ using std::moneypunct_byname; ++ ++ // [category.messages], message retrieval ++ using std::messages; ++ using std::messages_base; ++ using std::messages_byname; ++ ++ // [depr.conversions.buffer] ++ using std::wbuffer_convert; ++ ++ // [depr.conversions.string] ++ using std::wstring_convert; ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/map.cppm b/libcxx/modules/std/map.cppm +new file mode 100644 +index 000000000000..69a156ba4c59 +--- /dev/null ++++ b/libcxx/modules/std/map.cppm +@@ -0,0 +1,38 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:map; ++export namespace std { ++ // [map], class template map ++ using std::map; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ ++ // [map.erasure], erasure for map ++ using std::erase_if; ++ ++ // [multimap], class template multimap ++ using std::multimap; ++ ++ // [multimap.erasure], erasure for multimap ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::map; ++ using std::pmr::multimap; ++ } // namespace pmr ++ ++} // namespace std +diff --git a/libcxx/modules/std/mdspan.cppm b/libcxx/modules/std/mdspan.cppm +new file mode 100644 +index 000000000000..4ee3931c6e52 +--- /dev/null ++++ b/libcxx/modules/std/mdspan.cppm +@@ -0,0 +1,37 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:mdspan; ++export namespace std { ++#if 0 ++ // [mdspan.extents], class template extents ++ using std::extents; ++ ++ // [mdspan.extents.dextents], alias template dextents ++ using std::dextents; ++ ++ // [mdspan.layout], layout mapping ++ using std::layout_left; ++ using std::layout_right; ++ using std::layout_stride; ++ ++ // [mdspan.accessor.default], class template default_­accessor ++ using std::default_accessor; ++ ++ // [mdspan.mdspan], class template mdspan ++ using std::mdspan; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/memory.cppm b/libcxx/modules/std/memory.cppm +new file mode 100644 +index 000000000000..ad9760d7cada +--- /dev/null ++++ b/libcxx/modules/std/memory.cppm +@@ -0,0 +1,215 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:memory; ++export namespace std { ++ // [pointer.traits], pointer traits ++ using std::pointer_traits; ++ ++ // [pointer.conversion], pointer conversion ++ using std::to_address; ++ ++ // [ptr.align], pointer alignment ++ using std::align; ++ using std::assume_aligned; ++ ++ // [obj.lifetime], explicit lifetime management ++ // using std::start_lifetime_as; NOT IMPLEMENTED ++ // using std::start_lifetime_as_array NOT IMPLEMENTED; ++ ++ // [allocator.tag], allocator argument tag ++ // using std::allocator_arg; TODO INTERNAL LINKAGE ++ // using std::allocator_arg_t TODO INTERNAL LINKAGE; ++ ++ // [allocator.uses], uses_allocator ++ using std::uses_allocator; ++ ++ // [allocator.uses.trait], uses_allocator ++ using std::uses_allocator_v; ++ ++ // [allocator.uses.construction], uses-allocator construction ++ using std::uses_allocator_construction_args; ++ ++ using std::make_obj_using_allocator; ++ using std::uninitialized_construct_using_allocator; ++ ++ // [allocator.traits], allocator traits ++ using std::allocator_traits; // freestanding ++ ++ using std::allocation_result; ++ ++ using std::allocate_at_least; ++ ++ // [default.allocator], the default allocator ++ using std::allocator; ++ using std::operator==; ++ ++ // [specialized.addressof], addressof ++ using std::addressof; ++ ++ // [specialized.algorithms], specialized algorithms ++ // [special.mem.concepts], special memory concepts ++ ++ using std::uninitialized_default_construct; ++ using std::uninitialized_default_construct_n; ++ ++ namespace ranges { ++ using std::ranges::uninitialized_default_construct; ++ using std::ranges::uninitialized_default_construct_n; ++ } // namespace ranges ++ ++ using std::uninitialized_value_construct; ++ using std::uninitialized_value_construct_n; ++ ++ namespace ranges { ++ using std::ranges::uninitialized_value_construct; ++ using std::ranges::uninitialized_value_construct_n; ++ } // namespace ranges ++ ++ using std::uninitialized_copy; ++ using std::uninitialized_copy_n; ++ ++ namespace ranges { ++ using std::ranges::uninitialized_copy; ++ using std::ranges::uninitialized_copy_result; ++ ++ using std::ranges::uninitialized_copy_n; ++ using std::ranges::uninitialized_copy_n_result; ++ ++ } // namespace ranges ++ using std::uninitialized_move; ++ using std::uninitialized_move_n; ++ ++ namespace ranges { ++ using std::ranges::uninitialized_move; ++ using std::ranges::uninitialized_move_result; ++ ++ using std::ranges::uninitialized_move_n; ++ using std::ranges::uninitialized_move_n_result; ++ ++ } // namespace ranges ++ ++ using std::uninitialized_fill; ++ using std::uninitialized_fill_n; ++ ++ namespace ranges { ++ using std::ranges::uninitialized_fill; ++ using std::ranges::uninitialized_fill_n; ++ } // namespace ranges ++ ++ // [specialized.construct], construct_at ++ using std::construct_at; ++ ++ namespace ranges { ++ using std::ranges::construct_at; ++ } ++ // [specialized.destroy], destroy ++ using std::destroy; ++ using std::destroy_at; ++ using std::destroy_n; ++ ++ namespace ranges { ++ using std::ranges::destroy; ++ using std::ranges::destroy_at; ++ using std::ranges::destroy_n; ++ } // namespace ranges ++ // [unique.ptr], class template unique_ptr ++ using std::default_delete; ++ using std::unique_ptr; ++ ++ using std::make_unique; ++ using std::make_unique_for_overwrite; ++ ++ using std::swap; ++ ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ using std::operator<=>; ++ ++ using std::operator<<; ++ ++ // [util.smartptr.weak.bad], class bad_weak_ptr ++ using std::bad_weak_ptr; ++ ++ // [util.smartptr.shared], class template shared_ptr ++ using std::shared_ptr; ++ ++ // [util.smartptr.shared.create], shared_ptr creation ++ using std::allocate_shared; ++ using std::allocate_shared_for_overwrite; ++ using std::make_shared; ++ using std::make_shared_for_overwrite; ++ ++ // [util.smartptr.shared.spec], shared_ptr specialized algorithms ++ using std::swap; ++ ++ // [util.smartptr.shared.cast], shared_ptr casts ++ using std::const_pointer_cast; ++ using std::dynamic_pointer_cast; ++ using std::reinterpret_pointer_cast; ++ using std::static_pointer_cast; ++ ++ using std::get_deleter; ++ ++ // [util.smartptr.shared.io], shared_ptr I/O ++ ++ // [util.smartptr.weak], class template weak_ptr ++ using std::weak_ptr; ++ ++ // [util.smartptr.weak.spec], weak_ptr specialized algorithms ++ ++ // [util.smartptr.ownerless], class template owner_less ++ using std::owner_less; ++ ++ // [util.smartptr.enab], class template enable_shared_from_this ++ using std::enable_shared_from_this; ++ ++ // [util.smartptr.hash], hash support ++ using std::hash; ++ ++ // [util.smartptr.atomic], atomic smart pointers ++ using std::atomic; ++ ++ // [out.ptr.t], class template out_ptr_t ++ // using std::out_ptr_t NOT IMPLEMENTED; ++ ++ // [out.ptr], function template out_ptr ++ // using std::out_ptr NOT IMPLEMENTED; ++ ++ // [inout.ptr.t], class template inout_ptr_t ++ // using std::inout_ptr_t NOT IMPLEMENTED; ++ ++ // [inout.ptr], function template inout_ptr ++ // using std::inout_ptr NOT IMPLEMENTED; ++ ++ // [depr.util.smartptr.shared.atomic] ++ using std::atomic_is_lock_free; ++ ++ using std::atomic_load; ++ using std::atomic_load_explicit; ++ ++ using std::atomic_store; ++ using std::atomic_store_explicit; ++ ++ using std::atomic_exchange; ++ using std::atomic_exchange_explicit; ++ ++ using std::atomic_compare_exchange_strong; ++ using std::atomic_compare_exchange_strong_explicit; ++ using std::atomic_compare_exchange_weak; ++ using std::atomic_compare_exchange_weak_explicit; ++ ++} // namespace std +diff --git a/libcxx/modules/std/memory_resource.cppm b/libcxx/modules/std/memory_resource.cppm +new file mode 100644 +index 000000000000..3bf0834e7199 +--- /dev/null ++++ b/libcxx/modules/std/memory_resource.cppm +@@ -0,0 +1,37 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:memory_resource; ++export namespace std::pmr { ++ ++ // [mem.res.class], class memory_resource ++ using std::pmr::memory_resource; ++ ++ using std::pmr::operator==; ++ ++ // [mem.poly.allocator.class], class template polymorphic_allocator ++ using std::pmr::polymorphic_allocator; ++ ++ // [mem.res.global], global memory resources ++ using std::pmr::get_default_resource; ++ using std::pmr::new_delete_resource; ++ using std::pmr::null_memory_resource; ++ using std::pmr::set_default_resource; ++ ++ // [mem.res.pool], pool resource classes ++ using std::pmr::monotonic_buffer_resource; ++ using std::pmr::pool_options; ++ using std::pmr::synchronized_pool_resource; ++ using std::pmr::unsynchronized_pool_resource; ++ ++} // namespace std::pmr +diff --git a/libcxx/modules/std/mutex.cppm b/libcxx/modules/std/mutex.cppm +new file mode 100644 +index 000000000000..0dbf05bf757d +--- /dev/null ++++ b/libcxx/modules/std/mutex.cppm +@@ -0,0 +1,49 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:mutex; ++export namespace std { ++ ++ // [thread.mutex.class], class mutex ++ using std::mutex; ++ // [thread.mutex.recursive], class recursive_mutex ++ using std::recursive_mutex; ++ // [thread.timedmutex.class] class timed_mutex ++ using std::timed_mutex; ++ // [thread.timedmutex.recursive], class recursive_timed_mutex ++ using std::recursive_timed_mutex; ++ ++ using std::adopt_lock_t; ++ using std::defer_lock_t; ++ using std::try_to_lock_t; ++ ++ // using std::adopt_lock; internal linkage ++ // using std::defer_lock; internal linkage ++ // using std::try_to_lock; internal linkage ++ ++ // [thread.lock], locks ++ using std::lock_guard; ++ using std::scoped_lock; ++ using std::unique_lock; ++ ++ using std::swap; ++ ++ // [thread.lock.algorithm], generic locking algorithms ++ using std::lock; ++ using std::try_lock; ++ ++ using std::once_flag; ++ ++ using std::call_once; ++ ++} // namespace std +diff --git a/libcxx/modules/std/new.cppm b/libcxx/modules/std/new.cppm +new file mode 100644 +index 000000000000..7f349f7f8af2 +--- /dev/null ++++ b/libcxx/modules/std/new.cppm +@@ -0,0 +1,49 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:__new; // Note new is a keyword and not a valid identifier ++export namespace std { ++ ++ // [alloc.errors], storage allocation errors ++ using std::bad_alloc; ++ using std::bad_array_new_length; ++ ++ using std::destroying_delete; ++ using std::destroying_delete_t; ++ ++ // global operator new control ++ using std::align_val_t; ++ ++ using std::nothrow; ++ using std::nothrow_t; ++ ++ using std::get_new_handler; ++ using std::new_handler; ++ using std::set_new_handler; ++ ++ // [ptr.launder], pointer optimization barrier ++ using std::launder; ++ ++#if 0 // This has not been implemented yet ++ // [hardware.interference], hardware interference size ++ using std::hardware_constructive_interference_size; ++ using std::hardware_destructive_interference_size; ++#endif ++} // namespace std ++ ++export { ++ using ::operator new; ++ using ::operator delete; ++ using ::operator new[]; ++ using ::operator delete[]; ++} // export +diff --git a/libcxx/modules/std/numbers.cppm b/libcxx/modules/std/numbers.cppm +new file mode 100644 +index 000000000000..82c9abdcc592 +--- /dev/null ++++ b/libcxx/modules/std/numbers.cppm +@@ -0,0 +1,57 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:numbers; ++export namespace std::numbers { ++ using std::numbers::e_v; ++ using std::numbers::egamma_v; ++ using std::numbers::inv_pi_v; ++ using std::numbers::inv_sqrt3_v; ++ using std::numbers::inv_sqrtpi_v; ++ using std::numbers::ln10_v; ++ using std::numbers::ln2_v; ++ using std::numbers::log10e_v; ++ using std::numbers::log2e_v; ++ using std::numbers::phi_v; ++ using std::numbers::pi_v; ++ using std::numbers::sqrt2_v; ++ using std::numbers::sqrt3_v; ++ ++ using std::numbers::e_v; ++ using std::numbers::egamma_v; ++ using std::numbers::inv_pi_v; ++ using std::numbers::inv_sqrt3_v; ++ using std::numbers::inv_sqrtpi_v; ++ using std::numbers::ln10_v; ++ using std::numbers::ln2_v; ++ using std::numbers::log10e_v; ++ using std::numbers::log2e_v; ++ using std::numbers::phi_v; ++ using std::numbers::pi_v; ++ using std::numbers::sqrt2_v; ++ using std::numbers::sqrt3_v; ++ ++ using std::numbers::e; ++ using std::numbers::egamma; ++ using std::numbers::inv_pi; ++ using std::numbers::inv_sqrt3; ++ using std::numbers::inv_sqrtpi; ++ using std::numbers::ln10; ++ using std::numbers::ln2; ++ using std::numbers::log10e; ++ using std::numbers::log2e; ++ using std::numbers::phi; ++ using std::numbers::pi; ++ using std::numbers::sqrt2; ++ using std::numbers::sqrt3; ++} // namespace std::numbers +diff --git a/libcxx/modules/std/numeric.cppm b/libcxx/modules/std/numeric.cppm +new file mode 100644 +index 000000000000..6a6f000d18b3 +--- /dev/null ++++ b/libcxx/modules/std/numeric.cppm +@@ -0,0 +1,64 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:numeric; ++export namespace std { ++ ++ // [accumulate], accumulate ++ using std::accumulate; ++ ++ // [reduce], reduce ++ using std::reduce; ++ ++ // [inner.product], inner product ++ using std::inner_product; ++ ++ // [transform.reduce], transform reduce ++ using std::transform_reduce; ++ ++ // [partial.sum], partial sum ++ using std::partial_sum; ++ ++ // [exclusive.scan], exclusive scan ++ using std::exclusive_scan; ++ ++ // [inclusive.scan], inclusive scan ++ using std::inclusive_scan; ++ ++ // [transform.exclusive.scan], transform exclusive scan ++ using std::transform_exclusive_scan; ++ ++ // [transform.inclusive.scan], transform inclusive scan ++ using std::transform_inclusive_scan; ++ ++ // [adjacent.difference], adjacent difference ++ using std::adjacent_difference; ++ ++ // [numeric.iota], iota ++ using std::iota; ++ ++ namespace ranges { ++ // using std::ranges::iota_result; NOT YET IMPLEMENTED ++ // using std::ranges::iota; NOT YET IMPLEMENTED ++ } // namespace ranges ++ ++ // [numeric.ops.gcd], greatest common divisor ++ using std::gcd; ++ ++ // [numeric.ops.lcm], least common multiple ++ using std::lcm; ++ ++ // [numeric.ops.midpoint], midpoint ++ using std::midpoint; ++ ++} // namespace std +diff --git a/libcxx/modules/std/optional.cppm b/libcxx/modules/std/optional.cppm +new file mode 100644 +index 000000000000..b298133dfd3c +--- /dev/null ++++ b/libcxx/modules/std/optional.cppm +@@ -0,0 +1,48 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:optional; ++export namespace std { ++ ++ // [optional.optional], class template optional ++ using std::optional; ++ ++ // [optional.nullopt], no-value state indicator ++ using std::nullopt; ++ using std::nullopt_t; ++ ++ // [optional.bad.access], class bad_optional_access ++ using std::bad_optional_access; ++ ++ // [optional.relops], relational operators ++ using std::operator==; ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ using std::operator<=>; ++ ++ // [optional.nullops], comparison with nullopt ++ ++ // [optional.comp.with.t], comparison with T ++ ++ // [optional.specalg], specialized algorithms ++ using std::swap; ++ ++ using std::make_optional; ++ ++ // [optional.hash], hash support ++ using std::hash; ++ ++} // namespace std +diff --git a/libcxx/modules/std/ostream.cppm b/libcxx/modules/std/ostream.cppm +new file mode 100644 +index 000000000000..2e0a475811a7 +--- /dev/null ++++ b/libcxx/modules/std/ostream.cppm +@@ -0,0 +1,48 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:ostream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::basic_ostream; ++ ++ using std::ostream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wostream; ++# endif ++ ++ using std::endl; ++ using std::ends; ++ using std::flush; ++ ++# if 0 ++ using std::emit_on_flush; ++ using std::flush_emit; ++ using std::noemit_on_flush; ++# endif ++ using std::operator<<; ++ ++# if 0 ++ // [ostream.formatted.print], print functions ++ using std::print; ++ using std::println; ++ ++ using std::vprint_nonunicode; ++ using std::vprint_unicode; ++# endif ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/print.cppm b/libcxx/modules/std/print.cppm +new file mode 100644 +index 000000000000..0dac901d1824 +--- /dev/null ++++ b/libcxx/modules/std/print.cppm +@@ -0,0 +1,28 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:print; ++export namespace std { ++#if 0 ++ // [print.fun], print functions ++ using std::print; ++ using std::println; ++ ++ using std::vprint_unicode; ++ ++ using std::vprint_nonunicode; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/queue.cppm b/libcxx/modules/std/queue.cppm +new file mode 100644 +index 000000000000..b506f029b5ac +--- /dev/null ++++ b/libcxx/modules/std/queue.cppm +@@ -0,0 +1,32 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:queue; ++export namespace std { ++ ++ // [queue], class template queue ++ using std::queue; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ using std::uses_allocator; ++ ++ // [priority.queue], class template priority_queue ++ using std::priority_queue; ++ ++ // Note formatter not in synopsis ++ // TODO Test whether the ommission fails tests. ++ ++} // namespace std +diff --git a/libcxx/modules/std/random.cppm b/libcxx/modules/std/random.cppm +new file mode 100644 +index 000000000000..a3efa497c5bb +--- /dev/null ++++ b/libcxx/modules/std/random.cppm +@@ -0,0 +1,120 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:random; ++export namespace std { ++ ++ // [rand.req.urng], uniform random bit generator requirements ++ using std::uniform_random_bit_generator; ++ ++ // [rand.eng.lcong], class template linear_congruential_engine ++ using std::linear_congruential_engine; ++ ++ // [rand.eng.mers], class template mersenne_twister_engine ++ using std::mersenne_twister_engine; ++ ++ // [rand.eng.sub], class template subtract_with_carry_engine ++ using std::subtract_with_carry_engine; ++ ++ // [rand.adapt.disc], class template discard_block_engine ++ using std::discard_block_engine; ++ ++ // [rand.adapt.ibits], class template independent_bits_engine ++ using std::independent_bits_engine; ++ ++ // [rand.adapt.shuf], class template shuffle_order_engine ++ using std::shuffle_order_engine; ++ ++ // [rand.predef], engines and engine adaptors with predefined parameters ++ using std::knuth_b; ++ using std::minstd_rand; ++ using std::minstd_rand0; ++ using std::mt19937; ++ using std::mt19937_64; ++ using std::ranlux24; ++ using std::ranlux24_base; ++ using std::ranlux48; ++ using std::ranlux48_base; ++ ++ using std::default_random_engine; ++ ++ // [rand.device], class random_device ++ using std::random_device; ++ ++ // [rand.util.seedseq], class seed_seq ++ using std::seed_seq; ++ ++ // [rand.util.canonical], function template generate_canonical ++ using std::generate_canonical; ++ ++ // [rand.dist.uni.int], class template uniform_int_distribution ++ using std::uniform_int_distribution; ++ ++ // [rand.dist.uni.real], class template uniform_real_distribution ++ using std::uniform_real_distribution; ++ ++ // [rand.dist.bern.bernoulli], class bernoulli_distribution ++ using std::bernoulli_distribution; ++ ++ // [rand.dist.bern.bin], class template binomial_distribution ++ using std::binomial_distribution; ++ ++ // [rand.dist.bern.geo], class template geometric_distribution ++ using std::geometric_distribution; ++ ++ // [rand.dist.bern.negbin], class template negative_binomial_distribution ++ using std::negative_binomial_distribution; ++ ++ // [rand.dist.pois.poisson], class template poisson_distribution ++ using std::poisson_distribution; ++ ++ // [rand.dist.pois.exp], class template exponential_distribution ++ using std::exponential_distribution; ++ ++ // [rand.dist.pois.gamma], class template gamma_distribution ++ using std::gamma_distribution; ++ ++ // [rand.dist.pois.weibull], class template weibull_distribution ++ using std::weibull_distribution; ++ ++ // [rand.dist.pois.extreme], class template extreme_value_distribution ++ using std::extreme_value_distribution; ++ ++ // [rand.dist.norm.normal], class template normal_distribution ++ using std::normal_distribution; ++ ++ // [rand.dist.norm.lognormal], class template lognormal_distribution ++ using std::lognormal_distribution; ++ ++ // [rand.dist.norm.chisq], class template chi_squared_distribution ++ using std::chi_squared_distribution; ++ ++ // [rand.dist.norm.cauchy], class template cauchy_distribution ++ using std::cauchy_distribution; ++ ++ // [rand.dist.norm.f], class template fisher_f_distribution ++ using std::fisher_f_distribution; ++ ++ // [rand.dist.norm.t], class template student_t_distribution ++ using std::student_t_distribution; ++ ++ // [rand.dist.samp.discrete], class template discrete_distribution ++ using std::discrete_distribution; ++ ++ // [rand.dist.samp.pconst], class template piecewise_constant_distribution ++ using std::piecewise_constant_distribution; ++ ++ // [rand.dist.samp.plinear], class template piecewise_linear_distribution ++ using std::piecewise_linear_distribution; ++ ++} // namespace std +diff --git a/libcxx/modules/std/ranges.cppm b/libcxx/modules/std/ranges.cppm +new file mode 100644 +index 000000000000..49a4df838991 +--- /dev/null ++++ b/libcxx/modules/std/ranges.cppm +@@ -0,0 +1,344 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:ranges; ++export namespace std { ++ ++ namespace ranges { ++ ++ inline namespace __cpo { ++ // [range.access], range access ++ using std::ranges::__cpo::begin; ++ using std::ranges::__cpo::cbegin; ++ using std::ranges::__cpo::cend; ++ using std::ranges::__cpo::crbegin; ++ using std::ranges::__cpo::crend; ++ using std::ranges::__cpo::end; ++ using std::ranges::__cpo::rbegin; ++ using std::ranges::__cpo::rend; ++ ++ using std::ranges::__cpo::cdata; ++ using std::ranges::__cpo::data; ++ using std::ranges::__cpo::empty; ++ using std::ranges::__cpo::size; ++ using std::ranges::__cpo::ssize; ++ } // namespace __cpo ++ ++ // [range.range], ranges ++ using std::ranges::range; ++ ++ using std::ranges::enable_borrowed_range; ++ ++ using std::ranges::borrowed_range; ++ ++ // using std::ranges::const_iterator_t; NOT IMPLEMENTED YET ++ // using std::ranges::const_sentinel_t; NOT IMPLEMENTED YET ++ using std::ranges::iterator_t; ++ // using std::ranges::range_const_reference_t; NOT IMPLEMENTED YET ++ using std::ranges::range_difference_t; ++ using std::ranges::range_reference_t; ++ using std::ranges::range_rvalue_reference_t; ++ using std::ranges::range_size_t; ++ using std::ranges::range_value_t; ++ using std::ranges::sentinel_t; ++ ++ // [range.sized], sized ranges ++ using std::ranges::disable_sized_range; ++ using std::ranges::sized_range; ++ ++ // [range.view], views ++ using std::ranges::enable_view; ++ using std::ranges::view; ++ using std::ranges::view_base; ++ ++ // [range.refinements], other range refinements ++ using std::ranges::bidirectional_range; ++ using std::ranges::common_range; ++ // using std::ranges::constant_range; NOT IMPLEMENTED YET ++ using std::ranges::contiguous_range; ++ using std::ranges::forward_range; ++ using std::ranges::input_range; ++ using std::ranges::output_range; ++ using std::ranges::random_access_range; ++ using std::ranges::viewable_range; ++ ++ // [view.interface], class template view_­interface ++ using std::ranges::view_interface; ++ ++ // [range.subrange], sub-ranges ++ using std::ranges::subrange; ++ using std::ranges::subrange_kind; ++ ++ using std::ranges::get; ++ ++ } // namespace ranges ++ ++ using std::ranges::get; ++ ++ namespace ranges { ++ ++ // [range.dangling], dangling iterator handling ++ using std::ranges::dangling; ++ ++ // [range.elementsof], class template elements_­of ++ // using std::ranges::elements_of; NOT IMPLEMENTED YET ++ ++ using std::ranges::borrowed_iterator_t; ++ ++ using std::ranges::borrowed_subrange_t; ++ ++ // [range.utility.conv], range conversions ++ // using std::ranges::to; NOT YET IMPLEMENTED ++ ++ // [range.empty], empty view ++ using std::ranges::empty_view; ++ ++ namespace views { ++ using std::ranges::views::empty; ++ } ++ ++ // [range.single], single view ++ using std::ranges::single_view; // freestanding ++ ++ namespace views { ++ using std::ranges::views::single; ++ } // namespace views ++ ++ // [range.iota], iota view ++ using std::ranges::iota_view; ++ ++ namespace views { ++ using std::ranges::views::iota; ++ } // namespace views ++ ++ // [range.repeat], repeat view ++#if 0 ++ using std::ranges::repeat_view; ++ ++ namespace views { ++ using std::ranges::views::repeat; ++ } // namespace views ++#endif ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++ // [range.istream], istream view ++ using std::ranges::basic_istream_view; ++ using std::ranges::istream_view; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::ranges::wistream_view; ++# endif ++ ++ namespace views { ++ using std::ranges::views::istream; ++ } ++#endif // _LIBCPP_HAS_NO_LOCALIZATION ++ ++ // [range.adaptor.object], range adaptor objects ++ // using std::ranges::range_adaptor_closure; NOT IMPLEMENTED YET ++ ++ // [range.all], all view ++ namespace views { ++ using std::ranges::views::all; ++ ++ using std::ranges::views::all_t; ++ } // namespace views ++ ++ // [range.ref.view], ref view ++ using std::ranges::ref_view; ++ ++ // [range.owning.view], owning view ++ using std::ranges::owning_view; ++ ++ // [range.as.rvalue], as rvalue view ++#if 0 ++ using std::ranges::as_rvalue_view; ++ ++ namespace views { ++ using std::ranges::views::as_rvalue; ++ } // namespace views ++#endif ++ // [range.filter], filter view ++ using std::ranges::filter_view; ++ ++ namespace views { ++ using std::ranges::views::filter; ++ } // namespace views ++ ++ // [range.transform], transform view ++ using std::ranges::transform_view; ++ ++ namespace views { ++ using std::ranges::views::transform; ++ } // namespace views ++ ++ // [range.take], take view ++ using std::ranges::take_view; ++ ++ namespace views { ++ using std::ranges::views::take; ++ } // namespace views ++ ++ // [range.take.while], take while view ++ using std::ranges::take_while_view; ++ ++ namespace views { ++ using std::ranges::views::take_while; ++ } // namespace views ++ ++ // [range.drop], drop view ++ using std::ranges::drop_view; ++ ++ namespace views { ++ using std::ranges::views::drop; ++ } // namespace views ++ ++ // [range.drop.while], drop while view ++ using std::ranges::drop_while_view; ++ ++ namespace views { ++ using std::ranges::views::drop_while; ++ } // namespace views ++ ++ using std::ranges::join_view; ++ ++ namespace views { ++ using std::ranges::views::join; ++ } // namespace views ++#if 0 ++ using std::ranges::join_with_view; ++ ++ namespace views { ++ using std::ranges::views::join_with; ++ } // namespace views ++#endif ++ using std::ranges::lazy_split_view; ++ ++ // [range.split], split view ++ using std::ranges::split_view; ++ ++ namespace views { ++ using std::ranges::views::lazy_split; ++ using std::ranges::views::split; ++ } // namespace views ++ ++ // [range.counted], counted view ++ namespace views { ++ using std::ranges::views::counted; ++ } // namespace views ++ ++ // [range.common], common view ++ using std::ranges::common_view; ++ ++ namespace views { ++ using std::ranges::views::common; ++ } // namespace views ++ ++ // [range.reverse], reverse view ++ using std::ranges::reverse_view; ++ ++ namespace views { ++ using std::ranges::views::reverse; ++ } // namespace views ++ ++ // [range.as.const], as const view ++#if 0 ++ using std::ranges::as_const_view; ++ ++ namespace views { ++ using std::ranges::views::as_const; ++ } // namespace views ++#endif ++ // [range.elements], elements view ++ using std::ranges::elements_view; ++ ++ using std::ranges::keys_view; ++ using std::ranges::values_view; ++ ++ namespace views { ++ using std::ranges::views::elements; ++ using std::ranges::views::keys; ++ using std::ranges::views::values; ++ } // namespace views ++ ++ // [range.zip], zip view ++ using std::ranges::zip_view; ++ ++ namespace views { ++ using std::ranges::views::zip; ++ } // namespace views ++ ++ // [range.zip.transform], zip transform view ++#if 0 ++ using std::ranges::zip_transform_view; ++ ++ namespace views { ++ using std::ranges::views::zip_transform; ++ } ++ ++ using std::ranges::adjacent_view; ++ ++ namespace views { ++ using std::ranges::views::adjacent; ++ using std::ranges::views::pairwise; ++ } // namespace views ++ ++ using std::ranges::adjacent_transform_view; ++ ++ namespace views { ++ using std::ranges::views::adjacent_transform; ++ using std::ranges::views::pairwise_transform; ++ } // namespace views ++ ++ using std::ranges::chunk_view; ++ ++ using std::ranges::chunk_view; ++ ++ namespace views { ++ using std::ranges::views::chunk; ++ } ++ ++ using std::ranges::slide_view; ++ ++ namespace views { ++ using std::ranges::views::slide; ++ } ++ ++ // [range.chunk.by], chunk by view ++ using std::ranges::chunk_by_view; ++ ++ namespace views { ++ using std::ranges::views::chunk_by; ++ } ++ ++ // [range.stride], stride view ++ using std::ranges::stride_view; ++ ++ namespace views { ++ using std::ranges::views::stride; ++ } ++ ++ using std::ranges::cartesian_product_view; ++ ++ namespace views { ++ using std::ranges::views::cartesian_product; ++ } ++#endif ++ } // namespace ranges ++ ++ namespace views = ranges::views; ++ ++ using std::tuple_element; ++ using std::tuple_size; ++ ++ // using std::from_range_t; NOT IMPLEMENTED YET ++ ++} // namespace std +diff --git a/libcxx/modules/std/ratio.cppm b/libcxx/modules/std/ratio.cppm +new file mode 100644 +index 000000000000..4f49b23c1b48 +--- /dev/null ++++ b/libcxx/modules/std/ratio.cppm +@@ -0,0 +1,65 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:ratio; ++export namespace std { ++ ++ // [ratio.ratio], class template ratio ++ using std::ratio; ++ ++ // [ratio.arithmetic], ratio arithmetic ++ using std::ratio_add; ++ using std::ratio_divide; ++ using std::ratio_multiply; ++ using std::ratio_subtract; ++ ++ // [ratio.comparison], ratio comparison ++ using std::ratio_equal; ++ using std::ratio_greater; ++ using std::ratio_greater_equal; ++ using std::ratio_less; ++ using std::ratio_less_equal; ++ using std::ratio_not_equal; ++ ++ using std::ratio_equal_v; ++ using std::ratio_greater_equal_v; ++ using std::ratio_greater_v; ++ using std::ratio_less_equal_v; ++ using std::ratio_less_v; ++ using std::ratio_not_equal_v; ++ ++ // [ratio.si], convenience SI typedefs ++ using std::atto; ++ using std::centi; ++ using std::deca; ++ using std::deci; ++ using std::exa; ++ using std::femto; ++ using std::giga; ++ using std::hecto; ++ using std::kilo; ++ using std::mega; ++ using std::micro; ++ using std::milli; ++ using std::nano; ++ using std::peta; ++ using std::pico; ++ using std::tera; ++ ++ // These are not supported by libc++, due to the range of intmax_t ++ // using std::yocto; ++ // using std::yotta; ++ // using std::zepto; ++ // using std::zetta ++ ++} // namespace std +diff --git a/libcxx/modules/std/regex.cppm b/libcxx/modules/std/regex.cppm +new file mode 100644 +index 000000000000..6c0a8783179f +--- /dev/null ++++ b/libcxx/modules/std/regex.cppm +@@ -0,0 +1,127 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:regex; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ // [re.const], regex constants ++ namespace regex_constants { ++ using std::regex_constants::error_type; ++ using std::regex_constants::match_flag_type; ++ using std::regex_constants::syntax_option_type; ++ ++ // regex_constants is a bitmask type. ++ // [bitmask.types] specified operators ++ using std::regex_constants::operator&; ++ using std::regex_constants::operator&=; ++ using std::regex_constants::operator^; ++ using std::regex_constants::operator^=; ++ using std::regex_constants::operator|; ++ using std::regex_constants::operator|=; ++ using std::regex_constants::operator~; ++ ++ } // namespace regex_constants ++ ++ // [re.badexp], class regex_error ++ using std::regex_error; ++ ++ // [re.traits], class template regex_traits ++ using std::regex_traits; ++ ++ // [re.regex], class template basic_regex ++ using std::basic_regex; ++ ++ using std::regex; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wregex; ++# endif ++ ++ // [re.regex.swap], basic_regex swap ++ using std::swap; ++ ++ // [re.submatch], class template sub_match ++ using std::sub_match; ++ ++ using std::csub_match; ++ using std::ssub_match; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wcsub_match; ++ using std::wssub_match; ++# endif ++ ++ // [re.submatch.op], sub_match non-member operators ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::operator<<; ++ ++ // [re.results], class template match_results ++ using std::match_results; ++ ++ using std::cmatch; ++ using std::smatch; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wcmatch; ++ using std::wsmatch; ++# endif ++ ++ // match_results comparisons ++ ++ // [re.results.swap], match_results swap ++ ++ // [re.alg.match], function template regex_match ++ using std::regex_match; ++ ++ // [re.alg.search], function template regex_search ++ using std::regex_search; ++ ++ // [re.alg.replace], function template regex_replace ++ using std::regex_replace; ++ ++ // [re.regiter], class template regex_iterator ++ using std::regex_iterator; ++ ++ using std::cregex_iterator; ++ using std::sregex_iterator; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wcregex_iterator; ++ using std::wsregex_iterator; ++# endif ++ ++ // [re.tokiter], class template regex_token_iterator ++ using std::regex_token_iterator; ++ ++ using std::cregex_token_iterator; ++ using std::sregex_token_iterator; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wcregex_token_iterator; ++ using std::wsregex_token_iterator; ++# endif ++ ++ namespace pmr { ++ using std::pmr::match_results; ++ ++ using std::pmr::cmatch; ++ using std::pmr::smatch; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::pmr::wcmatch; ++ using std::pmr::wsmatch; ++# endif ++ } // namespace pmr ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/scoped_allocator.cppm b/libcxx/modules/std/scoped_allocator.cppm +new file mode 100644 +index 000000000000..5eebb3728e5b +--- /dev/null ++++ b/libcxx/modules/std/scoped_allocator.cppm +@@ -0,0 +1,22 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:scoped_allocator; ++export namespace std { ++ // class template scoped_allocator_adaptor ++ using std::scoped_allocator_adaptor; ++ ++ // [scoped.adaptor.operators], scoped allocator operators ++ using std::operator==; ++ ++} // namespace std +diff --git a/libcxx/modules/std/semaphore.cppm b/libcxx/modules/std/semaphore.cppm +new file mode 100644 +index 000000000000..9c366be4214e +--- /dev/null ++++ b/libcxx/modules/std/semaphore.cppm +@@ -0,0 +1,20 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:semaphore; ++export namespace std { ++ // [thread.sema.cnt], class template counting_semaphore ++ using std::counting_semaphore; ++ ++ using std::binary_semaphore; ++} // namespace std +diff --git a/libcxx/modules/std/set.cppm b/libcxx/modules/std/set.cppm +new file mode 100644 +index 000000000000..53441c7f7d59 +--- /dev/null ++++ b/libcxx/modules/std/set.cppm +@@ -0,0 +1,39 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:set; ++export namespace std { ++ // [set], class template set ++ using std::set; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ using std::swap; ++ ++ // [set.erasure], erasure for set ++ using std::erase_if; ++ ++ // [multiset], class template multiset ++ using std::multiset; ++ ++ // [multiset.erasure], erasure for multiset ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::set; ++ ++ using std::pmr::multiset; ++ } // namespace pmr ++ ++} // namespace std +diff --git a/libcxx/modules/std/shared_mutex.cppm b/libcxx/modules/std/shared_mutex.cppm +new file mode 100644 +index 000000000000..a7c415e45b2f +--- /dev/null ++++ b/libcxx/modules/std/shared_mutex.cppm +@@ -0,0 +1,23 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:shared_mutex; ++export namespace std { ++ // [thread.sharedmutex.class], class shared_­mutex ++ using std::shared_mutex; ++ // [thread.sharedtimedmutex.class], class shared_­timed_­mutex ++ using std::shared_timed_mutex; ++ // [thread.lock.shared], class template shared_­lock ++ using std::shared_lock; ++ using std::swap; ++} // namespace std +diff --git a/libcxx/modules/std/source_location.cppm b/libcxx/modules/std/source_location.cppm +new file mode 100644 +index 000000000000..029aec5ec6ff +--- /dev/null ++++ b/libcxx/modules/std/source_location.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:source_location; ++export namespace std { ++ using std::source_location; ++} // namespace std +diff --git a/libcxx/modules/std/span.cppm b/libcxx/modules/std/span.cppm +new file mode 100644 +index 000000000000..aeccc3e01cc8 +--- /dev/null ++++ b/libcxx/modules/std/span.cppm +@@ -0,0 +1,33 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:span; ++export namespace std { ++ ++ // constants ++ using std::dynamic_extent; ++ ++ // [views.span], class template span ++ using std::span; ++ ++ namespace ranges { ++ using std::ranges::enable_borrowed_range; ++ using std::ranges::enable_view; ++ } // namespace ranges ++ ++ // [span.objectrep], views of object representation ++ using std::as_bytes; ++ ++ using std::as_writable_bytes; ++ ++} // namespace std +diff --git a/libcxx/modules/std/spanstream.cppm b/libcxx/modules/std/spanstream.cppm +new file mode 100644 +index 000000000000..7456e11feb44 +--- /dev/null ++++ b/libcxx/modules/std/spanstream.cppm +@@ -0,0 +1,50 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:spanstream; ++export namespace std { ++#if 0 ++ using std::basic_spanbuf; ++ ++ using std::swap; ++ ++ using std::spanbuf; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wspanbuf; ++# endif ++ ++ using std::basic_ispanstream; ++ ++ using std::ispanstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wispanstream; ++# endif ++ ++ using std::basic_ospanstream; ++ ++ using std::ospanstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wospanstream; ++# endif ++ ++ using std::basic_spanstream; ++ ++ using std::spanstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wspanstream; ++# endif ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/sstream.cppm b/libcxx/modules/std/sstream.cppm +new file mode 100644 +index 000000000000..284ac056c117 +--- /dev/null ++++ b/libcxx/modules/std/sstream.cppm +@@ -0,0 +1,52 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:sstream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ ++ using std::basic_stringbuf; ++ ++ using std::swap; ++ ++ using std::stringbuf; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wstringbuf; ++# endif ++ ++ using std::basic_istringstream; ++ ++ using std::istringstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wistringstream; ++# endif ++ ++ using std::basic_ostringstream; ++ ++ using std::ostringstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wostringstream; ++# endif ++ ++ using std::basic_stringstream; ++ ++ using std::stringstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wstringstream; ++# endif ++ ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/stack.cppm b/libcxx/modules/std/stack.cppm +new file mode 100644 +index 000000000000..d61f9d5694fc +--- /dev/null ++++ b/libcxx/modules/std/stack.cppm +@@ -0,0 +1,30 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:stack; ++export namespace std { ++ ++ // [stack], class template stack ++ using std::stack; ++ ++ using std::operator==; ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ using std::operator<=>; ++ ++ using std::swap; ++ using std::uses_allocator; ++} // namespace std +diff --git a/libcxx/modules/std/stacktrace.cppm b/libcxx/modules/std/stacktrace.cppm +new file mode 100644 +index 000000000000..c91fab0de6bc +--- /dev/null ++++ b/libcxx/modules/std/stacktrace.cppm +@@ -0,0 +1,46 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:stacktrace; ++export namespace std { ++#if 0 ++ // [stacktrace.entry], class stacktrace_­entry ++ using std::stacktrace_entry; ++ ++ // [stacktrace.basic], class template basic_­stacktrace ++ using std::basic_stacktrace; ++ ++ // basic_­stacktrace typedef-names ++ using std::stacktrace; ++ ++ // [stacktrace.basic.nonmem], non-member functions ++ using std::swap; ++ ++ using std::to_string; ++ ++ using std::to_string; ++ ++ using std::operator<<; ++ using std::operator<<; ++ ++ namespace pmr { ++ using std::pmr::stacktrace; ++ } ++ ++ // [stacktrace.basic.hash], hash support ++ using std::hash; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/stdexcept.cppm b/libcxx/modules/std/stdexcept.cppm +new file mode 100644 +index 000000000000..ef4495ef3b80 +--- /dev/null ++++ b/libcxx/modules/std/stdexcept.cppm +@@ -0,0 +1,26 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:stdexcept; ++export namespace std { ++ using std::domain_error; ++ using std::invalid_argument; ++ using std::length_error; ++ using std::logic_error; ++ using std::out_of_range; ++ using std::overflow_error; ++ using std::range_error; ++ using std::runtime_error; ++ using std::underflow_error; ++ ++} // namespace std +diff --git a/libcxx/modules/std/stdfloat.cppm b/libcxx/modules/std/stdfloat.cppm +new file mode 100644 +index 000000000000..a6f37c3a091c +--- /dev/null ++++ b/libcxx/modules/std/stdfloat.cppm +@@ -0,0 +1,35 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally" ++# include ++#endif ++ ++export module std:stdfloat; ++export namespace std { ++#if defined(__STDCPP_FLOAT16_T__) ++ using std::float16_t; ++#endif ++#if defined(__STDCPP_FLOAT32_T__) ++ using std::float32_t; ++#endif ++#if defined(__STDCPP_FLOAT64_T__) ++ using std::float64_t; ++#endif ++#if defined(__STDCPP_FLOAT128_T__) ++ using std::float128_t; ++#endif ++#if defined(__STDCPP_BFLOAT16_T__) ++ using std::bfloat16_t; ++#endif ++ ++} // namespace std +diff --git a/libcxx/modules/std/stop_token.cppm b/libcxx/modules/std/stop_token.cppm +new file mode 100644 +index 000000000000..42c6f96c539d +--- /dev/null ++++ b/libcxx/modules/std/stop_token.cppm +@@ -0,0 +1,33 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() // D145183 contains a patch for this header ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:stop_token; ++export namespace std { ++#if 0 ++ // [stoptoken], class stop_­token ++ using std::stop_token; ++ ++ // [stopsource], class stop_­source ++ using std::stop_source; ++ ++ // no-shared-stop-state indicator ++ using std::nostopstate; ++ using std::nostopstate_t; ++ ++ // [stopcallback], class template stop_­callback ++ using std::stop_callback; ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/streambuf.cppm b/libcxx/modules/std/streambuf.cppm +new file mode 100644 +index 000000000000..eba0e40e9f73 +--- /dev/null ++++ b/libcxx/modules/std/streambuf.cppm +@@ -0,0 +1,26 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:streambuf; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ using std::basic_streambuf; ++ using std::streambuf; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wstreambuf; ++# endif ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/string.cppm b/libcxx/modules/std/string.cppm +new file mode 100644 +index 000000000000..3916324c1fef +--- /dev/null ++++ b/libcxx/modules/std/string.cppm +@@ -0,0 +1,84 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:string; ++export namespace std { ++ ++ // [char.traits], character traits ++ using std::char_traits; ++ ++ // [basic.string], basic_string ++ using std::basic_string; ++ ++ using std::operator+; ++ using std::operator==; ++ using std::operator<=>; ++ ++ // [string.special], swap ++ using std::swap; ++ ++ // [string.io], inserters and extractors ++ using std::operator>>; ++ using std::operator<<; ++ using std::getline; ++ ++ // [string.erasure], erasure ++ using std::erase; ++ using std::erase_if; ++ ++ // basic_string typedef-names ++ using std::string; ++ using std::u16string; ++ using std::u32string; ++ using std::u8string; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wstring; ++#endif ++ ++ // [string.conversions], numeric conversions ++ using std::stod; ++ using std::stof; ++ using std::stoi; ++ using std::stol; ++ using std::stold; ++ using std::stoll; ++ using std::stoul; ++ using std::stoull; ++ using std::to_string; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::to_wstring; ++#endif ++ ++ namespace pmr { ++ using std::pmr::basic_string; ++ using std::pmr::string; ++ using std::pmr::u16string; ++ using std::pmr::u32string; ++ using std::pmr::u8string; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::pmr::wstring; ++#endif ++ ++ } // namespace pmr ++ ++ // [basic.string.hash], hash support ++ using std::hash; ++ ++ inline namespace literals { ++ inline namespace string_literals { ++ // [basic.string.literals], suffix for basic_string literals ++ using std::literals::string_literals::operator""s; ++ } // namespace string_literals ++ } // namespace literals ++ ++} // namespace std +diff --git a/libcxx/modules/std/string_view.cppm b/libcxx/modules/std/string_view.cppm +new file mode 100644 +index 000000000000..8f23a155781e +--- /dev/null ++++ b/libcxx/modules/std/string_view.cppm +@@ -0,0 +1,52 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:string_view; ++export namespace std { ++ ++ // [string.view.template], class template basic_string_view ++ using std::basic_string_view; ++ ++ namespace ranges { ++ using std::ranges::enable_borrowed_range; ++ using std::ranges::enable_view; ++ } // namespace ranges ++ ++ // [string.view.comparison], non-member comparison functions ++ using std::operator==; ++ using std::operator<=>; ++ ++ // see [string.view.comparison], sufficient additional overloads of comparison functions ++ ++ // [string.view.io], inserters and extractors ++ using std::operator<<; ++ ++ // basic_string_view typedef-names ++ using std::string_view; ++ using std::u16string_view; ++ using std::u32string_view; ++ using std::u8string_view; ++#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wstring_view; ++#endif ++ ++ // [string.view.hash], hash support ++ using std::hash; ++ ++ inline namespace literals { ++ inline namespace string_view_literals { ++ // [string.view.literals], suffix for basic_string_view literals ++ using std::literals::string_view_literals::operator"" sv; ++ } // namespace string_view_literals ++ } // namespace literals ++} // namespace std +diff --git a/libcxx/modules/std/strstream.cppm b/libcxx/modules/std/strstream.cppm +new file mode 100644 +index 000000000000..f114c09fbb16 +--- /dev/null ++++ b/libcxx/modules/std/strstream.cppm +@@ -0,0 +1,25 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include <__config> ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++# include ++#endif ++ ++export module std:strstream; ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION ++export namespace std { ++ using std::istrstream; ++ using std::ostrstream; ++ using std::strstream; ++ using std::strstreambuf; ++} // namespace std ++#endif // _LIBCPP_HAS_NO_LOCALIZATION +diff --git a/libcxx/modules/std/syncstream.cppm b/libcxx/modules/std/syncstream.cppm +new file mode 100644 +index 000000000000..8f6b407d2f2a +--- /dev/null ++++ b/libcxx/modules/std/syncstream.cppm +@@ -0,0 +1,36 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#if __has_include() ++# error "include this header unconditionally and uncomment the exported symbols" ++# include ++#endif ++ ++export module std:syncstream; ++export namespace std { ++#if 0 ++ using std::basic_syncbuf; ++ ++ // [syncstream.syncbuf.special], specialized algorithms ++ using std::swap; ++ ++ using std::syncbuf; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wsyncbuf; ++# endif ++ using std::basic_osyncstream; ++ ++ using std::osyncstream; ++# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS ++ using std::wosyncstream; ++# endif ++#endif ++} // namespace std +diff --git a/libcxx/modules/std/system_error.cppm b/libcxx/modules/std/system_error.cppm +new file mode 100644 +index 000000000000..b7a6f3d50f35 +--- /dev/null ++++ b/libcxx/modules/std/system_error.cppm +@@ -0,0 +1,48 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:system_error; ++export namespace std { ++ ++ using std::error_category; ++ using std::generic_category; ++ using std::system_category; ++ ++ using std::error_code; ++ using std::error_condition; ++ using std::system_error; ++ ++ using std::is_error_code_enum; ++ ++ using std::errc; ++ ++ // [syserr.errcode.nonmembers], non-member functions ++ using std::make_error_code; ++ ++ using std::operator<<; ++ ++ // [syserr.errcondition.nonmembers], non-member functions ++ using std::make_error_condition; ++ ++ // [syserr.compare], comparison operator functions ++ using std::operator==; ++ using std::operator<=>; ++ ++ // [syserr.hash], hash support ++ using std::hash; ++ ++ // [syserr], system error support ++ using std::is_error_code_enum_v; ++ using std::is_error_condition_enum_v; ++ ++} // namespace std +diff --git a/libcxx/modules/std/thread.cppm b/libcxx/modules/std/thread.cppm +new file mode 100644 +index 000000000000..35f75b1d47c8 +--- /dev/null ++++ b/libcxx/modules/std/thread.cppm +@@ -0,0 +1,41 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:thread; ++export namespace std { ++ // [thread.thread.class], class thread ++ using std::thread; ++ ++ using std::swap; ++ ++#if 0 // TODO Enable when implementing P0660 ++ // [thread.jthread.class], class jthread ++ using std::jthread; ++#endif ++ ++ // [thread.thread.this], namespace this_thread ++ namespace this_thread { ++ using std::this_thread::get_id; ++ ++ using std::this_thread::sleep_for; ++ using std::this_thread::sleep_until; ++ using std::this_thread::yield; ++ } // namespace this_thread ++ ++ // [thread.thread.id] ++ using std::operator==; ++ using std::operator<<; ++ // using std::formatter; ++ using std::hash; ++ ++} // namespace std +diff --git a/libcxx/modules/std/tuple.cppm b/libcxx/modules/std/tuple.cppm +new file mode 100644 +index 000000000000..7d5445f8c85d +--- /dev/null ++++ b/libcxx/modules/std/tuple.cppm +@@ -0,0 +1,61 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:tuple; ++export namespace std { ++ ++ // [tuple.tuple], class template tuple ++ using std::tuple; ++ ++ // [tuple.like], concept tuple-like ++ ++ // [tuple.common.ref], common_reference related specializations ++ using std::basic_common_reference; ++ using std::common_type; ++ ++ // [tuple.creation], tuple creation functions ++ using std::ignore; ++ ++ using std::forward_as_tuple; ++ using std::make_tuple; ++ using std::tie; ++ using std::tuple_cat; ++ ++ // [tuple.apply], calling a function with a tuple of arguments ++ using std::apply; ++ ++ using std::make_from_tuple; ++ ++ // [tuple.helper], tuple helper classes ++ using std::tuple_element; ++ using std::tuple_size; ++ ++ using std::tuple_element_t; ++ ++ // [tuple.elem], element access ++ using std::tuple_element_t; ++ ++ // [tuple.rel], relational operators ++ using std::operator==; ++ using std::operator<=>; ++ ++ // [tuple.traits], allocator-related traits ++ using std::uses_allocator; ++ ++ // [tuple.special], specialized algorithms ++ using std::swap; ++ ++ // [tuple.helper], tuple helper classes ++ using std::tuple_size_v; ++ ++} // namespace std +diff --git a/libcxx/modules/std/type_traits.cppm b/libcxx/modules/std/type_traits.cppm +new file mode 100644 +index 000000000000..1d4c2e6c7f8f +--- /dev/null ++++ b/libcxx/modules/std/type_traits.cppm +@@ -0,0 +1,295 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include // needed for unwrap_ref_decay (is this a bug?) ++#include ++export module std:type_traits; ++export namespace std { ++ using std::bool_constant; ++ using std::false_type; ++ using std::integral_constant; ++ using std::true_type; ++ ++ // helper traits ++ using std::conditional; ++ using std::enable_if; ++ ++ // Primary classification traits: ++ using std::is_array; ++ using std::is_class; ++ using std::is_enum; ++ using std::is_floating_point; ++ using std::is_function; ++ using std::is_integral; ++ using std::is_lvalue_reference; ++ using std::is_member_function_pointer; ++ using std::is_member_object_pointer; ++ using std::is_null_pointer; // C++14 ++ using std::is_pointer; ++ using std::is_rvalue_reference; ++ using std::is_union; ++ using std::is_void; ++ ++ // Secondary classification traits: ++ using std::is_arithmetic; ++ using std::is_compound; ++ using std::is_fundamental; ++ using std::is_member_pointer; ++ using std::is_object; ++ using std::is_reference; ++ using std::is_scalar; ++ using std::is_scoped_enum; ++ ++ // Const-volatile properties and transformations: ++ using std::add_const; ++ using std::add_cv; ++ using std::add_volatile; ++ using std::is_const; ++ using std::is_volatile; ++ using std::remove_const; ++ using std::remove_cv; ++ using std::remove_volatile; ++ ++ // Reference transformations: ++ using std::add_lvalue_reference; ++ using std::add_rvalue_reference; ++ using std::remove_reference; ++ ++ // Pointer transformations: ++ using std::add_pointer; ++ using std::remove_pointer; ++ ++ using std::type_identity; // C++20 ++ using std::type_identity_t; ++ ++ // Integral properties: ++ using std::is_signed; ++ using std::is_unsigned; ++ using std::make_signed; ++ using std::make_unsigned; ++ ++ // Array properties and transformations: ++ using std::extent; ++ using std::rank; ++ using std::remove_all_extents; ++ using std::remove_extent; ++ ++ using std::is_bounded_array; // C++20 ++ using std::is_unbounded_array; // C++20 ++ ++ // Member introspection: ++ using std::is_abstract; ++ using std::is_aggregate; // C++17 ++ using std::is_empty; ++ using std::is_final; // C++14 ++ using std::is_pod; ++ using std::is_polymorphic; ++ using std::is_standard_layout; ++ using std::is_trivial; ++ using std::is_trivially_copyable; ++ ++ using std::is_assignable; ++ using std::is_constructible; ++ using std::is_copy_assignable; ++ using std::is_copy_constructible; ++ using std::is_default_constructible; ++ using std::is_destructible; ++ using std::is_move_assignable; ++ using std::is_move_constructible; ++ using std::is_swappable; // C++17 ++ using std::is_swappable_with; // C++17 ++ ++ using std::is_trivially_assignable; ++ using std::is_trivially_constructible; ++ using std::is_trivially_copy_assignable; ++ using std::is_trivially_copy_constructible; ++ using std::is_trivially_default_constructible; ++ using std::is_trivially_destructible; ++ using std::is_trivially_move_assignable; ++ using std::is_trivially_move_constructible; ++ ++ using std::is_nothrow_assignable; ++ using std::is_nothrow_constructible; ++ using std::is_nothrow_copy_assignable; ++ using std::is_nothrow_copy_constructible; ++ using std::is_nothrow_default_constructible; ++ using std::is_nothrow_destructible; ++ using std::is_nothrow_move_assignable; ++ using std::is_nothrow_move_constructible; ++ using std::is_nothrow_swappable; // C++17 ++ using std::is_nothrow_swappable_with; // C++17 ++ ++ using std::has_virtual_destructor; ++ ++ using std::has_unique_object_representations; // C++17 ++ ++ // Relationships between types: ++ using std::is_base_of; ++ using std::is_same; ++ ++ using std::is_convertible; ++ using std::is_nothrow_convertible; // C++20 ++ using std::is_nothrow_convertible_v; // C++20 ++ ++ using std::is_invocable; ++ using std::is_invocable_r; ++ ++ using std::is_nothrow_invocable; ++ using std::is_nothrow_invocable_r; ++ ++ // Alignment properties and transformations: ++ using std::aligned_storage; ++ using std::aligned_union; ++ using std::alignment_of; ++ using std::remove_cvref; // C++20 ++ ++ using std::common_type; ++ using std::decay; ++ using std::invoke_result; // C++17 ++ using std::underlying_type; ++ using std::unwrap_ref_decay; ++ ++ // const-volatile modifications: ++ using std::add_const_t; ++ using std::add_cv_t; ++ using std::add_volatile_t; ++ using std::remove_const_t; ++ using std::remove_cv_t; ++ using std::remove_volatile_t; ++ ++ // reference modifications: ++ using std::add_lvalue_reference_t; ++ using std::add_rvalue_reference_t; ++ using std::remove_reference_t; ++ ++ // sign modifications: ++ using std::make_signed_t; ++ using std::make_unsigned_t; ++ ++ // array modifications: ++ using std::remove_all_extents_t; ++ using std::remove_extent_t; ++ ++ using std::is_bounded_array_v; // C++20 ++ using std::is_unbounded_array_v; // C++20 ++ ++ // pointer modifications: ++ using std::add_pointer_t; // C++14 ++ using std::remove_pointer_t; // C++14 ++ ++ // other transformations: ++ using std::aligned_storage_t; // C++14 ++ using std::aligned_union_t; // C++14 ++ using std::common_type_t; // C++14 ++ using std::conditional_t; // C++14 ++ using std::decay_t; // C++14 ++ using std::enable_if_t; // C++14 ++ using std::invoke_result_t; ++ using std::remove_cvref_t; // C++20 ++ using std::underlying_type_t; ++ using std::unwrap_ref_decay_t; ++ ++ using std::void_t; ++ ++ // See C++14 20.10.4.1, primary type categories ++ using std::is_array_v; ++ using std::is_class_v; ++ using std::is_enum_v; ++ using std::is_floating_point_v; ++ using std::is_function_v; ++ using std::is_integral_v; ++ using std::is_lvalue_reference_v; ++ using std::is_member_function_pointer_v; ++ using std::is_member_object_pointer_v; ++ using std::is_null_pointer_v; ++ using std::is_pointer_v; ++ using std::is_rvalue_reference_v; ++ using std::is_union_v; ++ using std::is_void_v; ++ ++ // See C++14 20.10.4.2, composite type categories ++ using std::is_arithmetic_v; ++ using std::is_compound_v; ++ using std::is_fundamental_v; ++ using std::is_member_pointer_v; ++ using std::is_object_v; ++ using std::is_reference_v; ++ using std::is_scalar_v; ++ using std::is_scoped_enum_v; ++ ++ // See C++14 20.10.4.3, type properties ++ using std::has_unique_object_representations_v; // C++17; ++ using std::has_virtual_destructor_v; ++ using std::is_abstract_v; ++ using std::is_aggregate_v; ++ using std::is_assignable_v; ++ using std::is_const_v; ++ using std::is_constructible_v; ++ using std::is_copy_assignable_v; ++ using std::is_copy_constructible_v; ++ using std::is_default_constructible_v; ++ using std::is_destructible_v; ++ using std::is_empty_v; ++ using std::is_final_v; ++ using std::is_move_assignable_v; ++ using std::is_move_constructible_v; ++ using std::is_nothrow_assignable_v; ++ using std::is_nothrow_constructible_v; ++ using std::is_nothrow_copy_assignable_v; ++ using std::is_nothrow_copy_constructible_v; ++ using std::is_nothrow_default_constructible_v; ++ using std::is_nothrow_destructible_v; ++ using std::is_nothrow_move_assignable_v; ++ using std::is_nothrow_move_constructible_v; ++ using std::is_nothrow_swappable_v; ++ using std::is_nothrow_swappable_with_v; ++ using std::is_pod_v; ++ using std::is_polymorphic_v; ++ using std::is_signed_v; ++ using std::is_standard_layout_v; ++ using std::is_swappable_v; ++ using std::is_swappable_with_v; ++ using std::is_trivial_v; ++ using std::is_trivially_assignable_v; ++ using std::is_trivially_constructible_v; ++ using std::is_trivially_copy_assignable_v; ++ using std::is_trivially_copy_constructible_v; ++ using std::is_trivially_copyable_v; ++ using std::is_trivially_default_constructible_v; ++ using std::is_trivially_destructible_v; ++ using std::is_trivially_move_assignable_v; ++ using std::is_trivially_move_constructible_v; ++ using std::is_unsigned_v; ++ using std::is_volatile_v; ++ ++ // See C++14 20.10.5, type property queries ++ using std::alignment_of_v; // C++17 ++ using std::extent_v; // C++17 ++ using std::rank_v; // C++17 ++ ++ // See C++14 20.10.6, type relations ++ using std::is_base_of_v; ++ using std::is_convertible_v; ++ using std::is_invocable_r_v; ++ using std::is_invocable_v; ++ using std::is_nothrow_invocable_r_v; ++ using std::is_nothrow_invocable_v; ++ using std::is_same_v; ++ ++ // [meta.logical], logical operator traits: // C++17 ++ using std::conjunction_v; ++ using std::disjunction_v; ++ using std::negation_v; ++ ++ // Move to proper section ++ using std::is_constant_evaluated; ++ using std::negation; ++} // namespace std +diff --git a/libcxx/modules/std/typeindex.cppm b/libcxx/modules/std/typeindex.cppm +new file mode 100644 +index 000000000000..c0f5f87cb4d6 +--- /dev/null ++++ b/libcxx/modules/std/typeindex.cppm +@@ -0,0 +1,18 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:typeindex; ++export namespace std { ++ using std::hash; ++ using std::type_index; ++} // namespace std +diff --git a/libcxx/modules/std/typeinfo.cppm b/libcxx/modules/std/typeinfo.cppm +new file mode 100644 +index 000000000000..f4b9e46a17f7 +--- /dev/null ++++ b/libcxx/modules/std/typeinfo.cppm +@@ -0,0 +1,19 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:typeinfo; ++export namespace std { ++ using std::bad_cast; ++ using std::bad_typeid; ++ using std::type_info; ++} // namespace std +diff --git a/libcxx/modules/std/unordered_map.cppm b/libcxx/modules/std/unordered_map.cppm +new file mode 100644 +index 000000000000..0fc507ac7d96 +--- /dev/null ++++ b/libcxx/modules/std/unordered_map.cppm +@@ -0,0 +1,36 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:unordered_map; ++export namespace std { ++ // [unord.map], class template unordered_­map ++ using std::unordered_map; ++ ++ // [unord.multimap], class template unordered_­multimap ++ using std::unordered_multimap; ++ ++ using std::operator==; ++ ++ using std::swap; ++ ++ // [unord.map.erasure], erasure for unordered_­map ++ using std::erase_if; ++ ++ // [unord.multimap.erasure], erasure for unordered_­multimap ++ ++ namespace pmr { ++ using std::pmr::unordered_map; ++ using std::pmr::unordered_multimap; ++ } // namespace pmr ++ ++} // namespace std +diff --git a/libcxx/modules/std/unordered_set.cppm b/libcxx/modules/std/unordered_set.cppm +new file mode 100644 +index 000000000000..6cd135303bdc +--- /dev/null ++++ b/libcxx/modules/std/unordered_set.cppm +@@ -0,0 +1,36 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:unordered_set; ++export namespace std { ++ // [unord.set], class template unordered_­set ++ using std::unordered_set; ++ ++ // [unord.multiset], class template unordered_­multiset ++ using std::unordered_multiset; ++ ++ using std::operator==; ++ ++ using std::swap; ++ ++ // [unord.set.erasure], erasure for unordered_­set ++ using std::erase_if; ++ ++ // [unord.multiset.erasure], erasure for unordered_­multiset ++ ++ namespace pmr { ++ using std::pmr::unordered_set; ++ ++ using std::pmr::unordered_multiset; ++ } // namespace pmr ++} // namespace std +diff --git a/libcxx/modules/std/utility.cppm b/libcxx/modules/std/utility.cppm +new file mode 100644 +index 000000000000..e81c2e74220e +--- /dev/null ++++ b/libcxx/modules/std/utility.cppm +@@ -0,0 +1,69 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++export module std:utility; ++export namespace std { ++ using std::swap; ++ ++ namespace rel_ops { ++ using rel_ops::operator!=; ++ using rel_ops::operator>; ++ using rel_ops::operator<=; ++ using rel_ops::operator>=; ++ } // namespace rel_ops ++ ++ using std::as_const; ++ using std::cmp_equal; ++ using std::cmp_greater; // C++20 ++ using std::cmp_greater_equal; // C++20 ++ using std::cmp_less; // C++20 ++ using std::cmp_less_equal; // C++20 ++ using std::cmp_not_equal; // C++20 ++ using std::declval; ++ using std::forward; ++ using std::forward_like; ++ using std::in_range; // C++20 ++ using std::move; ++ using std::move_if_noexcept; ++ ++ using std::basic_common_reference; ++ using std::pair; ++ using std::operator==; ++ ++ using std::make_pair; ++ using std::piecewise_construct_t; ++ // FIXME: We can't export non-inline constexpr variables. ++ // using std::piecewise_construct; ++ ++ using std::tuple_element; ++ using std::tuple_size; ++ ++ using std::unreachable; ++ ++ using std::get; ++ using std::index_sequence; ++ using std::index_sequence_for; ++ using std::integer_sequence; ++ using std::make_index_sequence; ++ using std::make_integer_sequence; ++ ++ using std::exchange; ++ using std::in_place; ++ using std::in_place_t; ++ ++ using std::in_place_index_t; ++ using std::in_place_type; ++ using std::in_place_type_t; ++ ++ using std::in_place_index; ++ using std::to_underlying; ++} // namespace std +diff --git a/libcxx/modules/std/valarray.cppm b/libcxx/modules/std/valarray.cppm +new file mode 100644 +index 000000000000..303620a527ea +--- /dev/null ++++ b/libcxx/modules/std/valarray.cppm +@@ -0,0 +1,73 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:valarray; ++export namespace std { ++ using std::gslice; ++ using std::gslice_array; ++ using std::indirect_array; ++ using std::mask_array; ++ using std::slice; ++ using std::slice_array; ++ using std::valarray; ++ ++ using std::swap; ++ ++ using std::operator*; ++ using std::operator/; ++ using std::operator%; ++ using std::operator+; ++ using std::operator-; ++ ++ using std::operator^; ++ using std::operator&; ++ using std::operator|; ++ ++ using std::operator<<; ++ using std::operator>>; ++ ++ using std::operator&&; ++ using std::operator||; ++ ++ using std::operator==; ++ using std::operator!=; ++ ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ ++ using std::abs; ++ using std::acos; ++ using std::asin; ++ using std::atan; ++ ++ using std::atan2; ++ ++ using std::cos; ++ using std::cosh; ++ using std::exp; ++ using std::log; ++ using std::log10; ++ ++ using std::pow; ++ ++ using std::sin; ++ using std::sinh; ++ using std::sqrt; ++ using std::tan; ++ using std::tanh; ++ ++ using std::begin; ++ using std::end; ++} // namespace std +diff --git a/libcxx/modules/std/variant.cppm b/libcxx/modules/std/variant.cppm +new file mode 100644 +index 000000000000..8fbe51b0006e +--- /dev/null ++++ b/libcxx/modules/std/variant.cppm +@@ -0,0 +1,57 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:variant; ++export namespace std { ++ // [variant.variant], class template variant ++ using std::variant; ++ ++ // [variant.helper], variant helper classes ++ using std::variant_alternative; ++ using std::variant_npos; ++ using std::variant_size; ++ using std::variant_size_v; ++ ++ // [variant.get], value access ++ using std::get; ++ using std::get_if; ++ using std::holds_alternative; ++ using std::variant_alternative_t; ++ ++ // [variant.relops], relational operators ++ using std::operator==; ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ using std::operator<=>; ++ ++ // [variant.visit], visitation ++ using std::visit; ++ ++ // [variant.monostate], class monostate ++ using std::monostate; ++ ++ // [variant.monostate.relops], monostate relational operators ++ ++ // [variant.specalg], specialized algorithms ++ using std::swap; ++ ++ // [variant.bad.access], class bad_variant_access ++ using std::bad_variant_access; ++ ++ // [variant.hash], hash support ++ using std::hash; ++ ++} // namespace std +diff --git a/libcxx/modules/std/vector.cppm b/libcxx/modules/std/vector.cppm +new file mode 100644 +index 000000000000..179edd5e5b42 +--- /dev/null ++++ b/libcxx/modules/std/vector.cppm +@@ -0,0 +1,50 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++#include ++export module std:vector; ++ ++export namespace std { ++ // [vector], class template vector ++ using std::vector; ++ ++ using std::operator==; ++ using std::operator<=>; ++ ++ /* These should be removed after https://reviews.llvm.org/D132268 lands. */ ++ using std::operator!=; ++ using std::operator<; ++ using std::operator>; ++ using std::operator<=; ++ using std::operator>=; ++ ++ using std::swap; ++ ++ // [vector.erasure], erasure ++ using std::erase; ++ using std::erase_if; ++ ++ namespace pmr { ++ using std::pmr::vector; ++ } ++ ++ // [vector.bool], specialization of vector for bool ++ // [vector.bool.pspc], partial class template specialization vector ++ ++ // hash support ++ using std::hash; ++ ++ // [vector.bool.fmt], formatter specialization for vector ++ using std::formatter; ++} // namespace std ++ ++export { using ::operator new; } +diff --git a/libcxx/modules/std/version.cppm b/libcxx/modules/std/version.cppm +new file mode 100644 +index 000000000000..f699be94c067 +--- /dev/null ++++ b/libcxx/modules/std/version.cppm +@@ -0,0 +1,17 @@ ++# 1 __FILE__ 1 3 ++// -*- C++ -*- ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++module; ++#include ++ ++export module std:version; ++export namespace std { ++ // This module exports nothing. ++} // namespace std +diff --git a/libcxx/test/configs/cmake-bridge.cfg.in b/libcxx/test/configs/cmake-bridge.cfg.in +index e2c86f7c7c3f..4a29168c8ed9 100644 +--- a/libcxx/test/configs/cmake-bridge.cfg.in ++++ b/libcxx/test/configs/cmake-bridge.cfg.in +@@ -27,7 +27,13 @@ import shlex + config.substitutions.append(('%{cxx}', shlex.quote('@CMAKE_CXX_COMPILER@'))) + config.substitutions.append(('%{libcxx}', '@LIBCXX_SOURCE_DIR@')) + config.substitutions.append(('%{include}', '@LIBCXX_GENERATED_INCLUDE_DIR@')) ++config.substitutions.append(('%{module}', '@LIBCXX_GENERATED_MODULE_DIR@')) + config.substitutions.append(('%{target-include}', '@LIBCXX_GENERATED_INCLUDE_TARGET_DIR@')) + config.substitutions.append(('%{lib}', '@LIBCXX_LIBRARY_DIR@')) + config.substitutions.append(('%{executor}', '@LIBCXX_EXECUTOR@')) + config.substitutions.append(('%{test-tools}', '@LIBCXX_TEST_TOOLS_PATH@')) ++ ++# These are for testing with modules. This is probably not the way forward ++config.substitutions.append(('%{cmake}', '@CMAKE_COMMAND@')) ++config.substitutions.append(('%{make}', '@CMAKE_MAKE_PROGRAM@')) ++config.substitutions.append(('%{generator}', '@CMAKE_GENERATOR@')) +diff --git a/libcxx/test/configs/llvm-libc++-shared.cfg.in b/libcxx/test/configs/llvm-libc++-shared.cfg.in +index eb86b88f956a..2a2a712661d2 100644 +--- a/libcxx/test/configs/llvm-libc++-shared.cfg.in ++++ b/libcxx/test/configs/llvm-libc++-shared.cfg.in +@@ -4,13 +4,13 @@ + lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + + config.substitutions.append(('%{flags}', +- '-isysroot {}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '' ++ '-pthread -isysroot {}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '' + )) + config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include} -I %{target-include} -I %{libcxx}/test/support' + )) + config.substitutions.append(('%{link_flags}', +- '-nostdlib++ -L %{lib} -Wl,-rpath,%{lib} -lc++ -pthread' ++ '-nostdlib++ -L %{lib} -Wl,-rpath,%{lib} -lc++' + )) + config.substitutions.append(('%{exec}', + '%{executor} --execdir %T -- ' +diff --git a/libcxx/test/configs/llvm-libc++-static.cfg.in b/libcxx/test/configs/llvm-libc++-static.cfg.in +index 8b66a129098b..fa10b6332e0c 100644 +--- a/libcxx/test/configs/llvm-libc++-static.cfg.in ++++ b/libcxx/test/configs/llvm-libc++-static.cfg.in +@@ -4,13 +4,13 @@ + lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + + config.substitutions.append(('%{flags}', +- '-isysroot {}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '' ++ '-pthread -isysroot {}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '' + )) + config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include} -I %{target-include} -I %{libcxx}/test/support' + )) + config.substitutions.append(('%{link_flags}', +- '-nostdlib++ -L %{lib} -lc++ -lc++abi -pthread' ++ '-nostdlib++ -L %{lib} -lc++ -lc++abi' + )) + config.substitutions.append(('%{exec}', + '%{executor} --execdir %T -- ' +diff --git a/libcxx/test/libcxx/language.support/support.types/cstddef.compile.pass.cpp b/libcxx/test/libcxx/language.support/support.types/cstddef.compile.pass.cpp +index 514353a10302..830cf1b54f3b 100644 +--- a/libcxx/test/libcxx/language.support/support.types/cstddef.compile.pass.cpp ++++ b/libcxx/test/libcxx/language.support/support.types/cstddef.compile.pass.cpp +@@ -10,7 +10,15 @@ + // This is a conforming extension to be consistent with other implementations, which all + // appear to provide that behavior too. + +-#include ++// XFAIL: use_module_std ++ ++#if defined(TEST_USE_MODULE_STD) ++import std; ++#elif defined(TEST_USE_MODULE_STD_COMPAT) ++import std.compat; ++#else ++# include ++#endif + #include "test_macros.h" + + using PtrdiffT = ::ptrdiff_t; +@@ -19,8 +27,10 @@ using SizeT = ::size_t; + using MaxAlignT = ::max_align_t; + #endif + ++#ifndef TEST_USE_MODULE + // Supported in C++03 mode too for backwards compatibility with previous versions of libc++ + using NullptrT = ::nullptr_t; ++#endif + + // Also ensure that we provide std::nullptr_t in C++03 mode, which is an extension too. + using StdNullptrT = std::nullptr_t; +diff --git a/libcxx/test/libcxx/module_std.sh.cpp b/libcxx/test/libcxx/module_std.sh.cpp +new file mode 100644 +index 000000000000..106309dce241 +--- /dev/null ++++ b/libcxx/test/libcxx/module_std.sh.cpp +@@ -0,0 +1,613 @@ ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 ++ ++// TODO This test only works when modules are enabled, so limit to the module std test ++ ++// REQUIRES: has-clang-tidy ++ ++// The GCC compiler flags are not always compatible with clang-tidy. ++// UNSUPPORTED: gcc ++ ++// RUN %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} ++// should the headers list just be a list of regexes where symbols from are available... ++ ++/* ++BEGIN-SCRIPT ++ ++# Used because the sequence of tokens RUN : can't appear anywhere or it'll confuse Lit. ++RUN = "RUN" ++ ++### Remove the headers that have no module associated with them ++ ++# Note all C-headers using .h are filtered in the loop ++ ++# These headers are not available in C++23, but in older language Standards. ++toplevel_headers.remove('ccomplex') ++toplevel_headers.remove('ciso646') ++toplevel_headers.remove('cstdbool') ++toplevel_headers.remove('ctgmath') ++ ++# Header to consider adding ++toplevel_headers.remove('iosfwd') ++ ++ ++# Ignore several declarations found in the includes. ++SkipDeclarations = dict() ++# The operators are added for private types like __iom_t10. ++SkipDeclarations['iomanip'] = "std::operator<< std::operator>>" ++# Declared in the forward header since std::string uses std::allocator ++SkipDeclarations['string'] = "std::allocator" ++# TODO This type should be private ++SkipDeclarations['valarray'] = "std::sliceExpr" ++ ++ ++# Adds an extra header file to scan ++ExtraHeader = dict() ++# locale has a file and not a subdirectory ++ExtraHeader['locale'] = "v1/__locale$" ++ExtraHeader['thread'] = "v1/__threading_support$" ++ ++ ++### Remove headers with support issues ++ ++# Note these headers should be validated for their modules once the issues have been resolved. ++ ++# Headers under evaluation ++toplevel_headers.remove('condition_variable') ++toplevel_headers.remove('mutex') ++ ++toplevel_headers.remove('cstdint') # TODO this is a missing include ++toplevel_headers.remove('cuchar') # TODO review this header ++toplevel_headers.remove('cwchar') # TODO review this header, it has comments ++ ++# we could move these fwd parts to __fwd/fstream.h and include these from iosfwd which would be consistent with the other newer forward parts ++toplevel_headers.remove('ios') ++toplevel_headers.remove('fstream') ++toplevel_headers.remove('istream') ++toplevel_headers.remove('ostream') ++toplevel_headers.remove('iostream') ++toplevel_headers.remove('sstream') ++toplevel_headers.remove('streambuf') ++ ++# These headers contain operator!= that need to be evaluated ++# P1614 probably should have removed them, however that paper is partly implemented. ++toplevel_headers.remove('memory_resource') ++toplevel_headers.remove('complex') ++toplevel_headers.remove('unordered_set') ++toplevel_headers.remove('unordered_map') ++ ++# These headers use the spaceship of P1614. ++# Some progress has been made upstream in this area, before removing it from the export ++# list first revase this patch. ++toplevel_headers.remove('array') ++toplevel_headers.remove('deque') ++toplevel_headers.remove('forward_list') ++toplevel_headers.remove('map') ++toplevel_headers.remove('optional') ++toplevel_headers.remove('queue') ++toplevel_headers.remove('regex') ++toplevel_headers.remove('scoped_allocator') ++toplevel_headers.remove('set') ++toplevel_headers.remove('stack') ++toplevel_headers.remove('thread') ++toplevel_headers.remove('vector') ++ ++# The header provides the following entries not in the module ++# using std::operator!=; ++# using std::operator<<; ++# using std::operator==; ++# using std::operator>>; ++# ++# The first is probably P1614 ++# The other 3 are hidden friend in the Standard but not in the header's synopis. ++# Maybe a paper not implemented? ++toplevel_headers.remove('random') ++ ++# This header also provides declarations in the namespace that might be an error ++# using std::operator!=; ++# using std::operator==; ++toplevel_headers.remove('filesystem') ++ ++# This header needs review, but first the placeholders (_1, etc) need to be available ++toplevel_headers.remove('functional') ++ ++ ++# This exports friend like ++# template friend class basic_string; ++# template friend class _LIBCPP_TEMPLATE_VIS vector; ++# template friend class _LIBCPP_TEMPLATE_VIS span; ++# The script needs to be adapted not to do that, ++# Note the other issues need to be investigated ++toplevel_headers.remove('iterator') ++ ++# the C++11 isblank is missing, this seems like a bug since there is no test either. ++# libcxx/test/std/localization/locales/locale.convenience/classification ++toplevel_headers.remove('locale') ++ ++# The header contains the following zombie names ++# return_temporary_buffer ++# get_temporary_buffer ++# did we forget to implement some papers? ++# Some parts have internal linker issues ++toplevel_headers.remove('memory') ++ ++# Some parts have been refactored and might be fixed upstream ++toplevel_headers.remove('system_error') ++ ++# a part is in __fwd/foo.h ++toplevel_headers.remove('ranges') ++ ++# also has some oddities ++toplevel_headers.remove('tuple') ++ ++# needs review ++toplevel_headers.remove('type_traits') ++toplevel_headers.remove('utility') ++ ++# Create empty file with all parts. ++print(f"// {RUN}: echo -n > %t.parts") ++ ++# Validate all module parts. ++for i, header in enumerate(toplevel_headers): ++ if header.endswith('.h'): # Skip C compatibility headers ++ continue ++ ++ # Dump the information as found in the module's cppm file. ++ print(f"// {RUN}: %{{clang-tidy}} %{{module}}/std/{header}.cppm --checks='-*,libcpp-header-exportable-declarations' " ++ f"-config='{{CheckOptions: [ {{key: libcpp-header-exportable-declarations.Header, value: {header}.cppm}} ]}}' " ++ f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} " ++ f"| sort > %t.{header}.module") ++ print(f"// {RUN}: cat %t.{header}.module >> %t.parts") ++ ++ # Dump the information as found in the module by using the header file(s). ++ skip = SkipDeclarations.get(header, "") ++ if len(skip): ++ skip = f", {{key: libcpp-header-exportable-declarations.SkipDeclarations, value: \"{skip}\"}}" ++ ++ extra_header = ExtraHeader.get(header, "") ++ if len(extra_header): ++ extra_header = f", {{key: libcpp-header-exportable-declarations.ExtraHeader, value: \"{extra_header}\"}}" ++ ++ print(f"// {RUN}: %{{clang-tidy}} %s --checks='-*,libcpp-header-exportable-declarations' " ++ f"-config='{{CheckOptions: [ {{key: libcpp-header-exportable-declarations.Header, value: {header}}} {skip} {extra_header} ]}}' " ++ f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} -DTEST_{i} " ++ f"| sort > %t.{header}.include") ++ ++ # Compare the cppm and header file(s) return the same results. ++ print(f"// {RUN}: diff -u %t.{header}.module %t.{header}.include") ++ ++ # The actual include script. ++ print(f"#if defined(TEST_{i})") ++ print(f"#include <{header}>") ++ print("#endif") ++ ++# Validate the module parts against the main module. ++ ++# Merge the data of the parts ++print(f"// {RUN}: sort -u -o %t.parts %t.parts") ++ ++# Dump the information as found in std.cppm. ++# ++# XXX This would require clang-tidy 17 since the the PCH files are not compatible with different versions ++###print(f"// {RUN}: %{{clang-tidy}} %{{module}}/std.cppm --checks='-*,libcpp-header-exportable-declarations' " ++### f"-config='{{CheckOptions: [ {{key: libcpp-header-exportable-declarations.Header, value: std.cppm}} ]}}' " ++### f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} " ++### f"| sort > %t.module") ++ ++# Compare the sum of the parts with the main module. ++###print(f"// {RUN}: diff -u %t.parts %t.module") ++ ++END-SCRIPT ++*/ ++ ++// DO NOT MANUALLY EDIT ANYTHING BETWEEN THE MARKERS BELOW ++// GENERATED-MARKER ++// RUN: echo -n > %t.parts ++// RUN: %{clang-tidy} %{module}/std/algorithm.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: algorithm.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.algorithm.module ++// RUN: cat %t.algorithm.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: algorithm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_0 | sort > %t.algorithm.include ++// RUN: diff -u %t.algorithm.module %t.algorithm.include ++#if defined(TEST_0) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/any.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: any.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.any.module ++// RUN: cat %t.any.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: any} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_1 | sort > %t.any.include ++// RUN: diff -u %t.any.module %t.any.include ++#if defined(TEST_1) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/atomic.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: atomic.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.atomic.module ++// RUN: cat %t.atomic.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: atomic} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_2 | sort > %t.atomic.include ++// RUN: diff -u %t.atomic.module %t.atomic.include ++#if defined(TEST_2) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/barrier.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: barrier.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.barrier.module ++// RUN: cat %t.barrier.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: barrier} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_3 | sort > %t.barrier.include ++// RUN: diff -u %t.barrier.module %t.barrier.include ++#if defined(TEST_3) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/bit.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: bit.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.bit.module ++// RUN: cat %t.bit.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: bit} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_4 | sort > %t.bit.include ++// RUN: diff -u %t.bit.module %t.bit.include ++#if defined(TEST_4) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/bitset.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: bitset.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.bitset.module ++// RUN: cat %t.bitset.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: bitset} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_5 | sort > %t.bitset.include ++// RUN: diff -u %t.bitset.module %t.bitset.include ++#if defined(TEST_5) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cassert.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cassert.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cassert.module ++// RUN: cat %t.cassert.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cassert} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_6 | sort > %t.cassert.include ++// RUN: diff -u %t.cassert.module %t.cassert.include ++#if defined(TEST_6) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cctype.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cctype.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cctype.module ++// RUN: cat %t.cctype.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cctype} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_7 | sort > %t.cctype.include ++// RUN: diff -u %t.cctype.module %t.cctype.include ++#if defined(TEST_7) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cerrno.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cerrno.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cerrno.module ++// RUN: cat %t.cerrno.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cerrno} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_8 | sort > %t.cerrno.include ++// RUN: diff -u %t.cerrno.module %t.cerrno.include ++#if defined(TEST_8) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cfenv.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cfenv.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cfenv.module ++// RUN: cat %t.cfenv.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cfenv} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_9 | sort > %t.cfenv.include ++// RUN: diff -u %t.cfenv.module %t.cfenv.include ++#if defined(TEST_9) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cfloat.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cfloat.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cfloat.module ++// RUN: cat %t.cfloat.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cfloat} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_10 | sort > %t.cfloat.include ++// RUN: diff -u %t.cfloat.module %t.cfloat.include ++#if defined(TEST_10) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/charconv.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: charconv.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.charconv.module ++// RUN: cat %t.charconv.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: charconv} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_11 | sort > %t.charconv.include ++// RUN: diff -u %t.charconv.module %t.charconv.include ++#if defined(TEST_11) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/chrono.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: chrono.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.chrono.module ++// RUN: cat %t.chrono.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: chrono} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_12 | sort > %t.chrono.include ++// RUN: diff -u %t.chrono.module %t.chrono.include ++#if defined(TEST_12) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cinttypes.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cinttypes.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cinttypes.module ++// RUN: cat %t.cinttypes.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cinttypes} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_13 | sort > %t.cinttypes.include ++// RUN: diff -u %t.cinttypes.module %t.cinttypes.include ++#if defined(TEST_13) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/climits.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: climits.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.climits.module ++// RUN: cat %t.climits.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: climits} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_14 | sort > %t.climits.include ++// RUN: diff -u %t.climits.module %t.climits.include ++#if defined(TEST_14) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/clocale.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: clocale.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.clocale.module ++// RUN: cat %t.clocale.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: clocale} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_15 | sort > %t.clocale.include ++// RUN: diff -u %t.clocale.module %t.clocale.include ++#if defined(TEST_15) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cmath.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cmath.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cmath.module ++// RUN: cat %t.cmath.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cmath} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_16 | sort > %t.cmath.include ++// RUN: diff -u %t.cmath.module %t.cmath.include ++#if defined(TEST_16) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/codecvt.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: codecvt.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.codecvt.module ++// RUN: cat %t.codecvt.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: codecvt} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_17 | sort > %t.codecvt.include ++// RUN: diff -u %t.codecvt.module %t.codecvt.include ++#if defined(TEST_17) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/compare.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: compare.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.compare.module ++// RUN: cat %t.compare.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: compare} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_18 | sort > %t.compare.include ++// RUN: diff -u %t.compare.module %t.compare.include ++#if defined(TEST_18) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/concepts.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: concepts.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.concepts.module ++// RUN: cat %t.concepts.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: concepts} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_20 | sort > %t.concepts.include ++// RUN: diff -u %t.concepts.module %t.concepts.include ++#if defined(TEST_20) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/coroutine.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: coroutine.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.coroutine.module ++// RUN: cat %t.coroutine.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: coroutine} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_21 | sort > %t.coroutine.include ++// RUN: diff -u %t.coroutine.module %t.coroutine.include ++#if defined(TEST_21) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/csetjmp.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: csetjmp.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.csetjmp.module ++// RUN: cat %t.csetjmp.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: csetjmp} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_22 | sort > %t.csetjmp.include ++// RUN: diff -u %t.csetjmp.module %t.csetjmp.include ++#if defined(TEST_22) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/csignal.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: csignal.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.csignal.module ++// RUN: cat %t.csignal.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: csignal} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_23 | sort > %t.csignal.include ++// RUN: diff -u %t.csignal.module %t.csignal.include ++#if defined(TEST_23) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cstdarg.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdarg.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdarg.module ++// RUN: cat %t.cstdarg.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdarg} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_24 | sort > %t.cstdarg.include ++// RUN: diff -u %t.cstdarg.module %t.cstdarg.include ++#if defined(TEST_24) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cstddef.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstddef.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstddef.module ++// RUN: cat %t.cstddef.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstddef} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_25 | sort > %t.cstddef.include ++// RUN: diff -u %t.cstddef.module %t.cstddef.include ++#if defined(TEST_25) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cstdio.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdio.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdio.module ++// RUN: cat %t.cstdio.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdio} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_26 | sort > %t.cstdio.include ++// RUN: diff -u %t.cstdio.module %t.cstdio.include ++#if defined(TEST_26) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cstdlib.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdlib.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdlib.module ++// RUN: cat %t.cstdlib.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstdlib} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_27 | sort > %t.cstdlib.include ++// RUN: diff -u %t.cstdlib.module %t.cstdlib.include ++#if defined(TEST_27) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cstring.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstring.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstring.module ++// RUN: cat %t.cstring.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cstring} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_28 | sort > %t.cstring.include ++// RUN: diff -u %t.cstring.module %t.cstring.include ++#if defined(TEST_28) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/ctime.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: ctime.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ctime.module ++// RUN: cat %t.ctime.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: ctime} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_29 | sort > %t.ctime.include ++// RUN: diff -u %t.ctime.module %t.ctime.include ++#if defined(TEST_29) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/cwctype.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cwctype.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cwctype.module ++// RUN: cat %t.cwctype.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: cwctype} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_31 | sort > %t.cwctype.include ++// RUN: diff -u %t.cwctype.module %t.cwctype.include ++#if defined(TEST_31) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/exception.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: exception.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.exception.module ++// RUN: cat %t.exception.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: exception} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_33 | sort > %t.exception.include ++// RUN: diff -u %t.exception.module %t.exception.include ++#if defined(TEST_33) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/execution.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: execution.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.execution.module ++// RUN: cat %t.execution.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: execution} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_34 | sort > %t.execution.include ++// RUN: diff -u %t.execution.module %t.execution.include ++#if defined(TEST_34) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/expected.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: expected.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.expected.module ++// RUN: cat %t.expected.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: expected} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_35 | sort > %t.expected.include ++// RUN: diff -u %t.expected.module %t.expected.include ++#if defined(TEST_35) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/format.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: format.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.format.module ++// RUN: cat %t.format.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: format} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_38 | sort > %t.format.include ++// RUN: diff -u %t.format.module %t.format.include ++#if defined(TEST_38) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/future.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: future.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.future.module ++// RUN: cat %t.future.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: future} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_39 | sort > %t.future.include ++// RUN: diff -u %t.future.module %t.future.include ++#if defined(TEST_39) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/initializer_list.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: initializer_list.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.initializer_list.module ++// RUN: cat %t.initializer_list.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: initializer_list} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_40 | sort > %t.initializer_list.include ++// RUN: diff -u %t.initializer_list.module %t.initializer_list.include ++#if defined(TEST_40) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/iomanip.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: iomanip.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.iomanip.module ++// RUN: cat %t.iomanip.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: iomanip} , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::operator<< std::operator>>"} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_42 | sort > %t.iomanip.include ++// RUN: diff -u %t.iomanip.module %t.iomanip.include ++#if defined(TEST_42) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/latch.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: latch.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.latch.module ++// RUN: cat %t.latch.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: latch} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_43 | sort > %t.latch.include ++// RUN: diff -u %t.latch.module %t.latch.include ++#if defined(TEST_43) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/limits.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: limits.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.limits.module ++// RUN: cat %t.limits.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: limits} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_44 | sort > %t.limits.include ++// RUN: diff -u %t.limits.module %t.limits.include ++#if defined(TEST_44) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/list.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: list.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.list.module ++// RUN: cat %t.list.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: list} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_46 | sort > %t.list.include ++// RUN: diff -u %t.list.module %t.list.include ++#if defined(TEST_46) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/new.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: new.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.new.module ++// RUN: cat %t.new.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: new} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_49 | sort > %t.new.include ++// RUN: diff -u %t.new.module %t.new.include ++#if defined(TEST_49) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/numbers.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: numbers.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.numbers.module ++// RUN: cat %t.numbers.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: numbers} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_50 | sort > %t.numbers.include ++// RUN: diff -u %t.numbers.module %t.numbers.include ++#if defined(TEST_50) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/numeric.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: numeric.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.numeric.module ++// RUN: cat %t.numeric.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: numeric} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_51 | sort > %t.numeric.include ++// RUN: diff -u %t.numeric.module %t.numeric.include ++#if defined(TEST_51) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/ratio.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: ratio.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ratio.module ++// RUN: cat %t.ratio.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: ratio} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_52 | sort > %t.ratio.include ++// RUN: diff -u %t.ratio.module %t.ratio.include ++#if defined(TEST_52) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/semaphore.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: semaphore.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.semaphore.module ++// RUN: cat %t.semaphore.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: semaphore} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_53 | sort > %t.semaphore.include ++// RUN: diff -u %t.semaphore.module %t.semaphore.include ++#if defined(TEST_53) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/shared_mutex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: shared_mutex.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.shared_mutex.module ++// RUN: cat %t.shared_mutex.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: shared_mutex} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_55 | sort > %t.shared_mutex.include ++// RUN: diff -u %t.shared_mutex.module %t.shared_mutex.include ++#if defined(TEST_55) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/source_location.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: source_location.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.source_location.module ++// RUN: cat %t.source_location.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: source_location} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_56 | sort > %t.source_location.include ++// RUN: diff -u %t.source_location.module %t.source_location.include ++#if defined(TEST_56) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/span.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: span.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.span.module ++// RUN: cat %t.span.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: span} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_57 | sort > %t.span.include ++// RUN: diff -u %t.span.module %t.span.include ++#if defined(TEST_57) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/stdexcept.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: stdexcept.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.stdexcept.module ++// RUN: cat %t.stdexcept.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: stdexcept} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_61 | sort > %t.stdexcept.include ++// RUN: diff -u %t.stdexcept.module %t.stdexcept.include ++#if defined(TEST_61) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/string.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: string.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.string.module ++// RUN: cat %t.string.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: string} , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::allocator"} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_65 | sort > %t.string.include ++// RUN: diff -u %t.string.module %t.string.include ++#if defined(TEST_65) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/string_view.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: string_view.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.string_view.module ++// RUN: cat %t.string_view.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: string_view} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_67 | sort > %t.string_view.include ++// RUN: diff -u %t.string_view.module %t.string_view.include ++#if defined(TEST_67) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/strstream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: strstream.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.strstream.module ++// RUN: cat %t.strstream.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: strstream} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_68 | sort > %t.strstream.include ++// RUN: diff -u %t.strstream.module %t.strstream.include ++#if defined(TEST_68) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/typeindex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: typeindex.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.typeindex.module ++// RUN: cat %t.typeindex.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: typeindex} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_70 | sort > %t.typeindex.include ++// RUN: diff -u %t.typeindex.module %t.typeindex.include ++#if defined(TEST_70) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/typeinfo.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: typeinfo.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.typeinfo.module ++// RUN: cat %t.typeinfo.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: typeinfo} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_71 | sort > %t.typeinfo.include ++// RUN: diff -u %t.typeinfo.module %t.typeinfo.include ++#if defined(TEST_71) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/valarray.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: valarray.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.valarray.module ++// RUN: cat %t.valarray.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: valarray} , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::sliceExpr"} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_73 | sort > %t.valarray.include ++// RUN: diff -u %t.valarray.module %t.valarray.include ++#if defined(TEST_73) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/variant.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: variant.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.variant.module ++// RUN: cat %t.variant.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: variant} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_74 | sort > %t.variant.include ++// RUN: diff -u %t.variant.module %t.variant.include ++#if defined(TEST_74) ++#include ++#endif ++// RUN: %{clang-tidy} %{module}/std/version.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: version.cppm} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.version.module ++// RUN: cat %t.version.module >> %t.parts ++// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: version} ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_75 | sort > %t.version.include ++// RUN: diff -u %t.version.module %t.version.include ++#if defined(TEST_75) ++#include ++#endif ++// RUN: sort -u -o %t.parts %t.parts ++// GENERATED-MARKER +diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp +index 54819c666392..cbdb6de3db90 100644 +--- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp ++++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp +@@ -8,7 +8,10 @@ + + // UNSUPPORTED: c++03, c++11, c++14 + +-// XFAIL: no-wide-characters ++// Modules won't issue a diagnostic for deprecated symbols. ++// UNSUPPORTED: use_module_std, use_module_std.compat ++ ++// UNSUPPORTED: no-wide-characters + + // + +diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp +index f44a8af3d936..5de926c6edfc 100644 +--- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp ++++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp +@@ -7,6 +7,9 @@ + //===----------------------------------------------------------------------===// + + // UNSUPPORTED: c++03, c++11, c++14 ++// Modules won't issue a diagnostic for deprecated symbols. ++// UNSUPPORTED: use_module_std, use_module_std.compat ++ + // UNSUPPORTED: no-wide-characters + + // +diff --git a/libcxx/test/std/time/time.syn/formatter_tests.h b/libcxx/test/std/time/time.syn/formatter_tests.h +index 42c176b3b47e..e72c198d7a90 100644 +--- a/libcxx/test/std/time/time.syn/formatter_tests.h ++++ b/libcxx/test/std/time/time.syn/formatter_tests.h +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #define STR(S) MAKE_STRING(CharT, S) + #define SV(S) MAKE_STRING_VIEW(CharT, S) +diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp +index 0e46dbe635aa..482c99629f35 100644 +--- a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp ++++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp +@@ -9,6 +9,9 @@ + // UNSUPPORTED: libcpp-has-no-incomplete-format + // UNSUPPORTED: no-wide-characters + ++// Modules can't be used with compilation flags that change the PCH. ++// UNSUPPORTED: use_module_std, use_module_std.compat ++ + // Validate it works regardless of the signedness of `char`. + // RUN: %{cxx} %{flags} %{compile_flags} -fsigned-char -fsyntax-only %s + // RUN: %{cxx} %{flags} %{compile_flags} -funsigned-char -fsyntax-only %s +diff --git a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp b/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp +index ceeb4dd3eeec..ea4d30fbdf33 100644 +--- a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp ++++ b/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp +@@ -6,13 +6,16 @@ + // + //===----------------------------------------------------------------------===// + ++// UNSUPPORTED: c++03, c++11 ++ ++// The define changes the header which is not possible in modules. ++// UNSUPPORTED: use_module_std, use_module_std.compat ++ + // + + // template + // using make_integer_sequence = integer_sequence; + +-// UNSUPPORTED: c++03, c++11 +- + #define _LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE + #include "make_integer_seq.pass.cpp" + +diff --git a/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp b/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp +index 28495cfebd45..0c23d9d1aa20 100644 +--- a/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp ++++ b/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp +@@ -9,6 +9,7 @@ + // UNSUPPORTED: c++03 + + // ADDITIONAL_COMPILE_FLAGS: -D _LIBCPP_USE_IS_CONVERTIBLE_FALLBACK ++// UNSUPPORTED: use_module_std, use_module_std.compat + + // type_traits + +diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +index bd1611fb0a9c..1e3cdd6d2278 100644 +--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt ++++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +@@ -16,6 +16,7 @@ endif() + + set(SOURCES + abi_tag_on_virtual.cpp ++ header_exportable_declarations.cpp + hide_from_abi.cpp + proper_version_checks.cpp + qualify_declval.cpp +diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp +new file mode 100644 +index 000000000000..9a8903779f2e +--- /dev/null ++++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp +@@ -0,0 +1,177 @@ ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "clang-tidy/ClangTidyCheck.h" ++#include "clang-tidy/ClangTidyModuleRegistry.h" ++ ++#include "header_exportable_declarations.hpp" ++ ++#include ++#include ++#include ++ ++namespace libcpp { ++header_exportable_declarations::header_exportable_declarations( ++ llvm::StringRef name, clang::tidy::ClangTidyContext* context) ++ : clang::tidy::ClangTidyCheck(name, context), ++ header_(Options.get("Header")), ++ extra_header_(Options.get("ExtraHeader", "")) { ++ if (!header_) ++ llvm::errs() << "No header is provided.\n"; ++ ++ // Header -> name ++ // Module -> name ++ // ++ // SkipDeclaration -> space separated list declarationst to ignore ++ // They will be added to decls_. Note typical separators may be part of the ++ // identifier. ++ ++ std::optional skip_list = Options.get("SkipDeclarations"); ++ if (skip_list) ++ for (auto decl : std::views::split(*skip_list, ' ')) { ++ std::string s; ++ std::ranges::copy(decl, std::back_inserter(s)); // use range based constructor ++ decls_.emplace(std::move(s)); ++ } ++} ++ ++void header_exportable_declarations::registerMatchers(clang::ast_matchers::MatchFinder* finder) { ++ // there are no public names in the Standard starting with an underscore, so no need to check the strict rules ++ using namespace clang::ast_matchers; ++ ++ bool is_module = header_->endswith(".cppm"); ++ ++ if (!is_module) ++ finder->addMatcher( ++ namedDecl( ++ // Looks at the common locations where headers store their data ++ // * header ++ // * __header/*.h ++ // * __fwd/header.h ++ anyOf(isExpansionInFileMatching(("v1/__" + *header_ + "/").str()), ++ isExpansionInFileMatching(extra_header_), ++ isExpansionInFileMatching(("v1/__fwd/" + *header_ + "\\.h$").str()), ++ isExpansionInFileMatching(("v1/" + *header_ + "$").str()))) ++ .bind("header_exportable_declarations"), ++ this); ++ else ++ finder->addMatcher(namedDecl(isExpansionInFileMatching(*header_)).bind("header_exportable_declarations"), this); ++} ++ ++/// Returns the qualified name of a declaration. ++/// ++/// There is a small issue with qualified names. Typically the name returned is ++/// in the namespace \c std instead of the namespace \c std::__1. Except when a ++/// name is declared both in the namespace \c std and in the namespace ++/// \c std::__1. In that case the returned value will adjust the name to use ++/// the namespace \c std. ++/// ++/// The reason this happens is due to some parts of libc++ using ++/// \code namespace std \endcode instead of ++/// \code _LIBCPP_BEGIN_NAMESPACE_STD \endcode ++/// Some examples ++/// * cstddef has bitwise operators for the type \c byte ++/// * exception has equality operators for the type \c exception_ptr ++/// * initializer_list has the functions \c begin and \c end ++/// ++/// TODO is this an issue in libc++? ++static std::string get_qualified_name(const clang::NamedDecl& decl) { ++ std::string result = decl.getQualifiedNameAsString(); ++ ++ if (result.starts_with("std::__1::")) ++ result.erase(5, 5); ++ ++ return result; ++} ++ ++static bool is_vaiable_declaration(const clang::NamedDecl* decl) { ++ // Declarations nested in records are automatically exported with the record itself. ++ if (!decl->getDeclContext()->isNamespace()) ++ return false; ++ ++ // Declarations that are a subobject of a friend Declaration are automatically exported with the record itself. ++ if (decl->getFriendObjectKind() != clang::Decl::FOK_None) ++ return false; ++ ++ // Function declarations ++ if (clang::CXXMethodDecl::classof(decl)) ++ return false; ++ ++ if (clang::CXXDeductionGuideDecl::classof(decl)) ++ return false; ++ ++ if (clang::FunctionDecl::classof(decl)) ++ return true; ++ ++ // Record declarations ++ ++ if (clang::CXXConstructorDecl::classof(decl)) ++ return false; ++ ++ // implicit constructors disallowed ++ if (const auto* r = llvm::dyn_cast_or_null(decl)) ++ return !r->isLambda() && !r->isImplicit(); ++ ++ // Enumerate declarations ++ ++ if (clang::EnumDecl::classof(decl)) ++ return true; ++ ++ // Variable declarations ++ if (clang::VarDecl::classof(decl)) ++ return true; ++ ++ // Concept declarations ++ if (clang::ConceptDecl::classof(decl)) ++ return true; ++ ++ // Using declarations ++ if (clang::TypedefNameDecl::classof(decl)) ++ return true; ++ if (clang::UsingDecl::classof(decl)) ++ return true; ++ ++ return false; ++} ++ ++/// Returns the name is a reserved name. ++/// ++/// This test misses 2 candidates which are not used in libc++ ++/// * any identifier with two underscores not at the start ++/// * a name with a leading underscore in the global namespace ++bool is_reserved_name(const std::string& name) { ++ std::size_t pos = name.find("::_"); ++ if (pos == std::string::npos) ++ return false; ++ ++ if (pos + 3 > name.size()) ++ return false; ++ ++ return name[pos + 3] == '_' || std::isupper(name[pos + 3]); ++} ++ ++void header_exportable_declarations::check(const clang::ast_matchers::MatchFinder::MatchResult& result) { ++ if (const auto* decl = result.Nodes.getNodeAs("header_exportable_declarations"); decl != nullptr) { ++ // if it's a template specialization then need to export the main declaration? ++ ++ if (!is_vaiable_declaration(decl)) ++ return; ++ ++ std::string name = get_qualified_name(*decl); ++ if (is_reserved_name(name)) ++ return; ++ ++ if (decls_.contains(name)) ++ return; ++ ++ std::cout << "using " << std::string{name} << ";\n"; ++ decls_.insert(name); ++ } ++} ++ ++} // namespace libcpp +diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp +new file mode 100644 +index 000000000000..691bca8f755a +--- /dev/null ++++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp +@@ -0,0 +1,23 @@ ++//===----------------------------------------------------------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "clang-tidy/ClangTidyCheck.h" ++ ++namespace libcpp { ++class header_exportable_declarations : public clang::tidy::ClangTidyCheck { ++public: ++ header_exportable_declarations(llvm::StringRef, clang::tidy::ClangTidyContext*); ++ void registerMatchers(clang::ast_matchers::MatchFinder*) override; ++ void check(const clang::ast_matchers::MatchFinder::MatchResult&) override; ++ ++private: ++ const std::optional header_; ++ const llvm::StringRef extra_header_; ++ std::set decls_; ++}; ++} // namespace libcpp +diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp +index 9ecb41e20a2d..fa4f2c69538b 100644 +--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp ++++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp +@@ -10,6 +10,7 @@ + #include "clang-tidy/ClangTidyModuleRegistry.h" + + #include "abi_tag_on_virtual.hpp" ++#include "header_exportable_declarations.hpp" + #include "hide_from_abi.hpp" + #include "proper_version_checks.hpp" + #include "qualify_declval.hpp" +@@ -21,11 +22,12 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule { + public: + void addCheckFactories(clang::tidy::ClangTidyCheckFactories& check_factories) override { + check_factories.registerCheck("libcpp-avoid-abi-tag-on-virtual"); ++ check_factories.registerCheck("libcpp-header-exportable-declarations"); + check_factories.registerCheck("libcpp-hide-from-abi"); + check_factories.registerCheck("libcpp-cpp-version-check"); ++ check_factories.registerCheck("libcpp-qualify-declval"); + check_factories.registerCheck("libcpp-robust-against-adl"); + check_factories.registerCheck("libcpp-uglify-attributes"); +- check_factories.registerCheck("libcpp-qualify-declval"); + } + }; + } // namespace +diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml +index 474138d21f4f..d77ea08177d7 100644 +--- a/libcxx/utils/ci/buildkite-pipeline.yml ++++ b/libcxx/utils/ci/buildkite-pipeline.yml +@@ -47,1000 +47,3 @@ steps: + - exit_status: -1 # Agent was lost + limit: 2 + timeout_in_minutes: 120 +- +- - label: "Generated output" +- command: "libcxx/utils/ci/run-buildbot check-generated-output" +- artifact_paths: +- - "**/generated_output.patch" +- - "**/generated_output.status" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- CLANG_FORMAT: "/usr/bin/clang-format-${LLVM_STABLE_VERSION}" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Documentation" +- command: "libcxx/utils/ci/run-buildbot documentation" +- artifact_paths: +- - "**/test-results.xml" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # +- # General testing with the default configuration, under all the supported +- # Standard modes, with Clang and GCC. This catches most issues upfront. +- # The goal of this step is to catch most issues while being very fast. +- # +- - wait +- +- - label: "GCC ${GCC_STABLE_VERSION} / C++latest" +- command: "libcxx/utils/ci/run-buildbot generic-gcc" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "gcc-${GCC_STABLE_VERSION}" +- CXX: "g++-${GCC_STABLE_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "C++2b" +- command: "libcxx/utils/ci/run-buildbot generic-cxx2b" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Modular build" +- command: "libcxx/utils/ci/run-buildbot generic-modules" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "C++11" +- command: "libcxx/utils/ci/run-buildbot generic-cxx11" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "C++03" +- command: "libcxx/utils/ci/run-buildbot generic-cxx03" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # +- # All other supported configurations of libc++. +- # +- - wait +- +- - label: "C++20" +- command: "libcxx/utils/ci/run-buildbot generic-cxx20" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "C++17" +- command: "libcxx/utils/ci/run-buildbot generic-cxx17" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "C++14" +- command: "libcxx/utils/ci/run-buildbot generic-cxx14" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Tests with the supported compilers. +- - label: "GCC ${GCC_STABLE_VERSION} / C++11" +- command: "libcxx/utils/ci/run-buildbot generic-gcc-cxx11" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "gcc-${GCC_STABLE_VERSION}" +- CXX: "g++-${GCC_STABLE_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Clang 15" +- command: "libcxx/utils/ci/run-buildbot generic-cxx2b" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-15" +- CXX: "clang++-15" +- # TODO LLVM18: Enable clang-tidy +- # ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Clang 16" +- command: "libcxx/utils/ci/run-buildbot generic-cxx2b" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-16" +- CXX: "clang++-16" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Tests with the sanitizers. +- - group: "Sanitizers" +- steps: +- - label: "ASAN" +- command: "libcxx/utils/ci/run-buildbot generic-asan" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "TSAN" +- command: "libcxx/utils/ci/run-buildbot generic-tsan" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "UBSAN" +- command: "libcxx/utils/ci/run-buildbot generic-ubsan" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "MSAN" +- command: "libcxx/utils/ci/run-buildbot generic-msan" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Tests with the various supported ways to build libc++. +- - label: "Bootstrapping build" +- command: "libcxx/utils/ci/run-buildbot bootstrapping-build" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- - "**/crash_diagnostics/*" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- LLVM_SYMBOLIZER_PATH: "/usr/bin/llvm-symbolizer-${LLVM_HEAD_VERSION}" +- CLANG_CRASH_DIAGNOSTICS_DIR: "crash_diagnostics" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Tests with various build configurations. +- - label: "Static libraries" +- command: "libcxx/utils/ci/run-buildbot generic-static" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Shared library with merged ABI and unwinder libraries" +- command: "libcxx/utils/ci/run-buildbot generic-merged" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Assertions enabled" +- command: "libcxx/utils/ci/run-buildbot generic-assertions" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Debug mode" +- command: "libcxx/utils/ci/run-buildbot generic-debug-mode" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "With LLVM's libunwind" +- command: "libcxx/utils/ci/run-buildbot generic-with_llvm_unwinder" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Modular build with Local Submodule Visibility" +- command: "libcxx/utils/ci/run-buildbot generic-modules-lsv" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - group: "Parts disabled" +- steps: +- - label: "No threads" +- command: "libcxx/utils/ci/run-buildbot generic-no-threads" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No filesystem" +- command: "libcxx/utils/ci/run-buildbot generic-no-filesystem" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No random device" +- command: "libcxx/utils/ci/run-buildbot generic-no-random_device" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No fstream" +- command: "libcxx/utils/ci/run-buildbot generic-no-fstream" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No locale" +- command: "libcxx/utils/ci/run-buildbot generic-no-localization" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No Unicode" +- command: "libcxx/utils/ci/run-buildbot generic-no-unicode" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No wide characters" +- command: "libcxx/utils/ci/run-buildbot generic-no-wide-characters" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No experimental features" +- command: "libcxx/utils/ci/run-buildbot generic-no-experimental" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "No exceptions" +- command: "libcxx/utils/ci/run-buildbot generic-noexceptions" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Unstable ABI" +- command: "libcxx/utils/ci/run-buildbot generic-abi-unstable" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Other non-testing CI jobs +- - label: "Benchmarks" +- command: "libcxx/utils/ci/run-buildbot benchmarks" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang-${LLVM_HEAD_VERSION}" +- CXX: "clang++-${LLVM_HEAD_VERSION}" +- ENABLE_CLANG_TIDY: "On" +- agents: +- queue: "libcxx-builders" +- os: "linux" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Tests on non-Unix platforms +- - group: ":windows: Windows" +- steps: +- - label: "Clang-cl (DLL)" +- command: "bash libcxx/utils/ci/run-buildbot clang-cl-dll" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Clang-cl (Static)" +- command: "bash libcxx/utils/ci/run-buildbot clang-cl-static" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Clang-cl (no vcruntime exceptions)" +- command: "bash libcxx/utils/ci/run-buildbot clang-cl-no-vcruntime" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- +- - label: "MinGW (DLL, x86_64)" +- command: "bash libcxx/utils/ci/run-buildbot mingw-dll" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "MinGW (Static, x86_64)" +- command: "bash libcxx/utils/ci/run-buildbot mingw-static" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "MinGW (DLL, i686)" +- command: "bash libcxx/utils/ci/run-buildbot mingw-dll-i686" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "windows" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - group: ":apple: Apple" +- steps: +- - label: "MacOS x86_64" +- command: "libcxx/utils/ci/run-buildbot generic-cxx20" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "x86_64" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "MacOS arm64" +- command: "libcxx/utils/ci/run-buildbot generic-cxx20" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "arm64" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "MacOS with Modules" +- command: "libcxx/utils/ci/run-buildbot generic-modules" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Build with the configuration we use to generate libc++.dylib on Apple platforms +- - label: "Apple system" +- command: "libcxx/utils/ci/run-buildbot apple-system" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "arm64" # This can technically run on any architecture, but we have more resources on arm64 so we pin this job to arm64 +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- # Test back-deployment to older Apple platforms +- - label: "Apple back-deployment macosx10.9" +- command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-10.9" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "x86_64" # We need to use x86_64 for back-deployment CI on this target since macOS didn't support arm64 back then. +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Apple back-deployment macosx10.15" +- command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-10.15" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "x86_64" # We need to use x86_64 for back-deployment CI on this target since macOS didn't support arm64 back then. +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Apple back-deployment macosx11.0 arm64" +- command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-11.0" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- arch: "arm64" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Apple back-deployment with assertions enabled" +- command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-assertions-11.0" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders" +- os: "macos" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - group: "ARM" +- steps: +- - label: "AArch64" +- command: "libcxx/utils/ci/run-buildbot aarch64" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "aarch64" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "AArch64 -fno-exceptions" +- command: "libcxx/utils/ci/run-buildbot aarch64-noexceptions" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "aarch64" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Armv8" +- command: "libcxx/utils/ci/run-buildbot armv8" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "armv8l" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Armv8 -fno-exceptions" +- command: "libcxx/utils/ci/run-buildbot armv8-noexceptions" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "armv8l" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Armv7" +- command: "libcxx/utils/ci/run-buildbot armv7" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "armv8l" # Compiling for v7, running on v8 hardware +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "Armv7 -fno-exceptions" +- command: "libcxx/utils/ci/run-buildbot armv7-noexceptions" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- agents: +- queue: "libcxx-builders-linaro-arm" +- arch: "armv8l" # Compiling for v7, running on v8 hardware +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - group: "AIX" +- steps: +- - label: "AIX (32-bit)" +- command: "libcxx/utils/ci/run-buildbot aix" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang" +- CXX: "clang++" +- OBJECT_MODE: "32" +- agents: +- queue: libcxx-builders +- os: aix +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - label: "AIX (64-bit)" +- command: "libcxx/utils/ci/run-buildbot aix" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang" +- CXX: "clang++" +- OBJECT_MODE: "64" +- agents: +- queue: libcxx-builders +- os: aix +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +- +- - group: "FreeBSD" +- steps: +- - label: "FreeBSD 13 amd64" +- command: "libcxx/utils/ci/run-buildbot generic-cxx2b" +- artifact_paths: +- - "**/test-results.xml" +- - "**/*.abilist" +- env: +- CC: "clang15" +- CXX: "clang++15" +- agents: +- queue: "libcxx-builders" +- os: "freebsd" +- retry: +- automatic: +- - exit_status: -1 # Agent was lost +- limit: 2 +- timeout_in_minutes: 120 +diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot +index 15b8688bb8a8..467a3fa404c0 100755 +--- a/libcxx/utils/ci/run-buildbot ++++ b/libcxx/utils/ci/run-buildbot +@@ -89,7 +89,7 @@ INSTALL_DIR="${BUILD_DIR}/install" + # version will generally work with the Clang shipped in Xcode (e.g. if Clang + # knows about -std=c++20, the CMake bundled in Xcode will probably know about + # that flag too). +-if xcrun --find ninja &>/dev/null; then NINJA="$(xcrun --find ninja)"; else NINJA="ninja"; fi ++if xcrun --find ninja &>/dev/null; then NINJA="$(xcrun --find ninja)"; else NINJA="/usr/local/bin/ninja"; fi + if xcrun --find cmake &>/dev/null; then CMAKE="$(xcrun --find cmake)"; else CMAKE="cmake"; fi + + function clean() { +@@ -378,6 +378,24 @@ generic-with_llvm_unwinder) + generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON + check-runtimes + ;; ++generic-module-std) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std.cmake" ++ check-runtimes ++;; ++generic-module-std-compat) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" ++ check-runtimes ++;; + generic-modules) + clean + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules.cmake" +@@ -441,6 +459,99 @@ generic-noexceptions) + check-abi-list + ;; + # ++# Parts removed using the std.compat module ++# ++generic-module-std-compat-no-threads) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-threads.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-filesystem) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-filesystem.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-random_device) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-random_device.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-fstream) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-fstream.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-localization) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-unicode) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-unicode.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-wide-characters) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-wide-characters.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-no-experimental) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-experimental.cmake" ++ check-runtimes ++;; ++generic-module-std-compat-noexceptions) ++ clean ++ export CC=/usr/lib/llvm-17/bin/clang ++ export CXX=/usr/lib/llvm-17/bin/clang++ ++ export CMAKE=/opt/bin/cmake ++ echo "Manually selected CMake 3.26 instead of the system version" ++ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-compat.cmake" \ ++ -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-noexceptions.cmake" ++ check-runtimes ++;; ++# + # Other miscellaneous jobs + # + generic-abi-unstable) +diff --git a/libcxx/utils/generate_header_tests.py b/libcxx/utils/generate_header_tests.py +index f9f9ddc4cfdc..aca5f4f7be50 100755 +--- a/libcxx/utils/generate_header_tests.py ++++ b/libcxx/utils/generate_header_tests.py +@@ -144,6 +144,7 @@ def main(): + produce(test.joinpath('libcxx/double_include.sh.cpp'), variables) + produce(test.joinpath('libcxx/min_max_macros.compile.pass.cpp'), variables) + produce(test.joinpath('libcxx/modules_include.sh.cpp'), variables) ++ produce(test.joinpath('libcxx/module_std.sh.cpp'), variables) + produce(test.joinpath('libcxx/nasty_macros.compile.pass.cpp'), variables) + produce(test.joinpath('libcxx/no_assert_include.compile.pass.cpp'), variables) + produce(test.joinpath('libcxx/private_headers.verify.cpp'), variables) +diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py +index 99ccb5af9f5d..0f7c1539d609 100644 +--- a/libcxx/utils/libcxx/test/dsl.py ++++ b/libcxx/utils/libcxx/test/dsl.py +@@ -12,6 +12,7 @@ import pipes + import platform + import re + import shutil ++import subprocess + import tempfile + + import libcxx.test.format +@@ -386,6 +387,61 @@ class AddFlag(ConfigAction): + def pretty(self, config, litParams): + return 'add {} to %{{flags}}'.format(self._getFlag(config)) + ++def _getSubstitution(substitution, config): ++ for (orig, replacement) in config.substitutions: ++ if orig == substitution: ++ return replacement ++ raise ValueError('Substitution {} is not in the config.'.format(substitution)) ++ ++# TODO This solution works, but is way too slow. Running in the CI ++# should trigger the build once. Running one test will also trigger this ++# which gives quite a overhead when quickly testing some changes. ++class AddModule(ConfigAction): ++ ++ def applyTo(self, config): ++ build = os.path.join(config.test_exec_root, '__config_module__') ++ ++ cxx = _getSubstitution('%{cxx}', config) ++ std = _getSubstitution('%{cxx_std}', config) ++ if std == 'cxx2b': ++ std = '23' ++ else: ++ std = '17' # Not allowed for modules ++ ++ flags = _getSubstitution('%{flags}', config) ++ include = _getSubstitution('%{include}', config) ++ source = _getSubstitution('%{module}', config) ++ ++ cmake = _getSubstitution('%{cmake}', config) ++ make = _getSubstitution('%{make}', config) ++ generator = _getSubstitution('%{generator}', config) ++ ++ print(f"cxx {cxx}") ++ print(f"std {std}") ++ print(f"flags {flags}") ++ print(f"include {include}") ++ print(f"source {source}") ++ ++ print(f"cmake {cmake}") ++ print(f"make {make}") ++ print(f"generator {generator}") ++ ++ subprocess.check_call([cmake, ++ "-G" + generator, ++ "-DCMAKE_MAKE_PROGRAM=" + make, ++ "-B" + build, ++ "-H" + source, ++ "-DCMAKE_CXX_COMPILER_WORKS=TRUE", # The compiler test fails, but forcing this works ++ "-DCMAKE_CXX_COMPILER=" + cxx, ++ "-DCMAKE_CXX_STANDARD=" + std, ++ "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", ++ f"-DCMAKE_CXX_FLAGS={flags}", ++ ], env={}) ++ ++ subprocess.check_call([cmake, "--build", build], env={}) ++ ++ def pretty(self, config, litParams): ++ pass + + class AddFlagIfSupported(ConfigAction): + """ +@@ -438,13 +494,13 @@ class AddLinkFlag(ConfigAction): + + def applyTo(self, config): + flag = self._getFlag(config) +- assert hasCompileFlag(config, flag), "Trying to enable link flag {}, which is not supported".format(flag) ++ # TODO This fails when enabling the modular flags. ++ #assert hasCompileFlag(config, flag), "Trying to enable link flag {}, which is not supported".format(flag) + config.substitutions = _appendToSubstitution(config.substitutions, '%{link_flags}', flag) + + def pretty(self, config, litParams): + return 'append {} to %{{link_flags}}'.format(self._getFlag(config)) + +- + class PrependLinkFlag(ConfigAction): + """ + This action prepends the given flag to the %{link_flags} substitution. +diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py +index 3d0addb9ba4b..8cef94012e72 100644 +--- a/libcxx/utils/libcxx/test/params.py ++++ b/libcxx/utils/libcxx/test/params.py +@@ -68,6 +68,21 @@ def getStdFlag(cfg, std): + return '-std='+fallbacks[std] + return None + ++_allModules = ['none', 'clang', 'std', 'std.compat'] ++def getModuleFlag(cfg, enable_modules): ++ # Originaly the flag was a Boolean, this maps the original Boolean values ++ # to the new enumerate values. ++ fallbacks = { ++ 'none': 'False', ++ 'clang': 'True', ++ } ++ if enable_modules in _allModules: ++ return enable_modules ++ if enable_modules in fallbacks: ++ return fallbacks[enable_modules] ++ return None ++ ++ + DEFAULT_PARAMETERS = [ + Parameter(name='target_triple', type=str, + help="The target triple to compile the test suite for. This must be " +@@ -87,13 +102,30 @@ DEFAULT_PARAMETERS = [ + AddCompileFlag(lambda cfg: getStdFlag(cfg, std)), + ]), + +- Parameter(name='enable_modules', choices=[True, False], type=bool, default=False, +- help="Whether to build the test suite with Clang modules enabled.", +- actions=lambda modules: [ ++ Parameter(name='enable_modules', choices=_allModules + ['True', 'False'], type=str, ++ help="Whether to build the test suite with modules enabled. Select " ++ "Clang for Clang modules and c++ for C++ Standard modules", ++ default=lambda cfg: next(s for s in _allModules if getModuleFlag(cfg, s)), ++ actions=lambda enable_modules: [ + AddFeature('modules-build'), + AddCompileFlag('-fmodules'), + AddCompileFlag('-fcxx-modules'), # AppleClang disregards -fmodules entirely when compiling C++. This enables modules for C++. +- ] if modules else []), ++ ] if enable_modules == "clang" or enable_modules == "True" else [ ++ AddFeature('use_module_std'), ++ AddCompileFlag('-DTEST_USE_MODULE'), ++ AddCompileFlag('-DTEST_USE_MODULE_STD'), ++ AddCompileFlag(lambda cfg: '-fprebuilt-module-path=' + os.path.join(cfg.test_exec_root, '__config_module__/CMakeFiles/std.dir')), ++ AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '__config_module__/libstd.a')), ++ AddModule(), ++ ] if enable_modules == "std" else [ ++ AddFeature('use_module_std.compat'), ++ AddCompileFlag('-DTEST_USE_MODULE'), ++ AddCompileFlag("-DTEST_USE_MODULE_STD_COMPAT"), ++ AddCompileFlag(lambda cfg: '-fprebuilt-module-path=' + os.path.join(cfg.test_exec_root, '__config_module__/CMakeFiles/std.compat.dir')), ++ AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '__config_module__/libstd.compat.a')), ++ AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '__config_module__/libstd.a')), ++ AddModule(), ++ ] if enable_modules == "std.compat" else []), + + Parameter(name='enable_modules_lsv', choices=[True, False], type=bool, default=False, + help="Whether to enable Local Submodule Visibility in the Modules build.", +diff --git a/libcxx/utils/use_modules_in_test.py b/libcxx/utils/use_modules_in_test.py +new file mode 100755 +index 000000000000..e63383460a71 +--- /dev/null ++++ b/libcxx/utils/use_modules_in_test.py +@@ -0,0 +1,300 @@ ++#!/usr/bin/env python ++# ===------------------------------------------------------------------------------===## ++# ++# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++# See https://llvm.org/LICENSE.txt for license information. ++# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++# ++# ===------------------------------------------------------------------------------===## ++ ++# This script converts a regular test to a test using modules. ++# ++# Note this script is mainly used to test the patch https://reviews.llvm.org/D144994 ++# It has not been decided that libc++ will use this approach for modules. Therefore ++# the transformation uses a simple algorithm and generates not the prettiest output. ++# ++# The main goal is to quickly convert a batch of tests to the use modules to test ++# whether the std module works for the headers that have been converted. The ++# script can't be executed twice on the same header, so it's intended this ++# script is executed on a not-yet converted code base. ++# ++# Usage ++# use_modules_in_test.py ++# ++# If the file contains at least one of the headers that is available in the std module ++# it will add a guarded import statement. All headers that are in the module std will ++# be included conditionally. ++ ++import re ++import sys ++from dataclasses import dataclass, field ++ ++ ++HEADERS_MODULE_STD = [ ++ "algorithm", ++ "any", ++ "array", ++ "atomic", ++ "barrier", ++ "bit", ++ "bitset", ++ "cctype", ++ "cfenv", ++ "charconv", ++ "chrono", ++ "cinttypes", ++ "climits", ++ "clocale", ++ "cmath", ++ "codecvt", ++ "compare", ++ "complex", ++ "concepts", ++ "coroutines", ++ "csetjmp", ++ "csignal", ++ "cstdarg", ++ "cstddef", ++ "cstdio", ++ "cstdlib", ++ "cstlib", ++ "cstring", ++ "ctime", ++ "ctype.h", ++ "cuchar", ++ "cwchar", ++ "cwctype", ++ "deque", ++ "exception", ++ "execution", ++ "expected", ++ "fenv.h", ++ "filesystem", ++ "flat_map", ++ "flat_set", ++ "float.h", ++ "format", ++ "forward_list", ++ "fstream", ++ "functional", ++ "generator", ++ "initializer_list", ++ "inttypes.h", ++ "iomanip", ++ "ios", ++ "iostream", ++ "istream", ++ "iterator", ++ "latch", ++ "limits", ++ "list", ++ "locale", ++ "locale.h", ++ "map", ++ "math.h", ++ "mdspan", ++ "memory", ++ "memory_resource", ++ "mutex", ++ "new", ++ "numbers", ++ "numeric", ++ "optional", ++ "ostream", ++ "print", ++ "queue", ++ "random", ++ "ranges", ++ "ratio", ++ "regex", ++ "scoped_allocator", ++ "semaphore", ++ "set", ++ "setjmp.h", ++ "shared_mutex", ++ "signal.h", ++ "source_location", ++ "span", ++ "spanstream", ++ "sstream", ++ "stack", ++ "stacktrace", ++ "stdarg.h", ++ "stddef.h", ++ "stdexcept", ++ "stdfloat", ++ "stdint.h", ++ "stdio.h", ++ "stdlib.h", ++ "stop_token", ++ "streambuf", ++ "string", ++ "string.h", ++ "string_view", ++ "strstream", ++ "syncstream", ++ "system_error", ++ "thread", ++ "time.h", ++ "tuple", ++ "type_traits", ++ "typeindex", ++ "typeinfo", ++ "uchar.h", ++ "unordered_map", ++ "unordered_set", ++ "utility", ++ "valarray", ++ "variant", ++ "vector", ++ "wchar.h", ++ "wctype.h", ++] ++ ++# Tests that need to be marked as XFAIL for various reasons ++# ++# For example is_literal type has been removed from C++20, the tests reenables it using ++# test specific compile flags. This is not supported by modules. ++UNSUPPORTED_TESTS = [ ++ "libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp", ++] ++# Due to a Clang limitation the import needs to be after all includes. ++# Therefore non-system includes are parsed too. ++INCLUDE_REGEX = re.compile(r"^\s*#\s*include\s*[\"<](?P[^\">]+)[\">]") ++ ++# Ignore tests that issue deprecation warnings. ++# ++# An alternative would be just to remove this option, this would be possible ++# when the script is only used to convert in the CI. ++DISABLE_DEPRECATION_WARNINGS_REGEXES = [ ++ re.compile( ++ r"//\s*ADDITIONAL_COMPILE_FLAGS:.*-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ++ ), ++ re.compile(r"//\s*ADDITIONAL_COMPILE_FLAGS:.*-D_LIBCPP_HAS_NO_UNICODE"), ++] ++ ++ ++# Marks a test as unsupported. ++# ++# Since the script runs on a not yet converted set of tests the script does not ++# test existing markers. In the future it should look at: ++# - tests with (XFAIL|UNSUPPORTED) use_module_std(|.compat) ++# - tests with an import statement ++def is_unsupported(filename: str) -> bool: ++ file = open(filename) ++ lines = file.readlines() ++ file.close() ++ ++ for index, line in enumerate(lines): ++ for re in DISABLE_DEPRECATION_WARNINGS_REGEXES: ++ if re.search(line): ++ lines.insert( ++ index + 1, "// UNSUPPORTED: use_module_std, use_module_std.compat\n" ++ ) ++ ++ file = open(filename, "w") ++ for line in lines: ++ file.write(line) ++ ++ return True ++ return False ++ ++ ++@dataclass ++class Include: ++ line: int = -1 ++ is_system_header: bool = False ++ ++ ++def gather_includes(lines: list[str]) -> list[Include]: ++ result = list() ++ for index, line in enumerate(lines): ++ if m := INCLUDE_REGEX.match(line): ++ result.append(Include(index, m.group("include") in HEADERS_MODULE_STD)) ++ return result ++ ++ ++def insert_imports(lines: list[str], includes: list[Include]) -> None: ++ assert len(lines) ++ assert len(includes) ++ ++ # The imports are always added after the last header ++ # Note this fails when a test has an #include in the middle of the file ++ ++ line = includes[-1].line + 1 ++ ++ imports = list() ++ lines.insert( ++ line, ++ """ ++#if defined(TEST_USE_MODULE_STD) ++import std; ++#elif defined(TEST_USE_MODULE_STD_COMPAT) ++import std.compat; ++#endif ++""", ++ ) ++ ++ ++def make_modularized_headers_conditionally( ++ lines: list[str], includes: list[Include] ++) -> None: ++ assert len(lines) ++ assert len(includes) ++ ++ inside = False ++ # Iterate backwards so the line numbers of the includes remain stable. ++ for include in reversed(includes): ++ if include.is_system_header: ++ if not inside: ++ lines.insert(include.line + 1, "#endif // TEST_USE_MODULE\n") ++ inside = True ++ else: ++ if inside: ++ lines.insert(include.line + 1, "#ifdef TEST_USE_MODULE\n") ++ inside = False ++ ++ # Add the ifdef for the first entry if needed. ++ if inside: ++ for include in includes: ++ if include.is_system_header: ++ lines.insert(include.line, "#ifdef TEST_USE_MODULE\n") ++ return ++ assert False ++ ++ ++def process_supported(filename: str) -> None: ++ import_written = False ++ ++ file = open(filename) ++ lines = file.readlines() ++ file.close() ++ includes = gather_includes(lines) ++ # for include in includes: ++ # print(f"{include.is_system_header} {include.line:4}: {lines[include.line]}") ++ if len(includes) == 0: ++ return ++ ++ # TODO Once Clang works properly with includes after imports this import can be ++ # at the top of the file. ++ insert_imports(lines, includes) ++ # for line in lines: ++ # print(line) ++ ++ make_modularized_headers_conditionally(lines, includes) ++ # for line in lines: ++ # print(line) ++ ++ file = open(filename, "w") ++ for line in lines: ++ file.write(line) ++ ++ ++def process(filename: str) -> None: ++ if not is_unsupported(filename): ++ process_supported(filename) ++ ++ ++if __name__ == "__main__": ++ if len(sys.argv) == 2: ++ process(sys.argv[1]) +diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt +index 37cab6e17ee0..24ffbf903b4a 100644 +--- a/runtimes/CMakeLists.txt ++++ b/runtimes/CMakeLists.txt +@@ -146,6 +146,13 @@ llvm_check_compiler_linker_flag(CXX "-nostdlib++" CXX_SUPPORTS_NOSTDLIBXX_FLAG) + if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++") + endif() ++# When present, the -nostdinc++ flag gets propagated to the linker flags. In ++# CMake 3.26 this causes try_compile to fail for other compile options. Which ++# results in flags not being set, even when present. ++check_c_compiler_flag("-Wno-unused-command-line-argument" C_SUPPORTS_START_NO_UNUSED_COMMAND_LINE_ARGUMENTS) ++if (C_SUPPORTS_START_NO_UNUSED_COMMAND_LINE_ARGUMENTS) ++ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wno-unused-command-line-argument") ++endif() + check_cxx_compiler_flag(-nostdinc++ CXX_SUPPORTS_NOSTDINCXX_FLAG) + if (CXX_SUPPORTS_NOSTDINCXX_FLAG) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdinc++")