Index: cfe/trunk/lib/Sema/SemaCodeComplete.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -2162,6 +2162,53 @@ return Result; } +/// \brief Tries to find the most appropriate type location for an Objective-C +/// block placeholder. +/// +/// This function ignores things like typedefs and qualifiers in order to +/// present the most relevant and accurate block placeholders in code completion +/// results. +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 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