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