1// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
2namespace A {
3  struct C {
4    static int cx;
5
6    static int cx2;
7
8    static int Ag1();
9    static int Ag2();
10  };
11  int ax;
12  void Af();
13}
14
15A:: ; // expected-error {{expected unqualified-id}}
16// FIXME: there is a member 'ax'; it's just not a class.
17::A::ax::undef ex3; // expected-error {{no member named 'ax'}}
18A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}}
19
20int A::C::Ag1() { return 0; }
21
22static int A::C::Ag2() { return 0; } // expected-error{{'static' can}}
23
24int A::C::cx = 17;
25
26
27static int A::C::cx2 = 17; // expected-error{{'static' can}}
28
29class C2 {
30  void m(); // expected-note{{member declaration does not match because it is not const qualified}}
31
32  void f(const int& parm); // expected-note{{type of 1st parameter of member declaration does not match definition ('const int &' vs 'int')}}
33  void f(int) const; // expected-note{{member declaration does not match because it is const qualified}}
34  void f(float);
35
36  int x;
37};
38
39void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'C2'}}
40
41void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'C2'}}
42
43void C2::m() {
44  x = 0;
45}
46
47namespace B {
48  void ::A::Af() {} // expected-error {{cannot define or redeclare 'Af' here because namespace 'B' does not enclose namespace 'A'}}
49}
50
51void f1() {
52  void A::Af(); // expected-error {{definition or redeclaration of 'Af' not allowed inside a function}}
53}
54
55void f2() {
56  A:: ; // expected-error {{expected unqualified-id}}
57  A::C::undef = 0; // expected-error {{no member named 'undef'}}
58  ::A::C::cx = 0;
59  int x = ::A::ax = A::C::cx;
60  x = sizeof(A::C);
61  x = sizeof(::A::C::cx);
62}
63
64A::C c1;
65struct A::C c2;
66struct S : public A::C {};
67struct A::undef; // expected-error {{no struct named 'undef' in namespace 'A'}}
68
69namespace A2 {
70  typedef int INT;
71  struct RC;
72  struct CC {
73    struct NC;
74  };
75}
76
77struct A2::RC {
78  INT x;
79};
80
81struct A2::CC::NC {
82  void m() {}
83};
84
85void f3() {
86  N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
87  int N;
88  N::x = 0; // expected-error {{expected a class or namespace}}
89  { int A;           A::ax = 0; }
90  { typedef int A;   A::ax = 0; } // expected-error{{expected a class or namespace}}
91  { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
92  { typedef A::C A;  A::cx = 0; }
93}
94
95// make sure the following doesn't hit any asserts
96void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}}
97
98typedef void C2::f5(int); // expected-error{{typedef declarator cannot be qualified}}
99
100void f6(int A2::RC::x); // expected-error{{parameter declarator cannot be qualified}}
101
102int A2::RC::x; // expected-error{{non-static data member defined out-of-line}}
103
104void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member must be a definition}}
105
106
107namespace E {
108  int X = 5;
109
110  namespace Nested {
111    enum E {
112      X = 0
113    };
114
115    void f() {
116      return E::X; // expected-error{{expected a class or namespace}}
117    }
118  }
119}
120
121
122class Operators {
123  Operators operator+(const Operators&) const; // expected-note{{member declaration does not match because it is const qualified}}
124  operator bool();
125};
126
127Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'Operators'}}
128  Operators ops;
129  return ops;
130}
131
132Operators Operators::operator+(const Operators&) const {
133  Operators ops;
134  return ops;
135}
136
137Operators::operator bool() {
138  return true;
139}
140
141namespace A {
142  void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
143}
144
145void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'$}}
146
147void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
148
149struct Struct { };
150
151void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'Struct'}}
152
153void global_func(int);
154void global_func2(int);
155
156namespace N {
157  void ::global_func(int) { } // expected-error{{definition or redeclaration of 'global_func' cannot name the global scope}}
158
159  void f();
160  // FIXME: if we move this to a separate definition of N, things break!
161}
162void ::global_func2(int) { } // expected-warning{{extra qualification on member 'global_func2'}}
163
164void N::f() { } // okay
165
166struct Y;  // expected-note{{forward declaration of 'Y'}}
167Y::foo y; // expected-error{{incomplete type 'Y' named in nested name specifier}}
168
169X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
170      // expected-error{{C++ requires a type specifier for all declarations}} \
171      // expected-error{{only constructors take base initializers}}
172
173struct foo_S {
174  static bool value;
175};
176bool (foo_S::value);
177
178
179namespace somens {
180  struct a { }; // expected-note{{candidate constructor (the implicit copy constructor)}}
181}
182
183template <typename T>
184class foo {
185};
186
187
188// PR4452 / PR4451
189foo<somens:a> a2;  // expected-error {{unexpected ':' in nested name specifier}}
190
191somens::a a3 = a2; // expected-error {{no viable conversion}}
192
193// typedefs and using declarations.
194namespace test1 {
195  namespace ns {
196    class Counter { public: static int count; };
197    typedef Counter counter;
198  }
199  using ns::counter;
200
201  class Test {
202    void test1() {
203      counter c;
204      c.count++;
205      counter::count++;
206    }
207  };
208}
209
210// We still need to do lookup in the lexical scope, even if we push a
211// non-lexical scope.
212namespace test2 {
213  namespace ns {
214    extern int *count_ptr;
215  }
216  namespace {
217    int count = 0;
218  }
219
220  int *ns::count_ptr = &count;
221}
222
223// PR6259, invalid case
224namespace test3 {
225  class A; // expected-note {{forward declaration}}
226  void foo(const char *path) {
227    A::execute(path); // expected-error {{incomplete type 'test3::A' named in nested name specifier}}
228  }
229}
230
231namespace PR7133 {
232  namespace A {
233    class Foo;
234  }
235
236  namespace A {
237    namespace B {
238      bool foo(Foo &);
239    }
240  }
241
242  bool A::B::foo(Foo &) {
243    return false;
244  }
245}
246
247class CLASS {
248  void CLASS::foo2(); // expected-warning {{extra qualification on member 'foo2'}}
249};
250
251namespace PR8159 {
252  class B { };
253
254  class A {
255    int A::a; // expected-warning{{extra qualification on member 'a'}}
256    static int A::b; // expected-warning{{extra qualification on member 'b'}}
257    int ::c; // expected-error{{non-friend class member 'c' cannot have a qualified name}}
258  };
259}
260
261namespace rdar7980179 {
262  class A { void f0(); }; // expected-note {{previous}}
263  int A::f0() {} // expected-error {{out-of-line definition of 'rdar7980179::A::f0' differs from the declaration in the return type}}
264}
265
266namespace alias = A;
267double *dp = (alias::C*)0; // expected-error{{cannot initialize a variable of type 'double *' with an rvalue of type 'alias::C *'}}
268
269// http://llvm.org/PR10109
270namespace PR10109 {
271template<typename T>
272struct A {
273protected:
274  struct B;
275  struct B::C; // expected-error {{requires a template parameter list}} \
276               // expected-error {{no struct named 'C'}} \
277    // expected-error{{non-friend class member 'C' cannot have a qualified name}}
278};
279
280template<typename T>
281struct A2 {
282protected:
283  struct B;
284};
285template <typename T>
286struct A2<T>::B::C; // expected-error {{no struct named 'C'}}
287}
288
289namespace PR13033 {
290namespace NS {
291 int a; // expected-note {{'NS::a' declared here}}
292 int longer_b; //expected-note {{'NS::longer_b' declared here}}
293}
294
295// Suggest adding a namespace qualifier to both variable names even though one
296// is only a single character long.
297int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \
298                           // expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}}
299}
300