[cfe-dev] [PATCH] Libc++ Windows fixes (Attention all libc++ ports!!!)

Howard Hinnant hhinnant at apple.com
Sun Sep 25 14:30:02 PDT 2011


On Sep 25, 2011, at 10:13 AM, Ruben Van Boxem wrote:

> 2011/9/23 Howard Hinnant <hhinnant at apple.com>
> On Sep 23, 2011, at 3:14 PM, Ruben Van Boxem wrote:
> 
> > Can anything be done about this GCC incompatibility: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10980#c7 ? It is preventing me from linking a functional libc++ (as Clang is not capable of producing correct object files to be linked together), and of course, testing the beast :). To fix it, this basically needs the functions in question to not be declared as "always inline", because GCC produces an error in this case. If Clang does not inline in this case, it should really also produce an error instead of silently ignoring the attribute.
> 
> Seems like the easiest thing to do would be to rewrite these without using va_list.  Only one or two arguments need to be supported.  Just make these always-inline templates.
> 
> Thanks for the valuable idea. Attached patch implements these for non-clang compiles (#ifdef __clang__). I also used the available *_l function variants for those that are available on Windows (MSVC++ runtime 8.0 and later). I also fixed up the win32 support header stuff to work with the full <locale> header things required.
> I added a mingw bit to the lib/buildit script, that for now quite hackishly links to libsupc++ and allows multiple definitions due to a missing alternative. This will at least allow some testing to happen on the rest of the libc++ code, that isn't compiled into the library itself.
> I envision a full LLVM alternative to libgcc and libsupc++, but that is still a looooong way off.
> 
> Comments and especially commits are very welcome!
> 
> Ruben
> 
> PS: the only thing holding back a test run is an undefined reference in mingw-w64's winpthreads library.
> <windows.patch>

I think it is getting time for a refactoring in <locale>.

What appears to be happening is that functions like asprintf_l are getting implemented for each platform, which I think is a good thing.  But it appears to be happening in an increasingly convoluted way.  For example we have:

#ifdef _LIBCPP_STABLE_APPLE_ABI
        __n = asprintf_l(&__bb, 0, "%.0Lf", __units);
#else
        __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
#endif

The first branch is only taken by __APPLE__.  The second branch is taken by everyone else and the definition of __asprintf_l is earlier in <locale>.  This definition sometimes calls vasprintf_l, vasprintf, asprintf, and even (ironically) asprintf_l!  And it isn't easy (at least to me), to see what is happening on each platform.

Suggestion:

#ifdef __APPLE__
#   define _LIBCPP_GET_C_LOCALE 0
#else
#   define _LIBCPP_GET_C_LOCALE __cloc()
#endif

...

     __n = asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units);

And then everyone go off and implement asprintf_l, preferably not in <locale>.  E.g. (and correct me if I'm wrong), __FreeBSD__ has done this in libc.  _WIN32 is doing it in src/support/win32/support.cpp.  I'd like to see this block of code:

// OSX has nice foo_l() functions that let you turn off use of the global
// locale.  Linux, not so much.  The following functions avoid the locale when
// that's possible and otherwise do the wrong thing.  FIXME.
#ifndef _LIBCPP_STABLE_APPLE_ABI

just disappear, or at the very least become greatly reduced.

Thoughts?

Howard




More information about the cfe-dev mailing list