blob: f1bdf3e1e6d5a684a784eeacff6bdaf8cd15e0fe [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
3template<typename T>
4class X {
5public:
6 struct C { T &foo(); };
7
8 struct D {
Douglas Gregord048bb72009-03-25 21:23:52 +00009 struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000010 struct F; // expected-note{{member is declared here}}
11 };
12};
13
14X<int>::C *c1;
15X<float>::C *c2;
16
Douglas Gregor0efc2c12010-01-13 17:31:36 +000017X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
18X<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 +000019
20void test_naming() {
Douglas Gregord4eea832010-04-09 00:35:39 +000021 c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}}
22 xi = xf; // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000023 // FIXME: error above doesn't print the type X<int>::X cleanly!
24}
25
26void test_instantiation(X<double>::C *x,
27 X<float>::D::E *e,
28 X<float>::D::F *f) {
29 double &dr = x->foo();
30 float &fr = e->bar();
John McCall7c2342d2010-03-10 11:27:22 +000031 f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
Douglas Gregord475b8d2009-03-25 21:17:03 +000032
33}
Douglas Gregord048bb72009-03-25 21:23:52 +000034
35
36X<void>::C *c3; // okay
37X<void>::D::E *e1; // okay
John McCall7c2342d2010-03-10 11:27:22 +000038X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
John McCall6c1c1b82009-12-15 22:29:06 +000039
40// Redeclarations.
41namespace test1 {
42 template <typename T> struct Registry {
John McCall7002f4c2010-04-09 19:03:51 +000043 struct node;
John McCall6c1c1b82009-12-15 22:29:06 +000044 static node *Head;
John McCall7002f4c2010-04-09 19:03:51 +000045 struct node {
John McCall6c1c1b82009-12-15 22:29:06 +000046 node(int v) { Head = this; }
47 };
48 };
49 void test() {
50 Registry<int>::node node(0);
51 }
52}
John McCall22432882010-03-26 21:56:38 +000053
54// Redeclarations during explicit instantiations.
55namespace test2 {
56 template <typename T> class A {
57 class Foo;
58 class Foo {
59 int foo();
60 };
61 };
62 template class A<int>;
63
64 template <typename T> class B {
65 class Foo;
66 class Foo {
John McCall7002f4c2010-04-09 19:03:51 +000067 public:
John McCall22432882010-03-26 21:56:38 +000068 typedef int X;
69 };
70 typename Foo::X x;
71 class Foo;
72 };
73 template class B<int>;
74
75 template <typename T> class C {
76 class Foo;
77 class Foo;
78 };
79 template <typename T> class C<T>::Foo {
80 int x;
81 };
82 template class C<int>;
83}