1// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s 2 3namespace basic { 4struct C { 5 static void foo2() {} 6}; 7template <typename T> 8struct A { 9 typedef C D; 10}; 11 12template <typename T> 13struct B : A<T> { 14 void foo() { 15 D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}} 16 } 17}; 18 19template struct B<int>; // Instantiation has no warnings. 20} 21 22namespace nested_nodep_base { 23// There are limits to our hacks, MSVC accepts this, but we don't. 24struct A { 25 struct D { static void foo2(); }; 26}; 27template <typename T> 28struct B : T { 29 struct C { 30 void foo() { 31 D::foo2(); // expected-error {{use of undeclared identifier 'D'}} 32 } 33 }; 34}; 35 36template struct B<A>; // Instantiation has no warnings. 37} 38 39namespace nested_dep_base { 40// We actually accept this because the inner class has a dependent base even 41// though it isn't a template. 42struct A { 43 struct D { static void foo2(); }; 44}; 45template <typename T> 46struct B { 47 struct C : T { 48 void foo() { 49 D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'C' is a Microsoft extension}} 50 } 51 }; 52}; 53 54template struct B<A>; // Instantiation has no warnings. 55} 56