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