class-template-spec.cpp revision 1fef4e60e7e884803977a8376c172ea584f8a5d1
1d7d5f0223bd30dfd618762349c6209dd1d5ea3e6Daniel Dunbar// RUN: clang-cc -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{ 22cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}} 2398137534e612c274ba270af99d73429043957e53Douglas Gregor (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct 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 7388b7094185b9d4fe9820c731b6936d8d37f6143eDouglas 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 89d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<> struct N::B<float> { }; // expected-error{{originally}} 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 94d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor template<> struct ::A<long double>; // expected-error{{originally}} 9588b7094185b9d4fe9820c731b6936d8d37f6143eDouglas Gregor} 966bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor 976bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregortemplate<> struct N::B<char> { 986bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor int testf(int x) { return f(x); } 996bc9f7e286913fb1df95fa3fdcac7aab2628eaebDouglas Gregor}; 10065100792a69a16895bd80f1d639b99e7ad903386Douglas Gregor 101