From: Argyrios Kyrtzidis Date: Tue, 10 Apr 2012 17:23:48 +0000 (+0000) Subject: [code-complete] Introduce CodeCompletionTUInfo which will be used for caching X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=28a83f57003469fb615ad27dd34bcf5b0a10da8c;p=clang [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 --- diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 3d0639561a..5b869a2136 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -58,14 +58,6 @@ class ASTFrontendAction; using namespace idx; -/// \brief Allocator for a cached set of global code completions. -class GlobalCodeCompletionAllocator - : public CodeCompletionAllocator, - public RefCountedBase -{ - -}; - /// \brief Utility class for loading a ASTContext from an AST file. /// class ASTUnit : public ModuleLoader { @@ -324,25 +316,20 @@ public: getCachedCompletionAllocator() { return CachedCompletionAllocator; } - - /// \brief Retrieve the allocator used to cache global code completions. - /// Creates the allocator if it doesn't already exist. - IntrusiveRefCntPtr - 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 CachedCompletionAllocator; - /// \brief Allocator used to store code completions for arbitrary cursors. - IntrusiveRefCntPtr - CursorCompletionAllocator; + OwningPtr CCTUInfo; /// \brief The set of cached code-completion results. std::vector CachedCompletionResults; diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index ff2ca871f2..fe9bed5c86 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -501,8 +501,6 @@ public: /// \brief An allocator used specifically for the purpose of code completion. class CodeCompletionAllocator : public llvm::BumpPtrAllocator { - llvm::DenseMap ParentNames; - public: /// \brief Copy the given string into this allocator. const char *CopyString(StringRef String); @@ -519,12 +517,34 @@ public: 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 &getParentNames() { - return ParentNames; +}; + +/// \brief Allocator for a cached set of global code completions. +class GlobalCodeCompletionAllocator + : public CodeCompletionAllocator, + public RefCountedBase +{ + +}; + +class CodeCompletionTUInfo { + llvm::DenseMap ParentNames; + IntrusiveRefCntPtr AllocatorRef; + +public: + explicit CodeCompletionTUInfo( + IntrusiveRefCntPtr Allocator) + : AllocatorRef(Allocator) { } + + IntrusiveRefCntPtr getAllocatorRef() const { + return AllocatorRef; + } + CodeCompletionAllocator &getAllocator() const { + assert(AllocatorRef); + return *AllocatorRef; } + + StringRef getParentName(DeclContext *DC); }; } // end namespace clang @@ -544,6 +564,7 @@ public: private: CodeCompletionAllocator &Allocator; + CodeCompletionTUInfo &CCTUInfo; unsigned Priority; CXAvailabilityKind Availability; CXCursorKind ParentKind; @@ -555,19 +576,25 @@ private: SmallVector 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 @@ public: /// \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 @@ public: /// 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 @@ public: /// \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 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { /// \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 @@ public: 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 @@ public: OverloadCandidate *Candidates, unsigned NumCandidates); - virtual CodeCompletionAllocator &getAllocator() { return Allocator; } + virtual CodeCompletionAllocator &getAllocator() { + return CCTUInfo.getAllocator(); + } + + virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; } }; } // end namespace clang diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 674dd25604..31c410a9f9 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -78,6 +78,7 @@ namespace clang { class ClassTemplateSpecializationDecl; class CodeCompleteConsumer; class CodeCompletionAllocator; + class CodeCompletionTUInfo; class CodeCompletionResult; class Decl; class DeclAccessPair; @@ -6647,6 +6648,7 @@ public: unsigned Argument); void CodeCompleteNaturalLanguage(); void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, SmallVectorImpl &Results); //@} diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 25c8ab89b7..563ed03588 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -351,7 +351,8 @@ void ASTUnit::CacheCodeCompletionResults() { typedef CodeCompletionResult Result; SmallVector Results; CachedCompletionAllocator = new GlobalCodeCompletionAllocator; - TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, Results); + TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, + getCodeCompletionTUInfo(), Results); // Translate global code completions into cached completions. llvm::DenseMap CompletionTypes; @@ -362,7 +363,8 @@ void ASTUnit::CacheCodeCompletionResults() { 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 @@ void ASTUnit::CacheCodeCompletionResults() { 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 @@ void ASTUnit::CacheCodeCompletionResults() { 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 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 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 @@ namespace { virtual CodeCompletionAllocator &getAllocator() { return Next.getAllocator(); } + + virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { + return Next.getCodeCompletionTUInfo(); + } }; } @@ -2210,8 +2218,8 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 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; diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index dbc9b0080a..ce9bbb9238 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -267,8 +267,70 @@ const char *CodeCompletionAllocator::CopyString(Twine String) { return CopyString(String.toStringRef(Data)); } +StringRef CodeCompletionTUInfo::getParentName(DeclContext *DC) { + NamedDecl *ND = dyn_cast(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 Contexts; + while (DC && !DC->isFunctionOrMethod()) { + if (NamedDecl *ND = dyn_cast(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(CurDC)) + CurDC = CatImpl->getCategoryDecl(); + + if (ObjCCategoryDecl *Cat = dyn_cast(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(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()); @@ -329,54 +391,7 @@ void CodeCompletionBuilder::addParentContext(DeclContext *DC) { 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 Contexts; - while (DC && !DC->isFunctionOrMethod()) { - if (NamedDecl *ND = dyn_cast(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(CurDC)) - CurDC = CatImpl->getCategoryDecl(); - - if (ObjCCategoryDecl *Cat = dyn_cast(CurDC)) { - ObjCInterfaceDecl *Interface = Cat->getClassInterface(); - if (!Interface) - return; - - OS << Interface->getName() << '(' << Cat->getName() << ')'; - } else { - OS << cast(CurDC)->getName(); - } - } - - ParentName = Allocator.CopyString(OS.str()); - CachedParentName = ParentName; - } + ParentName = getCodeCompletionTUInfo().getParentName(DC); } unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) { @@ -458,7 +473,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, 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 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, 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 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef, for (unsigned I = 0; I != NumCandidates; ++I) { if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(CurrentArg, SemaRef, - Allocator)) { + getAllocator(), CCTUInfo)) { OS << "OVERLOAD: " << CCS->getAsString() << "\n"; } } diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index c09cd177be..32f36d4559 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -123,6 +123,8 @@ namespace { /// \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 @@ namespace { 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 @@ namespace { /// \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 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, 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 AddObjCInterfaceResults(const LangOptions &LangOpts, 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 @@ static void addThisCompletion(Sema &S, ResultBuilder &Results) { 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 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, 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 @@ static void AddFunctionParameterChunks(ASTContext &Context, 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 @@ static void AddTemplateParameterChunks(ASTContext &Context, 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 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, } 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(Sema &S, 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 @@ CodeCompletionString * 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 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, 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(*M); if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl()) continue; @@ -3034,11 +3048,12 @@ void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc, 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 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), mapCodeCompletionContext(*this, CompletionContext)); Results.EnterNewScope(); @@ -3180,6 +3196,7 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNestedNameSpecifiers) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), AllowNestedNameSpecifiers ? CodeCompletionContext::CCC_PotentiallyQualifiedName : CodeCompletionContext::CCC_Name); @@ -3257,6 +3274,7 @@ void Sema::CodeCompleteExpression(Scope *S, 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 @@ static void AddObjCProperties(ObjCContainerDecl *Container, 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 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, } ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext(contextKind, BaseType), &ResultBuilder::IsMember); @@ -3540,7 +3560,8 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { 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::CodeCompleteTag(Scope *S, unsigned TagSpec) { 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 @@ void Sema::CodeCompleteCase(Scope *S) { // 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::CodeCompleteReturn(Scope *S) { 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 @@ void Sema::CodeCompleteAfterIf(Scope *S) { 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 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, return; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Name); Results.EnterNewScope(); @@ -3939,6 +3965,7 @@ void Sema::CodeCompleteUsing(Scope *S) { return; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_PotentiallyQualifiedName, &ResultBuilder::IsNestedNameSpecifier); Results.EnterNewScope(); @@ -3966,6 +3993,7 @@ void Sema::CodeCompleteUsingDirective(Scope *S) { // 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 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { = Ctx && !CodeCompleter->includeGlobals() && isa(Ctx); ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), SuppressedGlobalResults ? CodeCompletionContext::CCC_Namespace : CodeCompletionContext::CCC_Other, @@ -4029,6 +4058,7 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { // 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 @@ void Sema::CodeCompleteOperatorName(Scope *S) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Type, &ResultBuilder::IsType); Results.EnterNewScope(); @@ -4080,6 +4111,7 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD, return; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_PotentiallyQualifiedName); Results.EnterNewScope(); @@ -4096,7 +4128,8 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD, } // 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 @@ static bool isNamespaceScope(Scope *S) { 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 @@ static void AddObjCImplementationResults(const LangOptions &LangOpts, // 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 AddObjCInterfaceResults(const LangOptions &LangOpts, 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 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { void Sema::CodeCompleteObjCAtDirective(Scope *S) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); if (isa(CurContext)) @@ -4342,7 +4379,8 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S) { 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 AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { 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 @@ static void AddObjCVisibilityResults(const LangOptions &LangOpts, 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::CodeCompleteObjCAtVisibility(Scope *S) { 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::CodeCompleteObjCAtStatement(Scope *S) { void Sema::CodeCompleteObjCAtExpression(Scope *S) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); AddObjCExpressionResults(Results, false); @@ -4527,6 +4569,7 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 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 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 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 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { // Find all of the potential getters. ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); @@ -4776,6 +4822,7 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S) { // Find all of the potential getters. ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); @@ -4793,6 +4840,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Type); Results.EnterNewScope(); @@ -4824,8 +4872,9 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, // 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 @@ static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword, } // 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 @@ static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword, 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 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, QualType T = this->GetTypeFromParser(Receiver); ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, T, SelIdents, NumSelIdents)); @@ -5335,6 +5387,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, // 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 @@ void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents, } ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_SelectorName); Results.EnterNewScope(); for (GlobalMethodPool::iterator M = MethodPool.begin(), @@ -5496,7 +5550,8 @@ void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents, 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 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, 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::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, void Sema::CodeCompleteObjCProtocolDecl(Scope *) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_ObjCProtocolName); if (CodeCompleter && CodeCompleter->includeGlobals()) { @@ -5612,6 +5669,7 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); @@ -5631,6 +5689,7 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 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::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); @@ -5677,6 +5737,7 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 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 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 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::CodeCompleteObjCImplementationCategory(Scope *S, 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 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 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 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 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 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // 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 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, // 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 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, 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 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, // 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 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 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::CodeCompleteObjCMethodDeclSelector(Scope *S, void Sema::CodeCompletePreprocessorDirective(bool InConditional) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_PreprocessorDirective); Results.EnterNewScope(); // #if - 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::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) { 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::CodeCompletePreprocessorMacroName(bool IsDefinition) { void Sema::CodeCompletePreprocessorExpression() { ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_PreprocessorExpression); if (!CodeCompleter || CodeCompleter->includeMacros()) @@ -7038,7 +7112,8 @@ void Sema::CodeCompletePreprocessorExpression() { // defined () 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::CodeCompleteNaturalLanguage() { } void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, SmallVectorImpl &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()); diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 95ed3c4843..303fb1f9d5 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -264,7 +264,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { CachedCompletionAllocator; /// \brief Allocator used to store code completion results. - clang::CodeCompletionAllocator CodeCompletionAllocator; + IntrusiveRefCntPtr + CodeCompletionAllocator; /// \brief Context under which completion occurred. enum clang::CodeCompletionContext::Kind ContextKind; @@ -300,6 +301,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults( 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 @@ static unsigned long long getContextsForContextKind( namespace { class CaptureCompletionResults : public CodeCompleteConsumer { AllocatedCXCodeCompleteResults &AllocatedResults; + CodeCompletionTUInfo CCTUInfo; SmallVector 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 @@ namespace { 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 @@ namespace { 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 @@ namespace { } virtual CodeCompletionAllocator &getAllocator() { - return AllocatedResults.CodeCompletionAllocator; + return *AllocatedResults.CodeCompletionAllocator; } + + virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; } private: void Finish() { diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 84a6ccb07e..0533c84a57 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -1076,13 +1076,12 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { Decl *decl = getCursorDecl(cursor); if (NamedDecl *namedDecl = dyn_cast_or_null(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 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { MacroDefinition *definition = getCursorMacroDefinition(cursor); const IdentifierInfo *MacroInfo = definition->getName(); ASTUnit *unit = getCursorASTUnit(cursor); - CodeCompletionAllocator *Allocator - = unit->getCursorCompletionAllocator().getPtr(); CodeCompletionResult Result(const_cast(MacroInfo)); CodeCompletionString *String = Result.CreateCodeCompletionString(unit->getASTContext(), unit->getPreprocessor(), - *Allocator); + unit->getCodeCompletionTUInfo().getAllocator(), + unit->getCodeCompletionTUInfo()); return String; } return NULL;