1 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s 2 3 struct errc { 4 int v_; 5 operator int() const {return v_;} 6 }; 7 8 class error_condition 9 { 10 int _val_; 11 public: 12 error_condition() : _val_(0) {} 13 14 error_condition(int _val) 15 : _val_(_val) {} 16 17 template <class E> 18 error_condition(E _e) { 19 // make_error_condition must not be typo corrected to error_condition 20 // even though the first declaration of make_error_condition has not 21 // yet been encountered. This was a bug in the first version of the type 22 // name typo correction patch that wasn't noticed until building LLVM with 23 // Clang failed. 24 *this = make_error_condition(_e); 25 } 26 27 }; 28 29 inline error_condition make_error_condition(errc _e) { 30 return error_condition(static_cast<int>(_e)); 31 } 32 33 34 // Prior to the introduction of a callback object to further filter possible 35 // typo corrections, this example would not trigger a suggestion as "base_type" 36 // is a closer match to "basetype" than is "BaseType" but "base_type" does not 37 // refer to a base class or non-static data member. 38 struct BaseType { }; 39 struct Derived : public BaseType { // expected-note {{base class 'BaseType' specified here}} 40 static int base_type; // expected-note {{'base_type' declared here}} 41 Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}} 42 }; 43 44 // Test the improvement from passing a callback object to CorrectTypo in 45 // the helper function LookupMemberExprInRecord. 46 int get_type(struct Derived *st) { 47 return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}} 48 } 49 50 // In this example, somename should not be corrected to the cached correction 51 // "some_name" since "some_name" is a class and a namespace name is needed. 52 class some_name {}; // expected-note {{'some_name' declared here}} 53 somename Foo; // expected-error {{unknown type name 'somename'; did you mean 'some_name'?}} 54 namespace SomeName {} // expected-note {{namespace 'SomeName' defined here}} 55 using namespace somename; // expected-error {{no namespace named 'somename'; did you mean 'SomeName'?}} 56 57 58 // Without the callback object, CorrectTypo would choose "field1" as the 59 // correction for "fielda" as it is closer than "FieldA", but that correction 60 // would be later discarded by the caller and no suggestion would be given. 61 struct st { 62 struct { 63 int field1; 64 }; 65 double FieldA; // expected-note{{'FieldA' declared here}} 66 }; 67 st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}} 68 69 // Test the improvement from passing a callback object to CorrectTypo in 70 // Sema::BuildCXXNestedNameSpecifier. And also for the improvement by doing 71 // so in Sema::getTypeName. 72 typedef char* another_str; // expected-note{{'another_str' declared here}} 73 namespace AnotherStd { // expected-note{{'AnotherStd' declared here}} 74 class string {}; 75 } 76 another_std::string str; // expected-error{{use of undeclared identifier 'another_std'; did you mean 'AnotherStd'?}} 77 another_str *cstr = new AnotherStr; // expected-error{{unknown type name 'AnotherStr'; did you mean 'another_str'?}} 78 79 // Test the improvement from passing a callback object to CorrectTypo in 80 // Sema::ActOnSizeofParameterPackExpr. 81 char* TireNames; 82 template<typename ...TypeNames> struct count { // expected-note{{parameter pack 'TypeNames' declared here}} 83 static const unsigned value = sizeof...(TyreNames); // expected-error{{'TyreNames' does not refer to the name of a parameter pack; did you mean 'TypeNames'?}} 84 }; 85 86 // Test the typo-correction callback in Sema::DiagnoseUnknownTypeName. 87 namespace unknown_type_test { 88 class StreamOut {}; // expected-note 2 {{'StreamOut' declared here}} 89 long stream_count; // expected-note 2 {{'stream_count' declared here}} 90 }; 91 unknown_type_test::stream_out out; // expected-error{{no type named 'stream_out' in namespace 'unknown_type_test'; did you mean 'StreamOut'?}} 92 93 // Demonstrate a case where using only the cached value returns the wrong thing 94 // when the cached value was the result of a previous callback object that only 95 // accepts a subset of the current callback object. 96 namespace { 97 using namespace unknown_type_test; 98 void bar(long i); 99 void before_caching_classname() { 100 bar((stream_out)); // expected-error{{use of undeclared identifier 'stream_out'; did you mean 'stream_count'?}} 101 } 102 stream_out out; // expected-error{{unknown type name 'stream_out'; did you mean 'StreamOut'?}} 103 void after_caching_classname() { 104 bar((stream_out)); // expected-error{{use of undeclared identifier 'stream_out'; did you mean 'stream_count'?}} 105 } 106 } 107 108 // Test the typo-correction callback in Sema::DiagnoseInvalidRedeclaration. 109 struct BaseDecl { 110 void add_in(int i); 111 }; 112 struct TestRedecl : public BaseDecl { 113 void add_it(int i); // expected-note{{'add_it' declared here}} 114 }; 115 void TestRedecl::add_in(int i) {} // expected-error{{out-of-line definition of 'add_in' does not match any declaration in 'TestRedecl'; did you mean 'add_it'?}} 116 117 // Test the improved typo correction for the Parser::ParseCastExpr => 118 // Sema::ActOnIdExpression => Sema::DiagnoseEmptyLookup call path. 119 class SomeNetMessage; 120 class Message {}; 121 void foo(Message&); 122 void foo(SomeNetMessage&); 123 void doit(void *data) { 124 Message somenetmsg; // expected-note{{'somenetmsg' declared here}} 125 foo(somenetmessage); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'somenetmsg'?}} 126 foo((somenetmessage)data); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'SomeNetMessage'?}} 127 } 128 129 // Test the typo-correction callback in BuildRecoveryCallExpr. 130 // Solves the main issue in PR 9320 of suggesting corrections that take the 131 // wrong number of arguments. 132 void revoke(const char*); // expected-note 2{{'revoke' declared here}} 133 void Test() { 134 Invoke(); // expected-error{{use of undeclared identifier 'Invoke'}} 135 Invoke("foo"); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'revoke'?}} 136 Invoke("foo", "bar"); // expected-error{{use of undeclared identifier 'Invoke'}} 137 } 138 void Test2(void (*invoke)(const char *, int)) { // expected-note{{'invoke' declared here}} 139 Invoke(); // expected-error{{use of undeclared identifier 'Invoke'}} 140 Invoke("foo"); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'revoke'?}} 141 Invoke("foo", 7); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'invoke'?}} 142 Invoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Invoke'}} 143 } 144 145 void provoke(const char *x, bool y=false) {} // expected-note 2{{'provoke' declared here}} 146 void Test3() { 147 Provoke(); // expected-error{{use of undeclared identifier 'Provoke'}} 148 Provoke("foo"); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}} 149 Provoke("foo", true); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}} 150 Provoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Provoke'}} 151 } 152 153 // PR 11737 - Don't try to typo-correct the implicit 'begin' and 'end' in a 154 // C++11 for-range statement. 155 struct R {}; 156 bool begun(R); 157 void RangeTest() { 158 for (auto b : R()) {} // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type}} 159 } 160 161 // PR 12019 - Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration 162 // by not trying to typo-correct a method redeclaration to declarations not 163 // in the current record. 164 class Parent { 165 void set_types(int index, int value); 166 void add_types(int value); 167 }; 168 class Child: public Parent {}; 169 void Child::add_types(int value) {} // expected-error{{out-of-line definition of 'add_types' does not match any declaration in 'Child'}} 170 171 // Fix the callback based filtering of typo corrections within 172 // Sema::ActOnIdExpression by Parser::ParseCastExpression to allow type names as 173 // potential corrections for template arguments. 174 namespace clash { 175 class ConstructExpr {}; // expected-note{{'clash::ConstructExpr' declared here}} 176 } 177 class ClashTool { 178 bool HaveConstructExpr(); 179 template <class T> T* getExprAs(); 180 181 void test() { 182 ConstructExpr *expr = // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}} 183 getExprAs<ConstructExpr>(); // expected-error{{use of undeclared identifier 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}} 184 } 185 }; 186 187 namespace test1 { 188 struct S { 189 struct Foobar *f; // expected-note{{'Foobar' declared here}} 190 }; 191 test1::FooBar *b; // expected-error{{no type named 'FooBar' in namespace 'test1'; did you mean 'Foobar'?}} 192 } 193