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 /clang/lib/Sema/SemaCodeComplete.cpp | |
| 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
Diffstat (limited to 'clang/lib/Sema/SemaCodeComplete.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 113 |
1 files changed, 75 insertions, 38 deletions
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(); |

