1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li namespace N { 3*67e74705SXin Li struct Outer { 4*67e74705SXin Li struct Inner { 5*67e74705SXin Li template<typename T> 6*67e74705SXin Li struct InnerTemplate { 7*67e74705SXin Li struct VeryInner { 8*67e74705SXin Li typedef T type; 9*67e74705SXin Li 10*67e74705SXin Li static enum K1 { K1Val = sizeof(T) } Kind1; 11*67e74705SXin Li static enum { K2Val = sizeof(T)*2 } Kind2; 12*67e74705SXin Li enum { K3Val = sizeof(T)*2 } Kind3; 13*67e74705SXin Li fooN::Outer::Inner::InnerTemplate::VeryInner14*67e74705SXin Li void foo() { 15*67e74705SXin Li K1 k1 = K1Val; 16*67e74705SXin Li Kind1 = K1Val; 17*67e74705SXin Li Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; 18*67e74705SXin Li Kind3 = K3Val; 19*67e74705SXin Li } 20*67e74705SXin Li 21*67e74705SXin Li struct UeberInner { barN::Outer::Inner::InnerTemplate::VeryInner::UeberInner22*67e74705SXin Li void bar() { 23*67e74705SXin Li K1 k1 = K1Val; 24*67e74705SXin Li Kind1 = K1Val; 25*67e74705SXin Li Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; 26*67e74705SXin Li 27*67e74705SXin Li InnerTemplate t; 28*67e74705SXin Li InnerTemplate<type> t2; 29*67e74705SXin Li } 30*67e74705SXin Li }; 31*67e74705SXin Li }; 32*67e74705SXin Li }; 33*67e74705SXin Li }; 34*67e74705SXin Li }; 35*67e74705SXin Li } 36*67e74705SXin Li 37*67e74705SXin Li typedef int INT; 38*67e74705SXin Li template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner; 39*67e74705SXin Li template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}} 40*67e74705SXin Li 41*67e74705SXin Li namespace N2 { 42*67e74705SXin Li struct Outer2 { 43*67e74705SXin Li template<typename T, typename U = T> 44*67e74705SXin Li struct Inner { fooN2::Outer2::Inner45*67e74705SXin Li void foo() { 46*67e74705SXin Li enum { K1Val = sizeof(T) } k1; 47*67e74705SXin Li enum K2 { K2Val = sizeof(T)*2 } k2a; 48*67e74705SXin Li 49*67e74705SXin Li K2 k2b = K2Val; 50*67e74705SXin Li 51*67e74705SXin Li struct S { T x, y; } s1; 52*67e74705SXin Li struct { U x, y; } s2; 53*67e74705SXin Li s1.x = s2.x; // expected-error{{incompatible}} 54*67e74705SXin Li 55*67e74705SXin Li typedef T type; 56*67e74705SXin Li type t2 = s1.x; 57*67e74705SXin Li 58*67e74705SXin Li typedef struct { T z; } type2; 59*67e74705SXin Li type2 t3 = { s1.x }; 60*67e74705SXin Li 61*67e74705SXin Li Inner i1; 62*67e74705SXin Li i1.foo(); 63*67e74705SXin Li Inner<T> i2; 64*67e74705SXin Li i2.foo(); 65*67e74705SXin Li } 66*67e74705SXin Li }; 67*67e74705SXin Li }; 68*67e74705SXin Li } 69*67e74705SXin Li 70*67e74705SXin Li template struct N2::Outer2::Inner<float>; 71*67e74705SXin Li template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}} 72*67e74705SXin Li 73*67e74705SXin Li // Test dependent pointer-to-member expressions. 74*67e74705SXin Li template<typename T> 75*67e74705SXin Li struct smart_ptr { 76*67e74705SXin Li struct safe_bool { 77*67e74705SXin Li int member; 78*67e74705SXin Li }; 79*67e74705SXin Li operator int safe_bool::*smart_ptr80*67e74705SXin Li operator int safe_bool::*() const { 81*67e74705SXin Li return ptr? &safe_bool::member : 0; 82*67e74705SXin Li } 83*67e74705SXin Li 84*67e74705SXin Li T* ptr; 85*67e74705SXin Li }; 86*67e74705SXin Li test_smart_ptr(smart_ptr<int> p)87*67e74705SXin Livoid test_smart_ptr(smart_ptr<int> p) { 88*67e74705SXin Li if (p) { } 89*67e74705SXin Li } 90*67e74705SXin Li 91*67e74705SXin Li // PR5517 92*67e74705SXin Li namespace test0 { 93*67e74705SXin Li template <int K> struct X { Xtest0::X94*67e74705SXin Li X() { extern void x(); } 95*67e74705SXin Li }; g()96*67e74705SXin Li void g() { X<2>(); } 97*67e74705SXin Li } 98*67e74705SXin Li 99*67e74705SXin Li // <rdar://problem/8302161> 100*67e74705SXin Li namespace test1 { f(T const & t)101*67e74705SXin Li template <typename T> void f(T const &t) { 102*67e74705SXin Li union { char c; T t_; }; 103*67e74705SXin Li c = 'a'; // <- this shouldn't silently fail to instantiate 104*67e74705SXin Li T::foo(); // expected-error {{has no members}} 105*67e74705SXin Li } 106*67e74705SXin Li template void f(int const &); // expected-note {{requested here}} 107*67e74705SXin Li } 108*67e74705SXin Li 109*67e74705SXin Li namespace test2 { f()110*67e74705SXin Li template<typename T> void f() { 111*67e74705SXin Li T::error; // expected-error {{no member}} 112*67e74705SXin Li } g()113*67e74705SXin Li void g() { 114*67e74705SXin Li // This counts as an odr-use, so should trigger the instantiation of f<int>. 115*67e74705SXin Li (void)&f<int>; // expected-note {{here}} 116*67e74705SXin Li } 117*67e74705SXin Li } 118