blob: f7867d8339bb265d1beca77e9df08a22ea434c0e [file] [log] [blame]
Reid Kleckner993e72a2013-09-20 17:04:25 +00001// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
Francois Pichetb23dc092011-07-27 01:05:24 +00002
Reid Kleckner062be332014-08-14 23:34:52 +00003namespace basic {
4struct C {
5 static void foo2() {}
Francois Pichetb23dc092011-07-27 01:05:24 +00006};
Reid Kleckner062be332014-08-14 23:34:52 +00007template <typename T>
8struct A {
9 typedef C D;
Francois Pichetb23dc092011-07-27 01:05:24 +000010};
11
Reid Kleckner062be332014-08-14 23:34:52 +000012template <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 }
Francois Pichetb23dc092011-07-27 01:05:24 +000017};
Reid Kleckner062be332014-08-14 23:34:52 +000018
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}