forked from OSchip/llvm-project
Convert SemaInit.cpp to pass a callback object to CorrectTypo.
And once again improve the typo correction results in certain situations just by moving the existing checks on the correction. llvm-svn: 148037
This commit is contained in:
parent
3d3aea9374
commit
b02c5e9356
|
@ -1529,6 +1529,26 @@ static DesignatedInitExpr *CloneDesignatedInitExpr(Sema &SemaRef,
|
||||||
DIE->usesGNUSyntax(), DIE->getInit());
|
DIE->usesGNUSyntax(), DIE->getInit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Callback to only accept typo corrections that are for field members of
|
||||||
|
// the given struct or union.
|
||||||
|
class FieldInitializerValidatorCCC : public CorrectionCandidateCallback {
|
||||||
|
public:
|
||||||
|
explicit FieldInitializerValidatorCCC(RecordDecl *RD)
|
||||||
|
: Record(RD) {}
|
||||||
|
|
||||||
|
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
|
||||||
|
FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>();
|
||||||
|
return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RecordDecl *Record;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Check the well-formedness of a C99 designated initializer.
|
/// @brief Check the well-formedness of a C99 designated initializer.
|
||||||
///
|
///
|
||||||
/// Determines whether the designated initializer @p DIE, which
|
/// Determines whether the designated initializer @p DIE, which
|
||||||
|
@ -1687,19 +1707,17 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
|
||||||
if (Lookup.first == Lookup.second) {
|
if (Lookup.first == Lookup.second) {
|
||||||
// Name lookup didn't find anything. Determine whether this
|
// Name lookup didn't find anything. Determine whether this
|
||||||
// was a typo for another field name.
|
// was a typo for another field name.
|
||||||
LookupResult R(SemaRef, FieldName, D->getFieldLoc(),
|
FieldInitializerValidatorCCC Validator(RT->getDecl());
|
||||||
Sema::LookupMemberName);
|
|
||||||
TypoCorrection Corrected = SemaRef.CorrectTypo(
|
TypoCorrection Corrected = SemaRef.CorrectTypo(
|
||||||
DeclarationNameInfo(FieldName, D->getFieldLoc()),
|
DeclarationNameInfo(FieldName, D->getFieldLoc()),
|
||||||
Sema::LookupMemberName, /*Scope=*/NULL, /*SS=*/NULL,
|
Sema::LookupMemberName, /*Scope=*/0, /*SS=*/0, &Validator,
|
||||||
RT->getDecl(), false, Sema::CTC_NoKeywords);
|
RT->getDecl());
|
||||||
if ((ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>()) &&
|
if (Corrected) {
|
||||||
ReplacementField->getDeclContext()->getRedeclContext()
|
|
||||||
->Equals(RT->getDecl())) {
|
|
||||||
std::string CorrectedStr(
|
std::string CorrectedStr(
|
||||||
Corrected.getAsString(SemaRef.getLangOptions()));
|
Corrected.getAsString(SemaRef.getLangOptions()));
|
||||||
std::string CorrectedQuotedStr(
|
std::string CorrectedQuotedStr(
|
||||||
Corrected.getQuoted(SemaRef.getLangOptions()));
|
Corrected.getQuoted(SemaRef.getLangOptions()));
|
||||||
|
ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>();
|
||||||
SemaRef.Diag(D->getFieldLoc(),
|
SemaRef.Diag(D->getFieldLoc(),
|
||||||
diag::err_field_designator_unknown_suggest)
|
diag::err_field_designator_unknown_suggest)
|
||||||
<< FieldName << CurrentObjectType << CorrectedQuotedStr
|
<< FieldName << CurrentObjectType << CorrectedQuotedStr
|
||||||
|
|
|
@ -47,3 +47,15 @@ class some_name {}; // expected-note {{'some_name' declared here}}
|
||||||
somename Foo; // expected-error {{unknown type name 'somename'; did you mean 'some_name'?}}
|
somename Foo; // expected-error {{unknown type name 'somename'; did you mean 'some_name'?}}
|
||||||
namespace SomeName {} // expected-note {{namespace 'SomeName' defined here}}
|
namespace SomeName {} // expected-note {{namespace 'SomeName' defined here}}
|
||||||
using namespace somename; // expected-error {{no namespace named 'somename'; did you mean 'SomeName'?}}
|
using namespace somename; // expected-error {{no namespace named 'somename'; did you mean 'SomeName'?}}
|
||||||
|
|
||||||
|
|
||||||
|
// Without the callback object, CorrectTypo would choose "field1" as the
|
||||||
|
// correction for "fielda" as it is closer than "FieldA", but that correction
|
||||||
|
// would be later discarded by the caller and no suggestion would be given.
|
||||||
|
struct st {
|
||||||
|
struct {
|
||||||
|
int field1;
|
||||||
|
};
|
||||||
|
double FieldA; // expected-note{{'FieldA' declared here}}
|
||||||
|
};
|
||||||
|
st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}}
|
||||||
|
|
Loading…
Reference in New Issue