// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s namespace basic { struct C { static void foo2() {} }; template <typename T> struct A { typedef C D; }; template <typename T> struct B : A<T> { void foo() { D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}} } }; template struct B<int>; // Instantiation has no warnings. } namespace nested_nodep_base { // There are limits to our hacks, MSVC accepts this, but we don't. struct A { struct D { static void foo2(); }; }; template <typename T> struct B : T { struct C { void foo() { D::foo2(); // expected-error {{use of undeclared identifier 'D'}} } }; }; template struct B<A>; // Instantiation has no warnings. } namespace nested_dep_base { // We actually accept this because the inner class has a dependent base even // though it isn't a template. struct A { struct D { static void foo2(); }; }; template <typename T> struct B { struct C : T { void foo() { D::foo2(); // expected-warning {{use of undeclared identifier 'D'; unqualified lookup into dependent bases of class template 'C' is a Microsoft extension}} } }; }; template struct B<A>; // Instantiation has no warnings. }