[cfe-dev] [PATCH] Libc++ Windows fixes

Aaron Ballman aaron at aaronballman.com
Sun Oct 16 08:42:44 PDT 2011


On Sun, Oct 16, 2011 at 6:17 AM, Ruben Van Boxem
<vanboxem.ruben at gmail.com> wrote:
>  - pragma GCC system_header needed to be surrounded by an ifdef, because
> MSVC doesn't even have a sensible equivalent. I'll just need to eradicate
> all code that produces warnings :)
>  - I added a _WIN32 _LIBCPP_VISIBILITY section to correspond to the
> dllimport/dllexport stuff. I removed _LIBCPP_VISIBILITY_TAG because it is
> useless. I used the "cxx_EXPORTS" define I get from the CMake build. Is it
> supposed to be used for this? If so, please correct, although there will
> need to be a (compiler) define to activate the correct definition when
> building against a pre-built DLL libc++. For static these should all be
> no-ops, and every symbol should be available.
>  - I added a _MSC_VER section detailing all (missing) compiler features.
> Inline namespaces is the worst, for now, MSVC produces unversioned symbols.
> I asked on SO.com for a workaround, but haven't gotten any response yet :(
>  - I also fixed some formatting in results.Windows
>  - I tried to make do_scan_is better, to allow for more than one mask bit,
> like do_is before. I hope I got the logic right.
>
> Please comment or apply. Hopefully more inbound, unless I run into an
> unfixable compiler incompatibility.

> --- test/input.output/iostream.format/ext.manip/get_time.pass.cpp	(revision 141003)
> +++ test/input.output/iostream.format/ext.manip/get_time.pass.cpp	(working copy)
>
> @@ -70,4 +72,8 @@
>          assert(is.eof());
>          assert(!is.fail());
>      }
> +	catch( std::exception &e )
> +	{
> +	    std::cout << e.what();
> +	}
> }

Tabs snuck in here.

> --- include/__config	(revision 141003)
> +++ include/__config	(working copy)
>
> @@ -275,8 +307,30 @@
>  using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
>  }
>
> -#endif  // defined(__GNUC__)
> +#elif defined(_MSC_VER)
>
> +#define _LIBCPP_HAS_NO_UNICODE_CHARS
> +#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
> +#define _LIBCPP_HAS_NO_CONSTEXPR
> +#define _LIBCPP_HAS_NO_UNICODE_CHARS

_LIBCPP_HAS_NO_UNICODE_CHARS is defined twice.

> --- src/locale.cpp	(revision 141003)
> +++ src/locale.cpp	(working copy)
> @@ -1089,17 +1089,18 @@
>          if (iswctype_l(*low, m, __l))
>              break;
>  #else
> -        if (m & space && !iswspace_l(*low, __l)) continue;
> -        if (m & print && !iswprint_l(*low, __l)) continue;
> -        if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
> -        if (m & upper && !iswupper_l(*low, __l)) continue;
> -        if (m & lower && !iswlower_l(*low, __l)) continue;
> -        if (m & alpha && !iswalpha_l(*low, __l)) continue;
> -        if (m & digit && !iswdigit_l(*low, __l)) continue;
> -        if (m & punct && !iswpunct_l(*low, __l)) continue;
> -        if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
> -        if (m & blank && !iswblank_l(*low, __l)) continue;
> -        break;
> +        bool should_break = false
> +        if (m & space && !iswspace_l(*low, __l)) should_break |= true;
> +        if (m & print && !iswprint_l(*low, __l)) should_break |= true;
> +        if (m & cntrl && !iswcntrl_l(*low, __l)) should_break |= true;
> +        if (m & upper && !iswupper_l(*low, __l)) should_break |= true;
> +        if (m & lower && !iswlower_l(*low, __l)) should_break |= true;
> +        if (m & alpha && !iswalpha_l(*low, __l)) should_break |= true;
> +        if (m & digit && !iswdigit_l(*low, __l)) should_break |= true;
> +        if (m & punct && !iswpunct_l(*low, __l)) should_break |= true;
> +        if (m & xdigit && !iswxdigit_l(*low, __l)) should_break |= true;
> +        if (m & blank && !iswblank_l(*low, __l)) should_break |= true;
> +        if( should_break ) break;
>  #endif
>      }
>      return low;

I don't believe these are equivalent.  In the first case, as soon as
something fails the is* test, you start the next loop iteration.  If
you find nothing failing the loop test, you break.  In the second
case, you plow through all of the is* tests and then break if any of
them fail.  Maybe they're not meant to be equivalent and I'm just not
understanding the reason for the logic change, though.

~Aaron




More information about the cfe-dev mailing list