// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s template struct A { typedef S B; template using C = typename T::B; template struct D { template using E = typename A::template C>; template using F = A>; template using G = C>; G g; }; typedef decltype(D().g) H; D h; template using I = A; template using J = typename A::template C>; }; A a; A::D b; template T make(); namespace X { template struct traits { typedef T thing; typedef decltype(val(make())) inner_ptr; template using rebind_thing = typename thing::template rebind; template using rebind = traits>; inner_ptr &&alloc(); void free(inner_ptr&&); }; template struct ptr_traits { typedef T *type; }; template using ptr = typename ptr_traits::type; template struct thing { typedef T inner; typedef ptr inner_ptr; typedef traits> traits_type; template using rebind = thing; thing(traits_type &traits) : traits(traits), val(traits.alloc()) {} ~thing() { traits.free(static_cast(val)); } traits_type &traits; inner_ptr val; friend inner_ptr val(const thing &t) { return t.val; } }; template<> struct ptr_traits { typedef bool &type; }; template<> bool &traits>::alloc() { static bool b; return b; } template<> void traits>::free(bool&) {} } typedef X::traits> itt; itt::thing::traits_type itr; itt::thing ith(itr); itt::rebind btr; itt::rebind_thing btt(btr);