Clang Modules interacting with std <iterator> and <boost / move / iterator.hpp>
(See the end of the question for information on the specific versions of Boost and Clang that I use)
Compiling in Clang from master / HEAD using the new experimental function -fmodules
, I get a build error from compiling the following file with command line parameters shown below:
#include <iterator> #include <boost/move/iterator.hpp>
Compile command and error:
anhall@leviathan : <path-to-clang-install-from-master>/bin/clang++ -o file.o -c file.cpp --std=c++1z -stdlib=libc++ -fmodules In file included from file.cpp:2: In file included from /usr/local/include/boost/move/iterator.hpp:27: /usr/local/include/boost/move/detail/iterator_traits.hpp:60:17: error: reference to 'random_access_iterator_tag' is ambiguous typedef std::random_access_iterator_tag iterator_category; ^ /Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:438:30: note: candidate found by name lookup is 'std::__1::random_access_iterator_tag' struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {}; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:34:8: note: candidate found by name lookup is 'std::random_access_iterator_tag' struct random_access_iterator_tag; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:71:17: error: reference to 'random_access_iterator_tag' is ambiguous typedef std::random_access_iterator_tag iterator_category; ^ /Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:438:30: note: candidate found by name lookup is 'std::__1::random_access_iterator_tag' struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {}; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:34:8: note: candidate found by name lookup is 'std::random_access_iterator_tag' struct random_access_iterator_tag; ^ In file included from file.cpp:2: /usr/local/include/boost/move/iterator.hpp:196:17: error: reference to 'output_iterator_tag' is ambiguous typedef std::output_iterator_tag iterator_category; ^ /Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag' struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {}; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag' struct output_iterator_tag; ^ In file included from file.cpp:2: /usr/local/include/boost/move/iterator.hpp:238:17: error: reference to 'output_iterator_tag' is ambiguous typedef std::output_iterator_tag iterator_category; ^ /Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag' struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {}; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag' struct output_iterator_tag; ^ In file included from file.cpp:2: /usr/local/include/boost/move/iterator.hpp:278:17: error: reference to 'output_iterator_tag' is ambiguous typedef std::output_iterator_tag iterator_category; ^ /Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag' struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {}; ^ /usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag' struct output_iterator_tag; ^ 5 errors generated.
If I delete #include <iterator>
or move it after #include <boost/move/iterator.hpp>
, the errors disappear.
Question: Is this just a byproduct of the Boost libraries (in particular, apparently, the Boost Move) that do not prepare for modules with Clang module map files? Could this be an error with the module map files that Clang has now implemented for libC ++ or even an error in the module implementation itself?
Interestingly, I can make the error go away by commenting on lines 28-28 from boost/move/detail/iterator_traits.hpp
:
// #include <boost/move/detail/std_ns_begin.hpp> // BOOST_MOVE_STD_NS_BEG // // struct input_iterator_tag; // struct forward_iterator_tag; // struct bidirectional_iterator_tag; // struct random_access_iterator_tag; // struct output_iterator_tag; // // BOOST_MOVE_STD_NS_END // #include <boost/move/detail/std_ns_end.hpp>
Used Versions
Boost 1.61
Clang is located from the tip of the master branch in the LLVM github mirror starting December 7, 2016 (technically this is from the LLVM fork, but only on the main branch, identical to the own branch of the main LLVM):
clang version 4.0.0 (https://github.com/matus-chochlik/clang.git b9cb1c8a1ebf52695372de12c7b04c8ef1bd8b4e) (https://github.com/llvm-mirror/llvm.git b60c7b1f61eabbe971d08568adb790a7cfc6a403) Target: x86_64-apple-darwin15.6.0 Thread model: posix InstalledDir: /Users/anhall/impersonal/code/llvm-reflexpr/install/bin
I believe this is caused by a problem with libC ++ module.modulemap, which I fixed yesterday in r289028 . This error led to the fact that the _LIBCPP_VERSION
macro _LIBCPP_VERSION
not exported by lib ++ when modules were turned on.
After looking at boost/move/detail/iterator_traits.hpp
it seems that if _LIBCPP_VERSION
not defined, it will skip-configure and eventually declare completely different definitions of iterator tags. (In particular, he will define them directly in the std
, and not in the libC ++ version namespace).
If you rebuilt LLVM and libC ++, it should fix your problem. If you can not write down the error .
PS. It seems I'm just a step ahead .
I can only speak for boost 1.59.1 at the moment, but it also explicitly makes the assumption that libC ++ can only be seen when created with clang:
#if defined(__clang__) && defined(_LIBCPP_VERSION) // ... #else // ... #endif
This causes almost the same error as above, even on Mac OS X 10.9 with libC ++, which precedes the implementation of libC ++ regression, which caused the problem discussed in this thread.