1*0333dd95SReid Kleckner template<typename T, class P>
2*0333dd95SReid Kleckner struct TwoOptionTemplate {};
3*0333dd95SReid Kleckner 
4*0333dd95SReid Kleckner template<typename T>
5*0333dd95SReid Kleckner struct TwoOptionTemplate<T, char> {
6*0333dd95SReid Kleckner   int member;
7*0333dd95SReid Kleckner };
8*0333dd95SReid Kleckner 
9*0333dd95SReid Kleckner 
10*0333dd95SReid Kleckner template<typename T>
11*0333dd95SReid Kleckner struct TwoOptionTemplate<T, double> {
12*0333dd95SReid Kleckner   float member;
13*0333dd95SReid Kleckner };
14*0333dd95SReid Kleckner 
15*0333dd95SReid Kleckner template<typename T>
16*0333dd95SReid Kleckner struct TwoOptionTemplate<T, T> {
17*0333dd95SReid Kleckner   T** member;
18*0333dd95SReid Kleckner };
19*0333dd95SReid Kleckner 
20*0333dd95SReid Kleckner TwoOptionTemplate<int, char> X0;
21*0333dd95SReid Kleckner TwoOptionTemplate<int, float> X1;
22*0333dd95SReid Kleckner TwoOptionTemplate<void *, wchar_t> X2;
23*0333dd95SReid Kleckner TwoOptionTemplate<long, long> X3;
24*0333dd95SReid Kleckner TwoOptionTemplate<float, float> X4;
25*0333dd95SReid Kleckner TwoOptionTemplate<long, long> SingleSource;
26*0333dd95SReid Kleckner TwoOptionTemplate<char, double> SecondDoubleSource;
27*0333dd95SReid Kleckner 
28*0333dd95SReid Kleckner 
29*0333dd95SReid Kleckner template<int I, class C>
30*0333dd95SReid Kleckner struct IntTemplateSpec {};
31*0333dd95SReid Kleckner 
32*0333dd95SReid Kleckner template<class C>
33*0333dd95SReid Kleckner struct IntTemplateSpec<4, C> {
34*0333dd95SReid Kleckner   C member;
35*0333dd95SReid Kleckner };
36*0333dd95SReid Kleckner 
37*0333dd95SReid Kleckner template<int I>
38*0333dd95SReid Kleckner struct IntTemplateSpec<I, void *> {
39*0333dd95SReid Kleckner   int member;
40*0333dd95SReid Kleckner   static constexpr int val = I;
41*0333dd95SReid Kleckner };
42*0333dd95SReid Kleckner 
43*0333dd95SReid Kleckner template<int I>
44*0333dd95SReid Kleckner struct IntTemplateSpec<I, double> {
45*0333dd95SReid Kleckner   char member;
46*0333dd95SReid Kleckner   static constexpr int val = I;
47*0333dd95SReid Kleckner };
48*0333dd95SReid Kleckner 
49*0333dd95SReid Kleckner IntTemplateSpec<4, wchar_t> Y0;
50*0333dd95SReid Kleckner IntTemplateSpec<5, void *> Y1;
51*0333dd95SReid Kleckner IntTemplateSpec<1, long> Y2;
52*0333dd95SReid Kleckner IntTemplateSpec<3, int> Y3;
53*0333dd95SReid Kleckner //template<int I> constexpr int IntTemplateSpec<I, double>::val;
54*0333dd95SReid Kleckner IntTemplateSpec<42, double> NumberSource;
55*0333dd95SReid Kleckner static_assert(NumberSource.val == 42);
56*0333dd95SReid Kleckner 
57*0333dd95SReid Kleckner namespace One {
58*0333dd95SReid Kleckner namespace Two {
59*0333dd95SReid Kleckner   // Just an empty namespace to ensure we can deal with multiple namespace decls.
60*0333dd95SReid Kleckner }
61*0333dd95SReid Kleckner }
62*0333dd95SReid Kleckner 
63*0333dd95SReid Kleckner 
64*0333dd95SReid Kleckner namespace One {
65*0333dd95SReid Kleckner namespace Two {
66*0333dd95SReid Kleckner namespace Three {
67*0333dd95SReid Kleckner 
68*0333dd95SReid Kleckner template<class T>
69*0333dd95SReid Kleckner class Parent {};
70*0333dd95SReid Kleckner 
71*0333dd95SReid Kleckner } // namespace Three
72*0333dd95SReid Kleckner 
73*0333dd95SReid Kleckner } // namespace Two
74*0333dd95SReid Kleckner 
75*0333dd95SReid Kleckner template<typename T, typename X>
76*0333dd95SReid Kleckner struct Child1: public Two::Three::Parent<unsigned> {
77*0333dd95SReid Kleckner   char member;
78*0333dd95SReid Kleckner };
79*0333dd95SReid Kleckner 
80*0333dd95SReid Kleckner template<class T>
81*0333dd95SReid Kleckner struct Child1<T, One::Two::Three::Parent<T>> {
82*0333dd95SReid Kleckner   T member;
83*0333dd95SReid Kleckner };
84*0333dd95SReid Kleckner 
85*0333dd95SReid Kleckner } // namespace One
86*0333dd95SReid Kleckner 
87*0333dd95SReid Kleckner One::Child1<int, double> Z0Source;
88*0333dd95SReid Kleckner 
89*0333dd95SReid Kleckner // Test import of nested namespace specifiers
90*0333dd95SReid Kleckner template<typename T>
91*0333dd95SReid Kleckner struct Outer {
92*0333dd95SReid Kleckner   template<typename U> class Inner0;
93*0333dd95SReid Kleckner };
94*0333dd95SReid Kleckner 
95*0333dd95SReid Kleckner template<typename X>
96*0333dd95SReid Kleckner template<typename Y>
97*0333dd95SReid Kleckner class Outer<X>::Inner0 {
98*0333dd95SReid Kleckner public:
99*0333dd95SReid Kleckner   void f(X, Y);
100*0333dd95SReid Kleckner   template<typename Z> struct Inner1;
101*0333dd95SReid Kleckner };
102*0333dd95SReid Kleckner 
103*0333dd95SReid Kleckner template<typename X>
104*0333dd95SReid Kleckner template<typename Y>
f(X,Y)105*0333dd95SReid Kleckner void Outer<X>::Inner0<Y>::f(X, Y) {}
106*0333dd95SReid Kleckner 
107*0333dd95SReid Kleckner template<typename X>
108*0333dd95SReid Kleckner template<typename Y>
109*0333dd95SReid Kleckner template<typename Z>
110*0333dd95SReid Kleckner class Outer<X>::Inner0<Y>::Inner1 {
111*0333dd95SReid Kleckner public:
112*0333dd95SReid Kleckner   void f(Y, Z);
113*0333dd95SReid Kleckner };
114*0333dd95SReid Kleckner 
115*0333dd95SReid Kleckner template<typename X>
116*0333dd95SReid Kleckner template<typename Y>
117*0333dd95SReid Kleckner template<typename Z>
f(Y,Z)118*0333dd95SReid Kleckner void Outer<X>::Inner0<Y>::Inner1<Z>::f(Y, Z) {}
119