diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -105,6 +105,10 @@ 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") @@ -401,6 +405,9 @@ # TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR # instead of hard-coding include/c++/v1. +# TODO: The LIBCXX_GENERATED_MODULE_DIR is a placeholder. A proper directory +# needs to be determined. Maybe look at how other library vendors tackle this. + set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH "Path where target-agnostic libc++ headers should be installed.") set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH @@ -412,6 +419,7 @@ 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}/include/c++/modules") 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.") @@ -425,9 +433,11 @@ 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}/include/c++/modules") 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}/include/c++/modules") endif() set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH @@ -913,6 +923,9 @@ add_subdirectory(include) add_subdirectory(src) add_subdirectory(utils) +if (LIBCXX_ENABLE_STD_MODULE) + add_subdirectory(stdmodules) +endif() set(LIBCXX_TEST_DEPS "cxx_experimental") @@ -924,6 +937,10 @@ 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 --- /dev/null +++ b/libcxx/cmake/caches/Generic-module-std-compat.cmake @@ -0,0 +1,4 @@ +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 --- /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 --- /dev/null +++ b/libcxx/docs/Modules.rst @@ -0,0 +1,164 @@ +.. _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 + +Some of the current limitations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * For now everything requires CMake. + * The files are not installed, but available in the build tree. + * The ``pcm`` files are regenerated when running a ``lit`` invocation. + * There is no Buildkite CI job yet. + * All tests need to be modified for modules, this can be done with a tool. + * The ``std`` module is incomplete. + * The ``std.compat`` module is incomplete. + * Requires CMake 3.26 (soon to be released) + * 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. + * There is no `P1689 style output `_ yet. + The file generated by clang-scan-deps contains absolute paths to the files + in the libc++ build directory. (These should be relative paths or paths to + the installation directory.) + * Configurations with parts disable do not work properly. The ``#ifdef`` + are not in the ``.cppm`` files yet. + +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 210 of the 7243 test in the directory ``libcxx/test/std`` fail. + * 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 `__ + * The code contains ``_LIBCPP_HIDE_FROM_ABI static constexpr``. There + might be a patch. + + * Clang + + * ``__synth_three_way_result`` does not work. There is a work-around in libc++. + + * `bug report `__ + * `patch `__ + + * The ranges Niebloids doen'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++. + +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++23`` or restrict it to ``C++23`` and later? + * 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. + * Currently the ``.cppm`` file and the generated ``CMakeLists.txt`` are not + installed. Before doing that it would be good to determine what the best + location for these files is. + * 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. + * Should P1689 style output files be shipped with libc++? + + +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 modules + +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. 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. diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -39,6 +39,7 @@ BuildingLibcxx TestingLibcxx Contributing + Modules Status/Cxx14 Status/Cxx17 Status/Cxx20 diff --git a/libcxx/include/__algorithm/ranges_find_if.h b/libcxx/include/__algorithm/ranges_find_if.h --- a/libcxx/include/__algorithm/ranges_find_if.h +++ b/libcxx/include/__algorithm/ranges_find_if.h @@ -31,7 +31,7 @@ namespace ranges { template -_LIBCPP_HIDE_FROM_ABI static constexpr +_LIBCPP_HIDE_FROM_ABI constexpr // HAS THIS BEEN FIXED UPSTREAM??? _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) diff --git a/libcxx/include/__algorithm/ranges_min_element.h b/libcxx/include/__algorithm/ranges_min_element.h --- a/libcxx/include/__algorithm/ranges_min_element.h +++ b/libcxx/include/__algorithm/ranges_min_element.h @@ -32,7 +32,7 @@ // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. template -_LIBCPP_HIDE_FROM_ABI static constexpr +_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { if (__first == __last) return __first; diff --git a/libcxx/include/__compare/synth_three_way.h b/libcxx/include/__compare/synth_three_way.h --- a/libcxx/include/__compare/synth_three_way.h +++ b/libcxx/include/__compare/synth_three_way.h @@ -25,6 +25,10 @@ // [expos.only.func] +// Fails with C++20 modules. +// https://github.com/llvm/llvm-project/issues/57222#issuecomment-1261618636 +// Possible fix https://reviews.llvm.org/D140002 +#if 0 _LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = [](const _Tp& __t, const _Up& __u) requires requires { @@ -40,6 +44,23 @@ return weak_ordering::equivalent; } }; +#else +template +_LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up& __u) + requires requires { + { __t < __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + } + { + if constexpr (three_way_comparable_with<_Tp, _Up>) { + return __t <=> __u; + } else { + if (__t < __u) return weak_ordering::less; + if (__u < __t) return weak_ordering::greater; + return weak_ordering::equivalent; + } + } +#endif template using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -1501,9 +1501,10 @@ 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/stdmodules/.clang-format b/libcxx/stdmodules/.clang-format new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/.clang-format @@ -0,0 +1,3 @@ +BasedOnStyle: InheritParentConfig + +NamespaceIndentation: All diff --git a/libcxx/stdmodules/CMakeLists.txt b/libcxx/stdmodules/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/CMakeLists.txt @@ -0,0 +1,61 @@ +set(LIBCXX_SOURCES_MODULE_STD + std.cppm + #std-algorithm.cppm + std-array.cppm + std-charconv.cppm + std-chrono.cppm + std-coroutine.cppm + std-concepts.cppm + std-cstddef.cppm + std-cstdlib.cppm + std-exception.cppm + std-expected.cppm + std-format.cppm + std-functional.cppm + std-iterator.cppm + std-initializer_list.cppm + std-memory.cppm + std-numeric.cppm + std-optional.cppm + #std-ranges.cppm + std-span.cppm + std-string.cppm + std-string_view.cppm + std-system_error.cppm + std-type_traits.cppm + std-tuple.cppm + std-utility.cppm + std-variant.cppm + std-vector.cppm +) +if(LIBCXX_ENABLE_LOCALIZATION) + list(APPEND LIBCXX_SOURCES_MODULE_STD + std-fstream.cppm + std-iostream.cppm + ) +endif() + +set(LIBCXX_SOURCES_MODULE_STD_COMPAT + std-compat.cppm + std-compat-stddef.cppm +) + +configure_file("CMakeLists.txt.in" "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt" @ONLY) + +set(_all_modules "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt") +#list(APPEND LIBCXX_SOURCES_MODULE_STD ${LIBCXX_SOURCES_MODULE_STD_COMPAT}) + +foreach(f ${LIBCXX_SOURCES_MODULE_STD} ${LIBCXX_SOURCES_MODULE_STD_COMPAT}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}") + set(dst "${LIBCXX_GENERATED_MODULE_DIR}/${f}") + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying CXX module ${f}") + list(APPEND _all_modules "${dst}") +endforeach() + +add_custom_target(generate-cxx-modules + ALL DEPENDS + ${_all_modules} +) diff --git a/libcxx/stdmodules/CMakeLists.txt.in b/libcxx/stdmodules/CMakeLists.txt.in new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/CMakeLists.txt.in @@ -0,0 +1,99 @@ +# CMake 3.25 has modules support, but that does not work properly. +cmake_minimum_required(VERSION 3.26) + +project(libc++-std LANGUAGES CXX) + +# CMake specific magic +# In the future this probably is not needed and will be part of CMake itself. + +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") +set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3") + +set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) +string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE + "${CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS}" + " -format=p1689" + " --" + " " + " -x c++ -c -o " + " -MT " + " -MD -MF " + " > ") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "clang") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@") + +# Default to C++ extensions being off. Clang's modules support have trouble +# with extensions right now. +set(CMAKE_CXX_EXTENSIONS OFF) + + +#if( @_LIBCPP_ENABLE_EXPERIMENTAL@) +# add_target_definitions(std PRIVATE _LIBCPP_ENABLE_EXPERIMENTAL) +#endif() + +# 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() + +# TODO Evaluate whether all are needed +compile_define_if(@LIBCXX_HAS_PTHREAD_API@ _LIBCPP_HAS_THREAD_API_PTHREAD) +compile_define_if(@LIBCXX_HAS_EXTERNAL_THREAD_API@ _LIBCPP_HAS_THREAD_API_EXTERNAL) +compile_define_if(@LIBCXX_HAS_WIN32_THREAD_API@ _LIBCPP_HAS_THREAD_API_WIN32) +compile_define_if(@LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY@ _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) +compile_define_if(@LIBCXX_HAS_MUSL_LIBC@ _LIBCPP_HAS_MUSL_LIBC) +#compile_define_if(@LIBCXX_NO_VCRUNTIME@ _LIBCPP_NO_VCRUNTIME) +compile_define_if(@LIBCXX_ENABLE_PARALLEL_ALGORITHMS@ _LIBCPP_HAS_PARALLEL_ALGORITHMS) +compile_define_if_not(@LIBCXX_ENABLE_FILESYSTEM@ _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) +compile_define_if_not(@LIBCXX_ENABLE_RANDOM_DEVICE@ _LIBCPP_HAS_NO_RANDOM_DEVICE) +compile_define_if_not(@LIBCXX_ENABLE_LOCALIZATION@ _LIBCPP_HAS_NO_LOCALIZATION) +compile_define_if_not(@LIBCXX_ENABLE_FSTREAM@ _LIBCPP_HAS_NO_FSTREAM) +compile_define_if_not(@LIBCXX_ENABLE_UNICODE@ _LIBCPP_HAS_NO_UNICODE) +compile_define_if_not(@LIBCXX_ENABLE_WIDE_CHARACTERS@ _LIBCPP_HAS_NO_WIDE_CHARACTERS) +#compile_define_if_not(@LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS@ _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +compile_define_if(@LIBCXX_ENABLE_DEBUG_MODE@ _LIBCPP_ENABLE_DEBUG_MODE) +#if (@LIBCXX_ENABLE_ASSERTIONS@) +# target_compile_definitions(std PRIVATE _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 1) +#else() +# target_compile_definitions(std PRIVATE _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0) +#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_GENERATED_INCLUDE_TARGET_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_GENERATED_INCLUDE_TARGET_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/stdmodules/std-array.cppm b/libcxx/stdmodules/std-array.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-charconv.cppm b/libcxx/stdmodules/std-charconv.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-charconv.cppm @@ -0,0 +1,29 @@ +# 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; + + // [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/stdmodules/std-chrono.cppm b/libcxx/stdmodules/std-chrono.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-compat-stddef.cppm b/libcxx/stdmodules/std-compat-stddef.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-compat-stddef.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:stddef; +export { + // validate the list against the proper C standard + using ::max_align_t; + using ::ptrdiff_t; + using ::size_t; + +// using ::nullptr_t; // required? + +} // export diff --git a/libcxx/stdmodules/std-compat.cppm b/libcxx/stdmodules/std-compat.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-compat.cppm @@ -0,0 +1,14 @@ +# 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; +export import :stddef; + diff --git a/libcxx/stdmodules/std-concepts.cppm b/libcxx/stdmodules/std-concepts.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-coroutine.cppm b/libcxx/stdmodules/std-coroutine.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-coroutine.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 +#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::suspend_always; + using std::suspend_never; + + using std::hash; +} // namespace std diff --git a/libcxx/stdmodules/std-cstddef.cppm b/libcxx/stdmodules/std-cstddef.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-cstdlib.cppm b/libcxx/stdmodules/std-cstdlib.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-exception.cppm b/libcxx/stdmodules/std-exception.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-exception.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: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_if_nested; + using std::set_terminate; + using std::terminate; + using std::throw_with_nested; + using std::uncaught_exception; +} // namespace std diff --git a/libcxx/stdmodules/std-expected.cppm b/libcxx/stdmodules/std-expected.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-format.cppm b/libcxx/stdmodules/std-format.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-fstream.cppm b/libcxx/stdmodules/std-fstream.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-fstream.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; +#include + +export module std:fstream; +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 diff --git a/libcxx/stdmodules/std-functional.cppm b/libcxx/stdmodules/std-functional.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-initializer_list.cppm b/libcxx/stdmodules/std-initializer_list.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-iostream.cppm b/libcxx/stdmodules/std-iostream.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-iostream.cppm @@ -0,0 +1,29 @@ +# 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:iostream; +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 diff --git a/libcxx/stdmodules/std-iterator.cppm b/libcxx/stdmodules/std-iterator.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-iterator.cppm @@ -0,0 +1,254 @@ +# 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; + +#if 0 // TODO INVESTIGATE + namespace ranges { + // [iterator.cust], customization point objects + inline namespace unspecified { + // [iterator.cust.move], ranges​::​iter_move + inline constexpr unspecified iter_move = unspecified; + + // [iterator.cust.swap], ranges​::​iter_swap + inline constexpr unspecified iter_swap = unspecified; + } + } +#endif + + 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/stdmodules/std-memory.cppm b/libcxx/stdmodules/std-memory.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-memory.cppm @@ -0,0 +1,198 @@ +# 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::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; + +} // namespace std diff --git a/libcxx/stdmodules/std-numeric.cppm b/libcxx/stdmodules/std-numeric.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-numeric.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: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; + + // [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/stdmodules/std-optional.cppm b/libcxx/stdmodules/std-optional.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-span.cppm b/libcxx/stdmodules/std-span.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-span.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:span; +export namespace std { + + // constants + using std::dynamic_extent; + + // [views.span], class template span + using std::span; + + using std::ranges::enable_borrowed_range; + using std::ranges::enable_view; + + // [span.objectrep], views of object representation + using std::as_bytes; + + using std::as_writable_bytes; + +} // namespace std diff --git a/libcxx/stdmodules/std-string.cppm b/libcxx/stdmodules/std-string.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-string_view.cppm b/libcxx/stdmodules/std-string_view.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-string_view.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 + +export module std:string_view; +export namespace std { + + // [string.view.template], class template basic_string_view + using std::basic_string_view; + + using std::ranges::enable_borrowed_range; + using std::ranges::enable_view; + + // [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 literals +} // namespace std diff --git a/libcxx/stdmodules/std-system_error.cppm b/libcxx/stdmodules/std-system_error.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-tuple.cppm b/libcxx/stdmodules/std-tuple.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/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/stdmodules/std-type_traits.cppm b/libcxx/stdmodules/std-type_traits.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-type_traits.cppm @@ -0,0 +1,300 @@ +# 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; +#if _LIBCPP_STD_VER >= 23 // TODO Do we want to provide std module in C++20 + using std::is_scoped_enum; // C++2b +#endif + + // 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::unwrap_ref_decay; + using std::underlying_type; + + // 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; + +#if _LIBCPP_STD_VER >= 23 // TODO Do we want to provide std module in C++20 + using std::is_scoped_enum_v; +#endif + + // 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/stdmodules/std-utility.cppm b/libcxx/stdmodules/std-utility.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-utility.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: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; +// TODO Even when we don't want to provide std module in C++20 this is kept for now. +// This allows testing whether this way works properly. That will be required for +// symbols that will be added in C++26. +#if _LIBCPP_STD_VER >= 23 // TODO Do we want to provide std module in C++20 + using std::forward_like; +#endif + using std::in_range; // C++20 + using std::move; + using std::move_if_noexcept; + + 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::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; +#if _LIBCPP_STD_VER >= 23 // TODO Do we want to provide std module in C++20 + using std::to_underlying; +#endif +} // namespace std diff --git a/libcxx/stdmodules/std-variant.cppm b/libcxx/stdmodules/std-variant.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-variant.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: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; + + // [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/stdmodules/std-vector.cppm b/libcxx/stdmodules/std-vector.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-vector.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 +#include +export module std:vector; + +export namespace std { + using std::hash; + using std::swap; + using std::vector; + using std::operator==; + using std::erase; + using std::erase_if; +} // namespace std + +export { using ::operator new; } diff --git a/libcxx/stdmodules/std.cppm b/libcxx/stdmodules/std.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std.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 +// +//===----------------------------------------------------------------------===// + +export module std; +// export import :algorithm; // Work in progress +export import :array; +export import :charconv; +export import :chrono; +export import :coroutine; +export import :concepts; +export import :cstddef; +export import :cstdlib; +export import :exception; +export import :expected; +export import :format; +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +export import :fstream; +#endif +export import :functional; +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +export import :iostream; +#endif +export import :iterator; +export import :initializer_list; +export import :memory; +export import :numeric; +export import :optional; +// export import :ranges; Does not work properly in modules +export import :span; +export import :string; +export import :string_view; +export import :system_error; +export import :type_traits; +export import :tuple; +export import :utility; +export import :variant; +export import :vector; diff --git a/libcxx/test/configs/cmake-bridge.cfg.in b/libcxx/test/configs/cmake-bridge.cfg.in --- a/libcxx/test/configs/cmake-bridge.cfg.in +++ b/libcxx/test/configs/cmake-bridge.cfg.in @@ -31,3 +31,8 @@ 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 --- 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 --- 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 --- 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 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/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -47,967 +47,3 @@ - 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 apple-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 apple-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 - - # 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 diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -378,6 +378,20 @@ 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++ + 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++ + 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" diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -12,6 +12,7 @@ import platform import re import shutil +import subprocess import tempfile import libcxx.test.format @@ -386,6 +387,63 @@ 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 == 'cxx20': + std = '20' + elif std == 'cxx2b': + std = '23' + else: + std = '17' # Not allowed for modules + + flags = _getSubstitution('%{flags}', config) + include = _getSubstitution('%{include}', config) + source = os.path.join(include, '../modules') + + 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 +496,13 @@ 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 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -67,6 +67,21 @@ 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 " @@ -86,13 +101,30 @@ 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_MODULES'), # remove + 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')), + 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 --- /dev/null +++ b/libcxx/utils/use_modules_in_test.py @@ -0,0 +1,125 @@ +#!/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 + + +HEADERS_MODULE_STD = [ + # "algorithm", + "array", + "charconv", + "chrono", + "coroutines", + "concepts", + "cstddef", + "cstdlib", + "exception", + "expected", + "format", + "fstream", + "functional", + "iostream", + "iterator", + "initializer_list", + "memory", + "numeric", + "optional", + # "ranges", + "span", + "string", + "string_view", + "system_error", + "tuple", + "type_traits", + "utility", + "variant", + "vector", +] + +# 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", +] + +INCLUDE_REGEX = re.compile(r"^\s*#\s*include\s*<(?P[^>]+)>") + + +def process_unsupported(filename: str) -> None: + file = open(filename) + lines = file.readlines() + file.close() + + file = open(filename, "w") + file.write("// UNSUPPORTED: c++-modules-build\n") + for line in lines: + file.write(line) + + +def process_supported(filename: str) -> None: + import_written = False + + file = open(filename) + lines = file.readlines() + file.close() + + file = open(filename, "w") + for line in lines: + if m := INCLUDE_REGEX.match(line): + include = m.group("include") + if include in HEADERS_MODULE_STD: + if not import_written: + import_written = True + # Note some tests depend on the relavant part of version to be included. + # Therefore include this header unconditionally. + file.write( + """#ifdef TEST_USE_MODULE +import TEST_USE_MODULE; +#include // TODO REMOVE +#endif +""" + ) + file.write(f"#ifndef TEST_USE_MODULE\n{line}#endif\n") + else: + file.write(line) + else: + file.write(line) + + +def process(filename: str) -> None: + if filename in UNSUPPORTED_TESTS: + process_unsupported(filename) + else: + 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 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -144,6 +144,13 @@ 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++")