Perform typo correction for base class specifiers.

llvm-svn: 159046
This commit is contained in:
Kaelyn Uhrain 2012-06-22 23:37:05 +00:00
parent 460e94d842
commit 9cb8e9fc89
4 changed files with 20 additions and 6 deletions

View File

@ -5550,6 +5550,8 @@ def warn_missing_method_return_type : Warning<
InGroup<MissingMethodReturnType>, DefaultIgnore;
// Spell-checking diagnostics
def err_unknown_type_or_class_name_suggest : Error<
"unknown %select{type|class}2 name %0; did you mean %1?">;
def err_unknown_typename_suggest : Error<
"unknown type name %0; did you mean %1?">;
def err_unknown_nested_typename_suggest : Error<

View File

@ -874,10 +874,12 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
}
// We have an identifier; check whether it is actually a type.
IdentifierInfo *CorrectedII = 0;
ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
false, ParsedType(),
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo=*/true);
/*NonTrivialTypeSourceInfo=*/true,
&CorrectedII);
if (!Type) {
Diag(IdLoc, diag::err_expected_class_name);
return true;

View File

@ -60,7 +60,8 @@ namespace {
class TypeNameValidatorCCC : public CorrectionCandidateCallback {
public:
TypeNameValidatorCCC(bool AllowInvalid) : AllowInvalidDecl(AllowInvalid) {
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false)
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) {
WantExpressionKeywords = false;
WantCXXNamedCasts = false;
WantRemainingKeywords = false;
@ -71,11 +72,12 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
(AllowInvalidDecl || !ND->isInvalidDecl());
else
return candidate.isKeyword();
return !WantClassName && candidate.isKeyword();
}
private:
bool AllowInvalidDecl;
bool WantClassName;
};
}
@ -209,7 +211,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
TypeNameValidatorCCC Validator(true);
TypeNameValidatorCCC Validator(true, isClassName);
TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(),
Kind, S, SS, Validator);
IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
@ -238,8 +240,8 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
std::string CorrectedStr(Correction.getAsString(getLangOpts()));
std::string CorrectedQuotedStr(
Correction.getQuoted(getLangOpts()));
Diag(NameLoc, diag::err_unknown_typename_suggest)
<< Result.getLookupName() << CorrectedQuotedStr
Diag(NameLoc, diag::err_unknown_type_or_class_name_suggest)
<< Result.getLookupName() << CorrectedQuotedStr << isClassName
<< FixItHint::CreateReplacement(SourceRange(NameLoc),
CorrectedStr);
if (NamedDecl *FirstDecl = Correction.getCorrectionDecl())

View File

@ -219,3 +219,11 @@ namespace PR13051 {
f(&S<int>::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S<int>'$}}
}
}
namespace PR6325 {
class foo { }; // expected-note{{'foo' declared here}}
// Note that for this example (pulled from the PR), if keywords are not excluded
// as correction candidates then no suggestion would be given; correcting
// 'boo' to 'bool' is the same edit distance as correcting 'boo' to 'foo'.
class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}}
}