CGBlocks.cpp revision 204793
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 "CGDebugInfo.h"
15#include "CodeGenFunction.h"
16#include "CGObjCRuntime.h"
17#include "CodeGenModule.h"
18#include "clang/AST/DeclObjC.h"
19#include "llvm/Module.h"
20#include "llvm/Target/TargetData.h"
21#include <algorithm>
22
23using namespace clang;
24using namespace CodeGen;
25
26llvm::Constant *CodeGenFunction::
27BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
28                         const llvm::StructType* Ty,
29                         std::vector<HelperInfo> *NoteForHelper) {
30  const llvm::Type *UnsignedLongTy
31    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
32  llvm::Constant *C;
33  std::vector<llvm::Constant*> Elts;
34
35  // reserved
36  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
37  Elts.push_back(C);
38
39  // Size
40  // FIXME: What is the right way to say this doesn't fit?  We should give
41  // a user diagnostic in that case.  Better fix would be to change the
42  // API to size_t.
43  C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity());
44  Elts.push_back(C);
45
46  // optional copy/dispose helpers
47  if (BlockHasCopyDispose) {
48    // copy_func_helper_decl
49    Elts.push_back(BuildCopyHelper(Ty, NoteForHelper));
50
51    // destroy_func_decl
52    Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper));
53  }
54
55  // Signature.  non-optional ObjC-style method descriptor @encode sequence
56  std::string BlockTypeEncoding;
57  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
58
59  Elts.push_back(llvm::ConstantExpr::getBitCast(
60          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty));
61
62  // Layout.
63  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
64  Elts.push_back(C);
65
66  C = llvm::ConstantStruct::get(VMContext, Elts, false);
67
68  C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
69                               llvm::GlobalValue::InternalLinkage,
70                               C, "__block_descriptor_tmp");
71  return C;
72}
73
74llvm::Constant *BlockModule::getNSConcreteGlobalBlock() {
75  if (NSConcreteGlobalBlock == 0)
76    NSConcreteGlobalBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
77                                                      "_NSConcreteGlobalBlock");
78  return NSConcreteGlobalBlock;
79}
80
81llvm::Constant *BlockModule::getNSConcreteStackBlock() {
82  if (NSConcreteStackBlock == 0)
83    NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
84                                                     "_NSConcreteStackBlock");
85  return NSConcreteStackBlock;
86}
87
88static void CollectBlockDeclRefInfo(
89  const Stmt *S, CodeGenFunction::BlockInfo &Info,
90  llvm::SmallSet<const DeclContext *, 16> &InnerContexts) {
91  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
92       I != E; ++I)
93    if (*I)
94      CollectBlockDeclRefInfo(*I, Info, InnerContexts);
95
96  // We want to ensure we walk down into block literals so we can find
97  // all nested BlockDeclRefExprs.
98  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
99    InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl()));
100    CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
101  }
102
103  if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
104    // FIXME: Handle enums.
105    if (isa<FunctionDecl>(BDRE->getDecl()))
106      return;
107
108    // Only Decls that escape are added.
109    if (!InnerContexts.count(BDRE->getDecl()->getDeclContext()))
110      Info.DeclRefs.push_back(BDRE);
111  }
112}
113
114/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
115/// declared as a global variable instead of on the stack.
116static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
117  return Info.DeclRefs.empty();
118}
119
120/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
121/// ensure we can generate the debug information for the parameter for the block
122/// invoke function.
123static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info,
124                                     CodeGenFunction *CGF) {
125  // FIXME: Also always forward the this pointer in C++ as well.
126
127  for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
128    CGF->AllocateBlockDecl(Info.DeclRefs[i]);
129}
130
131// FIXME: Push most into CGM, passing down a few bits, like current function
132// name.
133llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
134
135  std::string Name = CurFn->getName();
136  CodeGenFunction::BlockInfo Info(0, Name.c_str());
137  llvm::SmallSet<const DeclContext *, 16> InnerContexts;
138  InnerContexts.insert(BE->getBlockDecl());
139  CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
140
141  // Check if the block can be global.
142  // FIXME: This test doesn't work for nested blocks yet.  Longer term, I'd like
143  // to just have one code path.  We should move this function into CGM and pass
144  // CGF, then we can just check to see if CGF is 0.
145  if (0 && CanBlockBeGlobal(Info))
146    return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
147
148  size_t BlockFields = 5;
149
150  std::vector<llvm::Constant*> Elts(BlockFields);
151
152  llvm::Constant *C;
153  llvm::Value *V;
154
155  {
156    // C = BuildBlockStructInitlist();
157    unsigned int flags = BLOCK_HAS_SIGNATURE;
158
159    // We run this first so that we set BlockHasCopyDispose from the entire
160    // block literal.
161    // __invoke
162    CharUnits subBlockSize;
163    CharUnits subBlockAlign;
164    llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
165    bool subBlockHasCopyDispose = false;
166    llvm::Function *Fn
167      = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl,
168                                                   LocalDeclMap,
169                                                   subBlockSize,
170                                                   subBlockAlign,
171                                                   subBlockDeclRefDecls,
172                                                   subBlockHasCopyDispose);
173    BlockHasCopyDispose |= subBlockHasCopyDispose;
174    Elts[3] = Fn;
175
176    // FIXME: Don't use BlockHasCopyDispose, it is set more often then
177    // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); }
178    if (subBlockHasCopyDispose)
179      flags |= BLOCK_HAS_COPY_DISPOSE;
180
181    // __isa
182    C = CGM.getNSConcreteStackBlock();
183    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
184    Elts[0] = C;
185
186    // __flags
187    {
188      QualType BPT = BE->getType();
189      const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>();
190      QualType ResultType = ftype->getResultType();
191
192      CallArgList Args;
193      CodeGenTypes &Types = CGM.getTypes();
194      const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args,
195                                                       CC_Default, false);
196      if (CGM.ReturnTypeUsesSret(FnInfo))
197        flags |= BLOCK_USE_STRET;
198    }
199    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
200      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
201    C = llvm::ConstantInt::get(IntTy, flags);
202    Elts[1] = C;
203
204    // __reserved
205    C = llvm::ConstantInt::get(IntTy, 0);
206    Elts[2] = C;
207
208    if (subBlockDeclRefDecls.size() == 0) {
209      // __descriptor
210      Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize,
211                                         0, 0);
212
213      // Optimize to being a global block.
214      Elts[0] = CGM.getNSConcreteGlobalBlock();
215
216      Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL);
217
218      C = llvm::ConstantStruct::get(VMContext, Elts, false);
219
220      C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
221                                   llvm::GlobalValue::InternalLinkage, C,
222                                   "__block_holder_tmp_" +
223                                   llvm::Twine(CGM.getGlobalUniqueCount()));
224      QualType BPT = BE->getType();
225      C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
226      return C;
227    }
228
229    std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size());
230    for (int i=0; i<4; ++i)
231      Types[i] = Elts[i]->getType();
232    Types[4] = PtrToInt8Ty;
233
234    for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) {
235      const Expr *E = subBlockDeclRefDecls[i];
236      const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
237      QualType Ty = E->getType();
238      if (BDRE && BDRE->isByRef()) {
239        Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
240      } else
241        Types[i+BlockFields] = ConvertType(Ty);
242    }
243
244    llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true);
245
246    llvm::AllocaInst *A = CreateTempAlloca(Ty);
247    A->setAlignment(subBlockAlign.getQuantity());
248    V = A;
249
250    std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size());
251    int helpersize = 0;
252
253    for (unsigned i=0; i<4; ++i)
254      Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
255
256    for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i)
257      {
258        // FIXME: Push const down.
259        Expr *E = const_cast<Expr*>(subBlockDeclRefDecls[i]);
260        DeclRefExpr *DR;
261        ValueDecl *VD;
262
263        DR = dyn_cast<DeclRefExpr>(E);
264        // Skip padding.
265        if (DR) continue;
266
267        BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
268        VD = BDRE->getDecl();
269
270        llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp");
271        NoteForHelper[helpersize].index = i+5;
272        NoteForHelper[helpersize].RequiresCopying
273          = BlockRequiresCopying(VD->getType());
274        NoteForHelper[helpersize].flag
275          = (VD->getType()->isBlockPointerType()
276             ? BLOCK_FIELD_IS_BLOCK
277             : BLOCK_FIELD_IS_OBJECT);
278
279        if (LocalDeclMap[VD]) {
280          if (BDRE->isByRef()) {
281            NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
282              // FIXME: Someone double check this.
283              (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
284            llvm::Value *Loc = LocalDeclMap[VD];
285            Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
286            Loc = Builder.CreateLoad(Loc);
287            Builder.CreateStore(Loc, Addr);
288            ++helpersize;
289            continue;
290          } else
291            E = new (getContext()) DeclRefExpr (VD,
292                                                VD->getType(),
293                                                SourceLocation());
294        }
295        if (BDRE->isByRef()) {
296          NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
297            // FIXME: Someone double check this.
298            (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
299          E = new (getContext())
300            UnaryOperator(E, UnaryOperator::AddrOf,
301                          getContext().getPointerType(E->getType()),
302                          SourceLocation());
303        }
304        ++helpersize;
305
306        RValue r = EmitAnyExpr(E, Addr, false);
307        if (r.isScalar()) {
308          llvm::Value *Loc = r.getScalarVal();
309          const llvm::Type *Ty = Types[i+BlockFields];
310          if  (BDRE->isByRef()) {
311            // E is now the address of the value field, instead, we want the
312            // address of the actual ByRef struct.  We optimize this slightly
313            // compared to gcc by not grabbing the forwarding slot as this must
314            // be done during Block_copy for us, and we can postpone the work
315            // until then.
316            CharUnits offset = BlockDecls[BDRE->getDecl()];
317
318            llvm::Value *BlockLiteral = LoadBlockStruct();
319
320            Loc = Builder.CreateGEP(BlockLiteral,
321                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
322                                                           offset.getQuantity()),
323                                    "block.literal");
324            Ty = llvm::PointerType::get(Ty, 0);
325            Loc = Builder.CreateBitCast(Loc, Ty);
326            Loc = Builder.CreateLoad(Loc);
327            // Loc = Builder.CreateBitCast(Loc, Ty);
328          }
329          Builder.CreateStore(Loc, Addr);
330        } else if (r.isComplex())
331          // FIXME: implement
332          ErrorUnsupported(BE, "complex in block literal");
333        else if (r.isAggregate())
334          ; // Already created into the destination
335        else
336          assert (0 && "bad block variable");
337        // FIXME: Ensure that the offset created by the backend for
338        // the struct matches the previously computed offset in BlockDecls.
339      }
340    NoteForHelper.resize(helpersize);
341
342    // __descriptor
343    llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
344                                                       subBlockHasCopyDispose,
345                                                       subBlockSize, Ty,
346                                                       &NoteForHelper);
347    Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
348    Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
349  }
350
351  QualType BPT = BE->getType();
352  V = Builder.CreateBitCast(V, ConvertType(BPT));
353  // See if this is a __weak block variable and the must call objc_read_weak
354  // on it.
355  const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>();
356  QualType RES = ftype->getResultType();
357  if (RES.isObjCGCWeak()) {
358    // Must cast argument to id*
359    const llvm::Type *ObjectPtrTy =
360      ConvertType(CGM.getContext().getObjCIdType());
361    const llvm::Type *PtrObjectPtrTy =
362      llvm::PointerType::getUnqual(ObjectPtrTy);
363    V = Builder.CreateBitCast(V, PtrObjectPtrTy);
364    V =  CGM.getObjCRuntime().EmitObjCWeakRead(*this, V);
365  }
366  return V;
367}
368
369
370const llvm::Type *BlockModule::getBlockDescriptorType() {
371  if (BlockDescriptorType)
372    return BlockDescriptorType;
373
374  const llvm::Type *UnsignedLongTy =
375    getTypes().ConvertType(getContext().UnsignedLongTy);
376
377  // struct __block_descriptor {
378  //   unsigned long reserved;
379  //   unsigned long block_size;
380  //
381  //   // later, the following will be added
382  //
383  //   struct {
384  //     void (*copyHelper)();
385  //     void (*copyHelper)();
386  //   } helpers;                // !!! optional
387  //
388  //   const char *signature;   // the block signature
389  //   const char *layout;      // reserved
390  // };
391  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy->getContext(),
392                                              UnsignedLongTy,
393                                              UnsignedLongTy,
394                                              NULL);
395
396  getModule().addTypeName("struct.__block_descriptor",
397                          BlockDescriptorType);
398
399  return BlockDescriptorType;
400}
401
402const llvm::Type *BlockModule::getGenericBlockLiteralType() {
403  if (GenericBlockLiteralType)
404    return GenericBlockLiteralType;
405
406  const llvm::Type *BlockDescPtrTy =
407    llvm::PointerType::getUnqual(getBlockDescriptorType());
408
409  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
410    getTypes().ConvertType(getContext().IntTy));
411
412  // struct __block_literal_generic {
413  //   void *__isa;
414  //   int __flags;
415  //   int __reserved;
416  //   void (*__invoke)(void *);
417  //   struct __block_descriptor *__descriptor;
418  // };
419  GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(),
420                                                  PtrToInt8Ty,
421                                                  IntTy,
422                                                  IntTy,
423                                                  PtrToInt8Ty,
424                                                  BlockDescPtrTy,
425                                                  NULL);
426
427  getModule().addTypeName("struct.__block_literal_generic",
428                          GenericBlockLiteralType);
429
430  return GenericBlockLiteralType;
431}
432
433
434RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,
435                                          ReturnValueSlot ReturnValue) {
436  const BlockPointerType *BPT =
437    E->getCallee()->getType()->getAs<BlockPointerType>();
438
439  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
440
441  // Get a pointer to the generic block literal.
442  const llvm::Type *BlockLiteralTy =
443    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
444
445  // Bitcast the callee to a block literal.
446  llvm::Value *BlockLiteral =
447    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");
448
449  // Get the function pointer from the literal.
450  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
451
452  BlockLiteral =
453    Builder.CreateBitCast(BlockLiteral,
454                          llvm::Type::getInt8PtrTy(VMContext),
455                          "tmp");
456
457  // Add the block literal.
458  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
459  CallArgList Args;
460  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));
461
462  QualType FnType = BPT->getPointeeType();
463
464  // And the rest of the arguments.
465  EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(),
466               E->arg_begin(), E->arg_end());
467
468  // Load the function.
469  llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp");
470
471  const FunctionType *FuncTy = FnType->getAs<FunctionType>();
472  QualType ResultType = FuncTy->getResultType();
473
474  const CGFunctionInfo &FnInfo =
475    CGM.getTypes().getFunctionInfo(ResultType, Args, FuncTy->getCallConv(),
476                                   FuncTy->getNoReturnAttr());
477
478  // Cast the function pointer to the right type.
479  const llvm::Type *BlockFTy =
480    CGM.getTypes().GetFunctionType(FnInfo, false);
481
482  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
483  Func = Builder.CreateBitCast(Func, BlockFTyPtr);
484
485  // And call the block.
486  return EmitCall(FnInfo, Func, ReturnValue, Args);
487}
488
489CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
490  const ValueDecl *VD = E->getDecl();
491  CharUnits &offset = BlockDecls[VD];
492
493  // See if we have already allocated an offset for this variable.
494  if (offset.isPositive())
495    return offset;
496
497  // Don't run the expensive check, unless we have to.
498  if (!BlockHasCopyDispose)
499    if (E->isByRef()
500        || BlockRequiresCopying(E->getType()))
501      BlockHasCopyDispose = true;
502
503  // if not, allocate one now.
504  offset = getBlockOffset(E);
505
506  return offset;
507}
508
509llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
510  const ValueDecl *VD = E->getDecl();
511  CharUnits offset = AllocateBlockDecl(E);
512
513
514  llvm::Value *BlockLiteral = LoadBlockStruct();
515  llvm::Value *V = Builder.CreateGEP(BlockLiteral,
516                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
517                                                         offset.getQuantity()),
518                                     "block.literal");
519  if (E->isByRef()) {
520    const llvm::Type *PtrStructTy
521      = llvm::PointerType::get(BuildByRefType(VD), 0);
522    // The block literal will need a copy/destroy helper.
523    BlockHasCopyDispose = true;
524
525    const llvm::Type *Ty = PtrStructTy;
526    Ty = llvm::PointerType::get(Ty, 0);
527    V = Builder.CreateBitCast(V, Ty);
528    V = Builder.CreateLoad(V);
529    V = Builder.CreateStructGEP(V, 1, "forwarding");
530    V = Builder.CreateLoad(V);
531    V = Builder.CreateBitCast(V, PtrStructTy);
532    V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
533                                VD->getNameAsString());
534  } else {
535    const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
536
537    Ty = llvm::PointerType::get(Ty, 0);
538    V = Builder.CreateBitCast(V, Ty);
539  }
540  return V;
541}
542
543void CodeGenFunction::BlockForwardSelf() {
544  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
545  ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
546  llvm::Value *&DMEntry = LocalDeclMap[SelfDecl];
547  if (DMEntry)
548    return;
549  // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care
550  BlockDeclRefExpr *BDRE = new (getContext())
551    BlockDeclRefExpr(SelfDecl,
552                     SelfDecl->getType(), SourceLocation(), false);
553  DMEntry = GetAddrOfBlockDecl(BDRE);
554}
555
556llvm::Constant *
557BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
558  // Generate the block descriptor.
559  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
560  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
561    getTypes().ConvertType(getContext().IntTy));
562
563  llvm::Constant *DescriptorFields[4];
564
565  // Reserved
566  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);
567
568  // Block literal size. For global blocks we just use the size of the generic
569  // block literal struct.
570  CharUnits BlockLiteralSize =
571    CGM.GetTargetTypeStoreSize(getGenericBlockLiteralType());
572  DescriptorFields[1] =
573    llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity());
574
575  // signature.  non-optional ObjC-style method descriptor @encode sequence
576  std::string BlockTypeEncoding;
577  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
578
579  DescriptorFields[2] = llvm::ConstantExpr::getBitCast(
580          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty);
581
582  // layout
583  DescriptorFields[3] =
584    llvm::ConstantInt::get(UnsignedLongTy,0);
585
586  // build the structure from the 4 elements
587  llvm::Constant *DescriptorStruct =
588    llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 4, false);
589
590  llvm::GlobalVariable *Descriptor =
591    new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true,
592                             llvm::GlobalVariable::InternalLinkage,
593                             DescriptorStruct, "__block_descriptor_global");
594
595  int FieldCount = 5;
596  // Generate the constants for the block literal.
597
598  std::vector<llvm::Constant*> LiteralFields(FieldCount);
599
600  CodeGenFunction::BlockInfo Info(0, n);
601  CharUnits subBlockSize;
602  CharUnits subBlockAlign;
603  llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
604  bool subBlockHasCopyDispose = false;
605  llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
606  llvm::Function *Fn
607    = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap,
608                                                 subBlockSize,
609                                                 subBlockAlign,
610                                                 subBlockDeclRefDecls,
611                                                 subBlockHasCopyDispose);
612  assert(subBlockSize == BlockLiteralSize
613         && "no imports allowed for global block");
614
615  // isa
616  LiteralFields[0] = getNSConcreteGlobalBlock();
617
618  // Flags
619  LiteralFields[1] =
620    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);
621
622  // Reserved
623  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);
624
625  // Function
626  LiteralFields[3] = Fn;
627
628  // Descriptor
629  LiteralFields[4] = Descriptor;
630
631  llvm::Constant *BlockLiteralStruct =
632    llvm::ConstantStruct::get(VMContext, LiteralFields, false);
633
634  llvm::GlobalVariable *BlockLiteral =
635    new llvm::GlobalVariable(getModule(), BlockLiteralStruct->getType(), true,
636                             llvm::GlobalVariable::InternalLinkage,
637                             BlockLiteralStruct, "__block_literal_global");
638
639  return BlockLiteral;
640}
641
642llvm::Value *CodeGenFunction::LoadBlockStruct() {
643  llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()],
644                                      "self");
645  // For now, we codegen based upon byte offsets.
646  return Builder.CreateBitCast(V, PtrToInt8Ty);
647}
648
649llvm::Function *
650CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
651                                       const BlockInfo& Info,
652                                       const Decl *OuterFuncDecl,
653                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm,
654                                       CharUnits &Size,
655                                       CharUnits &Align,
656                       llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
657                                       bool &subBlockHasCopyDispose) {
658
659  // Check if we should generate debug info for this block.
660  if (CGM.getDebugInfo())
661    DebugInfo = CGM.getDebugInfo();
662
663  // Arrange for local static and local extern declarations to appear
664  // to be local to this function as well, as they are directly referenced
665  // in a block.
666  for (llvm::DenseMap<const Decl *, llvm::Value*>::iterator i = ldm.begin();
667       i != ldm.end();
668       ++i) {
669    const VarDecl *VD = dyn_cast<VarDecl>(i->first);
670
671    if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage())
672      LocalDeclMap[VD] = i->second;
673  }
674
675  BlockOffset =
676      CGM.GetTargetTypeStoreSize(CGM.getGenericBlockLiteralType());
677  BlockAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
678
679  const FunctionType *BlockFunctionType = BExpr->getFunctionType();
680  QualType ResultType;
681  CallingConv CC = BlockFunctionType->getCallConv();
682  bool NoReturn = BlockFunctionType->getNoReturnAttr();
683  bool IsVariadic;
684  if (const FunctionProtoType *FTy =
685      dyn_cast<FunctionProtoType>(BlockFunctionType)) {
686    ResultType = FTy->getResultType();
687    IsVariadic = FTy->isVariadic();
688  } else {
689    // K&R style block.
690    ResultType = BlockFunctionType->getResultType();
691    IsVariadic = false;
692  }
693
694  FunctionArgList Args;
695
696  CurFuncDecl = OuterFuncDecl;
697
698  const BlockDecl *BD = BExpr->getBlockDecl();
699
700  IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
701
702  // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below.
703  AllocateAllBlockDeclRefs(Info, this);
704
705  QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
706                                                  BlockDeclRefDecls);
707  // FIXME: This leaks
708  ImplicitParamDecl *SelfDecl =
709    ImplicitParamDecl::Create(getContext(), 0,
710                              SourceLocation(), II,
711                              ParmTy);
712
713  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
714  BlockStructDecl = SelfDecl;
715
716  for (BlockDecl::param_const_iterator i = BD->param_begin(),
717       e = BD->param_end(); i != e; ++i)
718    Args.push_back(std::make_pair(*i, (*i)->getType()));
719
720  const CGFunctionInfo &FI =
721    CGM.getTypes().getFunctionInfo(ResultType, Args, CC, NoReturn);
722
723  CodeGenTypes &Types = CGM.getTypes();
724  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
725
726  llvm::Function *Fn =
727    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
728                           llvm::Twine("__") + Info.Name + "_block_invoke_",
729                           &CGM.getModule());
730
731  CGM.SetInternalFunctionAttributes(BD, Fn, FI);
732
733  StartFunction(BD, ResultType, Fn, Args,
734                BExpr->getBody()->getLocEnd());
735
736  CurFuncDecl = OuterFuncDecl;
737  CurCodeDecl = BD;
738
739  // Save a spot to insert the debug information for all the BlockDeclRefDecls.
740  llvm::BasicBlock *entry = Builder.GetInsertBlock();
741  llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
742  --entry_ptr;
743
744  EmitStmt(BExpr->getBody());
745
746  // Remember where we were...
747  llvm::BasicBlock *resume = Builder.GetInsertBlock();
748
749  // Go back to the entry.
750  ++entry_ptr;
751  Builder.SetInsertPoint(entry, entry_ptr);
752
753  if (CGDebugInfo *DI = getDebugInfo()) {
754    // Emit debug information for all the BlockDeclRefDecls.
755    for (unsigned i = 0, e = BlockDeclRefDecls.size(); i != e; ++i) {
756      if (const BlockDeclRefExpr *BDRE =
757            dyn_cast<BlockDeclRefExpr>(BlockDeclRefDecls[i])) {
758        const ValueDecl *D = BDRE->getDecl();
759        DI->setLocation(D->getLocation());
760        DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
761                                             LocalDeclMap[getBlockStructDecl()],
762                                              Builder, this);
763      }
764    }
765  }
766  // And resume where we left off.
767  if (resume == 0)
768    Builder.ClearInsertionPoint();
769  else
770    Builder.SetInsertPoint(resume);
771
772  FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
773
774  // The runtime needs a minimum alignment of a void *.
775  CharUnits MinAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
776  BlockOffset = CharUnits::fromQuantity(
777      llvm::RoundUpToAlignment(BlockOffset.getQuantity(),
778                               MinAlign.getQuantity()));
779
780  Size = BlockOffset;
781  Align = BlockAlign;
782  subBlockDeclRefDecls = BlockDeclRefDecls;
783  subBlockHasCopyDispose |= BlockHasCopyDispose;
784  return Fn;
785}
786
787CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
788  const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl());
789
790  CharUnits Size = getContext().getTypeSizeInChars(D->getType());
791  CharUnits Align = getContext().getDeclAlign(D);
792
793  if (BDRE->isByRef()) {
794    Size = getContext().getTypeSizeInChars(getContext().VoidPtrTy);
795    Align = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
796  }
797
798  assert ((Align.isPositive()) && "alignment must be 1 byte or more");
799
800  CharUnits OldOffset = BlockOffset;
801
802  // Ensure proper alignment, even if it means we have to have a gap
803  BlockOffset = CharUnits::fromQuantity(
804      llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align.getQuantity()));
805  BlockAlign = std::max(Align, BlockAlign);
806
807  CharUnits Pad = BlockOffset - OldOffset;
808  if (Pad.isPositive()) {
809    llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad.getQuantity());
810    QualType PadTy = getContext().getConstantArrayType(getContext().CharTy,
811                                                       llvm::APInt(32,
812                                                         Pad.getQuantity()),
813                                                       ArrayType::Normal, 0);
814    ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(),
815                                         0, QualType(PadTy), 0, VarDecl::None);
816    Expr *E;
817    E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
818                                       SourceLocation());
819    BlockDeclRefDecls.push_back(E);
820  }
821  BlockDeclRefDecls.push_back(BDRE);
822
823  BlockOffset += Size;
824  return BlockOffset-Size;
825}
826
827llvm::Constant *BlockFunction::
828GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
829                           std::vector<HelperInfo> *NoteForHelperp) {
830  QualType R = getContext().VoidTy;
831
832  FunctionArgList Args;
833  // FIXME: This leaks
834  ImplicitParamDecl *Dst =
835    ImplicitParamDecl::Create(getContext(), 0,
836                              SourceLocation(), 0,
837                              getContext().getPointerType(getContext().VoidTy));
838  Args.push_back(std::make_pair(Dst, Dst->getType()));
839  ImplicitParamDecl *Src =
840    ImplicitParamDecl::Create(getContext(), 0,
841                              SourceLocation(), 0,
842                              getContext().getPointerType(getContext().VoidTy));
843  Args.push_back(std::make_pair(Src, Src->getType()));
844
845  const CGFunctionInfo &FI =
846    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
847
848  // FIXME: We'd like to put these into a mergable by content, with
849  // internal linkage.
850  CodeGenTypes &Types = CGM.getTypes();
851  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
852
853  llvm::Function *Fn =
854    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
855                           "__copy_helper_block_", &CGM.getModule());
856
857  IdentifierInfo *II
858    = &CGM.getContext().Idents.get("__copy_helper_block_");
859
860  FunctionDecl *FD = FunctionDecl::Create(getContext(),
861                                          getContext().getTranslationUnitDecl(),
862                                          SourceLocation(), II, R, 0,
863                                          FunctionDecl::Static, false,
864                                          true);
865  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
866
867  llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
868  llvm::Type *PtrPtrT;
869
870  if (NoteForHelperp) {
871    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
872
873    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
874    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
875    SrcObj = Builder.CreateLoad(SrcObj);
876
877    llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst);
878    llvm::Type *PtrPtrT;
879    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
880    DstObj = Builder.CreateBitCast(DstObj, PtrPtrT);
881    DstObj = Builder.CreateLoad(DstObj);
882
883    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
884      int flag = NoteForHelper[i].flag;
885      int index = NoteForHelper[i].index;
886
887      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
888          || NoteForHelper[i].RequiresCopying) {
889        llvm::Value *Srcv = SrcObj;
890        Srcv = Builder.CreateStructGEP(Srcv, index);
891        Srcv = Builder.CreateBitCast(Srcv,
892                                     llvm::PointerType::get(PtrToInt8Ty, 0));
893        Srcv = Builder.CreateLoad(Srcv);
894
895        llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
896        Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
897
898        llvm::Value *N = llvm::ConstantInt::get(
899              llvm::Type::getInt32Ty(T->getContext()), flag);
900        llvm::Value *F = getBlockObjectAssign();
901        Builder.CreateCall3(F, Dstv, Srcv, N);
902      }
903    }
904  }
905
906  CGF.FinishFunction();
907
908  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
909}
910
911llvm::Constant *BlockFunction::
912GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
913                              const llvm::StructType* T,
914                              std::vector<HelperInfo> *NoteForHelperp) {
915  QualType R = getContext().VoidTy;
916
917  FunctionArgList Args;
918  // FIXME: This leaks
919  ImplicitParamDecl *Src =
920    ImplicitParamDecl::Create(getContext(), 0,
921                              SourceLocation(), 0,
922                              getContext().getPointerType(getContext().VoidTy));
923
924  Args.push_back(std::make_pair(Src, Src->getType()));
925
926  const CGFunctionInfo &FI =
927    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
928
929  // FIXME: We'd like to put these into a mergable by content, with
930  // internal linkage.
931  CodeGenTypes &Types = CGM.getTypes();
932  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
933
934  llvm::Function *Fn =
935    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
936                           "__destroy_helper_block_", &CGM.getModule());
937
938  IdentifierInfo *II
939    = &CGM.getContext().Idents.get("__destroy_helper_block_");
940
941  FunctionDecl *FD = FunctionDecl::Create(getContext(),
942                                          getContext().getTranslationUnitDecl(),
943                                          SourceLocation(), II, R, 0,
944                                          FunctionDecl::Static, false,
945                                          true);
946  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
947
948  if (NoteForHelperp) {
949    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
950
951    llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
952    llvm::Type *PtrPtrT;
953    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
954    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
955    SrcObj = Builder.CreateLoad(SrcObj);
956
957    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
958      int flag = NoteForHelper[i].flag;
959      int index = NoteForHelper[i].index;
960
961      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
962          || NoteForHelper[i].RequiresCopying) {
963        llvm::Value *Srcv = SrcObj;
964        Srcv = Builder.CreateStructGEP(Srcv, index);
965        Srcv = Builder.CreateBitCast(Srcv,
966                                     llvm::PointerType::get(PtrToInt8Ty, 0));
967        Srcv = Builder.CreateLoad(Srcv);
968
969        BuildBlockRelease(Srcv, flag);
970      }
971    }
972  }
973
974  CGF.FinishFunction();
975
976  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
977}
978
979llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T,
980                                       std::vector<HelperInfo> *NoteForHelper) {
981  return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose,
982                                                         T, NoteForHelper);
983}
984
985llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T,
986                                      std::vector<HelperInfo> *NoteForHelperp) {
987  return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose,
988                                                            T, NoteForHelperp);
989}
990
991llvm::Constant *BlockFunction::
992GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {
993  QualType R = getContext().VoidTy;
994
995  FunctionArgList Args;
996  // FIXME: This leaks
997  ImplicitParamDecl *Dst =
998    ImplicitParamDecl::Create(getContext(), 0,
999                              SourceLocation(), 0,
1000                              getContext().getPointerType(getContext().VoidTy));
1001  Args.push_back(std::make_pair(Dst, Dst->getType()));
1002
1003  // FIXME: This leaks
1004  ImplicitParamDecl *Src =
1005    ImplicitParamDecl::Create(getContext(), 0,
1006                              SourceLocation(), 0,
1007                              getContext().getPointerType(getContext().VoidTy));
1008  Args.push_back(std::make_pair(Src, Src->getType()));
1009
1010  const CGFunctionInfo &FI =
1011    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
1012
1013  CodeGenTypes &Types = CGM.getTypes();
1014  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
1015
1016  // FIXME: We'd like to put these into a mergable by content, with
1017  // internal linkage.
1018  llvm::Function *Fn =
1019    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
1020                           "__Block_byref_id_object_copy_", &CGM.getModule());
1021
1022  IdentifierInfo *II
1023    = &CGM.getContext().Idents.get("__Block_byref_id_object_copy_");
1024
1025  FunctionDecl *FD = FunctionDecl::Create(getContext(),
1026                                          getContext().getTranslationUnitDecl(),
1027                                          SourceLocation(), II, R, 0,
1028                                          FunctionDecl::Static, false,
1029                                          true);
1030  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
1031
1032  // dst->x
1033  llvm::Value *V = CGF.GetAddrOfLocalVar(Dst);
1034  V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
1035  V = Builder.CreateLoad(V);
1036  V = Builder.CreateStructGEP(V, 6, "x");
1037  llvm::Value *DstObj = Builder.CreateBitCast(V, PtrToInt8Ty);
1038
1039  // src->x
1040  V = CGF.GetAddrOfLocalVar(Src);
1041  V = Builder.CreateLoad(V);
1042  V = Builder.CreateBitCast(V, T);
1043  V = Builder.CreateStructGEP(V, 6, "x");
1044  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
1045  llvm::Value *SrcObj = Builder.CreateLoad(V);
1046
1047  flag |= BLOCK_BYREF_CALLER;
1048
1049  llvm::Value *N = llvm::ConstantInt::get(
1050          llvm::Type::getInt32Ty(T->getContext()), flag);
1051  llvm::Value *F = getBlockObjectAssign();
1052  Builder.CreateCall3(F, DstObj, SrcObj, N);
1053
1054  CGF.FinishFunction();
1055
1056  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
1057}
1058
1059llvm::Constant *
1060BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
1061                                                  int flag) {
1062  QualType R = getContext().VoidTy;
1063
1064  FunctionArgList Args;
1065  // FIXME: This leaks
1066  ImplicitParamDecl *Src =
1067    ImplicitParamDecl::Create(getContext(), 0,
1068                              SourceLocation(), 0,
1069                              getContext().getPointerType(getContext().VoidTy));
1070
1071  Args.push_back(std::make_pair(Src, Src->getType()));
1072
1073  const CGFunctionInfo &FI =
1074    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
1075
1076  CodeGenTypes &Types = CGM.getTypes();
1077  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
1078
1079  // FIXME: We'd like to put these into a mergable by content, with
1080  // internal linkage.
1081  llvm::Function *Fn =
1082    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
1083                           "__Block_byref_id_object_dispose_",
1084                           &CGM.getModule());
1085
1086  IdentifierInfo *II
1087    = &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_");
1088
1089  FunctionDecl *FD = FunctionDecl::Create(getContext(),
1090                                          getContext().getTranslationUnitDecl(),
1091                                          SourceLocation(), II, R, 0,
1092                                          FunctionDecl::Static, false,
1093                                          true);
1094  CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
1095
1096  llvm::Value *V = CGF.GetAddrOfLocalVar(Src);
1097  V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
1098  V = Builder.CreateLoad(V);
1099  V = Builder.CreateStructGEP(V, 6, "x");
1100  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
1101  V = Builder.CreateLoad(V);
1102
1103  flag |= BLOCK_BYREF_CALLER;
1104  BuildBlockRelease(V, flag);
1105  CGF.FinishFunction();
1106
1107  return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
1108}
1109
1110llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T,
1111                                                    int Flag, unsigned Align) {
1112  // All alignments below that of pointer alignment collapse down to just
1113  // pointer alignment, as we always have at least that much alignment to begin
1114  // with.
1115  Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
1116
1117  // As an optimization, we only generate a single function of each kind we
1118  // might need.  We need a different one for each alignment and for each
1119  // setting of flags.  We mix Align and flag to get the kind.
1120  uint64_t Kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + Flag;
1121  llvm::Constant *&Entry = CGM.AssignCache[Kind];
1122  if (Entry)
1123    return Entry;
1124  return Entry = CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, Flag);
1125}
1126
1127llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T,
1128                                                       int Flag,
1129                                                       unsigned Align) {
1130  // All alignments below that of pointer alignment collpase down to just
1131  // pointer alignment, as we always have at least that much alignment to begin
1132  // with.
1133  Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
1134
1135  // As an optimization, we only generate a single function of each kind we
1136  // might need.  We need a different one for each alignment and for each
1137  // setting of flags.  We mix Align and flag to get the kind.
1138  uint64_t Kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + Flag;
1139  llvm::Constant *&Entry = CGM.DestroyCache[Kind];
1140  if (Entry)
1141    return Entry;
1142  return Entry=CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, Flag);
1143}
1144
1145llvm::Value *BlockFunction::getBlockObjectDispose() {
1146  if (CGM.BlockObjectDispose == 0) {
1147    const llvm::FunctionType *FTy;
1148    std::vector<const llvm::Type*> ArgTys;
1149    const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
1150    ArgTys.push_back(PtrToInt8Ty);
1151    ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
1152    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
1153    CGM.BlockObjectDispose
1154      = CGM.CreateRuntimeFunction(FTy, "_Block_object_dispose");
1155  }
1156  return CGM.BlockObjectDispose;
1157}
1158
1159llvm::Value *BlockFunction::getBlockObjectAssign() {
1160  if (CGM.BlockObjectAssign == 0) {
1161    const llvm::FunctionType *FTy;
1162    std::vector<const llvm::Type*> ArgTys;
1163    const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
1164    ArgTys.push_back(PtrToInt8Ty);
1165    ArgTys.push_back(PtrToInt8Ty);
1166    ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
1167    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
1168    CGM.BlockObjectAssign
1169      = CGM.CreateRuntimeFunction(FTy, "_Block_object_assign");
1170  }
1171  return CGM.BlockObjectAssign;
1172}
1173
1174void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) {
1175  llvm::Value *F = getBlockObjectDispose();
1176  llvm::Value *N;
1177  V = Builder.CreateBitCast(V, PtrToInt8Ty);
1178  N = llvm::ConstantInt::get(llvm::Type::getInt32Ty(V->getContext()), flag);
1179  Builder.CreateCall2(F, V, N);
1180}
1181
1182ASTContext &BlockFunction::getContext() const { return CGM.getContext(); }
1183
1184BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf,
1185                             CGBuilderTy &B)
1186  : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()), Builder(B) {
1187  PtrToInt8Ty = llvm::PointerType::getUnqual(
1188            llvm::Type::getInt8Ty(VMContext));
1189
1190  BlockHasCopyDispose = false;
1191}
1192