diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 94ba269aecb4..a2ab883432e0 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -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 DeclRefs; - - /// InnerBlocks - This block and the blocks it encloses. - llvm::SmallPtrSet 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 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 *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")); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index a9519ed2bb08..fdee1dee135c 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -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 &) { + return NULLPtr; + } }; } // end anonymous namespace diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 4db7ec5f9ffa..b30b44ba87e0 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -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 &); + }; 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 &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 diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index bf172f9b1e3b..584760f6f343 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -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 &) = 0; + }; /// Creates an instance of an Objective-C runtime class. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 787457091770..b9abe1405218 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -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 *); @@ -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 DeclRefs; + + /// InnerBlocks - This block and the blocks it encloses. + llvm::SmallPtrSet 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 BlockLayout; + + CGBlockInfo(const char *Name); +}; + } // end namespace CodeGen } // end namespace clang