xref: /aosp_15_r20/external/clang/test/SemaTemplate/nested-name-spec-template.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 N {
6*67e74705SXin Li   namespace M {
7*67e74705SXin Li     template<typename T> struct Promote;
8*67e74705SXin Li 
9*67e74705SXin Li     template<> struct Promote<short> {
10*67e74705SXin Li       typedef int type;
11*67e74705SXin Li     };
12*67e74705SXin Li 
13*67e74705SXin Li     template<> struct Promote<int> {
14*67e74705SXin Li       typedef int type;
15*67e74705SXin Li     };
16*67e74705SXin Li 
17*67e74705SXin Li     template<> struct Promote<float> {
18*67e74705SXin Li       typedef double type;
19*67e74705SXin Li     };
20*67e74705SXin Li 
ret_intptr(int * ip)21*67e74705SXin Li     Promote<short>::type *ret_intptr(int* ip) { return ip; }
ret_intptr2(int * ip)22*67e74705SXin Li     Promote<int>::type *ret_intptr2(int* ip) { return ip; }
23*67e74705SXin Li   }
24*67e74705SXin Li 
ret_intptr3(int * ip)25*67e74705SXin Li   M::Promote<int>::type *ret_intptr3(int* ip) { return ip; }
ret_intptr4(int * ip)26*67e74705SXin Li   M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; }
27*67e74705SXin Li #if __cplusplus <= 199711L
28*67e74705SXin Li   // expected-warning@-2 {{'template' keyword outside of a template}}
29*67e74705SXin Li #endif
30*67e74705SXin Li 
31*67e74705SXin Li   M::template Promote<int> pi;
32*67e74705SXin Li #if __cplusplus <= 199711L
33*67e74705SXin Li   // expected-warning@-2 {{'template' keyword outside of a template}}
34*67e74705SXin Li #endif
35*67e74705SXin Li }
36*67e74705SXin Li 
ret_intptr5(int * ip)37*67e74705SXin Li N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }
ret_intptr6(int * ip)38*67e74705SXin Li ::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; }
39*67e74705SXin Li 
40*67e74705SXin Li 
41*67e74705SXin Li N::M::template; // expected-error{{expected unqualified-id}}
42*67e74705SXin Li N::M::template Promote; // expected-error{{expected unqualified-id}}
43*67e74705SXin Li 
44*67e74705SXin Li namespace N {
45*67e74705SXin Li   template<typename T> struct A;
46*67e74705SXin Li 
47*67e74705SXin Li   template<>
48*67e74705SXin Li   struct A<int> {
49*67e74705SXin Li     struct X;
50*67e74705SXin Li   };
51*67e74705SXin Li 
52*67e74705SXin Li   struct B;
53*67e74705SXin Li }
54*67e74705SXin Li 
55*67e74705SXin Li struct ::N::A<int>::X {
56*67e74705SXin Li   int foo;
57*67e74705SXin Li };
58*67e74705SXin Li 
59*67e74705SXin Li template<typename T>
60*67e74705SXin Li struct TestA {
61*67e74705SXin Li   typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
62*67e74705SXin Li                                                 // expected-error{{expected member name}}
63*67e74705SXin Li };
64*67e74705SXin Li 
65*67e74705SXin Li // Reduced from a Boost failure.
66*67e74705SXin Li namespace test1 {
67*67e74705SXin Li   template <class T> struct pair {
68*67e74705SXin Li     T x;
69*67e74705SXin Li     T y;
70*67e74705SXin Li 
71*67e74705SXin Li     static T pair<T>::* const mem_array[2];
72*67e74705SXin Li   };
73*67e74705SXin Li 
74*67e74705SXin Li   template <class T>
75*67e74705SXin Li   T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y };
76*67e74705SXin Li }
77*67e74705SXin Li 
78*67e74705SXin Li typedef int T;
79*67e74705SXin Li namespace N1 {
80*67e74705SXin Li   template<typename T> T f0();
81*67e74705SXin Li }
82*67e74705SXin Li 
f0()83*67e74705SXin Li template<typename T> T N1::f0() { }
84*67e74705SXin Li 
85*67e74705SXin Li namespace PR7385 {
86*67e74705SXin Li   template< typename > struct has_xxx0
87*67e74705SXin Li   {
88*67e74705SXin Li     template< typename > struct has_xxx0_introspect
89*67e74705SXin Li     {
90*67e74705SXin Li       template< typename > struct has_xxx0_substitute ;
91*67e74705SXin Li       template< typename V >
92*67e74705SXin Li       int int00( has_xxx0_substitute < typename V::template xxx< > > = 0 );
93*67e74705SXin Li     };
94*67e74705SXin Li     static const int value = has_xxx0_introspect<int>::value; // expected-error{{no member named 'value'}}
95*67e74705SXin Li     typedef int type;
96*67e74705SXin Li   };
97*67e74705SXin Li 
98*67e74705SXin Li   has_xxx0<int>::type t; // expected-note{{instantiation of}}
99*67e74705SXin Li }
100*67e74705SXin Li 
101*67e74705SXin Li namespace PR7725 {
102*67e74705SXin Li   template<class ignored> struct TypedefProvider;
103*67e74705SXin Li   template<typename T>
104*67e74705SXin Li   struct TemplateClass : public TypedefProvider<T>
105*67e74705SXin Li   {
PrintSelfPR7725::TemplateClass106*67e74705SXin Li     void PrintSelf() {
107*67e74705SXin Li       TemplateClass::Test::PrintSelf();
108*67e74705SXin Li     }
109*67e74705SXin Li   };
110*67e74705SXin Li }
111*67e74705SXin Li 
112*67e74705SXin Li namespace PR9226 {
113*67e74705SXin Li   template<typename a>
nt()114*67e74705SXin Li   void nt() // expected-note{{function template 'nt' declared here}}
115*67e74705SXin Li   { nt<>:: } // expected-error{{qualified name refers into a specialization of function template 'nt'}} \
116*67e74705SXin Li   // expected-error{{expected unqualified-id}}
117*67e74705SXin Li 
118*67e74705SXin Li   template<typename T>
119*67e74705SXin Li   void f(T*); // expected-note{{function template 'f' declared here}}
120*67e74705SXin Li 
121*67e74705SXin Li   template<typename T>
122*67e74705SXin Li   void f(T*, T*); // expected-note{{function template 'f' declared here}}
123*67e74705SXin Li 
g()124*67e74705SXin Li   void g() {
125*67e74705SXin Li     f<int>:: // expected-error{{qualified name refers into a specialization of function template 'f'}}
126*67e74705SXin Li   } // expected-error{{expected unqualified-id}}
127*67e74705SXin Li 
128*67e74705SXin Li   struct X {
129*67e74705SXin Li     template<typename T> void f(); // expected-note{{function template 'f' declared here}}
130*67e74705SXin Li   };
131*67e74705SXin Li 
132*67e74705SXin Li   template<typename T, typename U>
133*67e74705SXin Li   struct Y {
134*67e74705SXin Li     typedef typename T::template f<U> type; // expected-error{{template name refers to non-type template 'X::f'}}
135*67e74705SXin Li   };
136*67e74705SXin Li 
137*67e74705SXin Li   Y<X, int> yxi; // expected-note{{in instantiation of template class 'PR9226::Y<PR9226::X, int>' requested here}}
138*67e74705SXin Li }
139*67e74705SXin Li 
140*67e74705SXin Li namespace PR9449 {
141*67e74705SXin Li   template <typename T>
142*67e74705SXin Li   struct s; // expected-note{{template is declared here}}
143*67e74705SXin Li 
144*67e74705SXin Li   template <typename T>
f()145*67e74705SXin Li   void f() {
146*67e74705SXin Li     int s<T>::template n<T>::* f; // expected-error{{implicit instantiation of undefined template 'PR9449::s<int>'}} \
147*67e74705SXin Li     // expected-error{{following the 'template' keyword}}
148*67e74705SXin Li   }
149*67e74705SXin Li 
150*67e74705SXin Li   template void f<int>(); // expected-note{{in instantiation of}}
151*67e74705SXin Li }
152