From: Mike Stump Date: Fri, 20 Mar 2009 21:53:12 +0000 (+0000) Subject: Fix codegen for support for super inside block literal expressions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6cc88f78fd36d3511b89412b193494b3e423cbff;p=clang Fix codegen for support for super inside block literal expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67406 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index fcda90794e..c233ff3854 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -13,6 +13,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "clang/AST/DeclObjC.h" #include "llvm/Module.h" #include "llvm/Target/TargetData.h" @@ -155,7 +156,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { uint64_t subBlockSize, subBlockAlign; llvm::SmallVector subBlockDeclRefDecls; llvm::Function *Fn - = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap, + = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl, LocalDeclMap, subBlockSize, subBlockAlign, subBlockDeclRefDecls, @@ -525,6 +526,19 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { return V; } +void CodeGenFunction::BlockForwardSelf() { + const ObjCMethodDecl *OMD = cast(CurFuncDecl); + ImplicitParamDecl *SelfDecl = OMD->getSelfDecl(); + llvm::Value *&DMEntry = LocalDeclMap[SelfDecl]; + if (DMEntry) + return; + // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care + BlockDeclRefExpr *BDRE = new (getContext()) + BlockDeclRefExpr(SelfDecl, + SelfDecl->getType(), SourceLocation(), false); + DMEntry = GetAddrOfBlockDecl(BDRE); +} + llvm::Constant * BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { // Generate the block descriptor. @@ -561,7 +575,7 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { bool subBlockHasCopyDispose = false; llvm::DenseMap LocalDeclMap; llvm::Function *Fn - = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap, + = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap, subBlockSize, subBlockAlign, subBlockDeclRefDecls, @@ -605,6 +619,7 @@ llvm::Value *CodeGenFunction::LoadBlockStruct() { llvm::Function * CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, const BlockInfo& Info, + const Decl *OuterFuncDecl, llvm::DenseMap ldm, uint64_t &Size, uint64_t &Align, @@ -657,6 +672,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, StartFunction(BD, FTy->getResultType(), Fn, Args, BExpr->getBody()->getLocEnd()); + CurFuncDecl = OuterFuncDecl; EmitStmt(BExpr->getBody()); FinishFunction(cast(BExpr->getBody())->getRBracLoc()); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 6646365b45..eb2fe4f502 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -89,10 +89,6 @@ CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D, else if (isa(CurFuncDecl)) ContextName = std::string(CurFn->getNameStart(), CurFn->getNameStart() + CurFn->getNameLen()); - else if (isa(CurFuncDecl)) - // FIXME: We want to traverse up and pick a name based upon where we came - // from. - ContextName = "block"; else assert(0 && "Unknown context for block var decl"); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 7f5262df1d..acc07c740a 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -304,6 +304,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, llvm::Value *CodeGenFunction::LoadObjCSelf() { const ObjCMethodDecl *OMD = cast(CurFuncDecl); + // See if we need to lazily forward self inside a block literal. + BlockForwardSelf(); return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index a54e187658..9771c83d84 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -72,7 +72,8 @@ public: typedef std::pair ComplexPairTy; CGBuilderTy Builder; - // Holds the Decl for the current function or method + /// CurFuncDecl - Holds the Decl for the current function or method. This + /// excludes BlockDecls. const Decl *CurFuncDecl; const CGFunctionInfo *CurFnInfo; QualType FnRetTy; @@ -272,11 +273,13 @@ public: llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr, const BlockInfo& Info, + const Decl *OuterFuncDecl, llvm::DenseMap ldm, uint64_t &Size, uint64_t &Align, llvm::SmallVector &subBlockDeclRefDecls, bool &subBlockHasCopyDispose); + void BlockForwardSelf(); llvm::Value *LoadBlockStruct(); llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E); diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m index c32419e424..e9ca2238ba 100644 --- a/test/CodeGenObjC/blocks.m +++ b/test/CodeGenObjC/blocks.m @@ -15,3 +15,13 @@ void foo(T *P) { [P foo: 0]; } +@interface A +-(void) im0; +@end + +@interface B : A @end +@implementation B +-(void) im1 { + ^(void) { [super im0]; }(); +} +@end