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