Bug 13699 - Types unexpectedly lose visibility. This is happening when using iterators.

I'm working with libclang in VIM's clang_complete.
I'm having the following unexpected behavior when using iterators. Initially it
was showing up with the new C++ range-for but in the end I've reduced it to
iterator usage.

#include <vector>

int main()
    // std::vector type is visible here

    std::vector<int>::iterator i;

    // after declaring an iterator like above, std::vector
    // is not visible for completion anymore.

    return 0;

So sad of losing completion for containers =(

It seems this behavior comes from usage of the __wrap_iter template.

basic_string also declares its iterator with it like this:
typedef __wrap_iter<pointer> iterator;

And it suffers from the same behavior. After declaring:

std::basic_string<char>::iterator c;

std::basic_string ceases to be accessible from completion.

This __wrap_iter template exists in the libc++, which I'm using.

Digging the __wrap_iter I've reduced it to a problem of weird behavior.
If I put a header file, like dummy.h for example, inside
which is a default search location for standard headers files by the Clang
compiler, and it's where libc++ lives at my system, with the following

namespace std
    struct __X{};

std::__X is not given for completion of std::

If I change the contents of dummy.h to

namespace std
    struct X{};

std::X is given for completion of std::

Now, if I put this dummy.h file with the first __X in a directory different
from libc++ headers location, I've tested putting it besides my test.cpp
then __X shows up for completion of std:: !

Anything with one or two underscores from <iterator>, and maybe other headers
from libc++ location is not given for completion.

Ok, the problem of no visibility of underscored types at libc++ *location* is
not the real cause for losing visibility for types after using it's iterator

I've reduced the problem to template friendship usage:

namespace std
    template <class I> struct __W
        template<class E> friend class V;

    template <class T> struct V

int main()
    // There's visibility for *std::V* here

    std::__W<int> w;

    // There's NO visibility for *std::V* here

    return 0;

__wrap_iter and vector/basic_string have a pattern resembling the above, and
that's why after using a std::vector<int>::iterator, the std::vector
template is not given as a completion option after std::