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