[cfe-commits] r154408 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Sema/CodeCompleteConsumer.cpp lib/Sema/SemaCodeComplete.cpp tools/libclang/CIndexCodeCompletion.cpp tools/libclang/CXCursor.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Apr 10 10:23:48 PDT 2012


Author: akirtzidis
Date: Tue Apr 10 12:23:48 2012
New Revision: 154408

URL: http://llvm.org/viewvc/llvm-project?rev=154408&view=rev
Log:
[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.

Modified:
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Apr 10 12:23:48 2012
@@ -58,14 +58,6 @@
 
 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.
 ///
 class ASTUnit : public ModuleLoader {
@@ -324,25 +316,20 @@
   getCachedCompletionAllocator() {
     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:
   /// \brief Allocator used to store cached code completions.
   IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
     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.
   std::vector<CachedCodeCompletionResult> CachedCompletionResults;

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Tue Apr 10 12:23:48 2012
@@ -501,8 +501,6 @@
 
 /// \brief An allocator used specifically for the purpose of code completion.
 class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
-  llvm::DenseMap<DeclContext *, StringRef> ParentNames;
-  
 public:
   /// \brief Copy the given string into this allocator.
   const char *CopyString(StringRef String);
@@ -519,12 +517,34 @@
   const char *CopyString(const std::string &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
@@ -544,6 +564,7 @@
 
 private:
   CodeCompletionAllocator &Allocator;
+  CodeCompletionTUInfo &CCTUInfo;
   unsigned Priority;
   CXAvailabilityKind Availability;
   CXCursorKind ParentKind;
@@ -555,19 +576,25 @@
   SmallVector<const char *, 2> Annotations;
 
 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) { }
 
   CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
+                        CodeCompletionTUInfo &CCTUInfo,
                         unsigned Priority, CXAvailabilityKind Availability)
-    : Allocator(Allocator), Priority(Priority), Availability(Availability),
+    : Allocator(Allocator), CCTUInfo(CCTUInfo),
+      Priority(Priority), Availability(Availability),
       ParentKind(CXCursor_NotImplemented) { }
 
   /// \brief Retrieve the allocator into which the code completion
   /// strings should be allocated.
   CodeCompletionAllocator &getAllocator() const { return Allocator; }
 
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
+
   /// \brief Take the resulting completion string.
   ///
   /// This operation can only be performed once.
@@ -753,10 +780,12 @@
   /// \param Allocator The allocator that will be used to allocate the
   /// string itself.
   CodeCompletionString *CreateCodeCompletionString(Sema &S,
-                                           CodeCompletionAllocator &Allocator);
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo);
   CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
                                                    Preprocessor &PP,
-                                           CodeCompletionAllocator &Allocator);
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo);
 
   /// \brief Determine a base priority for the given declaration.
   static unsigned getPriorityFromDecl(NamedDecl *ND);
@@ -868,7 +897,8 @@
     /// signature of this overload candidate.
     CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
                                                 Sema &S,
-                                      CodeCompletionAllocator &Allocator) const;
+                                      CodeCompletionAllocator &Allocator,
+                                      CodeCompletionTUInfo &CCTUInfo) const;
   };
 
   CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
@@ -918,6 +948,8 @@
   /// \brief Retrieve the allocator that will be used to allocate
   /// code completion strings.
   virtual CodeCompletionAllocator &getAllocator() = 0;
+
+  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0;
 };
 
 /// \brief A simple code-completion consumer that prints the results it
@@ -926,7 +958,7 @@
   /// \brief The raw output stream.
   raw_ostream &OS;
 
-  CodeCompletionAllocator Allocator;
+  CodeCompletionTUInfo CCTUInfo;
 
 public:
   /// \brief Create a new printing code-completion consumer that prints its
@@ -935,7 +967,8 @@
                                bool IncludeGlobals,
                                raw_ostream &OS)
     : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
-                           false), OS(OS) {}
+                           false), OS(OS),
+      CCTUInfo(new GlobalCodeCompletionAllocator) {}
 
   /// \brief Prints the finalized code-completion results.
   virtual void ProcessCodeCompleteResults(Sema &S,
@@ -947,7 +980,11 @@
                                          OverloadCandidate *Candidates,
                                          unsigned NumCandidates);
 
-  virtual CodeCompletionAllocator &getAllocator() { return Allocator; }
+  virtual CodeCompletionAllocator &getAllocator() {
+    return CCTUInfo.getAllocator();
+  }
+
+  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 10 12:23:48 2012
@@ -78,6 +78,7 @@
   class ClassTemplateSpecializationDecl;
   class CodeCompleteConsumer;
   class CodeCompletionAllocator;
+  class CodeCompletionTUInfo;
   class CodeCompletionResult;
   class Decl;
   class DeclAccessPair;
@@ -6647,6 +6648,7 @@
                                              unsigned Argument);
   void CodeCompleteNaturalLanguage();
   void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
+                                   CodeCompletionTUInfo &CCTUInfo,
                   SmallVectorImpl<CodeCompletionResult> &Results);
   //@}
 

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Apr 10 12:23:48 2012
@@ -351,7 +351,8 @@
   typedef CodeCompletionResult Result;
   SmallVector<Result, 8> Results;
   CachedCompletionAllocator = new GlobalCodeCompletionAllocator;
-  TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results);
+  TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
+                                       getCodeCompletionTUInfo(), Results);
   
   // Translate global code completions into cached completions.
   llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
@@ -362,7 +363,8 @@
       bool IsNestedNameSpecifier = false;
       CachedCodeCompletionResult CachedResult;
       CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
-                                                    *CachedCompletionAllocator);
+                                                    *CachedCompletionAllocator,
+                                                    getCodeCompletionTUInfo());
       CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
                                                         Ctx->getLangOpts(),
                                                         IsNestedNameSpecifier);
@@ -426,7 +428,8 @@
           Results[I].StartsNestedNameSpecifier = true;
           CachedResult.Completion 
             = Results[I].CreateCodeCompletionString(*TheSema,
-                                                    *CachedCompletionAllocator);
+                                                    *CachedCompletionAllocator,
+                                                    getCodeCompletionTUInfo());
           CachedResult.ShowInContexts = RemainingContexts;
           CachedResult.Priority = CCP_NestedNameSpecifier;
           CachedResult.TypeClass = STC_Void;
@@ -447,7 +450,8 @@
       CachedCodeCompletionResult CachedResult;
       CachedResult.Completion 
         = Results[I].CreateCodeCompletionString(*TheSema,
-                                                *CachedCompletionAllocator);
+                                                *CachedCompletionAllocator,
+                                                getCodeCompletionTUInfo());
       CachedResult.ShowInContexts
         = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
@@ -1989,9 +1993,9 @@
       CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
     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;
 }
@@ -2053,6 +2057,10 @@
     virtual CodeCompletionAllocator &getAllocator() {
       return Next.getAllocator();
     }
+
+    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() {
+      return Next.getCodeCompletionTUInfo();
+    }
   };
 }
 
@@ -2210,8 +2218,8 @@
         Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
       // Create a new code-completion string that just contains the
       // 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());
       CursorKind = CXCursor_NotImplemented;
       Priority = CCP_CodePattern;

Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Tue Apr 10 12:23:48 2012
@@ -267,8 +267,70 @@
   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() {
-  void *Mem = Allocator.Allocate(
+  void *Mem = getAllocator().Allocate(
                   sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size()
                                     + sizeof(const char *) * Annotations.size(),
                                  llvm::alignOf<CodeCompletionString>());
@@ -329,54 +391,7 @@
     return;
   
   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) {
@@ -458,7 +473,8 @@
       if (Results[I].Hidden)
         OS << " (Hidden)";
       if (CodeCompletionString *CCS 
-            = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
+            = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
+                                                    CCTUInfo)) {
         OS << " : " << CCS->getAsString();
       }
         
@@ -472,7 +488,8 @@
     case CodeCompletionResult::RK_Macro: {
       OS << Results[I].Macro->getName();
       if (CodeCompletionString *CCS 
-            = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
+            = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
+                                                    CCTUInfo)) {
         OS << " : " << CCS->getAsString();
       }
       OS << '\n';
@@ -496,7 +513,7 @@
   for (unsigned I = 0; I != NumCandidates; ++I) {
     if (CodeCompletionString *CCS
           = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
-                                                Allocator)) {
+                                                getAllocator(), CCTUInfo)) {
       OS << "OVERLOAD: " << CCS->getAsString() << "\n";
     }
   }

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

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Tue Apr 10 12:23:48 2012
@@ -264,7 +264,8 @@
     CachedCompletionAllocator;
   
   /// \brief Allocator used to store code completion results.
-  clang::CodeCompletionAllocator CodeCompletionAllocator;
+  IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
+    CodeCompletionAllocator;
   
   /// \brief Context under which completion occurred.
   enum clang::CodeCompletionContext::Kind ContextKind;
@@ -300,6 +301,7 @@
     FileSystemOpts(FileSystemOpts),
     FileMgr(new FileManager(FileSystemOpts)),
     SourceMgr(new SourceManager(*Diag, *FileMgr)),
+    CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
     Contexts(CXCompletionContext_Unknown),
     ContainerKind(CXCursor_InvalidCode),
     ContainerUSR(createCXString("")),
@@ -503,13 +505,15 @@
 namespace {
   class CaptureCompletionResults : public CodeCompleteConsumer {
     AllocatedCXCodeCompleteResults &AllocatedResults;
+    CodeCompletionTUInfo CCTUInfo;
     SmallVector<CXCompletionResult, 16> StoredResults;
     CXTranslationUnit *TU;
   public:
     CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
                              CXTranslationUnit *TranslationUnit)
       : CodeCompleteConsumer(true, false, true, false), 
-        AllocatedResults(Results), TU(TranslationUnit) { }
+        AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
+        TU(TranslationUnit) { }
     ~CaptureCompletionResults() { Finish(); }
     
     virtual void ProcessCodeCompleteResults(Sema &S, 
@@ -519,8 +523,8 @@
       StoredResults.reserve(StoredResults.size() + NumResults);
       for (unsigned I = 0; I != NumResults; ++I) {
         CodeCompletionString *StoredCompletion        
-          = Results[I].CreateCodeCompletionString(S, 
-                                      AllocatedResults.CodeCompletionAllocator);
+          = Results[I].CreateCodeCompletionString(S, getAllocator(),
+                                                  getCodeCompletionTUInfo());
         
         CXCompletionResult R;
         R.CursorKind = Results[I].CursorKind;
@@ -607,8 +611,8 @@
       StoredResults.reserve(StoredResults.size() + NumCandidates);
       for (unsigned I = 0; I != NumCandidates; ++I) {
         CodeCompletionString *StoredCompletion
-          = Candidates[I].CreateSignatureString(CurrentArg, S, 
-                                      AllocatedResults.CodeCompletionAllocator);
+          = Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
+                                                getCodeCompletionTUInfo());
         
         CXCompletionResult R;
         R.CursorKind = CXCursor_NotImplemented;
@@ -618,8 +622,10 @@
     }
     
     virtual CodeCompletionAllocator &getAllocator() { 
-      return AllocatedResults.CodeCompletionAllocator;
+      return *AllocatedResults.CodeCompletionAllocator;
     }
+
+    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
     
   private:
     void Finish() {

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=154408&r1=154407&r2=154408&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Apr 10 12:23:48 2012
@@ -1076,13 +1076,12 @@
     Decl *decl = getCursorDecl(cursor);
     if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
       ASTUnit *unit = getCursorASTUnit(cursor);
-      CodeCompletionAllocator *Allocator
-        = unit->getCursorCompletionAllocator().getPtr();
       CodeCompletionResult Result(namedDecl);
       CodeCompletionString *String
         = Result.CreateCodeCompletionString(unit->getASTContext(),
                                             unit->getPreprocessor(),
-                                            *Allocator);
+                                 unit->getCodeCompletionTUInfo().getAllocator(),
+                                 unit->getCodeCompletionTUInfo());
       return String;
     }
   }
@@ -1090,13 +1089,12 @@
     MacroDefinition *definition = getCursorMacroDefinition(cursor);
     const IdentifierInfo *MacroInfo = definition->getName();
     ASTUnit *unit = getCursorASTUnit(cursor);
-    CodeCompletionAllocator *Allocator
-      = unit->getCursorCompletionAllocator().getPtr();
     CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
     CodeCompletionString *String
       = Result.CreateCodeCompletionString(unit->getASTContext(),
                                           unit->getPreprocessor(),
-                                          *Allocator);
+                                 unit->getCodeCompletionTUInfo().getAllocator(),
+                                 unit->getCodeCompletionTUInfo());
     return String;
   }
   return NULL;





More information about the cfe-commits mailing list