summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-06-18 14:34:13 +0200
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-06-21 08:44:37 +0000
commit43ac160b1aa4d98ad07f1e8dde5e445593dc8d91 (patch)
tree6f33e2af21b7bd1b987e668d64c74627da5675db /lib
parent7e438f61d9caa617562cd650bf6578be64be94ac (diff)
[Frontend] Share global completions cache
Append ASTUnit cache with global completions cache. In case of multiple translation units for the same file reduces the memory consumption and save completions cache generation time. Change-Id: I9acd8734f81f622fedd3aac08dbd45e208a70918 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'lib')
-rw-r--r--lib/Frontend/ASTUnit.cpp164
1 files changed, 91 insertions, 73 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index b1a6583714..2a498498e8 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -348,6 +348,7 @@ void ASTUnit::CacheCodeCompletionResults() {
llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);
+ std::vector<CachedCodeCompletionResult> CachedCompletionResults;
for (Result &R : Results) {
switch (R.Kind) {
case Result::RK_Declaration: {
@@ -466,11 +467,15 @@ void ASTUnit::CacheCodeCompletionResults() {
}
// Save the current top-level hash value.
- CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
+ StringRef MainFilePath = getMainFileName();
+ std::lock_guard<std::recursive_mutex> Lock(CacheMutex);
+ ASTUnitCacheMap[MainFilePath].CachedCompletionResults = std::move(CachedCompletionResults);
+ ASTUnitCacheMap[MainFilePath].CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
}
void ASTUnit::ClearCachedCompletionResults() {
- CachedCompletionResults.clear();
+ std::lock_guard<std::recursive_mutex> Lock(CacheMutex);
+ ASTUnitCacheMap[getMainFileName()].CachedCompletionResults.clear();
CachedCompletionTypes.clear();
CachedCompletionAllocator = nullptr;
}
@@ -1377,7 +1382,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
// entities the last time we rebuilt the preamble, clear out the completion
// cache.
if (NewPreambleTopLevelHashValue != PreambleTopLevelHashValue) {
- CompletionCacheTopLevelHashValue = 0;
+ ASTUnitCacheMap[MainFilePath].CompletionCacheTopLevelHashValue = 0;
PreambleTopLevelHashValue = NewPreambleTopLevelHashValue;
}
@@ -1843,11 +1848,16 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
bool Result =
Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
- // If we're caching global code-completion results, and the top-level
- // declarations have changed, clear out the code-completion cache.
- if (!Result && ShouldCacheCodeCompletionResults &&
- CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
- CacheCodeCompletionResults();
+ {
+ std::lock_guard<std::recursive_mutex> Lock(CacheMutex);
+ // If we're caching global code-completion results, and the top-level
+ // declarations have changed, clear out the code-completion cache.
+ if (!Result && ShouldCacheCodeCompletionResults &&
+ CurrentTopLevelHashValue !=
+ ASTUnitCacheMap[MainFilePath].CompletionCacheTopLevelHashValue) {
+ CacheCodeCompletionResults();
+ }
+ }
// We now need to clear out the completion info related to this translation
// unit; it'll be recreated if necessary.
@@ -2028,72 +2038,74 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
typedef CodeCompletionResult Result;
SmallVector<Result, 8> AllResults;
- for (ASTUnit::cached_completion_iterator
- C = AST.cached_completion_begin(),
- CEnd = AST.cached_completion_end();
- C != CEnd; ++C) {
- // If the context we are in matches any of the contexts we are
- // interested in, we'll add this result.
- if ((C->ShowInContexts & InContexts) == 0)
- continue;
-
- // If we haven't added any results previously, do so now.
- if (!AddedResult) {
- CalculateHiddenNames(Context, Results, NumResults, S.Context,
- HiddenNames);
- AllResults.insert(AllResults.end(), Results, Results + NumResults);
- AddedResult = true;
- }
-
- // Determine whether this global completion result is hidden by a local
- // completion result. If so, skip it.
- if (C->Kind != CXCursor_MacroDefinition &&
- HiddenNames.count(C->Completion->getTypedText()))
- continue;
-
- // Adjust priority based on similar type classes.
- unsigned Priority = C->Priority;
- CodeCompletionString *Completion = C->Completion;
- if (!Context.getPreferredType().isNull()) {
- if (C->Kind == CXCursor_MacroDefinition) {
- Priority = getMacroUsagePriority(C->Completion->getTypedText(),
- S.getLangOpts(),
- Context.getPreferredType()->isAnyPointerType());
- } else if (C->Type) {
- CanQualType Expected
- = S.Context.getCanonicalType(
- Context.getPreferredType().getUnqualifiedType());
- SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
- if (ExpectedSTC == C->TypeClass) {
- // We know this type is similar; check for an exact match.
- llvm::StringMap<unsigned> &CachedCompletionTypes
- = AST.getCachedCompletionTypes();
- llvm::StringMap<unsigned>::iterator Pos
- = CachedCompletionTypes.find(QualType(Expected).getAsString());
- if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
- Priority /= CCF_ExactTypeMatch;
- else
- Priority /= CCF_SimilarTypeMatch;
+
+ {
+ std::lock_guard<std::recursive_mutex> Lock(ASTUnit::getCacheMutex());
+ for (ASTUnit::cached_completion_iterator C = AST.cached_completion_begin(),
+ CEnd = AST.cached_completion_end();
+ C != CEnd; ++C) {
+ // If the context we are in matches any of the contexts we are
+ // interested in, we'll add this result.
+ if ((C->ShowInContexts & InContexts) == 0)
+ continue;
+
+ // If we haven't added any results previously, do so now.
+ if (!AddedResult) {
+ CalculateHiddenNames(Context, Results, NumResults, S.Context,
+ HiddenNames);
+ AllResults.insert(AllResults.end(), Results, Results + NumResults);
+ AddedResult = true;
+ }
+
+ // Determine whether this global completion result is hidden by a local
+ // completion result. If so, skip it.
+ if (C->Kind != CXCursor_MacroDefinition &&
+ HiddenNames.count(C->Completion->getTypedText()))
+ continue;
+
+ // Adjust priority based on similar type classes.
+ unsigned Priority = C->Priority;
+ CodeCompletionString *Completion = C->Completion;
+ if (!Context.getPreferredType().isNull()) {
+ if (C->Kind == CXCursor_MacroDefinition) {
+ Priority = getMacroUsagePriority(
+ C->Completion->getTypedText(), S.getLangOpts(),
+ Context.getPreferredType()->isAnyPointerType());
+ } else if (C->Type) {
+ CanQualType Expected = S.Context.getCanonicalType(
+ Context.getPreferredType().getUnqualifiedType());
+ SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
+ if (ExpectedSTC == C->TypeClass) {
+ // We know this type is similar; check for an exact match.
+ llvm::StringMap<unsigned> &CachedCompletionTypes =
+ AST.getCachedCompletionTypes();
+ llvm::StringMap<unsigned>::iterator Pos =
+ CachedCompletionTypes.find(QualType(Expected).getAsString());
+ if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
+ Priority /= CCF_ExactTypeMatch;
+ else
+ Priority /= CCF_SimilarTypeMatch;
+ }
}
}
+
+ // Adjust the completion string, if required.
+ if (C->Kind == CXCursor_MacroDefinition &&
+ Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
+ // Create a new code-completion string that just contains the
+ // macro name, without its arguments.
+ CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
+ CCP_CodePattern, C->Availability);
+ Builder.AddTypedTextChunk(C->Completion->getTypedText());
+ Priority = CCP_CodePattern;
+ Completion = Builder.TakeString();
+ }
+
+ AllResults.push_back(
+ Result(Completion, Priority, C->Kind, C->Availability));
}
-
- // Adjust the completion string, if required.
- if (C->Kind == CXCursor_MacroDefinition &&
- Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
- // Create a new code-completion string that just contains the
- // macro name, without its arguments.
- CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
- CCP_CodePattern, C->Availability);
- Builder.AddTypedTextChunk(C->Completion->getTypedText());
- Priority = CCP_CodePattern;
- Completion = Builder.TakeString();
- }
-
- AllResults.push_back(Result(Completion, Priority, C->Kind,
- C->Availability));
}
-
+
// If we did not add any cached completion results, just forward the
// results we were given to the next consumer.
if (!AddedResult) {
@@ -2128,9 +2140,15 @@ void ASTUnit::CodeComplete(
PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
StringRef MainFilePath = getMainFileName();
- CodeCompleteOpts.IncludeMacros = IncludeMacros &&
- CachedCompletionResults.empty();
- CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
+ {
+ std::lock_guard<std::recursive_mutex> Lock(CacheMutex);
+ CodeCompleteOpts.IncludeMacros =
+ IncludeMacros &&
+ ASTUnitCacheMap[MainFilePath].CachedCompletionResults.empty();
+ CodeCompleteOpts.IncludeGlobals =
+ ASTUnitCacheMap[MainFilePath].CachedCompletionResults.empty();
+ }
+
CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();