diff options
author | Douglas Gregor <dgregor@apple.com> | 2015-07-07 06:20:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2015-07-07 06:20:19 +0000 |
commit | c3425b1ff9b9b2027447fc004a1e4b530d19d3cf (patch) | |
tree | 92adf1050e80dae60b49f1367c66e603d541fe37 | |
parent | ab7f0b342f2f5dd85c6ede23bc843c5128f6ed10 (diff) | |
download | bcm5719-llvm-c3425b1ff9b9b2027447fc004a1e4b530d19d3cf.tar.gz bcm5719-llvm-c3425b1ff9b9b2027447fc004a1e4b530d19d3cf.zip |
[libclang] Replace ObjC generic parameters in code-completion results.
rdar://19369529
llvm-svn: 241557
-rw-r--r-- | clang/include/clang/Sema/CodeCompleteConsumer.h | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/CodeCompleteConsumer.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 113 | ||||
-rw-r--r-- | clang/test/Index/complete-parameterized-classes.m | 53 | ||||
-rw-r--r-- | clang/tools/libclang/CIndexCodeCompletion.cpp | 2 | ||||
-rw-r--r-- | clang/tools/libclang/CXCursor.cpp | 12 |
7 files changed, 147 insertions, 48 deletions
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index de65c43c76b..97022738d03 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -765,11 +765,13 @@ public: /// \param Allocator The allocator that will be used to allocate the /// string itself. CodeCompletionString *CreateCodeCompletionString(Sema &S, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments); CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx, Preprocessor &PP, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 01c56bdc4df..57c97d0c312 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -353,6 +353,7 @@ void ASTUnit::CacheCodeCompletionResults() { // Translate global code completions into cached completions. llvm::DenseMap<CanQualType, unsigned> CompletionTypes; + CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel); for (Result &R : Results) { switch (R.Kind) { @@ -360,7 +361,7 @@ void ASTUnit::CacheCodeCompletionResults() { bool IsNestedNameSpecifier = false; CachedCodeCompletionResult CachedResult; CachedResult.Completion = R.CreateCodeCompletionString( - *TheSema, *CachedCompletionAllocator, CCTUInfo, + *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo, IncludeBriefCommentsInCodeCompletion); CachedResult.ShowInContexts = getDeclShowContexts( R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier); @@ -423,7 +424,7 @@ void ASTUnit::CacheCodeCompletionResults() { // nested-name-specifier completion. R.StartsNestedNameSpecifier = true; CachedResult.Completion = R.CreateCodeCompletionString( - *TheSema, *CachedCompletionAllocator, CCTUInfo, + *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo, IncludeBriefCommentsInCodeCompletion); CachedResult.ShowInContexts = RemainingContexts; CachedResult.Priority = CCP_NestedNameSpecifier; @@ -444,7 +445,7 @@ void ASTUnit::CacheCodeCompletionResults() { case Result::RK_Macro: { CachedCodeCompletionResult CachedResult; CachedResult.Completion = R.CreateCodeCompletionString( - *TheSema, *CachedCompletionAllocator, CCTUInfo, + *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo, IncludeBriefCommentsInCodeCompletion); CachedResult.ShowInContexts = (1LL << CodeCompletionContext::CCC_TopLevel) diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 69ae4f01dc7..18e9a591164 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -444,7 +444,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, if (Results[I].Hidden) OS << " (Hidden)"; if (CodeCompletionString *CCS - = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(), + = Results[I].CreateCodeCompletionString(SemaRef, Context, + getAllocator(), CCTUInfo, includeBriefComments())) { OS << " : " << CCS->getAsString(); @@ -462,7 +463,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, case CodeCompletionResult::RK_Macro: { OS << Results[I].Macro->getName(); if (CodeCompletionString *CCS - = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(), + = Results[I].CreateCodeCompletionString(SemaRef, Context, + getAllocator(), CCTUInfo, includeBriefComments())) { OS << " : " << CCS->getAsString(); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index e4e99ab9932..61e244601fb 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2057,6 +2057,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, static void AddResultTypeChunk(ASTContext &Context, const PrintingPolicy &Policy, const NamedDecl *ND, + QualType BaseType, CodeCompletionBuilder &Result) { if (!ND) return; @@ -2070,16 +2071,28 @@ static void AddResultTypeChunk(ASTContext &Context, QualType T; if (const FunctionDecl *Function = ND->getAsFunction()) T = Function->getReturnType(); - else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) - T = Method->getReturnType(); - else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) + else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) { + if (!BaseType.isNull()) + T = Method->getSendResultType(BaseType); + else + T = Method->getReturnType(); + } else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); else if (isa<UnresolvedUsingValueDecl>(ND)) { /* Do nothing: ignore unresolved using declarations*/ + } else if (const ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { + if (!BaseType.isNull()) + T = Ivar->getUsageType(BaseType); + else + T = Ivar->getType(); } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) { T = Value->getType(); - } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) - T = Property->getType(); + } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) { + if (!BaseType.isNull()) + T = Property->getUsageType(BaseType); + else + T = Property->getType(); + } if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) return; @@ -2140,7 +2153,8 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals, static std::string FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, bool SuppressName = false, - bool SuppressBlock = false) { + bool SuppressBlock = false, + Optional<ArrayRef<QualType>> ObjCSubsts = None) { bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); if (Param->getType()->isDependentType() || !Param->getType()->isBlockPointerType()) { @@ -2152,6 +2166,9 @@ static std::string FormatFunctionParameter(const PrintingPolicy &Policy, Result = Param->getIdentifier()->getName(); QualType Type = Param->getType(); + if (ObjCSubsts) + Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts, + ObjCSubstitutionContext::Parameter); if (ObjCMethodParam) { Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); @@ -2226,6 +2243,10 @@ static std::string FormatFunctionParameter(const PrintingPolicy &Policy, // written in the source. std::string Result; QualType ResultType = Block.getTypePtr()->getReturnType(); + if (ObjCSubsts) + ResultType = ResultType.substObjCTypeArgs(Param->getASTContext(), + *ObjCSubsts, + ObjCSubstitutionContext::Result); if (!ResultType->isVoidType() || SuppressBlock) ResultType.getAsStringInternal(Result, Policy); @@ -2243,7 +2264,8 @@ static std::string FormatFunctionParameter(const PrintingPolicy &Policy, Params += ", "; Params += FormatFunctionParameter(Policy, Block.getParam(I), /*SuppressName=*/false, - /*SuppressBlock=*/true); + /*SuppressBlock=*/true, + ObjCSubsts); if (I == N - 1 && BlockProto.getTypePtr()->isVariadic()) Params += ", ..."; @@ -2537,11 +2559,12 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, } CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) { - return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo, - IncludeBriefComments); + return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator, + CCTUInfo, IncludeBriefComments); } /// \brief If possible, create a new code completion string for the given @@ -2553,6 +2576,7 @@ CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S, CodeCompletionString * CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, Preprocessor &PP, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) { @@ -2666,7 +2690,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, for (const auto *I : ND->specific_attrs<AnnotateAttr>()) Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation())); - AddResultTypeChunk(Ctx, Policy, ND, Result); + AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result); if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, @@ -2786,14 +2810,22 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, continue; std::string Arg; - - if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity) - Arg = FormatFunctionParameter(Policy, *P, true); + QualType ParamType = (*P)->getType(); + Optional<ArrayRef<QualType>> ObjCSubsts; + if (!CCContext.getBaseType().isNull()) + ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method); + + if (ParamType->isBlockPointerType() && !DeclaringEntity) + Arg = FormatFunctionParameter(Policy, *P, true, + /*SuppressBlock=*/false, + ObjCSubsts); else { - QualType Type = (*P)->getType(); + if (ObjCSubsts) + ParamType = ParamType.substObjCTypeArgs(Ctx, *ObjCSubsts, + ObjCSubstitutionContext::Parameter); Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(), - Type); - Arg += Type.getAsString(Policy) + ")"; + ParamType); + Arg += ParamType.getAsString(Policy) + ")"; if (IdentifierInfo *II = (*P)->getIdentifier()) if (DeclaringEntity || AllParametersAreInformative) Arg += II->getName(); @@ -2930,7 +2962,7 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( if (auto RC = S.getASTContext().getRawCommentForAnyRedecl( FDecl->getParamDecl(CurrentArg))) Result.addBriefComment(RC->getBriefText(S.getASTContext())); - AddResultTypeChunk(S.Context, Policy, FDecl, Result); + AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result); Result.AddTextChunk( Result.getAllocator().CopyString(FDecl->getNameAsString())); } else { @@ -3522,7 +3554,8 @@ static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) { return Container; } -static void AddObjCProperties(ObjCContainerDecl *Container, +static void AddObjCProperties(const CodeCompletionContext &CCContext, + ObjCContainerDecl *Container, bool AllowCategories, bool AllowNullaryMethods, DeclContext *CurContext, @@ -3549,7 +3582,8 @@ static void AddObjCProperties(ObjCContainerDecl *Container, if (AddedProperties.insert(Name).second) { CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); - AddResultTypeChunk(Context, Policy, M, Builder); + AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), + Builder); Builder.AddTypedTextChunk( Results.getAllocator().CopyString(Name->getName())); @@ -3564,32 +3598,32 @@ static void AddObjCProperties(ObjCContainerDecl *Container, // Add properties in referenced protocols. if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { for (auto *P : Protocol->protocols()) - AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext, - AddedProperties, Results); + AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, + CurContext, AddedProperties, Results); } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){ if (AllowCategories) { // Look through categories. for (auto *Cat : IFace->known_categories()) - AddObjCProperties(Cat, AllowCategories, AllowNullaryMethods, CurContext, - AddedProperties, Results); + AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods, + CurContext, AddedProperties, Results); } // Look through protocols. for (auto *I : IFace->all_referenced_protocols()) - AddObjCProperties(I, AllowCategories, AllowNullaryMethods, CurContext, - AddedProperties, Results); + AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods, + CurContext, AddedProperties, Results); // Look in the superclass. if (IFace->getSuperClass()) - AddObjCProperties(IFace->getSuperClass(), AllowCategories, + AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results); } else if (const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { // Look through protocols. for (auto *P : Category->protocols()) - AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext, - AddedProperties, Results); + AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, + CurContext, AddedProperties, Results); } } @@ -3631,11 +3665,11 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, contextKind = CodeCompletionContext::CCC_DotMemberAccess; } } - + + CodeCompletionContext CCContext(contextKind, BaseType); ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext(contextKind, - BaseType), + CCContext, &ResultBuilder::IsMember); Results.EnterNewScope(); if (const RecordType *Record = BaseType->getAs<RecordType>()) { @@ -3675,14 +3709,14 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, const ObjCObjectPointerType *ObjCPtr = BaseType->getAsObjCInterfacePointerType(); assert(ObjCPtr && "Non-NULL pointer guaranteed above!"); - AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, + AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true, /*AllowNullaryMethods=*/true, CurContext, AddedProperties, Results); // Add properties from the protocols in a qualified interface. for (auto *I : ObjCPtr->quals()) - AddObjCProperties(I, true, /*AllowNullaryMethods=*/true, CurContext, - AddedProperties, Results); + AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true, + CurContext, AddedProperties, Results); } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || (!IsArrow && BaseType->isObjCObjectType())) { // Objective-C instance variable access. @@ -5336,7 +5370,8 @@ static ObjCMethodDecl *AddSuperSendCompletion( Results.getCodeCompletionTUInfo()); // Give this completion a return type. - AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, + AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, + Results.getCompletionContext().getBaseType(), Builder); // If we need the "super" keyword, add it (plus some spacing). @@ -6090,9 +6125,10 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, } void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { + CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other); ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_Other); + CCContext); // Figure out where this @synthesize lives. ObjCContainerDecl *Container @@ -6113,11 +6149,12 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { Results.EnterNewScope(); if (ObjCImplementationDecl *ClassImpl = dyn_cast<ObjCImplementationDecl>(Container)) - AddObjCProperties(ClassImpl->getClassInterface(), false, + AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false, /*AllowNullaryMethods=*/false, CurContext, AddedProperties, Results); else - AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(), + AddObjCProperties(CCContext, + cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(), false, /*AllowNullaryMethods=*/false, CurContext, AddedProperties, Results); Results.ExitScope(); diff --git a/clang/test/Index/complete-parameterized-classes.m b/clang/test/Index/complete-parameterized-classes.m new file mode 100644 index 00000000000..2d60eaca95f --- /dev/null +++ b/clang/test/Index/complete-parameterized-classes.m @@ -0,0 +1,53 @@ +@protocol NSObject +@end + +@interface NSObject +@end + +@interface Test<T : id, U : NSObject *> : NSObject +{ +@public + U myVar; +} +-(U)getit:(T)val; +-(void)apply:(void(^)(T, U))block; + +@property (strong) T prop; +@end + +@interface MyClsA : NSObject +@end +@interface MyClsB : NSObject +@end + +void test1(Test<MyClsA*, MyClsB*> *obj) { + [obj ]; + obj.; + obj->; +} + +void test2(Test *obj) { + [obj ]; + obj.; + obj->; +} + +// RUN: c-index-test -code-completion-at=%s:24:8 %s | FileCheck -check-prefix=CHECK-CC0 %s +// CHECK-CC0: ObjCInstanceMethodDecl:{ResultType void}{TypedText apply:}{Placeholder ^(MyClsA *, MyClsB *)block} (35) +// CHECK-CC0: ObjCInstanceMethodDecl:{ResultType MyClsB *}{TypedText getit:}{Placeholder (MyClsA *)} (35) + +// RUN: c-index-test -code-completion-at=%s:25:7 %s | FileCheck -check-prefix=CHECK-CC1 %s +// CHECK-CC1: ObjCPropertyDecl:{ResultType MyClsA *}{TypedText prop} (35) + +// RUN: c-index-test -code-completion-at=%s:26:8 %s | FileCheck -check-prefix=CHECK-CC2 %s +// CHECK-CC2: ObjCIvarDecl:{ResultType MyClsB *}{TypedText myVar} (35) + +// RUN: c-index-test -code-completion-at=%s:30:8 %s | FileCheck -check-prefix=CHECK-CC3 %s +// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType void}{TypedText apply:}{Placeholder ^(id, NSObject *)block} (35) +// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType __kindof NSObject *}{TypedText getit:}{Placeholder (id)} (35) + +// RUN: c-index-test -code-completion-at=%s:31:7 %s | FileCheck -check-prefix=CHECK-CC4 %s +// CHECK-CC4: ObjCPropertyDecl:{ResultType id}{TypedText prop} (35) + +// RUN: c-index-test -code-completion-at=%s:32:8 %s | FileCheck -check-prefix=CHECK-CC5 %s +// CHECK-CC5: ObjCIvarDecl:{ResultType __kindof NSObject *}{TypedText myVar} (35) diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp index a7b8e292047..9609a693abd 100644 --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -542,7 +542,7 @@ namespace { StoredResults.reserve(StoredResults.size() + NumResults); for (unsigned I = 0; I != NumResults; ++I) { CodeCompletionString *StoredCompletion - = Results[I].CreateCodeCompletionString(S, getAllocator(), + = Results[I].CreateCodeCompletionString(S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index fe9ba4eac1b..099edcf14fe 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -1298,6 +1298,7 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { CodeCompletionString *String = Result.CreateCodeCompletionString(unit->getASTContext(), unit->getPreprocessor(), + CodeCompletionContext::CCC_Other, unit->getCodeCompletionTUInfo().getAllocator(), unit->getCodeCompletionTUInfo(), true); @@ -1308,10 +1309,13 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { const IdentifierInfo *MacroInfo = definition->getName(); ASTUnit *unit = getCursorASTUnit(cursor); CodeCompletionResult Result(MacroInfo); - CodeCompletionString *String = Result.CreateCodeCompletionString( - unit->getASTContext(), unit->getPreprocessor(), - unit->getCodeCompletionTUInfo().getAllocator(), - unit->getCodeCompletionTUInfo(), false); + CodeCompletionString *String + = Result.CreateCodeCompletionString(unit->getASTContext(), + unit->getPreprocessor(), + CodeCompletionContext::CCC_Other, + unit->getCodeCompletionTUInfo().getAllocator(), + unit->getCodeCompletionTUInfo(), + false); return String; } return nullptr; |