xref: /llvm-project/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp (revision 972fe534ed33dbb10a26b527f69f19c677722277)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 namespace PR5907 {
4   template<typename T> struct identity { typedef T type; };
5   struct A { A(); };
6   identity<A>::type::A() { }
7 
8   struct B { void f(); };
9   template<typename T> struct C { typedef B type; };
10 
11   void C<int>::type::f() { }
12 }
13 
14 namespace PR9421 {
15   namespace N { template<typename T> struct S { void f(); }; }
16   typedef N::S<int> T;
17   namespace N { template<> void T::f() {} }
18 }
19 
20 namespace PR8277 {
21   template< typename S >
22   struct C
23   {
24     template< int >
25     void F( void )
26     {
27     }
28   };
29 
30   template< typename S >
31   struct D
32   {
33     typedef C< int > A;
34   };
35 
36   typedef D< int >::A A;
37 
38   template<>
39   template<>
40   void A::F< 0 >( void )
41   {
42   }
43 }
44 
45 namespace PR8277b {
46   template<typename S> struct C {
47     void f();
48   };
49   template<typename S> struct D {
50     typedef C<int> A;
51   };
52   template<> void D<int>::A::f() {
53   }
54 }
55 
56 namespace PR8708 {
57   template<typename T> struct A {
58     template<typename U> struct B {
59       // #2
60       void f();
61     };
62   };
63 
64   // #A specialize the member template for
65   // implicit instantiation of A<int>,
66   // leaving the member template "unspecialized"
67   // (14.7.3/16). Specialization uses the syntax
68   // for explicit specialization (14.7.3/14)
69   template<> template<typename U>
70   struct A<int>::B {
71     // #1
72     void g();
73   };
74 
75   // #1 define its function g. There is an enclosing
76   // class template, so we write template<> for each
77   // specialized template (14.7.3/15).
78   template<> template<typename U>
79   void A<int>::B<U>::g() { }
80 
81   // #2 define the unspecialized member template's
82   // f
83   template<typename T> template<typename U>
84   void A<T>::B<U>::f() { }
85 
86 
87   // specialize the member template again, now
88   // specializing the member too. This specializes
89   // #A
90   template<> template<>
91   struct A<int>::B<int> {
92     // #3
93     void h();
94   };
95 
96   // defines #3. There is no enclosing class template, so
97   // we write no "template<>".
98   void A<int>::B<int>::h() { }
99 
100   void test() {
101     // calls #1
102     A<int>::B<float> a; a.g();
103 
104     // calls #2
105     A<float>::B<int> b; b.f();
106 
107     // calls #3
108     A<int>::B<int> c; c.h();
109   }
110 }
111 
112 namespace PR9482 {
113   namespace N1 {
114     template <typename T> struct S {
115       void foo() {}
116     };
117   }
118 
119   namespace N2 {
120     typedef N1::S<int> X;
121   }
122 
123   namespace N1 {
124     template<> void N2::X::foo() {}
125   }
126 }
127 
128 namespace PR9668 {
129   namespace First
130   {
131     template<class T>
132     class Bar
133     {
134     protected:
135 
136       static const bool static_bool;
137     };
138   }
139 
140   namespace Second
141   {
142     class Foo;
143   }
144 
145   typedef First::Bar<Second::Foo> Special;
146 
147   namespace
148   First
149   {
150     template<>
151     const bool Special::static_bool(false);
152   }
153 }
154 
155 namespace PR9877 {
156   template<int>
157   struct X
158   {
159     struct Y;
160   };
161 
162   template<> struct X<0>::Y { static const int Z = 1; };
163   template<> struct X<1>::Y { static const int Z = 1; };
164 
165   const int X<0>::Y::Z;
166   template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
167 }
168