Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -2162,6 +2162,53 @@ return Result; } +static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo, + FunctionTypeLoc &Block, + FunctionProtoTypeLoc &BlockProto, + bool SuppressBlock = false) { + if (!TSInfo) + return; + TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); + while (true) { + // Look through typedefs. + if (!SuppressBlock) { + if (TypedefTypeLoc TypedefTL = TL.getAs()) { + if (TypeSourceInfo *InnerTSInfo = + TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) { + TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); + continue; + } + } + + // Look through qualified types + if (QualifiedTypeLoc QualifiedTL = TL.getAs()) { + TL = QualifiedTL.getUnqualifiedLoc(); + continue; + } + + if (AttributedTypeLoc AttrTL = TL.getAs()) { + TL = AttrTL.getModifiedLoc(); + continue; + } + } + + // Try to get the function prototype behind the block pointer type, + // then we're done. + if (BlockPointerTypeLoc BlockPtr = TL.getAs()) { + TL = BlockPtr.getPointeeLoc().IgnoreParens(); + Block = TL.getAs(); + BlockProto = TL.getAs(); + } + break; + } +} + +static std::string +formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, + FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, + bool SuppressBlock = false, + Optional> ObjCSubsts = None); + static std::string FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, bool SuppressName = false, @@ -2192,47 +2239,13 @@ } return Result; } - + // The argument for a block pointer parameter is a block literal with // the appropriate type. FunctionTypeLoc Block; FunctionProtoTypeLoc BlockProto; - TypeLoc TL; - if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) { - TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); - while (true) { - // Look through typedefs. - if (!SuppressBlock) { - if (TypedefTypeLoc TypedefTL = TL.getAs()) { - if (TypeSourceInfo *InnerTSInfo = - TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) { - TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); - continue; - } - } - - // Look through qualified types - if (QualifiedTypeLoc QualifiedTL = TL.getAs()) { - TL = QualifiedTL.getUnqualifiedLoc(); - continue; - } - - if (AttributedTypeLoc AttrTL = TL.getAs()) { - TL = AttrTL.getModifiedLoc(); - continue; - } - } - - // Try to get the function prototype behind the block pointer type, - // then we're done. - if (BlockPointerTypeLoc BlockPtr = TL.getAs()) { - TL = BlockPtr.getPointeeLoc().IgnoreParens(); - Block = TL.getAs(); - BlockProto = TL.getAs(); - } - break; - } - } + findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto, + SuppressBlock); if (!Block) { // We were unable to find a FunctionProtoTypeLoc with parameter names @@ -2258,12 +2271,21 @@ // We have the function prototype behind the block pointer type, as it was // written in the source. + return formatBlockPlaceholder(Policy, Param, Block, BlockProto, SuppressBlock, + ObjCSubsts); +} + +static std::string +formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, + FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, + bool SuppressBlock, + Optional> ObjCSubsts) { std::string Result; QualType ResultType = Block.getTypePtr()->getReturnType(); if (ObjCSubsts) - ResultType = ResultType.substObjCTypeArgs(Param->getASTContext(), - *ObjCSubsts, - ObjCSubstitutionContext::Result); + ResultType = + ResultType.substObjCTypeArgs(BlockDecl->getASTContext(), *ObjCSubsts, + ObjCSubstitutionContext::Result); if (!ResultType->isVoidType() || SuppressBlock) ResultType.getAsStringInternal(Result, Policy); @@ -2281,31 +2303,30 @@ Params += ", "; Params += FormatFunctionParameter(Policy, Block.getParam(I), /*SuppressName=*/false, - /*SuppressBlock=*/true, - ObjCSubsts); + /*SuppressBlock=*/true, ObjCSubsts); if (I == N - 1 && BlockProto.getTypePtr()->isVariadic()) Params += ", ..."; } Params += ")"; } - + if (SuppressBlock) { // Format as a parameter. Result = Result + " (^"; - if (Param->getIdentifier()) - Result += Param->getIdentifier()->getName(); + if (BlockDecl->getIdentifier()) + Result += BlockDecl->getIdentifier()->getName(); Result += ")"; Result += Params; } else { // Format as a block literal argument. Result = '^' + Result; Result += Params; - - if (Param->getIdentifier()) - Result += Param->getIdentifier()->getName(); + + if (BlockDecl->getIdentifier()) + Result += BlockDecl->getIdentifier()->getName(); } - + return Result; }