blob: e44115c748c3949be269b5ef216980d1f2d8e891 [file] [log] [blame]
Daniel Dunbard7d5f022009-03-24 02:24:46 +00001// RUN: clang-cc -fsyntax-only -verify %s
Douglas Gregor1fef4e62009-10-07 22:35:40 +00002template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
3 // expected-note{{explicitly specialized}}
Douglas Gregorcc636682009-02-17 23:15:12 +00004
Douglas Gregor88b70942009-02-25 22:02:03 +00005template<> struct A<double, double>; // expected-note{{forward declaration}}
Douglas Gregorcc636682009-02-17 23:15:12 +00006
Douglas Gregor88b70942009-02-25 22:02:03 +00007template<> struct A<float, float> { // expected-note{{previous definition}}
Douglas Gregorcc636682009-02-17 23:15:12 +00008 int x;
9};
10
Douglas Gregor88b70942009-02-25 22:02:03 +000011template<> struct A<float> { // expected-note{{previous definition}}
Douglas Gregorcc636682009-02-17 23:15:12 +000012 int y;
13};
14
15int test_specs(A<float, float> *a1, A<float, int> *a2) {
16 return a1->x + a2->y;
17}
18
19int test_incomplete_specs(A<double, double> *a1,
Douglas Gregor2943aed2009-03-03 04:44:36 +000020 A<double> *a2)
Douglas Gregorcc636682009-02-17 23:15:12 +000021{
22 (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
Douglas Gregorb3ae4fc2009-10-12 20:18:28 +000023 (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} \
24 // expected-note{{first required here}}
Douglas Gregorcc636682009-02-17 23:15:12 +000025}
26
27typedef float FLOAT;
28
Douglas Gregor88b70942009-02-25 22:02:03 +000029template<> struct A<float, FLOAT>;
Douglas Gregorcc636682009-02-17 23:15:12 +000030
Douglas Gregor88b70942009-02-25 22:02:03 +000031template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
Douglas Gregorcc636682009-02-17 23:15:12 +000032
Douglas Gregor88b70942009-02-25 22:02:03 +000033template<> struct A<float, int> { }; // expected-error{{redefinition}}
Douglas Gregor611a8c42009-02-19 00:52:42 +000034
Douglas Gregor88b70942009-02-25 22:02:03 +000035template<typename T, typename U = int> struct X;
Douglas Gregor611a8c42009-02-19 00:52:42 +000036
Douglas Gregor88b70942009-02-25 22:02:03 +000037template <> struct X<int, int> { int foo(); }; // #1
38template <> struct X<float> { int bar(); }; // #2
Douglas Gregor611a8c42009-02-19 00:52:42 +000039
40typedef int int_type;
41void testme(X<int_type> *x1, X<float, int> *x2) {
Douglas Gregor65100792009-02-26 00:02:51 +000042 (void)x1->foo(); // okay: refers to #1
43 (void)x2->bar(); // okay: refers to #2
Douglas Gregor611a8c42009-02-19 00:52:42 +000044}
Douglas Gregor39a8de12009-02-25 19:37:18 +000045
Douglas Gregor65100792009-02-26 00:02:51 +000046// Make sure specializations are proper classes.
47template<>
48struct A<char> {
49 A();
50};
51
52A<char>::A() { }
53
Douglas Gregordb3a0f52009-08-26 18:54:58 +000054// Make sure we can see specializations defined before the primary template.
55namespace N{
56 template<typename T> struct A0;
57}
58
59namespace N {
60 template<>
61 struct A0<void> {
62 typedef void* pointer;
63 };
64}
65
66namespace N {
67 template<typename T>
68 struct A0 {
69 void foo(A0<void>::pointer p = 0);
70 };
71}
72
Douglas Gregor65100792009-02-26 00:02:51 +000073// Diagnose specialization errors
Douglas Gregorb3ae4fc2009-10-12 20:18:28 +000074struct A<double> { }; // expected-error{{template specialization requires 'template<>'}} \
75 // expected-error{{after instantiation}}
Douglas Gregor88b70942009-02-25 22:02:03 +000076
Douglas Gregor88b70942009-02-25 22:02:03 +000077template<> struct ::A<double>;
78
79namespace N {
Douglas Gregor1fef4e62009-10-07 22:35:40 +000080 template<typename T> struct B; // expected-note 2{{explicitly specialized}}
Douglas Gregor88b70942009-02-25 22:02:03 +000081
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000082 template<> struct ::N::B<char>; // okay
Douglas Gregor88b70942009-02-25 22:02:03 +000083 template<> struct ::N::B<short>; // okay
84 template<> struct ::N::B<int>; // okay
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000085
86 int f(int);
Douglas Gregor88b70942009-02-25 22:02:03 +000087}
88
89template<> struct N::B<int> { }; // okay
90
Douglas Gregord5cb8762009-10-07 00:13:32 +000091template<> struct N::B<float> { }; // expected-error{{originally}}
Douglas Gregor88b70942009-02-25 22:02:03 +000092
93namespace M {
94 template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
95
Douglas Gregord5cb8762009-10-07 00:13:32 +000096 template<> struct ::A<long double>; // expected-error{{originally}}
Douglas Gregor88b70942009-02-25 22:02:03 +000097}
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000098
99template<> struct N::B<char> {
100 int testf(int x) { return f(x); }
101};
Douglas Gregor65100792009-02-26 00:02:51 +0000102