Avoid the hard-coded limit on the number of typo corrections attempted.

Move some tests from typo-correction.cpp to typo-correction-pt2.cpp
because they were running afoul of the hard-coded limit of 20 typos
corrected. Some of the tests after it were still working due to the
limit not applying to cached corrections and in cases where a non-NULL
MemberContext is passed in to Sema::CorrectTypo.  Most of the moved tests
still passed after being moved, but the test involving "data_struct" had
only been passing because the test had exceeded that limit so a fix for
it is also included (most of the changes to ParseStmt.cpp are shared with
and originated from another typo correction impovement that was split
into a separate commit).

llvm-svn: 191544
This commit is contained in:
Kaelyn Uhrain 2013-09-27 19:40:12 +00:00
parent 0e23844f57
commit 3dfff19658
3 changed files with 66 additions and 48 deletions

View File

@ -111,6 +111,33 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
}
namespace {
class StatementFilterCCC : public CorrectionCandidateCallback {
public:
StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) ||
nextTok.is(tok::identifier) || nextTok.is(tok::star) ||
nextTok.is(tok::amp) || nextTok.is(tok::l_square);
WantExpressionKeywords = nextTok.is(tok::l_paren) ||
nextTok.is(tok::identifier) ||
nextTok.is(tok::arrow) || nextTok.is(tok::period);
WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) ||
nextTok.is(tok::identifier) ||
nextTok.is(tok::l_brace);
WantCXXNamedCasts = false;
}
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
return isa<ObjCIvarDecl>(FD);
return CorrectionCandidateCallback::ValidateCandidate(candidate);
}
private:
Token NextToken;
};
}
StmtResult
Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
bool OnlyStatement, SourceLocation *TrailingElseLoc,
@ -149,21 +176,8 @@ Retry:
if (Next.isNot(tok::coloncolon)) {
// Try to limit which sets of keywords should be included in typo
// correction based on what the next token is.
// FIXME: Pass the next token into the CorrectionCandidateCallback and
// do this filtering in a more fine-grained manner.
CorrectionCandidateCallback DefaultValidator;
DefaultValidator.WantTypeSpecifiers =
Next.is(tok::l_paren) || Next.is(tok::less) ||
Next.is(tok::identifier) || Next.is(tok::star) ||
Next.is(tok::amp) || Next.is(tok::l_square);
DefaultValidator.WantExpressionKeywords =
Next.is(tok::l_paren) || Next.is(tok::identifier) ||
Next.is(tok::arrow) || Next.is(tok::period);
DefaultValidator.WantRemainingKeywords =
Next.is(tok::l_paren) || Next.is(tok::semi) ||
Next.is(tok::identifier) || Next.is(tok::l_brace);
DefaultValidator.WantCXXNamedCasts = false;
if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator)
StatementFilterCCC Validator(Next);
if (TryAnnotateName(/*IsAddressOfOperand*/false, &Validator)
== ANK_Error) {
// Handle errors here by skipping up to the next semicolon or '}', and
// eat the semicolon if that's what stopped us.

View File

@ -5,6 +5,37 @@
// attempt within a single file (which is to avoid having very broken files take
// minutes to finally be rejected by the parser).
namespace bogus_keyword_suggestion {
void test() {
status = "OK"; // expected-error-re {{use of undeclared identifier 'status'$}}
return status; // expected-error-re {{use of undeclared identifier 'status'$}}
}
}
namespace PR13387 {
struct A {
void CreateFoo(float, float);
void CreateBar(float, float);
};
struct B : A {
using A::CreateFoo;
void CreateFoo(int, int);
};
void f(B &x) {
x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
}
}
struct DataStruct {void foo();};
struct T {
DataStruct data_struct;
void f();
};
// should be void T::f();
void f() {
data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
}
namespace PR12287 {
class zif {
void nab(int);

View File

@ -246,37 +246,6 @@ namespace outer {
}
}
namespace bogus_keyword_suggestion {
void test() {
status = "OK"; // expected-error-re{{use of undeclared identifier 'status'$}}
return status; // expected-error-re{{use of undeclared identifier 'status'$}}
}
}
namespace PR13387 {
struct A {
void CreateFoo(float, float);
void CreateBar(float, float);
};
struct B : A {
using A::CreateFoo;
void CreateFoo(int, int);
};
void f(B &x) {
x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
}
}
struct DataStruct {void foo();};
struct T {
DataStruct data_struct;
void f();
};
// should be void T::f();
void f() {
data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
}
namespace b6956809_test1 {
struct A {};
struct B {};
@ -319,9 +288,13 @@ namespace b6956809_test2 {
}
}
// This test should have one correction, followed by an error without a
// suggestion due to exceeding the maximum number of typos for which correction
// is attempted.
namespace CorrectTypo_has_reached_its_limit {
int flibberdy(); // no note here
int flibberdy(); // expected-note{{'flibberdy' declared here}}
int no_correction() {
return gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'$}}
return hibberdy() + // expected-error{{use of undeclared identifier 'hibberdy'; did you mean 'flibberdy'?}}
gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'$}}
};
}