blob: ce721a46408f7bb81d67372cc3188a57179e16d9 [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/SmallVector.h"
21#include "clang/Basic/TargetInfo.h"
Ken Dyck40775002010-01-11 17:06:35 +000022#include "clang/AST/CharUnits.h"
Mike Stump95435672009-03-04 18:17:45 +000023#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;
John McCall21886962010-04-21 10:05:39 +000041 class PointerType;
Mike Stump95435672009-03-04 18:17:45 +000042 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),
Blaine Garstf27ab712010-03-05 01:29:59 +000057 BLOCK_USE_STRET = (1 << 29),
58 BLOCK_HAS_SIGNATURE = (1 << 30)
Mike Stump376e3c02009-03-04 15:35:22 +000059 };
60};
61
Blaine Garstf27ab712010-03-05 01:29:59 +000062
Mike Stump376e3c02009-03-04 15:35:22 +000063class BlockModule : public BlockBase {
Mike Stump95435672009-03-04 18:17:45 +000064 ASTContext &Context;
65 llvm::Module &TheModule;
Mike Stump6c396662009-03-04 18:47:42 +000066 const llvm::TargetData &TheTargetData;
Mike Stump95435672009-03-04 18:17:45 +000067 CodeGenTypes &Types;
Mike Stump6c396662009-03-04 18:47:42 +000068 CodeGenModule &CGM;
Owen Anderson170229f2009-07-14 23:10:40 +000069 llvm::LLVMContext &VMContext;
Mike Stump11289f42009-09-09 15:08:12 +000070
Mike Stump95435672009-03-04 18:17:45 +000071 ASTContext &getContext() const { return Context; }
72 llvm::Module &getModule() const { return TheModule; }
73 CodeGenTypes &getTypes() { return Types; }
Mike Stump6c396662009-03-04 18:47:42 +000074 const llvm::TargetData &getTargetData() const { return TheTargetData; }
Mike Stump95435672009-03-04 18:17:45 +000075public:
Mike Stump95435672009-03-04 18:17:45 +000076 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 const llvm::Type *BlockDescriptorType;
84 const llvm::Type *GenericBlockLiteralType;
Blaine Garst5421a832010-02-19 00:24:37 +000085
Mike Stump95435672009-03-04 18:17:45 +000086 struct {
87 int GlobalUniqueCount;
88 } Block;
89
John McCallbd309292010-07-06 01:34:17 +000090 const llvm::PointerType *PtrToInt8Ty;
Mike Stump626aecc2009-03-05 01:23:13 +000091
Mike Stumpcbc2bca2009-06-05 23:26:36 +000092 std::map<uint64_t, llvm::Constant *> AssignCache;
93 std::map<uint64_t, llvm::Constant *> DestroyCache;
94
Mike Stump6c396662009-03-04 18:47:42 +000095 BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
96 CodeGenTypes &T, CodeGenModule &CodeGen)
97 : Context(C), TheModule(M), TheTargetData(TD), Types(T),
Owen Anderson170229f2009-07-14 23:10:40 +000098 CGM(CodeGen), VMContext(M.getContext()),
Daniel Dunbar900546d2010-07-16 00:00:15 +000099 BlockDescriptorType(0), GenericBlockLiteralType(0) {
Mike Stump95435672009-03-04 18:17:45 +0000100 Block.GlobalUniqueCount = 0;
Benjamin Kramerabd5b902009-10-13 10:07:13 +0000101 PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());
Mike Stump95435672009-03-04 18:17:45 +0000102 }
Mike Stump2114d7c2009-09-22 02:12:52 +0000103
Mike Stump41eb02d2009-10-21 18:23:01 +0000104 bool BlockRequiresCopying(QualType Ty)
105 { return getContext().BlockRequiresCopying(Ty); }
Fariborz Jahanian2a5deb52010-11-11 00:11:38 +0000106 bool BlockRequiresCopying(const BlockDeclRefExpr *E)
107 { return E->getCopyConstructorExpr() != 0 ||
108 getContext().BlockRequiresCopying(E->getType()); }
Mike Stump376e3c02009-03-04 15:35:22 +0000109};
110
111class BlockFunction : public BlockBase {
Mike Stump626aecc2009-03-05 01:23:13 +0000112 CodeGenModule &CGM;
Mike Stump4446dcf2009-03-05 08:32:30 +0000113 ASTContext &getContext() const;
Mike Stump626aecc2009-03-05 01:23:13 +0000114
Owen Anderson170229f2009-07-14 23:10:40 +0000115protected:
116 llvm::LLVMContext &VMContext;
117
Mike Stump376e3c02009-03-04 15:35:22 +0000118public:
Chris Lattner5e016ae2010-06-27 07:15:29 +0000119 CodeGenFunction &CGF;
120
John McCall21886962010-04-21 10:05:39 +0000121 const llvm::PointerType *PtrToInt8Ty;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000122 struct HelperInfo {
123 int index;
124 int flag;
125 bool RequiresCopying;
126 };
127
Mike Stump626aecc2009-03-05 01:23:13 +0000128 enum {
Mike Stump376e3c02009-03-04 15:35:22 +0000129 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
130 block, ... */
131 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
132 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block
133 variable */
134 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
135 helpers */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000136 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose
Mike Stump376e3c02009-03-04 15:35:22 +0000137 support routines */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000138 BLOCK_BYREF_CURRENT_MAX = 256
Mike Stump376e3c02009-03-04 15:35:22 +0000139 };
Mike Stump06acea8a2009-03-04 18:57:26 +0000140
141 CGBuilderTy &Builder;
142
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000143 BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
144
145 /// BlockOffset - The offset in bytes for the next allocation of an
146 /// imported block variable.
Ken Dyck40775002010-01-11 17:06:35 +0000147 CharUnits BlockOffset;
Ken Dyck5262b112010-01-26 19:13:33 +0000148 /// BlockAlign - Maximal alignment needed for the Block expressed in
149 /// characters.
150 CharUnits BlockAlign;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000151
John McCall87fe5d52010-05-20 01:18:31 +0000152 /// getBlockOffset - Allocate a location within the block's storage
153 /// for a value with the given size and alignment requirements.
154 CharUnits getBlockOffset(CharUnits Size, CharUnits Align);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000155
156 /// BlockHasCopyDispose - True iff the block uses copy/dispose.
157 bool BlockHasCopyDispose;
158
John McCall87fe5d52010-05-20 01:18:31 +0000159 /// BlockLayout - The layout of the block's storage, represented as
160 /// a sequence of expressions which require such storage. The
161 /// expressions can be:
162 /// - a BlockDeclRefExpr, indicating that the given declaration
163 /// from an enclosing scope is needed by the block;
164 /// - a DeclRefExpr, which always wraps an anonymous VarDecl with
165 /// array type, used to insert padding into the block; or
166 /// - a CXXThisExpr, indicating that the C++ 'this' value should
167 /// propagate from the parent to the block.
168 /// This is a really silly representation.
169 llvm::SmallVector<const Expr *, 8> BlockLayout;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000170
171 /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
John McCall87fe5d52010-05-20 01:18:31 +0000172 llvm::DenseMap<const Decl*, CharUnits> BlockDecls;
Fariborz Jahanian64176c22010-06-04 16:10:00 +0000173
John McCall87fe5d52010-05-20 01:18:31 +0000174 /// BlockCXXThisOffset - The offset of the C++ 'this' value within
175 /// the block structure.
176 CharUnits BlockCXXThisOffset;
Mike Stump06acea8a2009-03-04 18:57:26 +0000177
Mike Stump8473a122009-03-04 19:03:44 +0000178 ImplicitParamDecl *BlockStructDecl;
179 ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
180
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000181 llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000182 std::vector<HelperInfo> *);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000183 llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000184 std::vector<HelperInfo> *);
Mike Stump0c743272009-03-06 01:33:24 +0000185
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000186 llvm::Constant *BuildCopyHelper(const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000187 std::vector<HelperInfo> *);
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000188 llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
Mike Stump67645932009-04-10 18:52:28 +0000189 std::vector<HelperInfo> *);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000190
Mike Stumpf89230d2009-03-06 06:12:24 +0000191 llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
Mike Stumpfbe25dd2009-03-06 04:53:30 +0000192 llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000193
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000194 llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag,
195 unsigned Align);
196 llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag,
197 unsigned Align);
Mike Stump06acea8a2009-03-04 18:57:26 +0000198
Mike Stumpfbe25dd2009-03-06 04:53:30 +0000199 void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
Mike Stump4446dcf2009-03-05 08:32:30 +0000200
Mike Stump41eb02d2009-10-21 18:23:01 +0000201 bool BlockRequiresCopying(QualType Ty)
202 { return getContext().BlockRequiresCopying(Ty); }
Fariborz Jahanian2a5deb52010-11-11 00:11:38 +0000203 bool BlockRequiresCopying(const BlockDeclRefExpr *E)
204 { return E->getCopyConstructorExpr() != 0 ||
205 getContext().BlockRequiresCopying(E->getType()); }
Mike Stump376e3c02009-03-04 15:35:22 +0000206};
207
208} // end namespace CodeGen
209} // end namespace clang
210
211#endif