forked from OSchip/llvm-project
Some early work for providing block layout info.
for objective-c/c++ blocks (NeXt runtime). llvm-svn: 110213
This commit is contained in:
parent
a3ed071166
commit
c05349e53a
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue