diff options
-rw-r--r-- | include/clang/Frontend/ASTUnit.h | 26 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 164 |
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(); |