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:
Kaelyn Uhrain 2012-01-13 23:10:36 +00:00
parent 81bd038623
commit 637b5b3235
3 changed files with 41 additions and 16 deletions

View File

@ -301,10 +301,15 @@ void Sema::LookupTemplateName(LookupResult &Found,
// If we did not find any names, attempt to correct any typos.
DeclarationName Name = Found.getLookupName();
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(),
Found.getLookupKind(), S, &SS,
LookupCtx, false,
CTC_CXXCasts)) {
&FilterCCC, LookupCtx)) {
Found.setLookupName(Corrected.getCorrection());
if (Corrected.getCorrectionDecl())
Found.addDecl(Corrected.getCorrectionDecl());

View File

@ -708,6 +708,19 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
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
/// is parsed.
///
@ -733,6 +746,7 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
LookupName(R, S);
NamedDecl *ParameterPack = 0;
ParameterPackValidatorCCC Validator;
switch (R.getResultKind()) {
case LookupResult::Found:
ParameterPack = R.getFoundDecl();
@ -741,19 +755,16 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
R.getLookupKind(), S, 0, 0,
false, CTC_NoKeywords)) {
if (NamedDecl *CorrectedResult = Corrected.getCorrectionDecl())
if (CorrectedResult->isParameterPack()) {
std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
ParameterPack = CorrectedResult;
Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
<< &Name << CorrectedQuotedStr
<< FixItHint::CreateReplacement(
NameLoc, Corrected.getAsString(getLangOptions()));
Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
<< CorrectedQuotedStr;
}
R.getLookupKind(), S, 0,
&Validator)) {
std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
ParameterPack = Corrected.getCorrectionDecl();
Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
<< &Name << CorrectedQuotedStr
<< FixItHint::CreateReplacement(
NameLoc, Corrected.getAsString(getLangOptions()));
Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
<< CorrectedQuotedStr;
}
case LookupResult::FoundOverloaded:

View File

@ -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'?}}
};
// Test the improvement from passing a callback object to CorrectTypo in
// the helper function LookupMemberExprInRecord.
int get_type(struct Derived *st) {
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'?}}
// Test the improvement from passing a callback object to CorrectTypo in
// Test the improvement from passing a callback object to CorrectTypo in
// Sema::BuildCXXNestedNameSpecifier.
typedef char* another_str;
namespace AnotherStd { // expected-note{{'AnotherStd' declared here}}
class string {};
}
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'?}}
};