<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 21, 2014 at 5:27 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Tue, Oct 21, 2014 at 2:34 PM, Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>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:</div><div><br></div><div>1. From stdlib.h if _USE_EXTENDED_LOCALES_ is defined.</div><div>2. From xlocale.h if stdlib.h has been previously included (this is sort of nasty, but documented <a href="http://www.freebsd.org/cgi/man.cgi?query=xlocale&sektion=3" target="_blank">http://www.freebsd.org/cgi/man.cgi?query=xlocale&sektion=3</a> "These functions are exposed by including <xlocale.h> after<span style="white-space:pre-wrap"> </span>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).</div><div><br></div><div>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>`.</div><div><br></div><div>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.</div><div><br></div><div>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.</div></div></blockquote><div><br></div></span><div>Did you try adding -D_USE_ to the command line in your reduced testcase?</div><span class=""><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Richard, any ideas on what the "right" solution is here?</div></div></blockquote><div><br></div></span><div>One possibility would be to split stdlib.h up into three:</div><div><br></div><div>1) A module providing most of the stdlib.h contents</div><div>2) A module providing xlocale/_stdlib.h (it seems this part is already done)</div><div>3) A file that imports (1) and (2)</div><div><br></div><div>... 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.</div><div><br></div><div>Another would be for stdlib.h to always provide everything when built with modules enabled.</div><div><br></div><div>Another would be to add -D_USE_EXTENDED_LOCALES_ to your clang command line.</div></div></div></div></blockquote><div><br></div><div>I think in this case it's not meant to be something for the end-user to configure. It seems like _USE_EXTENDED_LOCALES_ is just a cookie that xlocale.h sets so that stdlib.h et al. remember to include their relevant xlocale/_stdlib.h file (I was mostly thinking about config_macros as a hack to work around it).</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Stephen, thanks for being a brave guinea pig here :)</div><span><font color="#888888"><div><br></div><div>-- Sean Silva</div><div><br></div><div><br></div><div><br></div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 21, 2014 at 4:57 AM, Stephen Kelly <span dir="ltr"><<a href="mailto:steveire@gmail.com" target="_blank">steveire@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>Richard Smith <richard@...> writes:<br>
<br>
> libc++ already ships with a module map.<br>
<br>
</span>Today I built llvm, clang and libcxx on a Mac (OSX 10.9 I assume), and when<br>
I try to use -fmodules, it can't build the module.modulemap shipped with<br>
libcxx. Any idea what's going wrong?<br>
<br>
$ clang++ -E -fmodules test.cpp<br>
# 1 "test.cpp"<br>
# 1 "<built-in>" 1<br>
# 1 "<built-in>" 3<br>
# 325 "<built-in>" 3<br>
# 1 "<command line>" 1<br>
# 1 "<built-in>" 2<br>
# 1 "test.cpp" 2<br>
While building module 'std' imported from test.cpp:6:<br>
In file included from <module-includes>:4:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:<br>
/Users/ske/dev/prefix/bin/../include/c++/v1/locale:873:26: error: use of<br>
undeclared identifier 'strtoll_l'; did you mean 'wcstoll_l'?<br>
        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);<br>
                         ^<br>
/usr/include/xlocale/_wchar.h:98:2: note: 'wcstoll_l' declared here<br>
        wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int,<br>
        ^<br>
While building module 'std' imported from test.cpp:6:<br>
In file included from <module-includes>:4:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:<br>
/Users/ske/dev/prefix/bin/../include/c++/v1/locale:873:36: error: cannot<br>
initialize a parameter of type 'const wchar_t *' with an lvalue of type<br>
'const char *'<br>
        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);<br>
                                   ^~~<br>
/usr/include/xlocale/_wchar.h:98:38: note: passing argument to parameter here<br>
        wcstoll_l(const wchar_t * __restrict, wchar_t ** __restrict, int,<br>
                                            ^<br>
While building module 'std' imported from test.cpp:6:<br>
In file included from <module-includes>:4:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:<br>
/Users/ske/dev/prefix/bin/../include/c++/v1/locale:913:35: error: use of<br>
undeclared identifier 'strtoull_l'; did you mean 'wcstoull_l'?<br>
        unsigned long long __ll = strtoull_l(__a, &__p2, __base,<br>
_LIBCPP_GET_C_LOCALE);<br>
                                  ^<br>
/usr/include/xlocale/_wchar.h:101:2: note: 'wcstoull_l' declared here<br>
        wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int,<br>
        ^<br>
While building module 'std' imported from test.cpp:6:<br>
In file included from <module-includes>:4:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:<br>
/Users/ske/dev/prefix/bin/../include/c++/v1/locale:913:46: error: cannot<br>
initialize a parameter of type 'const wchar_t *' with an lvalue of type<br>
'const char *'<br>
        unsigned long long __ll = strtoull_l(__a, &__p2, __base,<br>
_LIBCPP_GET_C_LOCALE);<br>
                                             ^~~<br>
/usr/include/xlocale/_wchar.h:101:39: note: passing argument to parameter here<br>
        wcstoull_l(const wchar_t * __restrict, wchar_t ** __restrict, int,<br>
                                             ^<br>
While building module 'std' imported from test.cpp:6:<br>
In file included from <module-includes>:4:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ccomplex:21:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/complex:247:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/sstream:174:<br>
In file included from /Users/ske/dev/prefix/bin/../include/c++/v1/ostream:140:<br>
/Users/ske/dev/prefix/bin/../include/c++/v1/locale:943:28: error: use of<br>
undeclared identifier 'strtold_l'<br>
        long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);<br>
                           ^<br>
test.cpp:6:10: fatal error: could not build module 'std'<br>
#include <utility><br>
 ~~~~~~~~^<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
int main(int argc, char** argv)<br>
{<br>
    return 0;<br>
}<br>
6 errors generated.<br>
<br>
$ cat test.cpp<br>
<br>
//#include "foo.h"<br>
<br>
//#include <QtCore/qxmlstream.h><br>
<br>
#include <utility><br>
<br>
int main(int argc, char** argv)<br>
{<br>
    return 0;<br>
}<br>
<br>
$ clang++ --version<br>
clang version 3.6.0<br>
Target: x86_64-apple-darwin13.4.0<br>
Thread model: posix<br>
<div><div><br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>