Selaa lähdekoodia

[code-complete] Introduce CodeCompletionTUInfo which will be used for caching
code-completion related strings specific to a translation unit (ASTContext and related data)

CodeCompletionAllocator does such limited caching, by caching the name assigned
to a DeclContext*, but that is not the appropriate place since that object has
a lifetime that can extend beyond that of an ASTContext.

Introduce CodeCompletionTUInfo which will be always tied to a translation unit
to do this kind of caching and move the caching of CodeCompletionAllocator into this
object, and propagate it to all the places where it will be needed.

The plan is to extend the caching where appropriate, using CodeCompletionTUInfo,
to avoid re-calculating code-completion strings.

Part of rdar://10796159.

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

Argyrios Kyrtzidis 13 vuotta sitten
vanhempi
commit
28a83f5700

+ 8 - 21
include/clang/Frontend/ASTUnit.h

@@ -58,14 +58,6 @@ class ASTFrontendAction;
 
 
 using namespace idx;
 using namespace idx;
   
   
-/// \brief Allocator for a cached set of global code completions.
-class GlobalCodeCompletionAllocator 
-  : public CodeCompletionAllocator,
-    public RefCountedBase<GlobalCodeCompletionAllocator>
-{
-
-};
-  
 /// \brief Utility class for loading a ASTContext from an AST file.
 /// \brief Utility class for loading a ASTContext from an AST file.
 ///
 ///
 class ASTUnit : public ModuleLoader {
 class ASTUnit : public ModuleLoader {
@@ -324,25 +316,20 @@ public:
   getCachedCompletionAllocator() {
   getCachedCompletionAllocator() {
     return CachedCompletionAllocator;
     return CachedCompletionAllocator;
   }
   }
-  
-  /// \brief Retrieve the allocator used to cache global code completions.
-  /// Creates the allocator if it doesn't already exist.
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
-  getCursorCompletionAllocator() {
-    if (!CursorCompletionAllocator.getPtr()) {
-      CursorCompletionAllocator = new GlobalCodeCompletionAllocator;
-    }
-    return CursorCompletionAllocator;
+
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() {
+    if (!CCTUInfo)
+      CCTUInfo.reset(new CodeCompletionTUInfo(
+                                            new GlobalCodeCompletionAllocator));
+    return *CCTUInfo;
   }
   }
-  
+
 private:
 private:
   /// \brief Allocator used to store cached code completions.
   /// \brief Allocator used to store cached code completions.
   IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
   IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
     CachedCompletionAllocator;
     CachedCompletionAllocator;
   
   
-  /// \brief Allocator used to store code completions for arbitrary cursors.
-  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
-    CursorCompletionAllocator;
+  OwningPtr<CodeCompletionTUInfo> CCTUInfo;
 
 
   /// \brief The set of cached code-completion results.
   /// \brief The set of cached code-completion results.
   std::vector<CachedCodeCompletionResult> CachedCompletionResults;
   std::vector<CachedCodeCompletionResult> CachedCompletionResults;

+ 53 - 16
include/clang/Sema/CodeCompleteConsumer.h

@@ -501,8 +501,6 @@ public:
 
 
 /// \brief An allocator used specifically for the purpose of code completion.
 /// \brief An allocator used specifically for the purpose of code completion.
 class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
 class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
-  llvm::DenseMap<DeclContext *, StringRef> ParentNames;
-  
 public:
 public:
   /// \brief Copy the given string into this allocator.
   /// \brief Copy the given string into this allocator.
   const char *CopyString(StringRef String);
   const char *CopyString(StringRef String);
@@ -519,12 +517,34 @@ public:
   const char *CopyString(const std::string &String) {
   const char *CopyString(const std::string &String) {
     return CopyString(StringRef(String));
     return CopyString(StringRef(String));
   }
   }
-  
-  /// \brief Retrieve the mapping from known parent declaration contexts to
-  /// the (already copied) strings associated with each context.
-  llvm::DenseMap<DeclContext *, StringRef> &getParentNames() {
-    return ParentNames;
+};
+
+/// \brief Allocator for a cached set of global code completions.
+class GlobalCodeCompletionAllocator 
+  : public CodeCompletionAllocator,
+    public RefCountedBase<GlobalCodeCompletionAllocator>
+{
+
+};
+
+class CodeCompletionTUInfo {
+  llvm::DenseMap<DeclContext *, StringRef> ParentNames;
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef;
+
+public:
+  explicit CodeCompletionTUInfo(
+                    IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator)
+    : AllocatorRef(Allocator) { }
+
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
+    return AllocatorRef;
+  }
+  CodeCompletionAllocator &getAllocator() const {
+    assert(AllocatorRef);
+    return *AllocatorRef;
   }
   }
+
+  StringRef getParentName(DeclContext *DC);
 };
 };
 
 
 } // end namespace clang
 } // end namespace clang
@@ -544,6 +564,7 @@ public:
 
 
 private:
 private:
   CodeCompletionAllocator &Allocator;
   CodeCompletionAllocator &Allocator;
+  CodeCompletionTUInfo &CCTUInfo;
   unsigned Priority;
   unsigned Priority;
   CXAvailabilityKind Availability;
   CXAvailabilityKind Availability;
   CXCursorKind ParentKind;
   CXCursorKind ParentKind;
@@ -555,19 +576,25 @@ private:
   SmallVector<const char *, 2> Annotations;
   SmallVector<const char *, 2> Annotations;
 
 
 public:
 public:
-  CodeCompletionBuilder(CodeCompletionAllocator &Allocator)
-    : Allocator(Allocator), Priority(0), Availability(CXAvailability_Available),
+  CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
+                        CodeCompletionTUInfo &CCTUInfo)
+    : Allocator(Allocator), CCTUInfo(CCTUInfo),
+      Priority(0), Availability(CXAvailability_Available),
       ParentKind(CXCursor_NotImplemented) { }
       ParentKind(CXCursor_NotImplemented) { }
 
 
   CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
   CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
+                        CodeCompletionTUInfo &CCTUInfo,
                         unsigned Priority, CXAvailabilityKind Availability)
                         unsigned Priority, CXAvailabilityKind Availability)
-    : Allocator(Allocator), Priority(Priority), Availability(Availability),
+    : Allocator(Allocator), CCTUInfo(CCTUInfo),
+      Priority(Priority), Availability(Availability),
       ParentKind(CXCursor_NotImplemented) { }
       ParentKind(CXCursor_NotImplemented) { }
 
 
   /// \brief Retrieve the allocator into which the code completion
   /// \brief Retrieve the allocator into which the code completion
   /// strings should be allocated.
   /// strings should be allocated.
   CodeCompletionAllocator &getAllocator() const { return Allocator; }
   CodeCompletionAllocator &getAllocator() const { return Allocator; }
 
 
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
+
   /// \brief Take the resulting completion string.
   /// \brief Take the resulting completion string.
   ///
   ///
   /// This operation can only be performed once.
   /// This operation can only be performed once.
@@ -753,10 +780,12 @@ public:
   /// \param Allocator The allocator that will be used to allocate the
   /// \param Allocator The allocator that will be used to allocate the
   /// string itself.
   /// string itself.
   CodeCompletionString *CreateCodeCompletionString(Sema &S,
   CodeCompletionString *CreateCodeCompletionString(Sema &S,
-                                           CodeCompletionAllocator &Allocator);
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo);
   CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
   CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
                                                    Preprocessor &PP,
                                                    Preprocessor &PP,
-                                           CodeCompletionAllocator &Allocator);
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo);
 
 
   /// \brief Determine a base priority for the given declaration.
   /// \brief Determine a base priority for the given declaration.
   static unsigned getPriorityFromDecl(NamedDecl *ND);
   static unsigned getPriorityFromDecl(NamedDecl *ND);
@@ -868,7 +897,8 @@ public:
     /// signature of this overload candidate.
     /// signature of this overload candidate.
     CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
     CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
                                                 Sema &S,
                                                 Sema &S,
-                                      CodeCompletionAllocator &Allocator) const;
+                                      CodeCompletionAllocator &Allocator,
+                                      CodeCompletionTUInfo &CCTUInfo) const;
   };
   };
 
 
   CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
   CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
@@ -918,6 +948,8 @@ public:
   /// \brief Retrieve the allocator that will be used to allocate
   /// \brief Retrieve the allocator that will be used to allocate
   /// code completion strings.
   /// code completion strings.
   virtual CodeCompletionAllocator &getAllocator() = 0;
   virtual CodeCompletionAllocator &getAllocator() = 0;
+
+  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0;
 };
 };
 
 
 /// \brief A simple code-completion consumer that prints the results it
 /// \brief A simple code-completion consumer that prints the results it
@@ -926,7 +958,7 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
   /// \brief The raw output stream.
   /// \brief The raw output stream.
   raw_ostream &OS;
   raw_ostream &OS;
 
 
-  CodeCompletionAllocator Allocator;
+  CodeCompletionTUInfo CCTUInfo;
 
 
 public:
 public:
   /// \brief Create a new printing code-completion consumer that prints its
   /// \brief Create a new printing code-completion consumer that prints its
@@ -935,7 +967,8 @@ public:
                                bool IncludeGlobals,
                                bool IncludeGlobals,
                                raw_ostream &OS)
                                raw_ostream &OS)
     : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
     : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
-                           false), OS(OS) {}
+                           false), OS(OS),
+      CCTUInfo(new GlobalCodeCompletionAllocator) {}
 
 
   /// \brief Prints the finalized code-completion results.
   /// \brief Prints the finalized code-completion results.
   virtual void ProcessCodeCompleteResults(Sema &S,
   virtual void ProcessCodeCompleteResults(Sema &S,
@@ -947,7 +980,11 @@ public:
                                          OverloadCandidate *Candidates,
                                          OverloadCandidate *Candidates,
                                          unsigned NumCandidates);
                                          unsigned NumCandidates);
 
 
-  virtual CodeCompletionAllocator &getAllocator() { return Allocator; }
+  virtual CodeCompletionAllocator &getAllocator() {
+    return CCTUInfo.getAllocator();
+  }
+
+  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
 };
 };
 
 
 } // end namespace clang
 } // end namespace clang

+ 2 - 0
include/clang/Sema/Sema.h

@@ -78,6 +78,7 @@ namespace clang {
   class ClassTemplateSpecializationDecl;
   class ClassTemplateSpecializationDecl;
   class CodeCompleteConsumer;
   class CodeCompleteConsumer;
   class CodeCompletionAllocator;
   class CodeCompletionAllocator;
+  class CodeCompletionTUInfo;
   class CodeCompletionResult;
   class CodeCompletionResult;
   class Decl;
   class Decl;
   class DeclAccessPair;
   class DeclAccessPair;
@@ -6647,6 +6648,7 @@ public:
                                              unsigned Argument);
                                              unsigned Argument);
   void CodeCompleteNaturalLanguage();
   void CodeCompleteNaturalLanguage();
   void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
   void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
+                                   CodeCompletionTUInfo &CCTUInfo,
                   SmallVectorImpl<CodeCompletionResult> &Results);
                   SmallVectorImpl<CodeCompletionResult> &Results);
   //@}
   //@}
 
 

+ 17 - 9
lib/Frontend/ASTUnit.cpp

@@ -351,7 +351,8 @@ void ASTUnit::CacheCodeCompletionResults() {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   SmallVector<Result, 8> Results;
   SmallVector<Result, 8> Results;
   CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
   CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
-  TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results);
+  TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
+                                       getCodeCompletionTUInfo(), Results);
   
   
   // Translate global code completions into cached completions.
   // Translate global code completions into cached completions.
   llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
   llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
@@ -362,7 +363,8 @@ void ASTUnit::CacheCodeCompletionResults() {
       bool IsNestedNameSpecifier = false;
       bool IsNestedNameSpecifier = false;
       CachedCodeCompletionResult CachedResult;
       CachedCodeCompletionResult CachedResult;
       CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
       CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
-                                                    *CachedCompletionAllocator);
+                                                    *CachedCompletionAllocator,
+                                                    getCodeCompletionTUInfo());
       CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
       CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
                                                         Ctx->getLangOpts(),
                                                         Ctx->getLangOpts(),
                                                         IsNestedNameSpecifier);
                                                         IsNestedNameSpecifier);
@@ -426,7 +428,8 @@ void ASTUnit::CacheCodeCompletionResults() {
           Results[I].StartsNestedNameSpecifier = true;
           Results[I].StartsNestedNameSpecifier = true;
           CachedResult.Completion 
           CachedResult.Completion 
             = Results[I].CreateCodeCompletionString(*TheSema,
             = Results[I].CreateCodeCompletionString(*TheSema,
-                                                    *CachedCompletionAllocator);
+                                                    *CachedCompletionAllocator,
+                                                    getCodeCompletionTUInfo());
           CachedResult.ShowInContexts = RemainingContexts;
           CachedResult.ShowInContexts = RemainingContexts;
           CachedResult.Priority = CCP_NestedNameSpecifier;
           CachedResult.Priority = CCP_NestedNameSpecifier;
           CachedResult.TypeClass = STC_Void;
           CachedResult.TypeClass = STC_Void;
@@ -447,7 +450,8 @@ void ASTUnit::CacheCodeCompletionResults() {
       CachedCodeCompletionResult CachedResult;
       CachedCodeCompletionResult CachedResult;
       CachedResult.Completion 
       CachedResult.Completion 
         = Results[I].CreateCodeCompletionString(*TheSema,
         = Results[I].CreateCodeCompletionString(*TheSema,
-                                                *CachedCompletionAllocator);
+                                                *CachedCompletionAllocator,
+                                                getCodeCompletionTUInfo());
       CachedResult.ShowInContexts
       CachedResult.ShowInContexts
         = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
         = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
@@ -1989,9 +1993,9 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
       CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
       CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
     CacheCodeCompletionResults();
     CacheCodeCompletionResults();
 
 
-  // We now need to clear out the completion allocator for
-  // clang_getCursorCompletionString; it'll be recreated if necessary.
-  CursorCompletionAllocator = 0;
+  // We now need to clear out the completion info related to this translation
+  // unit; it'll be recreated if necessary.
+  CCTUInfo.reset();
   
   
   return Result;
   return Result;
 }
 }
@@ -2053,6 +2057,10 @@ namespace {
     virtual CodeCompletionAllocator &getAllocator() {
     virtual CodeCompletionAllocator &getAllocator() {
       return Next.getAllocator();
       return Next.getAllocator();
     }
     }
+
+    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() {
+      return Next.getCodeCompletionTUInfo();
+    }
   };
   };
 }
 }
 
 
@@ -2210,8 +2218,8 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
         Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
         Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
       // Create a new code-completion string that just contains the
       // Create a new code-completion string that just contains the
       // macro name, without its arguments.
       // macro name, without its arguments.
-      CodeCompletionBuilder Builder(getAllocator(), CCP_CodePattern,
-                                    C->Availability);
+      CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
+                                    CCP_CodePattern, C->Availability);
       Builder.AddTypedTextChunk(C->Completion->getTypedText());
       Builder.AddTypedTextChunk(C->Completion->getTypedText());
       CursorKind = CXCursor_NotImplemented;
       CursorKind = CXCursor_NotImplemented;
       Priority = CCP_CodePattern;
       Priority = CCP_CodePattern;

+ 69 - 52
lib/Sema/CodeCompleteConsumer.cpp

@@ -267,8 +267,70 @@ const char *CodeCompletionAllocator::CopyString(Twine String) {
   return CopyString(String.toStringRef(Data));
   return CopyString(String.toStringRef(Data));
 }
 }
 
 
+StringRef CodeCompletionTUInfo::getParentName(DeclContext *DC) {
+  NamedDecl *ND = dyn_cast<NamedDecl>(DC);
+  if (!ND)
+    return StringRef();
+  
+  // Check whether we've already cached the parent name.
+  StringRef &CachedParentName = ParentNames[DC];
+  if (!CachedParentName.empty())
+    return CachedParentName;
+
+  // If we already processed this DeclContext and assigned empty to it, the
+  // data pointer will be non-null.
+  if (CachedParentName.data() != 0)
+    return StringRef();
+
+  // Find the interesting names.
+  llvm::SmallVector<DeclContext *, 2> Contexts;
+  while (DC && !DC->isFunctionOrMethod()) {
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
+      if (ND->getIdentifier())
+        Contexts.push_back(DC);
+    }
+    
+    DC = DC->getParent();
+  }
+
+  {
+    llvm::SmallString<128> S;
+    llvm::raw_svector_ostream OS(S);
+    bool First = true;
+    for (unsigned I = Contexts.size(); I != 0; --I) {
+      if (First)
+        First = false;
+      else {
+        OS << "::";
+      }
+      
+      DeclContext *CurDC = Contexts[I-1];
+      if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
+        CurDC = CatImpl->getCategoryDecl();
+      
+      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
+        ObjCInterfaceDecl *Interface = Cat->getClassInterface();
+        if (!Interface) {
+          // Assign an empty StringRef but with non-null data to distinguish
+          // between empty because we didn't process the DeclContext yet.
+          CachedParentName = StringRef((const char *)~0U, 0);
+          return StringRef();
+        }
+        
+        OS << Interface->getName() << '(' << Cat->getName() << ')';
+      } else {
+        OS << cast<NamedDecl>(CurDC)->getName();
+      }
+    }
+    
+    CachedParentName = AllocatorRef->CopyString(OS.str());
+  }
+
+  return CachedParentName;
+}
+
 CodeCompletionString *CodeCompletionBuilder::TakeString() {
 CodeCompletionString *CodeCompletionBuilder::TakeString() {
-  void *Mem = Allocator.Allocate(
+  void *Mem = getAllocator().Allocate(
                   sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size()
                   sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size()
                                     + sizeof(const char *) * Annotations.size(),
                                     + sizeof(const char *) * Annotations.size(),
                                  llvm::alignOf<CodeCompletionString>());
                                  llvm::alignOf<CodeCompletionString>());
@@ -329,54 +391,7 @@ void CodeCompletionBuilder::addParentContext(DeclContext *DC) {
     return;
     return;
   
   
   ParentKind = getCursorKindForDecl(ND);
   ParentKind = getCursorKindForDecl(ND);
-  
-  // Check whether we've already cached the parent name.
-  StringRef &CachedParentName = Allocator.getParentNames()[DC];
-  if (!CachedParentName.empty()) {
-    ParentName = CachedParentName;
-    return;
-  }
-
-  // Find the interesting names.
-  llvm::SmallVector<DeclContext *, 2> Contexts;
-  while (DC && !DC->isFunctionOrMethod()) {
-    if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
-      if (ND->getIdentifier())
-        Contexts.push_back(DC);
-    }
-    
-    DC = DC->getParent();
-  }
-
-  {
-    llvm::SmallString<128> S;
-    llvm::raw_svector_ostream OS(S);
-    bool First = true;
-    for (unsigned I = Contexts.size(); I != 0; --I) {
-      if (First)
-        First = false;
-      else {
-        OS << "::";
-      }
-      
-      DeclContext *CurDC = Contexts[I-1];
-      if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
-        CurDC = CatImpl->getCategoryDecl();
-      
-      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
-        ObjCInterfaceDecl *Interface = Cat->getClassInterface();
-        if (!Interface)
-          return;
-        
-        OS << Interface->getName() << '(' << Cat->getName() << ')';
-      } else {
-        OS << cast<NamedDecl>(CurDC)->getName();
-      }
-    }
-    
-    ParentName = Allocator.CopyString(OS.str());
-    CachedParentName = ParentName;
-  }
+  ParentName = getCodeCompletionTUInfo().getParentName(DC);
 }
 }
 
 
 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
@@ -458,7 +473,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
       if (Results[I].Hidden)
       if (Results[I].Hidden)
         OS << " (Hidden)";
         OS << " (Hidden)";
       if (CodeCompletionString *CCS 
       if (CodeCompletionString *CCS 
-            = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
+            = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
+                                                    CCTUInfo)) {
         OS << " : " << CCS->getAsString();
         OS << " : " << CCS->getAsString();
       }
       }
         
         
@@ -472,7 +488,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
     case CodeCompletionResult::RK_Macro: {
     case CodeCompletionResult::RK_Macro: {
       OS << Results[I].Macro->getName();
       OS << Results[I].Macro->getName();
       if (CodeCompletionString *CCS 
       if (CodeCompletionString *CCS 
-            = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
+            = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
+                                                    CCTUInfo)) {
         OS << " : " << CCS->getAsString();
         OS << " : " << CCS->getAsString();
       }
       }
       OS << '\n';
       OS << '\n';
@@ -496,7 +513,7 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
   for (unsigned I = 0; I != NumCandidates; ++I) {
   for (unsigned I = 0; I != NumCandidates; ++I) {
     if (CodeCompletionString *CCS
     if (CodeCompletionString *CCS
           = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
           = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
-                                                Allocator)) {
+                                                getAllocator(), CCTUInfo)) {
       OS << "OVERLOAD: " << CCS->getAsString() << "\n";
       OS << "OVERLOAD: " << CCS->getAsString() << "\n";
     }
     }
   }
   }

+ 114 - 37
lib/Sema/SemaCodeComplete.cpp

@@ -123,6 +123,8 @@ namespace {
 
 
     /// \brief The allocator used to allocate new code-completion strings.
     /// \brief The allocator used to allocate new code-completion strings.
     CodeCompletionAllocator &Allocator;
     CodeCompletionAllocator &Allocator;
+
+    CodeCompletionTUInfo &CCTUInfo;
     
     
     /// \brief If non-NULL, a filter function used to remove any code-completion
     /// \brief If non-NULL, a filter function used to remove any code-completion
     /// results that are not desirable.
     /// results that are not desirable.
@@ -166,9 +168,11 @@ namespace {
     
     
   public:
   public:
     explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
     explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
+                           CodeCompletionTUInfo &CCTUInfo,
                            const CodeCompletionContext &CompletionContext,
                            const CodeCompletionContext &CompletionContext,
                            LookupFilter Filter = 0)
                            LookupFilter Filter = 0)
-      : SemaRef(SemaRef), Allocator(Allocator), Filter(Filter), 
+      : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
+        Filter(Filter), 
         AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), 
         AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), 
         CompletionContext(CompletionContext),
         CompletionContext(CompletionContext),
         ObjCImplementation(0) 
         ObjCImplementation(0) 
@@ -251,6 +255,8 @@ namespace {
     
     
     /// \brief Retrieve the allocator used to allocate code completion strings.
     /// \brief Retrieve the allocator used to allocate code completion strings.
     CodeCompletionAllocator &getAllocator() const { return Allocator; }
     CodeCompletionAllocator &getAllocator() const { return Allocator; }
+
+    CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
     
     
     /// \brief Determine whether the given declaration is at all interesting
     /// \brief Determine whether the given declaration is at all interesting
     /// as a code-completion result.
     /// as a code-completion result.
@@ -1231,7 +1237,8 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
     Results.AddResult(Result("restrict", CCP_Type));
     Results.AddResult(Result("restrict", CCP_Type));
   }
   }
   
   
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   if (LangOpts.CPlusPlus) {
   if (LangOpts.CPlusPlus) {
     // C++-specific
     // C++-specific
     Results.AddResult(Result("bool", CCP_Type + 
     Results.AddResult(Result("bool", CCP_Type + 
@@ -1341,7 +1348,8 @@ static void AddObjCInterfaceResults(const LangOptions &LangOpts,
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
 
 
 static void AddTypedefResult(ResultBuilder &Results) {
 static void AddTypedefResult(ResultBuilder &Results) {
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   Builder.AddTypedTextChunk("typedef");
   Builder.AddTypedTextChunk("typedef");
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddPlaceholderChunk("type");
   Builder.AddPlaceholderChunk("type");
@@ -1434,7 +1442,7 @@ static void addThisCompletion(Sema &S, ResultBuilder &Results) {
     return;
     return;
   
   
   CodeCompletionAllocator &Allocator = Results.getAllocator();
   CodeCompletionAllocator &Allocator = Results.getAllocator();
-  CodeCompletionBuilder Builder(Allocator);
+  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
   PrintingPolicy Policy = getCompletionPrintingPolicy(S);
   PrintingPolicy Policy = getCompletionPrintingPolicy(S);
   Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 
   Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 
                                                      S.Context, 
                                                      S.Context, 
@@ -1450,7 +1458,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Sema &SemaRef,
                                    Sema &SemaRef,
                                    ResultBuilder &Results) {
                                    ResultBuilder &Results) {
   CodeCompletionAllocator &Allocator = Results.getAllocator();
   CodeCompletionAllocator &Allocator = Results.getAllocator();
-  CodeCompletionBuilder Builder(Allocator);
+  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
   PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
   PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
   
   
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
@@ -2180,7 +2188,8 @@ static void AddFunctionParameterChunks(ASTContext &Context,
     if (Param->hasDefaultArg() && !InOptional) {
     if (Param->hasDefaultArg() && !InOptional) {
       // When we see an optional default argument, put that argument and
       // When we see an optional default argument, put that argument and
       // the remaining default arguments into a new, optional string.
       // the remaining default arguments into a new, optional string.
-      CodeCompletionBuilder Opt(Result.getAllocator());
+      CodeCompletionBuilder Opt(Result.getAllocator(),
+                                Result.getCodeCompletionTUInfo());
       if (!FirstParameter)
       if (!FirstParameter)
         Opt.AddChunk(CodeCompletionString::CK_Comma);
         Opt.AddChunk(CodeCompletionString::CK_Comma);
       AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
       AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
@@ -2271,7 +2280,8 @@ static void AddTemplateParameterChunks(ASTContext &Context,
     if (HasDefaultArg && !InDefaultArg) {
     if (HasDefaultArg && !InDefaultArg) {
       // When we see an optional default argument, put that argument and
       // When we see an optional default argument, put that argument and
       // the remaining default arguments into a new, optional string.
       // the remaining default arguments into a new, optional string.
-      CodeCompletionBuilder Opt(Result.getAllocator());
+      CodeCompletionBuilder Opt(Result.getAllocator(),
+                                Result.getCodeCompletionTUInfo());
       if (!FirstParameter)
       if (!FirstParameter)
         Opt.AddChunk(CodeCompletionString::CK_Comma);
         Opt.AddChunk(CodeCompletionString::CK_Comma);
       AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
       AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
@@ -2426,8 +2436,9 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
 }
 }
 
 
 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
-                                         CodeCompletionAllocator &Allocator) {
-  return CreateCodeCompletionString(S.Context, S.PP, Allocator);
+                                         CodeCompletionAllocator &Allocator,
+                                         CodeCompletionTUInfo &CCTUInfo) {
+  return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo);
 }
 }
 
 
 /// \brief If possible, create a new code completion string for the given
 /// \brief If possible, create a new code completion string for the given
@@ -2439,8 +2450,9 @@ CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
 CodeCompletionString *
 CodeCompletionString *
 CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
 CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
                                                  Preprocessor &PP,
                                                  Preprocessor &PP,
-                                           CodeCompletionAllocator &Allocator) {
-  CodeCompletionBuilder Result(Allocator, Priority, Availability);
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo) {
+  CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
   
   
   PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
   PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
   if (Kind == RK_Pattern) {
   if (Kind == RK_Pattern) {
@@ -2695,11 +2707,12 @@ CodeCompletionString *
 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
                                                           unsigned CurrentArg,
                                                           unsigned CurrentArg,
                                                                Sema &S,
                                                                Sema &S,
-                                     CodeCompletionAllocator &Allocator) const {
+                                     CodeCompletionAllocator &Allocator,
+                                     CodeCompletionTUInfo &CCTUInfo) const {
   PrintingPolicy Policy = getCompletionPrintingPolicy(S);
   PrintingPolicy Policy = getCompletionPrintingPolicy(S);
 
 
   // FIXME: Set priority, availability appropriately.
   // FIXME: Set priority, availability appropriately.
-  CodeCompletionBuilder Result(Allocator, 1, CXAvailability_Available);
+  CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
   FunctionDecl *FDecl = getFunction();
   FunctionDecl *FDecl = getFunction();
   AddResultTypeChunk(S.Context, Policy, FDecl, Result);
   AddResultTypeChunk(S.Context, Policy, FDecl, Result);
   const FunctionProtoType *Proto 
   const FunctionProtoType *Proto 
@@ -2986,7 +2999,8 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
   for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
   for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
                                    MEnd = Method->end_overridden_methods();
                                    MEnd = Method->end_overridden_methods();
        M != MEnd; ++M) {
        M != MEnd; ++M) {
-    CodeCompletionBuilder Builder(Results.getAllocator());
+    CodeCompletionBuilder Builder(Results.getAllocator(),
+                                  Results.getCodeCompletionTUInfo());
     CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
     CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
     if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
     if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
       continue;
       continue;
@@ -3034,11 +3048,12 @@ void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
                                     ModuleIdPath Path) {
                                     ModuleIdPath Path) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
   CodeCompletionAllocator &Allocator = Results.getAllocator();
   CodeCompletionAllocator &Allocator = Results.getAllocator();
-  CodeCompletionBuilder Builder(Allocator);
+  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   if (Path.empty()) {
   if (Path.empty()) {
     // Enumerate all top-level modules.
     // Enumerate all top-level modules.
@@ -3085,6 +3100,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S,
                                     ParserCompletionContext CompletionContext) {
                                     ParserCompletionContext CompletionContext) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         mapCodeCompletionContext(*this, CompletionContext));
                         mapCodeCompletionContext(*this, CompletionContext));
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -3180,6 +3196,7 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
                                 bool AllowNestedNameSpecifiers) {
                                 bool AllowNestedNameSpecifiers) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         AllowNestedNameSpecifiers
                         AllowNestedNameSpecifiers
                           ? CodeCompletionContext::CCC_PotentiallyQualifiedName
                           ? CodeCompletionContext::CCC_PotentiallyQualifiedName
                           : CodeCompletionContext::CCC_Name);
                           : CodeCompletionContext::CCC_Name);
@@ -3257,6 +3274,7 @@ void Sema::CodeCompleteExpression(Scope *S,
                                   const CodeCompleteExpressionData &Data) {
                                   const CodeCompleteExpressionData &Data) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Expression);
                         CodeCompletionContext::CCC_Expression);
   if (Data.ObjCCollection)
   if (Data.ObjCCollection)
     Results.setFilter(&ResultBuilder::IsObjCCollection);
     Results.setFilter(&ResultBuilder::IsObjCCollection);
@@ -3339,7 +3357,8 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
       if (M->getSelector().isUnarySelector())
       if (M->getSelector().isUnarySelector())
         if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
         if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
           if (AddedProperties.insert(Name)) {
           if (AddedProperties.insert(Name)) {
-            CodeCompletionBuilder Builder(Results.getAllocator());
+            CodeCompletionBuilder Builder(Results.getAllocator(),
+                                          Results.getCodeCompletionTUInfo());
             AddResultTypeChunk(Context, Policy, *M, Builder);
             AddResultTypeChunk(Context, Policy, *M, Builder);
             Builder.AddTypedTextChunk(
             Builder.AddTypedTextChunk(
                             Results.getAllocator().CopyString(Name->getName()));
                             Results.getAllocator().CopyString(Name->getName()));
@@ -3431,6 +3450,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
   }
   }
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                   CodeCompletionContext(contextKind,
                   CodeCompletionContext(contextKind,
                                         BaseType),
                                         BaseType),
                         &ResultBuilder::IsMember);
                         &ResultBuilder::IsMember);
@@ -3540,7 +3560,8 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
     llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
     llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
   }
   }
   
   
-  ResultBuilder Results(*this, CodeCompleter->getAllocator(), ContextKind);
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
 
 
   // First pass: look for tags.
   // First pass: look for tags.
@@ -3560,6 +3581,7 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
 
 
 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_TypeQualifiers);
                         CodeCompletionContext::CCC_TypeQualifiers);
   Results.EnterNewScope();
   Results.EnterNewScope();
   if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
   if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
@@ -3640,6 +3662,7 @@ void Sema::CodeCompleteCase(Scope *S) {
   
   
   // Add any enumerators that have not yet been mentioned.
   // Add any enumerators that have not yet been mentioned.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Expression);
                         CodeCompletionContext::CCC_Expression);
   Results.EnterNewScope();
   Results.EnterNewScope();
   for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
   for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
@@ -3830,6 +3853,7 @@ void Sema::CodeCompleteReturn(Scope *S) {
 void Sema::CodeCompleteAfterIf(Scope *S) {
 void Sema::CodeCompleteAfterIf(Scope *S) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         mapCodeCompletionContext(*this, PCC_Statement));
                         mapCodeCompletionContext(*this, PCC_Statement));
   Results.setFilter(&ResultBuilder::IsOrdinaryName);
   Results.setFilter(&ResultBuilder::IsOrdinaryName);
   Results.EnterNewScope();
   Results.EnterNewScope();
@@ -3841,7 +3865,8 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
   AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
   AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
   
   
   // "else" block
   // "else" block
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   Builder.AddTypedTextChunk("else");
   Builder.AddTypedTextChunk("else");
   if (Results.includeCodePatterns()) {
   if (Results.includeCodePatterns()) {
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
@@ -3908,6 +3933,7 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
     return;
     return;
 
 
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Name);
                         CodeCompletionContext::CCC_Name);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -3939,6 +3965,7 @@ void Sema::CodeCompleteUsing(Scope *S) {
     return;
     return;
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_PotentiallyQualifiedName,
                         CodeCompletionContext::CCC_PotentiallyQualifiedName,
                         &ResultBuilder::IsNestedNameSpecifier);
                         &ResultBuilder::IsNestedNameSpecifier);
   Results.EnterNewScope();
   Results.EnterNewScope();
@@ -3966,6 +3993,7 @@ void Sema::CodeCompleteUsingDirective(Scope *S) {
   // After "using namespace", we expect to see a namespace name or namespace
   // After "using namespace", we expect to see a namespace name or namespace
   // alias.
   // alias.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Namespace,
                         CodeCompletionContext::CCC_Namespace,
                         &ResultBuilder::IsNamespaceOrAlias);
                         &ResultBuilder::IsNamespaceOrAlias);
   Results.EnterNewScope();
   Results.EnterNewScope();
@@ -3990,6 +4018,7 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
     = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
     = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         SuppressedGlobalResults
                         SuppressedGlobalResults
                           ? CodeCompletionContext::CCC_Namespace
                           ? CodeCompletionContext::CCC_Namespace
                           : CodeCompletionContext::CCC_Other,
                           : CodeCompletionContext::CCC_Other,
@@ -4029,6 +4058,7 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
   
   
   // After "namespace", we expect to see a namespace or alias.
   // After "namespace", we expect to see a namespace or alias.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Namespace,
                         CodeCompletionContext::CCC_Namespace,
                         &ResultBuilder::IsNamespaceOrAlias);
                         &ResultBuilder::IsNamespaceOrAlias);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
@@ -4045,6 +4075,7 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
 
 
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Type,
                         CodeCompletionContext::CCC_Type,
                         &ResultBuilder::IsType);
                         &ResultBuilder::IsType);
   Results.EnterNewScope();
   Results.EnterNewScope();
@@ -4080,6 +4111,7 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
     return;
     return;
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_PotentiallyQualifiedName);
                         CodeCompletionContext::CCC_PotentiallyQualifiedName);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -4096,7 +4128,8 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
   }
   }
   
   
   // Add completions for base classes.
   // Add completions for base classes.
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   bool SawLastInitializer = (NumInitializers == 0);
   bool SawLastInitializer = (NumInitializers == 0);
   CXXRecordDecl *ClassDecl = Constructor->getParent();
   CXXRecordDecl *ClassDecl = Constructor->getParent();
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
@@ -4194,6 +4227,7 @@ static bool isNamespaceScope(Scope *S) {
 void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
 void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
                                         bool AfterAmpersand) {
                                         bool AfterAmpersand) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
 
 
@@ -4246,7 +4280,8 @@ static void AddObjCImplementationResults(const LangOptions &LangOpts,
   // Since we have an implementation, we can end it.
   // Since we have an implementation, we can end it.
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
   
   
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   if (LangOpts.ObjC2) {
   if (LangOpts.ObjC2) {
     // @dynamic
     // @dynamic
     Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
     Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
@@ -4284,7 +4319,8 @@ static void AddObjCInterfaceResults(const LangOptions &LangOpts,
 
 
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   
   
   // @class name ;
   // @class name ;
   Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
   Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
@@ -4326,6 +4362,7 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
 void Sema::CodeCompleteObjCAtDirective(Scope *S) {
 void Sema::CodeCompleteObjCAtDirective(Scope *S) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   if (isa<ObjCImplDecl>(CurContext))
   if (isa<ObjCImplDecl>(CurContext))
@@ -4342,7 +4379,8 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S) {
 
 
 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
 
 
   // @encode ( type-name )
   // @encode ( type-name )
   const char *EncodeType = "char[]";
   const char *EncodeType = "char[]";
@@ -4395,7 +4433,8 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
 
 
 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   
   
   if (Results.includeCodePatterns()) {
   if (Results.includeCodePatterns()) {
     // @try { statements } @catch ( declaration ) { statements } @finally
     // @try { statements } @catch ( declaration ) { statements } @finally
@@ -4451,6 +4490,7 @@ static void AddObjCVisibilityResults(const LangOptions &LangOpts,
 
 
 void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
 void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   AddObjCVisibilityResults(getLangOpts(), Results, false);
   AddObjCVisibilityResults(getLangOpts(), Results, false);
@@ -4462,6 +4502,7 @@ void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
 
 
 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   AddObjCStatementResults(Results, false);
   AddObjCStatementResults(Results, false);
@@ -4474,6 +4515,7 @@ void Sema::CodeCompleteObjCAtStatement(Scope *S) {
 
 
 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   AddObjCExpressionResults(Results, false);
   AddObjCExpressionResults(Results, false);
@@ -4527,6 +4569,7 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
   
   
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
@@ -4549,14 +4592,16 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
     Results.AddResult(CodeCompletionResult("atomic"));
     Results.AddResult(CodeCompletionResult("atomic"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
-    CodeCompletionBuilder Setter(Results.getAllocator());
+    CodeCompletionBuilder Setter(Results.getAllocator(),
+                                 Results.getCodeCompletionTUInfo());
     Setter.AddTypedTextChunk("setter");
     Setter.AddTypedTextChunk("setter");
     Setter.AddTextChunk(" = ");
     Setter.AddTextChunk(" = ");
     Setter.AddPlaceholderChunk("method");
     Setter.AddPlaceholderChunk("method");
     Results.AddResult(CodeCompletionResult(Setter.TakeString()));
     Results.AddResult(CodeCompletionResult(Setter.TakeString()));
   }
   }
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
-    CodeCompletionBuilder Getter(Results.getAllocator());
+    CodeCompletionBuilder Getter(Results.getAllocator(),
+                                 Results.getCodeCompletionTUInfo());
     Getter.AddTypedTextChunk("getter");
     Getter.AddTypedTextChunk("getter");
     Getter.AddTextChunk(" = ");
     Getter.AddTextChunk(" = ");
     Getter.AddPlaceholderChunk("method");
     Getter.AddPlaceholderChunk("method");
@@ -4747,6 +4792,7 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
 
 
   // Find all of the potential getters.
   // Find all of the potential getters.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
 
 
@@ -4776,6 +4822,7 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
 
 
   // Find all of the potential getters.
   // Find all of the potential getters.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
 
 
@@ -4793,6 +4840,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
                                        bool IsParameter) {
                                        bool IsParameter) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Type);
                         CodeCompletionContext::CCC_Type);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -4824,8 +4872,9 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
   //   IBAction)<#selector#>:(id)sender
   //   IBAction)<#selector#>:(id)sender
   if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
   if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
       Context.Idents.get("IBAction").hasMacroDefinition()) {
       Context.Idents.get("IBAction").hasMacroDefinition()) {
-    CodeCompletionBuilder Builder(Results.getAllocator(), CCP_CodePattern, 
-                                  CXAvailability_Available);
+    CodeCompletionBuilder Builder(Results.getAllocator(),
+                                  Results.getCodeCompletionTUInfo(),
+                                  CCP_CodePattern, CXAvailability_Available);
     Builder.AddTypedTextChunk("IBAction");
     Builder.AddTypedTextChunk("IBAction");
     Builder.AddChunk(CodeCompletionString::CK_RightParen);
     Builder.AddChunk(CodeCompletionString::CK_RightParen);
     Builder.AddPlaceholderChunk("selector");
     Builder.AddPlaceholderChunk("selector");
@@ -4996,7 +5045,8 @@ static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
   }
   }
   
   
   // We have a superclass method. Now, form the send-to-super completion.
   // We have a superclass method. Now, form the send-to-super completion.
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   
   
   // Give this completion a return type.
   // Give this completion a return type.
   AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, 
   AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, 
@@ -5050,6 +5100,7 @@ static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCMessageReceiver,
                         CodeCompletionContext::CCC_ObjCMessageReceiver,
                         getLangOpts().CPlusPlus0x
                         getLangOpts().CPlusPlus0x
                           ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
                           ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
@@ -5270,6 +5321,7 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
   QualType T = this->GetTypeFromParser(Receiver);
   QualType T = this->GetTypeFromParser(Receiver);
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
               CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
               CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
                                     T, SelIdents, NumSelIdents));
                                     T, SelIdents, NumSelIdents));
     
     
@@ -5335,6 +5387,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
 
 
   // Build the set of methods we can see.
   // Build the set of methods we can see.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
            CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
            CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
                                  ReceiverType, SelIdents, NumSelIdents));
                                  ReceiverType, SelIdents, NumSelIdents));
   
   
@@ -5486,6 +5539,7 @@ void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
   }
   }
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_SelectorName);
                         CodeCompletionContext::CCC_SelectorName);
   Results.EnterNewScope();
   Results.EnterNewScope();
   for (GlobalMethodPool::iterator M = MethodPool.begin(),
   for (GlobalMethodPool::iterator M = MethodPool.begin(),
@@ -5496,7 +5550,8 @@ void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
     if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
     if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
       continue;
       continue;
 
 
-    CodeCompletionBuilder Builder(Results.getAllocator());
+    CodeCompletionBuilder Builder(Results.getAllocator(),
+                                  Results.getCodeCompletionTUInfo());
     if (Sel.isUnarySelector()) {
     if (Sel.isUnarySelector()) {
       Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
       Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
                                                        Sel.getNameForSlot(0)));
                                                        Sel.getNameForSlot(0)));
@@ -5547,6 +5602,7 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
 void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
 void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
                                               unsigned NumProtocols) {
                                               unsigned NumProtocols) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCProtocolName);
                         CodeCompletionContext::CCC_ObjCProtocolName);
   
   
   if (CodeCompleter && CodeCompleter->includeGlobals()) {
   if (CodeCompleter && CodeCompleter->includeGlobals()) {
@@ -5574,6 +5630,7 @@ void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
 
 
 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCProtocolName);
                         CodeCompletionContext::CCC_ObjCProtocolName);
   
   
   if (CodeCompleter && CodeCompleter->includeGlobals()) {
   if (CodeCompleter && CodeCompleter->includeGlobals()) {
@@ -5612,6 +5669,7 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
 
 
 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 
 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -5631,6 +5689,7 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
                                       SourceLocation ClassNameLoc) { 
                                       SourceLocation ClassNameLoc) { 
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCInterfaceName);
                         CodeCompletionContext::CCC_ObjCInterfaceName);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
@@ -5655,6 +5714,7 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
 
 
 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
 
 
@@ -5677,6 +5737,7 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCCategoryName);
                         CodeCompletionContext::CCC_ObjCCategoryName);
   
   
   // Ignore any categories we find that have already been implemented by this
   // Ignore any categories we find that have already been implemented by this
@@ -5720,6 +5781,7 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
     return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
     return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
     
     
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_ObjCCategoryName);
                         CodeCompletionContext::CCC_ObjCCategoryName);
   
   
   // Add all of the categories that have have corresponding interface 
   // Add all of the categories that have have corresponding interface 
@@ -5748,6 +5810,7 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
 
 
   // Figure out where this @synthesize lives.
   // Figure out where this @synthesize lives.
@@ -5788,6 +5851,7 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
                                                   IdentifierInfo *PropertyName) {
                                                   IdentifierInfo *PropertyName) {
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
 
 
   // Figure out where this @synthesize lives.
   // Figure out where this @synthesize lives.
@@ -5857,7 +5921,8 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
     unsigned Priority = CCP_MemberDeclaration + 1;
     unsigned Priority = CCP_MemberDeclaration + 1;
     typedef CodeCompletionResult Result;
     typedef CodeCompletionResult Result;
     CodeCompletionAllocator &Allocator = Results.getAllocator();
     CodeCompletionAllocator &Allocator = Results.getAllocator();
-    CodeCompletionBuilder Builder(Allocator, Priority,CXAvailability_Available);
+    CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
+                                  Priority,CXAvailability_Available);
 
 
     PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
     PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
     Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
     Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
@@ -6004,7 +6069,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
   // Builder that will create each code completion.
   // Builder that will create each code completion.
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   CodeCompletionAllocator &Allocator = Results.getAllocator();
   CodeCompletionAllocator &Allocator = Results.getAllocator();
-  CodeCompletionBuilder Builder(Allocator);
+  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
   
   
   // The selector table.
   // The selector table.
   SelectorTable &Selectors = Context.Selectors;
   SelectorTable &Selectors = Context.Selectors;
@@ -6658,6 +6723,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
   // Add declarations or definitions for each of the known methods.
   // Add declarations or definitions for each of the known methods.
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   Results.EnterNewScope();
   Results.EnterNewScope();
   PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
   PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
@@ -6665,7 +6731,8 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
                               MEnd = KnownMethods.end();
                               MEnd = KnownMethods.end();
        M != MEnd; ++M) {
        M != MEnd; ++M) {
     ObjCMethodDecl *Method = M->second.first;
     ObjCMethodDecl *Method = M->second.first;
-    CodeCompletionBuilder Builder(Results.getAllocator());
+    CodeCompletionBuilder Builder(Results.getAllocator(),
+                                  Results.getCodeCompletionTUInfo());
     
     
     // If the result type was not already provided, add it to the
     // If the result type was not already provided, add it to the
     // pattern as (type).
     // pattern as (type).
@@ -6796,6 +6863,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
   // Build the set of methods we can see.
   // Build the set of methods we can see.
   typedef CodeCompletionResult Result;
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Other);
                         CodeCompletionContext::CCC_Other);
   
   
   if (ReturnTy)
   if (ReturnTy)
@@ -6818,7 +6886,8 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
         if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
         if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
           ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
           ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
           if (Param->getIdentifier()) {
           if (Param->getIdentifier()) {
-            CodeCompletionBuilder Builder(Results.getAllocator());
+            CodeCompletionBuilder Builder(Results.getAllocator(),
+                                          Results.getCodeCompletionTUInfo());
             Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
             Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
                                            Param->getIdentifier()->getName()));
                                            Param->getIdentifier()->getName()));
             Results.AddResult(Builder.TakeString());
             Results.AddResult(Builder.TakeString());
@@ -6844,11 +6913,13 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
 
 
 void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
 void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_PreprocessorDirective);
                         CodeCompletionContext::CCC_PreprocessorDirective);
   Results.EnterNewScope();
   Results.EnterNewScope();
   
   
   // #if <condition>
   // #if <condition>
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   Builder.AddTypedTextChunk("if");
   Builder.AddTypedTextChunk("if");
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddPlaceholderChunk("condition");
   Builder.AddPlaceholderChunk("condition");
@@ -7007,11 +7078,13 @@ void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
 
 
 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         IsDefinition? CodeCompletionContext::CCC_MacroName
                         IsDefinition? CodeCompletionContext::CCC_MacroName
                                     : CodeCompletionContext::CCC_MacroNameUse);
                                     : CodeCompletionContext::CCC_MacroNameUse);
   if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
   if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
     // Add just the names of macros, not their arguments.    
     // Add just the names of macros, not their arguments.    
-    CodeCompletionBuilder Builder(Results.getAllocator());
+    CodeCompletionBuilder Builder(Results.getAllocator(),
+                                  Results.getCodeCompletionTUInfo());
     Results.EnterNewScope();
     Results.EnterNewScope();
     for (Preprocessor::macro_iterator M = PP.macro_begin(), 
     for (Preprocessor::macro_iterator M = PP.macro_begin(), 
                                    MEnd = PP.macro_end();
                                    MEnd = PP.macro_end();
@@ -7031,6 +7104,7 @@ void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
 
 
 void Sema::CodeCompletePreprocessorExpression() {
 void Sema::CodeCompletePreprocessorExpression() {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_PreprocessorExpression);
                         CodeCompletionContext::CCC_PreprocessorExpression);
   
   
   if (!CodeCompleter || CodeCompleter->includeMacros())
   if (!CodeCompleter || CodeCompleter->includeMacros())
@@ -7038,7 +7112,8 @@ void Sema::CodeCompletePreprocessorExpression() {
   
   
     // defined (<macro>)
     // defined (<macro>)
   Results.EnterNewScope();
   Results.EnterNewScope();
-  CodeCompletionBuilder Builder(Results.getAllocator());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
   Builder.AddTypedTextChunk("defined");
   Builder.AddTypedTextChunk("defined");
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddChunk(CodeCompletionString::CK_LeftParen);
   Builder.AddChunk(CodeCompletionString::CK_LeftParen);
@@ -7070,8 +7145,10 @@ void Sema::CodeCompleteNaturalLanguage() {
 }
 }
 
 
 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
+                                       CodeCompletionTUInfo &CCTUInfo,
                  SmallVectorImpl<CodeCompletionResult> &Results) {
                  SmallVectorImpl<CodeCompletionResult> &Results) {
-  ResultBuilder Builder(*this, Allocator, CodeCompletionContext::CCC_Recovery);
+  ResultBuilder Builder(*this, Allocator, CCTUInfo,
+                        CodeCompletionContext::CCC_Recovery);
   if (!CodeCompleter || CodeCompleter->includeGlobals()) {
   if (!CodeCompleter || CodeCompleter->includeGlobals()) {
     CodeCompletionDeclConsumer Consumer(Builder, 
     CodeCompletionDeclConsumer Consumer(Builder, 
                                         Context.getTranslationUnitDecl());
                                         Context.getTranslationUnitDecl());

+ 13 - 7
tools/libclang/CIndexCodeCompletion.cpp

@@ -264,7 +264,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
     CachedCompletionAllocator;
     CachedCompletionAllocator;
   
   
   /// \brief Allocator used to store code completion results.
   /// \brief Allocator used to store code completion results.
-  clang::CodeCompletionAllocator CodeCompletionAllocator;
+  IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
+    CodeCompletionAllocator;
   
   
   /// \brief Context under which completion occurred.
   /// \brief Context under which completion occurred.
   enum clang::CodeCompletionContext::Kind ContextKind;
   enum clang::CodeCompletionContext::Kind ContextKind;
@@ -300,6 +301,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
     FileSystemOpts(FileSystemOpts),
     FileSystemOpts(FileSystemOpts),
     FileMgr(new FileManager(FileSystemOpts)),
     FileMgr(new FileManager(FileSystemOpts)),
     SourceMgr(new SourceManager(*Diag, *FileMgr)),
     SourceMgr(new SourceManager(*Diag, *FileMgr)),
+    CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
     Contexts(CXCompletionContext_Unknown),
     Contexts(CXCompletionContext_Unknown),
     ContainerKind(CXCursor_InvalidCode),
     ContainerKind(CXCursor_InvalidCode),
     ContainerUSR(createCXString("")),
     ContainerUSR(createCXString("")),
@@ -503,13 +505,15 @@ static unsigned long long getContextsForContextKind(
 namespace {
 namespace {
   class CaptureCompletionResults : public CodeCompleteConsumer {
   class CaptureCompletionResults : public CodeCompleteConsumer {
     AllocatedCXCodeCompleteResults &AllocatedResults;
     AllocatedCXCodeCompleteResults &AllocatedResults;
+    CodeCompletionTUInfo CCTUInfo;
     SmallVector<CXCompletionResult, 16> StoredResults;
     SmallVector<CXCompletionResult, 16> StoredResults;
     CXTranslationUnit *TU;
     CXTranslationUnit *TU;
   public:
   public:
     CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
     CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
                              CXTranslationUnit *TranslationUnit)
                              CXTranslationUnit *TranslationUnit)
       : CodeCompleteConsumer(true, false, true, false), 
       : CodeCompleteConsumer(true, false, true, false), 
-        AllocatedResults(Results), TU(TranslationUnit) { }
+        AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
+        TU(TranslationUnit) { }
     ~CaptureCompletionResults() { Finish(); }
     ~CaptureCompletionResults() { Finish(); }
     
     
     virtual void ProcessCodeCompleteResults(Sema &S, 
     virtual void ProcessCodeCompleteResults(Sema &S, 
@@ -519,8 +523,8 @@ namespace {
       StoredResults.reserve(StoredResults.size() + NumResults);
       StoredResults.reserve(StoredResults.size() + NumResults);
       for (unsigned I = 0; I != NumResults; ++I) {
       for (unsigned I = 0; I != NumResults; ++I) {
         CodeCompletionString *StoredCompletion        
         CodeCompletionString *StoredCompletion        
-          = Results[I].CreateCodeCompletionString(S, 
-                                      AllocatedResults.CodeCompletionAllocator);
+          = Results[I].CreateCodeCompletionString(S, getAllocator(),
+                                                  getCodeCompletionTUInfo());
         
         
         CXCompletionResult R;
         CXCompletionResult R;
         R.CursorKind = Results[I].CursorKind;
         R.CursorKind = Results[I].CursorKind;
@@ -607,8 +611,8 @@ namespace {
       StoredResults.reserve(StoredResults.size() + NumCandidates);
       StoredResults.reserve(StoredResults.size() + NumCandidates);
       for (unsigned I = 0; I != NumCandidates; ++I) {
       for (unsigned I = 0; I != NumCandidates; ++I) {
         CodeCompletionString *StoredCompletion
         CodeCompletionString *StoredCompletion
-          = Candidates[I].CreateSignatureString(CurrentArg, S, 
-                                      AllocatedResults.CodeCompletionAllocator);
+          = Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
+                                                getCodeCompletionTUInfo());
         
         
         CXCompletionResult R;
         CXCompletionResult R;
         R.CursorKind = CXCursor_NotImplemented;
         R.CursorKind = CXCursor_NotImplemented;
@@ -618,8 +622,10 @@ namespace {
     }
     }
     
     
     virtual CodeCompletionAllocator &getAllocator() { 
     virtual CodeCompletionAllocator &getAllocator() { 
-      return AllocatedResults.CodeCompletionAllocator;
+      return *AllocatedResults.CodeCompletionAllocator;
     }
     }
+
+    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
     
     
   private:
   private:
     void Finish() {
     void Finish() {

+ 4 - 6
tools/libclang/CXCursor.cpp

@@ -1076,13 +1076,12 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
     Decl *decl = getCursorDecl(cursor);
     Decl *decl = getCursorDecl(cursor);
     if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
     if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
       ASTUnit *unit = getCursorASTUnit(cursor);
       ASTUnit *unit = getCursorASTUnit(cursor);
-      CodeCompletionAllocator *Allocator
-        = unit->getCursorCompletionAllocator().getPtr();
       CodeCompletionResult Result(namedDecl);
       CodeCompletionResult Result(namedDecl);
       CodeCompletionString *String
       CodeCompletionString *String
         = Result.CreateCodeCompletionString(unit->getASTContext(),
         = Result.CreateCodeCompletionString(unit->getASTContext(),
                                             unit->getPreprocessor(),
                                             unit->getPreprocessor(),
-                                            *Allocator);
+                                 unit->getCodeCompletionTUInfo().getAllocator(),
+                                 unit->getCodeCompletionTUInfo());
       return String;
       return String;
     }
     }
   }
   }
@@ -1090,13 +1089,12 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
     MacroDefinition *definition = getCursorMacroDefinition(cursor);
     MacroDefinition *definition = getCursorMacroDefinition(cursor);
     const IdentifierInfo *MacroInfo = definition->getName();
     const IdentifierInfo *MacroInfo = definition->getName();
     ASTUnit *unit = getCursorASTUnit(cursor);
     ASTUnit *unit = getCursorASTUnit(cursor);
-    CodeCompletionAllocator *Allocator
-      = unit->getCursorCompletionAllocator().getPtr();
     CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
     CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
     CodeCompletionString *String
     CodeCompletionString *String
       = Result.CreateCodeCompletionString(unit->getASTContext(),
       = Result.CreateCodeCompletionString(unit->getASTContext(),
                                           unit->getPreprocessor(),
                                           unit->getPreprocessor(),
-                                          *Allocator);
+                                 unit->getCodeCompletionTUInfo().getAllocator(),
+                                 unit->getCodeCompletionTUInfo());
     return String;
     return String;
   }
   }
   return NULL;
   return NULL;