diff options
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/algorithm.cxx | 13 | ||||
-rw-r--r-- | libbuild2/c/init.cxx | 26 | ||||
-rw-r--r-- | libbuild2/cc/buildfile | 8 | ||||
-rw-r--r-- | libbuild2/cc/common.cxx | 14 | ||||
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 302 | ||||
-rw-r--r-- | libbuild2/cc/predefs-rule.cxx | 2 | ||||
-rw-r--r-- | libbuild2/cc/std.compat.cppm | 996 | ||||
-rw-r--r-- | libbuild2/cc/std.cppm | 134 | ||||
-rw-r--r-- | libbuild2/cxx/init.cxx | 51 | ||||
-rw-r--r-- | libbuild2/diagnostics.cxx | 36 | ||||
-rw-r--r-- | libbuild2/dist/operation.cxx | 2 | ||||
-rw-r--r-- | libbuild2/file.cxx | 11 | ||||
-rw-r--r-- | libbuild2/scheduler.cxx | 12 |
13 files changed, 1348 insertions, 259 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index 62c500d..16f1503 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -1282,6 +1282,19 @@ namespace build2 // has no own prerequisites and the group's ones will be matched // by the group. } + else + { + // Similar to catch(failed) below. + // + s.state = target_state::failed; + l.offset = target::offset_applied; + + // Make sure we don't relock a failed target. + // + match_extra& me (s.match_extra); + me.cur_options = match_extra::all_options; + me.cur_options_.store (me.cur_options, memory_order_relaxed); + } } else l.offset = target::offset_tried; diff --git a/libbuild2/c/init.cxx b/libbuild2/c/init.cxx index 8bc2f7d..f100abc 100644 --- a/libbuild2/c/init.cxx +++ b/libbuild2/c/init.cxx @@ -111,23 +111,31 @@ namespace build2 // From version 16.8 VC now supports /std:c11 and /std:c17 options // which enable C11/17 conformance. However, as of version 16.10, // neither SDK nor CRT can be compiled in these modes (see the /std - // option documentation for details/updates). + // option documentation for details/updates). There is also now + // /std:clatest which can be used to enable C23 typeof as of MSVC + // 17.9. So let's map C23 to that. // if (v == nullptr) ; else if (!stdcmp ("90")) { - uint64_t cver (ci.version.major); - - if ((stdcmp ("99") && cver < 16) || // Since VS2010/10.0. - ((stdcmp ("11") || - stdcmp ("17") || - stdcmp ("18")) && cver < 18) || // Since VS????/11.0. - (stdcmp ("23", "2x") )) + uint64_t mj (ci.version.major); + uint64_t mi (ci.version.minor); + + if (stdcmp ("99") && mj >= 16) // Since VS2010/10.0. + ; + else if ((stdcmp ("11") || + stdcmp ("17") || + stdcmp ("18")) && mj >= 18) // Since VS????/11.0. + ; + else if (stdcmp ("23", "2x") && + (mj > 19 || (mj == 19 && mi >= 39))) // Since 17.9. { + mode.insert (mode.begin (), "/std:clatest"); + } + else fail << "C " << *v << " is not supported by " << ci.signature << info << "required by " << project (rs) << '@' << rs; - } } break; } diff --git a/libbuild2/cc/buildfile b/libbuild2/cc/buildfile index 7dcd811..05e4c8c 100644 --- a/libbuild2/cc/buildfile +++ b/libbuild2/cc/buildfile @@ -11,7 +11,7 @@ libpkgconf = $config.build2.libpkgconf if $libpkgconf import impl_libs += libpkgconf%lib{pkgconf} else - import impl_libs += libpkg-config%lib{pkg-config} + import impl_libs += libbutl%lib{butl-pkg-config} include ../bin/ intf_libs = ../bin/lib{build2-bin} @@ -25,14 +25,14 @@ libul{build2-cc}: cxx{pkgconfig-libpkg-config}: include = (!$libpkgconf) libul{build2-cc}: $intf_libs $impl_libs -# libc++ std module interface translation unit. +# libc++ std module interface translation units. # # Hopefully temporary, see llvm-project GH issues #73089. # # @@ TMP: make sure sync'ed with upstream before release (keep this note). # -lib{build2-cc}: file{std.cppm} -file{std.cppm}@./: install = data/libbuild2/cc/ +lib{build2-cc}: file{std.cppm std.compat.cppm} +file{std.cppm}@./ file{std.compat.cppm}@./: install = data/libbuild2/cc/ # Unit tests. # diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx index 2a8bc50..9a4a07c 100644 --- a/libbuild2/cc/common.cxx +++ b/libbuild2/cc/common.cxx @@ -1691,6 +1691,10 @@ namespace build2 // Note that clang-cl appears to use -fansi-escape-codes. See GH // issue #312 for background. // + // Note that MSVC ignores /diagnostics:color if diagnostics is + // written to a pipe. See GH issue #312 for details and a link to + // the MSVC bug report. + // if (show_diag_color ()) { if (cvariant.empty () && @@ -1716,7 +1720,8 @@ namespace build2 // // Supported from GCC 4.9 (8.1 on Windows) and (at least) from Clang // 3.5. Clang supports -f[no]color-diagnostics in addition to the - // GCC's spelling. + // GCC's spelling. Note that to enable color on Windows Clang also + // needs -fansi-escape-codes. // if ( #ifndef _WIN32 @@ -1742,7 +1747,14 @@ namespace build2 show_diag_color () ? "-fdiagnostics-color" : stderr_term ? "-fno-diagnostics-color" : nullptr)) + { args.push_back (o); + +#ifdef _WIN32 + if (ctype == compiler_type::clang && o[2] != 'n') + args.push_back ("-fansi-escape-codes"); +#endif + } } } diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index 2e4775e..7629ed5 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -6151,180 +6151,185 @@ namespace build2 } }; - // Pre-resolve std modules in an ad hoc way for certain compilers. + // Pre-resolve standard library modules (std and std.compat) in an ad + // hoc way. // - // @@ TODO: cache x_stdlib value. + + // Similar logic to check_exact() above. // - if ((ctype == compiler_type::msvc) || - (ctype == compiler_type::clang && - cmaj >= 17 && - cast<string> (rs[x_stdlib]) == "libc++")) + done = true; + + for (size_t i (0); i != n; ++i) { - // Similar logic to check_exact() above. - // - done = true; + module_import& m (imports[i]); - for (size_t i (0); i != n; ++i) + if (m.name == "std" || m.name == "std.compat") { - module_import& m (imports[i]); + otype ot (otype::e); + const target* mt (nullptr); - if (m.name == "std" || m.name == "std.compat") + switch (ctype) { - otype ot (otype::e); - const target* mt (nullptr); - - switch (ctype) + case compiler_type::clang: { - case compiler_type::clang: - { - if (m.name != "std") - fail << "module " << m.name << " not yet provided by libc++"; + // @@ TODO: cache x_stdlib value. + // + if (cast<string> (rs[x_stdlib]) != "libc++") + fail << "standard library module '" << m.name << "' is " + << "currently only supported in libc++" << + info << "try adding -stdlib=libc++ as compiler mode option"; - // Find or insert std.cppm (similar code to pkgconfig.cxx). - // - // Note: build_install_data is absolute and normalized. - // - mt = &ctx.targets.insert_locked ( - *x_mod, - (dir_path (build_install_data) /= "libbuild2") /= "cc", - dir_path (), - "std", - string ("cppm"), // For C++14 during bootstrap. - target_decl::implied, - trace).first; - - // Which output type should we use, static or shared? The - // correct way would be to detect whether static or shared - // version of libc++ is to be linked and use the corresponding - // type. And we could do that by looking for -static-libstdc++ - // in loption (and no, it's not -static-libc++). - // - // But, looking at the object file produced from std.cppm, it - // only contains one symbol, the static object initializer. - // And this is unlikely to change since all other non-inline - // or template symbols should be in libc++. So feels like it's - // not worth the trouble and one variant should be good enough - // for both cases. Let's use the shared one for less - // surprising diagnostics (as in, "why are you linking obje{} - // to a shared library?") - // - // (Of course, theoretically, std.cppm could detect via a - // macro whether it's being compiled with -fPIC or not and do - // things differently, but this seems far-fetched). - // - ot = otype::s; + if (cmaj < 18) + fail << "standard library module '" << m.name << "' is " + << "only supported in Clang 18 or later"; - break; - } - case compiler_type::msvc: + // Find or insert std*.cppm (similar code to pkgconfig.cxx). + // + // Note: build_install_data is absolute and normalized. + // + mt = &ctx.targets.insert_locked ( + *x_mod, + (dir_path (build_install_data) /= "libbuild2") /= "cc", + dir_path (), + m.name, + string ("cppm"), // For C++14 during bootstrap. + target_decl::implied, + trace).first; + + // Which output type should we use, static or shared? The + // correct way would be to detect whether static or shared + // version of libc++ is to be linked and use the corresponding + // type. And we could do that by looking for -static-libstdc++ + // in loption (and no, it's not -static-libc++). + // + // But, looking at the object file produced from std*.cppm, they + // only contain one symbol, the static object initializer. And + // this is unlikely to change since all other non-inline or + // template symbols should be in libc++. So feels like it's not + // worth the trouble and one variant should be good enough for + // both cases. Let's use the shared one for less surprising + // diagnostics (as in, "why are you linking obje{} to a shared + // library?") + // + // (Of course, theoretically, std*.cppm could detect via a macro + // whether they are being compiled with -fPIC or not and do + // things differently, but this seems far-fetched). + // + ot = otype::s; + + break; + } + case compiler_type::msvc: + { + // For MSVC, the source files std.ixx and std.compat.ixx are + // found in the modules/ subdirectory which is a sibling of + // include/ in the MSVC toolset (and "that is a contract with + // customers" to quote one of the developers). + // + // The problem of course is that there are multiple system + // header search directories (for example, as specified in the + // INCLUDE environment variable) and which one of them is for + // the MSVC toolset is not specified. So what we are going to do + // is search for one of the well-known standard C++ headers and + // assume that the directory where we found it is the one we are + // looking for. Or we could look for something MSVC-specific + // like vcruntime.h. + // + dir_path modules; + if (optional<path> p = find_system_header (path ("vcruntime.h"))) { - // For MSVC, the source files std.ixx and std.compat.ixx are - // found in the modules/ subdirectory which is a sibling of - // include/ in the MSVC toolset (and "that is a contract with - // customers" to quote one of the developers). - // - // The problem of course is that there are multiple system - // header search directories (for example, as specified in the - // INCLUDE environment variable) and which one of them is for - // the MSVC toolset is not specified. So what we are going to - // do is search for one of the well-known standard C++ headers - // and assume that the directory where we found it is the one - // we are looking for. Or we could look for something - // MSVC-specific like vcruntime.h. - // - dir_path modules; - if (optional<path> p = find_system_header (path ("vcruntime.h"))) + p->make_directory (); // Strip vcruntime.h. + if (p->leaf () == path ("include")) // Sanity check. { - p->make_directory (); // Strip vcruntime.h. - if (p->leaf () == path ("include")) // Sanity check. - { - modules = path_cast<dir_path> (move (p->make_directory ())); - modules /= "modules"; - } + modules = path_cast<dir_path> (move (p->make_directory ())); + modules /= "modules"; } + } - if (modules.empty ()) - fail << "unable to locate MSVC standard modules directory"; - - mt = &ctx.targets.insert_locked ( - *x_mod, - move (modules), - dir_path (), - m.name, - string ("ixx"), // For C++14 during bootstrap. - target_decl::implied, - trace).first; + if (modules.empty ()) + fail << "unable to locate MSVC standard modules directory"; - // For MSVC it's easier to detect the runtime being used since - // it's specified with the compile options (/MT[d], /MD[d]). - // - // Similar semantics as in extract_headers() except here we - // use options visible from the root scope. Note that - // find_option_prefixes() looks in reverse, so look in the - // cmode, x_coptions, c_coptions order. - // - initializer_list<const char*> os {"/MD", "/MT", "-MD", "-MT"}; + mt = &ctx.targets.insert_locked ( + *x_mod, + move (modules), + dir_path (), + m.name, + string ("ixx"), // For C++14 during bootstrap. + target_decl::implied, + trace).first; - const string* o; - if ((o = find_option_prefixes (os, cmode)) != nullptr || - (o = find_option_prefixes (os, rs, x_coptions)) != nullptr || - (o = find_option_prefixes (os, rs, c_coptions)) != nullptr) - { - ot = (*o)[2] == 'D' ? otype::s : otype::a; - } - else - ot = otype::s; // The default is /MD. + // For MSVC it's easier to detect the runtime being used since + // it's specified with the compile options (/MT[d], /MD[d]). + // + // Similar semantics as in extract_headers() except here we use + // options visible from the root scope. Note that + // find_option_prefixes() looks in reverse, so look in the + // cmode, x_coptions, c_coptions order. + // + initializer_list<const char*> os {"/MD", "/MT", "-MD", "-MT"}; - break; + const string* o; + if ((o = find_option_prefixes (os, cmode)) != nullptr || + (o = find_option_prefixes (os, rs, x_coptions)) != nullptr || + (o = find_option_prefixes (os, rs, c_coptions)) != nullptr) + { + ot = (*o)[2] == 'D' ? otype::s : otype::a; } - case compiler_type::gcc: - case compiler_type::icc: - assert (false); - }; + else + ot = otype::s; // The default is /MD. + + break; + } + case compiler_type::gcc: + case compiler_type::icc: + { + fail << "standard library module '" << m.name << "' is " + << "not yet supported in this compiler"; + } + }; - pair<target&, ulock> tl ( - this->make_module_sidebuild ( // GCC 4.9 - a, bs, nullptr, ot, *mt, m.name)); + pair<target&, ulock> tl ( + this->make_module_sidebuild ( // GCC 4.9 + a, bs, nullptr, ot, *mt, m.name)); - if (tl.second.owns_lock ()) + if (tl.second.owns_lock ()) + { + // Special compile options for the std modules. + // + if (ctype == compiler_type::clang) { - // Special compile options for the std modules. - // - if (ctype == compiler_type::clang) - { - value& v (tl.first.append_locked (x_coptions)); + value& v (tl.first.append_locked (x_coptions)); - if (v.null) - v = strings {}; + if (v.null) + v = strings {}; - strings& cops (v.as<strings> ()); + strings& cops (v.as<strings> ()); - switch (ctype) + switch (ctype) + { + case compiler_type::clang: { - case compiler_type::clang: - { - cops.push_back ("-Wno-reserved-module-identifier"); - break; - } - case compiler_type::msvc: - // It appears nothing special is needed to compile MSVC - // standard modules. - case compiler_type::gcc: - case compiler_type::icc: - assert (false); - }; - } - - tl.second.unlock (); + cops.push_back ("-Wno-reserved-module-identifier"); + break; + } + case compiler_type::msvc: + // It appears nothing special is needed to compile MSVC + // standard modules. + case compiler_type::gcc: + case compiler_type::icc: + assert (false); + }; } - pts[start + i].target = &tl.first; - m.score = match_max (m.name) + 1; - continue; // Scan the rest to detect if all done. + tl.second.unlock (); } - done = false; + pts[start + i].target = &tl.first; + m.score = match_max (m.name) + 1; + continue; // Scan the rest to detect if all done. } + + done = false; } // Go over prerequisites and try to resolve imported modules with them. @@ -6672,6 +6677,15 @@ namespace build2 // string extra; + // @@ What happens if different projects used different standards? + // Specifically, how do we detect this and what can the user do + // about it? For the latter question, forcing the same standard + // with config.cxx.std seems like the only sensible option. For + // the former, we could read the value of cxx.std using our + // buildfile first-line peeking mechanism. But doing that for + // every module interface feels inefficient so we will probably + // need to cache it on the per-project basis. Maybe/later. + // if (const string* std = cast_null<string> (rs[x_std])) extra += string (x) + ".std = " + *std + '\n'; diff --git a/libbuild2/cc/predefs-rule.cxx b/libbuild2/cc/predefs-rule.cxx index e74192d..606db06 100644 --- a/libbuild2/cc/predefs-rule.cxx +++ b/libbuild2/cc/predefs-rule.cxx @@ -278,7 +278,7 @@ namespace build2 args.push_back ("/Zc:preprocessor"); // Preproc. conformance mode. // Output (note that while the /Fi: variant is only availbale - // starting with VS2013, /Zc:preprocessor is only available in + // starting with VS2013, /Zc:preprocessor is only available // starting from VS2019). // args.push_back ("/Fi:"); diff --git a/libbuild2/cc/std.compat.cppm b/libbuild2/cc/std.compat.cppm new file mode 100644 index 0000000..2668b30 --- /dev/null +++ b/libbuild2/cc/std.compat.cppm @@ -0,0 +1,996 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_libcxx_cppm_in.py +// DO NOT MODIFY! + +module; + +#include <__config> + +#if _LIBCPP_VERSION < 180000 +#error libc++ version 18.0.0 or later required +#endif + +// The headers of Table 24: C++ library headers [tab:headers.cpp] +// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] +#include <cassert> +#include <cctype> +#include <cerrno> +#include <cfenv> +#include <cfloat> +#include <cinttypes> +#include <climits> +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include <clocale> +#endif +#include <cmath> +#include <csetjmp> +#include <csignal> +#include <cstdarg> +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> +#include <cuchar> +#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) +# include <cwchar> +#endif +#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) +# include <cwctype> +#endif + +#if 0 +// *** Headers not yet available *** +#if __has_include(<debugging>) +# error "please update the header information for <debugging> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<debugging>) +#if __has_include(<flat_map>) +# error "please update the header information for <flat_map> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<flat_map>) +#if __has_include(<flat_set>) +# error "please update the header information for <flat_set> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<flat_set>) +#if __has_include(<generator>) +# error "please update the header information for <generator> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<generator>) +#if __has_include(<hazard_pointer>) +# error "please update the header information for <hazard_pointer> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<hazard_pointer>) +#if __has_include(<linalg>) +# error "please update the header information for <linalg> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<linalg>) +#if __has_include(<rcu>) +# error "please update the header information for <rcu> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<rcu>) +#if __has_include(<spanstream>) +# error "please update the header information for <spanstream> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<spanstream>) +#if __has_include(<stacktrace>) +# error "please update the header information for <stacktrace> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<stacktrace>) +#if __has_include(<stdfloat>) +# error "please update the header information for <stdfloat> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<stdfloat>) +#if __has_include(<text_encoding>) +# error "please update the header information for <text_encoding> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<text_encoding>) +#endif + +export module std.compat; +export import std; + +// cassert.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // This module exports nothing. +} // export + +// cctype.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::isalnum; + using ::isalpha; + using ::isblank; + using ::iscntrl; + using ::isdigit; + using ::isgraph; + using ::islower; + using ::isprint; + using ::ispunct; + using ::isspace; + using ::isupper; + using ::isxdigit; + using ::tolower; + using ::toupper; +} // export + +// cerrno.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // This module exports nothing. +} // export + +// cfenv.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // types + using ::fenv_t; + using ::fexcept_t; + + // functions + using ::feclearexcept; + using ::fegetexceptflag; + using ::feraiseexcept; + using ::fesetexceptflag; + using ::fetestexcept; + + using ::fegetround; + using ::fesetround; + + using ::fegetenv; + using ::feholdexcept; + using ::fesetenv; + using ::feupdateenv; +} // export + +// cfloat.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // This module exports nothing. +} // export + +// cinttypes.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::imaxdiv_t; + + using ::imaxabs; + using ::imaxdiv; + using ::strtoimax; + using ::strtoumax; + using ::wcstoimax; + using ::wcstoumax; + + // abs is conditionally here, but always present in cmath.cppm. To avoid + // conflicing declarations omit the using here. + + // div is conditionally here, but always present in cstdlib.cppm. To avoid + // conflicing declarations omit the using here. +} // export + +// climits.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // This module exports nothing. +} // export + +// clocale.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + using ::lconv; + + using ::localeconv; + using ::setlocale; +#endif // _LIBCPP_HAS_NO_LOCALIZATION +} // export + +// cmath.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::double_t; + using ::float_t; + + using ::acos; + using ::acosf; + using ::acosl; + + using ::asin; + using ::asinf; + using ::asinl; + + using ::atan; + using ::atanf; + using ::atanl; + + using ::atan2; + using ::atan2f; + using ::atan2l; + + using ::cos; + using ::cosf; + using ::cosl; + + using ::sin; + using ::sinf; + using ::sinl; + + using ::tan; + using ::tanf; + using ::tanl; + + using ::acosh; + using ::acoshf; + using ::acoshl; + + using ::asinh; + using ::asinhf; + using ::asinhl; + + using ::atanh; + using ::atanhf; + using ::atanhl; + + using ::cosh; + using ::coshf; + using ::coshl; + + using ::sinh; + using ::sinhf; + using ::sinhl; + + using ::tanh; + using ::tanhf; + using ::tanhl; + + using ::exp; + using ::expf; + using ::expl; + + using ::exp2; + using ::exp2f; + using ::exp2l; + + using ::expm1; + using ::expm1f; + using ::expm1l; + + using ::frexp; + using ::frexpf; + using ::frexpl; + + using ::ilogb; + using ::ilogbf; + using ::ilogbl; + + using ::ldexp; + using ::ldexpf; + using ::ldexpl; + + using ::log; + using ::logf; + using ::logl; + + using ::log10; + using ::log10f; + using ::log10l; + + using ::log1p; + using ::log1pf; + using ::log1pl; + + using ::log2; + using ::log2f; + using ::log2l; + + using ::logb; + using ::logbf; + using ::logbl; + + using ::modf; + using ::modff; + using ::modfl; + + using ::scalbn; + using ::scalbnf; + using ::scalbnl; + + using ::scalbln; + using ::scalblnf; + using ::scalblnl; + + using ::cbrt; + using ::cbrtf; + using ::cbrtl; + + // [c.math.abs], absolute values + using ::abs; + + using ::fabs; + using ::fabsf; + using ::fabsl; + + using ::hypot; + using ::hypotf; + using ::hypotl; + + // [c.math.hypot3], three-dimensional hypotenuse + + using ::pow; + using ::powf; + using ::powl; + + using ::sqrt; + using ::sqrtf; + using ::sqrtl; + + using ::erf; + using ::erff; + using ::erfl; + + using ::erfc; + using ::erfcf; + using ::erfcl; + + using ::lgamma; + using ::lgammaf; + using ::lgammal; + + using ::tgamma; + using ::tgammaf; + using ::tgammal; + + using ::ceil; + using ::ceilf; + using ::ceill; + + using ::floor; + using ::floorf; + using ::floorl; + + using ::nearbyint; + using ::nearbyintf; + using ::nearbyintl; + + using ::rint; + using ::rintf; + using ::rintl; + + using ::lrint; + using ::lrintf; + using ::lrintl; + + using ::llrint; + using ::llrintf; + using ::llrintl; + + using ::round; + using ::roundf; + using ::roundl; + + using ::lround; + using ::lroundf; + using ::lroundl; + + using ::llround; + using ::llroundf; + using ::llroundl; + + using ::trunc; + using ::truncf; + using ::truncl; + + using ::fmod; + using ::fmodf; + using ::fmodl; + + using ::remainder; + using ::remainderf; + using ::remainderl; + + using ::remquo; + using ::remquof; + using ::remquol; + + using ::copysign; + using ::copysignf; + using ::copysignl; + + using ::nan; + using ::nanf; + using ::nanl; + + using ::nextafter; + using ::nextafterf; + using ::nextafterl; + + using ::nexttoward; + using ::nexttowardf; + using ::nexttowardl; + + using ::fdim; + using ::fdimf; + using ::fdiml; + + using ::fmax; + using ::fmaxf; + using ::fmaxl; + + using ::fmin; + using ::fminf; + using ::fminl; + + using ::fma; + using ::fmaf; + using ::fmal; + + // [c.math.lerp], linear interpolation + // [support.c.headers.other]/1 + // ... placed within the global namespace scope, except for the functions + // described in [sf.cmath], the std::lerp function overloads ([c.math.lerp]) + // ... + + // [c.math.fpclass], classification / comparison functions + using ::fpclassify; + using ::isfinite; + using ::isgreater; + using ::isgreaterequal; + using ::isinf; + using ::isless; + using ::islessequal; + using ::islessgreater; + using ::isnan; + using ::isnormal; + using ::isunordered; + using ::signbit; + + // [sf.cmath], mathematical special functions +} // export + +// csetjmp.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::jmp_buf; + using ::longjmp; +} // export + +// csignal.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::sig_atomic_t; + + // [support.signal], signal handlers + using ::signal; + + using ::raise; +} // export + +// cstdarg.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { using ::va_list; } // export + +// cstddef.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::max_align_t; + using ::nullptr_t; + using ::ptrdiff_t; + using ::size_t; + + // [support.c.headers]/1 + // ... placed within the global namespace scope, except for ... the + // declaration of std::byte ([cstddef.syn]), and the functions and + // function templates described in [support.types.byteops]. ... + + // [support.types.byteops], byte type operations +} // export + +// cstdint.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // signed + using ::int8_t _LIBCPP_USING_IF_EXISTS; + using ::int16_t _LIBCPP_USING_IF_EXISTS; + using ::int32_t _LIBCPP_USING_IF_EXISTS; + using ::int64_t _LIBCPP_USING_IF_EXISTS; + + using ::int_fast16_t; + using ::int_fast32_t; + using ::int_fast64_t; + using ::int_fast8_t; + + using ::int_least16_t; + using ::int_least32_t; + using ::int_least64_t; + using ::int_least8_t; + + using ::intmax_t; + + using ::intptr_t _LIBCPP_USING_IF_EXISTS; + + // unsigned + using ::uint8_t _LIBCPP_USING_IF_EXISTS; + using ::uint16_t _LIBCPP_USING_IF_EXISTS; + using ::uint32_t _LIBCPP_USING_IF_EXISTS; + using ::uint64_t _LIBCPP_USING_IF_EXISTS; + + using ::uint_fast16_t; + using ::uint_fast32_t; + using ::uint_fast64_t; + using ::uint_fast8_t; + + using ::uint_least16_t; + using ::uint_least32_t; + using ::uint_least64_t; + using ::uint_least8_t; + + using ::uintmax_t; + + using ::uintptr_t _LIBCPP_USING_IF_EXISTS; +} // export + +// cstdio.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::FILE; + using ::fpos_t; + using ::size_t; + + using ::clearerr; + using ::fclose; + using ::feof; + using ::ferror; + using ::fflush; + using ::fgetc; + using ::fgetpos; + using ::fgets; + using ::fopen; + using ::fprintf; + using ::fputc; + using ::fputs; + using ::fread; + using ::freopen; + using ::fscanf; + using ::fseek; + using ::fsetpos; + using ::ftell; + using ::fwrite; + using ::getc; + using ::getchar; + using ::perror; + using ::printf; + using ::putc; + using ::putchar; + using ::puts; + using ::remove; + using ::rename; + using ::rewind; + using ::scanf; + using ::setbuf; + using ::setvbuf; + using ::snprintf; + using ::sprintf; + using ::sscanf; + using ::tmpfile; + using ::tmpnam; + using ::ungetc; + using ::vfprintf; + using ::vfscanf; + using ::vprintf; + using ::vscanf; + using ::vsnprintf; + using ::vsprintf; + using ::vsscanf; + +} // export + +// cstdlib.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::div_t; + using ::ldiv_t; + using ::lldiv_t; + using ::size_t; + + // [support.start.term], start and termination + using ::_Exit; + using ::abort; + using ::at_quick_exit _LIBCPP_USING_IF_EXISTS; + using ::atexit; + using ::exit; + using ::quick_exit _LIBCPP_USING_IF_EXISTS; + + using ::getenv; + using ::system; + + // [c.malloc], C library memory allocation + using ::aligned_alloc _LIBCPP_USING_IF_EXISTS; + using ::calloc; + using ::free; + using ::malloc; + using ::realloc; + + using ::atof; + using ::atoi; + using ::atol; + using ::atoll; + using ::strtod; + using ::strtof; + using ::strtol; + using ::strtold; + using ::strtoll; + using ::strtoul; + using ::strtoull; + + // [c.mb.wcs], multibyte / wide string and character conversion functions + using ::mblen; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + using ::mbstowcs; + using ::mbtowc; + using ::wcstombs; + using ::wctomb; +#endif + // [alg.c.library], C standard library algorithms + using ::bsearch; + using ::qsort; + + // [c.math.rand], low-quality random number generation + using ::rand; + using ::srand; + + // [c.math.abs], absolute values + using ::abs; + + using ::labs; + using ::llabs; + + using ::div; + using ::ldiv; + using ::lldiv; + +} // export + +// cstring.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::size_t; + + using ::memchr; + using ::memcmp; + using ::memcpy; + using ::memmove; + using ::memset; + using ::strcat; + using ::strchr; + using ::strcmp; + using ::strcoll; + using ::strcpy; + using ::strcspn; + using ::strerror; + using ::strlen; + using ::strncat; + using ::strncmp; + using ::strncpy; + using ::strpbrk; + using ::strrchr; + using ::strspn; + using ::strstr; + using ::strtok; + using ::strxfrm; + +} // export + +// ctime.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + using ::clock_t; + using ::size_t; + using ::time_t; + + using ::timespec; + using ::tm; + + using ::asctime; + using ::clock; + using ::ctime; + using ::difftime; + using ::gmtime; + using ::localtime; + using ::mktime; + using ::strftime; + using ::time; + using ::timespec_get _LIBCPP_USING_IF_EXISTS; +} // export + +// cuchar.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { + // Note the Standard does not mark these symbols optional, but libc++'s header + // does. So this seems strictly not to be conforming. + + // mbstate_t is conditionally here, but always present in cwchar.cppm. To avoid + // conflicing declarations omit the using here. + + // size_t is conditionally here, but always present in cstddef.cppm. To avoid + // conflicing declarations omit the using here. + +#if !defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8) + using ::mbrtoc8 _LIBCPP_USING_IF_EXISTS; + using ::c8rtomb _LIBCPP_USING_IF_EXISTS; +#endif + using ::mbrtoc16 _LIBCPP_USING_IF_EXISTS; + using ::c16rtomb _LIBCPP_USING_IF_EXISTS; + using ::mbrtoc32 _LIBCPP_USING_IF_EXISTS; + using ::c32rtomb _LIBCPP_USING_IF_EXISTS; +} // export + +// cwchar.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + using ::mbstate_t; + using ::size_t; + using ::wint_t; + + using ::tm; + + using ::btowc; + using ::fgetwc; + using ::fgetws; + using ::fputwc; + using ::fputws; + using ::fwide; + using ::fwprintf; + using ::fwscanf; + using ::getwc; + using ::getwchar; + using ::putwc; + using ::putwchar; + using ::swprintf; + using ::swscanf; + using ::ungetwc; + using ::vfwprintf; + using ::vfwscanf; + using ::vswprintf; + using ::vswscanf; + using ::vwprintf; + using ::vwscanf; + using ::wcscat; + using ::wcschr; + using ::wcscmp; + using ::wcscoll; + using ::wcscpy; + using ::wcscspn; + using ::wcsftime; + using ::wcslen; + using ::wcsncat; + using ::wcsncmp; + using ::wcsncpy; + using ::wcspbrk; + using ::wcsrchr; + using ::wcsspn; + using ::wcsstr; + using ::wcstod; + using ::wcstof; + using ::wcstok; + using ::wcstol; + using ::wcstold; + using ::wcstoll; + using ::wcstoul; + using ::wcstoull; + using ::wcsxfrm; + using ::wctob; + using ::wmemchr; + using ::wmemcmp; + using ::wmemcpy; + using ::wmemmove; + using ::wmemset; + using ::wprintf; + using ::wscanf; + + // [c.mb.wcs], multibyte / wide string and character conversion functions + using ::mbrlen; + using ::mbrtowc; + using ::mbsinit; + using ::mbsrtowcs; + using ::wcrtomb; + using ::wcsrtombs; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +} // export + +// cwctype.inc +// -*- 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 +// +//===----------------------------------------------------------------------===// + +export { +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + using ::wctrans_t; + using ::wctype_t; + using ::wint_t; + + using ::iswalnum; + using ::iswalpha; + using ::iswblank; + using ::iswcntrl; + using ::iswctype; + using ::iswdigit; + using ::iswgraph; + using ::iswlower; + using ::iswprint; + using ::iswpunct; + using ::iswspace; + using ::iswupper; + using ::iswxdigit; + using ::towctrans; + using ::towlower; + using ::towupper; + using ::wctrans; + using ::wctype; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +} // export diff --git a/libbuild2/cc/std.cppm b/libbuild2/cc/std.cppm index 5368d1c..575e6a4 100644 --- a/libbuild2/cc/std.cppm +++ b/libbuild2/cc/std.cppm @@ -8,15 +8,15 @@ //===----------------------------------------------------------------------===// // WARNING, this entire header is generated by -// utils/generate_std_cppm_in.py +// utils/generate_libcxx_cppm_in.py // DO NOT MODIFY! module; #include <__config> -#if _LIBCPP_VERSION < 170000 -#error libc++ version 17.0.0 or later required +#if _LIBCPP_VERSION < 180000 +#error libc++ version 18.0.0 or later required #endif // The headers of Table 24: C++ library headers [tab:headers.cpp] @@ -153,11 +153,8 @@ module; # include <strstream> #endif #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -#if __has_include(<syncstream>) -# define _LIPCPP_HAS_YES_SYNCSTREAM # include <syncstream> #endif -#endif #include <system_error> #if !defined(_LIBCPP_HAS_NO_THREADS) # include <thread> @@ -177,38 +174,38 @@ module; #if 0 // *** Headers not yet available *** #if __has_include(<debugging>) -# error "update the header information for <debugging> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<debugging>) +# error "please update the header information for <debugging> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<debugging>) #if __has_include(<flat_map>) -# error "update the header information for <flat_map> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<flat_map>) +# error "please update the header information for <flat_map> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<flat_map>) #if __has_include(<flat_set>) -# error "update the header information for <flat_set> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<flat_set>) +# error "please update the header information for <flat_set> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<flat_set>) #if __has_include(<generator>) -# error "update the header information for <generator> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<generator>) +# error "please update the header information for <generator> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<generator>) #if __has_include(<hazard_pointer>) -# error "update the header information for <hazard_pointer> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<hazard_pointer>) +# error "please update the header information for <hazard_pointer> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<hazard_pointer>) #if __has_include(<linalg>) -# error "update the header information for <linalg> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<linalg>) +# error "please update the header information for <linalg> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<linalg>) #if __has_include(<rcu>) -# error "update the header information for <rcu> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<rcu>) +# error "please update the header information for <rcu> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<rcu>) #if __has_include(<spanstream>) -# error "update the header information for <spanstream> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<spanstream>) +# error "please update the header information for <spanstream> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<spanstream>) #if __has_include(<stacktrace>) -# error "update the header information for <stacktrace> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<stacktrace>) +# error "please update the header information for <stacktrace> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<stacktrace>) #if __has_include(<stdfloat>) -# error "update the header information for <stdfloat> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<stdfloat>) +# error "please update the header information for <stdfloat> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<stdfloat>) #if __has_include(<text_encoding>) -# error "update the header information for <text_encoding> in libcxx/utils/generate_std_cppm_in.py" -#endif // __has_include(<text_encoding>) +# error "please update the header information for <text_encoding> in headers_not_available in utils/libcxx/header_information.py" +#endif // __has_include(<text_encoding>) #endif export module std; @@ -232,7 +229,9 @@ export namespace std { using std::ranges::in_in_result; using std::ranges::in_out_out_result; using std::ranges::in_out_result; - // using std::ranges::in_value_result; +#if _LIBCPP_STD_VER >= 23 + using std::ranges::in_value_result; +#endif using std::ranges::min_max_result; // using std::ranges::out_value_result; } // namespace ranges @@ -256,13 +255,15 @@ export namespace std { using std::ranges::none_of; } +#if _LIBCPP_STD_VER >= 23 // [alg.contains], contains -#if 0 namespace ranges { using std::ranges::contains; +#if 0 using std::ranges::contains_subrange; - } // namespace ranges #endif + } // namespace ranges +#endif // _LIBCPP_STD_VER >= 23 // [alg.foreach], for each using std::for_each; @@ -370,20 +371,18 @@ export namespace std { // [alg.starts.with], starts with using std::ranges::starts_with; -#if _LIBCPP_VERSION >= 180000 // [alg.ends.with], ends with using std::ranges::ends_with; -#endif -# if 0 // [alg.fold], fold using std::ranges::fold_left; + using std::ranges::fold_left_with_iter; + using std::ranges::fold_left_with_iter_result; +# if 0 using std::ranges::fold_left_first; using std::ranges::fold_right; using std::ranges::fold_right_last; using std::ranges::fold_left_with_iter; - using std::ranges::fold_left_with_iter_result; - using std::ranges::fold_left_with_iter; using std::ranges::fold_left_first_with_iter; using std::ranges::fold_left_first_with_iter; # endif @@ -955,7 +954,9 @@ export namespace std { using std::atomic_char; using std::atomic_char16_t; using std::atomic_char32_t; +#ifndef _LIBCPP_HAS_NO_CHAR8_T using std::atomic_char8_t; +#endif using std::atomic_int; using std::atomic_llong; using std::atomic_long; @@ -1993,11 +1994,13 @@ export namespace std { export namespace std { #ifndef _LIBCPP_HAS_NO_LOCALIZATION +# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT) using std::codecvt_mode; using std::codecvt_utf16; using std::codecvt_utf8; using std::codecvt_utf8_utf16; +# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT) #endif // _LIBCPP_HAS_NO_LOCALIZATION } // namespace std @@ -2617,7 +2620,7 @@ export namespace std { using std::mktime; using std::strftime; using std::time; - using std::timespec_get; + using std::timespec_get _LIBCPP_USING_IF_EXISTS; } // namespace std // cuchar.inc @@ -3108,6 +3111,9 @@ export namespace std { #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using std::wformat_string; #endif +#if _LIBCPP_STD_VER >= 26 + using std::runtime_format; +#endif //_LIBCPP_STD_VER >= 26 // [format.functions], formatting functions using std::format; @@ -3590,9 +3596,11 @@ export namespace std { #endif using std::u16streampos; using std::u32streampos; +#ifndef _LIBCPP_HAS_NO_CHAR8_T using std::u8streampos; +#endif -#ifdef _LIBCPP_HAS_YES_SYNCSTREAM +#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM using std::basic_osyncstream; using std::basic_syncbuf; #endif @@ -3600,13 +3608,11 @@ export namespace std { using std::istreambuf_iterator; using std::ostreambuf_iterator; -#ifdef _LIBCPP_HAS_YES_SYNCSTREAM +#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM using std::osyncstream; using std::syncbuf; -#endif #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -#ifdef _LIBCPP_HAS_YES_SYNCSTREAM using std::wosyncstream; using std::wsyncbuf; #endif @@ -4112,9 +4118,7 @@ export namespace std { // [mdspan.layout], layout mapping using std::layout_left; using std::layout_right; -#if _LIBCPP_VERSION >= 180000 using std::layout_stride; -#endif // [mdspan.accessor.default], class template default_accessor using std::default_accessor; @@ -4171,7 +4175,9 @@ export namespace std { #if _LIBCPP_STD_VER >= 23 using std::allocation_result; - using std::allocate_at_least; + // Note: no longer in Clang 19. + // + //using std::allocate_at_least; #endif // [default.allocator], the default allocator @@ -4283,7 +4289,9 @@ export namespace std { using std::reinterpret_pointer_cast; using std::static_pointer_cast; +#ifndef _LIBCPP_HAS_NO_RTTI using std::get_deleter; +#endif // _LIBCPP_HAS_NO_RTTI // [util.smartptr.shared.io], shared_ptr I/O @@ -4555,6 +4563,16 @@ export namespace std { // [numeric.ops.midpoint], midpoint using std::midpoint; + +#if _LIBCPP_STD_VER >= 26 + // [numeric.sat], saturation arithmetic + using std::add_sat; + using std::div_sat; + using std::mul_sat; + using std::saturate_cast; + using std::sub_sat; +#endif + } // namespace std // optional.inc @@ -4626,14 +4644,17 @@ export namespace std { # endif using std::operator<<; -# if 0 +# if _LIBCPP_STD_VER >= 23 // [ostream.formatted.print], print functions using std::print; using std::println; using std::vprint_nonunicode; +# ifndef _LIBCPP_HAS_NO_UNICODE using std::vprint_unicode; -# endif +# endif // _LIBCPP_HAS_NO_UNICODE +# endif // _LIBCPP_STD_VER >= 23 + #endif // _LIBCPP_HAS_NO_LOCALIZATION } // namespace std @@ -5013,13 +5034,11 @@ export namespace std { using std::ranges::views::drop_while; } // namespace views -#ifdef _LIBCPP_ENABLE_EXPERIMENTAL using std::ranges::join_view; namespace views { using std::ranges::views::join; } // namespace views -#endif // _LIBCPP_ENABLE_EXPERIMENTAL #if 0 using std::ranges::join_with_view; @@ -5123,14 +5142,12 @@ export namespace std { #endif #if _LIBCPP_STD_VER >= 23 -#if _LIBCPP_VERSION >= 180000 // [range.chunk.by], chunk by view using std::ranges::chunk_by_view; namespace views { using std::ranges::views::chunk_by; } -#endif #endif // _LIBCPP_STD_VER >= 23 #if 0 @@ -5783,7 +5800,9 @@ export namespace std { using std::string; using std::u16string; using std::u32string; +#ifndef _LIBCPP_HAS_NO_CHAR8_T using std::u8string; +#endif #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using std::wstring; #endif @@ -5807,7 +5826,9 @@ export namespace std { using std::pmr::string; using std::pmr::u16string; using std::pmr::u32string; +#ifndef _LIBCPP_HAS_NO_CHAR8_T using std::pmr::u8string; +#endif #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using std::pmr::wstring; #endif @@ -5816,17 +5837,12 @@ export namespace std { // [basic.string.hash], hash support using std::hash; - // TODO MODULES is this a bug? -#if _LIBCPP_STD_VER >= 23 - using std::operator""s; -#else inline namespace literals { inline namespace string_literals { // [basic.string.literals], suffix for basic_string literals using std::literals::string_literals::operator""s; } // namespace string_literals - } // namespace literals -#endif + } // namespace literals } // namespace std // string_view.inc @@ -5859,7 +5875,9 @@ export namespace std { using std::string_view; using std::u16string_view; using std::u32string_view; +#ifndef _LIBCPP_HAS_NO_CHAR8_T using std::u8string_view; +#endif #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using std::wstring_view; #endif @@ -5904,8 +5922,6 @@ export namespace std { // //===----------------------------------------------------------------------===// -#ifdef _LIBCPP_HAS_YES_SYNCSTREAM - export namespace std { #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM) using std::basic_syncbuf; @@ -5926,8 +5942,6 @@ export namespace std { #endif // !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM) } // namespace std -#endif - // system_error.inc // -*- C++ -*- //===----------------------------------------------------------------------===// diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx index 8159d18..3185eaa 100644 --- a/libbuild2/cxx/init.cxx +++ b/libbuild2/cxx/init.cxx @@ -335,7 +335,12 @@ namespace build2 { case compiler_type::gcc: { - if (mj >= 11) + if (mj >= 14) + { + o = "-std=c++26"; + cplusplus = 202400; + } + else if (mj >= 11) { o = "-std=c++23"; cplusplus = 202302; @@ -367,25 +372,29 @@ namespace build2 } case compiler_type::clang: { - // Clang 10.0.0 targeting MSVC 16.4 and 16.5 (preview) in the - // c++2a mode uncovers some Concepts-related bugs in MSVC STL - // (LLVM bug #44956). So in this case we map `latest` to - // c++17. - // - // While reportedly this has been fixed in the later versions - // of MSVC, instead of somehow passing the version of MSVC - // Clang is targeting, we will just assume that Clang 11 - // and later are used with a sufficiently new version of - // MSVC. - // - - if (mj >= 13) + if (mj >= 18) + { + o = "-std=c++26"; + cplusplus = 202400; + } + else if (mj >= 13) { o = "-std=c++2b"; cplusplus = 202302; } else if (mj == 10 && latest && tt.system == "win32-msvc") { + // Clang 10.0.0 targeting MSVC 16.4 and 16.5 (preview) in + // the c++2a mode uncovers some Concepts-related bugs in + // MSVC STL (LLVM bug #44956). So in this case we map + // `latest` to c++17. + // + // While reportedly this has been fixed in the later + // versions of MSVC, instead of somehow passing the version + // of MSVC Clang is targeting, we will just assume that + // Clang 11 and later are used with a sufficiently new + // version of MSVC. + // o = "-std=c++17"; cplusplus = 201703; } @@ -446,7 +455,7 @@ namespace build2 // 26 to 2c for compatibility with older versions of the // compilers. // - // @@ TMP: update C++26 __cplusplus value once known. + // @@ TMP: update C++26 __cplusplus value once known (and above). // o = "-std="; @@ -481,6 +490,12 @@ namespace build2 { case compiler_type::msvc: { + // Let's enable the new preprocessor in this mode. For background, + // see MSVC issue 10537317. + // + if (mj > 19 || (mj == 19 && mi >= 39)) + prepend ("/Zc:preprocessor"); + // Starting with 15.5 (19.12) Visual Studio-created projects // default to the strict mode. However, this flag currently tends // to trigger too many compiler bugs. So for now we leave it to @@ -498,8 +513,8 @@ namespace build2 // Unless disabled by the user, try to enable C++ modules. // - // NOTE: see also diagnostics about modules support required in compile - // rule. + // NOTE: see also diagnostics about modules support required (if + // attempting to use) in compile rule. // if (!modules.value || *modules.value) { @@ -580,7 +595,7 @@ namespace build2 // around Clang 16 so we don't support anything earlier than // that (it's not practically usable anyway). // - // Clang enable modules by default in c++20 or later but they + // Clang enables modules by default in c++20 or later but they // don't yet (as of Clang 18) define __cpp_modules. When they // do, we can consider enabling modules by default on our side. // For now, we only enable modules if forced with explicit diff --git a/libbuild2/diagnostics.cxx b/libbuild2/diagnostics.cxx index 4a46756..c795e44 100644 --- a/libbuild2/diagnostics.cxx +++ b/libbuild2/diagnostics.cxx @@ -55,31 +55,31 @@ namespace build2 if (st) { - // @@ TMP: eventually we want to enable on Windows by default. + // Only attempt to enable if explicitly requested by the user. Note that + // while we may enable color for our process, who knows if this gets + // inherited by other processes we start (e.g., compilers) and/or + // whether they will do something sensible about any of this. // -#ifdef _WIN32 - if (c && *c) + try { -#endif - stderr_term_color = fdterm_color (stderr_fd (), !c || *c /* enable */); + stderr_term_color = fdterm_color (stderr_fd (), c && *c /* enable */); + } + catch (const io_error& e) + { + fail << "unable to query terminal color support for stderr: " << e; + } - // If the user specified --diag-color on POSIX we will trust the color - // is supported (e.g., wrong TERM value, etc). - // - if (!stderr_term_color && c && *c) - { + // If the user specified --diag-color on POSIX we will trust the color + // is supported (e.g., wrong TERM value, etc). + // + if (!stderr_term_color && c && *c) + { #ifdef _WIN32 - fail << "unable to enable diagnostics color support for stderr"; + fail << "unable to enable diagnostics color support for stderr"; #else - stderr_term_color = true; + stderr_term_color = true; #endif - } - -#ifdef _WIN32 } - else - stderr_term_color = false; -#endif } else stderr_term_color = false; diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index cd88eac..cfc90cf 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -156,7 +156,7 @@ namespace build2 { const path& n (e.path ()); - if (n.string ()[0] != '.') + if (!n.empty () && n.string ().front () != '.') try { if (e.type () == entry_type::directory) // Can throw. diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index c0957ad..18147a2 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -859,6 +859,13 @@ namespace build2 for (const dir_entry& de: dir_iterator (d, dir_iterator::detect_dangling)) { + const path& n (de.path ()); + + // Skip hidden entries. + // + if (n.empty () || n.string ().front () == '.') + continue; + if (de.type () != entry_type::directory) { if (de.type () == entry_type::unknown) @@ -867,13 +874,13 @@ namespace build2 warn << "skipping " << (sl ? "dangling symlink" : "inaccessible entry") << ' ' - << d / de.path (); + << d / n; } continue; } - dir_path sd (d / path_cast<dir_path> (de.path ())); + dir_path sd (d / path_cast<dir_path> (n)); bool src (false); optional<bool> altn; diff --git a/libbuild2/scheduler.cxx b/libbuild2/scheduler.cxx index e3fbcc1..69673e6 100644 --- a/libbuild2/scheduler.cxx +++ b/libbuild2/scheduler.cxx @@ -97,6 +97,10 @@ namespace build2 { // Note: assume non-serial execution. + // Note: increment progress before/after every wait. + // + progress_.fetch_add (1, memory_order_relaxed); + lock l (move (rl)); // Make sure unlocked on exception. active_--; @@ -135,6 +139,10 @@ namespace build2 { // Note: assume non-serial execution. + // Note: increment progress before/after every wait. + // + progress_.fetch_add (1, memory_order_relaxed); + lock l (mutex_); if (collision) @@ -1053,7 +1061,9 @@ namespace build2 // Re-check active/external counts for good measure (in case we were // spinning too fast). // - if (np == op && s.active_ == 0 && s.external_ == 0 && !s.shutdown_) + if (np == op && + s.active_ == 0 && s.external_ == 0 && !s.shutdown_ && + s.progress_.load (memory_order_consume) == op) { // Shutting things down cleanly is tricky: we could have handled it // in the scheduler (e.g., by setting a flag and then waking |