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