1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3namespace PR8965 { 4 template<typename T> 5 struct X { 6 typedef int type; 7 8 T field; // expected-note{{in instantiation of member class}} 9 }; 10 11 template<typename T> 12 struct Y { 13 struct Inner; 14 15 typedef typename X<Inner>::type // expected-note{{in instantiation of template class}} 16 type; // expected-note{{not-yet-instantiated member is declared here}} 17 18 struct Inner { 19 typedef type field; // expected-error{{no member 'type' in 'PR8965::Y<int>'; it has not yet been instantiated}} 20 }; 21 }; 22 23 Y<int> y; // expected-note{{in instantiation of template class}} 24} 25 26template<typename T> 27class X { 28public: 29 struct C { T &foo(); }; 30 31 struct D { 32 struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}} 33 struct F; // expected-note{{member is declared here}} 34 }; 35}; 36 37X<int>::C *c1; 38X<float>::C *c2; 39 40X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} 41X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} 42 43void test_naming() { 44 c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}} 45 xi = xf; // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}} 46 // FIXME: error above doesn't print the type X<int>::X cleanly! 47} 48 49void test_instantiation(X<double>::C *x, 50 X<float>::D::E *e, 51 X<float>::D::F *f) { 52 double &dr = x->foo(); 53 float &fr = e->bar(); 54 f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}} 55 56} 57 58 59X<void>::C *c3; // okay 60X<void>::D::E *e1; // okay 61X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}} 62 63// Redeclarations. 64namespace test1 { 65 template <typename T> struct Registry { 66 struct node; 67 static node *Head; 68 struct node { 69 node(int v) { Head = this; } 70 }; 71 }; 72 void test() { 73 Registry<int>::node node(0); 74 } 75} 76 77// Redeclarations during explicit instantiations. 78namespace test2 { 79 template <typename T> class A { 80 class Foo; 81 class Foo { 82 int foo(); 83 }; 84 }; 85 template class A<int>; 86 87 template <typename T> class B { 88 class Foo; 89 class Foo { 90 public: 91 typedef int X; 92 }; 93 typename Foo::X x; 94 class Foo; 95 }; 96 template class B<int>; 97 98 template <typename T> class C { 99 class Foo; 100 class Foo; 101 }; 102 template <typename T> class C<T>::Foo { 103 int x; 104 }; 105 template class C<int>; 106} 107 108namespace AliasTagDef { 109 template<typename T> 110 struct F { 111 using S = struct U { // expected-warning {{C++11}} 112 T g() { 113 return T(); 114 } 115 }; 116 }; 117 118 int m = F<int>::S().g(); 119 int n = F<int>::U().g(); 120} 121 122namespace rdar10397846 { 123 template<int I> struct A 124 { 125 struct B 126 { 127 struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} 128 }; 129 }; 130 131 template<int N> void foo() 132 { 133 class A<N>::B::C X; // expected-note{{in instantiation of member function}} 134 int A<N+1>::B::C::*member = 0; 135 } 136 137 void bar() 138 { 139 foo<0>(); 140 foo<1>(); // expected-note{{in instantiation of function template}} 141 } 142} 143