blob: 56d3a2d3b10f2abb59f0d0ddaa3d6fc069025452 [file] [log] [blame]
Mike Stump16c92a12009-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 Stump1f010b52009-03-04 18:17:45 +000017#include "CodeGenTypes.h"
18#include "clang/AST/Type.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/SmallVector.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/AST/Expr.h"
23#include "clang/AST/ExprCXX.h"
24#include "clang/AST/ExprObjC.h"
25
26#include <vector>
27#include <map>
28
29#include "CGBuilder.h"
30#include "CGCall.h"
31#include "CGValue.h"
32
33namespace llvm {
34 class Module;
35 class Constant;
36 class Function;
37 class GlobalValue;
38 class TargetData;
39 class FunctionType;
40 class Value;
41}
42
Mike Stump16c92a12009-03-04 15:35:22 +000043namespace clang {
44
45namespace CodeGen {
Mike Stumpd6d0ebe2009-03-04 18:47:42 +000046class CodeGenModule;
Mike Stump16c92a12009-03-04 15:35:22 +000047
48class BlockBase {
49public:
50 enum {
51 BLOCK_NEEDS_FREE = (1 << 24),
52 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
53 BLOCK_HAS_CXX_OBJ = (1 << 26),
54 BLOCK_IS_GC = (1 << 27),
55 BLOCK_IS_GLOBAL = (1 << 28),
56 BLOCK_HAS_DESCRIPTOR = (1 << 29)
57 };
58};
59
60class BlockModule : public BlockBase {
Mike Stump1f010b52009-03-04 18:17:45 +000061 ASTContext &Context;
62 llvm::Module &TheModule;
Mike Stumpd6d0ebe2009-03-04 18:47:42 +000063 const llvm::TargetData &TheTargetData;
Mike Stump1f010b52009-03-04 18:17:45 +000064 CodeGenTypes &Types;
Mike Stumpd6d0ebe2009-03-04 18:47:42 +000065 CodeGenModule &CGM;
Mike Stump1f010b52009-03-04 18:17:45 +000066
67 ASTContext &getContext() const { return Context; }
68 llvm::Module &getModule() const { return TheModule; }
69 CodeGenTypes &getTypes() { return Types; }
Mike Stumpd6d0ebe2009-03-04 18:47:42 +000070 const llvm::TargetData &getTargetData() const { return TheTargetData; }
Mike Stump1f010b52009-03-04 18:17:45 +000071public:
72 llvm::Constant *getNSConcreteGlobalBlock();
73 llvm::Constant *getNSConcreteStackBlock();
74 int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
75 const llvm::Type *getBlockDescriptorType();
76
77 const llvm::Type *getGenericBlockLiteralType();
78 const llvm::Type *getGenericExtendedBlockLiteralType();
79
Mike Stumpd6d0ebe2009-03-04 18:47:42 +000080 llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
81
Mike Stump1f010b52009-03-04 18:17:45 +000082 /// NSConcreteGlobalBlock - Cached reference to the class pointer for global
83 /// blocks.
84 llvm::Constant *NSConcreteGlobalBlock;
85
86 /// NSConcreteStackBlock - Cached reference to the class poinnter for stack
87 /// blocks.
88 llvm::Constant *NSConcreteStackBlock;
89
90 const llvm::Type *BlockDescriptorType;
91 const llvm::Type *GenericBlockLiteralType;
92 const llvm::Type *GenericExtendedBlockLiteralType;
93 struct {
94 int GlobalUniqueCount;
95 } Block;
96
Mike Stump11973b62009-03-06 06:12:24 +000097 llvm::Value *BlockObjectAssign;
Mike Stump60294662009-03-05 01:23:13 +000098 llvm::Value *BlockObjectDispose;
99 const llvm::Type *PtrToInt8Ty;
100
Mike Stumpd6d0ebe2009-03-04 18:47:42 +0000101 BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
102 CodeGenTypes &T, CodeGenModule &CodeGen)
103 : Context(C), TheModule(M), TheTargetData(TD), Types(T),
104 CGM(CodeGen),
105 NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
Mike Stump1fa52fe2009-03-07 02:35:30 +0000106 GenericBlockLiteralType(0), GenericExtendedBlockLiteralType(0),
107 BlockObjectAssign(0), BlockObjectDispose(0) {
Mike Stump1f010b52009-03-04 18:17:45 +0000108 Block.GlobalUniqueCount = 0;
Mike Stump60294662009-03-05 01:23:13 +0000109 PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Mike Stump1f010b52009-03-04 18:17:45 +0000110 }
Mike Stump16c92a12009-03-04 15:35:22 +0000111};
112
113class BlockFunction : public BlockBase {
Mike Stump60294662009-03-05 01:23:13 +0000114 CodeGenModule &CGM;
Mike Stumpecd79422009-03-06 01:33:24 +0000115 CodeGenFunction &CGF;
Mike Stump1bdbf632009-03-05 08:32:30 +0000116 ASTContext &getContext() const;
Mike Stump60294662009-03-05 01:23:13 +0000117
Mike Stump16c92a12009-03-04 15:35:22 +0000118public:
Mike Stump60294662009-03-05 01:23:13 +0000119 const llvm::Type *PtrToInt8Ty;
Mike Stump1fa52fe2009-03-07 02:35:30 +0000120 struct HelperInfo {
121 int index;
122 int flag;
123 bool RequiresCopying;
124 };
125
Mike Stump60294662009-03-05 01:23:13 +0000126 enum {
Mike Stump16c92a12009-03-04 15:35:22 +0000127 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
128 block, ... */
129 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
130 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block
131 variable */
132 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
133 helpers */
134 BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose
135 support routines */
136 };
Mike Stumpa79696d2009-03-04 18:57:26 +0000137
Mike Stump788fa7d2009-03-04 19:03:44 +0000138 /// BlockInfo - Information to generate a block literal.
139 struct BlockInfo {
140 /// BlockLiteralTy - The type of the block literal.
141 const llvm::Type *BlockLiteralTy;
142
Daniel Dunbara5bdb592009-05-14 16:42:16 +0000143 /// Name - the name of the function this block was created for, if any.
Mike Stump788fa7d2009-03-04 19:03:44 +0000144 const char *Name;
145
146 /// ByCopyDeclRefs - Variables from parent scopes that have been imported
147 /// into this block.
148 llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs;
149
150 // ByRefDeclRefs - __block variables from parent scopes that have been
151 // imported into this block.
152 llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs;
153
154 BlockInfo(const llvm::Type *blt, const char *n)
Daniel Dunbara5bdb592009-05-14 16:42:16 +0000155 : BlockLiteralTy(blt), Name(n) {
156 // Skip asm prefix, if any.
157 if (Name && Name[0] == '\01')
158 ++Name;
159 }
Mike Stump788fa7d2009-03-04 19:03:44 +0000160 };
161
Mike Stumpa79696d2009-03-04 18:57:26 +0000162 CGBuilderTy &Builder;
163
Mike Stump1fa52fe2009-03-07 02:35:30 +0000164 BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
165
166 /// BlockOffset - The offset in bytes for the next allocation of an
167 /// imported block variable.
168 uint64_t BlockOffset;
169 /// BlockAlign - Maximal alignment needed for the Block expressed in bytes.
170 uint64_t BlockAlign;
171
172 /// getBlockOffset - Allocate an offset for the ValueDecl from a
173 /// BlockDeclRefExpr in a block literal (BlockExpr).
174 uint64_t getBlockOffset(const BlockDeclRefExpr *E);
175
176 /// BlockHasCopyDispose - True iff the block uses copy/dispose.
177 bool BlockHasCopyDispose;
178
179 /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
180 /// in a block literal. Decls without names are used for padding.
181 llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
182
183 /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
184 std::map<const Decl*, uint64_t> BlockDecls;
Mike Stumpa79696d2009-03-04 18:57:26 +0000185
Mike Stump788fa7d2009-03-04 19:03:44 +0000186 ImplicitParamDecl *BlockStructDecl;
187 ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
188
Mike Stump1fa52fe2009-03-07 02:35:30 +0000189 llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
Mike Stump2f9a4262009-04-10 18:52:28 +0000190 std::vector<HelperInfo> *);
Mike Stump1fa52fe2009-03-07 02:35:30 +0000191 llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
Mike Stump2f9a4262009-04-10 18:52:28 +0000192 std::vector<HelperInfo> *);
Mike Stumpecd79422009-03-06 01:33:24 +0000193
Mike Stump1fa52fe2009-03-07 02:35:30 +0000194 llvm::Constant *BuildCopyHelper(const llvm::StructType *,
Mike Stump2f9a4262009-04-10 18:52:28 +0000195 std::vector<HelperInfo> *);
Mike Stump1fa52fe2009-03-07 02:35:30 +0000196 llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
Mike Stump2f9a4262009-04-10 18:52:28 +0000197 std::vector<HelperInfo> *);
Mike Stumpf4b62342009-03-06 02:29:21 +0000198
Mike Stump11973b62009-03-06 06:12:24 +0000199 llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
Mike Stump4a0e5132009-03-06 04:53:30 +0000200 llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
Mike Stumpf4b62342009-03-06 02:29:21 +0000201
Mike Stump11973b62009-03-06 06:12:24 +0000202 llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag);
203 llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag);
Mike Stumpa79696d2009-03-04 18:57:26 +0000204
Mike Stump11973b62009-03-06 06:12:24 +0000205 llvm::Value *getBlockObjectAssign();
Mike Stump60294662009-03-05 01:23:13 +0000206 llvm::Value *getBlockObjectDispose();
Mike Stump4a0e5132009-03-06 04:53:30 +0000207 void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
Mike Stump1bdbf632009-03-05 08:32:30 +0000208
209 bool BlockRequiresCopying(QualType Ty) {
210 if (Ty->isBlockPointerType())
211 return true;
212 if (getContext().isObjCNSObjectType(Ty))
213 return true;
Mike Stump67774332009-04-10 23:09:55 +0000214 if (getContext().isObjCObjectPointerType(Ty))
215 return true;
Mike Stump1bdbf632009-03-05 08:32:30 +0000216 return false;
217 }
Mike Stump16c92a12009-03-04 15:35:22 +0000218};
219
220} // end namespace CodeGen
221} // end namespace clang
222
223#endif