forked from OSchip/llvm-project
Teach the CXCodeCompleteResults results structure, which stores
code-completion results accessed via libclang, to extend the lifetime of the allocator used for cached global code-completion results at least until these completion results are destroyed. Fixes <rdar://problem/8997369>. llvm-svn: 125678
This commit is contained in:
parent
1728c232d5
commit
162b712d38
|
@ -54,6 +54,14 @@ class TargetInfo;
|
|||
|
||||
using namespace idx;
|
||||
|
||||
/// \brief Allocator for a cached set of global code completions.
|
||||
class GlobalCodeCompletionAllocator
|
||||
: public CodeCompletionAllocator,
|
||||
public llvm::RefCountedBase<GlobalCodeCompletionAllocator>
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
/// \brief Utility class for loading a ASTContext from an AST file.
|
||||
///
|
||||
class ASTUnit {
|
||||
|
@ -287,9 +295,16 @@ public:
|
|||
return CachedCompletionTypes;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the allocator used to cache global code completions.
|
||||
llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
|
||||
getCachedCompletionAllocator() {
|
||||
return CachedCompletionAllocator;
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Allocator used to store cached code completions.
|
||||
CodeCompletionAllocator CachedCompletionAllocator;
|
||||
llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
|
||||
CachedCompletionAllocator;
|
||||
|
||||
/// \brief The set of cached code-completion results.
|
||||
std::vector<CachedCodeCompletionResult> CachedCompletionResults;
|
||||
|
|
|
@ -224,7 +224,8 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
// Gather the set of global code completions.
|
||||
typedef CodeCompletionResult Result;
|
||||
llvm::SmallVector<Result, 8> Results;
|
||||
TheSema->GatherGlobalCodeCompletions(CachedCompletionAllocator, Results);
|
||||
CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
|
||||
TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results);
|
||||
|
||||
// Translate global code completions into cached completions.
|
||||
llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
|
||||
|
@ -235,7 +236,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
bool IsNestedNameSpecifier = false;
|
||||
CachedCodeCompletionResult CachedResult;
|
||||
CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
|
||||
CachedCompletionAllocator);
|
||||
*CachedCompletionAllocator);
|
||||
CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
|
||||
Ctx->getLangOptions(),
|
||||
IsNestedNameSpecifier);
|
||||
|
@ -299,7 +300,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
Results[I].StartsNestedNameSpecifier = true;
|
||||
CachedResult.Completion
|
||||
= Results[I].CreateCodeCompletionString(*TheSema,
|
||||
CachedCompletionAllocator);
|
||||
*CachedCompletionAllocator);
|
||||
CachedResult.ShowInContexts = RemainingContexts;
|
||||
CachedResult.Priority = CCP_NestedNameSpecifier;
|
||||
CachedResult.TypeClass = STC_Void;
|
||||
|
@ -320,7 +321,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
CachedCodeCompletionResult CachedResult;
|
||||
CachedResult.Completion
|
||||
= Results[I].CreateCodeCompletionString(*TheSema,
|
||||
CachedCompletionAllocator);
|
||||
*CachedCompletionAllocator);
|
||||
CachedResult.ShowInContexts
|
||||
= (1 << (CodeCompletionContext::CCC_TopLevel - 1))
|
||||
| (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
|
||||
|
@ -353,7 +354,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
void ASTUnit::ClearCachedCompletionResults() {
|
||||
CachedCompletionResults.clear();
|
||||
CachedCompletionTypes.clear();
|
||||
CachedCompletionAllocator.Reset();
|
||||
CachedCompletionAllocator = 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -229,6 +229,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
|
|||
/// the code-completion results.
|
||||
llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
|
||||
|
||||
/// \brief Allocator used to store globally cached code-completion results.
|
||||
llvm::IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
|
||||
CachedCompletionAllocator;
|
||||
|
||||
/// \brief Allocator used to store code completion results.
|
||||
clang::CodeCompletionAllocator CodeCompletionAllocator;
|
||||
};
|
||||
|
@ -379,7 +383,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
|
|||
AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
|
||||
Results->Results = 0;
|
||||
Results->NumResults = 0;
|
||||
|
||||
|
||||
// Create a code-completion consumer to capture the results.
|
||||
CaptureCompletionResults Capture(*Results);
|
||||
|
||||
|
@ -392,6 +396,12 @@ void clang_codeCompleteAt_Impl(void *UserData) {
|
|||
*Results->Diag, Results->LangOpts, Results->SourceMgr,
|
||||
Results->FileMgr, Results->Diagnostics,
|
||||
Results->TemporaryBuffers);
|
||||
|
||||
// Keep a reference to the allocator used for cached global completions, so
|
||||
// that we can be sure that the memory used by our code completion strings
|
||||
// doesn't get freed due to subsequent reparses (while the code completion
|
||||
// results are still active).
|
||||
Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue