diff options
| author | Nick Lewycky <nicholas@mxc.ca> | 2014-12-16 21:39:02 +0000 |
|---|---|---|
| committer | Nick Lewycky <nicholas@mxc.ca> | 2014-12-16 21:39:02 +0000 |
| commit | 246532627e1493ce7605efda3ef152aeda0d9001 (patch) | |
| tree | 7f6e55807d78bb8bf863b6887e4b6f78aa8b3053 /clang/lib | |
| parent | f5acc8c625372597d033aec2cf1c1ef0db5434f7 (diff) | |
| download | bcm5719-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.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 85 |
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; |

