From: Alex Lorenz Date: Tue, 18 Oct 2016 10:35:27 +0000 (+0000) Subject: [CodeCompletion][NFC] Extract a function that looks for block decl type locs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0cbc713c96f0a22049d8b84fdffb6135854f71dd;p=clang [CodeCompletion][NFC] Extract a function that looks for block decl type locs. This commit extracts a new function named `findTypeLocationForBlockDecl` from the function `FormatFunctionParameter` so that it can be reused in follow-up commits that improve code completion for block property setters. Differential Revision: https://reviews.llvm.org/D25519 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284467 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d235479e94..8b89861577 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2162,6 +2162,53 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals, 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 @@ static std::string FormatFunctionParameter(const PrintingPolicy &Policy, } 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