forked from OSchip/llvm-project
Convert SemaTemplate*.cpp to pass a callback object to CorrectTypo.
The change to SemaTemplateVariadic.cpp improves the typo correction results in certain situations, while the change to SemaTemplate.cpp does not change existing behavior. llvm-svn: 148155
This commit is contained in:
parent
81bd038623
commit
637b5b3235
|
@ -301,10 +301,15 @@ void Sema::LookupTemplateName(LookupResult &Found,
|
||||||
// If we did not find any names, attempt to correct any typos.
|
// If we did not find any names, attempt to correct any typos.
|
||||||
DeclarationName Name = Found.getLookupName();
|
DeclarationName Name = Found.getLookupName();
|
||||||
Found.clear();
|
Found.clear();
|
||||||
|
// Simple filter callback that, for keywords, only accepts the C++ *_cast
|
||||||
|
CorrectionCandidateCallback FilterCCC;
|
||||||
|
FilterCCC.WantTypeSpecifiers = false;
|
||||||
|
FilterCCC.WantExpressionKeywords = false;
|
||||||
|
FilterCCC.WantRemainingKeywords = false;
|
||||||
|
FilterCCC.WantCXXNamedCasts = true;
|
||||||
if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(),
|
if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(),
|
||||||
Found.getLookupKind(), S, &SS,
|
Found.getLookupKind(), S, &SS,
|
||||||
LookupCtx, false,
|
&FilterCCC, LookupCtx)) {
|
||||||
CTC_CXXCasts)) {
|
|
||||||
Found.setLookupName(Corrected.getCorrection());
|
Found.setLookupName(Corrected.getCorrection());
|
||||||
if (Corrected.getCorrectionDecl())
|
if (Corrected.getCorrectionDecl())
|
||||||
Found.addDecl(Corrected.getCorrectionDecl());
|
Found.addDecl(Corrected.getCorrectionDecl());
|
||||||
|
|
|
@ -708,6 +708,19 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Callback to only accept typo corrections that refer to parameter packs.
|
||||||
|
class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
|
||||||
|
public:
|
||||||
|
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
|
||||||
|
NamedDecl *ND = candidate.getCorrectionDecl();
|
||||||
|
return ND && ND->isParameterPack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Called when an expression computing the size of a parameter pack
|
/// \brief Called when an expression computing the size of a parameter pack
|
||||||
/// is parsed.
|
/// is parsed.
|
||||||
///
|
///
|
||||||
|
@ -733,6 +746,7 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
|
||||||
LookupName(R, S);
|
LookupName(R, S);
|
||||||
|
|
||||||
NamedDecl *ParameterPack = 0;
|
NamedDecl *ParameterPack = 0;
|
||||||
|
ParameterPackValidatorCCC Validator;
|
||||||
switch (R.getResultKind()) {
|
switch (R.getResultKind()) {
|
||||||
case LookupResult::Found:
|
case LookupResult::Found:
|
||||||
ParameterPack = R.getFoundDecl();
|
ParameterPack = R.getFoundDecl();
|
||||||
|
@ -741,19 +755,16 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
|
||||||
case LookupResult::NotFound:
|
case LookupResult::NotFound:
|
||||||
case LookupResult::NotFoundInCurrentInstantiation:
|
case LookupResult::NotFoundInCurrentInstantiation:
|
||||||
if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
|
if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
|
||||||
R.getLookupKind(), S, 0, 0,
|
R.getLookupKind(), S, 0,
|
||||||
false, CTC_NoKeywords)) {
|
&Validator)) {
|
||||||
if (NamedDecl *CorrectedResult = Corrected.getCorrectionDecl())
|
std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
|
||||||
if (CorrectedResult->isParameterPack()) {
|
ParameterPack = Corrected.getCorrectionDecl();
|
||||||
std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
|
Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
|
||||||
ParameterPack = CorrectedResult;
|
<< &Name << CorrectedQuotedStr
|
||||||
Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
|
<< FixItHint::CreateReplacement(
|
||||||
<< &Name << CorrectedQuotedStr
|
NameLoc, Corrected.getAsString(getLangOptions()));
|
||||||
<< FixItHint::CreateReplacement(
|
Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
|
||||||
NameLoc, Corrected.getAsString(getLangOptions()));
|
<< CorrectedQuotedStr;
|
||||||
Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
|
|
||||||
<< CorrectedQuotedStr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case LookupResult::FoundOverloaded:
|
case LookupResult::FoundOverloaded:
|
||||||
|
|
|
@ -41,6 +41,8 @@ struct Derived : public BaseType { // expected-note {{base class 'BaseType' spec
|
||||||
Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}}
|
Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test the improvement from passing a callback object to CorrectTypo in
|
||||||
|
// the helper function LookupMemberExprInRecord.
|
||||||
int get_type(struct Derived *st) {
|
int get_type(struct Derived *st) {
|
||||||
return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}}
|
return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}}
|
||||||
}
|
}
|
||||||
|
@ -64,10 +66,17 @@ struct st {
|
||||||
};
|
};
|
||||||
st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}}
|
st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}}
|
||||||
|
|
||||||
// Test the improvement from passing a callback object to CorrectTypo in
|
// Test the improvement from passing a callback object to CorrectTypo in
|
||||||
// Sema::BuildCXXNestedNameSpecifier.
|
// Sema::BuildCXXNestedNameSpecifier.
|
||||||
typedef char* another_str;
|
typedef char* another_str;
|
||||||
namespace AnotherStd { // expected-note{{'AnotherStd' declared here}}
|
namespace AnotherStd { // expected-note{{'AnotherStd' declared here}}
|
||||||
class string {};
|
class string {};
|
||||||
}
|
}
|
||||||
another_std::string str; // expected-error{{use of undeclared identifier 'another_std'; did you mean 'AnotherStd'?}}
|
another_std::string str; // expected-error{{use of undeclared identifier 'another_std'; did you mean 'AnotherStd'?}}
|
||||||
|
|
||||||
|
// Test the improvement from passing a callback object to CorrectTypo in
|
||||||
|
// Sema::ActOnSizeofParameterPackExpr.
|
||||||
|
char* TireNames;
|
||||||
|
template<typename ...TypeNames> struct count { // expected-note{{parameter pack 'TypeNames' declared here}}
|
||||||
|
static const unsigned value = sizeof...(TyreNames); // expected-error{{'TyreNames' does not refer to the name of a parameter pack; did you mean 'TypeNames'?}}
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue