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