blob: 4ae1b9bdc9789afff0fbf528ed70b7c61eab5b2b [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) {
40 x1->foo(); // okay: refers to #1
41 x2->bar(); // okay: refers to #2
42}
Douglas Gregor39a8de12009-02-25 19:37:18 +000043
Douglas Gregorac1afdc2009-02-25 19:48:02 +000044// Diagnose specializations in a different namespace
Douglas Gregor88b70942009-02-25 22:02:03 +000045struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
46
47template<typename T> // expected-error{{class template partial specialization is not yet supported}}
48struct A<T*> { };
49
50template<> struct ::A<double>;
51
52namespace N {
53 template<typename T> struct B; // expected-note 2{{template is declared here}}
54
55 template<> struct ::N::B<short>; // okay
56 template<> struct ::N::B<int>; // okay
57}
58
59template<> struct N::B<int> { }; // okay
60
61template<> struct N::B<float> { }; // expected-error{{class template specialization of 'B' not in namespace 'N'}}
62
63namespace M {
64 template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
65
66 template<> struct ::A<long double>; // expected-error{{class template specialization of 'A' must occur in the global scope}}
67}