1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
21fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregortemplate<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
31fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor                                                 // expected-note{{explicitly specialized}}
4cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
588b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<double, double>; // expected-note{{forward declaration}}
6cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
788b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<float, float> {  // expected-note{{previous definition}}
8cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  int x;
9cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor};
10cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1188b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<float> { // expected-note{{previous definition}}
12cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  int y;
13cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor};
14cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
15cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregorint test_specs(A<float, float> *a1, A<float, int> *a2) {
16cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  return a1->x + a2->y;
17cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor}
18cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
19cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregorint test_incomplete_specs(A<double, double> *a1,
202943aed177b33ae3f14273b11a7b398e5276ec62Douglas Gregor                          A<double> *a2)
21cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor{
2203c5705a99a96a471b2868898ee9688a6721e02aDouglas Gregor  (void)a1->x; // expected-error{{member access into incomplete type}}
237c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
24cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor}
25cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
26cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregortypedef float FLOAT;
27cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
2888b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<float, FLOAT>;
29cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
3088b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
31cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
3288b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct A<float, int> { }; // expected-error{{redefinition}}
33611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregor
3488b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<typename T, typename U = int> struct X;
35611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregor
3688b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate <> struct X<int, int> { int foo(); }; // #1
3788b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate <> struct X<float> { int bar(); };  // #2
38611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregor
39611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregortypedef int int_type;
40611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregorvoid testme(X<int_type> *x1, X<float, int> *x2) {
4165100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor  (void)x1->foo(); // okay: refers to #1
4265100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor  (void)x2->bar(); // okay: refers to #2
43611a8c49c6a5848aed17eced8f2f3f7b1b7577a1Douglas Gregor}
4439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
4565100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor// Make sure specializations are proper classes.
4665100792a69a16895bd80f1d639b99e7ad903386Douglas Gregortemplate<>
4765100792a69a16895bd80f1d639b99e7ad903386Douglas Gregorstruct A<char> {
4865100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor  A();
4965100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor};
5065100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor
5165100792a69a16895bd80f1d639b99e7ad903386Douglas GregorA<char>::A() { }
5265100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor
53db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor// Make sure we can see specializations defined before the primary template.
54db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregornamespace N{
55db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  template<typename T> struct A0;
56db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor}
57db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor
58db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregornamespace N {
59db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  template<>
60db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  struct A0<void> {
61db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor    typedef void* pointer;
62db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  };
63db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor}
64db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor
65db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregornamespace N {
66db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  template<typename T>
67db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  struct A0 {
68db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor    void foo(A0<void>::pointer p = 0);
69db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor  };
70db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor}
71db3a0f543e9a120d37823c6f2a2f1c693b69f2a1Douglas Gregor
7265100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor// Diagnose specialization errors
73972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas Gregorstruct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
7488b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
7588b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct ::A<double>;
7688b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
7788b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregornamespace N {
781fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor  template<typename T> struct B; // expected-note 2{{explicitly specialized}}
7988b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
806bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor  template<> struct ::N::B<char>; // okay
8188b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor  template<> struct ::N::B<short>; // okay
8288b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor  template<> struct ::N::B<int>; // okay
836bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor
846bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor  int f(int);
8588b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor}
8688b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
8788b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregortemplate<> struct N::B<int> { }; // okay
8888b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
89d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithtemplate<> struct N::B<float> { }; // expected-warning{{C++11 extension}}
9088b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
9188b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregornamespace M {
9288b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor  template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
9388b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<> struct ::A<long double>; // expected-error{{must occur at global scope}}
9588b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor}
966bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor
976bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregortemplate<> struct N::B<char> {
986bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor  int testf(int x) { return f(x); }
996bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor};
10065100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor
101972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas Gregor// PR5264
102972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas Gregortemplate <typename T> class Foo;
103972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas GregorFoo<int>* v;
104972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas GregorFoo<int>& F() { return *v; }
105972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas Gregortemplate <typename T> class Foo {};
106972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas GregorFoo<int> x;
1078b13c08b1a181b290600814c765f9f199a74f414Douglas Gregor
1088b13c08b1a181b290600814c765f9f199a74f414Douglas Gregor
1098b13c08b1a181b290600814c765f9f199a74f414Douglas Gregor// Template template parameters
1108b13c08b1a181b290600814c765f9f199a74f414Douglas Gregortemplate<template<class T> class Wibble>
1118b13c08b1a181b290600814c765f9f199a74f414Douglas Gregorclass Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
1128e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor
1138e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregornamespace rdar9676205 {
1148e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor  template<typename T>
1158e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor  struct X {
1168e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor    template<typename U>
1178e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor    struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
1188e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor    };
1198e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor  };
1208e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor
1218e0c118cb6c22c448ce502f3e00d01630192f095Douglas Gregor}
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace PR18009 {
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template <typename T> struct A {
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template <int N, int M> struct S;
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template <int N> struct S<N, sizeof(T)> {};
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  A<int>::S<8, sizeof(int)> a; // ok
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template <typename T> struct B {
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template <int N, int M> struct S; // expected-note {{declared here}}
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template <int N> struct S<N, sizeof(T) +
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        > {};
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<int A> struct outer {
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<int B, int C> struct inner {};
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<int C> struct inner<A * 2, C> {};
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace PR16519 {
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, T...N> struct integer_sequence { typedef T value_type; }; // expected-warning {{extension}}
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct __make_integer_sequence;
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, T N> using make_integer_sequence = typename __make_integer_sequence<T>::template make<N, N % 2>::type; // expected-warning {{extension}}
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, typename T::value_type ...Extra> struct __make_integer_sequence_impl; // expected-warning {{extension}}
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { // expected-warning 2{{extension}}
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct __make_integer_sequence {
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<T N, T Parity, typename = void> struct make;
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename Dummy> struct make<0, 0, Dummy> { typedef integer_sequence<T> type; };
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename Dummy> struct make<1, 1, Dummy> { typedef integer_sequence<T, 0> type; };
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<T N, typename Dummy> struct make<N, 0, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2> > {};
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<T N, typename Dummy> struct make<N, 1, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2>, N - 1> {};
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using X = make_integer_sequence<int, 5>; // expected-warning {{extension}}
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using X = integer_sequence<int, 0, 1, 2, 3, 4>; // expected-warning {{extension}}
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace DefaultArgVsPartialSpec {
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check that the diagnostic points at the partial specialization, not just at
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // the default argument.
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, int N =
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  > struct X {};
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T,
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      T N = 0 // expected-note {{template parameter is declared here}}
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  > struct S;
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
180