diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 77a641a2c5d0..3426e433c5a2 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -259,6 +259,20 @@ private: /// type, which is used for type equality comparisons. llvm::StringMap CachedCompletionTypes; + /// \brief The number of top-level declarations present the last time we + /// cached code-completion results. + /// + /// The value is used to help detect when we should repopulate the global + /// completion cache. + unsigned NumTopLevelDeclsAtLastCompletionCache; + + /// \brief The number of reparses left until we'll consider updating the + /// code-completion cache. + /// + /// This is meant to avoid thrashing during reparsing, by not allowing the + /// code-completion cache to be updated on every reparse. + unsigned CacheCodeCompletionCoolDown; + /// \brief Cache any "global" code-completion results, so that we can avoid /// recomputing them with each completion. void CacheCodeCompletionResults(); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index c66f08df3d4f..428647f03f41 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -53,7 +53,9 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), CompleteTranslationUnit(true), ConcurrencyCheckValue(CheckUnlocked), PreambleRebuildCounter(0), SavedMainFileBuffer(0), - ShouldCacheCodeCompletionResults(false) { + ShouldCacheCodeCompletionResults(false), + NumTopLevelDeclsAtLastCompletionCache(0), + CacheCodeCompletionCoolDown(0) { } ASTUnit::~ASTUnit() { @@ -285,6 +287,10 @@ void ASTUnit::CacheCodeCompletionResults() { if (CachingTimer) CachingTimer->stopTimer(); + + // Make a note of the state when we performed this caching. + NumTopLevelDeclsAtLastCompletionCache = top_level_size(); + CacheCodeCompletionCoolDown = 15; } void ASTUnit::ClearCachedCompletionResults() { @@ -1411,6 +1417,14 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { bool Result = Parse(OverrideMainBuffer); if (ReparsingTimer) ReparsingTimer->stopTimer(); + + if (ShouldCacheCodeCompletionResults) { + if (CacheCodeCompletionCoolDown > 0) + --CacheCodeCompletionCoolDown; + else if (top_level_size() != NumTopLevelDeclsAtLastCompletionCache) + CacheCodeCompletionResults(); + } + return Result; }