class-template-spec.cpp revision 03c5705a99a96a471b2868898ee9688a6721e02a
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{
2203c5705a99a96a471b2868898ee9688a6721e02aDouglas Gregor  (void)a1->x; // expected-error{{member access into incomplete type}}
23972e6ce33c7e307f4b0da12bd6079bbd6ef76948Douglas 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
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
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
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}}
112