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