CGBlocks.cpp revision bd65cac8de63d108a681035782a71d42954b03ab
1//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
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 contains code to emit blocks.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
16#include "llvm/Module.h"
17#include "llvm/Target/TargetData.h"
18
19#include <algorithm>
20
21using namespace clang;
22using namespace CodeGen;
23
24enum {
25  BLOCK_NEEDS_FREE =        (1 << 24),
26  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
27  BLOCK_HAS_CXX_OBJ =       (1 << 26),
28  BLOCK_IS_GC =             (1 << 27),
29  BLOCK_IS_GLOBAL =         (1 << 28),
30  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
31};
32
33llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
34  // FIXME: Push up.
35  bool BlockHasCopyDispose = false;
36
37  const llvm::PointerType *PtrToInt8Ty
38    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
39  const llvm::Type *UnsignedLongTy
40    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
41  llvm::Constant *C;
42  std::vector<llvm::Constant*> Elts;
43
44  // reserved
45  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
46  Elts.push_back(C);
47
48  // Size
49  int sz;
50  if (!BlockHasCopyDispose)
51    sz = CGM.getTargetData()
52      .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;
53  else
54    sz = CGM.getTargetData()
55      .getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8;
56  C = llvm::ConstantInt::get(UnsignedLongTy, sz);
57  Elts.push_back(C);
58
59  if (BlockHasCopyDispose) {
60    // copy_func_helper_decl
61    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
62    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
63    Elts.push_back(C);
64
65    // destroy_func_decl
66    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
67    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
68    Elts.push_back(C);
69  }
70
71  C = llvm::ConstantStruct::get(Elts);
72
73  C = new llvm::GlobalVariable(C->getType(), true,
74                               llvm::GlobalValue::InternalLinkage,
75                               C, "__block_descriptor_tmp", &CGM.getModule());
76  return C;
77}
78
79llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
80  if (NSConcreteGlobalBlock)
81    return NSConcreteGlobalBlock;
82
83  const llvm::PointerType *PtrToInt8Ty
84    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
85  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
86  // same thing as CreateRuntimeFunction if there's already a variable with
87  // the same name.
88  NSConcreteGlobalBlock
89    = new llvm::GlobalVariable(PtrToInt8Ty, false,
90                               llvm::GlobalValue::ExternalLinkage,
91                               0, "_NSConcreteGlobalBlock",
92                               &getModule());
93
94  return NSConcreteGlobalBlock;
95}
96
97llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
98  if (NSConcreteStackBlock)
99    return NSConcreteStackBlock;
100
101  const llvm::PointerType *PtrToInt8Ty
102    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
103  // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the
104  // same thing as CreateRuntimeFunction if there's already a variable with
105  // the same name.
106  NSConcreteStackBlock
107    = new llvm::GlobalVariable(PtrToInt8Ty, false,
108                               llvm::GlobalValue::ExternalLinkage,
109                               0, "_NSConcreteStackBlock",
110                               &getModule());
111
112  return NSConcreteStackBlock;
113}
114
115// FIXME: Push most into CGM, passing down a few bits, like current
116// function name.
117llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
118  // FIXME: Push up
119  bool BlockHasCopyDispose = false;
120  bool insideFunction = false;
121  bool BlockRefDeclList = false;
122  bool BlockByrefDeclList = false;
123
124  std::vector<llvm::Constant*> Elts;
125  llvm::Constant *C;
126
127  {
128    // C = BuildBlockStructInitlist();
129    unsigned int flags = BLOCK_HAS_DESCRIPTOR;
130
131    if (BlockHasCopyDispose)
132      flags |= BLOCK_HAS_COPY_DISPOSE;
133
134    // __isa
135    C = CGM.getNSConcreteStackBlock();
136    if (!insideFunction ||
137        (!BlockRefDeclList && !BlockByrefDeclList)) {
138      C = CGM.getNSConcreteGlobalBlock();
139      flags |= BLOCK_IS_GLOBAL;
140    }
141    const llvm::PointerType *PtrToInt8Ty
142      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
143    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
144    Elts.push_back(C);
145
146    // __flags
147    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
148      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
149    C = llvm::ConstantInt::get(IntTy, flags);
150    Elts.push_back(C);
151
152    // __reserved
153    C = llvm::ConstantInt::get(IntTy, 0);
154    Elts.push_back(C);
155
156    // __invoke
157    const char *Name = "";
158    if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
159      if (ND->getIdentifier())
160        Name = ND->getNameAsCString();
161    BlockInfo Info(0, Name);
162    llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info);
163    Elts.push_back(Fn);
164
165    // __descriptor
166    Elts.push_back(BuildDescriptorBlockDecl());
167
168    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
169  }
170
171  C = llvm::ConstantStruct::get(Elts);
172
173  char Name[32];
174  sprintf(Name, "__block_holder_tmp_%d", CGM.getGlobalUniqueCount());
175  C = new llvm::GlobalVariable(C->getType(), true,
176                               llvm::GlobalValue::InternalLinkage,
177                               C, Name, &CGM.getModule());
178  QualType BPT = BE->getType();
179  C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
180  return C;
181}
182
183
184
185
186const llvm::Type *CodeGenModule::getBlockDescriptorType() {
187  if (BlockDescriptorType)
188    return BlockDescriptorType;
189
190  const llvm::Type *UnsignedLongTy =
191    getTypes().ConvertType(getContext().UnsignedLongTy);
192
193  // struct __block_descriptor {
194  //   unsigned long reserved;
195  //   unsigned long block_size;
196  // };
197  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy,
198                                              UnsignedLongTy,
199                                              NULL);
200
201  getModule().addTypeName("struct.__block_descriptor",
202                          BlockDescriptorType);
203
204  return BlockDescriptorType;
205}
206
207const llvm::Type *
208CodeGenModule::getGenericBlockLiteralType() {
209  if (GenericBlockLiteralType)
210    return GenericBlockLiteralType;
211
212  const llvm::Type *Int8PtrTy =
213    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
214
215  const llvm::Type *BlockDescPtrTy =
216    llvm::PointerType::getUnqual(getBlockDescriptorType());
217
218  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
219    getTypes().ConvertType(getContext().IntTy));
220
221  // struct __block_literal_generic {
222  //   void *__isa;
223  //   int __flags;
224  //   int __reserved;
225  //   void (*__invoke)(void *);
226  //   struct __block_descriptor *__descriptor;
227  // };
228  GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
229                                                  IntTy,
230                                                  IntTy,
231                                                  Int8PtrTy,
232                                                  BlockDescPtrTy,
233                                                  NULL);
234
235  getModule().addTypeName("struct.__block_literal_generic",
236                          GenericBlockLiteralType);
237
238  return GenericBlockLiteralType;
239}
240
241const llvm::Type *
242CodeGenModule::getGenericExtendedBlockLiteralType() {
243  if (GenericExtendedBlockLiteralType)
244    return GenericExtendedBlockLiteralType;
245
246  const llvm::Type *Int8PtrTy =
247    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
248
249  const llvm::Type *BlockDescPtrTy =
250    llvm::PointerType::getUnqual(getBlockDescriptorType());
251
252  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
253    getTypes().ConvertType(getContext().IntTy));
254
255  // struct __block_literal_generic {
256  //   void *__isa;
257  //   int __flags;
258  //   int __reserved;
259  //   void (*__invoke)(void *);
260  //   struct __block_descriptor *__descriptor;
261  //   void *__copy_func_helper_decl;
262  //   void *__destroy_func_decl;
263  // };
264  GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy,
265                                                          IntTy,
266                                                          IntTy,
267                                                          Int8PtrTy,
268                                                          BlockDescPtrTy,
269                                                          Int8PtrTy,
270                                                          Int8PtrTy,
271                                                          NULL);
272
273  getModule().addTypeName("struct.__block_literal_extended_generic",
274                          GenericExtendedBlockLiteralType);
275
276  return GenericExtendedBlockLiteralType;
277}
278
279/// getBlockFunctionType - Given a BlockPointerType, will return the
280/// function type for the block, including the first block literal argument.
281static QualType getBlockFunctionType(ASTContext &Ctx,
282                                     const BlockPointerType *BPT) {
283  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());
284
285  llvm::SmallVector<QualType, 8> Types;
286  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));
287
288  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
289       e = FTy->arg_type_end(); i != e; ++i)
290    Types.push_back(*i);
291
292  return Ctx.getFunctionType(FTy->getResultType(),
293                             &Types[0], Types.size(),
294                             FTy->isVariadic(), 0);
295}
296
297RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
298  const BlockPointerType *BPT =
299    E->getCallee()->getType()->getAsBlockPointerType();
300
301  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
302
303  // Get a pointer to the generic block literal.
304  const llvm::Type *BlockLiteralTy =
305    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
306
307  // Bitcast the callee to a block literal.
308  llvm::Value *BlockLiteral =
309    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");
310
311  // Get the function pointer from the literal.
312  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
313  llvm::Value *Func = Builder.CreateLoad(FuncPtr, FuncPtr, "tmp");
314
315  // Cast the function pointer to the right type.
316  const llvm::Type *BlockFTy =
317    ConvertType(getBlockFunctionType(getContext(), BPT));
318  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
319  Func = Builder.CreateBitCast(Func, BlockFTyPtr);
320
321  BlockLiteral =
322    Builder.CreateBitCast(BlockLiteral,
323                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
324                          "tmp");
325
326  // Add the block literal.
327  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
328  CallArgList Args;
329  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));
330
331  // And the rest of the arguments.
332  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
333       i != e; ++i)
334    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
335                                  i->getType()));
336
337  // And call the block.
338  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
339                  Func, Args);
340}
341
342llvm::Constant *
343CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
344  // Generate the block descriptor.
345  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
346  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
347    getTypes().ConvertType(getContext().IntTy));
348
349  llvm::Constant *DescriptorFields[2];
350
351  // Reserved
352  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);
353
354  // Block literal size. For global blocks we just use the size of the generic
355  // block literal struct.
356  uint64_t BlockLiteralSize =
357    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8;
358  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);
359
360  llvm::Constant *DescriptorStruct =
361    llvm::ConstantStruct::get(&DescriptorFields[0], 2);
362
363  llvm::GlobalVariable *Descriptor =
364    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
365                             llvm::GlobalVariable::InternalLinkage,
366                             DescriptorStruct, "__block_descriptor_global",
367                             &getModule());
368
369  // Generate the constants for the block literal.
370  llvm::Constant *LiteralFields[5];
371
372  CodeGenFunction::BlockInfo Info(0, n);
373  llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info);
374
375  // isa
376  LiteralFields[0] = getNSConcreteGlobalBlock();
377
378  // Flags
379  LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);
380
381  // Reserved
382  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);
383
384  // Function
385  LiteralFields[3] = Fn;
386
387  // Descriptor
388  LiteralFields[4] = Descriptor;
389
390  llvm::Constant *BlockLiteralStruct =
391    llvm::ConstantStruct::get(&LiteralFields[0], 5);
392
393  llvm::GlobalVariable *BlockLiteral =
394    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
395                             llvm::GlobalVariable::InternalLinkage,
396                             BlockLiteralStruct, "__block_literal_global",
397                             &getModule());
398
399  return BlockLiteral;
400}
401
402llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
403                                                       const BlockInfo& Info)
404{
405  const FunctionTypeProto *FTy =
406    cast<FunctionTypeProto>(Expr->getFunctionType());
407
408  FunctionArgList Args;
409
410  const BlockDecl *BD = Expr->getBlockDecl();
411
412  // FIXME: This leaks
413  ImplicitParamDecl *SelfDecl =
414    ImplicitParamDecl::Create(getContext(), 0,
415                              SourceLocation(), 0,
416                              getContext().getPointerType(getContext().VoidTy));
417
418  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
419
420  for (BlockDecl::param_iterator i = BD->param_begin(),
421       e = BD->param_end(); i != e; ++i)
422    Args.push_back(std::make_pair(*i, (*i)->getType()));
423
424  const CGFunctionInfo &FI =
425    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);
426
427  std::string Name = std::string("__") + Info.Name + "_block_invoke_";
428  CodeGenTypes &Types = CGM.getTypes();
429  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());
430
431  llvm::Function *Fn =
432    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
433                           Name,
434                           &CGM.getModule());
435
436  StartFunction(BD, FTy->getResultType(), Fn, Args,
437                Expr->getBody()->getLocEnd());
438  EmitStmt(Expr->getBody());
439  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());
440
441  return Fn;
442}
443