From 9e2702fad697ac04e6f1097fcbe3a88d1607119a Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Sun, 20 Aug 2023 12:30:57 +0200 Subject: [PATCH] [libc++][C++20 modules] Enabling in C++20. The vendors of the MSVC STL, libstdc++ and libc++ have agreed [1] to make the C++23 modules std and std.compat available in C++20. This provides the std module; libc++ has not implemented the std.compat module yet. [1] https://github.com/microsoft/STL/issues/3945 Depends on D158357 Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D158358 NOKEYCHECK=True GitOrigin-RevId: b9f24033f7f2d3485fbabbc56e3b31b5bc90e874 --- docs/Modules.rst | 3 +++ docs/UsingLibcxx.rst | 6 ++++++ modules/std/algorithm.inc | 8 +++++--- modules/std/bit.inc | 2 ++ modules/std/expected.inc | 2 ++ modules/std/format.inc | 4 ++++ modules/std/functional.inc | 2 ++ modules/std/mdspan.inc | 2 ++ modules/std/memory.inc | 2 ++ modules/std/print.inc | 6 ++++-- modules/std/ranges.inc | 10 ++++++++++ modules/std/string.inc | 2 +- modules/std/thread.inc | 2 ++ modules/std/tuple.inc | 2 ++ modules/std/type_traits.inc | 4 ++++ modules/std/utility.inc | 6 ++++++ modules/std/vector.inc | 2 ++ test/libcxx/module_std.gen.py | 2 +- test/lit.local.cfg | 2 ++ utils/ci/buildkite-pipeline.yml | 8 ++++++-- 20 files changed, 68 insertions(+), 9 deletions(-) diff --git a/docs/Modules.rst b/docs/Modules.rst index f7c4ea9412..85c42af5a6 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -49,10 +49,13 @@ What works * ``LIBCXX_ENABLE_RANDOM_DEVICE`` * ``LIBCXX_ENABLE_UNICODE`` + * A C++20 based extension + Some of the current limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * There is no official build system support, libc++ has experimental CMake support + * Requires CMake 3.26 for C++20 support * Requires CMake 3.26 for C++23 support * Requires CMake 3.27 for C++26 support * Requires Ninja 1.11 diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst index 1859645320..71a934f4bf 100644 --- a/docs/UsingLibcxx.rst +++ b/docs/UsingLibcxx.rst @@ -520,6 +520,12 @@ in their code base. In C++26 formatting pointers gained a type ``P`` and allows to use zero-padding. These options have been retroactively applied to C++20. +Extensions to the C++23 modules ``std`` and ``std.compat`` +---------------------------------------------------------- + +Like other major implementations, libc++ provides C++23 modules ``std`` and +``std.compat`` in C++20 as an extension" + .. _turning-off-asan: Turning off ASan annotation in containers diff --git a/modules/std/algorithm.inc b/modules/std/algorithm.inc index bb38f39df8..c951b2b36c 100644 --- a/modules/std/algorithm.inc +++ b/modules/std/algorithm.inc @@ -150,10 +150,11 @@ export namespace std { } namespace ranges { +#if _LIBCPP_STD_VER >= 23 // [alg.starts.with], starts with using std::ranges::starts_with; -#if 0 +# if 0 // [alg.ends.with], ends with using std::ranges::ends_with; @@ -167,8 +168,9 @@ export namespace std { using std::ranges::fold_left_with_iter; using std::ranges::fold_left_first_with_iter; using std::ranges::fold_left_first_with_iter; -#endif - } // namespace ranges +# endif +#endif // _LIBCPP_STD_VER >= 23 + } // namespace ranges // [alg.modifying.operations], mutating sequence operations // [alg.copy], copy diff --git a/modules/std/bit.inc b/modules/std/bit.inc index 2a05a8ee46..027a6c17ad 100644 --- a/modules/std/bit.inc +++ b/modules/std/bit.inc @@ -11,8 +11,10 @@ export namespace std { // [bit.cast], bit_cast using std::bit_cast; +#if _LIBCPP_STD_VER >= 23 // [bit.byteswap], byteswap using std::byteswap; +#endif // [bit.pow.two], integral powers of 2 using std::bit_ceil; diff --git a/modules/std/expected.inc b/modules/std/expected.inc index 1595230123..c21683cb90 100644 --- a/modules/std/expected.inc +++ b/modules/std/expected.inc @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [expected.unexpected], class template unexpected using std::unexpected; @@ -20,4 +21,5 @@ export namespace std { // [expected.expected], class template expected using std::expected; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/modules/std/format.inc b/modules/std/format.inc index ae7de95495..c1bc91f831 100644 --- a/modules/std/format.inc +++ b/modules/std/format.inc @@ -42,8 +42,10 @@ export namespace std { // [format.formatter], formatter using std::formatter; +#if _LIBCPP_STD_VER >= 23 // [format.formattable], concept formattable using std::formattable; +#endif // [format.parse.ctx], class template basic_format_parse_context using std::basic_format_parse_context; @@ -52,6 +54,7 @@ export namespace std { using std::wformat_parse_context; #endif +#if _LIBCPP_STD_VER >= 23 // [format.range], formatting of ranges // [format.range.fmtkind], variable template format_kind using std::format_kind; @@ -59,6 +62,7 @@ export namespace std { // [format.range.formatter], class template range_formatter using std::range_formatter; +#endif // _LIBCPP_STD_VER >= 23 // [format.arg], class template basic_format_arg using std::basic_format_arg; diff --git a/modules/std/functional.inc b/modules/std/functional.inc index f8a29e2f05..1148944a9d 100644 --- a/modules/std/functional.inc +++ b/modules/std/functional.inc @@ -10,7 +10,9 @@ export namespace std { // [func.invoke], invoke using std::invoke; +#if _LIBCPP_STD_VER >= 23 using std::invoke_r; +#endif // [refwrap], reference_wrapper using std::reference_wrapper; diff --git a/modules/std/mdspan.inc b/modules/std/mdspan.inc index 37580eaa45..888c94ad59 100644 --- a/modules/std/mdspan.inc +++ b/modules/std/mdspan.inc @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [mdspan.extents], class template extents using std::extents; @@ -24,4 +25,5 @@ export namespace std { // [mdspan.mdspan], class template mdspan using std::mdspan; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/modules/std/memory.inc b/modules/std/memory.inc index d91c549e85..fba2461732 100644 --- a/modules/std/memory.inc +++ b/modules/std/memory.inc @@ -41,9 +41,11 @@ export namespace std { // [allocator.traits], allocator traits using std::allocator_traits; +#if _LIBCPP_STD_VER >= 23 using std::allocation_result; using std::allocate_at_least; +#endif // [default.allocator], the default allocator using std::allocator; diff --git a/modules/std/print.inc b/modules/std/print.inc index 35a1635cf2..1ca52c7006 100644 --- a/modules/std/print.inc +++ b/modules/std/print.inc @@ -8,12 +8,14 @@ //===----------------------------------------------------------------------===// export namespace std { +#if _LIBCPP_STD_VER >= 23 // [print.fun], print functions using std::print; using std::println; using std::vprint_nonunicode; -#ifndef _LIBCPP_HAS_NO_UNICODE +# ifndef _LIBCPP_HAS_NO_UNICODE using std::vprint_unicode; -#endif // _LIBCPP_HAS_NO_UNICODE +# endif // _LIBCPP_HAS_NO_UNICODE +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/modules/std/ranges.inc b/modules/std/ranges.inc index a6b1bf5496..67b0f02ad9 100644 --- a/modules/std/ranges.inc +++ b/modules/std/ranges.inc @@ -90,8 +90,10 @@ export namespace std { using std::ranges::borrowed_subrange_t; +#if _LIBCPP_STD_VER >= 23 // [range.utility.conv], range conversions using std::ranges::to; +#endif // [range.empty], empty view using std::ranges::empty_view; @@ -114,12 +116,14 @@ export namespace std { using std::ranges::views::iota; } // namespace views +#if _LIBCPP_STD_VER >= 23 // [range.repeat], repeat view using std::ranges::repeat_view; namespace views { using std::ranges::views::repeat; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 #ifndef _LIBCPP_HAS_NO_LOCALIZATION // [range.istream], istream view @@ -149,12 +153,14 @@ export namespace std { // [range.owning.view], owning view using std::ranges::owning_view; +#if _LIBCPP_STD_VER >= 23 // [range.as.rvalue], as rvalue view using std::ranges::as_rvalue_view; namespace views { using std::ranges::views::as_rvalue; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 // [range.filter], filter view using std::ranges::filter_view; @@ -259,12 +265,14 @@ export namespace std { using std::ranges::views::values; } // namespace views +#if _LIBCPP_STD_VER >= 23 // [range.zip], zip view using std::ranges::zip_view; namespace views { using std::ranges::views::zip; } // namespace views +#endif // _LIBCPP_STD_VER >= 23 #if 0 // [range.zip.transform], zip transform view @@ -329,6 +337,8 @@ export namespace std { using std::tuple_element; using std::tuple_size; +#if _LIBCPP_STD_VER >= 23 using std::from_range; using std::from_range_t; +#endif // _LIBCPP_STD_VER >= 23 } // namespace std diff --git a/modules/std/string.inc b/modules/std/string.inc index 76b384c8b5..8366690fd9 100644 --- a/modules/std/string.inc +++ b/modules/std/string.inc @@ -68,7 +68,7 @@ export namespace std { using std::hash; // TODO MODULES is this a bug? -#if 1 +#if _LIBCPP_STD_VER >= 23 using std::operator""s; #else inline namespace literals { diff --git a/modules/std/thread.inc b/modules/std/thread.inc index 114840e3d1..43594d1a29 100644 --- a/modules/std/thread.inc +++ b/modules/std/thread.inc @@ -33,7 +33,9 @@ export namespace std { using std::operator<<; # endif // _LIBCPP_HAS_NO_LOCALIZATION +# if _LIBCPP_STD_VER >= 23 using std::formatter; +# endif using std::hash; #endif // _LIBCPP_HAS_NO_THREADS diff --git a/modules/std/tuple.inc b/modules/std/tuple.inc index 9a8fb72cb6..706e2266c1 100644 --- a/modules/std/tuple.inc +++ b/modules/std/tuple.inc @@ -13,9 +13,11 @@ export namespace std { // [tuple.like], concept tuple-like +#if _LIBCPP_STD_VER >= 23 // [tuple.common.ref], common_reference related specializations using std::basic_common_reference; using std::common_type; +#endif // [tuple.creation], tuple creation functions using std::ignore; diff --git a/modules/std/type_traits.inc b/modules/std/type_traits.inc index f0ec4cb6c7..d368daf35c 100644 --- a/modules/std/type_traits.inc +++ b/modules/std/type_traits.inc @@ -53,7 +53,9 @@ export namespace std { using std::is_volatile; using std::is_bounded_array; +#if _LIBCPP_STD_VER >= 23 using std::is_scoped_enum; +#endif using std::is_signed; using std::is_unbounded_array; using std::is_unsigned; @@ -255,7 +257,9 @@ export namespace std { using std::is_nothrow_swappable_v; using std::is_nothrow_swappable_with_v; using std::is_polymorphic_v; +#if _LIBCPP_STD_VER >= 23 using std::is_scoped_enum_v; +#endif using std::is_signed_v; using std::is_standard_layout_v; using std::is_swappable_v; diff --git a/modules/std/utility.inc b/modules/std/utility.inc index c8e4dc396c..77c21b8764 100644 --- a/modules/std/utility.inc +++ b/modules/std/utility.inc @@ -16,7 +16,9 @@ export namespace std { // [forward], forward/move using std::forward; +#if _LIBCPP_STD_VER >= 23 using std::forward_like; +#endif using std::move; using std::move_if_noexcept; @@ -37,11 +39,13 @@ export namespace std { using std::in_range; +#if _LIBCPP_STD_VER >= 23 // [utility.underlying], to_underlying using std::to_underlying; // [utility.unreachable], unreachable using std::unreachable; +#endif // _LIBCPP_STD_VER >= 23 // [intseq], compile-time integer sequences using std::index_sequence; @@ -55,8 +59,10 @@ export namespace std { // [pairs], class template pair using std::pair; +#if _LIBCPP_STD_VER >= 23 using std::basic_common_reference; using std::common_type; +#endif // [pairs.spec], pair specialized algorithms using std::operator==; using std::operator<=>; diff --git a/modules/std/vector.inc b/modules/std/vector.inc index a9ce764fc8..7168ec2bb7 100644 --- a/modules/std/vector.inc +++ b/modules/std/vector.inc @@ -27,6 +27,8 @@ export namespace std { // hash support using std::hash; +#if _LIBCPP_STD_VER >= 23 // [vector.bool.fmt], formatter specialization for vector using std::formatter; +#endif } // namespace std diff --git a/test/libcxx/module_std.gen.py b/test/libcxx/module_std.gen.py index 2a6b0f237a..8bd4f702c7 100644 --- a/test/libcxx/module_std.gen.py +++ b/test/libcxx/module_std.gen.py @@ -117,7 +117,7 @@ print( f"""\ //--- module_std.sh.cpp -// UNSUPPORTED{BLOCKLIT}: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED{BLOCKLIT}: c++03, c++11, c++14, c++17 // UNSUPPORTED{BLOCKLIT}: libcpp-has-no-std-modules // UNSUPPORTED{BLOCKLIT}: modules-build diff --git a/test/lit.local.cfg b/test/lit.local.cfg index 16ab3b1b62..ede8c65d89 100644 --- a/test/lit.local.cfg +++ b/test/lit.local.cfg @@ -34,6 +34,8 @@ if std == "cxx26": std = "26" elif std == "cxx23": std = "23" +elif std == "cxx20": + std = "20" else: std = "" diff --git a/utils/ci/buildkite-pipeline.yml b/utils/ci/buildkite-pipeline.yml index 723ae43861..5c1010e81a 100644 --- a/utils/ci/buildkite-pipeline.yml +++ b/utils/ci/buildkite-pipeline.yml @@ -218,9 +218,13 @@ steps: - "**/test-results.xml" - "**/*.abilist" env: - CC: "clang-${LLVM_HEAD_VERSION}" - CXX: "clang++-${LLVM_HEAD_VERSION}" + # Note: Modules require and absolute path for clang-scan-deps + # https://github.com/llvm/llvm-project/issues/61006 + CC: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang" + CXX: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang++" + CMAKE: "/opt/bin/cmake" ENABLE_CLANG_TIDY: "On" + ENABLE_STD_MODULES: "On" agents: queue: "libcxx-builders" os: "linux"