]> granicus.if.org Git - clang/commitdiff
Teach the CXCodeCompleteResults results structure, which stores
authorDouglas Gregor <dgregor@apple.com>
Wed, 16 Feb 2011 19:08:06 +0000 (19:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 16 Feb 2011 19:08:06 +0000 (19:08 +0000)
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>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125678 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTUnit.h
lib/Frontend/ASTUnit.cpp
tools/libclang/CIndexCodeCompletion.cpp

index 0841480cf570294bcbfdd729665e594bb78ff6ba..e93563311b858551be5fbb0828efa9fede6a87e1 100644 (file)
@@ -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;
index a56fefc69f10d4a51d91bc3b7cda14fcda2f8cc1..46f5b5a48e749d693f033e51b22ac5d760d013d3 100644 (file)
@@ -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 {
index 705c62c6fe04493f2834a9f398c08fc468c14bdd..292719bebdaeef5a7f08f13dbae24a174245e857 100644 (file)
@@ -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();