Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2221863/?format=api
{ "id": 2221863, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2221863/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260410122931.364726-1-tkaminsk@redhat.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.1/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<20260410122931.364726-1-tkaminsk@redhat.com>", "date": "2026-04-10T12:28:44", "name": "[v2] libstdc++: Export explicit instantiations of __format::__do_vformat_to.", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "7c1a623010cbfb5543ef61ade4b268eb251db4ca", "submitter": { "id": 90409, "url": "http://patchwork.ozlabs.org/api/1.1/people/90409/?format=api", "name": "Tomasz Kamiński", "email": "tkaminsk@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260410122931.364726-1-tkaminsk@redhat.com/mbox/", "series": [ { "id": 499452, "url": "http://patchwork.ozlabs.org/api/1.1/series/499452/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=499452", "date": "2026-04-10T12:28:44", "name": "[v2] libstdc++: Export explicit instantiations of __format::__do_vformat_to.", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/499452/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2221863/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2221863/checks/", "tags": {}, "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=QDwpeozg;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=QDwpeozg", "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com", "sourceware.org; spf=pass smtp.mailfrom=redhat.com", "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fsbjp0NbNz1yGS\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 22:30:20 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 34BC04BA23C2\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 12:30:18 +0000 (GMT)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id A83FF4BA2E0D\n for <gcc-patches@gcc.gnu.org>; Fri, 10 Apr 2026 12:29:37 +0000 (GMT)", "from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-213-j1AAO0gXNJedd3W-yrhang-1; Fri,\n 10 Apr 2026 08:29:35 -0400", "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 855461956095; Fri, 10 Apr 2026 12:29:34 +0000 (UTC)", "from localhost (unknown [10.44.32.176])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id AE7283000C16; Fri, 10 Apr 2026 12:29:33 +0000 (UTC)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org 34BC04BA23C2", "OpenDKIM Filter v2.11.0 sourceware.org A83FF4BA2E0D" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org A83FF4BA2E0D", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org A83FF4BA2E0D", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775824177; cv=none;\n b=NcywjSxDnvvTYDdgs9tr4sNkhNJtr8+bT7y7iuDgDZHhmSf2GMtymdLFnVwmerXGQF2pshjP5AoNRzyEJXnG2wMYlEIvNbItkIy8sU1a++yfHBHFRDbcnJCO7LqT62heiaVRo71vKu7Ic5RZfJFM1UmAcaJDUAyTzaDuSRfm+I4=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775824177; c=relaxed/simple;\n bh=qx4CgPZF8OodcK445Z+LR4Q3lYqFIJ6o7ztn19HOj4k=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=Wrs0KRqs2vphMJXt+GBah6MjPmnKg2B3LmWp1cvDJ+ZOJEXFtFhNxeJUi3XXlTRLVMFJ7eZGVzn0hZ+lonAzp5Yk1N/l8BlQzM9he6DkqBI35YOsRy7qgAbnvpGg+n61PuSWAMsBWNoHbD6Vvk6dUpw1ZwdQ6Y0mNpLMWRL9IVc=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775824177;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=fX7PZn0uyghJreaD8j5YVmRrx8cTUyCPFpPD7ATikMg=;\n b=QDwpeozg//DP7jJphnrftE05wbyALZFb2dcGr+RBLmS+aIwJXS0keXijhXPO+vvDpcSSdl\n lL6+og4PcAIVp89R4wRIMax3t+yDbOqKunE+rHX6m8Ls/cGpFhpy2IuI2FwzMSOhgW4vvH\n HWsAv0MkYlzGCiu8K3W5NbLoIXbMetw=", "X-MC-Unique": "j1AAO0gXNJedd3W-yrhang-1", "X-Mimecast-MFC-AGG-ID": "j1AAO0gXNJedd3W-yrhang_1775824174", "From": "=?utf-8?q?Tomasz_Kami=C5=84ski?= <tkaminsk@redhat.com>", "To": "libstdc++@gcc.gnu.org,\n\tgcc-patches@gcc.gnu.org", "Subject": "[PATCH v2] libstdc++: Export explicit instantiations of\n __format::__do_vformat_to.", "Date": "Fri, 10 Apr 2026 14:28:44 +0200", "Message-ID": "<20260410122931.364726-1-tkaminsk@redhat.com>", "In-Reply-To": "\n <CAKvuMXAwc0t=SzjHM5ziAG+=wCp9itX-SNDOUrsooZtUAvHQVQ@mail.gmail.com>", "References": "\n <CAKvuMXAwc0t=SzjHM5ziAG+=wCp9itX-SNDOUrsooZtUAvHQVQ@mail.gmail.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "0mojtiCDIjBzlZuAGHJ0_Xe6J0XVP8JzGKIah9PO4xU_1775824174", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "This patch extracts an __format::__do_vformat_to for the _Sink_iter\n(and matching format context) and exports explicit instantiations\nof it for wchar and wchar_t. As every format function is implementing\nas delegating the one of these overloads, this significantly reduces\nthe compliation time.\n\nInstantiating __format::__do_vformat_to triggers specializations of\nformatters for types stored in handle direclty (arithmetic types,\nstrings). In case when their behavior depends on the TU specific\nconfiguration, only one configuration can be exported from shared\nlib. In case of beforementioned formatter:\n* ? (debug mode) is accepted in for strings and characters\n* multibyte utf-8 encoded character is accepted as fill when the\n literal encoding is Unicode.\n\nThe first issue is addressed by this patch, by declaring extern\ndefintion only for the C++20. We will need to reconsider how to\nhandle the specifiers when C++23 becomes stable.\n\nThe literal encoding is handled by adding a second template parameter\nto __do_vformat_to overload, that is initialzied with 1 if literal\nencoding is unicode (the parameter has unsigned type to allow more\ninformation to be encoded). This allows library to export implementation\nfor unicode literal encoding (format-inst.cc is compiled with appropariate\nflag), by declaring extern specialization only for 1 value.\n\nlibstdc++-v3/ChangeLog:\n\n\t* config/abi/pre/gnu.ver (GLIBCXX_3.4): Exclude exports\n\tof std::basic_fo* (matching basic_format_context).\n\t(GLIBCXX_3.4.35): Export __format::__do_vformat_to\n\tspecializations for _Sink_iter and char/wchar_t.\n\t* include/std/format: (__format::__do_vformat_to):\n\tExtract overload accepting _Sink_iter and provide extern\n\texplicit specialization for char/wchar_t in C++20 mode.\n\t* src/c++20/Makefile.am: Add format-inst.cc.\n\t* src/c++20/Makefile.in: Regenerate.\n\t* src/c++20/format-inst.cc: New file defining explicit\n\tinstantiation.\n---\nSending v2 that addresses handling program using non-unicode literal\nencoding linking with libstdc++. I am starting to lean more into\nthis solution, in combination with accepting later format-string\nadditions as extension being better direction.\n\nTested on x86_64-linux.\n\n\n libstdc++-v3/config/abi/pre/gnu.ver | 8 +-\n libstdc++-v3/include/std/format | 154 +++++++++++++++-----------\n libstdc++-v3/src/c++20/Makefile.am | 10 +-\n libstdc++-v3/src/c++20/Makefile.in | 18 ++-\n libstdc++-v3/src/c++20/format-inst.cc | 46 ++++++++\n 5 files changed, 163 insertions(+), 73 deletions(-)\n create mode 100644 libstdc++-v3/src/c++20/format-inst.cc", "diff": "diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver\nindex 2ff2aa02383..fe6e6bf15b4 100644\n--- a/libstdc++-v3/config/abi/pre/gnu.ver\n+++ b/libstdc++-v3/config/abi/pre/gnu.ver\n@@ -34,7 +34,9 @@ GLIBCXX_3.4 {\n std::basic_[a-e]*;\n std::basic_f[a-h]*;\n # std::basic_filebuf;\n- std::basic_f[j-r]*;\n+ std::basic_f[j-n]*;\n+# std::basic_format_context;\n+ std::basic_f[p-r]*;\n # std::basic_fstream;\n std::basic_f[t-z]*;\n std::basic_[g-h]*;\n@@ -2608,6 +2610,10 @@ GLIBCXX_3.4.35 {\n _ZNSbIwSt11char_traitsIwESaIwEEC[12]EvQ26is_default_constructible_vIT1_E;\n _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[1-2]EvQ26is_default_constructible_vIT1_E;\n \n+ # __format::__do_vformat_to<char, 1>(_Sink_iter<char>, string_view, format_context&);\n+ # __format::__do_vformat_to<wchar_t, 1>(_Sink_iter<wchar_t>, wstring_view, format_context&);\n+ _ZNSt8__format15__do_vformat_toI[cw]Lj1EEENS_10_Sink_iterIT_EES3_St17basic_string_viewIS2_St11char_traitsIS2_EERSt20basic_format_contextIS3_S2_E;\n+\n #if defined (_WIN32) && !defined (__CYGWIN__)\n _ZSt19__get_once_callablev;\n _ZSt15__get_once_callv;\ndiff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format\nindex eca5bd213aa..57d2ddd511d 100644\n--- a/libstdc++-v3/include/std/format\n+++ b/libstdc++-v3/include/std/format\n@@ -5219,82 +5219,106 @@ namespace __format\n #endif\n };\n \n- template<typename _Out, typename _CharT, typename _Context>\n- inline _Out\n- __do_vformat_to(_Out __out, basic_string_view<_CharT> __fmt,\n-\t\t const basic_format_args<_Context>& __args,\n-\t\t const locale* __loc)\n+ template<typename _CharT, unsigned = __unicode::__literal_encoding_is_unicode<_CharT>()>\n+ _Sink_iter<_CharT>\n+ __do_vformat_to(_Sink_iter<_CharT> __out, basic_string_view<_CharT> __fmt,\n+\t\t __format_context<_CharT>& __ctx)\n {\n- if constexpr (is_same_v<_Out, _Sink_iter<_CharT>>)\n-\t{\n-\t if constexpr (is_same_v<_CharT, char>)\n-\t // Fast path for \"{}\" format strings and simple format arg types.\n-\t if (__fmt.size() == 2 && __fmt[0] == '{' && __fmt[1] == '}')\n-\t {\n-\t\tbool __done = false;\n-\t\t__format::__visit_format_arg([&](auto& __arg) {\n-\t\t using _Tp = remove_cvref_t<decltype(__arg)>;\n-\t\t if constexpr (is_same_v<_Tp, bool>)\n+ if constexpr (is_same_v<_CharT, char>)\n+\t// Fast path for \"{}\" format strings and simple format arg types.\n+\tif (__fmt.size() == 2 && __fmt[0] == '{' && __fmt[1] == '}')\n+\t {\n+\t bool __done = false;\n+\t __format::__visit_format_arg([&](auto& __arg) {\n+\t using _Tp = remove_cvref_t<decltype(__arg)>;\n+\t if constexpr (is_same_v<_Tp, bool>)\n+\t\t{\n+\t\t size_t __len = 4 + !__arg;\n+\t\t const char* __chars[] = { \"false\", \"true\" };\n+\t\t if (auto __res = __out._M_reserve(__len))\n \t\t {\n-\t\t size_t __len = 4 + !__arg;\n-\t\t const char* __chars[] = { \"false\", \"true\" };\n-\t\t if (auto __res = __out._M_reserve(__len))\n-\t\t\t{\n-\t\t\t __builtin_memcpy(__res.get(), __chars[__arg], __len);\n-\t\t\t __res._M_bump(__len);\n-\t\t\t __done = true;\n-\t\t\t}\n+\t\t __builtin_memcpy(__res.get(), __chars[__arg], __len);\n+\t\t __res._M_bump(__len);\n+\t\t __done = true;\n \t\t }\n-\t\t else if constexpr (is_same_v<_Tp, char>)\n+\t\t}\n+\t else if constexpr (is_same_v<_Tp, char>)\n+\t\t{\n+\t\t if (auto __res = __out._M_reserve(1))\n \t\t {\n-\t\t if (auto __res = __out._M_reserve(1))\n-\t\t\t{\n-\t\t\t *__res.get() = __arg;\n-\t\t\t __res._M_bump(1);\n-\t\t\t __done = true;\n-\t\t\t}\n+\t\t *__res.get() = __arg;\n+\t\t __res._M_bump(1);\n+\t\t __done = true;\n \t\t }\n-\t\t else if constexpr (is_integral_v<_Tp>)\n+\t\t}\n+\t else if constexpr (is_integral_v<_Tp>)\n+\t\t{\n+\t\t make_unsigned_t<_Tp> __uval;\n+\t\t const bool __neg = __arg < 0;\n+\t\t if (__neg)\n+\t\t __uval = make_unsigned_t<_Tp>(~__arg) + 1u;\n+\t\t else\n+\t\t __uval = __arg;\n+\t\t const auto __n = __detail::__to_chars_len(__uval);\n+\t\t if (auto __res = __out._M_reserve(__n + __neg))\n \t\t {\n-\t\t make_unsigned_t<_Tp> __uval;\n-\t\t const bool __neg = __arg < 0;\n-\t\t if (__neg)\n-\t\t\t__uval = make_unsigned_t<_Tp>(~__arg) + 1u;\n-\t\t else\n-\t\t\t__uval = __arg;\n-\t\t const auto __n = __detail::__to_chars_len(__uval);\n-\t\t if (auto __res = __out._M_reserve(__n + __neg))\n-\t\t\t{\n-\t\t\t auto __ptr = __res.get();\n-\t\t\t *__ptr = '-';\n-\t\t\t __detail::__to_chars_10_impl(__ptr + (int)__neg, __n,\n-\t\t\t\t\t\t __uval);\n-\t\t\t __res._M_bump(__n + __neg);\n-\t\t\t __done = true;\n-\t\t\t}\n+\t\t auto __ptr = __res.get();\n+\t\t *__ptr = '-';\n+\t\t __detail::__to_chars_10_impl(__ptr + (int)__neg, __n,\n+\t\t\t\t\t\t __uval);\n+\t\t __res._M_bump(__n + __neg);\n+\t\t __done = true;\n \t\t }\n-\t\t else if constexpr (is_convertible_v<_Tp, string_view>)\n+\t\t}\n+\t else if constexpr (is_convertible_v<_Tp, string_view>)\n+\t\t{\n+\t\t string_view __sv = __arg;\n+\t\t if (auto __res = __out._M_reserve(__sv.size()))\n \t\t {\n-\t\t string_view __sv = __arg;\n-\t\t if (auto __res = __out._M_reserve(__sv.size()))\n-\t\t\t{\n-\t\t\t __builtin_memcpy(__res.get(), __sv.data(), __sv.size());\n-\t\t\t __res._M_bump(__sv.size());\n-\t\t\t __done = true;\n-\t\t\t}\n+\t\t __builtin_memcpy(__res.get(), __sv.data(), __sv.size());\n+\t\t __res._M_bump(__sv.size());\n+\t\t __done = true;\n \t\t }\n-\t\t}, __args.get(0));\n+\t\t}\n+\t }, __ctx.arg(0));\n \n-\t\tif (__done)\n-\t\t return __out;\n-\t }\n+\t if (__done)\n+\t return __out;\n+\t }\n+\n+ _Formatting_scanner<_Sink_iter<_CharT>, _CharT> __scanner(__ctx, __fmt);\n+ __scanner._M_scan();\n+ return __out;\n+ }\n+\n+// The behavior of the formatters (interpretation of fill character) depends\n+// on the literal encoding. As explicit instantiation of __do_vformat_to\n+// instantiates formatters for types stored in basic_format_arg, we can\n+// support only single encoding, in this case unicode. This should cover\n+// most common use cases.\n+#if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0\n+ extern template _Sink_iter<char>\n+ __do_vformat_to<char, 1>(_Sink_iter<char>, string_view,\n+\t\t\t format_context&);\n+# ifdef _GLIBCXX_USE_WCHAR_T\n+ extern template _Sink_iter<wchar_t>\n+ __do_vformat_to<wchar_t, 1>(_Sink_iter<wchar_t>, wstring_view,\n+\t\t\t\t wformat_context&);\n+# endif\n+#endif\n \n+ template<typename _Out, typename _CharT, typename _Context>\n+ inline _Out\n+ __do_vformat_to(_Out __out, basic_string_view<_CharT> __fmt,\n+\t\t const basic_format_args<_Context>& __args,\n+\t\t const locale* __loc)\n+ {\n+ if constexpr (is_same_v<_Out, _Sink_iter<_CharT>>)\n+\t{\n \t auto __ctx = __loc == nullptr\n-\t\t\t ? _Context(__args, __out)\n-\t\t\t : _Context(__args, __out, *__loc);\n-\t _Formatting_scanner<_Sink_iter<_CharT>, _CharT> __scanner(__ctx, __fmt);\n-\t __scanner._M_scan();\n-\t return __out;\n+\t\t ? _Context(__args, __out)\n+\t\t : _Context(__args, __out, *__loc);\n+\t return __do_vformat_to(std::move(__out), __fmt, __ctx);\n \t}\n else if constexpr (__contiguous_char_iter<_CharT, _Out>)\n \t{\n@@ -5311,7 +5335,7 @@ namespace __format\n }\n \n template<typename _Out, typename _CharT>\n- format_to_n_result<_Out>\n+ inline format_to_n_result<_Out>\n __do_vformat_to_n(_Out __out, iter_difference_t<_Out> __n,\n \t\t basic_string_view<_CharT> __fmt,\n \t\t const type_identity_t<\ndiff --git a/libstdc++-v3/src/c++20/Makefile.am b/libstdc++-v3/src/c++20/Makefile.am\nindex af5d2fa4057..c2311696415 100644\n--- a/libstdc++-v3/src/c++20/Makefile.am\n+++ b/libstdc++-v3/src/c++20/Makefile.am\n@@ -33,11 +33,11 @@ else\n extra_string_inst_sources =\n endif\n \n-\n if ENABLE_EXTERN_TEMPLATE\n # XTEMPLATE_FLAGS = -fno-implicit-templates\n inst_sources = \\\n \tsstream-inst.cc \\\n+\tformat-inst.cc\n \tstring-inst.cc \\\n \t$(extra_string_inst_sources)\n else\n@@ -73,6 +73,14 @@ format.lo: format.cc\n format.o: format.cc\n \t$(CXXCOMPILE) -std=gnu++26 -fno-access-control -c $<\n \n+if ENABLE_EXTERN_TEMPLATE\n+# The unicode literal version of formatters is exported, override the encoding accordingly\n+format-inst.lo: format-inst.cc\n+\t$(LTCXXCOMPILE) -fexec-charset=UTF-8 -c $<\n+format-inst.o: format-inst.cc\n+\t$(CXXCOMPILE) -fexec-charset=UTF-8 -c $<\n+endif\n+\n if GLIBCXX_HOSTED\n libc__20convenience_la_SOURCES = $(sources) $(inst_sources)\n else\ndiff --git a/libstdc++-v3/src/c++20/Makefile.in b/libstdc++-v3/src/c++20/Makefile.in\nindex a2386ec7ee0..44110878307 100644\n--- a/libstdc++-v3/src/c++20/Makefile.in\n+++ b/libstdc++-v3/src/c++20/Makefile.in\n@@ -124,11 +124,10 @@ CONFIG_CLEAN_VPATH_FILES =\n LTLIBRARIES = $(noinst_LTLIBRARIES)\n libc__20convenience_la_LIBADD =\n am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo syncbuf.lo\n-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-string-inst.lo\n-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = sstream-inst.lo \\\n-@ENABLE_EXTERN_TEMPLATE_TRUE@\tstring-inst.lo $(am__objects_2)\n+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo \\\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tformat-inst.lo\n @GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \\\n-@GLIBCXX_HOSTED_TRUE@\t$(am__objects_1) $(am__objects_3)\n+@GLIBCXX_HOSTED_TRUE@\t$(am__objects_1) $(am__objects_2)\n libc__20convenience_la_OBJECTS = $(am_libc__20convenience_la_OBJECTS)\n AM_V_lt = $(am__v_lt_@AM_V@)\n am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)\n@@ -438,8 +437,7 @@ headers =\n # XTEMPLATE_FLAGS = -fno-implicit-templates\n @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \\\n @ENABLE_EXTERN_TEMPLATE_TRUE@\tsstream-inst.cc \\\n-@ENABLE_EXTERN_TEMPLATE_TRUE@\tstring-inst.cc \\\n-@ENABLE_EXTERN_TEMPLATE_TRUE@\t$(extra_string_inst_sources)\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tformat-inst.cc\n \n sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc\n @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = \n@@ -750,6 +748,8 @@ uninstall-am:\n \n .PRECIOUS: Makefile\n \n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tstring-inst.cc \\\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\t$(extra_string_inst_sources)\n \n vpath % $(top_srcdir)/src/c++20\n \n@@ -773,6 +773,12 @@ format.lo: format.cc\n format.o: format.cc\n \t$(CXXCOMPILE) -std=gnu++26 -fno-access-control -c $<\n \n+# The unicode literal version of formatters is exported, override the encoding accordingly\n+@ENABLE_EXTERN_TEMPLATE_TRUE@format-inst.lo: format-inst.cc\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\t$(LTCXXCOMPILE) -fexec-charset=UTF-8 -c $<\n+@ENABLE_EXTERN_TEMPLATE_TRUE@format-inst.o: format-inst.cc\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\t$(CXXCOMPILE) -fexec-charset=UTF-8 -c $<\n+\n # Tell versions [3.59,3.63) of GNU make to not export all variables.\n # Otherwise a system limit (for SysV at least) may be exceeded.\n .NOEXPORT:\ndiff --git a/libstdc++-v3/src/c++20/format-inst.cc b/libstdc++-v3/src/c++20/format-inst.cc\nnew file mode 100644\nindex 00000000000..1c5973b4bcb\n--- /dev/null\n+++ b/libstdc++-v3/src/c++20/format-inst.cc\n@@ -0,0 +1,46 @@\n+// Definitions for <chrono> formatting -*- C++ -*-\n+\n+// Copyright The GNU Toolchain Authors.\n+//\n+// This file is part of the GNU ISO C++ Library. This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+// GNU General Public License for more details.\n+\n+// Under Section 7 of GPL version 3, you are granted additional\n+// permissions described in the GCC Runtime Library Exception, version\n+// 3.1, as published by the Free Software Foundation.\n+\n+// You should have received a copy of the GNU General Public License and\n+// a copy of the GCC Runtime Library Exception along with this program;\n+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see\n+// <http://www.gnu.org/licenses/>.\n+\n+#include <format>\n+#include <chrono>\n+\n+namespace std\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+namespace __format\n+{\n+\n+ template _Sink_iter<char>\n+ __do_vformat_to<char, 1>(_Sink_iter<char>, string_view,\n+\t\t \t format_context&);\n+\n+# ifdef _GLIBCXX_USE_WCHAR_T\n+ template _Sink_iter<wchar_t>\n+ __do_vformat_to<wchar_t, 1>(_Sink_iter<wchar_t>, wstring_view,\n+\t\t\t wformat_context&);\n+# endif\n+\n+} // namespace __format\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n", "prefixes": [ "v2" ] }