diff options
author | Mike Stump <mrs@apple.com> | 2009-10-21 03:49:08 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-10-21 03:49:08 +0000 |
commit | ea26cb522e88fc86b0d1cae61dcefcfe4cc20231 (patch) | |
tree | a9afb8e3511ba7a61e2caf474ebe54b26c51f7bc /lib/CodeGen/CGBlocks.cpp | |
parent | 3c50bfe3d9d4bda4183a541d97ec5b32bbae7aab (diff) |
Prep work to always preallocate BlockDeclRefExprs so that we can
generate the debug information for the first parameter to the block
invoke functions. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84737 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 118 |
1 files changed, 75 insertions, 43 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 8e020c80ea..692a7a6bc5 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -80,22 +80,48 @@ static void CollectBlockDeclRefInfo(const Stmt *S, if (*I) CollectBlockDeclRefInfo(*I, Info); + // We want to ensure we walk down into block literals so we can find + // all nested BlockDeclRefExprs. + if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) + CollectBlockDeclRefInfo(BE->getBody(), Info); + if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) { // FIXME: Handle enums. if (isa<FunctionDecl>(DE->getDecl())) return; - if (DE->isByRef()) - Info.ByRefDeclRefs.push_back(DE); - else - Info.ByCopyDeclRefs.push_back(DE); + Info.DeclRefs.push_back(DE); } } /// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be /// declared as a global variable instead of on the stack. static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) { - return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty(); + return Info.DeclRefs.empty(); +} + +/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to +/// ensure we can generate the debug information for the parameter for the block +/// invoke function. +static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info, + CodeGenFunction *CGF) { + // Always allocate self, as it is often handy in the debugger, even if there + // is no codegen in the block that uses it. This is also useful to always do + // this as if we didn't, we'd have to figure out all code that uses a self + // pointer, including implicit uses. + if (const ObjCMethodDecl *OMD + = dyn_cast_or_null<ObjCMethodDecl>(CGF->CurFuncDecl)) { + ImplicitParamDecl *SelfDecl = OMD->getSelfDecl(); + BlockDeclRefExpr *BDRE = new (CGF->getContext()) + BlockDeclRefExpr(SelfDecl, + SelfDecl->getType(), SourceLocation(), false); + CGF->AllocateBlockDecl(BDRE); + } + + // FIXME: Also always forward the this pointer in C++ as well. + + for (size_t i = 0; i < Info.DeclRefs.size(); ++i) + CGF->AllocateBlockDecl(Info.DeclRefs[i]); } // FIXME: Push most into CGM, passing down a few bits, like current function @@ -159,7 +185,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (subBlockDeclRefDecls.size() == 0) { // __descriptor - Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0); + Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, + 0, 0); // Optimize to being a global block. Elts[0] = CGM.getNSConcreteGlobalBlock(); @@ -269,7 +296,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { llvm::Value *BlockLiteral = LoadBlockStruct(); Loc = Builder.CreateGEP(BlockLiteral, - llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), + llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), offset), "block.literal"); Ty = llvm::PointerType::get(Ty, 0); @@ -447,24 +474,32 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) { return EmitCall(FnInfo, Func, Args); } -llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { +uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { const ValueDecl *VD = E->getDecl(); - uint64_t &offset = BlockDecls[VD]; - // See if we have already allocated an offset for this variable. - if (offset == 0) { - // Don't run the expensive check, unless we have to. - if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType())) - BlockHasCopyDispose = true; - // if not, allocate one now. - offset = getBlockOffset(E); - } + if (offset) + return offset; + + // Don't run the expensive check, unless we have to. + if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType())) + BlockHasCopyDispose = true; + + // if not, allocate one now. + offset = getBlockOffset(E); + + return offset; +} + +llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { + const ValueDecl *VD = E->getDecl(); + uint64_t offset = AllocateBlockDecl(E); + llvm::Value *BlockLiteral = LoadBlockStruct(); llvm::Value *V = Builder.CreateGEP(BlockLiteral, - llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), + llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), offset), "block.literal"); if (E->isByRef()) { @@ -633,12 +668,19 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, FunctionArgList Args; + CurFuncDecl = OuterFuncDecl; + const BlockDecl *BD = BExpr->getBlockDecl(); - IdentifierInfo *II - = &CGM.getContext().Idents.get(".block_descriptor"); + IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); + + // Allocate all BlockDeclRefDecls, so we can calculate the the + // right ParmTy below. + // FIXME: Resolve testsuite problems, then enable. + if (0) + AllocateAllBlockDeclRefs(Info, this); - QualType ParmTy = getContext().getBlockParmType(); + QualType ParmTy = getContext().getBlockParmType(BlockDeclRefDecls); // FIXME: This leaks ImplicitParamDecl *SelfDecl = ImplicitParamDecl::Create(getContext(), 0, @@ -708,22 +750,6 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc()); - // And now finish off the type for the parameter, since now we know - // BlockDeclRefDecls is complete. - getContext().completeBlockParmType(ParmTy, BlockDeclRefDecls); - -#define REV2 -#ifdef REV2 - TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl(); - CGM.UpdateCompletedType(TD); -#else - TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl(); - TagDecl::redecl_iterator rdi = TD->redecls_begin(); - ++rdi; - TD = *rdi; - CGM.UpdateCompletedType(TD); -#endif - // The runtime needs a minimum alignment of a void *. uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign); @@ -781,11 +807,13 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, FunctionArgList Args; // FIXME: This leaks ImplicitParamDecl *Dst = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Dst, Dst->getType())); ImplicitParamDecl *Src = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Src, Src->getType())); @@ -866,7 +894,8 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, FunctionArgList Args; // FIXME: This leaks ImplicitParamDecl *Src = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Src, Src->getType())); @@ -945,13 +974,15 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) { FunctionArgList Args; // FIXME: This leaks ImplicitParamDecl *Dst = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Dst, Dst->getType())); // FIXME: This leaks ImplicitParamDecl *Src = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Src, Src->getType())); @@ -1014,7 +1045,8 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, FunctionArgList Args; // FIXME: This leaks ImplicitParamDecl *Src = - ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + ImplicitParamDecl::Create(getContext(), 0, + SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); Args.push_back(std::make_pair(Src, Src->getType())); |