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