diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -304,6 +304,14 @@ option(LIBCXX_HERMETIC_STATIC_LIBRARY "Do not export any symbols from the static library." ${LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT}) +set(LIBCXX_TIME_ZONE_DB "" CACHE PATH + "Where the time zone data files are found. When the path is empty + the platform specific defaults are used. Consult the libc++ building + instructions for more information.") +if(LIBCXX_TIME_ZONE_DB) + add_definitions(-D_LIBCPP_TIME_ZONE_DB_PATH="${LIBCXX_TIME_ZONE_DB}") +endif() + #=============================================================================== # Check option configurations #=============================================================================== diff --git a/libcxx/docs/BuildingLibcxx.rst b/libcxx/docs/BuildingLibcxx.rst --- a/libcxx/docs/BuildingLibcxx.rst +++ b/libcxx/docs/BuildingLibcxx.rst @@ -22,6 +22,36 @@ place to install libc++. +.. _TimeZoneDatabase: + +Time Zone Database +================== + +Starting with C++20 the ```` library has support for time zones. +In order to use this facility libc++ needs to know where the +`IANA Time Zone Database `__ is stored. +The database consists of a directory with the following files: + +- ``tzdata.zi``, and +- ``leap-seconds.list`` + +On platforms that ship the required database, libc++ will automatically find +the database. + +If the database is not available on your platform, you can +`download `__ +and install the database manually. In order for libc++ to find the +database configure CMake with the proper value for the option +``LIBCXX_TIME_ZONE_DB``. + +.. note:: When your platform ships the database and libc++ fails to find it + automatically, please file a bug report using the + `LLVM bug tracker `_. + Make sure the report contains the location of the database on + your platform. Alternatively you can provide a patch for the file + ``libcxx/include/__config``. + + The default build ================= @@ -304,6 +334,13 @@ Additional libraries libc++ is linked to which can be provided in cache. +.. option:: LIBCXX_TIME_ZONE_DB:PATH + + **Default**: ``""`` + + The path where the time zone data files are found. When the path is empty + the platform specific defaults are used. + .. _ABI Library Specific Options: diff --git a/libcxx/docs/DesignDocs/TimeZone.rst b/libcxx/docs/DesignDocs/TimeZone.rst new file mode 100644 --- /dev/null +++ b/libcxx/docs/DesignDocs/TimeZone.rst @@ -0,0 +1,146 @@ +================= +Time Zone Support +================= + +Introduction +============ + +Starting with C++20 the ```` library has support for time zones. +These are available in the +`IANA Time Zone Database `_. +This page describes the design decisions and trade-offs made to implement this +feature. This page contains several links with more information regarding the +contents of the IANA database, this page assumes the reader is familiar with +this information. + +Which version of the Time Zone Database to use +============================================== + +The data of the database is available in several platforms in different forms: + +- Typically Unix systems ship the database as + `TZif files `_. This format has + 3 versions and the ``time_zone_link`` information is not always available. + If available, they are symlinks in the file system. + These files don't provide the database version information. This information + is needed for the functions ``std::chrono:: remote_version()`` and + ``std::chrono::reload_tzdb()``. + +- On several Unix systems the time zone source files are available. These files + are stored in several regions, mainly the continents. This file contains a + large amount of comment with historical information regarding time zones. + The format is documented in the + `IANA documentation `_ + and in the `man page `_ of zic. + The disadvantage of this version is that at least Linux versions don't have + the database version information. This information is needed for the functions + ``std::chrono:: remote_version()`` and ``std::chrono::reload_tzdb()``. + +- On Linux systems ``tzdata.zi`` is available. This contains the same + information as the source files but in one file without the comments. This + file uses the same format as the sources, but shortens the names. For example + ``Rule`` is abbreviated to ``R``. This file contains the database version + information. + +The disadvantage of the binary data is that it's not possible on all platforms +to get the proper ``time_zone_link`` information. This information is in the +database, this difference is observable by users. Without the database version +information it's not possible to create a conforming implementation. + +Since it's easier to parse one file than a set of files the libc++ team decided +to use the ``tzdata.zi``. The other benefit is that the ``tzdata.zi`` file +contains the database version information needed for a conforming +implementation. + +The file ``tzdata.zi`` is not available on all platforms, so vendors need to +make changes for their platform. Most vendors already ship the database, so +they need to adjust the packaging of their time zone package. On Windows this +is not available by default. However it's possible for Windows packagers to add +these files to their libc++ packages. The IANA databases can be +`downloaded `_. + +An alternative would be to ship the database with libc++, either as a file or +compiled in the dylib. The text file is about 112 KB. For now libc++ will not +ship this file. When it's hard to get vendors to ship these files we can +reconsider based on that information. + +Leap seconds +------------ + +For the leap seconds libc++ will use the source file ``leap-seconds.list``. +This file is easier to parse than the ``leapseconds`` file. Both files are +present on Linux, but not always on other platforms. Since these platforms need +to change their packaging for ``tzdata.zi``, adding two instead of one files +seems a small change. + + +Selecting the Time Zone Database location +========================================= + +There are several mechanisms to select the database location + +- Use the location known to libc++. At the moment of writing not all platforms + ship the database. Those that ship the database have the path configured in + ``include/__config``. +- The CMake configuration option ``LIBCXX_TIME_ZONE_DB``. This makes it + possible for vendors to ship the database when its location is unknown to + libc++. The vendor may opt to notify the libc++ development team when the + location is hard coded so the default location can be set. However when the + location is configurable this offers a flexible way to configure the location + system wide. +- Overriding ``std::chrono::__libcpp_tzdb_directory()``. This allows + applications to specify their own database path and implement their own time + zone update policy. This may be important for applications that require more + up to date information than their operating system provides. This is also + heavily used to test the parsing of the time zone database in libc++. + This includes testing with corrupt databases. + + +Updating the Time Zone Database +=============================== + +Per `[time.zone.db.remote]/1 `_ + +.. code-block:: text + + The local time zone database is that supplied by the implementation when the + program first accesses the database, for example via current_zone(). While the + program is running, the implementation may choose to update the time zone + database. This update shall not impact the program in any way unless the + program calls the functions in this subclause. This potentially updated time + zone database is referred to as the remote time zone database. + +There is an update mechanism in libc++, however this is not done automatically. +Invoking the function ``std::chrono:: remote_version()`` will parse the version +information of the ``tzdata.zi`` file and returns that information. Similar +``std::chrono::reload_tzdb()`` will parse the ``tzdata.zi`` and +``leap-seconds.list`` again. This makes is possible to update the database if +needed by the application and gives the user full power over the update policy. + +This approach has several advantages: + +- It is simple to implement. +- The library does not need to start a periodic background process to poll + changes to the filesystem. When using a background process, it may become + active when the application is busy with its core task, taking away resources + from that task. +- When there is no threading available this polling + becomes more involved. For example, query the file every *x* calls to + ``std::chrono::get_tzdb()``. This mean calls to ``std::chrono::get_tzdb()`` + has different performance characteristics. +- Even when the automatic update is implemented, user may want + ``std::chrono:: remote_version()`` to load the most recent information. For + example since they use ``std::chrono::__libcpp_tzdb_directory()`` to have + full control over the time zone information in their application. + That means ``std::chrono:: remote_version()`` should always query. + +The small drawback is: + +- On platforms with threading enabled updating the database may take longer. + On these platforms the remote database could have been loaded in a background + process. + +Another issue with the automatic update is, that is may not be considered +Standard compliant "This update shall not impact the program in any way". Using +resources could be considered impacting the program. + diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst --- a/libcxx/docs/Status/Cxx20.rst +++ b/libcxx/docs/Status/Cxx20.rst @@ -51,6 +51,15 @@ .. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet. .. [#note-P0408] P0408: Only `view()` members implemented. .. [#note-P0660] P0660: Section 32.3 Stop Tokens is complete. ``jthread`` hasn't been implemented yet. + .. [#note-P0355] P0355: The implementation status is: + + * ``Calendars`` mostely done in Clang 7 + * ``Input parsers`` not done + * ``Stream output`` Obsolete due to `P1361R2 `_ "Integration of chrono with text formatting" + * ``Time zone and leap seconds`` In Progress + * ``TAI clock`` not done + * ``GPS clock`` not done + * ``UTC clock`` not done .. _issues-status-cxx20: diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv --- a/libcxx/docs/Status/Cxx20Issues.csv +++ b/libcxx/docs/Status/Cxx20Issues.csv @@ -241,7 +241,7 @@ "`3316 `__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","","|chrono|" "`3317 `__","Incorrect ``operator<<``\ for floating-point durations","Prague","","","|chrono|" "`3318 `__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|" -"`3319 `__","Properly reference specification of IANA time zone database","Prague","","","|chrono|" +"`3319 `__","Properly reference specification of IANA time zone database","Prague","|Nothing To Do|","","|chrono|" "`3320 `__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|","" "`3321 `__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","|Complete|","16.0" "`3323 `__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","|Complete|","16.0","|ranges|" diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -17,7 +17,7 @@ "`P0768R1 `__","CWG","Library Support for the Spaceship (Comparison) Operator","Albuquerque","|Complete|","" "`P0777R1 `__","LWG","Treating Unnecessary ``decay``\ ","Albuquerque","|Complete|","7.0" "`P0122R7 `__","LWG","","Jacksonville","|Complete|","7.0" -"`P0355R7 `__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|In Progress|","" +"`P0355R7 `__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|Partial| [#note-P0355]_","" "`P0551R3 `__","LWG","Thou Shalt Not Specialize ``std``\ Function Templates!","Jacksonville","|Complete|","11.0" "`P0753R2 `__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","","" "`P0754R2 `__","LWG","","Jacksonville","|Complete|","7.0" diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -537,6 +537,76 @@ Unicode code points, without requiring the user to use the latest C++ version in their code base. +Extensions to ```` +-------------------------- + +Configuring the Time Zone Database location +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``chrono`` library offers a way to change the path where the +`IANA `__ Time Zone Database is stored. +By default the path is the system or vendor provided path. +There are a several use cases where changing the default can be useful: + +- The system or vendor does not provide a database. Please contact your + vendor to provide support. +- Your application needs more control over the database version used. + The ``chrono`` library has the function ``std::chrono::reload_tzdb`` + to update the database, but it provides no Standard way to specify how + a new database is provided. +- Testing libc++ with a known version of the database. + +In order to change the path you need to use link-time customization of +the path lookup function, similarly to how replacing operator new works. +Link-time customization is done by simply defining the following +function in exactly one translation unit of your program: + +.. code-block:: cpp + + std::string_view std::chrono::__libcpp_tzdb_directory(); + + +This mechanism is similar to how one can replace the default definition +of operator new and operator delete. For example: + +.. code-block:: cpp + + // In HelloWorldHandler.cpp + #include + + std::string_view std::chrono::__libcpp_tzdb_directory() { + static std::string_view result = "C:/usr/share/zoneinfo"; + return result; + } + + // In HelloWorld.cpp + #include + + int main() { + return std::chrono::remote_version() == "my_database"; + } + + +.. warning:: + The path used must contain a database with the + :ref:`required files `. + + +Updating the Time Zone Database +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Standard allows implementations to automatically update the +*remote time zone database*. Libc++ opts not to do that. Instead calling + +- ``std::chrono::remote_version()`` will update the verson information of the + *remote time zone database*, +- ``std::chrono::reload_tzdb()``, if needed, will update the the entire + *remote time zone database*. + +This offers a method users to update the *remote time zone database*, and +giving them full control over the process. + + Turning off ASan annotation in containers ----------------------------------------- diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -191,6 +191,7 @@ DesignDocs/UniquePtrTrivialAbi DesignDocs/UnspecifiedBehaviorRandomization DesignDocs/VisibilityMacros + DesignDocs/TimeZone Build Bots and Test Coverage diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -280,6 +280,8 @@ __chrono/steady_clock.h __chrono/system_clock.h __chrono/time_point.h + __chrono/tzdb.h + __chrono/tzdb_list.h __chrono/weekday.h __chrono/year.h __chrono/year_month.h diff --git a/libcxx/include/__availability b/libcxx/include/__availability --- a/libcxx/include/__availability +++ b/libcxx/include/__availability @@ -174,6 +174,11 @@ // # define _LIBCPP_AVAILABILITY_HAS_NO_PMR # define _LIBCPP_AVAILABILITY_PMR + // This controls the availability of the C++20 time zone database. + // The parser code is built in the library. +// # define _LIBCPP_AVAILABILITY_TZDB +# define _LIBCPP_AVAILABILITY_TZDB + #elif defined(__APPLE__) // shared_mutex and shared_timed_mutex @@ -348,6 +353,8 @@ # define _LIBCPP_AVAILABILITY_PMR # endif +# define _LIBCPP_AVAILABILITY_TZDB __attribute__((unavailable)) + #else // ...New vendors can add availability markup here... diff --git a/libcxx/include/__chrono/tzdb.h b/libcxx/include/__chrono/tzdb.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__chrono/tzdb.h @@ -0,0 +1,43 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TZDB_H +#define _LIBCPP___CHRONO_TZDB_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) + +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +struct _LIBCPP_AVAILABILITY_TZDB tzdb { + string version; +}; + +} // namespace chrono + +# endif //_LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) + +#endif // _LIBCPP___CHRONO_TZDB_H diff --git a/libcxx/include/__chrono/tzdb_list.h b/libcxx/include/__chrono/tzdb_list.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__chrono/tzdb_list.h @@ -0,0 +1,116 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TZDB_LIST_H +#define _LIBCPP___CHRONO_TZDB_LIST_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) + +# include <__availability> +# include <__chrono/tzdb.h> +# include <__mutex/unique_lock.h> +# include +# include + +// When threads are not available the locking is not required. +# ifndef _LIBCPP_HAS_NO_THREADS +# include +# endif + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +// TODO TZDB Document and test _LIBCPP_NODISCARD_EXT. +class _LIBCPP_AVAILABILITY_TZDB tzdb_list { +public: + _LIBCPP_HIDE_FROM_ABI explicit tzdb_list(tzdb&& __tzdb) { __tzdb_.push_front(std::move(__tzdb)); } + + tzdb_list(const tzdb_list&) = delete; + tzdb_list& operator=(const tzdb_list&) = delete; + + using const_iterator = forward_list::const_iterator; + + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { +# ifndef _LIBCPP_HAS_NO_THREADS + shared_lock __lock{__mutex_}; +# endif + return __tzdb_.front(); + } + + _LIBCPP_HIDE_FROM_ABI const_iterator erase_after(const_iterator __p) { +# ifndef _LIBCPP_HAS_NO_THREADS + unique_lock __lock{__mutex_}; +# endif + return __tzdb_.erase_after(__p); + } + + _LIBCPP_HIDE_FROM_ABI tzdb& __emplace_front(tzdb&& __tzdb) { +# ifndef _LIBCPP_HAS_NO_THREADS + unique_lock __lock{__mutex_}; +# endif + return __tzdb_.emplace_front(std::move(__tzdb)); + } + + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { +# ifndef _LIBCPP_HAS_NO_THREADS + shared_lock __lock{__mutex_}; +# endif + return __tzdb_.begin(); + } + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { + // forward_list::end does not access the list. + return __tzdb_.end(); + } + + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); } + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); } + +private: +# ifndef _LIBCPP_HAS_NO_THREADS + mutable shared_mutex __mutex_; +# endif + forward_list __tzdb_; +}; + +// This function allows users to override the directory where the TZDB +// files are stored. This should rarely be needed, a better solution +// would be to set the proper value at build time in +// _LIBCPP_CHRONO_TZDB_DIRECTORY +_LIBCPP_AVAILABILITY_TZDB _LIBCPP_OVERRIDABLE_FUNC_VIS string_view __libcpp_tzdb_directory(); + +_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); + +_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { + return get_tzdb_list().front(); +} + +_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb(); + +_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); + +} // namespace chrono + +# endif //_LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB) + +#endif // _LIBCPP___CHRONO_TZDB_LIST_H diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -293,6 +293,10 @@ # define _LIBCPP_HAS_NO_INCOMPLETE_PSTL # endif +# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_HAS_NO_INCOMPLETE_TZDB +# endif + // Need to detect which libc we're using if we're on Linux. # if defined(__linux__) # include @@ -1344,6 +1348,15 @@ # define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED +// Libc++ support for the IANA Time Zone Database. +// TODO TZDB Add Apple when it provides the required files. +// TODO TZDB Add FreeBSD when it provides the required files. +# ifndef _LIBCPP_TIME_ZONE_DB_PATH +# if defined(__linux__) +# define _LIBCPP_TIME_ZONE_DB_PATH "/usr/share/zoneinfo/" +# endif +# endif // _LIBCPP_TIME_ZONE_DB_PATH + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/libcxx/include/chrono b/libcxx/include/chrono --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -677,6 +677,39 @@ constexpr hours make12(const hours& h) noexcept; constexpr hours make24(const hours& h, bool is_pm) noexcept; +// [time.zone.db], time zone database +struct tzdb { // C++20 + string version; +}; + +class tzdb_list { // C++20 +public: + tzdb_list(const tzdb_list&) = delete; + tzdb_list& operator=(const tzdb_list&) = delete; + + // unspecified additional constructors + + class const_iterator; + + const tzdb& front() const noexcept; + + const_iterator erase_after(const_iterator p); + + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; +}; + +// [time.zone.db.access], time zone database access +const tzdb& get_tzdb(); // C++20 +tzdb_list& get_tzdb_list(); // C++20 + +// [time.zone.db.remote], remote time zone database support +const tzdb& reload_tzdb(); // C++20 +string remote_version(); // C++20 + // 25.10.5, class time_zone // C++20 enum class choose {earliest, latest}; class time_zone; @@ -799,6 +832,10 @@ # include <__chrono/statically_widen.h> #endif +#if !defined(_LIBCPP_HAS_NO_FILESYSTEM) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include <__chrono/tzdb.h> +# include <__chrono/tzdb_list.h> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -782,6 +782,14 @@ export time_point } module time_point { private header "__chrono/time_point.h" } + module tzdb { + private header "__chrono/tzdb.h" + export string + } + module tzdb_list { + private header "__chrono/tzdb_list.h" + export forward_list + } module weekday { private header "__chrono/weekday.h" } module year { private header "__chrono/year.h" } module year_month { private header "__chrono/year_month.h" } diff --git a/libcxx/modules/std/chrono.cppm b/libcxx/modules/std/chrono.cppm --- a/libcxx/modules/std/chrono.cppm +++ b/libcxx/modules/std/chrono.cppm @@ -192,21 +192,21 @@ 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::current_zone; using std::chrono::get_tzdb; using std::chrono::get_tzdb_list; - using std::chrono::locate_zone; + // using std::chrono::locate_zone; // [time.zone.db.remote], remote time zone database support using std::chrono::reload_tzdb; using std::chrono::remote_version; +#if 0 // [time.zone.exception], exception classes using std::chrono::ambiguous_local_time; using std::chrono::nonexistent_local_time; diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -318,6 +318,12 @@ experimental/memory_resource.cpp ) +if (LIBCXX_ENABLE_LOCALIZATION AND LIBCXX_ENABLE_FILESYSTEM) + list(APPEND LIBCXX_EXPERIMENTAL_SOURCES + tz.cpp + ) +endif() + add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES}) target_link_libraries(cxx_experimental PUBLIC cxx-headers) if (LIBCXX_ENABLE_SHARED) diff --git a/libcxx/src/tz.cpp b/libcxx/src/tz.cpp new file mode 100644 --- /dev/null +++ b/libcxx/src/tz.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#include +#include +#include +#include +#include + +// Contains a parser for the IANA time zone data files. +// +// These files can be found at https://data.iana.org/time-zones/ and are in the +// public domain. Information regarding the input can be found at +// https://data.iana.org/time-zones/tz-how-to.html and +// https://man7.org/linux/man-pages/man8/zic.8.html . +// +// As indicated at https://howardhinnant.github.io/date/tz.html#Installation +// For Windows another file seems to be required +// https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml +// This file seems to contain the mapping of Windows time zone name to IANA +// time zone names. +// +// However this article mentions another way to do the mapping on Windows +// https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255 +// This requires Windows 10 Version 1903, which was released in May of 2019 +// and considered end of life in December 2020 +// https://learn.microsoft.com/en-us/lifecycle/announcements/windows-10-1903-end-of-servicing +// +// TODO TZDB Implement the Windows mapping in tzdb::current_zone + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono { + +[[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; } + +static void __skip_optional_whitespace(istream& __input) { + while (chrono::__is_whitespace(__input.peek())) + __input.get(); +} + +static void __skip_mandatory_whitespace(istream& __input) { + if (!chrono::__is_whitespace(__input.get())) + std::__throw_runtime_error("corrupt tzdb: expected whitespace"); + + chrono::__skip_optional_whitespace(__input); +} + +static void __matches(istream& __input, char __expected) { + if (std::tolower(__input.get()) != __expected) + std::__throw_runtime_error((string("corrupt tzdb: expected character '") + __expected + '\'').c_str()); +} + +static void __matches(istream& __input, string_view __expected) { + for (auto __c : __expected) + if (std::tolower(__input.get()) != __c) + std::__throw_runtime_error((string("corrupt tzdb: expected string '") + string(__expected) + '\'').c_str()); +} + +[[nodiscard]] static string __parse_string(istream& __input) { + string __result; + while (true) { + int __c = __input.get(); + switch (__c) { + case ' ': + case '\t': + case '\n': + __input.unget(); + [[fallthrough]]; + case istream::traits_type::eof(): + if (__result.empty()) + std::__throw_runtime_error("corrupt tzdb: expected a string"); + + return __result; + + default: + __result.push_back(__c); + } + } +} + +static string __parse_version(istream& __input) { + // The first line in tzdata.zi contains + // # version YYYYw + // The parser expects this pattern + // #\s*version\s*\(.*) + // This part is not documented. + chrono::__matches(__input, '#'); + chrono::__skip_optional_whitespace(__input); + chrono::__matches(__input, "version"); + chrono::__skip_mandatory_whitespace(__input); + return chrono::__parse_string(__input); +} + +static tzdb __make_tzdb() { + tzdb __result; + + filesystem::path __root = chrono::__libcpp_tzdb_directory(); + ifstream __tzdata{__root / "tzdata.zi"}; + + __result.version = chrono::__parse_version(__tzdata); + return __result; +} + +//===----------------------------------------------------------------------===// +// Public API +//===----------------------------------------------------------------------===// + +_LIBCPP_WEAK string_view __libcpp_tzdb_directory() { +#ifndef _LIBCPP_TIME_ZONE_DB_PATH + std::__throw_runtime_error("unknown path to the IANA Time Zone Database"); +#else + return _LIBCPP_TIME_ZONE_DB_PATH; +#endif +} + +_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list() { + static tzdb_list __result{chrono::__make_tzdb()}; + return __result; +} + +_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb() { + if (chrono::remote_version() == chrono::get_tzdb().version) + return chrono::get_tzdb(); + + return chrono::get_tzdb_list().__emplace_front(chrono::__make_tzdb()); +} + +_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version() { + filesystem::path __root = chrono::__libcpp_tzdb_directory(); + ifstream __tzdata{__root / "tzdata.zi"}; + return chrono::__parse_version(__tzdata); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp --- a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp +++ b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp @@ -26,3 +26,7 @@ #ifdef _LIBCPP_HAS_NO_INCOMPLETE_PSTL # error "-fexperimental-library should enable the PSTL" #endif + +#ifdef _LIBCPP_HAS_NO_INCOMPLETE_TZDB +# error "-fexperimental-library should enable the chrono TZDB" +#endif diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// +// +// class tzdb_list; +// +// const_iterator erase_after(const_iterator p); + +#include +#include +#include +#include + +#include "filesystem_test_helper.h" +#include "test_macros.h" + +scoped_test_env env; +[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo"); +const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi"); + +std::string_view std::chrono::__libcpp_tzdb_directory() { + static std::string result = dir.string(); + return result; +} + +static void write(std::string_view input) { std::ofstream{file}.write(input.data(), input.size()); } + +int main(int, const char**) { + write("# version 1"); + std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); // [1] + + write("# version 2"); + std::chrono::reload_tzdb(); // [2, 1] + + assert(std::distance(list.begin(), list.end()) == 2); + assert(list.front().version == "2"); + + list.erase_after(list.begin()); // [2] + assert(std::distance(list.begin(), list.end()) == 1); + assert(list.front().version == "2"); + + write("# version 3"); + std::chrono::reload_tzdb(); // [3, 2] + assert(std::distance(list.begin(), list.end()) == 2); + + write("# version 4"); + std::chrono::reload_tzdb(); // [4, 3, 2] + assert(std::distance(list.begin(), list.end()) == 3); + assert(list.front().version == "4"); + + std::chrono::tzdb_list::const_iterator it = ++list.begin(); + assert(it->version == "3"); + + list.erase_after(it); // [4, 3] + assert(std::distance(list.begin(), list.end()) == 2); + assert(list.front().version == "4"); + assert(it->version == "3"); +} diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// + +// const tzdb& reload_tzdb(); + +#include +#include +#include +#include + +#include "filesystem_test_helper.h" +#include "test_macros.h" + +scoped_test_env env; +[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo"); +const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi"); + +std::string_view std::chrono::__libcpp_tzdb_directory() { + static std::string result = dir.string(); + return result; +} + +static void write(std::string_view input) { std::ofstream{file}.write(input.data(), input.size()); } + +int main(int, const char**) { + write("# version old_version"); + const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); + std::string version = "new_version"; + + assert(list.front().version == "old_version"); + assert(std::distance(list.begin(), list.end()) == 1); + assert(std::distance(list.cbegin(), list.cend()) == 1); + + write("# version new_version"); + assert(std::chrono::remote_version() == version); + + std::chrono::reload_tzdb(); + + assert(std::distance(list.begin(), list.end()) == 2); + assert(std::distance(list.cbegin(), list.cend()) == 2); + assert(list.front().version == version); + + return 0; +} diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.db/version.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.db/version.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/time/time.zone/time.zone.db/version.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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// + +// Tests the IANA database version parsing. +// This is not part of the public tzdb interface. + +#include +#include +#include +#include + +#include "assert_macros.h" +#include "concat_macros.h" +#include "filesystem_test_helper.h" + +scoped_test_env env; +[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo"); +const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi"); + +std::string_view std::chrono::__libcpp_tzdb_directory() { + static std::string result = dir.string(); + return result; +} + +static void test(std::string_view input, std::string_view expected) { + std::ofstream{file}.write(input.data(), input.size()); + std::string version = std::chrono::remote_version(); + + TEST_REQUIRE( + version == expected, + TEST_WRITE_CONCATENATED( + "\nInput ", input, "\nExpected version ", expected, "\nActual version ", version, '\n')); +} + +static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) { + std::ofstream{file}.write(input.data(), input.size()); + + TEST_VALIDATE_EXCEPTION( + std::runtime_error, + [&]([[maybe_unused]] const std::runtime_error& e) { + TEST_LIBCPP_REQUIRE( + e.what() == what, + TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n')); + }, + TEST_IGNORE_NODISCARD std::chrono::remote_version()); +} + +int main(int, const char**) { + test_exception("", "corrupt tzdb: expected character '#'"); + test_exception("#version", "corrupt tzdb: expected whitespace"); + test("#version \t ABCD", "ABCD"); + test("#Version \t ABCD", "ABCD"); + test("#vErsion \t ABCD", "ABCD"); + test("#verSion \t ABCD", "ABCD"); + test("#VERSION \t ABCD", "ABCD"); + test("# \t version \t 2023a", "2023a"); + + return 0; +} diff --git a/libcxx/test/libcxx/transitive_includes.gen.py b/libcxx/test/libcxx/transitive_includes.gen.py --- a/libcxx/test/libcxx/transitive_includes.gen.py +++ b/libcxx/test/libcxx/transitive_includes.gen.py @@ -64,7 +64,7 @@ {lit_header_restrictions.get(header, '')} // TODO: Fix this test to make it work with localization or wide characters disabled -// UNSUPPORTED{BLOCKLIT}: no-localization, no-wide-characters +// UNSUPPORTED{BLOCKLIT}: no-localization, no-wide-characters, no-threads, no-filesystem, libcpp-has-no-incomplete-tzdb // When built with modules, this test doesn't work because --trace-includes doesn't // report the stack of includes correctly. diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -112,6 +112,7 @@ charconv limits charconv type_traits chrono bit +chrono cerrno chrono compare chrono concepts chrono cstddef @@ -119,9 +120,12 @@ chrono cstdlib chrono cstring chrono ctime +chrono forward_list chrono limits chrono ratio +chrono shared_mutex chrono stdexcept +chrono string chrono string_view chrono tuple chrono type_traits diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -112,6 +112,7 @@ charconv limits charconv type_traits chrono bit +chrono cerrno chrono compare chrono concepts chrono cstddef @@ -119,9 +120,12 @@ chrono cstdlib chrono cstring chrono ctime +chrono forward_list chrono limits chrono ratio +chrono shared_mutex chrono stdexcept +chrono string chrono string_view chrono tuple chrono type_traits diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -112,6 +112,7 @@ charconv limits charconv type_traits chrono bit +chrono cerrno chrono compare chrono concepts chrono cstddef @@ -119,9 +120,12 @@ chrono cstdlib chrono cstring chrono ctime +chrono forward_list chrono limits chrono ratio +chrono shared_mutex chrono stdexcept +chrono string chrono string_view chrono tuple chrono type_traits diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -112,6 +112,7 @@ charconv limits charconv type_traits chrono bit +chrono cerrno chrono compare chrono concepts chrono cstddef @@ -119,9 +120,12 @@ chrono cstdlib chrono cstring chrono ctime +chrono forward_list chrono limits chrono ratio +chrono shared_mutex chrono stdexcept +chrono string chrono string_view chrono tuple chrono type_traits diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -121,11 +121,13 @@ chrono cstdlib chrono cstring chrono ctime +chrono forward_list chrono limits chrono locale chrono optional chrono ostream chrono ratio +chrono shared_mutex chrono sstream chrono stdexcept chrono string diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -72,6 +72,7 @@ chrono cstdint chrono cstdlib chrono ctime +chrono forward_list chrono initializer_list chrono limits chrono locale @@ -79,6 +80,7 @@ chrono optional chrono ostream chrono ratio +chrono shared_mutex chrono sstream chrono stdexcept chrono string diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -72,6 +72,7 @@ chrono cstdint chrono cstdlib chrono ctime +chrono forward_list chrono initializer_list chrono limits chrono locale @@ -79,6 +80,7 @@ chrono optional chrono ostream chrono ratio +chrono shared_mutex chrono sstream chrono stdexcept chrono string diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// + +// const tzdb& get_tzdb(); + +#include + +#include + +#include "test_macros.h" + +int main(int, const char**) { + const std::chrono::tzdb& db = std::chrono::get_tzdb(); + + assert(!db.version.empty()); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb_list.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb_list.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb_list.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// + +// const tzdb& get_tzdb_list(); + +#include + +#include +#include + +#include "test_macros.h" + +int main(int, const char**) { + const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); + + assert(!list.front().version.empty()); + assert(std::distance(list.begin(), list.end()) == 1); + assert(std::distance(list.cbegin(), list.cend()) == 1); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/erase_after.compile.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/erase_after.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/erase_after.compile.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// +// +// class tzdb_list; +// +// const_iterator erase_after(const_iterator p); +// +// [time.zone.db.list]/5 +// Preconditions: The iterator following p is dereferenceable. +// +// Since there is no Standard way to create a second entry it's not +// possible to fullfill this precondition. This is tested in a libc++ +// specific test. + +#include +#include + +std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); +static_assert(std::same_as); diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/front.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/front.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/front.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// +// +// class tzdb_list; +// +// const tzdb& front() const noexcept; + +#include + +int main(int, char**) { + const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); + [[maybe_unused]] const std::chrono::tzdb& _ = list.front(); + static_assert(noexcept(list.front())); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/iterators.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/iterators.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/iterators.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// +// +// class tzdb_list; +// +// const_iterator begin() const noexcept; +// const_iterator end() const noexcept; +// +// const_iterator cbegin() const noexcept; +// const_iterator cend() const noexcept; + +#include +#include +#include + +int main(int, char**) { + const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); + using it = std::chrono::tzdb_list::const_iterator; + + static_assert(noexcept(list.begin())); + static_assert(noexcept(list.end())); + static_assert(noexcept(list.cbegin())); + static_assert(noexcept(list.cend())); + + std::same_as auto begin = list.begin(); + std::same_as auto end = list.end(); + assert(std::distance(begin, end) == 1); + + std::same_as auto cbegin = list.cbegin(); + assert(begin == cbegin); + + std::same_as auto cend = list.cend(); + assert(end == cend); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/types.compile.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/types.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.list/types.compile.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// + +// class tzdb_list { +// public: +// tzdb_list(const tzdb_list&) = delete; +// tzdb_list& operator=(const tzdb_list&) = delete; +// +// ... +// +// }; +// +// [time.zone.db.list]/1 +// The tzdb_list database is a singleton; the unique object of type +// tzdb_list can be accessed via the get_tzdb_list() function. +//// +// This means the class may not have a default constructor. + +#include +#include + +static_assert(!std::copyable); +static_assert(!std::movable); +static_assert(!std::default_initializable); diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// + +// Note there is no Standard way to change the remote database used. +// That is tested in +// test/libcxx/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp + +// const tzdb& reload_tzdb(); + +#include +#include +#include + +#include "test_macros.h" + +int main(int, const char**) { + const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); + std::string version = list.front().version; + assert(!version.empty()); + + assert(std::distance(list.begin(), list.end()) == 1); + assert(std::distance(list.cbegin(), list.cend()) == 1); + assert(std::chrono::remote_version() == version); + + std::chrono::reload_tzdb(); + + assert(std::distance(list.begin(), list.end()) == 1); + assert(std::distance(list.cbegin(), list.cend()) == 1); + assert(std::chrono::remote_version() == version); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/remote_version.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/remote_version.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.remote/remote_version.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing +// XFAIL: no-system-provided-tzdb + +// + +// const string remote_version(); + +#include + +#include + +#include "test_macros.h" + +int main(int, const char**) { + std::string version = std::chrono::remote_version(); + assert(!version.empty()); + + assert(version == std::chrono::get_tzdb().version); + assert(version == std::chrono::get_tzdb_list().front().version); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/tzdb.members.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/tzdb.members.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/tzdb.members.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: no-filesystem, no-localization + +// XFAIL: libcpp-has-no-incomplete-tzdb +// XFAIL: availability-tzdb-missing + +// + +// struct tzdb { +// string version; +// vector zones; +// vector links; +// vector leap_seconds; +// +// ... +// }; + +#include +#include + +#include "assert_macros.h" + +int main(int, const char**) { + std::chrono::tzdb tzdb; + + [[maybe_unused]] std::same_as auto _ = tzdb.version = "version"; + + // TODO TZDB add the other data members + + 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 @@ -30,498 +30,6 @@ LLVM_HEAD_VERSION: "17" GCC_STABLE_VERSION: "12" steps: - # - # Light pre-commit tests for things like formatting or when people forget - # to update generated files. - # - - label: "Format" - command: "libcxx/utils/ci/run-buildbot check-format" - artifact_paths: - - "**/clang-format.patch" - env: - GIT_CLANG_FORMAT: "/usr/bin/git-clang-format-${LLVM_STABLE_VERSION} --binary clang-format-${LLVM_STABLE_VERSION}" - 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 - - - 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++26" - command: "libcxx/utils/ci/run-buildbot generic-cxx26" - 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++23 Module std" - command: "libcxx/utils/ci/run-buildbot generic-module-std-cxx23" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - env: - # 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" - 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++23" - command: "libcxx/utils/ci/run-buildbot generic-cxx23" - 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++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-cxx23" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - env: - CC: "clang-15" - CXX: "clang++-15" - 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-cxx23" - 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: "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" @@ -560,24 +68,6 @@ 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 locale" command: "libcxx/utils/ci/run-buildbot generic-no-localization" artifact_paths: @@ -596,42 +86,6 @@ 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: @@ -650,61 +104,6 @@ limit: 2 timeout_in_minutes: 120 - - label: "No exceptions" - command: "libcxx/utils/ci/run-buildbot generic-no-exceptions" - 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: diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -558,6 +558,23 @@ cfg.available_features, ), ), + # Tests that require time zone database support in the built library + Feature( + name="availability-tzdb-missing", + when=lambda cfg: BooleanExpression.evaluate( + # TODO(ldionne) Please provide the correct value. + "(stdlib=apple-libc++ && target={{.+}}-apple-macosx{{(10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0|13.0)(.0)?}})", + cfg.available_features, + ), + ), + # Test that require a time zone database to be available on the system + Feature( + name="no-system-provided-tzdb", + when=lambda cfg: BooleanExpression.evaluate( + "freebsd || darwin || windows || buildhost=aix", + cfg.available_features, + ), + ), # Tests that require 64-bit architecture Feature( name="32-bit-pointer", 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 @@ -272,6 +272,7 @@ if experimental else [ AddFeature("libcpp-has-no-incomplete-pstl"), + AddFeature("libcpp-has-no-incomplete-tzdb"), ], ), Parameter(