Fix codegen for support for super inside block literal expressions.

llvm-svn: 67406
This commit is contained in:
Mike Stump 2009-03-20 21:53:12 +00:00
parent dfd72c2b44
commit 692c6e3729
5 changed files with 34 additions and 7 deletions

View File

@ -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<const Expr *, 8> 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<ObjCMethodDecl>(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<const Decl*, llvm::Value*> 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<const Decl*, llvm::Value*> 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<CompoundStmt>(BExpr->getBody())->getRBracLoc());

View File

@ -89,10 +89,6 @@ CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D,
else if (isa<ObjCMethodDecl>(CurFuncDecl))
ContextName = std::string(CurFn->getNameStart(),
CurFn->getNameStart() + CurFn->getNameLen());
else if (isa<BlockDecl>(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");

View File

@ -304,6 +304,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
llvm::Value *CodeGenFunction::LoadObjCSelf() {
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
// See if we need to lazily forward self inside a block literal.
BlockForwardSelf();
return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
}

View File

@ -72,7 +72,8 @@ public:
typedef std::pair<llvm::Value *, llvm::Value *> 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<const Decl*, llvm::Value*> ldm,
uint64_t &Size, uint64_t &Align,
llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
bool &subBlockHasCopyDispose);
void BlockForwardSelf();
llvm::Value *LoadBlockStruct();
llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);

View File

@ -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