1ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11
2ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
3ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
4ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
5567f917df048d42732997a479b2b257403fc88efLarisse Voufo#define CONST const
6567f917df048d42732997a479b2b257403fc88efLarisse Voufo
76aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#ifdef PRECXX11
86aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#define static_assert(expr, msg) typedef int static_assert[(expr) ? 1 : -1];
96aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#endif
106aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
11ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass A {
12567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> CONST T wrong;           // expected-error {{member 'wrong' declared as a template}}
13567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> CONST T wrong_init = 5;      // expected-error {{member 'wrong_init' declared as a template}}
14567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T, typename T0> static CONST T right = T(100);
15567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> static CONST T right<T,int> = 5;
16567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> CONST int right<int,T>;  // expected-error {{member 'right' declared as a template}}
17567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> CONST float right<float,T> = 5;  // expected-error {{member 'right' declared as a template}}
18567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<> static CONST int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
19567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<> static CONST float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
20567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template static CONST int right<int,int>;     // expected-error {{template specialization requires 'template<>'}} \
21ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                // expected-error {{explicit specialization of 'right' in class scope}}
22ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
23ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
24ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace out_of_line {
25ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B0 {
26567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T, typename T0> static CONST T right = T(100);
27567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T> static CONST T right<T,int> = T(5);
28ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
29567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<> CONST int B0::right<int,int> = 7;
30567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template CONST int B0::right<int,int>;
31567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<> CONST int B0::right<int,float>;
32567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template CONST int B0::right<int,float>;
33ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
34ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B1 {
35567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T, typename T0> static CONST T right;
36567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T> static CONST T right<T,int>;
37ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
38567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T, typename T0> CONST T B1::right = T(100);
39567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template<typename T> CONST T B1::right<T,int> = T(5);
40ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
41ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B2 {
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T, typename T0> static CONST T right = T(100);  // expected-note {{previous initialization is here}}
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T> static CONST T right<T,int> = T(5);          // expected-note {{previous initialization is here}}
44ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, typename T0> CONST T B2::right = T(100);   // expected-error {{static data member 'right' already has an initializer}}
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> CONST T B2::right<T,int> = T(5);           // expected-error {{static data member 'right' already has an initializer}}
47ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
48ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B3 {
49567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T, typename T0> static CONST T right = T(100);
50567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename T> static CONST T right<T,int> = T(5);
51ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
5258ee425b11e178c652fa6ff4c1c924fe9b98801eRichard Smith  template<typename T, typename T0> CONST T B3::right;
5358ee425b11e178c652fa6ff4c1c924fe9b98801eRichard Smith  template<typename T> CONST T B3::right<T,int>;
54ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
55ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B4 {
56d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T, typename T0> static CONST T a;
57d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static CONST T a<T,int> = T(100);
58d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T, typename T0> static CONST T b = T(100);
59d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static CONST T b<T,int>;
60ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
61d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}}
62d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T> CONST T B4::a<T,int>;
63d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int B4::a<int,char>; // expected-note {{in instantiation of}}
64d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int B4::a<int,int>;
65d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
66d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T, typename T0> CONST T B4::b;
67d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}}
68d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int B4::b<int,char>;
69d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int B4::b<int,int>; // expected-note {{in instantiation of}}
70ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo}
71ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
72ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace non_const_init {
73ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class A {
74d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static T wrong_inst_undefined = T(10); // expected-note {{refers here}}
75d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static T wrong_inst_defined = T(10); // expected-error {{non-const static data member must be initialized out of line}}
76d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static T wrong_inst_out_of_line;
77ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
78d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
79d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template const int A::wrong_inst_undefined<const int>; // expected-error {{undefined}}
80d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
81d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T> T A::wrong_inst_defined;
82d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template const int A::wrong_inst_defined<const int>;
83d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int A::wrong_inst_defined<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst_defined<int>' requested here}}
84d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
85d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T> T A::wrong_inst_out_of_line = T(10);
86d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int A::wrong_inst_out_of_line<int>;
87d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
88ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class B {
89d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static T wrong_inst; // expected-note {{refers here}}
90d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static T wrong_inst<T*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} expected-note {{refers here}}
91d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
92ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    template<typename T> static T wrong_inst_fixed;
93ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    template<typename T> static T wrong_inst_fixed<T*>;
94ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
95d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int B::wrong_inst<int>; // expected-error {{undefined}}
96d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  // FIXME: It'd be better to produce the 'explicit instantiation of undefined
97d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  // template' diagnostic here, not the 'must be initialized out of line'
98d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  // diagnostic.
99d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}}
100d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template const int B::wrong_inst<const int*>; // expected-error {{undefined}}
101ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template<typename T> T B::wrong_inst_fixed = T(100);
102ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template int B::wrong_inst_fixed<int>;
103d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
104ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class C {
105d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static CONST T right_inst = T(10); // expected-note {{here}}
106d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename T> static CONST T right_inst<T*> = T(100); // expected-note {{here}}
107ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
108d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int C::right_inst<int>; // expected-error {{undefined variable template}}
109d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template CONST int C::right_inst<int*>; // expected-error {{undefined variable template}}
110d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
111ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  namespace pointers {
112d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
113ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    struct C0 {
114ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      template<typename U> static U Data;
115d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename U> static CONST U Data<U*> = U(); // expected-note {{here}}
116d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
117d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename U> static U Data2;
118d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename U> static CONST U Data2<U*> = U();
119ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    };
120d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const int c0_test = C0::Data<int*>;
121d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(c0_test == 0, "");
122d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template const int C0::Data<int*>; // expected-error {{undefined}}
123d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
124d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> const U C0::Data2<U*>;
125d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template const int C0::Data2<int*>;
126d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
127ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    struct C1a {
128ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      template<typename U> static U Data;
129ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith      template<typename U> static U* Data<U*>;   // Okay, with out-of-line definition
130ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    };
131ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template<typename T> T* C1a::Data<T*> = new T();
132ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template int* C1a::Data<int*>;
133d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
134ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    struct C1b {
135ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      template<typename U> static U Data;
136ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith      template<typename U> static CONST U* Data<U*>;   // Okay, with out-of-line definition
137ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    };
138ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template<typename T> CONST T* C1b::Data<T*> = (T*)(0);
139ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template CONST int* C1b::Data<int*>;
140ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
141ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    struct C2a {
142ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith      template<typename U> static int Data;
143ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith      template<typename U> static U* Data<U*> = new U();   // expected-error {{non-const static data member must be initialized out of line}}
144ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    };
145ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template int* C2a::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}}
146d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
147d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    struct C2b {
148ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith      template<typename U> static int Data;
149d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename U> static U *const Data<U*> = (U*)(0); // expected-error {{static data member of type 'int *const'}}
150ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    };
151d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> U *const C2b::Data<U*>;
152d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template int *const C2b::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}}
153ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
154ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo}
155ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
156b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo#ifndef PRECXX11
157b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufonamespace constexpred {
158b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo  class A {
159b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T> constexpr T wrong;           // expected-error {{member 'wrong' declared as a template}} \
160b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo                                                      // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
161b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T> constexpr T wrong_init = 5;      // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
162b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T, typename T0> static constexpr T right = T(100);
163b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T> static constexpr T right<T,int> = 5;
164b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T> constexpr int right<int,T>;  // expected-error {{member 'right' declared as a template}} \
165b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo                                                      // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
166b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<typename T> constexpr float right<float,T> = 5;  // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
167b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<> static constexpr int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
168b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template<> static constexpr float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
169b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo    template static constexpr int right<int,int>;     // expected-error {{template specialization requires 'template<>'}} \
170b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo                                                  // expected-error {{explicit specialization of 'right' in class scope}}
171b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo  };
172b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo}
173b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo#endif
174b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo
175ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace in_class_template {
176ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
177ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template<typename T>
178ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class D0 {
179d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> static U Data; // expected-note {{here}}
180567f917df048d42732997a479b2b257403fc88efLarisse Voufo    template<typename U> static CONST U Data<U*> = U();
181ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
182567f917df048d42732997a479b2b257403fc88efLarisse Voufo  template CONST int D0<float>::Data<int*>;
183d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int D0<float>::Data<int>; // expected-error {{undefined}}
184d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template<typename T> template<typename U> const U D0<T>::Data<U*>;
185ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
186ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template<typename T>
187ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  class D1 {
188ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    template<typename U> static U Data;
189ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    template<typename U> static U* Data<U*>;
190ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
191ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template<typename T>
192ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  template<typename U> U* D1<T>::Data<U*> = (U*)(0);
193d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int* D1<float>::Data<int*>; // expected-note {{previous}}
194d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int* D1<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}}
19504592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo
19604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  template<typename T>
19704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  class D2 {
19804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<typename U> static U Data;
19904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<typename U> static U* Data<U*>;
20004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  };
20104592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  template<>
20204592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1;
203d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int* D2<float>::Data<int*>; // expected-note {{previous}}
204d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template int* D2<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}}
205567f917df048d42732997a479b2b257403fc88efLarisse Voufo
20604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  template<typename T>
20704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  struct D3 {
208d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> static CONST U Data = U(100); // expected-note {{here}}
20904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  };
21004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  static_assert(D3<float>::Data<int> == 100, "");
211d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  template const char D3<float>::Data<char>; // expected-error {{undefined}}
212ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
21304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  namespace bug_files {
21404592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<typename T>
215d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    class D0a {
21604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo      template<typename U> static U Data;
217567f917df048d42732997a479b2b257403fc88efLarisse Voufo      template<typename U> static CONST U Data<U*> = U(10);  // expected-note {{previous definition is here}}
21804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    };
21904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<>
220d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> U D0a<float>::Data<U*> = U(100);  // expected-error {{redefinition of 'Data'}}
22104592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo
222d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // FIXME: We should accept this, and the corresponding case for class
223d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // templates.
224d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    //
225d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // [temp.class.spec.mfunc]/2: If the primary member template is explicitly
226d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // specialized for a given specialization of the enclosing class template,
227d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // the partial specializations of the member template are ignored
22804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<typename T>
22904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    class D1 {
23004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo      template<typename U> static U Data;
231d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename U> static CONST U Data<U*> = U(10);  // expected-note {{previous definition is here}}
232d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    };
23304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template<>
234d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> U D1<float>::Data = U(10);
235d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<>
236d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename U> U D1<float>::Data<U*> = U(100);  // expected-error{{redefinition of 'Data'}}
23704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo  }
238ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith
239d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  namespace definition_after_outer_instantiation {
240d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename A> struct S {
241d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename B> static const int V1;
242d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith      template<typename B> static const int V2;
24304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    };
24404592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo    template struct S<int>;
245d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename A> template<typename B> const int S<A>::V1 = 123;
246d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename A> template<typename B> const int S<A>::V2<B*> = 456;
247d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
248d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<int>::V1<int> == 123, "");
249d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
250d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // FIXME: The first and third case below possibly should be accepted. We're
251d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // not picking up partial specializations added after the primary template
252d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2,
253d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // and matches our behavior for member class templates, but it's not clear
254d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // that this is intentional. See PR17294 and core-24030.
255d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<int>::V2<int*> == 456, ""); // FIXME expected-error {{}}
256d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<int>::V2<int&> == 789, ""); // expected-error {{}}
257d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
258d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    template<typename A> template<typename B> const int S<A>::V2<B&> = 789;
259d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<int>::V2<int&> == 789, ""); // FIXME expected-error {{}}
260d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith
261d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // All is OK if the partial specialization is declared before the implicit
262d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    // instantiation of the class template specialization.
263d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<char>::V1<int> == 123, "");
264d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<char>::V2<int*> == 456, "");
265d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(S<char>::V2<int&> == 789, "");
266ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2676aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2686aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith  namespace incomplete_array {
2696aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename T> extern T var[];
2706aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename T> T var[] = { 1, 2, 3 };
2716aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<> char var<char>[] = "hello";
2726aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename T> char var<T*>[] = "pointer";
2736aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2746aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    static_assert(sizeof(var<int>) == 12, "");
2756aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    static_assert(sizeof(var<char>) == 6, "");
2766aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    static_assert(sizeof(var<void*>) == 8, "");
2776aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2786aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename...> struct tuple;
2796aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2806aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename T> struct A {
2816aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith      template<typename U> static T x[];
2826aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith      template<typename U> static T y[];
2836aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2846aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith      template<typename...U> static T y<tuple<U...> >[];
2856aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    };
2866aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2876aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    int *use_before_definition = A<int>::x<char>;
288ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith    template<typename T> template<typename U> T A<T>::x[sizeof(U)];
289d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(sizeof(A<int>::x<char>) == 4, "");
2906aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith
2916aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith    template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
292d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
2936aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith  }
294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  namespace bad_reference {
296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    struct S {
297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      template<typename T> static int A; // expected-note 4{{here}}
298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T> void f() {
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}}
302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T> void g() {
304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}}
305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T> void h() {
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}}
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template<typename T>
311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}}
312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template void f<S>(); // expected-note {{in instantiation of}}
314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template void g<S>(); // expected-note {{in instantiation of}}
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template void h<S>(); // expected-note {{in instantiation of}}
316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    template struct X<S>; // expected-note {{in instantiation of}}
317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
318ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo}
319ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
320ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace in_nested_classes {
321ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // TODO:
322ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo}
323ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
324