1fd4d7770SDavid Goldman // RUN: %clang_cc1 -fsyntax-only -verify %s
2fd4d7770SDavid Goldman 
3fd4d7770SDavid Goldman // Check the following typo correction behavior:
4fd4d7770SDavid Goldman // - multiple typos in a single member call chain are all diagnosed
5fd4d7770SDavid Goldman // - no typos are diagnosed for multiple typos in an expression when not all
6fd4d7770SDavid Goldman //   typos can be corrected
7fd4d7770SDavid Goldman 
8fd4d7770SDavid Goldman class DeepClass
9fd4d7770SDavid Goldman {
10fd4d7770SDavid Goldman public:
11fd4d7770SDavid Goldman   void trigger() const;  // expected-note {{'trigger' declared here}}
12fd4d7770SDavid Goldman };
13fd4d7770SDavid Goldman 
14fd4d7770SDavid Goldman class Y
15fd4d7770SDavid Goldman {
16fd4d7770SDavid Goldman public:
getX() const17fd4d7770SDavid Goldman   const DeepClass& getX() const { return m_deepInstance; }  // expected-note {{'getX' declared here}}
18fd4d7770SDavid Goldman private:
19fd4d7770SDavid Goldman   DeepClass m_deepInstance;
20fd4d7770SDavid Goldman   int m_n;
21fd4d7770SDavid Goldman };
22fd4d7770SDavid Goldman 
23fd4d7770SDavid Goldman class Z
24fd4d7770SDavid Goldman {
25fd4d7770SDavid Goldman public:
getY0() const26fd4d7770SDavid Goldman   const Y& getY0() const { return m_y0; }  // expected-note {{'getY0' declared here}}
getActiveY() const27fd4d7770SDavid Goldman   const Y& getActiveY() const { return m_y0; }
28fd4d7770SDavid Goldman 
29fd4d7770SDavid Goldman private:
30fd4d7770SDavid Goldman   Y m_y0;
31fd4d7770SDavid Goldman   Y m_y1;
32fd4d7770SDavid Goldman };
33fd4d7770SDavid Goldman 
34fd4d7770SDavid Goldman Z z_obj;
35fd4d7770SDavid Goldman 
testMultipleCorrections()36fd4d7770SDavid Goldman void testMultipleCorrections()
37fd4d7770SDavid Goldman {
38fd4d7770SDavid Goldman   z_obj.getY2().  // expected-error {{no member named 'getY2' in 'Z'; did you mean 'getY0'}}
39fd4d7770SDavid Goldman       getM().     // expected-error {{no member named 'getM' in 'Y'; did you mean 'getX'}}
40fd4d7770SDavid Goldman       triggee();  // expected-error {{no member named 'triggee' in 'DeepClass'; did you mean 'trigger'}}
41fd4d7770SDavid Goldman }
42fd4d7770SDavid Goldman 
testNoCorrections()43fd4d7770SDavid Goldman void testNoCorrections()
44fd4d7770SDavid Goldman {
45fd4d7770SDavid Goldman   z_obj.getY2().  // expected-error {{no member named 'getY2' in 'Z'}}
46fd4d7770SDavid Goldman       getM().
47fd4d7770SDavid Goldman       thisDoesntSeemToMakeSense();
48fd4d7770SDavid Goldman }
49fd4d7770SDavid Goldman 
50fd4d7770SDavid Goldman struct C {};
51fd4d7770SDavid Goldman struct D { int value; };
52fd4d7770SDavid Goldman struct A {
53fd4d7770SDavid Goldman   C get_me_a_C();
54fd4d7770SDavid Goldman };
55fd4d7770SDavid Goldman struct B {
56fd4d7770SDavid Goldman   D get_me_a_D();  // expected-note {{'get_me_a_D' declared here}}
57fd4d7770SDavid Goldman };
58fd4d7770SDavid Goldman class Scope {
59fd4d7770SDavid Goldman public:
60fd4d7770SDavid Goldman   A make_an_A();
61fd4d7770SDavid Goldman   B make_a_B();  // expected-note {{'make_a_B' declared here}}
62fd4d7770SDavid Goldman };
63fd4d7770SDavid Goldman 
64fd4d7770SDavid Goldman Scope scope_obj;
65fd4d7770SDavid Goldman 
testDiscardedCorrections()66fd4d7770SDavid Goldman int testDiscardedCorrections() {
67fd4d7770SDavid Goldman   return scope_obj.make_an_E().  // expected-error {{no member named 'make_an_E' in 'Scope'; did you mean 'make_a_B'}}
68fd4d7770SDavid Goldman       get_me_a_Z().value;        // expected-error {{no member named 'get_me_a_Z' in 'B'; did you mean 'get_me_a_D'}}
69fd4d7770SDavid Goldman }
70fd4d7770SDavid Goldman 
71fd4d7770SDavid Goldman class AmbiguousHelper {
72fd4d7770SDavid Goldman public:
73fd4d7770SDavid Goldman   int helpMe();
74fd4d7770SDavid Goldman   int helpBe();
75fd4d7770SDavid Goldman };
76fd4d7770SDavid Goldman class Ambiguous {
77fd4d7770SDavid Goldman public:
78fd4d7770SDavid Goldman   int calculateA();
79fd4d7770SDavid Goldman   int calculateB();
80fd4d7770SDavid Goldman 
81fd4d7770SDavid Goldman   AmbiguousHelper getHelp1();
82fd4d7770SDavid Goldman   AmbiguousHelper getHelp2();
83fd4d7770SDavid Goldman };
84fd4d7770SDavid Goldman 
85fd4d7770SDavid Goldman Ambiguous ambiguous_obj;
86fd4d7770SDavid Goldman 
testDirectAmbiguousCorrection()87fd4d7770SDavid Goldman int testDirectAmbiguousCorrection() {
88fd4d7770SDavid Goldman   return ambiguous_obj.calculateZ();  // expected-error {{no member named 'calculateZ' in 'Ambiguous'}}
89fd4d7770SDavid Goldman }
90fd4d7770SDavid Goldman 
testRecursiveAmbiguousCorrection()91fd4d7770SDavid Goldman int testRecursiveAmbiguousCorrection() {
92fd4d7770SDavid Goldman   return ambiguous_obj.getHelp3().    // expected-error {{no member named 'getHelp3' in 'Ambiguous'}}
93fd4d7770SDavid Goldman       helpCe();
94fd4d7770SDavid Goldman }
95fd4d7770SDavid Goldman 
96fd4d7770SDavid Goldman 
97fd4d7770SDavid Goldman class DeepAmbiguityHelper {
98fd4d7770SDavid Goldman public:
99fd4d7770SDavid Goldman   DeepAmbiguityHelper& help1();
100fd4d7770SDavid Goldman   DeepAmbiguityHelper& help2();
101fd4d7770SDavid Goldman 
102fd4d7770SDavid Goldman   DeepAmbiguityHelper& methodA();
103fd4d7770SDavid Goldman   DeepAmbiguityHelper& somethingMethodB();
104fd4d7770SDavid Goldman   DeepAmbiguityHelper& functionC();
105fd4d7770SDavid Goldman   DeepAmbiguityHelper& deepMethodD();
106fd4d7770SDavid Goldman   DeepAmbiguityHelper& asDeepAsItGets();
107fd4d7770SDavid Goldman };
108fd4d7770SDavid Goldman 
109fd4d7770SDavid Goldman DeepAmbiguityHelper deep_obj;
110fd4d7770SDavid Goldman 
testDeepAmbiguity()111fd4d7770SDavid Goldman int testDeepAmbiguity() {
112fd4d7770SDavid Goldman   deep_obj.
113fd4d7770SDavid Goldman       methodB(). // expected-error {{no member named 'methodB' in 'DeepAmbiguityHelper'}}
114fd4d7770SDavid Goldman       somethingMethodC().
115fd4d7770SDavid Goldman       functionD().
116fd4d7770SDavid Goldman       deepMethodD().
117fd4d7770SDavid Goldman       help3().
118fd4d7770SDavid Goldman       asDeepASItGet().
119fd4d7770SDavid Goldman       functionE();
120fd4d7770SDavid Goldman }
121*dde98c82SDavid Goldman 
122*dde98c82SDavid Goldman struct Dog {
123*dde98c82SDavid Goldman   int age;  //expected-note{{'age' declared here}}
124*dde98c82SDavid Goldman   int size; //expected-note{{'size' declared here}}
125*dde98c82SDavid Goldman };
126*dde98c82SDavid Goldman 
127*dde98c82SDavid Goldman int from_dog_years(int DogYears, int DogSize);
get_dog_years()128*dde98c82SDavid Goldman int get_dog_years() {
129*dde98c82SDavid Goldman   struct Dog doggo;
130*dde98c82SDavid Goldman   return from_dog_years(doggo.agee,   //expected-error{{no member named 'agee' in 'Dog'; did you mean 'age'}}
131*dde98c82SDavid Goldman                         doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'; did you mean 'size'}}
132*dde98c82SDavid Goldman }
133