summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/Frontend/ASTUnit.h26
-rw-r--r--lib/Frontend/ASTUnit.cpp164
2 files changed, 104 insertions, 86 deletions
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 896cb31680..232f9406be 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -289,6 +289,9 @@ public:
/// of that loading. It must be cleared when preamble is recreated.
llvm::StringMap<SourceLocation> PreambleSrcLocCache;
+ /// \brief The set of cached code-completion results.
+ std::vector<CachedCodeCompletionResult> CachedCompletionResults;
+
/// \brief Counter that determines when we want to try building a
/// precompiled preamble.
///
@@ -306,6 +309,13 @@ public:
/// This hash value is used to determine when we need to refresh the
/// global code-completion cache after a rebuild of the precompiled preamble.
unsigned PreambleTopLevelHashValue = 0;
+
+ /// \brief A string hash of the top-level declaration and macro definition
+ /// names processed the last time that we reparsed the file.
+ ///
+ /// This hash value is used to determine when we need to refresh the
+ /// global code-completion cache.
+ unsigned CompletionCacheTopLevelHashValue = 0;
};
void initCache();
@@ -340,20 +350,10 @@ private:
std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
- /// \brief The set of cached code-completion results.
- std::vector<CachedCodeCompletionResult> CachedCompletionResults;
-
/// \brief A mapping from the formatted type name to a unique number for that
/// type, which is used for type equality comparisons.
llvm::StringMap<unsigned> CachedCompletionTypes;
- /// \brief A string hash of the top-level declaration and macro definition
- /// names processed the last time that we reparsed the file.
- ///
- /// This hash value is used to determine when we need to refresh the
- /// global code-completion cache.
- unsigned CompletionCacheTopLevelHashValue = 0;
-
/// \brief The current hash value for the top-level declaration and macro
/// definition names
unsigned CurrentTopLevelHashValue;
@@ -609,15 +609,15 @@ public:
cached_completion_iterator;
cached_completion_iterator cached_completion_begin() {
- return CachedCompletionResults.begin();
+ return ASTUnitCacheMap[getMainFileName()].CachedCompletionResults.begin();
}
cached_completion_iterator cached_completion_end() {
- return CachedCompletionResults.end();
+ return ASTUnitCacheMap[getMainFileName()].CachedCompletionResults.end();
}
unsigned cached_completion_size() const {
- return CachedCompletionResults.size();
+ return ASTUnitCacheMap[getMainFileName()].CachedCompletionResults.size();
}
/// \brief Returns an iterator range for the local preprocessing entities
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();