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