forked from OSchip/llvm-project
Fix codegen for support for super inside block literal expressions.
llvm-svn: 67406
This commit is contained in:
parent
dfd72c2b44
commit
692c6e3729
|
@ -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());
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue