xref: /aosp_15_r20/external/clang/test/SemaTemplate/nested-template.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li class A;
3*67e74705SXin Li 
4*67e74705SXin Li class S {
5*67e74705SXin Li public:
6*67e74705SXin Li    template<typename T> struct A {
7*67e74705SXin Li      struct Nested {
8*67e74705SXin Li        typedef T type;
9*67e74705SXin Li      };
10*67e74705SXin Li    };
11*67e74705SXin Li };
12*67e74705SXin Li 
13*67e74705SXin Li int i;
14*67e74705SXin Li S::A<int>::Nested::type *ip = &i;
15*67e74705SXin Li 
16*67e74705SXin Li template<typename T>
17*67e74705SXin Li struct Outer {
18*67e74705SXin Li   template<typename U>
19*67e74705SXin Li   class Inner0;
20*67e74705SXin Li 
21*67e74705SXin Li   template<typename U>
22*67e74705SXin Li   class Inner1 {
23*67e74705SXin Li     struct ReallyInner;
24*67e74705SXin Li 
25*67e74705SXin Li     T foo(U);
26*67e74705SXin Li     template<typename V> T bar(V);
27*67e74705SXin Li     template<typename V> T* bar(V);
28*67e74705SXin Li 
29*67e74705SXin Li     static T value1;
30*67e74705SXin Li     static U value2;
31*67e74705SXin Li   };
32*67e74705SXin Li };
33*67e74705SXin Li 
34*67e74705SXin Li template<typename X>
35*67e74705SXin Li template<typename Y>
36*67e74705SXin Li class Outer<X>::Inner0 {
37*67e74705SXin Li public:
38*67e74705SXin Li   void f(X, Y);
39*67e74705SXin Li };
40*67e74705SXin Li 
41*67e74705SXin Li template<typename X>
42*67e74705SXin Li template<typename Y>
f(X,Y)43*67e74705SXin Li void Outer<X>::Inner0<Y>::f(X, Y) {
44*67e74705SXin Li }
45*67e74705SXin Li 
46*67e74705SXin Li template<typename X>
47*67e74705SXin Li template<typename Y>
48*67e74705SXin Li struct Outer<X>::Inner1<Y>::ReallyInner {
49*67e74705SXin Li   static Y value3;
50*67e74705SXin Li 
51*67e74705SXin Li   void g(X, Y);
52*67e74705SXin Li };
53*67e74705SXin Li 
54*67e74705SXin Li template<typename X>
55*67e74705SXin Li template<typename Y>
g(X,Y)56*67e74705SXin Li void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) {
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li template<typename X>
60*67e74705SXin Li template<typename Y>
foo(Y)61*67e74705SXin Li X Outer<X>::Inner1<Y>::foo(Y) {
62*67e74705SXin Li   return X();
63*67e74705SXin Li }
64*67e74705SXin Li 
65*67e74705SXin Li template<typename X>
66*67e74705SXin Li template<typename Y>
67*67e74705SXin Li template<typename Z>
bar(Z)68*67e74705SXin Li X Outer<X>::Inner1<Y>::bar(Z) {
69*67e74705SXin Li   return X();
70*67e74705SXin Li }
71*67e74705SXin Li 
72*67e74705SXin Li template<typename X>
73*67e74705SXin Li template<typename Y>
74*67e74705SXin Li template<typename Z>
bar(Z)75*67e74705SXin Li X* Outer<X>::Inner1<Y>::bar(Z) {
76*67e74705SXin Li   return 0;
77*67e74705SXin Li }
78*67e74705SXin Li 
79*67e74705SXin Li template<typename X>
80*67e74705SXin Li template<typename Y>
81*67e74705SXin Li X Outer<X>::Inner1<Y>::value1 = 0;
82*67e74705SXin Li 
83*67e74705SXin Li template<typename X>
84*67e74705SXin Li template<typename Y>
85*67e74705SXin Li Y Outer<X>::Inner1<Y>::value2 = Y();
86*67e74705SXin Li 
87*67e74705SXin Li template<typename X>
88*67e74705SXin Li template<typename Y>
89*67e74705SXin Li Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
90*67e74705SXin Li 
91*67e74705SXin Li template<typename X>
92*67e74705SXin Li template<typename Y>
93*67e74705SXin Li Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
94*67e74705SXin Li 
95*67e74705SXin Li 
96*67e74705SXin Li template<typename T>
97*67e74705SXin Li struct X0 { };
98*67e74705SXin Li 
99*67e74705SXin Li template<typename T>
100*67e74705SXin Li struct X0<T*> {
101*67e74705SXin Li   template<typename U>
fX0102*67e74705SXin Li   void f(U u = T()) { }
103*67e74705SXin Li };
104*67e74705SXin Li 
105*67e74705SXin Li // PR5103
106*67e74705SXin Li template<typename>
107*67e74705SXin Li struct X1 {
108*67e74705SXin Li   template<typename, bool = false> struct B { };
109*67e74705SXin Li };
110*67e74705SXin Li template struct X1<int>::B<bool>;
111*67e74705SXin Li 
112*67e74705SXin Li // Template template parameters
113*67e74705SXin Li template<typename T>
114*67e74705SXin Li struct X2 {
115*67e74705SXin Li   template<template<class U, T Value> class>  // expected-error{{cannot have type 'float'}} \
116*67e74705SXin Li                                               // expected-note{{previous non-type template}}
117*67e74705SXin Li     struct Inner { };
118*67e74705SXin Li };
119*67e74705SXin Li 
120*67e74705SXin Li template<typename T,
121*67e74705SXin Li          int Value> // expected-note{{template non-type parameter}}
122*67e74705SXin Li   struct X2_arg;
123*67e74705SXin Li 
124*67e74705SXin Li X2<int>::Inner<X2_arg> x2i1;
125*67e74705SXin Li X2<float> x2a; // expected-note{{instantiation}}
126*67e74705SXin Li X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
127*67e74705SXin Li 
128*67e74705SXin Li namespace PR10896 {
129*67e74705SXin Li   template<typename TN>
130*67e74705SXin Li   class Foo {
131*67e74705SXin Li 
132*67e74705SXin Li   public:
foo()133*67e74705SXin Li     void foo() {}
134*67e74705SXin Li   private:
135*67e74705SXin Li 
136*67e74705SXin Li     template<typename T>
137*67e74705SXin Li     T SomeField; // expected-error {{member 'SomeField' declared as a template}}
138*67e74705SXin Li     template<> int SomeField2; // expected-error {{extraneous 'template<>' in declaration of member 'SomeField2'}}
139*67e74705SXin Li   };
140*67e74705SXin Li 
g()141*67e74705SXin Li   void g() {
142*67e74705SXin Li     Foo<int> f;
143*67e74705SXin Li     f.foo();
144*67e74705SXin Li   }
145*67e74705SXin Li }
146*67e74705SXin Li 
147*67e74705SXin Li namespace PR10924 {
148*67e74705SXin Li   template< class Topology, class ctype >
149*67e74705SXin Li   struct ReferenceElement
150*67e74705SXin Li   {
151*67e74705SXin Li   };
152*67e74705SXin Li 
153*67e74705SXin Li   template< class Topology, class ctype >
154*67e74705SXin Li   template< int codim >
155*67e74705SXin Li   class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'ReferenceElement<Topology, ctype>'}}
156*67e74705SXin Li   {
157*67e74705SXin Li   };
158*67e74705SXin Li }
159*67e74705SXin Li 
160*67e74705SXin Li class Outer1 {
161*67e74705SXin Li     template <typename T> struct X;
func()162*67e74705SXin Li     template <typename T> int X<T>::func() {} //  expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
163*67e74705SXin Li };
164