When typo-correcting a function name, consider correcting to a type name

for a function-style cast.

llvm-svn: 360302
This commit is contained in:
Richard Smith 2019-05-09 00:57:24 +00:00
parent c93f56d39e
commit 2194fb6ed9
5 changed files with 29 additions and 13 deletions

View File

@ -2068,8 +2068,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
AcceptableWithoutRecovery =
isa<TypeDecl>(UnderlyingND) || isa<ObjCInterfaceDecl>(UnderlyingND);
} else {
// FIXME: We found a keyword. Suggest it, but don't provide a fix-it
// because we aren't able to recover.
// FIXME: We found a keyword or a type. Suggest it, but don't provide a
// fix-it because we aren't able to recover.
AcceptableWithoutRecovery = true;
}

View File

@ -4996,7 +4996,9 @@ FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
: NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs),
CurContext(SemaRef.CurContext), MemberFn(ME) {
WantTypeSpecifiers = false;
WantFunctionLikeCasts = SemaRef.getLangOpts().CPlusPlus && NumArgs == 1;
WantFunctionLikeCasts = SemaRef.getLangOpts().CPlusPlus &&
!HasExplicitTemplateArgs && NumArgs == 1;
WantCXXNamedCasts = HasExplicitTemplateArgs && NumArgs == 1;
WantRemainingKeywords = false;
}
@ -5025,6 +5027,13 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) {
}
}
// A typo for a function-style cast can look like a function call in C++.
if ((HasExplicitTemplateArgs ? getAsTypeTemplateDecl(ND) != nullptr
: isa<TypeDecl>(ND)) &&
CurContext->getParentASTContext().getLangOpts().CPlusPlus)
// Only a class or class template can take two or more arguments.
return NumArgs <= 1 || HasExplicitTemplateArgs || isa<CXXRecordDecl>(ND);
// Skip the current candidate if it is not a FunctionDecl or does not accept
// the current number of arguments.
if (!FD || !(FD->getNumParams() >= NumArgs &&

View File

@ -9,14 +9,14 @@ struct S
static int v; //expected-error{{redefinition of 'v' as different kind of symbol}}
int v; //expected-error{{duplicate member 'v'}}
static int v; //expected-error{{redefinition of 'v' as different kind of symbol}}
enum EnumT { E = 10 };
enum EnumT { E = 10 }; // expected-note {{declared here}}
friend struct M;
struct X; //expected-note{{forward declaration of 'S::X'}}
friend struct X;
};
S::EnumT Evar = S::E; // ok
S::EnumT Evar2 = EnumT(); //expected-error{{use of undeclared identifier 'EnumT'}}
S::EnumT Evar2 = EnumT(); //expected-error{{use of undeclared identifier 'EnumT'; did you mean 'S::EnumT'?}}
S::M m; //expected-error{{no type named 'M' in 'S'}}
S::X x; //expected-error{{variable has incomplete type 'S::X'}}

View File

@ -8,3 +8,10 @@
float f(int y) {
return static_cst<float>(y); // expected-error{{use of undeclared identifier 'static_cst'; did you mean 'static_cast'?}}
}
struct Foobar {}; // expected-note {{here}}
template<typename T> struct Goobar {}; // expected-note {{here}}
void use_foobar() {
auto x = zoobar(); // expected-error {{did you mean 'Foobar'}}
auto y = zoobar<int>(); // expected-error {{did you mean 'Goobar'}}
}

View File

@ -344,20 +344,20 @@ void zif::nab(int) {
namespace TemplateFunction {
template <class T>
void A(T) { } // expected-note {{'::TemplateFunction::A' declared here}}
void fnA(T) { } // expected-note {{'::TemplateFunction::fnA' declared here}}
template <class T>
void B(T) { } // expected-note {{'::TemplateFunction::B' declared here}}
void fnB(T) { } // expected-note {{'::TemplateFunction::fnB' declared here}}
class Foo {
public:
void A(int, int) {}
void B() {}
void fnA(int, int) {}
void fnB() {}
};
void test(Foo F, int num) {
F.A(num); // expected-error {{too few arguments to function call, expected 2, have 1; did you mean '::TemplateFunction::A'?}}
F.B(num); // expected-error {{too many arguments to function call, expected 0, have 1; did you mean '::TemplateFunction::B'?}}
F.fnA(num); // expected-error {{too few arguments to function call, expected 2, have 1; did you mean '::TemplateFunction::fnA'?}}
F.fnB(num); // expected-error {{too many arguments to function call, expected 0, have 1; did you mean '::TemplateFunction::fnB'?}}
}
}
namespace using_suggestion_val_dropped_specifier {
@ -537,9 +537,9 @@ namespace no_correct_template_id_to_non_template {
namespace PR18852 {
void func() {
struct foo {
void bar() {}
void barberry() {}
};
bar(); // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
barberry(); // expected-error-re {{use of undeclared identifier 'barberry'{{$}}}}
}
class Thread {