18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s 2f98d9b60SDouglas Gregor namespace N { 3f98d9b60SDouglas Gregor struct Outer { 4f98d9b60SDouglas Gregor struct Inner { 5f98d9b60SDouglas Gregor template<typename T> 6f98d9b60SDouglas Gregor struct InnerTemplate { 7f98d9b60SDouglas Gregor struct VeryInner { 8f98d9b60SDouglas Gregor typedef T type; 9f98d9b60SDouglas Gregor 10f98d9b60SDouglas Gregor static enum K1 { K1Val = sizeof(T) } Kind1; 117a74938fSDouglas Gregor static enum { K2Val = sizeof(T)*2 } Kind2; 12b8006fafSDouglas Gregor enum { K3Val = sizeof(T)*2 } Kind3; 13f98d9b60SDouglas Gregor fooN::Outer::Inner::InnerTemplate::VeryInner14f98d9b60SDouglas Gregor void foo() { 15f98d9b60SDouglas Gregor K1 k1 = K1Val; 16f98d9b60SDouglas Gregor Kind1 = K1Val; 17f98d9b60SDouglas Gregor Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; 18b8006fafSDouglas Gregor Kind3 = K3Val; 19b8006fafSDouglas Gregor } 20b8006fafSDouglas Gregor 21b8006fafSDouglas Gregor struct UeberInner { barN::Outer::Inner::InnerTemplate::VeryInner::UeberInner22b8006fafSDouglas Gregor void bar() { 23b8006fafSDouglas Gregor K1 k1 = K1Val; 24b8006fafSDouglas Gregor Kind1 = K1Val; 25b8006fafSDouglas Gregor Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; 26cd3a0979SDouglas Gregor 27cd3a0979SDouglas Gregor InnerTemplate t; 28cd3a0979SDouglas Gregor InnerTemplate<type> t2; 29f98d9b60SDouglas Gregor } 30f98d9b60SDouglas Gregor }; 31f98d9b60SDouglas Gregor }; 32f98d9b60SDouglas Gregor }; 33f98d9b60SDouglas Gregor }; 34b8006fafSDouglas Gregor }; 35f98d9b60SDouglas Gregor } 36f98d9b60SDouglas Gregor 37f98d9b60SDouglas Gregor typedef int INT; 38f98d9b60SDouglas Gregor template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner; 39f5af3584SDouglas Gregor template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}} 40e44a2adfSDouglas Gregor 41e44a2adfSDouglas Gregor namespace N2 { 42e44a2adfSDouglas Gregor struct Outer2 { 438157b07cSDouglas Gregor template<typename T, typename U = T> 44e44a2adfSDouglas Gregor struct Inner { fooN2::Outer2::Inner45e44a2adfSDouglas Gregor void foo() { 46e44a2adfSDouglas Gregor enum { K1Val = sizeof(T) } k1; 478157b07cSDouglas Gregor enum K2 { K2Val = sizeof(T)*2 } k2a; 48e44a2adfSDouglas Gregor 498157b07cSDouglas Gregor K2 k2b = K2Val; 508157b07cSDouglas Gregor 518157b07cSDouglas Gregor struct S { T x, y; } s1; 528157b07cSDouglas Gregor struct { U x, y; } s2; 538157b07cSDouglas Gregor s1.x = s2.x; // expected-error{{incompatible}} 548157b07cSDouglas Gregor 558157b07cSDouglas Gregor typedef T type; 568157b07cSDouglas Gregor type t2 = s1.x; 57e44a2adfSDouglas Gregor 5805580944SDouglas Gregor typedef struct { T z; } type2; 5905580944SDouglas Gregor type2 t3 = { s1.x }; 6005580944SDouglas Gregor 61e44a2adfSDouglas Gregor Inner i1; 62e44a2adfSDouglas Gregor i1.foo(); 63e44a2adfSDouglas Gregor Inner<T> i2; 64e44a2adfSDouglas Gregor i2.foo(); 65e44a2adfSDouglas Gregor } 66e44a2adfSDouglas Gregor }; 67e44a2adfSDouglas Gregor }; 68e44a2adfSDouglas Gregor } 69e44a2adfSDouglas Gregor 708157b07cSDouglas Gregor template struct N2::Outer2::Inner<float>; 718157b07cSDouglas Gregor template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}} 72c95a1fa7SDouglas Gregor 73c95a1fa7SDouglas Gregor // Test dependent pointer-to-member expressions. 74c95a1fa7SDouglas Gregor template<typename T> 75c95a1fa7SDouglas Gregor struct smart_ptr { 76c95a1fa7SDouglas Gregor struct safe_bool { 77c95a1fa7SDouglas Gregor int member; 78c95a1fa7SDouglas Gregor }; 79c95a1fa7SDouglas Gregor operator int safe_bool::*smart_ptr80c95a1fa7SDouglas Gregor operator int safe_bool::*() const { 81c95a1fa7SDouglas Gregor return ptr? &safe_bool::member : 0; 82c95a1fa7SDouglas Gregor } 83c95a1fa7SDouglas Gregor 84c95a1fa7SDouglas Gregor T* ptr; 85c95a1fa7SDouglas Gregor }; 86c95a1fa7SDouglas Gregor test_smart_ptr(smart_ptr<int> p)87c95a1fa7SDouglas Gregorvoid test_smart_ptr(smart_ptr<int> p) { 88c95a1fa7SDouglas Gregor if (p) { } 89c95a1fa7SDouglas Gregor } 90ce410662SJohn McCall 91ce410662SJohn McCall // PR5517 92ce410662SJohn McCall namespace test0 { 93ce410662SJohn McCall template <int K> struct X { Xtest0::X94ce410662SJohn McCall X() { extern void x(); } 95ce410662SJohn McCall }; g()96ce410662SJohn McCall void g() { X<2>(); } 97ce410662SJohn McCall } 98815039afSJohn McCall 99815039afSJohn McCall // <rdar://problem/8302161> 100815039afSJohn McCall namespace test1 { f(T const & t)101815039afSJohn McCall template <typename T> void f(T const &t) { 102815039afSJohn McCall union { char c; T t_; }; 103815039afSJohn McCall c = 'a'; // <- this shouldn't silently fail to instantiate 104815039afSJohn McCall T::foo(); // expected-error {{has no members}} 105815039afSJohn McCall } 106815039afSJohn McCall template void f(int const &); // expected-note {{requested here}} 107815039afSJohn McCall } 108*f623c962SRichard Smith 109*f623c962SRichard Smith namespace test2 { f()110*f623c962SRichard Smith template<typename T> void f() { 111*f623c962SRichard Smith T::error; // expected-error {{no member}} 112*f623c962SRichard Smith } g()113*f623c962SRichard Smith void g() { 114*f623c962SRichard Smith // This counts as an odr-use, so should trigger the instantiation of f<int>. 115*f623c962SRichard Smith (void)&f<int>; // expected-note {{here}} 116*f623c962SRichard Smith } 117*f623c962SRichard Smith } 118