[PATCH] D18061: Add iterator types to iterator_range, to appease newer gcc's

Dimitry Andric via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 13:18:23 PST 2016


dim created this revision.
dim added reviewers: chandlerc, dblaikie.
dim added subscribers: emaste, llvm-commits.

When I recently imported llvm and clang 3.8.0 into FreeBSD, our buildbot
that builds the system with gcc 5.3.0 began complaining about a call to
llvm::reverse() in CFGBuilder::buildCFG().  (Note that we are compiling
clang using gcc 5.3.0, but also using libc++ as the C++ library.)

The gist of the errors is that gcc can't match either of the reverse()
variants in `include/llvm/ADT/STLExtras.h`; the first variant doesn't
match because CXXConstructorDecl::init_range (which is a
llvm::iterator_range) has no rbegin() or rend() methods:

    tools/clang/lib/Analysis/CFG.cpp: In member function 'std::__1::unique_ptr<clang::CFG> {anonymous}::CFGBuilder::buildCFG(const clang::Decl*, clang::Stmt*)':
    tools/clang/lib/Analysis/CFG.cpp:1046:45: error: no matching function for call to 'reverse(clang::CXXConstructorDecl::init_const_range)'
         for (auto *I : llvm::reverse(CD->inits())) {
                                                 ^
    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*)
     auto reverse(ContainerTy &&C,
          ^
    include/llvm/ADT/STLExtras.h:209:6: note:   template argument deduction/substitution failed:
    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*>]':
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here
    include/llvm/ADT/STLExtras.h:209:6: error: no type named 'type' in 'struct std::__1::enable_if<false, void>'

The second variant should really match, but for gcc it doesn't, because
llvm::iterator_range has no 'iterator' and 'const_iterator' types:

    include/llvm/ADT/STLExtras.h:228:64: error: no matching function for call to 'end(llvm::iterator_range<clang::CXXCtorInitializer* const*>&)'
         -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
                                                                    ^
    /usr/include/c++/v1/iterator:1575:1: note: candidate: template<class _Cp> typename _Cp::const_iterator std::__1::end(const _Cp&)
     end(const _Cp& __c)
     ^
    /usr/include/c++/v1/iterator:1575:1: note:   template argument deduction/substitution failed:
    /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*>]':
    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*>]'
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here
    /usr/include/c++/v1/iterator:1575:1: error: no type named 'const_iterator' in 'class llvm::iterator_range<clang::CXXCtorInitializer* const*>'
    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*>]':
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here
    /usr/include/c++/v1/iterator:1567:1: note: candidate: template<class _Cp> typename _Cp::iterator std::__1::end(_Cp&)
     end(_Cp& __c)
     ^
    /usr/include/c++/v1/iterator:1567:1: note:   template argument deduction/substitution failed:
    /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*>]':
    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*>]'
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here
    /usr/include/c++/v1/iterator:1567:1: error: no type named 'iterator' in 'class llvm::iterator_range<clang::CXXCtorInitializer* const*>'
    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*>]':
    tools/clang/lib/Analysis/CFG.cpp:1046:45:   required from here

To work around this, add 'iterator' and 'const_iterator' types to
llvm::iterator_range().  I think this might even be a requirement for
being able to use std::begin() and std::end()?

As a side note, maybe it would be more efficient to also add rbegin()
and rend() members to llvm::iterator_range(), then the first variant of
llvm::reverse() can be used?

http://reviews.llvm.org/D18061

Files:
  include/llvm/ADT/iterator_range.h

Index: include/llvm/ADT/iterator_range.h
===================================================================
--- include/llvm/ADT/iterator_range.h
+++ include/llvm/ADT/iterator_range.h
@@ -33,6 +33,9 @@
   IteratorT begin_iterator, end_iterator;
 
 public:
+  typedef IteratorT iterator;
+  typedef const IteratorT const_iterator;
+
   //TODO: Add SFINAE to test that the Container's iterators match the range's
   //      iterators.
   template <typename Container>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18061.50340.patch
Type: text/x-patch
Size: 467 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160310/c91e596f/attachment.bin>


More information about the llvm-commits mailing list