blob: 74c2609dcd0f3ed160364d33311c953c87f0f343 [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregord475b8d2009-03-25 21:17:03 +00002
Douglas Gregoreff1dbe2011-03-06 20:12:45 +00003namespace 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
Douglas Gregord475b8d2009-03-25 21:17:03 +000026template<typename T>
27class X {
28public:
29 struct C { T &foo(); };
30
31 struct D {
Douglas Gregord048bb72009-03-25 21:23:52 +000032 struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000033 struct F; // expected-note{{member is declared here}}
34 };
35};
36
37X<int>::C *c1;
38X<float>::C *c2;
39
Douglas Gregor0efc2c12010-01-13 17:31:36 +000040X<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}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000042
43void test_naming() {
Douglas Gregord4eea832010-04-09 00:35:39 +000044 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> *'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000046 // 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();
John McCall7c2342d2010-03-10 11:27:22 +000054 f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000055
56}
Douglas Gregord048bb72009-03-25 21:23:52 +000057
58
59X<void>::C *c3; // okay
60X<void>::D::E *e1; // okay
John McCall7c2342d2010-03-10 11:27:22 +000061X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
John McCall6c1c1b82009-12-15 22:29:06 +000062
63// Redeclarations.
64namespace test1 {
65 template <typename T> struct Registry {
John McCall7002f4c2010-04-09 19:03:51 +000066 struct node;
John McCall6c1c1b82009-12-15 22:29:06 +000067 static node *Head;
John McCall7002f4c2010-04-09 19:03:51 +000068 struct node {
John McCall6c1c1b82009-12-15 22:29:06 +000069 node(int v) { Head = this; }
70 };
71 };
72 void test() {
73 Registry<int>::node node(0);
74 }
75}
John McCall22432882010-03-26 21:56:38 +000076
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 {
John McCall7002f4c2010-04-09 19:03:51 +000090 public:
John McCall22432882010-03-26 21:56:38 +000091 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}