[cfe-dev] How do I try out C++ modules with clang?

Richard Smith richard at metafoo.co.uk
Tue Oct 21 17:27:04 PDT 2014


On Tue, Oct 21, 2014 at 2:34 PM, Sean Silva <chisophugis at gmail.com> wrote:

> After a bit of looking around on my Mac, I think I figured out what is
> going on. The declaration for those functions is in <xlocale/_stdlib.h>.
> That header is only included from two places:
>
> 1. From stdlib.h if _USE_EXTENDED_LOCALES_ is defined.
> 2. From xlocale.h if stdlib.h has been previously included (this is sort
> of nasty, but documented
> http://www.freebsd.org/cgi/man.cgi?query=xlocale&sektion=3 "These
> functions are exposed by including <xlocale.h> after including the
> relevant headers for the standard variant."; Apple doesn't document this
> because it looks like they use a non-modular trick described below to work
> around this).
>
> I'll assume you don't have _USE_EXTENDED_LOCALES_ defined on the command
> line. Looking at libc++'s <locale> and the headers it includes, it looks
> like xlocale.h gets included without stdlib.h having been included
> (<locale> --> <__locale> --> <xlocale.h>). If this hypothesis is correct,
> then these errors should go away if you change libc++'s <locale> by moving
> `#include <__locale>` below `#include <cstdlib>`.
>
> The trick that the Apple headers seem to use to work around the "must be
> included after" issue is that xlocale.h defines _USE_EXTENDED_LOCALES_ so
> that a subsequent include of stdlib.h will bring them in. However, stdlib.h
> is brought in from the module, where it was built without
> _USE_EXTENDED_LOCALES_ defined. Thus, <xlocale/_stdlib.h> is never seen by
> the compiler, and those functions are missing.
>
> This trick breaks one of the promises the module map file makes about
> stdlib.h, which roughly boils down to "this header isn't meant to change
> its behaviors depending on the set of macros defined when it is included";
> thus it is not surprising that this should break. I made a reduced test
> case (attached) which suggests that even clang's config_macros doesn't deal
> with this.
>

Did you try adding -D_USE_ to the command line in your reduced testcase?

Richard, any ideas on what the "right" solution is here?
>

One possibility would be to split stdlib.h up into three:

1) A module providing most of the stdlib.h contents
2) A module providing xlocale/_stdlib.h (it seems this part is already done)
3) A file that imports (1) and (2)

... and to treat (3) as a textually-included header rather than a module. I
think that's my preferred approach, since it allows retaining the existing
horrible mess of _*_SOURCE configuration macros controlling which symbols
come from which includes.

Another would be for stdlib.h to always provide everything when built with
modules enabled.

Another would be to add -D_USE_EXTENDED_LOCALES_ to your clang command line.

Stephen, thanks for being a brave guinea pig here :)
>
> -- Sean Silva
>
>
>
>
> On Tue, Oct 21, 2014 at 4:57 AM, Stephen Kelly <steveire at gmail.com> wrote:
>
>> Richard Smith <richard at ...> writes:
>>
>> > libc++ already ships with a module map.
>>
>> Today I built llvm, clang and libcxx on a Mac (OSX 10.9 I assume), and
>> when
>> I try to use -fmodules, it can't build the module.modulemap shipped with
>> libcxx. Any idea what's going wrong?
>>
>> $ clang++ -E -fmodules test.cpp
>> # 1 "test.cpp"
>> # 1 "<built-in>" 1
>> # 1 "<built-in>" 3
>> # 325 "<built-in>" 3
>> # 1 "<command line>" 1
>> # 1 "<built-in>" 2
>> # 1 "test.cpp" 2
>> While building module 'std' imported from test.cpp:6:
>> In file included from <module-includes>:4:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:
>> /Users/ske/dev/prefix/bin/../include/c++/v1/locale:873:26: error: use of
>> undeclared identifier 'strtoll_l'; did you mean 'wcstoll_l'?
>>         long long __ll = strtoll_l(__a, &__p2, __base,
>> _LIBCPP_GET_C_LOCALE);
>>                          ^
>> /usr/include/xlocale/_wchar.h:98:2: note: 'wcstoll_l' declared here
>>         wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int,
>>         ^
>> While building module 'std' imported from test.cpp:6:
>> In file included from <module-includes>:4:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:
>> /Users/ske/dev/prefix/bin/../include/c++/v1/locale:873:36: error: cannot
>> initialize a parameter of type 'const wchar_t *' with an lvalue of type
>> 'const char *'
>>         long long __ll = strtoll_l(__a, &__p2, __base,
>> _LIBCPP_GET_C_LOCALE);
>>                                    ^~~
>> /usr/include/xlocale/_wchar.h:98:38: note: passing argument to parameter
>> here
>>         wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int,
>>                                             ^
>> While building module 'std' imported from test.cpp:6:
>> In file included from <module-includes>:4:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:
>> /Users/ske/dev/prefix/bin/../include/c++/v1/locale:913:35: error: use of
>> undeclared identifier 'strtoull_l'; did you mean 'wcstoull_l'?
>>         unsigned long long __ll = strtoull_l(__a, &__p2, __base,
>> _LIBCPP_GET_C_LOCALE);
>>                                   ^
>> /usr/include/xlocale/_wchar.h:101:2: note: 'wcstoull_l' declared here
>>         wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int,
>>         ^
>> While building module 'std' imported from test.cpp:6:
>> In file included from <module-includes>:4:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:
>> /Users/ske/dev/prefix/bin/../include/c++/v1/locale:913:46: error: cannot
>> initialize a parameter of type 'const wchar_t *' with an lvalue of type
>> 'const char *'
>>         unsigned long long __ll = strtoull_l(__a, &__p2, __base,
>> _LIBCPP_GET_C_LOCALE);
>>                                              ^~~
>> /usr/include/xlocale/_wchar.h:101:39: note: passing argument to parameter
>> here
>>         wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int,
>>                                              ^
>> While building module 'std' imported from test.cpp:6:
>> In file included from <module-includes>:4:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:
>> In file included from
>> /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:
>> /Users/ske/dev/prefix/bin/../include/c++/v1/locale:943:28: error: use of
>> undeclared identifier 'strtold_l'
>>         long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
>>                            ^
>> test.cpp:6:10: fatal error: could not build module 'std'
>> #include <utility>
>>  ~~~~~~~~^
>>
>>
>>
>>
>>
>>
>>
>> int main(int argc, char** argv)
>> {
>>     return 0;
>> }
>> 6 errors generated.
>>
>> $ cat test.cpp
>>
>> //#include "foo.h"
>>
>> //#include <QtCore/qxmlstream.h>
>>
>> #include <utility>
>>
>> int main(int argc, char** argv)
>> {
>>     return 0;
>> }
>>
>> $ clang++ --version
>> clang version 3.6.0
>> Target: x86_64-apple-darwin13.4.0
>> Thread model: posix
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141021/2c640927/attachment.html>


More information about the cfe-dev mailing list