Some early work for providing block layout info.

for objective-c/c++ blocks (NeXt runtime).

llvm-svn: 110213
This commit is contained in:
Fariborz Jahanian 2010-08-04 16:57:49 +00:00
parent a3ed071166
commit c05349e53a
5 changed files with 57 additions and 40 deletions

View File

@ -24,36 +24,6 @@
using namespace clang;
using namespace CodeGen;
/// CGBlockInfo - Information to generate a block literal.
class clang::CodeGen::CGBlockInfo {
public:
/// Name - The name of the block, kindof.
const char *Name;
/// DeclRefs - Variables from parent scopes that have been
/// imported into this block.
llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
/// InnerBlocks - This block and the blocks it encloses.
llvm::SmallPtrSet<const DeclContext *, 4> InnerBlocks;
/// CXXThisRef - Non-null if 'this' was required somewhere, in
/// which case this is that expression.
const CXXThisExpr *CXXThisRef;
/// NeedsObjCSelf - True if something in this block has an implicit
/// reference to 'self'.
bool NeedsObjCSelf;
/// These are initialized by GenerateBlockFunction.
bool BlockHasCopyDispose;
CharUnits BlockSize;
CharUnits BlockAlign;
llvm::SmallVector<const Expr*, 8> BlockLayout;
CGBlockInfo(const char *Name);
};
CGBlockInfo::CGBlockInfo(const char *N)
: Name(N), CXXThisRef(0), NeedsObjCSelf(false) {
@ -64,9 +34,11 @@ CGBlockInfo::CGBlockInfo(const char *N)
llvm::Constant *CodeGenFunction::
BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
BuildDescriptorBlockDecl(const BlockExpr *BE, const CGBlockInfo &Info,
const llvm::StructType* Ty,
std::vector<HelperInfo> *NoteForHelper) {
bool BlockHasCopyDispose = Info.BlockHasCopyDispose;
CharUnits Size = Info.BlockSize;
const llvm::Type *UnsignedLongTy
= CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
llvm::Constant *C;
@ -100,7 +72,11 @@ BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnit
CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty));
// Layout.
C = llvm::ConstantInt::get(UnsignedLongTy, 0);
if (CGM.getContext().getLangOptions().ObjC1)
C = CGM.getObjCRuntime().GCBlockLayout(*this, Info.DeclRefs);
else
C = llvm::Constant::getNullValue(PtrToInt8Ty);
Elts.push_back(C);
C = llvm::ConstantStruct::get(VMContext, Elts, false);
@ -257,8 +233,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
if (Info.BlockLayout.empty()) {
// __descriptor
Elts[4] = BuildDescriptorBlockDecl(BE, Info.BlockHasCopyDispose,
Info.BlockSize, 0, 0);
Elts[4] = BuildDescriptorBlockDecl(BE, Info, 0, 0);
// Optimize to being a global block.
Elts[0] = CGM.getNSConcreteGlobalBlock();
@ -412,9 +387,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
NoteForHelper.resize(NumHelpers);
// __descriptor
llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
Info.BlockHasCopyDispose,
Info.BlockSize, Ty,
llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE, Info, Ty,
&NoteForHelper);
Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));

View File

@ -212,6 +212,10 @@ public:
virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &) {
return NULLPtr;
}
};
} // end anonymous namespace

View File

@ -1033,6 +1033,9 @@ public:
/// forward references will be filled in with empty bodies if no
/// definition is seen. The return value has type ProtocolPtrTy.
virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &);
};
class CGObjCMac : public CGObjCCommonMac {
@ -1686,6 +1689,11 @@ CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
}
llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &BDRE) {
return llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
}
llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *PD) {
// FIXME: I don't understand why gcc generates this, or where it is

View File

@ -52,6 +52,7 @@ namespace CodeGen {
class Selector;
class ObjCIvarDecl;
class ObjCStringLiteral;
class BlockDeclRefExpr;
namespace CodeGen {
class CodeGenModule;
@ -218,6 +219,9 @@ public:
llvm::Value *DestPtr,
llvm::Value *SrcPtr,
llvm::Value *Size) = 0;
virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &) = 0;
};
/// Creates an instance of an Objective-C runtime class.

View File

@ -759,8 +759,7 @@ public:
llvm::Value *BuildBlockLiteralTmp(const BlockExpr *);
llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *,
bool BlockHasCopyDispose,
CharUnits Size,
const CGBlockInfo &Info,
const llvm::StructType *,
std::vector<HelperInfo> *);
@ -1677,7 +1676,36 @@ private:
void EmitDeclMetadata();
};
/// CGBlockInfo - Information to generate a block literal.
class CGBlockInfo {
public:
/// Name - The name of the block, kindof.
const char *Name;
/// DeclRefs - Variables from parent scopes that have been
/// imported into this block.
llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
/// InnerBlocks - This block and the blocks it encloses.
llvm::SmallPtrSet<const DeclContext *, 4> InnerBlocks;
/// CXXThisRef - Non-null if 'this' was required somewhere, in
/// which case this is that expression.
const CXXThisExpr *CXXThisRef;
/// NeedsObjCSelf - True if something in this block has an implicit
/// reference to 'self'.
bool NeedsObjCSelf;
/// These are initialized by GenerateBlockFunction.
bool BlockHasCopyDispose;
CharUnits BlockSize;
CharUnits BlockAlign;
llvm::SmallVector<const Expr*, 8> BlockLayout;
CGBlockInfo(const char *Name);
};
} // end namespace CodeGen
} // end namespace clang