This patch implements the forwarding to frozen C++03 headers as
discussed in
https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc. In the
RFC, we initially proposed selecting the right headers from the Clang
driver, however consensus seemed to steer towards handling this in the
library itself. This patch implements that direction.
At a high level, the changes basically amount to making each public
header look like this:
```
// inside <vector>
#ifdef _LIBCPP_CXX03_LANG
# include <__cxx03/vector>
#else
// normal <vector> content
#endif
```
In most cases, public headers are simple umbrella headers so there isn't
much code in the #else branch. In other cases, the #else branch contains
the actual implementation of the header.
Currently, the library-internal feature test macros are only defined if
the feature is not available, and always have the prefix
`_LIBCPP_HAS_NO_`. This patch changes that, so that they are always
defined and have the prefix `_LIBCPP_HAS_` instead. This changes the
canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means
that using an undefined macro (e.g. due to a missing include) is
diagnosed now. While this is rather unlikely currently, a similar change
in `<__configuration/availability.h>` caught a few bugs. This also
improves readability, since it removes the double-negation of `#ifndef
_LIBCPP_HAS_NO_FEATURE`.
The current patch only touches the macros defined in `<__config>`. If
people are happy with this approach, I'll make a follow-up PR to also
change the macros defined in `<__config_site>`.
This is a small fix to https://github.com/llvm/llvm-project/pull/89305.
In the `__init` function of `_FillHelper`, `__fill_val_` was left
uninitialized. This worked for the implementation in the PR because we
always checked `__set_` before trying to read it, and would initialize
if it was unset.
However it turns out in earlier versions of the header (at least on AIX
which followed this path), we do a read of `__fill_val_` even if
`__set_` was false before initializing, to check if it matched the
sentinel value, so this causes undesired behaviour and UB.
This adds addressof at the required places in [input.output]. Some of
the new tests failed since string used operator& internally. These have
been fixed too.
Note the new fstream tests perform output to a basic_string instead of a
double. Using a double requires num_get specialization
num_get<CharT, istreambuf_iterator<CharT,
char_traits_operator_hijacker<CharT>>
This facet is not present in the locale database so the conversion would
fail due to a missing locale facet. Using basic_string avoids using the
locale.
As a drive-by fixes several bugs in the ofstream.cons tests. These
tested ifstream instead of ofstream with an open mode.
Implements:
- LWG3130 [input.output] needs many addressof
Closes#100246.
`libcxx std::basic_ios` uses `WEOF` to indicate the `fill` value is
uninitialized. On some platforms (e.g AIX and zOS in 64-bit mode)
`wchar_t` is 4 bytes `unsigned` and `wint_t` is also 4 bytes which means
`WEOF` cannot be distinguished from `WCHAR_MAX` by
`std::char_traits<wchar_t>::eq_int_type()`, meaning this valid character
value cannot be stored on affected platforms (as the implementation
triggers reinitialization to `widen(’ ’)`).
This patch introduces a new helper class `_FillHelper` uses a boolean
variable to indicate whether the fill character has been initialized,
which is used by default in libcxx ABI version 2. The patch does not
affect ABI version 1 except for targets AIX in 32- and 64-bit and z/OS
in 64-bit (so that the layout of the implementation is compatible with
the current IBM system provided libc++)
This is a continuation of Phabricator patch
[D124555](https://reviews.llvm.org/D124555). This patch uses a modified
version of the [approach](https://reviews.llvm.org/D124555#3566746)
suggested by @ldionne .
---------
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Co-authored-by: David Tenty <daltenty.dev@gmail.com>
Previously, we would issue an #error when using a header that requires
threading support or localization support in a configuration where that
is disabled. This is unlike what we do for all the other carve outs like
no-filesystem, no-wide-characters or no-random-device. Instead of
issuing an #error, we normally just remove the problematic parts of the
header.
This patch makes the handling of no-localization and no-threads
consistent with the other carve-outs. I dislike the fact that users
won't get an explicit error message when trying to use e.g. ios in a
build that doesn't support localization, but I think it is better to
handle things consistently. Note that besides the consistency argument,
the #error approach doesn't really work anyways since it would break
down if we moved towards assuming the C locale only in the
no-localization mode.
These were required a long time ago due to `static_assert` not actually
being available in C++03. Now `static_assert` is simply mapped to
`_Static_assert` in C++03, making the additional parens unnecessary.
Destroying an ios_base object before it is properly initialized is
undefined behavior. Unlike typical C++ classes the initialization is not
done in the constructor, but in a dedicated init function. Due to
virtual inheritance of the basic_ios object in ostream and friends this
undefined behaviour can be triggered when inheriting from classes that
can throw in their constructor and inheriting from ostream.
Use the __loc_ member of ios_base as sentinel to detect whether the
object has or has not been initialized.
Addresses https://github.com/llvm/llvm-project/issues/57964
Originally, we used __libcpp_verbose_abort to handle assertion failures.
That function was declared from all public headers. Since we don't use
that mechanism anymore, we don't need to declare __libcpp_verbose_abort
from all public headers, and we can clean up a lot of unnecessary
includes.
This patch also moves the definition of the various assertion categories
to the <__assert> header, since we now rely on regular IWYU for these
assertion macros.
rdar://105510916
We recently noticed that the unwrap_iter.h file was pushing macros, but
it was pushing them again instead of popping them at the end of the
file. This led to libc++ basically swallowing any custom definition of
these macros in user code:
#define min HELLO
#include <algorithm>
// min is not HELLO anymore, it's not defined
While investigating this issue, I noticed that our push/pop pragmas were
actually entirely wrong too. Indeed, instead of pushing macros like
`move`, we'd push `move(int, int)` in the pragma, which is not a valid
macro name. As a result, we would not actually push macros like `move`
-- instead we'd simply undefine them. This led to the following code not
working:
#define move HELLO
#include <algorithm>
// move is not HELLO anymore
Fixing the pragma push/pop incantations led to a cascade of issues
because we use identifiers like `move` in a large number of places, and
all of these headers would now need to do the push/pop dance.
This patch fixes all these issues. First, it adds a check that we don't
swallow important names like min, max, move or refresh as explained
above. This is done by augmenting the existing
system_reserved_names.gen.py test to also check that the macros are what
we expect after including each header.
Second, it fixes the push/pop pragmas to work properly and adds missing
pragmas to all the files I could detect a failure in via the newly added
test.
rdar://121365472
This patch runs clang-format on all of libcxx/include and libcxx/src, in
accordance with the RFC discussed at [1]. Follow-up patches will format
the benchmarks, the test suite and remaining parts of the code. I'm
splitting this one into its own patch so the diff is a bit easier to
review.
This patch was generated with:
find libcxx/include libcxx/src -type f \
| grep -v 'module.modulemap.in' \
| grep -v 'CMakeLists.txt' \
| grep -v 'README.txt' \
| grep -v 'libcxx.imp' \
| grep -v '__config_site.in' \
| xargs clang-format -i
A Git merge driver is available in libcxx/utils/clang-format-merge-driver.sh
to help resolve merge and rebase issues across these formatting changes.
[1]: https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
In preparation for running clang-format on the whole code base, we are
also removing mentions of the legacy _LIBCPP_INLINE_VISIBILITY macro in
favor of the newer _LIBCPP_HIDE_FROM_ABI.
We're still leaving the definition of _LIBCPP_INLINE_VISIBILITY to avoid
creating needless breakage in case some older patches are checked-in
with mentions of the old macro. After we branch for LLVM 18, we can do
another pass to clean up remaining uses of the macro that might have
gotten introduced by mistake (if any) and remove the macro itself at the
same time. This is just a minor convenience to smooth out the transition
as much as possible.
See
https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
for the clang-format proposal.
This patch brings std::ios_base::noreplace from P2467R1 to libc++.
This requires compiling the shared library in C++23 mode since otherwise
fstream::open(...) doesn't know about the new flag.
Differential Revision: https://reviews.llvm.org/D137640
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This allows including once_flag directly from <__locale> instead of
depending on all of <mutex>, which requires threading. In turn, this
makes it easier to support locales on platforms without threading.
Drive-by change: clang-format once_flag.h and use _LIBCPP_HIDE_FROM_ABI
Differential Revision: https://reviews.llvm.org/D155487
These macros are always defined identically, so we can simplify the code a bit by merging them.
Reviewed By: ldionne, #libc
Spies: libcxx-commits, krytarowski, smeenai
Differential Revision: https://reviews.llvm.org/D152652
To make sure all member functions that require it are marked `_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION` I compared the output of `objdump --syms lib/libc++.1.0.dylib` before and after, ignoring addresses.
Reviewed By: #libc, ldionne
Spies: Mordante, libcxx-commits, ldionne, arichardson, mstorsjo
Differential Revision: https://reviews.llvm.org/D150896
`basic_ios` is defined in `<ios>`, so it seems weird that we declare the explicit instantiation for it i `<streambuf>`, which is technically unrelated.
Reviewed By: #libc, EricWF, ldionne
Spies: ldionne, EricWF, libcxx-commits
Differential Revision: https://reviews.llvm.org/D150912
The module validation script of D144994 validate whether the contents of
an include match its module. An include is the set of files matching the
pattern:
- foo
- foo/*.
- __fwd/foo.h
Several declarations of the stream headers are in the header iosfwd.
This gives issue using the validation script. Adding iosfwd to the set
of matching files gives too many declarations. For example when
validating the fstream header it will pull in declarations of the
istream header. Instead if writing a set of filters the headers are
granularized into smaller headers containing the expected declarations.
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D148927
We already have a clang-tidy check for making sure that `_LIBCPP_HIDE_FROM_ABI` is on free functions. This patch extends this to class members. The places where we don't check for `_LIBCPP_HIDE_FROM_ABI` are classes for which we have an instantiation in the library.
Reviewed By: ldionne, Mordante, #libc
Spies: jplehr, mikhail.ramalho, sstefan1, libcxx-commits, krytarowski, miyuki, smeenai
Differential Revision: https://reviews.llvm.org/D142332
This results in proper error messages instead of just an abort.
Reviewed By: ldionne, Mordante, #libc
Spies: #libc_vendors, smeenai, libcxx-commits
Differential Revision: https://reviews.llvm.org/D141222
Other macros that disable parts of the library are named `_LIBCPP_HAS_NO_WHATEVER`.
Reviewed By: ldionne, Mordante, #libc
Spies: libcxx-commits, smeenai
Differential Revision: https://reviews.llvm.org/D143163
We should not surface CMake-level options like LIBCXX_ENABLE_FILESYSTEM
to our users, since they don't know what it means. Instead, use a slightly
more general wording.
Also, add an error in <ios> to improve the quality of errors for people
trying to use <iostream> when localization is disabled.
Differential Revision: https://reviews.llvm.org/D125910
This patch changes the requirement for getting the declaration of the
assertion handler from including <__assert> to including any public
C++ header of the library. Note that C compatibility headers are
excluded because we don't implement all the C headers ourselves --
some of them are taken straight from the C library, like assert.h.
It also adds a generated test to check it. Furthermore, this new
generated test is designed in a way that will make it possible to
replace almost all the existing test-generation scripts with this
system in upcoming patches.
Differential Revision: https://reviews.llvm.org/D122506
`basic_ios` delays initialization of `__fill_` to `widen(' ')` until `fill()` is called. But, `fill(char_type)` is missing this logic, so the fill character does not get initialized to whitespace if `fill(char_type)` is called first. This patch adds this logic to `fill(char_type)`.
Reviewed By: #libc, ldionne, Quuxplusone
Differential Revision: https://reviews.llvm.org/D120751
All supported compilers have implemented this feature.
Therefore use the language version instead of the feature macro.
Reviewed By: #libc, philnik, ldionne, Quuxplusone
Differential Revision: https://reviews.llvm.org/D119865
For some reason `<string>` defines `std::fpos`, which should be defined in `<ios>`.
Reviewed By: Quuxplusone, Mordante, #libc
Spies: libcxx-commits, mgorny
Differential Revision: https://reviews.llvm.org/D118914
Some headers which require the version header depend on other headers to
provide it. Include the version header in all top-level headers to make
sure a header cleanup can't remove the version header.
Note this doesn't add the version header to the c headers.
Reviewed By: #libc, Quuxplusone, ldionne
Differential Revision: https://reviews.llvm.org/D116172
Use `= delete` for member functions that are marked with `// = delete;`
Reviewed By: ldionne, Quuxplusone, #libc
Spies: jloser, libcxx-commits
Differential Revision: https://reviews.llvm.org/D115291
We've stopped doing it in libc++ for a while now because these names
would end up rotting as we move things around and copy/paste stuff.
This cleans up all the existing files so as to stop the spreading
as people copy-paste headers around.
efriedma noted that D104682 broke this test case, reduced from SPEC2006.
#include <istream>
bool a(std::istream a) {
return a.getline(0,0) == 0;
}
We can unbreak it by restoring the conversion to something-convertible-to-bool.
We chose `void*` in order to match libstdc++.
For more ancient history, see PR19460: https://bugs.llvm.org/show_bug.cgi?id=19460
Differential Revision: https://reviews.llvm.org/D107663
With the STL containers, I didn't enable move operations in C++03 mode
because that would change the overload resolution for things that today
are copy operations. With iostreams, though, the copy operations aren't
present at all, and so I see no problem with enabling move operations
even in (Clang's greatly extended) C++03 mode.
Clang's C++03 mode does not support delegating constructors.
Differential Revision: https://reviews.llvm.org/D104310
C++03 didn't support `explicit` conversion operators;
but Clang's C++03 mode does, as an extension, so we can use it.
This lets us make the conversion explicit in `std::function` (even in '03),
and remove some silly metaprogramming in `std::basic_ios`.
Drive-by improvements to the tests for these operators, in addition
to making sure all these tests also run in `c++03` mode.
Differential Revision: https://reviews.llvm.org/D104682