aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-01-15 14:09:21 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-09-15 16:15:28 +0100
commit1dde83f0ec313166fc91e6784a0ca2e3db46acee (patch)
tree3d6913fad6e908c5448177965f6ce927f13f961c
parentf91fe35aa14bf4d44f2c8394301858b42e12ee45 (diff)
downloadgcc-1dde83f0ec313166fc91e6784a0ca2e3db46acee.zip
gcc-1dde83f0ec313166fc91e6784a0ca2e3db46acee.tar.gz
gcc-1dde83f0ec313166fc91e6784a0ca2e3db46acee.tar.bz2
libstdc++: Enable most of <chrono> for freestanding
This makes durations, time points and calendrical types available for freestanding. The clocks and time zone utilities are disabled for freestanding, as they require functions in the hosted lib. Add support for a new macro _GLIBCXX_NO_FREESTANDING_CHRONO which can be used to explicitly disable <chrono> for freestanding. libstdc++-v3/ChangeLog: * doc/xml/manual/using.xml (_GLIBCXX_NO_FREESTANDING_CHRONO): Document macro. * doc/html/*: Regenerate. * include/bits/chrono.h [_GLIBCXX_NO_FREESTANDING_CHRONO]: Only include <bits/require_hosted.h> when this macro is defined. [_GLIBCXX_HOSTED]: Only define clocks for hosted. * include/bits/version.def (chrono_udls): Remove hosted=yes. * include/bits/version.h: Regenerate. * include/std/chrono [_GLIBCXX_HOSTED]: Only define clocks and time zone utilities for hosted. * testsuite/std/time/freestanding.cc: New test.
-rw-r--r--libstdc++-v3/doc/html/manual/using_macros.html7
-rw-r--r--libstdc++-v3/doc/xml/manual/using.xml12
-rw-r--r--libstdc++-v3/include/bits/chrono.h24
-rw-r--r--libstdc++-v3/include/bits/version.def1
-rw-r--r--libstdc++-v3/include/bits/version.h2
-rw-r--r--libstdc++-v3/include/std/chrono24
-rw-r--r--libstdc++-v3/testsuite/std/time/freestanding.cc52
7 files changed, 109 insertions, 13 deletions
diff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html
index ae56469..67623b5 100644
--- a/libstdc++-v3/doc/html/manual/using_macros.html
+++ b/libstdc++-v3/doc/html/manual/using_macros.html
@@ -124,4 +124,11 @@
must be present on all vector operations or none, so this macro must
be defined to the same value for all translation units that create,
destroy, or modify vectors.
+ </p></dd><dt><span class="term"><code class="code">_GLIBCXX_NO_FREESTANDING_CHRONO</code></span></dt><dd><p>
+ Undefined by default. When defined, the
+ <code class="filename">&lt;chrono&gt;</code> header cannot
+ be used with <code class="option">-ffreestanding</code>.
+ When not defined, durations, time points, and calendar types are
+ available for freestanding, but the standard clocks and the time zone
+ database are not (because they require OS support).
</p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using_headers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="using.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="using_dual_abi.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Headers </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Dual ABI</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
index 6675359..4e1c700 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1321,6 +1321,18 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
destroy, or modify vectors.
</para>
</listitem></varlistentry>
+
+ <varlistentry><term><code>_GLIBCXX_NO_FREESTANDING_CHRONO</code></term>
+ <listitem>
+ <para>
+ Undefined by default. When defined, the
+ <filename class="headerfile">&lt;chrono&gt;</filename> header cannot
+ be used with <option>-ffreestanding</option>.
+ When not defined, durations, time points, and calendar types are
+ available for freestanding, but the standard clocks and the time zone
+ database are not (because they require OS support).
+ </para>
+ </listitem></varlistentry>
</variablelist>
</section>
diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h
index 0773867..fd9c464 100644
--- a/libstdc++-v3/include/bits/chrono.h
+++ b/libstdc++-v3/include/bits/chrono.h
@@ -37,7 +37,9 @@
#include <ratio>
#include <type_traits>
#include <limits>
-#include <ctime>
+#if _GLIBCXX_HOSTED
+# include <ctime>
+#endif
#include <bits/parse_numbers.h> // for literals support.
#if __cplusplus >= 202002L
# include <concepts>
@@ -50,7 +52,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L && _GLIBCXX_HOSTED
namespace filesystem { struct __file_clock; };
#endif
@@ -372,7 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
#endif // C++20
-#ifdef __glibcxx_chrono // C++ >= 17 && HOSTED
+#if __cplusplus >= 201703L // C++ >= 17
/** Convert a `duration` to type `ToDur` and round down.
*
* If the duration cannot be represented exactly in the result type,
@@ -1196,6 +1198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @}
/// @} group chrono
+#if _GLIBCXX_HOSTED
// Clocks.
// Why nanosecond resolution as the default?
@@ -1310,9 +1313,18 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
template<> inline constexpr bool is_clock_v<file_clock> = true;
/// @}
#endif // C++20
+#elif __cplusplus >= 202002L
+ // Define a fake clock like chrono::local_t so that sys_time etc.
+ // can be used for freestanding.
+ struct __sys_t;
+ template<typename _Duration>
+ using sys_time = time_point<__sys_t, _Duration>;
+ using sys_seconds = sys_time<seconds>;
+ using sys_days = sys_time<days>;
+#endif // _GLIBCXX_HOSTED
} // namespace chrono
-#ifdef __glibcxx_chrono_udls // C++ >= 14 && HOSTED
+#ifdef __glibcxx_chrono_udls // C++ >= 14
inline namespace literals
{
/** ISO C++ 2014 namespace for suffixes for duration literals.
@@ -1435,7 +1447,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
} // namespace chrono
#endif // __glibcxx_chrono_udls
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L && _GLIBCXX_HOSTED
namespace filesystem
{
struct __file_clock
@@ -1497,7 +1509,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
}
};
} // namespace filesystem
-#endif // C++17
+#endif // C++17 && HOSTED
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index bd3af9c..36f9ea4 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -275,7 +275,6 @@ ftms = {
values = {
v = 201304;
cxxmin = 14;
- hosted = yes;
};
};
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 364e3a0..fb97e67 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -289,7 +289,7 @@
#undef __glibcxx_want_to_chars
#if !defined(__cpp_lib_chrono_udls)
-# if (__cplusplus >= 201402L) && _GLIBCXX_HOSTED
+# if (__cplusplus >= 201402L)
# define __glibcxx_chrono_udls 201304L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_chrono_udls)
# define __cpp_lib_chrono_udls 201304L
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 7ffa536..aa78254 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -32,7 +32,9 @@
#pragma GCC system_header
-#include <bits/requires_hosted.h> // for <ctime> and clocks
+#ifdef _GLIBCXX_NO_FREESTANDING_CHRONO
+# include <bits/requires_hosted.h> // for <ctime> and clocks
+#endif
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
@@ -41,7 +43,9 @@
#include <bits/chrono.h>
#if __cplusplus >= 202002L
-# include <bit>
+# include <bit> // __countr_zero
+#endif
+#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
# include <sstream>
# include <string>
# include <vector>
@@ -82,6 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using local_seconds = local_time<seconds>;
using local_days = local_time<days>;
+#if _GLIBCXX_HOSTED
class utc_clock;
class tai_clock;
class gps_clock;
@@ -234,7 +239,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
}
};
-
+#endif // _GLIBCXX_HOSTED
template<typename _DestClock, typename _SourceClock>
struct clock_time_conversion
@@ -251,6 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __t; }
};
+#if _GLIBCXX_HOSTED
template<>
struct clock_time_conversion<system_clock, system_clock>
{
@@ -355,6 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return _DestClock::from_utc(__t);
}
};
+#endif // _GLIBCXX_HOSTED
/// @cond undocumented
namespace __detail
@@ -365,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
clock_time_conversion<_DestClock, _SourceClock>{}(__t);
};
+#if _GLIBCXX_HOSTED
template<typename _DestClock, typename _SourceClock, typename _Duration>
concept __clock_convs_sys
= requires (const time_point<_SourceClock, _Duration>& __t) {
@@ -394,7 +402,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
clock_time_conversion<system_clock, utc_clock>{}(
clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
};
-
+#endif // _GLIBCXX_HOSTED
} // namespace __detail
/// @endcond
@@ -404,10 +412,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline auto
clock_cast(const time_point<_SourceClock, _Duration>& __t)
requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
+#if _GLIBCXX_HOSTED
|| __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
|| __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
|| __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
|| __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
+#endif // _GLIBCXX_HOSTED
{
constexpr bool __direct
= __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
@@ -415,6 +425,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
}
+#if _GLIBCXX_HOSTED
else
{
constexpr bool __convert_via_sys_clock
@@ -465,6 +476,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
}
+#endif // _GLIBCXX_HOSTED
}
// CALENDRICAL TYPES
@@ -2530,6 +2542,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#if _GLIBCXX_HOSTED
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
// C++20 [time.zones] Time zones
@@ -3324,6 +3337,7 @@ namespace __detail
const auto __li = __detail::__get_leap_second_info(__s, false);
return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
}
+#endif // _GLIBCXX_HOSTED
/// @} group chrono
#endif // C++20
@@ -3358,7 +3372,7 @@ namespace __detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
-#if __cplusplus >= 202002L
+#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
# include <bits/chrono_io.h>
#endif
diff --git a/libstdc++-v3/testsuite/std/time/freestanding.cc b/libstdc++-v3/testsuite/std/time/freestanding.cc
new file mode 100644
index 0000000..afda0d5
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/freestanding.cc
@@ -0,0 +1,52 @@
+// { dg-options "-ffreestanding" }
+// { dg-do compile { target c++11 } }
+
+#include <chrono>
+
+using namespace std::chrono;
+
+milliseconds
+test_duration()
+{
+ seconds sec{1};
+ sec = sec + -sec;
+ return duration_cast<milliseconds>(sec + microseconds{100});
+}
+
+struct Clock
+{
+ using rep = long;
+ using period = std::ratio<1,10>;
+ using duration = std::chrono::duration<rep, period>;
+ using time_point = std::chrono::time_point<Clock>;
+
+ static const bool is_steady = true;
+
+ static time_point now() noexcept
+ {
+ static time_point tick{duration{0}};
+ return tick + tick.time_since_epoch();
+ }
+};
+
+Clock::time_point
+test_time_point()
+{
+ auto t = Clock::now() + milliseconds{1};
+ return time_point_cast<Clock::duration>(t);
+}
+
+#if __cplusplus > 202002L
+static_assert( is_clock_v<Clock> );
+
+bool
+test_calendar()
+{
+ auto t = test_time_point();
+ t = clock_cast<Clock>(t);
+ local_days d{floor<days>(t + 1h + 1min + 1s).time_since_epoch()};
+ year_month_day ymd{d};
+ weekday w{d};
+ return w.ok();
+}
+#endif