summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2014-12-16 21:39:02 +0000
committerNick Lewycky <nicholas@mxc.ca>2014-12-16 21:39:02 +0000
commit246532627e1493ce7605efda3ef152aeda0d9001 (patch)
tree7f6e55807d78bb8bf863b6887e4b6f78aa8b3053 /clang/lib
parentf5acc8c625372597d033aec2cf1c1ef0db5434f7 (diff)
downloadbcm5719-llvm-246532627e1493ce7605efda3ef152aeda0d9001.tar.gz
bcm5719-llvm-246532627e1493ce7605efda3ef152aeda0d9001.zip
Add a new flag, -fspell-checking-limit=<number> to control how many times we'll do spell checking. Note that spell checking will change the produced AST, so we don't automatically change this value when someone sets -ferror-limit=. With this, merge test typo-correction-pt2.cpp into typo-correction.cpp.
Remove Sema::UnqualifiedTyposCorrected, a cache of corrected typos. It would only cache typo corrections that didn't provide ValidateCandidate of which there were few left, and it had a bug when we had the same identifier spelled wrong twice. See the last two tests in typo-correction.cpp for cases this fires. llvm-svn: 224375
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Tools.cpp6
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Sema/SemaLookup.cpp85
3 files changed, 24 insertions, 70 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 940be7e22c3..111a3834809 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3546,6 +3546,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
+ CmdArgs.push_back("-fspell-checking-limit");
+ CmdArgs.push_back(A->getValue());
+ }
+
// Pass -fmessage-length=.
CmdArgs.push_back("-fmessage-length");
if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
@@ -8306,4 +8311,3 @@ void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
}
-
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 610bfffc7ea..97be3d3fbf2 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -707,6 +707,9 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.ConstexprBacktraceLimit = getLastArgIntValue(
Args, OPT_fconstexpr_backtrace_limit,
DiagnosticOptions::DefaultConstexprBacktraceLimit, Diags);
+ Opts.SpellCheckingLimit = getLastArgIntValue(
+ Args, OPT_fspell_checking_limit,
+ DiagnosticOptions::DefaultSpellCheckingLimit, Diags);
Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
DiagnosticOptions::DefaultTabStop, Diags);
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e1a9a554b34..3445264461f 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4023,8 +4023,7 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
Scope *S, CXXScopeSpec *SS,
std::unique_ptr<CorrectionCandidateCallback> CCC,
DeclContext *MemberContext, bool EnteringContext,
- const ObjCObjectPointerType *OPT, bool ErrorRecovery,
- bool &IsUnqualifiedLookup) {
+ const ObjCObjectPointerType *OPT, bool ErrorRecovery) {
if (Diags.hasFatalErrorOccurred() || !getLangOpts().SpellChecking ||
DisableTypoCorrection)
@@ -4068,6 +4067,14 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
if (getLangOpts().AltiVec && Typo->isStr("vector"))
return nullptr;
+ // Provide a stop gap for files that are just seriously broken. Trying
+ // to correct all typos can turn into a HUGE performance penalty, causing
+ // some files to take minutes to get rejected by the parser.
+ unsigned Limit = getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
+ if (Limit && TyposCorrected >= Limit)
+ return nullptr;
+ ++TyposCorrected;
+
// If we're handling a missing symbol error, using modules, and the
// special search all modules option is used, look for a missing import.
if (ErrorRecovery && getLangOpts().Modules &&
@@ -4082,13 +4089,8 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
*this, TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
EnteringContext);
- // If a callback object considers an empty typo correction candidate to be
- // viable, assume it does not do any actual validation of the candidates.
- TypoCorrection EmptyCorrection;
- bool ValidatingCallback = !isCandidateViable(CCCRef, EmptyCorrection);
-
// Perform name lookup to find visible, similarly-named entities.
- IsUnqualifiedLookup = false;
+ bool IsUnqualifiedLookup = false;
DeclContext *QualifiedDC = MemberContext;
if (MemberContext) {
LookupVisibleDecls(MemberContext, LookupKind, *Consumer);
@@ -4103,46 +4105,9 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
if (!QualifiedDC)
return nullptr;
- // Provide a stop gap for files that are just seriously broken. Trying
- // to correct all typos can turn into a HUGE performance penalty, causing
- // some files to take minutes to get rejected by the parser.
- if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20)
- return nullptr;
- ++TyposCorrected;
-
LookupVisibleDecls(QualifiedDC, LookupKind, *Consumer);
} else {
IsUnqualifiedLookup = true;
- UnqualifiedTyposCorrectedMap::iterator Cached
- = UnqualifiedTyposCorrected.find(Typo);
- if (Cached != UnqualifiedTyposCorrected.end()) {
- // Add the cached value, unless it's a keyword or fails validation. In the
- // keyword case, we'll end up adding the keyword below.
- if (Cached->second) {
- if (!Cached->second.isKeyword() &&
- isCandidateViable(CCCRef, Cached->second)) {
- // Do not use correction that is unaccessible in the given scope.
- NamedDecl *CorrectionDecl = Cached->second.getCorrectionDecl();
- DeclarationNameInfo NameInfo(CorrectionDecl->getDeclName(),
- CorrectionDecl->getLocation());
- LookupResult R(*this, NameInfo, LookupOrdinaryName);
- if (LookupName(R, S))
- Consumer->addCorrection(Cached->second);
- }
- } else {
- // Only honor no-correction cache hits when a callback that will validate
- // correction candidates is not being used.
- if (!ValidatingCallback)
- return nullptr;
- }
- }
- if (Cached == UnqualifiedTyposCorrected.end()) {
- // Provide a stop gap for files that are just seriously broken. Trying
- // to correct all typos can turn into a HUGE performance penalty, causing
- // some files to take minutes to get rejected by the parser.
- if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20)
- return nullptr;
- }
}
// Determine whether we are going to search in the various namespaces for
@@ -4249,30 +4214,24 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
// for CTC_Unknown but not for CTC_ObjCMessageReceiver.
bool ObjCMessageReceiver = CCC->WantObjCSuper && !CCC->WantRemainingKeywords;
- TypoCorrection EmptyCorrection;
- bool ValidatingCallback = !isCandidateViable(*CCC, EmptyCorrection);
-
IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();
- bool IsUnqualifiedLookup = false;
auto Consumer = makeTypoCorrectionConsumer(
TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
- EnteringContext, OPT, Mode == CTK_ErrorRecovery, IsUnqualifiedLookup);
+ EnteringContext, OPT, Mode == CTK_ErrorRecovery);
if (!Consumer)
return TypoCorrection();
// If we haven't found anything, we're done.
if (Consumer->empty())
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
- IsUnqualifiedLookup);
+ return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
// Make sure the best edit distance (prior to adding any namespace qualifiers)
// is not more that about a third of the length of the typo's identifier.
unsigned ED = Consumer->getBestEditDistance(true);
unsigned TypoLen = Typo->getName().size();
if (ED > 0 && TypoLen / ED < 3)
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
- IsUnqualifiedLookup);
+ return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
TypoCorrection BestTC = Consumer->getNextCorrection();
TypoCorrection SecondBestTC = Consumer->getNextCorrection();
@@ -4285,8 +4244,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
// If this was an unqualified lookup and we believe the callback
// object wouldn't have filtered out possible corrections, note
// that no correction was found.
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
- IsUnqualifiedLookup && !ValidatingCallback);
+ return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
}
// If only a single name remains, return that result.
@@ -4299,10 +4257,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
if (ED == 0 && Result.isKeyword())
return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
- // Record the correction for unqualified lookup.
- if (IsUnqualifiedLookup)
- UnqualifiedTyposCorrected[Typo] = Result;
-
TypoCorrection TC = Result;
TC.setCorrectionRange(SS, TypoName);
checkCorrectionVisibility(*this, TC);
@@ -4323,10 +4277,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
BestTC.getCorrection().getAsString() != "super")
return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
- // Record the correction for unqualified lookup.
- if (IsUnqualifiedLookup)
- UnqualifiedTyposCorrected[Typo] = BestTC;
-
BestTC.setCorrectionRange(SS, TypoName);
return BestTC;
}
@@ -4334,8 +4284,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
// Record the failure's location if needed and return an empty correction. If
// this was an unqualified lookup and we believe the callback object did not
// filter out possible corrections, also cache the failure for the typo.
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
- IsUnqualifiedLookup && !ValidatingCallback);
+ return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
}
/// \brief Try to "correct" a typo in the source code by finding
@@ -4386,13 +4335,11 @@ TypoExpr *Sema::CorrectTypoDelayed(
assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
TypoCorrection Empty;
- bool IsUnqualifiedLookup = false;
auto Consumer = makeTypoCorrectionConsumer(
TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
EnteringContext, OPT,
/*SearchModules=*/(Mode == CTK_ErrorRecovery) && getLangOpts().Modules &&
- getLangOpts().ModulesSearchAll,
- IsUnqualifiedLookup);
+ getLangOpts().ModulesSearchAll);
if (!Consumer || Consumer->empty())
return nullptr;
OpenPOWER on IntegriCloud