1 //===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This is the internal state used for llvm translation for block literals.
12 //===----------------------------------------------------------------------===//
14 #ifndef CLANG_CODEGEN_CGBLOCKS_H
15 #define CLANG_CODEGEN_CGBLOCKS_H
17 #include "CodeGenTypes.h"
18 #include "clang/AST/Type.h"
19 #include "llvm/Module.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "clang/Basic/TargetInfo.h"
23 #include "clang/AST/Expr.h"
24 #include "clang/AST/ExprCXX.h"
25 #include "clang/AST/ExprObjC.h"
30 #include "CGBuilder.h"
53 BLOCK_NEEDS_FREE
= (1 << 24),
54 BLOCK_HAS_COPY_DISPOSE
= (1 << 25),
55 BLOCK_HAS_CXX_OBJ
= (1 << 26),
56 BLOCK_IS_GC
= (1 << 27),
57 BLOCK_IS_GLOBAL
= (1 << 28),
58 BLOCK_HAS_DESCRIPTOR
= (1 << 29)
62 class BlockModule
: public BlockBase
{
64 llvm::Module
&TheModule
;
65 const llvm::TargetData
&TheTargetData
;
68 llvm::LLVMContext
&VMContext
;
70 ASTContext
&getContext() const { return Context
; }
71 llvm::Module
&getModule() const { return TheModule
; }
72 CodeGenTypes
&getTypes() { return Types
; }
73 const llvm::TargetData
&getTargetData() const { return TheTargetData
; }
75 llvm::Constant
*getNSConcreteGlobalBlock();
76 llvm::Constant
*getNSConcreteStackBlock();
77 int getGlobalUniqueCount() { return ++Block
.GlobalUniqueCount
; }
78 const llvm::Type
*getBlockDescriptorType();
80 const llvm::Type
*getGenericBlockLiteralType();
81 const llvm::Type
*getGenericExtendedBlockLiteralType();
83 llvm::Constant
*GetAddrOfGlobalBlock(const BlockExpr
*BE
, const char *);
85 /// NSConcreteGlobalBlock - Cached reference to the class pointer for global
87 llvm::Constant
*NSConcreteGlobalBlock
;
89 /// NSConcreteStackBlock - Cached reference to the class poinnter for stack
91 llvm::Constant
*NSConcreteStackBlock
;
93 const llvm::Type
*BlockDescriptorType
;
94 const llvm::Type
*GenericBlockLiteralType
;
95 const llvm::Type
*GenericExtendedBlockLiteralType
;
97 int GlobalUniqueCount
;
100 llvm::Value
*BlockObjectAssign
;
101 llvm::Value
*BlockObjectDispose
;
102 const llvm::Type
*PtrToInt8Ty
;
104 std::map
<uint64_t, llvm::Constant
*> AssignCache
;
105 std::map
<uint64_t, llvm::Constant
*> DestroyCache
;
107 BlockModule(ASTContext
&C
, llvm::Module
&M
, const llvm::TargetData
&TD
,
108 CodeGenTypes
&T
, CodeGenModule
&CodeGen
)
109 : Context(C
), TheModule(M
), TheTargetData(TD
), Types(T
),
110 CGM(CodeGen
), VMContext(M
.getContext()),
111 NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
112 GenericBlockLiteralType(0), GenericExtendedBlockLiteralType(0),
113 BlockObjectAssign(0), BlockObjectDispose(0) {
114 Block
.GlobalUniqueCount
= 0;
115 PtrToInt8Ty
= llvm::PointerType::getUnqual(llvm::Type::Int8Ty
);
119 class BlockFunction
: public BlockBase
{
121 CodeGenFunction
&CGF
;
122 ASTContext
&getContext() const;
125 llvm::LLVMContext
&VMContext
;
128 const llvm::Type
*PtrToInt8Ty
;
132 bool RequiresCopying
;
136 BLOCK_FIELD_IS_OBJECT
= 3, /* id, NSObject, __attribute__((NSObject)),
138 BLOCK_FIELD_IS_BLOCK
= 7, /* a block variable */
139 BLOCK_FIELD_IS_BYREF
= 8, /* the on stack structure holding the __block
141 BLOCK_FIELD_IS_WEAK
= 16, /* declared __weak, only used in byref copy
143 BLOCK_BYREF_CALLER
= 128, /* called from __block (byref) copy/dispose
145 BLOCK_BYREF_CURRENT_MAX
= 256
148 /// BlockInfo - Information to generate a block literal.
150 /// BlockLiteralTy - The type of the block literal.
151 const llvm::Type
*BlockLiteralTy
;
153 /// Name - the name of the function this block was created for, if any.
156 /// ByCopyDeclRefs - Variables from parent scopes that have been imported
158 llvm::SmallVector
<const BlockDeclRefExpr
*, 8> ByCopyDeclRefs
;
160 // ByRefDeclRefs - __block variables from parent scopes that have been
161 // imported into this block.
162 llvm::SmallVector
<const BlockDeclRefExpr
*, 8> ByRefDeclRefs
;
164 BlockInfo(const llvm::Type
*blt
, const char *n
)
165 : BlockLiteralTy(blt
), Name(n
) {
166 // Skip asm prefix, if any.
167 if (Name
&& Name
[0] == '\01')
172 CGBuilderTy
&Builder
;
174 BlockFunction(CodeGenModule
&cgm
, CodeGenFunction
&cgf
, CGBuilderTy
&B
);
176 /// BlockOffset - The offset in bytes for the next allocation of an
177 /// imported block variable.
178 uint64_t BlockOffset
;
179 /// BlockAlign - Maximal alignment needed for the Block expressed in bytes.
182 /// getBlockOffset - Allocate an offset for the ValueDecl from a
183 /// BlockDeclRefExpr in a block literal (BlockExpr).
184 uint64_t getBlockOffset(const BlockDeclRefExpr
*E
);
186 /// BlockHasCopyDispose - True iff the block uses copy/dispose.
187 bool BlockHasCopyDispose
;
189 /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
190 /// in a block literal. Decls without names are used for padding.
191 llvm::SmallVector
<const Expr
*, 8> BlockDeclRefDecls
;
193 /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
194 std::map
<const Decl
*, uint64_t> BlockDecls
;
196 ImplicitParamDecl
*BlockStructDecl
;
197 ImplicitParamDecl
*getBlockStructDecl() { return BlockStructDecl
; }
199 llvm::Constant
*GenerateCopyHelperFunction(bool, const llvm::StructType
*,
200 std::vector
<HelperInfo
> *);
201 llvm::Constant
*GenerateDestroyHelperFunction(bool, const llvm::StructType
*,
202 std::vector
<HelperInfo
> *);
204 llvm::Constant
*BuildCopyHelper(const llvm::StructType
*,
205 std::vector
<HelperInfo
> *);
206 llvm::Constant
*BuildDestroyHelper(const llvm::StructType
*,
207 std::vector
<HelperInfo
> *);
209 llvm::Constant
*GeneratebyrefCopyHelperFunction(const llvm::Type
*, int flag
);
210 llvm::Constant
*GeneratebyrefDestroyHelperFunction(const llvm::Type
*T
, int);
212 llvm::Constant
*BuildbyrefCopyHelper(const llvm::Type
*T
, int flag
,
214 llvm::Constant
*BuildbyrefDestroyHelper(const llvm::Type
*T
, int flag
,
217 llvm::Value
*getBlockObjectAssign();
218 llvm::Value
*getBlockObjectDispose();
219 void BuildBlockRelease(llvm::Value
*DeclPtr
, int flag
= BLOCK_FIELD_IS_BYREF
);
221 bool BlockRequiresCopying(QualType Ty
) {
222 if (Ty
->isBlockPointerType())
224 if (getContext().isObjCNSObjectType(Ty
))
226 if (Ty
->isObjCObjectPointerType())
232 } // end namespace CodeGen
233 } // end namespace clang