lookup-dependent-bases.cpp 1.3 KB

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