1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 int foo(int);
3 
4 namespace N {
5   void f1() {
6     void foo(int); // okay
7     void bar(int); // expected-note 2{{previous declaration is here}}
8   }
9 
10   void foo(int); // expected-note 2{{previous declaration is here}}
11 
12   void f2() {
13     int foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
14     int bar(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
15     int baz(int); // expected-note {{previous declaration is here}}
16 
17     {
18       int foo;
19       int bar;
20       int baz;
21       {
22         float foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
23         float bar(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
24         float baz(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
25       }
26     }
27   }
28 }
29 
30 class A {
31  void typocorrection(); // expected-note {{'typocorrection' declared here}}
32 };
33 
34 void A::Notypocorrection() { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'A'; did you mean 'typocorrection'}}
35 }
36 
37 
38 namespace test0 {
39   void dummy() {
40     void Bar(); // expected-note {{'Bar' declared here}}
41     class A {
42       friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean 'Bar'}}
43     };
44   }
45 }
46 
47 
48 class B {
49  void typocorrection(const int); // expected-note {{'typocorrection' declared here}}
50  void typocorrection(double);
51 };
52 
53 void B::Notypocorrection(int) { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'B'; did you mean 'typocorrection'}}
54 }
55 
56 struct X { int f(); };
57 struct Y : public X {};
58 int Y::f() { return 3; } // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Y'}}
59 
60 namespace test1 {
61 struct Foo {
62   class Inner { };
63 };
64 }
65 
66 class Bar {
67   void f(test1::Foo::Inner foo) const; // expected-note {{member declaration does not match because it is const qualified}}
68 };
69 
70 using test1::Foo;
71 
72 void Bar::f(Foo::Inner foo) { // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Bar'}}
73   (void)foo;
74 }
75 
76 class Crash {
77  public:
78   void GetCart(int count) const;
79 };
80 // This out-of-line definition was fine...
81 void Crash::cart(int count) const {} // expected-error {{out-of-line definition of 'cart' does not match any declaration in 'Crash'}}
82 // ...while this one crashed clang
83 void Crash::chart(int count) const {} // expected-error {{out-of-line definition of 'chart' does not match any declaration in 'Crash'}}
84 
85 class TestConst {
86  public:
87   int getit() const; // expected-note {{member declaration does not match because it is const qualified}}
88   void setit(int); // expected-note {{member declaration does not match because it is not const qualified}}
89 };
90 
91 int TestConst::getit() { // expected-error {{out-of-line definition of 'getit' does not match any declaration in 'TestConst'}}
92   return 1;
93 }
94 
95 void TestConst::setit(int) const { // expected-error {{out-of-line definition of 'setit' does not match any declaration in 'TestConst'}}
96 }
97 
98 struct J { int typo() const; };
99 int J::typo_() { return 3; } // expected-error {{out-of-line definition of 'typo_' does not match any declaration in 'J'}}
100 
101 // Ensure we correct the redecl of Foo::isGood to Bar::Foo::isGood and not
102 // Foo::IsGood even though Foo::IsGood is technically a closer match since it
103 // already has a body. Also make sure Foo::beEvil is corrected to Foo::BeEvil
104 // since it is a closer match than Bar::Foo::beEvil and neither have a body.
105 namespace redecl_typo {
106 namespace Foo {
107   bool IsGood() { return false; }
108   void BeEvil(); // expected-note {{'BeEvil' declared here}}
109 }
110 namespace Bar {
111   namespace Foo {
112     bool isGood(); // expected-note {{'Bar::Foo::isGood' declared here}}
113     void beEvil();
114   }
115 }
116 bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'Bar::Foo::isGood'?}}
117   return true;
118 }
119 void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
120 }
121