<div dir="ltr">Is this a bug in libstdc++ - should it be requiring/relying on the operand to have an ::iterator typedef?<br><br>(& even if it is a bug, perhaps we should still workaround it - but I'm not entirely sure what the right workaround is, perhaps we should just have our own begin/end that don't have this feature/bug)</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 10, 2016 at 1:18 PM, Dimitry Andric via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">dim created this revision.<br>
dim added reviewers: chandlerc, dblaikie.<br>
dim added subscribers: emaste, llvm-commits.<br>
<br>
When I recently imported llvm and clang 3.8.0 into FreeBSD, our buildbot<br>
that builds the system with gcc 5.3.0 began complaining about a call to<br>
llvm::reverse() in CFGBuilder::buildCFG().  (Note that we are compiling<br>
clang using gcc 5.3.0, but also using libc++ as the C++ library.)<br>
<br>
The gist of the errors is that gcc can't match either of the reverse()<br>
variants in `include/llvm/ADT/STLExtras.h`; the first variant doesn't<br>
match because CXXConstructorDecl::init_range (which is a<br>
llvm::iterator_range) has no rbegin() or rend() methods:<br>
<br>
    tools/clang/lib/Analysis/CFG.cpp: In member function 'std::__1::unique_ptr<clang::CFG> {anonymous}::CFGBuilder::buildCFG(const clang::Decl*, clang::Stmt*)':<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45: error: no matching function for call to 'reverse(clang::CXXConstructorDecl::init_const_range)'<br>
         for (auto *I : llvm::reverse(CD->inits())) {<br>
                                                 ^<br>
    include/llvm/ADT/STLExtras.h:209:6: note: candidate: template<class ContainerTy> decltype (llvm::make_range(C.rbegin(), C.rend())) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<llvm::has_rbegin<ContainerTy>::value>::type*)<br>
     auto reverse(ContainerTy &&C,<br>
          ^<br>
    include/llvm/ADT/STLExtras.h:209:6: note:   template argument deduction/substitution failed:<br>
    include/llvm/ADT/STLExtras.h: In substitution of 'template<class ContainerTy> decltype (llvm::make_range(C.rbegin(), C.rend())) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<llvm::has_rbegin<ContainerTy>::value>::type*) [with ContainerTy = llvm::iterator_range<clang::CXXCtorInitializer* const*>]':<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here<br>
    include/llvm/ADT/STLExtras.h:209:6: error: no type named 'type' in 'struct std::__1::enable_if<false, void>'<br>
<br>
The second variant should really match, but for gcc it doesn't, because<br>
llvm::iterator_range has no 'iterator' and 'const_iterator' types:<br>
<br>
    include/llvm/ADT/STLExtras.h:228:64: error: no matching function for call to 'end(llvm::iterator_range<clang::CXXCtorInitializer* const*>&)'<br>
         -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),<br>
                                                                    ^<br>
    /usr/include/c++/v1/iterator:1575:1: note: candidate: template<class _Cp> typename _Cp::const_iterator std::__1::end(const _Cp&)<br>
     end(const _Cp& __c)<br>
     ^<br>
    /usr/include/c++/v1/iterator:1575:1: note:   template argument deduction/substitution failed:<br>
    /usr/include/c++/v1/iterator: In substitution of 'template<class _Cp> typename _Cp::const_iterator std::__1::end(const _Cp&) [with _Cp = llvm::iterator_range<clang::CXXCtorInitializer* const*>]':<br>
    include/llvm/ADT/STLExtras.h:228:64:   required by substitution of 'template<class ContainerTy> decltype (llvm::make_range(llvm::make_reverse_iterator(std::__1::end(C)), llvm::make_reverse_iterator(std::__1::begin(C)))) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<(! llvm::has_rbegin<ContainerTy>::value)>::type*) [with ContainerTy = llvm::iterator_range<clang::CXXCtorInitializer* const*>]'<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here<br>
    /usr/include/c++/v1/iterator:1575:1: error: no type named 'const_iterator' in 'class llvm::iterator_range<clang::CXXCtorInitializer* const*>'<br>
    include/llvm/ADT/STLExtras.h: In substitution of 'template<class ContainerTy> decltype (llvm::make_range(llvm::make_reverse_iterator(std::__1::end(C)), llvm::make_reverse_iterator(std::__1::begin(C)))) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<(! llvm::has_rbegin<ContainerTy>::value)>::type*) [with ContainerTy = llvm::iterator_range<clang::CXXCtorInitializer* const*>]':<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here<br>
    /usr/include/c++/v1/iterator:1567:1: note: candidate: template<class _Cp> typename _Cp::iterator std::__1::end(_Cp&)<br>
     end(_Cp& __c)<br>
     ^<br>
    /usr/include/c++/v1/iterator:1567:1: note:   template argument deduction/substitution failed:<br>
    /usr/include/c++/v1/iterator: In substitution of 'template<class _Cp> typename _Cp::iterator std::__1::end(_Cp&) [with _Cp = llvm::iterator_range<clang::CXXCtorInitializer* const*>]':<br>
    include/llvm/ADT/STLExtras.h:228:64:   required by substitution of 'template<class ContainerTy> decltype (llvm::make_range(llvm::make_reverse_iterator(std::__1::end(C)), llvm::make_reverse_iterator(std::__1::begin(C)))) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<(! llvm::has_rbegin<ContainerTy>::value)>::type*) [with ContainerTy = llvm::iterator_range<clang::CXXCtorInitializer* const*>]'<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here<br>
    /usr/include/c++/v1/iterator:1567:1: error: no type named 'iterator' in 'class llvm::iterator_range<clang::CXXCtorInitializer* const*>'<br>
    include/llvm/ADT/STLExtras.h: In substitution of 'template<class ContainerTy> decltype (llvm::make_range(llvm::make_reverse_iterator(std::__1::end(C)), llvm::make_reverse_iterator(std::__1::begin(C)))) llvm::reverse(ContainerTy&&, typename std::__1::enable_if<(! llvm::has_rbegin<ContainerTy>::value)>::type*) [with ContainerTy = llvm::iterator_range<clang::CXXCtorInitializer* const*>]':<br>
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here<br>
<br>
To work around this, add 'iterator' and 'const_iterator' types to<br>
llvm::iterator_range().  I think this might even be a requirement for<br>
being able to use std::begin() and std::end()?<br>
<br>
As a side note, maybe it would be more efficient to also add rbegin()<br>
and rend() members to llvm::iterator_range(), then the first variant of<br>
llvm::reverse() can be used?<br>
<br>
<a href="http://reviews.llvm.org/D18061" rel="noreferrer" target="_blank">http://reviews.llvm.org/D18061</a><br>
<br>
Files:<br>
  include/llvm/ADT/iterator_range.h<br>
<br>
Index: include/llvm/ADT/iterator_range.h<br>
===================================================================<br>
--- include/llvm/ADT/iterator_range.h<br>
+++ include/llvm/ADT/iterator_range.h<br>
@@ -33,6 +33,9 @@<br>
   IteratorT begin_iterator, end_iterator;<br>
<br>
 public:<br>
+  typedef IteratorT iterator;<br>
+  typedef const IteratorT const_iterator;<br>
+<br>
   //TODO: Add SFINAE to test that the Container's iterators match the range's<br>
   //      iterators.<br>
   template <typename Container><br>
<br>
<br>
<br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div>