blob: 8557d1f83bff97704bc6a635c08b427aef8b4766 [file] [log] [blame]
Mike Stumpd883d842009-03-04 15:35:22 +00001//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is the internal state used for llvm translation for block literals.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_CODEGEN_CGBLOCKS_H
15#define CLANG_CODEGEN_CGBLOCKS_H
16
Mike Stump2a998142009-03-04 18:17:45 +000017#include "CodeGenTypes.h"
18#include "clang/AST/Type.h"
Owen Andersona1cf15f2009-07-14 23:10:40 +000019#include "llvm/Module.h"
Mike Stump2a998142009-03-04 18:17:45 +000020#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"
26
27#include <vector>
28#include <map>
29
30#include "CGBuilder.h"
31#include "CGCall.h"
32#include "CGValue.h"
33
34namespace llvm {
35 class Module;
36 class Constant;
37 class Function;
38 class GlobalValue;
39 class TargetData;
40 class FunctionType;
41 class Value;
Benjamin Kramerf21efe92009-08-11 17:46:57 +000042 class LLVMContext;
Mike Stump2a998142009-03-04 18:17:45 +000043}
44
Mike Stumpd883d842009-03-04 15:35:22 +000045namespace clang {
46
47namespace CodeGen {
Mike Stump90a90432009-03-04 18:47:42 +000048class CodeGenModule;
Mike Stumpd883d842009-03-04 15:35:22 +000049
50class BlockBase {
51public:
52 enum {
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)
59 };
60};
61
62class BlockModule : public BlockBase {
Mike Stump2a998142009-03-04 18:17:45 +000063 ASTContext &Context;
64 llvm::Module &TheModule;
Mike Stump90a90432009-03-04 18:47:42 +000065 const llvm::TargetData &TheTargetData;
Mike Stump2a998142009-03-04 18:17:45 +000066 CodeGenTypes &Types;
Mike Stump90a90432009-03-04 18:47:42 +000067 CodeGenModule &CGM;
Owen Andersona1cf15f2009-07-14 23:10:40 +000068 llvm::LLVMContext &VMContext;
Mike Stump1eb44332009-09-09 15:08:12 +000069
Mike Stump2a998142009-03-04 18:17:45 +000070 ASTContext &getContext() const { return Context; }
71 llvm::Module &getModule() const { return TheModule; }
72 CodeGenTypes &getTypes() { return Types; }
Mike Stump90a90432009-03-04 18:47:42 +000073 const llvm::TargetData &getTargetData() const { return TheTargetData; }
Mike Stump2a998142009-03-04 18:17:45 +000074public:
75 llvm::Constant *getNSConcreteGlobalBlock();
76 llvm::Constant *getNSConcreteStackBlock();
77 int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
78 const llvm::Type *getBlockDescriptorType();
79
80 const llvm::Type *getGenericBlockLiteralType();
81 const llvm::Type *getGenericExtendedBlockLiteralType();
82
Mike Stump90a90432009-03-04 18:47:42 +000083 llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
84
Mike Stump2a998142009-03-04 18:17:45 +000085 /// NSConcreteGlobalBlock - Cached reference to the class pointer for global
86 /// blocks.
87 llvm::Constant *NSConcreteGlobalBlock;
88
89 /// NSConcreteStackBlock - Cached reference to the class poinnter for stack
90 /// blocks.
91 llvm::Constant *NSConcreteStackBlock;
Mike Stump1eb44332009-09-09 15:08:12 +000092
Mike Stump2a998142009-03-04 18:17:45 +000093 const llvm::Type *BlockDescriptorType;
94 const llvm::Type *GenericBlockLiteralType;
95 const llvm::Type *GenericExtendedBlockLiteralType;
96 struct {
97 int GlobalUniqueCount;
98 } Block;
99
Mike Stumpee094222009-03-06 06:12:24 +0000100 llvm::Value *BlockObjectAssign;
Mike Stump797b6322009-03-05 01:23:13 +0000101 llvm::Value *BlockObjectDispose;
102 const llvm::Type *PtrToInt8Ty;
103
Mike Stump3899a7f2009-06-05 23:26:36 +0000104 std::map<uint64_t, llvm::Constant *> AssignCache;
105 std::map<uint64_t, llvm::Constant *> DestroyCache;
106
Mike Stump90a90432009-03-04 18:47:42 +0000107 BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
108 CodeGenTypes &T, CodeGenModule &CodeGen)
109 : Context(C), TheModule(M), TheTargetData(TD), Types(T),
Owen Andersona1cf15f2009-07-14 23:10:40 +0000110 CGM(CodeGen), VMContext(M.getContext()),
Mike Stump90a90432009-03-04 18:47:42 +0000111 NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
Mike Stump08920992009-03-07 02:35:30 +0000112 GenericBlockLiteralType(0), GenericExtendedBlockLiteralType(0),
113 BlockObjectAssign(0), BlockObjectDispose(0) {
Mike Stump2a998142009-03-04 18:17:45 +0000114 Block.GlobalUniqueCount = 0;
Owen Anderson0032b272009-08-13 21:57:51 +0000115 PtrToInt8Ty = llvm::PointerType::getUnqual(
116 llvm::Type::getInt8Ty(M.getContext()));
Mike Stump2a998142009-03-04 18:17:45 +0000117 }
Mike Stump39605b42009-09-22 02:12:52 +0000118
119 bool BlockRequiresCopying(QualType Ty) {
120 if (Ty->isBlockPointerType())
121 return true;
122 if (getContext().isObjCNSObjectType(Ty))
123 return true;
124 if (Ty->isObjCObjectPointerType())
125 return true;
126 return false;
127 }
Mike Stumpd883d842009-03-04 15:35:22 +0000128};
129
130class BlockFunction : public BlockBase {
Mike Stump797b6322009-03-05 01:23:13 +0000131 CodeGenModule &CGM;
Mike Stumpa4f668f2009-03-06 01:33:24 +0000132 CodeGenFunction &CGF;
Mike Stump00470a12009-03-05 08:32:30 +0000133 ASTContext &getContext() const;
Mike Stump797b6322009-03-05 01:23:13 +0000134
Owen Andersona1cf15f2009-07-14 23:10:40 +0000135protected:
136 llvm::LLVMContext &VMContext;
137
Mike Stumpd883d842009-03-04 15:35:22 +0000138public:
Mike Stump797b6322009-03-05 01:23:13 +0000139 const llvm::Type *PtrToInt8Ty;
Mike Stump08920992009-03-07 02:35:30 +0000140 struct HelperInfo {
141 int index;
142 int flag;
143 bool RequiresCopying;
144 };
145
Mike Stump797b6322009-03-05 01:23:13 +0000146 enum {
Mike Stumpd883d842009-03-04 15:35:22 +0000147 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
148 block, ... */
149 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
150 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block
151 variable */
152 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
153 helpers */
Mike Stump3899a7f2009-06-05 23:26:36 +0000154 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose
Mike Stumpd883d842009-03-04 15:35:22 +0000155 support routines */
Mike Stump3899a7f2009-06-05 23:26:36 +0000156 BLOCK_BYREF_CURRENT_MAX = 256
Mike Stumpd883d842009-03-04 15:35:22 +0000157 };
Mike Stump3947de52009-03-04 18:57:26 +0000158
Mike Stumpad75ab42009-03-04 19:03:44 +0000159 /// BlockInfo - Information to generate a block literal.
160 struct BlockInfo {
161 /// BlockLiteralTy - The type of the block literal.
162 const llvm::Type *BlockLiteralTy;
163
Daniel Dunbar49f59ec2009-05-14 16:42:16 +0000164 /// Name - the name of the function this block was created for, if any.
Mike Stumpad75ab42009-03-04 19:03:44 +0000165 const char *Name;
166
167 /// ByCopyDeclRefs - Variables from parent scopes that have been imported
168 /// into this block.
169 llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs;
Mike Stump1eb44332009-09-09 15:08:12 +0000170
171 // ByRefDeclRefs - __block variables from parent scopes that have been
Mike Stumpad75ab42009-03-04 19:03:44 +0000172 // imported into this block.
173 llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs;
Mike Stump1eb44332009-09-09 15:08:12 +0000174
Mike Stumpad75ab42009-03-04 19:03:44 +0000175 BlockInfo(const llvm::Type *blt, const char *n)
Daniel Dunbar49f59ec2009-05-14 16:42:16 +0000176 : BlockLiteralTy(blt), Name(n) {
177 // Skip asm prefix, if any.
178 if (Name && Name[0] == '\01')
179 ++Name;
180 }
Mike Stumpad75ab42009-03-04 19:03:44 +0000181 };
182
Mike Stump3947de52009-03-04 18:57:26 +0000183 CGBuilderTy &Builder;
184
Mike Stump08920992009-03-07 02:35:30 +0000185 BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
186
187 /// BlockOffset - The offset in bytes for the next allocation of an
188 /// imported block variable.
189 uint64_t BlockOffset;
190 /// BlockAlign - Maximal alignment needed for the Block expressed in bytes.
191 uint64_t BlockAlign;
192
193 /// getBlockOffset - Allocate an offset for the ValueDecl from a
194 /// BlockDeclRefExpr in a block literal (BlockExpr).
195 uint64_t getBlockOffset(const BlockDeclRefExpr *E);
196
197 /// BlockHasCopyDispose - True iff the block uses copy/dispose.
198 bool BlockHasCopyDispose;
199
200 /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
201 /// in a block literal. Decls without names are used for padding.
202 llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
203
204 /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
205 std::map<const Decl*, uint64_t> BlockDecls;
Mike Stump3947de52009-03-04 18:57:26 +0000206
Mike Stumpad75ab42009-03-04 19:03:44 +0000207 ImplicitParamDecl *BlockStructDecl;
208 ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
209
Mike Stump08920992009-03-07 02:35:30 +0000210 llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
Mike Stumpb7477cf2009-04-10 18:52:28 +0000211 std::vector<HelperInfo> *);
Mike Stump08920992009-03-07 02:35:30 +0000212 llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
Mike Stumpb7477cf2009-04-10 18:52:28 +0000213 std::vector<HelperInfo> *);
Mike Stumpa4f668f2009-03-06 01:33:24 +0000214
Mike Stump08920992009-03-07 02:35:30 +0000215 llvm::Constant *BuildCopyHelper(const llvm::StructType *,
Mike Stumpb7477cf2009-04-10 18:52:28 +0000216 std::vector<HelperInfo> *);
Mike Stump08920992009-03-07 02:35:30 +0000217 llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
Mike Stumpb7477cf2009-04-10 18:52:28 +0000218 std::vector<HelperInfo> *);
Mike Stump45031c02009-03-06 02:29:21 +0000219
Mike Stumpee094222009-03-06 06:12:24 +0000220 llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
Mike Stump1851b682009-03-06 04:53:30 +0000221 llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
Mike Stump45031c02009-03-06 02:29:21 +0000222
Mike Stump3899a7f2009-06-05 23:26:36 +0000223 llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag,
224 unsigned Align);
225 llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag,
226 unsigned Align);
Mike Stump3947de52009-03-04 18:57:26 +0000227
Mike Stumpee094222009-03-06 06:12:24 +0000228 llvm::Value *getBlockObjectAssign();
Mike Stump797b6322009-03-05 01:23:13 +0000229 llvm::Value *getBlockObjectDispose();
Mike Stump1851b682009-03-06 04:53:30 +0000230 void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
Mike Stump00470a12009-03-05 08:32:30 +0000231
Mike Stump39605b42009-09-22 02:12:52 +0000232 bool BlockRequiresCopying(QualType Ty);
Mike Stumpd883d842009-03-04 15:35:22 +0000233};
234
235} // end namespace CodeGen
236} // end namespace clang
237
238#endif