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