blob: 3f49606b86e55932d281b1dbe25ccfc1beb19d40 [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;
John McCall22432882010-03-26 21:56:38 +000094 };
95 template class B<int>;
96
97 template <typename T> class C {
98 class Foo;
John McCall22432882010-03-26 21:56:38 +000099 };
100 template <typename T> class C<T>::Foo {
101 int x;
102 };
103 template class C<int>;
104}
Richard Smithc89edf52011-07-01 19:46:12 +0000105
106namespace AliasTagDef {
107 template<typename T>
108 struct F {
Douglas Gregorb3df1382011-10-12 19:26:40 +0000109 using S = struct U { // expected-warning {{C++11}}
Richard Smithc89edf52011-07-01 19:46:12 +0000110 T g() {
111 return T();
112 }
113 };
114 };
115
116 int m = F<int>::S().g();
117 int n = F<int>::U().g();
118}
Douglas Gregorefaa93a2011-11-07 17:33:42 +0000119
120namespace rdar10397846 {
121 template<int I> struct A
122 {
123 struct B
124 {
David Blaikie50800fc2012-08-08 17:33:31 +0000125 struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \
126 expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
Douglas Gregorefaa93a2011-11-07 17:33:42 +0000127 };
128 };
129
130 template<int N> void foo()
131 {
David Blaikie50800fc2012-08-08 17:33:31 +0000132 class A<N>::B::C X; // expected-note 2 {{in instantiation of member function}}
Douglas Gregorefaa93a2011-11-07 17:33:42 +0000133 int A<N+1>::B::C::*member = 0;
134 }
135
136 void bar()
137 {
David Blaikie50800fc2012-08-08 17:33:31 +0000138 foo<0>(); // expected-note{{in instantiation of function template}}
Douglas Gregorefaa93a2011-11-07 17:33:42 +0000139 foo<1>(); // expected-note{{in instantiation of function template}}
140 }
141}