142aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
242aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
342aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregornamespace PR8019 {
442aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor  struct x;
542aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor  template<typename T> struct x2;
642aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor  struct y {
742aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    struct PR8019::x { int x; };  // expected-error{{non-friend class member 'x' cannot have a qualified name}}
842aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
942aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    struct inner;
1075379455fc88ca1f021e55ffe1cab3a9c2b2a37aDouglas Gregor    struct y::inner { }; // expected-error{{extra qualification on member 'inner'}}
1142aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
1242aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    template<typename T>
1342aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    struct PR8019::x2 { }; // expected-error{{non-friend class member 'x2' cannot have a qualified name}}
1442aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
1542aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    template<typename T>
1642aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    struct inner_template;
1742aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
1842aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor    template<typename T>
1975379455fc88ca1f021e55ffe1cab3a9c2b2a37aDouglas Gregor    struct y::inner_template { }; // expected-error{{extra qualification on member 'inner_template'}}
2042aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor  };
2142aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor
2242aceadbc3806868cee8ac576347d258ac99e1f6Douglas Gregor}
236960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor
246960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregornamespace NS {
256960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor  void foo();
266960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor  extern int bar;
276960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor  struct X;
286960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor  template<typename T> struct Y;
296960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor  template<typename T> void wibble(T);
300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  struct Z;
316960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor}
326960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregornamespace NS {
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Under DR482, these are all valid, except for forward-declaring a struct
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // with a nested-name-specifier.
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void NS::foo(); // expected-warning {{extra qualification}}
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  extern int NS::bar; // expected-warning {{extra qualification}}
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct NS::X; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}}
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct NS::Y; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}}
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> void NS::wibble(T); // expected-warning {{extra qualification}}
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void NS::foo() {} // expected-warning{{extra qualification on member 'foo'}}
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int NS::bar; // expected-warning{{extra qualification on member 'bar'}}
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct NS::X { }; // expected-warning{{extra qualification on member 'X'}}
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct NS::Y { }; // expected-warning{{extra qualification on member 'Y'}}
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> void NS::wibble(T) { } // expected-warning{{extra qualification on member 'wibble'}}
466960587df0bd1b421c11715807a4d2302a3aae3cDouglas Gregor}
470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
480e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstruct ::{} a; // expected-error{{expected identifier}}
490e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstruct NS::Z:: {} b; // expected-error{{expected identifier}}
50