blob: 39f26f8b1363e66522db2072a98d99b1731ba50b [file] [log] [blame]
Mike Stump376e3c02009-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 Stump95435672009-03-04 18:17:45 +000017#include "CodeGenTypes.h"
18#include "clang/AST/Type.h"
Owen Anderson170229f2009-07-14 23:10:40 +000019#include "llvm/Module.h"
Mike Stump95435672009-03-04 18:17:45 +000020#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallVector.h"
22#include "clang/Basic/TargetInfo.h"
Ken Dyck40775002010-01-11 17:06:35 +000023#include "clang/AST/CharUnits.h"
Mike Stump95435672009-03-04 18:17:45 +000024#include "clang/AST/Expr.h"
25#include "clang/AST/ExprCXX.h"
26#include "clang/AST/ExprObjC.h"
27
28#include <vector>
29#include <map>
30
31#include "CGBuilder.h"
32#include "CGCall.h"
33#include "CGValue.h"
34
35namespace llvm {
36 class Module;
37 class Constant;
38 class Function;
39 class GlobalValue;
40 class TargetData;
41 class FunctionType;
42 class Value;
Benjamin Kramer9cd050a2009-08-11 17:46:57 +000043 class LLVMContext;
Mike Stump95435672009-03-04 18:17:45 +000044}
45
Mike Stump376e3c02009-03-04 15:35:22 +000046namespace clang {
47
48namespace CodeGen {
Mike Stump6c396662009-03-04 18:47:42 +000049class CodeGenModule;
Mike Stump376e3c02009-03-04 15:35:22 +000050
51class BlockBase {
52public:
53 enum {
Mike Stump376e3c02009-03-04 15:35:22 +000054 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
55 BLOCK_HAS_CXX_OBJ = (1 << 26),
Mike Stump376e3c02009-03-04 15:35:22 +000056 BLOCK_IS_GLOBAL = (1 << 28),
David Chisnall950a9512009-11-17 19:33:30 +000057 BLOCK_HAS_OBJC_TYPE = (1 << 30)
Mike Stump376e3c02009-03-04 15:35:22 +000058 };
59};
60
61class BlockModule : public BlockBase {
Mike Stump95435672009-03-04 18:17:45 +000062 ASTContext &Context;
63 llvm::Module &TheModule;
Mike Stump6c396662009-03-04 18:47:42 +000064 const llvm::TargetData &TheTargetData;
Mike Stump95435672009-03-04 18:17:45 +000065 CodeGenTypes &Types;
Mike Stump6c396662009-03-04 18:47:42 +000066 CodeGenModule &CGM;
Owen Anderson170229f2009-07-14 23:10:40 +000067 llvm::LLVMContext &VMContext;
Mike Stump11289f42009-09-09 15:08:12 +000068
Mike Stump95435672009-03-04 18:17:45 +000069 ASTContext &getContext() const { return Context; }
70 llvm::Module &getModule() const { return TheModule; }
71 CodeGenTypes &getTypes() { return Types; }
Mike Stump6c396662009-03-04 18:47:42 +000072 const llvm::TargetData &getTargetData() const { return TheTargetData; }
Mike Stump95435672009-03-04 18:17:45 +000073public:
74 llvm::Constant *getNSConcreteGlobalBlock();
75 llvm::Constant *getNSConcreteStackBlock();
76 int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
77 const llvm::Type *getBlockDescriptorType();
78
79 const llvm::Type *getGenericBlockLiteralType();
Mike Stump95435672009-03-04 18:17:45 +000080
Mike Stump6c396662009-03-04 18:47:42 +000081 llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
82
Mike Stump95435672009-03-04 18:17:45 +000083 /// NSConcreteGlobalBlock - Cached reference to the class pointer for global
84 /// blocks.
85 llvm::Constant *NSConcreteGlobalBlock;
86
87 /// NSConcreteStackBlock - Cached reference to the class poinnter for stack
88 /// blocks.
89 llvm::Constant *NSConcreteStackBlock;
Mike Stump11289f42009-09-09 15:08:12 +000090
Mike Stump95435672009-03-04 18:17:45 +000091 const llvm::Type *BlockDescriptorType;
92 const llvm::Type *GenericBlockLiteralType;
Blaine Garst5421a832010-02-19 00:24:37 +000093
Mike Stump95435672009-03-04 18:17:45 +000094 struct {
95 int GlobalUniqueCount;
96 } Block;
97
Mike Stumpf89230d2009-03-06 06:12:24 +000098 llvm::Value *BlockObjectAssign;
Mike Stump626aecc2009-03-05 01:23:13 +000099 llvm::Value *BlockObjectDispose;
100 const llvm::Type *PtrToInt8Ty;
101
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000102 std::map<uint64_t, llvm::Constant *> AssignCache;
103 std::map<uint64_t, llvm::Constant *> DestroyCache;
104
Mike Stump6c396662009-03-04 18:47:42 +0000105 BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
106 CodeGenTypes &T, CodeGenModule &CodeGen)
107 : Context(C), TheModule(M), TheTargetData(TD), Types(T),
Owen Anderson170229f2009-07-14 23:10:40 +0000108 CGM(CodeGen), VMContext(M.getContext()),
Mike Stump6c396662009-03-04 18:47:42 +0000109 NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0),
Blaine Garst5421a832010-02-19 00:24:37 +0000110 GenericBlockLiteralType(0),
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000111 BlockObjectAssign(0), BlockObjectDispose(0) {
Mike Stump95435672009-03-04 18:17:45 +0000112 Block.GlobalUniqueCount = 0;
Benjamin Kramerabd5b902009-10-13 10:07:13 +0000113 PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());
Mike Stump95435672009-03-04 18:17:45 +0000114 }
Mike Stump2114d7c2009-09-22 02:12:52 +0000115
Mike Stump41eb02d2009-10-21 18:23:01 +0000116 bool BlockRequiresCopying(QualType Ty)
117 { return getContext().BlockRequiresCopying(Ty); }
Mike Stump376e3c02009-03-04 15:35:22 +0000118};
119
120class BlockFunction : public BlockBase {
Mike Stump626aecc2009-03-05 01:23:13 +0000121 CodeGenModule &CGM;
Mike Stump0c743272009-03-06 01:33:24 +0000122 CodeGenFunction &CGF;
Mike Stump4446dcf2009-03-05 08:32:30 +0000123 ASTContext &getContext() const;
Mike Stump626aecc2009-03-05 01:23:13 +0000124
Owen Anderson170229f2009-07-14 23:10:40 +0000125protected:
126 llvm::LLVMContext &VMContext;
127
Mike Stump376e3c02009-03-04 15:35:22 +0000128public:
Mike Stump626aecc2009-03-05 01:23:13 +0000129 const llvm::Type *PtrToInt8Ty;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000130 struct HelperInfo {
131 int index;
132 int flag;
133 bool RequiresCopying;
134 };
135
Mike Stump626aecc2009-03-05 01:23:13 +0000136 enum {
Mike Stump376e3c02009-03-04 15:35:22 +0000137 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
138 block, ... */
139 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
140 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block
141 variable */
142 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
143 helpers */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000144 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose
Mike Stump376e3c02009-03-04 15:35:22 +0000145 support routines */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000146 BLOCK_BYREF_CURRENT_MAX = 256
Mike Stump376e3c02009-03-04 15:35:22 +0000147 };
Mike Stump06acea8a2009-03-04 18:57:26 +0000148
Mike Stump8473a122009-03-04 19:03:44 +0000149 /// BlockInfo - Information to generate a block literal.
150 struct BlockInfo {
151 /// BlockLiteralTy - The type of the block literal.
152 const llvm::Type *BlockLiteralTy;
153
Daniel Dunbar0a2171c2009-05-14 16:42:16 +0000154 /// Name - the name of the function this block was created for, if any.
Mike Stump8473a122009-03-04 19:03:44 +0000155 const char *Name;
156
157 /// ByCopyDeclRefs - Variables from parent scopes that have been imported
158 /// into this block.
Mike Stump7fe9cc12009-10-21 03:49:08 +0000159 llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
Mike Stump11289f42009-09-09 15:08:12 +0000160
Mike Stump8473a122009-03-04 19:03:44 +0000161 BlockInfo(const llvm::Type *blt, const char *n)
Daniel Dunbar0a2171c2009-05-14 16:42:16 +0000162 : BlockLiteralTy(blt), Name(n) {
163 // Skip asm prefix, if any.
164 if (Name && Name[0] == '\01')
165 ++Name;
166 }
Mike Stump8473a122009-03-04 19:03:44 +0000167 };
168
Mike Stump06acea8a2009-03-04 18:57:26 +0000169 CGBuilderTy &Builder;
170
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000171 BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
172
173 /// BlockOffset - The offset in bytes for the next allocation of an
174 /// imported block variable.
Ken Dyck40775002010-01-11 17:06:35 +0000175 CharUnits BlockOffset;
Ken Dyck5262b112010-01-26 19:13:33 +0000176 /// BlockAlign - Maximal alignment needed for the Block expressed in
177 /// characters.
178 CharUnits BlockAlign;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000179
180 /// getBlockOffset - Allocate an offset for the ValueDecl from a
181 /// BlockDeclRefExpr in a block literal (BlockExpr).
Ken Dyck40775002010-01-11 17:06:35 +0000182 CharUnits getBlockOffset(const BlockDeclRefExpr *E);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000183
184 /// BlockHasCopyDispose - True iff the block uses copy/dispose.
185 bool BlockHasCopyDispose;
186
187 /// BlockDeclRefDecls - Decls from BlockDeclRefExprs in apperance order
188 /// in a block literal. Decls without names are used for padding.
189 llvm::SmallVector<const Expr *, 8> BlockDeclRefDecls;
190
191 /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
Ken Dyck40775002010-01-11 17:06:35 +0000192 std::map<const Decl*, CharUnits> BlockDecls;
Mike Stump06acea8a2009-03-04 18:57:26 +0000193
Mike Stump8473a122009-03-04 19:03:44 +0000194 ImplicitParamDecl *BlockStructDecl;
195 ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
196
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000197 llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000198 std::vector<HelperInfo> *);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000199 llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000200 std::vector<HelperInfo> *);
Mike Stump0c743272009-03-06 01:33:24 +0000201
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000202 llvm::Constant *BuildCopyHelper(const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000203 std::vector<HelperInfo> *);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000204 llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000205 std::vector<HelperInfo> *);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000206
Mike Stumpf89230d2009-03-06 06:12:24 +0000207 llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
Mike Stumpfbe25dd2009-03-06 04:53:30 +0000208 llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000209
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000210 llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag,
211 unsigned Align);
212 llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag,
213 unsigned Align);
Mike Stump06acea8a2009-03-04 18:57:26 +0000214
Mike Stumpf89230d2009-03-06 06:12:24 +0000215 llvm::Value *getBlockObjectAssign();
Mike Stump626aecc2009-03-05 01:23:13 +0000216 llvm::Value *getBlockObjectDispose();
Mike Stumpfbe25dd2009-03-06 04:53:30 +0000217 void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
Mike Stump4446dcf2009-03-05 08:32:30 +0000218
Mike Stump41eb02d2009-10-21 18:23:01 +0000219 bool BlockRequiresCopying(QualType Ty)
220 { return getContext().BlockRequiresCopying(Ty); }
Mike Stump376e3c02009-03-04 15:35:22 +0000221};
222
223} // end namespace CodeGen
224} // end namespace clang
225
226#endif