// RUN: %clang_cc1 -fsyntax-only -verify %s namespace N { struct A { typedef int type; }; struct B { }; struct C { struct type { }; int type; // expected-note 2{{referenced member 'type' is declared here}} }; } int i; typename N::A::type *ip1 = &i; // expected-warning{{'typename' occurs outside of a template}} typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} \ // expected-warning{{'typename' occurs outside of a template}} typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} \ // expected-warning{{'typename' occurs outside of a template}} void test(double d) { typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}} \ // expected-warning 2{{'typename' occurs outside of a template}} int five = f(5); using namespace N; for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' occurs outside of a template}} five += 1; const typename N::A::type f2(d); // expected-warning{{'typename' occurs outside of a template}} } namespace N { template struct X { typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \ // expected-error {{no type named 'type' in 'B'}} \ // FIXME: location info for error above isn't very good \ // expected-error 2{{typename specifier refers to non-type member 'type'}} \ // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} }; } N::X::type *ip4 = &i; N::X::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X' requested here}} N::X::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X' requested here}} N::X::type fail1; // expected-note{{in instantiation of template class 'N::X' requested here}} template struct Y { typedef typename N::X::type *type; // expected-note{{in instantiation of template class 'N::X' requested here}} \ // expected-note{{in instantiation of template class 'N::X' requested here}} }; struct A { typedef int type; }; struct B { }; struct C { struct type { }; int type; // expected-note{{referenced member 'type' is declared here}} }; ::Y::type ip7 = &i; ::Y::type ip8 = &i; // expected-note{{in instantiation of template class 'Y' requested here}} ::Y::type ip9 = &i; // expected-note{{in instantiation of template class 'Y' requested here}} template struct D { typedef typename T::foo foo; // expected-error {{type 'long' cannot be used prior to '::' because it has no members}} typedef typename foo::bar bar; }; D struct_D; // expected-note {{in instantiation of template class 'D' requested here}} template struct E { typedef typename T::foo foo; typedef typename foo::bar bar; // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}} }; struct F { typedef double foo; }; E struct_E; // expected-note {{in instantiation of template class 'E' requested here}} template struct G { typedef typename T::foo foo; typedef typename foo::bar bar; }; struct H { struct foo { typedef double bar; }; }; G struct_G; namespace PR10925 { template< int mydim, typename Traits > class BasicGeometry { typedef int some_type_t; }; template class MockGeometry : BasicGeometry{ using typename BasicGeometry::operator[]; // expected-error {{typename is allowed for identifiers only}} }; }