18a0dde75SRichard Smith // RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s -Wno-microsoft
28a0dde75SRichard Smith // RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s -Wno-microsoft
38a0dde75SRichard Smith 
48a0dde75SRichard Smith class A {
58a0dde75SRichard Smith public:
68a0dde75SRichard Smith   template<typename T> struct X { typedef int x; };
78a0dde75SRichard Smith 
88a0dde75SRichard Smith   X<int>::x a; // expected-note {{implicit instantiation first required here}}
98a0dde75SRichard Smith 
108a0dde75SRichard Smith   template<> struct X<int>; // expected-error {{explicit specialization of 'A::X<int>' after instantiation}}
118a0dde75SRichard Smith   template<> struct X<char>; // expected-note {{forward declaration}}
128a0dde75SRichard Smith 
138a0dde75SRichard Smith   X<char>::x b; // expected-error {{incomplete type 'A::X<char>' named in nested name specifier}}
148a0dde75SRichard Smith 
158a0dde75SRichard Smith   template<> struct X<double> {
168a0dde75SRichard Smith     typedef int y;
178a0dde75SRichard Smith   };
188a0dde75SRichard Smith 
198a0dde75SRichard Smith   X<double>::y c;
208a0dde75SRichard Smith 
218a0dde75SRichard Smith   template<> struct X<float> {}; // expected-note {{previous definition is here}}
22*792c22dbSRichard Smith   template<> struct X<float> {}; // expected-error {{redefinition of 'X<float>'}}
238a0dde75SRichard Smith };
248a0dde75SRichard Smith 
258a0dde75SRichard Smith A::X<void>::x axv;
268a0dde75SRichard Smith A::X<float>::x axf; // expected-error {{no type named 'x'}}
278a0dde75SRichard Smith 
288a0dde75SRichard Smith template<class T> class B {
298a0dde75SRichard Smith public:
308a0dde75SRichard Smith   template<typename U> struct X { typedef int x; };
318a0dde75SRichard Smith 
328a0dde75SRichard Smith   typename X<int>::x a; // expected-note {{implicit instantiation first required here}}
338a0dde75SRichard Smith 
348a0dde75SRichard Smith   template<> struct X<int>; // expected-error {{explicit specialization of 'X<int>' after instantiation}}
358a0dde75SRichard Smith   template<> struct X<char>; // expected-note {{forward declaration}}
368a0dde75SRichard Smith 
378a0dde75SRichard Smith   typename X<char>::x b; // expected-error {{incomplete type 'B<float>::X<char>' named in nested name specifier}}
388a0dde75SRichard Smith 
398a0dde75SRichard Smith   template<> struct X<double> {
408a0dde75SRichard Smith     typedef int y;
418a0dde75SRichard Smith   };
428a0dde75SRichard Smith 
438a0dde75SRichard Smith   typename X<double>::y c;
448a0dde75SRichard Smith 
458a0dde75SRichard Smith   template<> struct X<float> {}; // expected-note {{previous definition is here}}
468a0dde75SRichard Smith   template<> struct X<T> {}; // expected-error {{redefinition of 'X<float>'}}
478a0dde75SRichard Smith };
488a0dde75SRichard Smith 
498a0dde75SRichard Smith B<float> b; // expected-note {{in instantiation of}}
50