blob: 15c797a5daf46efcf05ed8035138f19cf9d91251 [file] [log] [blame]
Douglas Gregora08b6c72009-02-17 23:15:12 +00001// RUN: clang -fsyntax-only -verify %s
Douglas Gregor0d93f692009-02-25 22:02:03 +00002template<typename T, typename U = int> struct A; // expected-note{{template is declared here}}
Douglas Gregora08b6c72009-02-17 23:15:12 +00003
Douglas Gregor0d93f692009-02-25 22:02:03 +00004template<> struct A<double, double>; // expected-note{{forward declaration}}
Douglas Gregora08b6c72009-02-17 23:15:12 +00005
Douglas Gregor0d93f692009-02-25 22:02:03 +00006template<> struct A<float, float> { // expected-note{{previous definition}}
Douglas Gregora08b6c72009-02-17 23:15:12 +00007 int x;
8};
9
Douglas Gregor0d93f692009-02-25 22:02:03 +000010template<> struct A<float> { // expected-note{{previous definition}}
Douglas Gregora08b6c72009-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 Gregor0d93f692009-02-25 22:02:03 +000027template<> struct A<float, FLOAT>;
Douglas Gregora08b6c72009-02-17 23:15:12 +000028
Douglas Gregor0d93f692009-02-25 22:02:03 +000029template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
Douglas Gregora08b6c72009-02-17 23:15:12 +000030
Douglas Gregor0d93f692009-02-25 22:02:03 +000031template<> struct A<float, int> { }; // expected-error{{redefinition}}
Douglas Gregor8d103492009-02-19 00:52:42 +000032
Douglas Gregor0d93f692009-02-25 22:02:03 +000033template<typename T, typename U = int> struct X;
Douglas Gregor8d103492009-02-19 00:52:42 +000034
Douglas Gregor0d93f692009-02-25 22:02:03 +000035template <> struct X<int, int> { int foo(); }; // #1
36template <> struct X<float> { int bar(); }; // #2
Douglas Gregor8d103492009-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 Gregor0c281a82009-02-25 19:37:18 +000043
Douglas Gregor849196f2009-02-25 19:48:02 +000044// Diagnose specializations in a different namespace
Douglas Gregor0d93f692009-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
Douglas Gregor50113ca2009-02-25 22:18:32 +000055 template<> struct ::N::B<char>; // okay
Douglas Gregor0d93f692009-02-25 22:02:03 +000056 template<> struct ::N::B<short>; // okay
57 template<> struct ::N::B<int>; // okay
Douglas Gregor50113ca2009-02-25 22:18:32 +000058
59 int f(int);
Douglas Gregor0d93f692009-02-25 22:02:03 +000060}
61
62template<> struct N::B<int> { }; // okay
63
64template<> struct N::B<float> { }; // expected-error{{class template specialization of 'B' not in namespace 'N'}}
65
66namespace M {
67 template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
68
69 template<> struct ::A<long double>; // expected-error{{class template specialization of 'A' must occur in the global scope}}
70}
Douglas Gregor50113ca2009-02-25 22:18:32 +000071
72template<> struct N::B<char> {
73 int testf(int x) { return f(x); }
74};