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") @@ -913,6 +917,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 +931,10 @@ list(APPEND LIBCXX_TEST_DEPS cxx-tidy) endif() +if (LIBCXX_ENABLE_STD_MODULE) + list(APPEND LIBCXX_TEST_DEPS std) +endif() + if (LIBCXX_INCLUDE_BENCHMARKS) add_subdirectory(benchmarks) endif() 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,55 @@ +set(PREBUILT_MODULE_PATH ${CMAKE_BINARY_DIR}/libcxx/modules) +file(MAKE_DIRECTORY ${PREBUILT_MODULE_PATH}) + +# CMake 3.25 has modules support, but that does not work properly. +cmake_minimum_required(VERSION 3.26) +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) + +add_library(std) +target_sources(std + PUBLIC + FILE_SET cxx_modules TYPE CXX_MODULES FILES + std-coroutine.cppm + std-exception.cppm + std-type_traits.cppm + std-utility.cppm + std-vector.cppm + std.cppm +) +target_compile_features(std PUBLIC cxx_std_23) +target_compile_options(std + PUBLIC + ${LIBCXX_COMPILE_FLAGS} + -std=c++2b + -stdlib=libc++ + -fprebuilt-module-path=${PREBUILT_MODULE_PATH} + -pthread + --target=x86_64-unknown-linux-gnu +) + +add_custom_command(TARGET std POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std-coroutine.pcm ${PREBUILT_MODULE_PATH}/std-coroutine.pcm + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std-exception.pcm ${PREBUILT_MODULE_PATH}/std-exception.pcm + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std-type_traits.pcm ${PREBUILT_MODULE_PATH}/std-type_traits.pcm + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std-utility.pcm ${PREBUILT_MODULE_PATH}/std-utility.pcm + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std-vector.pcm ${PREBUILT_MODULE_PATH}/std-vector.pcm + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/std.dir/std.pcm ${PREBUILT_MODULE_PATH}/std.pcm +) 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,16 @@ +module; +#include +#include +# 1 __FILE__ 1 3 +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-exception.cppm b/libcxx/stdmodules/std-exception.cppm new file mode 100644 --- /dev/null +++ b/libcxx/stdmodules/std-exception.cppm @@ -0,0 +1,18 @@ +module; +#include +# 1 __FILE__ 1 3 +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-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,278 @@ +module; +#include +# 1 __FILE__ 1 3 +export module std:type_traits; +export namespace std { + using std::false_type; + using std::integral_constant; + using std::true_type; + + // helper traits + using std::conditional; + using std::enable_if; + + // Primary classification traits: + using std::is_array; + using std::is_class; + using std::is_enum; + using std::is_floating_point; + using std::is_function; + using std::is_integral; + using std::is_lvalue_reference; + using std::is_member_function_pointer; + using std::is_member_object_pointer; + using std::is_null_pointer; // C++14 + using std::is_pointer; + using std::is_rvalue_reference; + using std::is_union; + using std::is_void; + + // Secondary classification traits: + using std::is_arithmetic; + using std::is_compound; + using std::is_fundamental; + using std::is_member_pointer; + using std::is_object; + using std::is_reference; + using std::is_scalar; + using std::is_scoped_enum; // C++2b + + // Const-volatile properties and transformations: + using std::add_const; + using std::add_cv; + using std::add_volatile; + using std::is_const; + using std::is_volatile; + using std::remove_const; + using std::remove_cv; + using std::remove_volatile; + + // Reference transformations: + using std::add_lvalue_reference; + using std::add_rvalue_reference; + using std::remove_reference; + + // Pointer transformations: + using std::add_pointer; + using std::remove_pointer; + + using std::type_identity; // C++20 + using std::type_identity_t; + + // Integral properties: + using std::is_signed; + using std::is_unsigned; + using std::make_signed; + using std::make_unsigned; + + // Array properties and transformations: + using std::extent; + using std::rank; + using std::remove_all_extents; + using std::remove_extent; + + using std::is_bounded_array; // C++20 + using std::is_unbounded_array; // C++20 + + // Member introspection: + using std::is_abstract; + using std::is_aggregate; // C++17 + using std::is_empty; + using std::is_final; // C++14 + using std::is_pod; + using std::is_polymorphic; + using std::is_standard_layout; + using std::is_trivial; + using std::is_trivially_copyable; + + using std::is_assignable; + using std::is_constructible; + using std::is_copy_assignable; + using std::is_copy_constructible; + using std::is_default_constructible; + using std::is_destructible; + using std::is_move_assignable; + using std::is_move_constructible; + using std::is_swappable; // C++17 + using std::is_swappable_with; // C++17 + + using std::is_trivially_assignable; + using std::is_trivially_constructible; + using std::is_trivially_copy_assignable; + using std::is_trivially_copy_constructible; + using std::is_trivially_default_constructible; + using std::is_trivially_destructible; + using std::is_trivially_move_assignable; + using std::is_trivially_move_constructible; + + using std::is_nothrow_assignable; + using std::is_nothrow_constructible; + using std::is_nothrow_copy_assignable; + using std::is_nothrow_copy_constructible; + using std::is_nothrow_default_constructible; + using std::is_nothrow_destructible; + using std::is_nothrow_move_assignable; + using std::is_nothrow_move_constructible; + using std::is_nothrow_swappable; // C++17 + using std::is_nothrow_swappable_with; // C++17 + + using std::has_virtual_destructor; + + using std::has_unique_object_representations; // C++17 + + // Relationships between types: + using std::is_base_of; + using std::is_same; + + using std::is_convertible; + using std::is_nothrow_convertible; // C++20 + using std::is_nothrow_convertible_v; // C++20 + + using std::is_invocable; + using std::is_invocable_r; + + using std::is_nothrow_invocable; + using std::is_nothrow_invocable_r; + + // Alignment properties and transformations: + using std::aligned_storage; + using std::aligned_union; + using std::alignment_of; + using std::remove_cvref; // C++20 + + using std::common_type; + using std::decay; + using std::invoke_result; // C++17 + using std::underlying_type; + + // 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::void_t; + + // See C++14 20.10.4.1, primary type categories + using std::is_array_v; + using std::is_class_v; + using std::is_enum_v; + using std::is_floating_point_v; + using std::is_function_v; + using std::is_integral_v; + using std::is_lvalue_reference_v; + using std::is_member_function_pointer_v; + using std::is_member_object_pointer_v; + using std::is_null_pointer_v; + using std::is_pointer_v; + using std::is_rvalue_reference_v; + using std::is_union_v; + using std::is_void_v; + + // See C++14 20.10.4.2, composite type categories + using std::is_arithmetic_v; + using std::is_compound_v; + using std::is_fundamental_v; + using std::is_member_pointer_v; + using std::is_object_v; + using std::is_reference_v; + using std::is_scalar_v; + using std::is_scoped_enum_v; + + // See C++14 20.10.4.3, type properties + using std::has_unique_object_representations_v; // C++17; + using std::has_virtual_destructor_v; + using std::is_abstract_v; + using std::is_aggregate_v; + using std::is_assignable_v; + using std::is_const_v; + using std::is_constructible_v; + using std::is_copy_assignable_v; + using std::is_copy_constructible_v; + using std::is_default_constructible_v; + using std::is_destructible_v; + using std::is_empty_v; + using std::is_final_v; + using std::is_move_assignable_v; + using std::is_move_constructible_v; + using std::is_nothrow_assignable_v; + using std::is_nothrow_constructible_v; + using std::is_nothrow_copy_assignable_v; + using std::is_nothrow_copy_constructible_v; + using std::is_nothrow_default_constructible_v; + using std::is_nothrow_destructible_v; + using std::is_nothrow_move_assignable_v; + using std::is_nothrow_move_constructible_v; + using std::is_nothrow_swappable_v; + using std::is_nothrow_swappable_with_v; + using std::is_pod_v; + using std::is_polymorphic_v; + using std::is_signed_v; + using std::is_standard_layout_v; + using std::is_swappable_v; + using std::is_swappable_with_v; + using std::is_trivial_v; + using std::is_trivially_assignable_v; + using std::is_trivially_constructible_v; + using std::is_trivially_copy_assignable_v; + using std::is_trivially_copy_constructible_v; + using std::is_trivially_copyable_v; + using std::is_trivially_default_constructible_v; + using std::is_trivially_destructible_v; + using std::is_trivially_move_assignable_v; + using std::is_trivially_move_constructible_v; + using std::is_unsigned_v; + using std::is_volatile_v; + + // See C++14 20.10.5, type property queries + using std::alignment_of_v; // C++17 + using std::extent_v; // C++17 + using std::rank_v; // C++17 + + // See C++14 20.10.6, type relations + using std::is_base_of_v; + using std::is_convertible_v; + using std::is_invocable_r_v; + using std::is_invocable_v; + using std::is_nothrow_invocable_r_v; + using std::is_nothrow_invocable_v; + using std::is_same_v; + + // [meta.logical], logical operator traits: // C++17 + using std::conjunction_v; + using std::disjunction_v; + using std::negation_v; +} // 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,57 @@ +module; +#include +# 1 __FILE__ 1 3 +export module std:utility; +export namespace std { + using std::swap; + + namespace rel_ops { + using rel_ops::operator!=; + using rel_ops::operator>; + using rel_ops::operator<=; + using rel_ops::operator>=; + } // namespace rel_ops + + using std::as_const; + using std::cmp_equal; + using std::cmp_greater; // C++20 + using std::cmp_greater_equal; // C++20 + using std::cmp_less; // C++20 + using std::cmp_less_equal; // C++20 + using std::cmp_not_equal; // C++20 + using std::declval; + using std::forward; + using std::forward_like; + using std::in_range; // C++20 + using std::move; + using std::move_if_noexcept; + + using std::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; + using std::to_underlying; +} // 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,16 @@ +module; +#include +#include +# 1 __FILE__ 1 3 +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,7 @@ +# 1 __FILE__ 1 3 +export module std; +export import :coroutine; +export import :type_traits; +export import :utility; +export import :vector; +export import :exception; diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// constexpr explicit operator bool() const noexcept + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +template +constexpr bool do_test() { + static_assert(std::is_nothrow_constructible::value, ""); + static_assert(!std::is_convertible::value, ""); + { + constexpr C c; + static_assert(bool(c) == false, ""); + } + { // null case + const C c = {}; + ASSERT_NOEXCEPT(bool(c)); + assert(c.address() == nullptr); + assert(bool(c) == false); + } + { // non-null case + char dummy = 42; + C c = C::from_address((void*)&dummy); + assert(c.address() == &dummy); + assert(bool(c) == true); + } + return true; +} + +int main(int, char**) +{ + do_test>(); + do_test>(); + static_assert(do_test>()); + static_assert(do_test>()); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept; + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +template +void do_test(int *LHSVal, int *RHSVal) { + const C LHS = C::from_address(LHSVal); + const C RHS = C::from_address(RHSVal); + const bool ExpectIsEqual = (LHSVal == RHSVal); + assert((LHS == RHS) == ExpectIsEqual); + assert((RHS == LHS) == ExpectIsEqual); + assert((LHS != RHS) == !ExpectIsEqual); + assert((RHS != LHS) == !ExpectIsEqual); + { + static_assert(noexcept(LHS == RHS), ""); + static_assert(noexcept(LHS != RHS), ""); + ASSERT_SAME_TYPE(decltype(LHS == RHS), bool); + ASSERT_SAME_TYPE(decltype(LHS != RHS), bool); + } +} + +int main(int, char**) +{ + int i; + std::pair const TestCases[] = { + {nullptr, nullptr}, + {&i, &i}, + {nullptr, &i}, + {&i, nullptr} + }; + for (auto& TC : TestCases) { + do_test>(TC.first, TC.second); + do_test>(TC.first, TC.second); + } + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept; + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +template +void do_test(int *LHSVal, int *RHSVal) { + const C LHS = C::from_address(LHSVal); + const C RHS = C::from_address(RHSVal); + assert((LHS < RHS) == (LHSVal < RHSVal)); + assert((RHS < LHS) == (RHSVal < LHSVal)); + assert((LHS > RHS) == (LHSVal > RHSVal)); + assert((RHS > LHS) == (RHSVal > LHSVal)); + assert((LHS <= RHS) == (LHSVal <= RHSVal)); + assert((RHS <= LHS) == (RHSVal <= LHSVal)); + assert((LHS >= RHS) == (LHSVal >= RHSVal)); + assert((RHS >= LHS) == (RHSVal >= LHSVal)); + { + static_assert(noexcept(LHS < RHS), ""); + static_assert(noexcept(LHS > RHS), ""); + static_assert(noexcept(LHS <= RHS), ""); + static_assert(noexcept(LHS >= RHS), ""); + ASSERT_SAME_TYPE(decltype(LHS < RHS), bool); + ASSERT_SAME_TYPE(decltype(LHS > RHS), bool); + ASSERT_SAME_TYPE(decltype(LHS <= RHS), bool); + ASSERT_SAME_TYPE(decltype(LHS >= RHS), bool); + } +} + +int main(int, char**) +{ + int i; + std::pair const TestCases[] = { + {nullptr, nullptr}, + {&i, &i}, + {nullptr, &i}, + {&i, nullptr} + }; + for (auto& TC : TestCases) { + do_test>(TC.first, TC.second); + do_test>(TC.first, TC.second); + } + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// bool done() const + +#ifdef TEST_MODULES +import std; +#else +# include +#endif +#include +#include "test_macros.h" + +template +void do_test(std::coroutine_handle const& H) { + // FIXME Add a runtime test + { + ASSERT_SAME_TYPE(decltype(H.done()), bool); + LIBCPP_ASSERT_NOT_NOEXCEPT(H.done()); + } +} + +int main(int, char**) +{ + do_test(std::coroutine_handle<>{}); + do_test(std::coroutine_handle{}); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// coroutine_handle& operator=(nullptr_t) noexcept + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +// For std::nullptr_t. We're not intentioned to implement std.comp yet. +#include + +template +void do_test() { + int dummy = 42; + void* dummy_h = &dummy; + { + static_assert(std::is_nothrow_assignable::value, ""); + static_assert(!std::is_assignable::value, ""); + } + { + C c = C::from_address(dummy_h); + assert(c.address() == &dummy); + c = nullptr; + assert(c.address() == nullptr); + c = nullptr; + assert(c.address() == nullptr); + } + { + C c; + C& cr = (c = nullptr); + assert(&c == &cr); + } +} + +int main(int, char**) +{ + do_test>(); + do_test>(); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// + +// template +// struct coroutine_handle; + +// constexpr coroutine_handle() noexcept +// constexpr coroutine_handle(nullptr_t) noexcept + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" +// For std::nullptr_t. We're not intentioned to implement std.comp yet. +#include + +template +constexpr bool do_test() { + static_assert(std::is_nothrow_constructible::value, ""); + static_assert(std::is_nothrow_constructible::value, ""); + { + C c; + assert(c.address() == nullptr); + } + { + C c = C(nullptr); + assert(c.address() == nullptr); + } + return true; +} + +int main(int, char**) +{ + do_test>(); + do_test>(); + static_assert(do_test>()); + static_assert(do_test>()); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/await_result.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/await_result.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/await_result.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +#ifdef TEST_MODULES +import std; +#else +# include +#endif +#include +#include "test_macros.h" + +struct coro_t { + struct promise_type { + coro_t get_return_object() { + std::coroutine_handle{}; + return {}; + } + std::suspend_never initial_suspend() { return {}; } + std::suspend_never final_suspend() noexcept { return {}; } + void return_void() {} + static void unhandled_exception() {} + }; +}; + +struct B { + ~B() {} + bool await_ready() { return true; } + B await_resume() { return {}; } + template + void await_suspend(F) {} +}; + +struct A { + ~A() {} + bool await_ready() { return true; } + int await_resume() { return 42; } + template + void await_suspend(F) {} +}; + +int last_value = -1; +void set_value(int x) { last_value = x; } + +coro_t f(int n) { + if (n == 0) { + set_value(0); + co_return; + } + int val = co_await A{}; + ((void)val); + set_value(42); +} + +coro_t g() { B val = co_await B{}; } + +int main(int, char**) { + last_value = -1; + f(0); + assert(last_value == 0); + f(1); + assert(last_value == 42); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/generator.pass.cpp b/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/generator.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.coroutines/end.to.end/generator.pass.cpp @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: libcpp-no-coroutines + +// See https://llvm.org/PR33271 +// UNSUPPORTED: ubsan + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +template struct generator { + struct promise_type { + Ty current_value; + std::suspend_always yield_value(Ty value) { + this->current_value = value; + return {}; + } + std::suspend_always initial_suspend() { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + generator get_return_object() { return generator{this}; }; + void return_void() {} + void unhandled_exception() {} + }; + + struct iterator { + std::coroutine_handle Coro_; + bool Done_; + + iterator(std::coroutine_handle Coro, bool Done) + : Coro_(Coro), Done_(Done) {} + + iterator &operator++() { + Coro_.resume(); + Done_ = Coro_.done(); + return *this; + } + + bool operator==(iterator const &_Right) const { + return Done_ == _Right.Done_; + } + + bool operator!=(iterator const &_Right) const { return !(*this == _Right); } + + Ty const &operator*() const { return Coro_.promise().current_value; } + + Ty const *operator->() const { return &(operator*()); } + }; + + iterator begin() { + p.resume(); + return {p, p.done()}; + } + + iterator end() { return {p, true}; } + + generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; } + + ~generator() { + if (p) + p.destroy(); + } + +private: + explicit generator(promise_type *promise) + : p(std::coroutine_handle::from_promise(*promise)) {} + + std::coroutine_handle p; +}; + +struct minig { + struct promise_type { + int current_value; + std::suspend_always yield_value(int value) { + this->current_value = value; + return {}; + } + std::suspend_always initial_suspend() { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + minig get_return_object() { return minig{this}; }; + void return_void() {} + void unhandled_exception() {} + }; + + bool move_next() { + p.resume(); + return !p.done(); + } + int current_value() { return p.promise().current_value; } + + minig(minig &&rhs) : p(rhs.p) { rhs.p = nullptr; } + + ~minig() { + if (p) + p.destroy(); + } + +private: + explicit minig(promise_type *promise) + : p(std::coroutine_handle::from_promise(*promise)) {} + + std::coroutine_handle p; +}; + + +minig mini_count(int n) { + for (int i = 0; i < n; i++) { + co_yield i; + } +} + +generator count(int n) { + for (int i = 0; i < n; ++i) + co_yield i; +} + +generator range(int from, int n) { + for (int i = from; i < n; ++i) + co_yield i; +} + +void test_count() { + const std::vector expect = {0, 1, 2, 3, 4}; + std::vector got; + for (auto x : count(5)) + got.push_back(x); + assert(expect == got); +} + +void test_range() { + int sum = 0; + for (auto v: range(1, 20)) + sum += v; + assert(sum == 190); +} + +void test_mini_generator() { + int sum = 0; + auto g = mini_count(5); + while (g.move_next()) { + sum += g.current_value(); + } + assert(sum == 10); +} + +int main(int, char**) { + test_count(); + test_range(); + test_mini_generator(); + + return 0; +} diff --git a/libcxx/test/std_modules/language.support/support.exception/propagation/current_exception.pass.cpp b/libcxx/test/std_modules/language.support/support.exception/propagation/current_exception.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std_modules/language.support/support.exception/propagation/current_exception.pass.cpp @@ -0,0 +1,282 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// FIXME: This test needs to be rewritten for the MSVC exception_ptr semantics +// which copy the exception each time the exception_ptr is copied. +// XFAIL: msvc + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: no-exceptions +// + +// exception_ptr current_exception(); + +#ifdef TEST_MODULES +import std; +#else +# include +# include +#endif +#include +#include "test_macros.h" + +struct A +{ + static int constructed; + + A() {++constructed;} + ~A() {--constructed;} + A(const A&) {++constructed;} +}; + +int A::constructed = 0; + +int main(int, char**) +{ + { + std::exception_ptr p = std::current_exception(); + assert(p == nullptr); + } + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + } + assert(A::constructed == 0); + } + assert(A::constructed == 0); + { + std::exception_ptr p2; + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 1); + assert(p != nullptr); + p2 = std::current_exception(); + assert(A::constructed == 1); + assert(p == p2); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + { + std::exception_ptr p2; + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (A&) + { + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 1); + assert(p != nullptr); + p2 = std::current_exception(); + assert(A::constructed == 1); + assert(p == p2); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + { + std::exception_ptr p2; + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (A) + { + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 2); + assert(p != nullptr); + p2 = std::current_exception(); + assert(A::constructed == 2); + assert(p == p2); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + assert(A::constructed == 1); + throw; + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + } + assert(A::constructed == 0); + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 1); + assert(p != nullptr); + throw; + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + } + assert(A::constructed == 0); + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + assert(A::constructed == 1); + throw; + assert(false); + } + catch (...) + { + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 1); + assert(p != nullptr); + } + assert(A::constructed == 1); + } + assert(A::constructed == 0); + } + assert(A::constructed == 0); + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + assert(A::constructed == 1); + throw; + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + } + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 1); + assert(p != nullptr); + } + assert(A::constructed == 0); + } + assert(A::constructed == 0); + { + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + assert(A::constructed == 1); + throw; + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + } + assert(A::constructed == 1); + } + std::exception_ptr p = std::current_exception(); + assert(A::constructed == 0); + assert(p == nullptr); + } + assert(A::constructed == 0); + { + std::exception_ptr p; + try + { + assert(A::constructed == 0); + throw A(); + assert(false); + } + catch (...) + { + assert(A::constructed == 1); + try + { + assert(A::constructed == 1); + throw; + assert(false); + } + catch (...) + { + p = std::current_exception(); + assert(A::constructed == 1); + } + assert(A::constructed == 1); + } + assert(A::constructed == 1); + assert(p != nullptr); + } + assert(A::constructed == 0); + + return 0; +} 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/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 @@ -438,7 +438,8 @@ 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): 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', 'c++'] +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,27 @@ 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 [ + AddCompileFlag(lambda cfg: '-fprebuilt-module-path=' + os.path.join(cfg.test_exec_root, '../libcxx/modules')), + # Flag to indicate we want to import std instead of library headers. + AddCompileFlag('-DTEST_MODULES'), + # The list of all modules needed to be imported. + # TODO avoid this duplication. + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std.pcm'), + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std-coroutine.pcm'), + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std-exception.pcm'), + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std-vector.pcm'), + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std-utility.pcm'), + AddLinkFlag(lambda cfg: os.path.join(cfg.test_exec_root, '../libcxx/modules/') + 'std-type_traits.pcm'), + ] if enable_modules == "c++" else []), Parameter(name='enable_modules_lsv', choices=[True, False], type=bool, default=False, help="Whether to enable Local Submodule Visibility in the Modules build.",