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