// RUN: %clang_cc1 -fsyntax-only -verify %s namespace N { struct Outer { struct Inner { template<typename T> struct InnerTemplate { struct VeryInner { typedef T type; static enum K1 { K1Val = sizeof(T) } Kind1; static enum { K2Val = sizeof(T)*2 } Kind2; enum { K3Val = sizeof(T)*2 } Kind3; void foo() { K1 k1 = K1Val; Kind1 = K1Val; Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; Kind3 = K3Val; } struct UeberInner { void bar() { K1 k1 = K1Val; Kind1 = K1Val; Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val; InnerTemplate t; InnerTemplate<type> t2; } }; }; }; }; }; } typedef int INT; template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner; template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}} namespace N2 { struct Outer2 { template<typename T, typename U = T> struct Inner { void foo() { enum { K1Val = sizeof(T) } k1; enum K2 { K2Val = sizeof(T)*2 } k2a; K2 k2b = K2Val; struct S { T x, y; } s1; struct { U x, y; } s2; s1.x = s2.x; // expected-error{{incompatible}} typedef T type; type t2 = s1.x; typedef struct { T z; } type2; type2 t3 = { s1.x }; Inner i1; i1.foo(); Inner<T> i2; i2.foo(); } }; }; } template struct N2::Outer2::Inner<float>; template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}} // Test dependent pointer-to-member expressions. template<typename T> struct smart_ptr { struct safe_bool { int member; }; operator int safe_bool::*() const { return ptr? &safe_bool::member : 0; } T* ptr; }; void test_smart_ptr(smart_ptr<int> p) { if (p) { } } // PR5517 namespace test0 { template <int K> struct X { X() { extern void x(); } }; void g() { X<2>(); } } // <rdar://problem/8302161> namespace test1 { template <typename T> void f(T const &t) { union { char c; T t_; }; c = 'a'; // <- this shouldn't silently fail to instantiate T::foo(); // expected-error {{has no members}} } template void f(int const &); // expected-note {{requested here}} } namespace test2 { template<typename T> void f() { T::error; // expected-error {{no member}} } void g() { // This counts as an odr-use, so should trigger the instantiation of f<int>. (void)&f<int>; // expected-note {{here}} } }