blob: 888fdb6a4005fd132777612320d8876cdf0d9676 [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;
John McCall351762c2011-02-07 10:33:21 +000050class CGBlockInfo;
Mike Stump376e3c02009-03-04 15:35:22 +000051
52class BlockBase {
53public:
54 enum {
Mike Stump376e3c02009-03-04 15:35:22 +000055 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
56 BLOCK_HAS_CXX_OBJ = (1 << 26),
Mike Stump376e3c02009-03-04 15:35:22 +000057 BLOCK_IS_GLOBAL = (1 << 28),
Blaine Garstf27ab712010-03-05 01:29:59 +000058 BLOCK_USE_STRET = (1 << 29),
59 BLOCK_HAS_SIGNATURE = (1 << 30)
Mike Stump376e3c02009-03-04 15:35:22 +000060 };
61};
62
Blaine Garstf27ab712010-03-05 01:29:59 +000063
Mike Stump376e3c02009-03-04 15:35:22 +000064class BlockModule : public BlockBase {
Mike Stump95435672009-03-04 18:17:45 +000065 ASTContext &Context;
66 llvm::Module &TheModule;
Mike Stump6c396662009-03-04 18:47:42 +000067 const llvm::TargetData &TheTargetData;
Mike Stump95435672009-03-04 18:17:45 +000068 CodeGenTypes &Types;
Mike Stump6c396662009-03-04 18:47:42 +000069 CodeGenModule &CGM;
Owen Anderson170229f2009-07-14 23:10:40 +000070 llvm::LLVMContext &VMContext;
Mike Stump11289f42009-09-09 15:08:12 +000071
Mike Stump95435672009-03-04 18:17:45 +000072 ASTContext &getContext() const { return Context; }
73 llvm::Module &getModule() const { return TheModule; }
74 CodeGenTypes &getTypes() { return Types; }
Mike Stump6c396662009-03-04 18:47:42 +000075 const llvm::TargetData &getTargetData() const { return TheTargetData; }
Mike Stump95435672009-03-04 18:17:45 +000076public:
Mike Stump95435672009-03-04 18:17:45 +000077 int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
78 const llvm::Type *getBlockDescriptorType();
79
80 const llvm::Type *getGenericBlockLiteralType();
Mike Stump95435672009-03-04 18:17:45 +000081
Mike Stump6c396662009-03-04 18:47:42 +000082 llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
83
Mike Stump95435672009-03-04 18:17:45 +000084 const llvm::Type *BlockDescriptorType;
85 const llvm::Type *GenericBlockLiteralType;
Blaine Garst5421a832010-02-19 00:24:37 +000086
Mike Stump95435672009-03-04 18:17:45 +000087 struct {
88 int GlobalUniqueCount;
89 } Block;
90
John McCallbd309292010-07-06 01:34:17 +000091 const llvm::PointerType *PtrToInt8Ty;
Mike Stump626aecc2009-03-05 01:23:13 +000092
Mike Stumpcbc2bca2009-06-05 23:26:36 +000093 std::map<uint64_t, llvm::Constant *> AssignCache;
94 std::map<uint64_t, llvm::Constant *> DestroyCache;
95
Mike Stump6c396662009-03-04 18:47:42 +000096 BlockModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD,
97 CodeGenTypes &T, CodeGenModule &CodeGen)
98 : Context(C), TheModule(M), TheTargetData(TD), Types(T),
Owen Anderson170229f2009-07-14 23:10:40 +000099 CGM(CodeGen), VMContext(M.getContext()),
Daniel Dunbar900546d2010-07-16 00:00:15 +0000100 BlockDescriptorType(0), GenericBlockLiteralType(0) {
Mike Stump95435672009-03-04 18:17:45 +0000101 Block.GlobalUniqueCount = 0;
Benjamin Kramerabd5b902009-10-13 10:07:13 +0000102 PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());
Mike Stump95435672009-03-04 18:17:45 +0000103 }
Mike Stump376e3c02009-03-04 15:35:22 +0000104};
105
106class BlockFunction : public BlockBase {
Mike Stump626aecc2009-03-05 01:23:13 +0000107 CodeGenModule &CGM;
Mike Stump4446dcf2009-03-05 08:32:30 +0000108 ASTContext &getContext() const;
Mike Stump626aecc2009-03-05 01:23:13 +0000109
Owen Anderson170229f2009-07-14 23:10:40 +0000110protected:
111 llvm::LLVMContext &VMContext;
112
Mike Stump376e3c02009-03-04 15:35:22 +0000113public:
Chris Lattner5e016ae2010-06-27 07:15:29 +0000114 CodeGenFunction &CGF;
115
John McCall351762c2011-02-07 10:33:21 +0000116 const CodeGen::CGBlockInfo *BlockInfo;
117 llvm::Value *BlockPointer;
118
John McCall21886962010-04-21 10:05:39 +0000119 const llvm::PointerType *PtrToInt8Ty;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000120 struct HelperInfo {
121 int index;
122 int flag;
Fariborz Jahaniane988bda2010-11-13 21:53:34 +0000123 const BlockDeclRefExpr *cxxvar_import;
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000124 bool RequiresCopying;
125 };
126
Mike Stump626aecc2009-03-05 01:23:13 +0000127 enum {
Mike Stump376e3c02009-03-04 15:35:22 +0000128 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
129 block, ... */
130 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
131 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block
132 variable */
133 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
134 helpers */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000135 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose
Mike Stump376e3c02009-03-04 15:35:22 +0000136 support routines */
Mike Stumpcbc2bca2009-06-05 23:26:36 +0000137 BLOCK_BYREF_CURRENT_MAX = 256
Mike Stump376e3c02009-03-04 15:35:22 +0000138 };
Mike Stump06acea8a2009-03-04 18:57:26 +0000139
140 CGBuilderTy &Builder;
141
Mike Stumpaeb0ffd2009-03-07 02:35:30 +0000142 BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B);
143
John McCall351762c2011-02-07 10:33:21 +0000144 llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
145 llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000146
Fariborz Jahanian50198092010-12-02 17:02:11 +0000147 llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag,
148 const VarDecl *BD);
149 llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
150 int flag,
151 const VarDecl *BD);
Mike Stumpee2a5ee2009-03-06 02:29:21 +0000152
John McCall351762c2011-02-07 10:33:21 +0000153 llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, uint32_t flags,
Fariborz Jahanian50198092010-12-02 17:02:11 +0000154 unsigned Align, const VarDecl *BD);
John McCall351762c2011-02-07 10:33:21 +0000155 llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, uint32_t flags,
Fariborz Jahanian50198092010-12-02 17:02:11 +0000156 unsigned Align, const VarDecl *BD);
Mike Stump06acea8a2009-03-04 18:57:26 +0000157
John McCall351762c2011-02-07 10:33:21 +0000158 void BuildBlockRelease(llvm::Value *DeclPtr, uint32_t flags);
Mike Stump376e3c02009-03-04 15:35:22 +0000159};
160
161} // end namespace CodeGen
162} // end namespace clang
163
164#endif