clang searches scopes in the wrong order, causing strange failures when
an inner template has a parameter with the same name as a type in an
outer scope.
clang bug report: <https://llvm.org/bugs/show_bug.cgi?id=13983>
Visual Studio 2013 Update 4 and Clang 3.4 fail to parse
valptridx_template_t related argument lists because they misinterpret
the unspecialized inner template name as a reference to the current
specialization. This seems to be nonconforming in C++11.
All gcc versions supported by Rebirth parse this sample program
correctly, but neither Visual Studio nor clang accept it.
template <template <typename> class>
struct A
{
};
template <typename>
struct B
{
B(A<B>);
};
In <https://stackoverflow.com/questions/17687459/clang-not-accepting-use-of-template-template-parameter-when-using-crtp>, a user saw a similar failure and received the answer:
Your code is legal.
From the C++11 Standard, section 14.6.1:
Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type- specifier of a friend class template declaration, it refers to the class template itself.
Looks like your version of clang is still implementing the old rule.
This failure was first seen with Visual Studio 2013, but ignored because
Visual Studio has so many other problems parsing Rebirth. Now that it
has been reported to affect clang as well, a workaround is clearly
needed. A fix was suggested by btb
<2f9543f981>,
but that fix breaks gcc.
Rewrite the valptridx_template_t parameter passing to avoid mentioning
unspecialized template names as template parameters while defining the
class used as the parameter.
Reported by btb (clang): https://github.com/dxx-rebirth/dxx-rebirth/pull/12