diff mbox

New std::string implementation

Message ID 20141128152448.GQ5191@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Nov. 28, 2014, 3:24 p.m. UTC
None
diff mbox

Patch

Here's the next version of the std::string rework, this time with
57.1428% more locale facets!

The problem is that there are several facet types that use std::string
in their public interfaces and as the parameters (or worse, as return
types) of virtual functions. It's not possible to overload the
functions to take either the old std::string or the new std::string
because that would add virtual functions to the vtable which is an ABI
change (and you can't overload on return type anyway). The facets are
used deep in the guts of locales and iostreams so need to remain
compatible.

My solution is to add a second version of each affected facet, with
one version using the old ABI and one using the new, but with
otherwise the same behaviour. When a piece of code says
std::use_facet<std::collate<char>>(someLocale) they get a reference to
the locale's std::collate<char> facet with the same ABI as is in
effect at the call site.

The difficult part is that users can replace a facet to customise
behaviour, so if they replace the old ABI version of
std::collate<char> I need to also replace the new ABI version of the
same facet, using a shim that has the same behaviour as the
user-defined facet (which is achieved by the shim just forwarding to
the user's facet, and converting between std::string representations).

I've also had to add a new virtual function to std::error_category so
you can call error_category::message() (which returns a std::string)
in the context of either ABI. Adding the virtual grows the size of the
vtable in a type that's been exported from libstdc++.so since 4.4.0 so
I moved std::error_category to src/c++11/compatibility-c++0x.cc and
added a new std::_V2::error_category in the same inline namespace used
for a similar switcheroo on std::condition_variable_any

With these changes the entire libstdc++ testsuite passes when using
either ABI, confirming that the library still exports everything
needed for existing code (compiled with GCC <5) to keep working, but
also contains everything for new code (GCC 5+) to work.

Tested x86_64-linux with:

  --target_board=unix\{-m32,\}\{,-D_GLIBCXX_USE_CXX11_ABI=0\}

Also tested on powerpc64-linux (where this patch doesn't actually
bootstrap due to PR 63573, there's a patch in the PR that's needed)
and i686-linux.

The Python pretty printers for std::string fail with the new ABI. I'm
not sure why, I think GDB is failing to distinguish between the two
types of std::string. That will only require changes to the python
code though.