blob: e4900838f114f311957a001c6aeacc2c98ad9782 [file] [log] [blame]
Douglas Gregorcc636682009-02-17 23:15:12 +00001// RUN: clang -fsyntax-only -verify %s
Douglas Gregor88b70942009-02-25 22:02:03 +00002template<typename T, typename U = int> struct A; // expected-note{{template is declared here}}
Douglas Gregorcc636682009-02-17 23:15:12 +00003
Douglas Gregor88b70942009-02-25 22:02:03 +00004template<> struct A<double, double>; // expected-note{{forward declaration}}
Douglas Gregorcc636682009-02-17 23:15:12 +00005
Douglas Gregor88b70942009-02-25 22:02:03 +00006template<> struct A<float, float> { // expected-note{{previous definition}}
Douglas Gregorcc636682009-02-17 23:15:12 +00007 int x;
8};
9
Douglas Gregor88b70942009-02-25 22:02:03 +000010template<> struct A<float> { // expected-note{{previous definition}}
Douglas Gregorcc636682009-02-17 23:15:12 +000011 int y;
12};
13
14int test_specs(A<float, float> *a1, A<float, int> *a2) {
15 return a1->x + a2->y;
16}
17
18int test_incomplete_specs(A<double, double> *a1,
19 A<double> *a2) // FIXME: expected-note{{forward declaration}}
20{
21 (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}}
22 (void)a2->x; // expected-error{{incomplete definition of type 'A<double>'}}
23}
24
25typedef float FLOAT;
26
Douglas Gregor88b70942009-02-25 22:02:03 +000027template<> struct A<float, FLOAT>;
Douglas Gregorcc636682009-02-17 23:15:12 +000028
Douglas Gregor88b70942009-02-25 22:02:03 +000029template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
Douglas Gregorcc636682009-02-17 23:15:12 +000030
Douglas Gregor88b70942009-02-25 22:02:03 +000031template<> struct A<float, int> { }; // expected-error{{redefinition}}
Douglas Gregor611a8c42009-02-19 00:52:42 +000032
Douglas Gregor88b70942009-02-25 22:02:03 +000033template<typename T, typename U = int> struct X;
Douglas Gregor611a8c42009-02-19 00:52:42 +000034
Douglas Gregor88b70942009-02-25 22:02:03 +000035template <> struct X<int, int> { int foo(); }; // #1
36template <> struct X<float> { int bar(); }; // #2
Douglas Gregor611a8c42009-02-19 00:52:42 +000037
38typedef int int_type;
39void testme(X<int_type> *x1, X<float, int> *x2) {
Douglas Gregor65100792009-02-26 00:02:51 +000040 (void)x1->foo(); // okay: refers to #1
41 (void)x2->bar(); // okay: refers to #2
Douglas Gregor611a8c42009-02-19 00:52:42 +000042}
Douglas Gregor39a8de12009-02-25 19:37:18 +000043
Douglas Gregor65100792009-02-26 00:02:51 +000044// Make sure specializations are proper classes.
45template<>
46struct A<char> {
47 A();
48};
49
50A<char>::A() { }
51
52// Diagnose specialization errors
Douglas Gregor88b70942009-02-25 22:02:03 +000053struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
54
55template<typename T> // expected-error{{class template partial specialization is not yet supported}}
56struct A<T*> { };
57
58template<> struct ::A<double>;
59
60namespace N {
61 template<typename T> struct B; // expected-note 2{{template is declared here}}
62
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000063 template<> struct ::N::B<char>; // okay
Douglas Gregor88b70942009-02-25 22:02:03 +000064 template<> struct ::N::B<short>; // okay
65 template<> struct ::N::B<int>; // okay
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000066
67 int f(int);
Douglas Gregor88b70942009-02-25 22:02:03 +000068}
69
70template<> struct N::B<int> { }; // okay
71
72template<> struct N::B<float> { }; // expected-error{{class template specialization of 'B' not in namespace 'N'}}
73
74namespace M {
75 template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
76
77 template<> struct ::A<long double>; // expected-error{{class template specialization of 'A' must occur in the global scope}}
78}
Douglas Gregor6bc9f7e2009-02-25 22:18:32 +000079
80template<> struct N::B<char> {
81 int testf(int x) { return f(x); }
82};
Douglas Gregor65100792009-02-26 00:02:51 +000083