diff options
author | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
commit | f27e5a09a0d815b8a4814152954ff87dadfdefc0 (patch) | |
tree | ce7d964cbb5e39695b71481698f10cb099c23d4a /lib/CodeGen/CGBlocks.h | |
download | FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.zip FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.tar.gz |
Import Clang, at r72732.
Diffstat (limited to 'lib/CodeGen/CGBlocks.h')
-rw-r--r-- | lib/CodeGen/CGBlocks.h | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h new file mode 100644 index 0000000..56d3a2d --- /dev/null +++ b/lib/CodeGen/CGBlocks.h @@ -0,0 +1,223 @@ +//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is the internal state used for llvm translation for block literals. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CODEGEN_CGBLOCKS_H +#define CLANG_CODEGEN_CGBLOCKS_H + +#include "CodeGenTypes.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" + +#include <vector> +#include <map> + +#include "CGBuilder.h" +#include "CGCall.h" +#include "CGValue.h" + +namespace llvm { + class Module; + class Constant; + class Function; + class GlobalValue; + class TargetData; + class FunctionType; + class Value; +} + +namespace clang { + +namespace CodeGen { +class CodeGenModule; + +class BlockBase { +public: + enum { + BLOCK_NEEDS_FREE = (1 << 24), + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CXX_OBJ = (1 << 26), + BLOCK_IS_GC = (1 << 27), + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_HAS_DESCRIPTOR = (1 << 29) + }; +}; + +class BlockModule : public BlockBase { + ASTContext &Context; + llvm::Module &TheModule; + const llvm::TargetData &TheTargetData; + CodeGenTypes &Types; + CodeGenModule &CGM; + + ASTContext &getContext() const { return Context; } + llvm::Module &getModule() const { return TheModule; } + CodeGenTypes &getTypes() { return Types; } + const llvm::TargetData &getTargetData() const { return TheTargetData; } +public: + llvm::Constant *getNSConcreteGlobalBlock(); + llvm::Constant *getNSConcreteStackBlock(); + int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; } + const llvm::Type *getBlockDescriptorType(); + + const llvm::Type *getGenericBlockLiteralType(); + const llvm::Type *getGenericExtendedBlockLiteralType(); + + llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *); + + /// NSConcreteGlobalBlock - Cached reference to the class pointer for global + /// blocks. + llvm::Constant *NSConcreteGlobalBlock; + + /// NSConcreteStackBlock - Cached reference to the class poinnter for stack + /// blocks. + llvm::Constant *NSConcreteStackBlock; + + const llvm::Type *BlockDescriptorType; + const llvm::Type *GenericBlockLiteralType; + const llvm::Type *GenericExtendedBlockLiteralType; + struct { + int GlobalUniqueCount; + } Block; + + llvm::Value *BlockObjectAssign; + llvm::Value *BlockObjectDispose; + const llvm::Type *PtrToInt8Ty; + + BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD, + CodeGenTypes &T, CodeGenModule &CodeGen) + : Context(C), TheModule(M), TheTargetData(TD), Types(T), + CGM(CodeGen), + NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0), + GenericBlockLiteralType(0), GenericExtendedBlockLiteralType(0), + BlockObjectAssign(0), BlockObjectDispose(0) { + Block.GlobalUniqueCount = 0; + PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + } +}; + +class BlockFunction : public BlockBase { + CodeGenModule &CGM; + CodeGenFunction &CGF; + ASTContext &getContext() const; + +public: + const llvm::Type *PtrToInt8Ty; + struct HelperInfo { + int index; + int flag; + bool RequiresCopying; + }; + + enum { + BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), + block, ... */ + BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ + BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block + variable */ + BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy + helpers */ + BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose + support routines */ + }; + + /// BlockInfo - Information to generate a block literal. + struct BlockInfo { + /// BlockLiteralTy - The type of the block literal. + const llvm::Type *BlockLiteralTy; + + /// Name - the name of the function this block was created for, if any. + const char *Name; + + /// ByCopyDeclRefs - Variables from parent scopes that have been imported + /// into this block. + llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs; + + // ByRefDeclRefs - __block variables from parent scopes that have been + // imported into this block. + llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs; + + BlockInfo(const llvm::Type *blt, const char *n) + : BlockLiteralTy(blt), Name(n) { + // Skip asm prefix, if any. + if (Name && Name[0] == '\01') + ++Name; + } + }; + + CGBuilderTy &Builder; + + BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B); + + /// BlockOffset - The offset in bytes for the next allocation of an + /// imported block variable. + uint64_t BlockOffset; + /// BlockAlign - Maximal alignment needed for the Block expressed in bytes. + uint64_t BlockAlign; + + /// getBlockOffset - Allocate an offset for the ValueDecl from a + /// BlockDeclRefExpr in a block literal (BlockExpr). + uint64_t getBlockOffset(const BlockDeclRefExpr *E); + + /// BlockHasCopyDispose - True iff the block uses copy/dispose. + bool BlockHasCopyDispose; + + /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order + /// in a block literal. Decls without names are used for padding. + llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls; + + /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs. + std::map<const Decl*, uint64_t> BlockDecls; + + ImplicitParamDecl *BlockStructDecl; + ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } + + llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *, + std::vector<HelperInfo> *); + llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *, + std::vector<HelperInfo> *); + + llvm::Constant *BuildCopyHelper(const llvm::StructType *, + std::vector<HelperInfo> *); + llvm::Constant *BuildDestroyHelper(const llvm::StructType *, + std::vector<HelperInfo> *); + + llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag); + llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int); + + llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag); + llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag); + + llvm::Value *getBlockObjectAssign(); + llvm::Value *getBlockObjectDispose(); + void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF); + + bool BlockRequiresCopying(QualType Ty) { + if (Ty->isBlockPointerType()) + return true; + if (getContext().isObjCNSObjectType(Ty)) + return true; + if (getContext().isObjCObjectPointerType(Ty)) + return true; + return false; + } +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif |