Add a stop gap to Sema::CorrectTypo() to correct only up to 20 typos.

This is to address a serious performance problem observed when running
'clang -fsyntax-only' on really broken source files.  In one case,
repeatedly calling CorrectTypo() caused one source file to be rejected
after 2 minutes instead of 1 second.

This patch causes typo correction to take neglible time on that file
while still providing correction results for the first 20 cases.  I
felt this was a reasonable number for moderately broken source files.

I don't claim this is the best solution.  Comments welcome.  It is
necessary for us to address this issue because it is a serious
performance problem.

llvm-svn: 95049
This commit is contained in:
Ted Kremenek 2010-02-02 02:07:01 +00:00
parent fab459fc95
commit 545168268b
3 changed files with 12 additions and 2 deletions

View File

@ -364,7 +364,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
GlobalNewDeleteDeclared(false),
CompleteTranslationUnit(CompleteTranslationUnit),
NumSFINAEErrors(0), NonInstantiationEntries(0),
CurrentInstantiationScope(0)
CurrentInstantiationScope(0), TyposCorrected(0)
{
TUScope = 0;
if (getLangOptions().CPlusPlus)

View File

@ -3305,6 +3305,9 @@ public:
/// variables.
LocalInstantiationScope *CurrentInstantiationScope;
/// \brief The number of typos corrected by CorrectTypo.
unsigned TyposCorrected;
/// \brief An entity for which implicit template instantiation is required.
///
/// The source location associated with the declaration is the first place in

View File

@ -2348,9 +2348,16 @@ void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
bool Sema::CorrectTypo(LookupResult &Res, Scope *S, const CXXScopeSpec *SS,
DeclContext *MemberContext, bool EnteringContext,
const ObjCObjectPointerType *OPT) {
if (Diags.hasFatalErrorOccurred())
return false;
// 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.
// FIXME: Is this the right solution?
if (TyposCorrected == 20)
return false;
++TyposCorrected;
// We only attempt to correct typos for identifiers.
IdentifierInfo *Typo = Res.getLookupName().getAsIdentifierInfo();