diff options
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
| -rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 162 | 
1 files changed, 104 insertions, 58 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 9815d1d4ef4d..969495376642 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -59,10 +59,10 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,                                              const CGBlockInfo &blockInfo) {    ASTContext &C = CGM.getContext(); -  const llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy); -  const llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); +  llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy); +  llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); -  llvm::SmallVector<llvm::Constant*, 6> elements; +  SmallVector<llvm::Constant*, 6> elements;    // reserved    elements.push_back(llvm::ConstantInt::get(ulong, 0)); @@ -243,7 +243,7 @@ static CharUnits getLowBit(CharUnits v) {  }  static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, -                             llvm::SmallVectorImpl<llvm::Type*> &elementTypes) { +                             SmallVectorImpl<llvm::Type*> &elementTypes) {    ASTContext &C = CGM.getContext();    // The header is basically a 'struct { void *; int; int; void *; void *; }'. @@ -280,7 +280,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) {    ASTContext &C = CGM.getContext();    const BlockDecl *block = info.getBlockDecl(); -  llvm::SmallVector<llvm::Type*, 8> elementTypes; +  SmallVector<llvm::Type*, 8> elementTypes;    initializeForBlockHeader(CGM, info, elementTypes);    if (!block->hasCaptures()) { @@ -291,7 +291,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) {    }    // Collect the layout chunks. -  llvm::SmallVector<BlockLayoutChunk, 16> layout; +  SmallVector<BlockLayoutChunk, 16> layout;    layout.reserve(block->capturesCXXThis() +                   (block->capture_end() - block->capture_begin())); @@ -422,7 +422,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) {    // which has 7 bytes of padding, as opposed to the naive solution    // which might have less (?).    if (endAlign < maxFieldAlign) { -    llvm::SmallVectorImpl<BlockLayoutChunk>::iterator +    SmallVectorImpl<BlockLayoutChunk>::iterator        li = layout.begin() + 1, le = layout.end();      // Look for something that the header end is already @@ -433,7 +433,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) {      // If we found something that's naturally aligned for the end of      // the header, keep adding things...      if (li != le) { -      llvm::SmallVectorImpl<BlockLayoutChunk>::iterator first = li; +      SmallVectorImpl<BlockLayoutChunk>::iterator first = li;        for (; li != le; ++li) {          assert(endAlign >= li->Alignment); @@ -468,7 +468,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) {    // Slam everything else on now.  This works because they have    // strictly decreasing alignment and we expect that size is always a    // multiple of alignment. -  for (llvm::SmallVectorImpl<BlockLayoutChunk>::iterator +  for (SmallVectorImpl<BlockLayoutChunk>::iterator           li = layout.begin(), le = layout.end(); li != le; ++li) {      assert(endAlign >= li->Alignment);      li->setIndex(info, elementTypes.size()); @@ -507,7 +507,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {    // Build the block descriptor.    llvm::Constant *descriptor = buildBlockDescriptor(CGM, blockInfo); -  const llvm::Type *intTy = ConvertType(getContext().IntTy); +  llvm::Type *intTy = ConvertType(getContext().IntTy);    llvm::AllocaInst *blockAddr =      CreateTempAlloca(blockInfo.StructureType, "block"); @@ -617,10 +617,9 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {        ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,                             declRef, VK_RValue);        EmitExprAsInit(&l2r, &blockFieldPseudoVar, -                     LValue::MakeAddr(blockField, type, -                                      getContext().getDeclAlign(variable) -                                                  .getQuantity(), -                                      getContext()), +                     MakeAddrLValue(blockField, type, +                                    getContext().getDeclAlign(variable) +                                                .getQuantity()),                       /*captured by init*/ false);      } @@ -681,8 +680,8 @@ llvm::Type *CodeGenModule::getBlockDescriptorType() {    //   const char *layout;      // reserved    // };    BlockDescriptorType = -    llvm::StructType::createNamed("struct.__block_descriptor", -                                  UnsignedLongTy, UnsignedLongTy, NULL); +    llvm::StructType::create("struct.__block_descriptor", +                             UnsignedLongTy, UnsignedLongTy, NULL);    // Now form a pointer to that.    BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType); @@ -703,13 +702,9 @@ llvm::Type *CodeGenModule::getGenericBlockLiteralType() {    //   struct __block_descriptor *__descriptor;    // };    GenericBlockLiteralType = -    llvm::StructType::createNamed("struct.__block_literal_generic", -                                  VoidPtrTy, -                                  IntTy, -                                  IntTy, -                                  VoidPtrTy, -                                  BlockDescPtrTy, -                                  NULL); +    llvm::StructType::create("struct.__block_literal_generic", +                             VoidPtrTy, IntTy, IntTy, VoidPtrTy, +                             BlockDescPtrTy, NULL);    return GenericBlockLiteralType;  } @@ -723,7 +718,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,    llvm::Value *Callee = EmitScalarExpr(E->getCallee());    // Get a pointer to the generic block literal. -  const llvm::Type *BlockLiteralTy = +  llvm::Type *BlockLiteralTy =      llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());    // Bitcast the callee to a block literal. @@ -731,9 +726,9 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,      Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");    // Get the function pointer from the literal. -  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); +  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3); -  BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy, "tmp"); +  BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy);    // Add the block literal.    CallArgList Args; @@ -746,20 +741,16 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,                 E->arg_begin(), E->arg_end());    // Load the function. -  llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp"); +  llvm::Value *Func = Builder.CreateLoad(FuncPtr);    const FunctionType *FuncTy = FnType->castAs<FunctionType>(); -  QualType ResultType = FuncTy->getResultType(); - -  const CGFunctionInfo &FnInfo = -    CGM.getTypes().getFunctionInfo(ResultType, Args, -                                   FuncTy->getExtInfo()); +  const CGFunctionInfo &FnInfo = CGM.getTypes().getFunctionInfo(Args, FuncTy);    // Cast the function pointer to the right type. -  const llvm::Type *BlockFTy = +  llvm::Type *BlockFTy =      CGM.getTypes().GetFunctionType(FnInfo, false); -  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); +  llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);    Func = Builder.CreateBitCast(Func, BlockFTyPtr);    // And call the block. @@ -783,7 +774,7 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,      // to byref*.      addr = Builder.CreateLoad(addr); -    const llvm::PointerType *byrefPointerType +    llvm::PointerType *byrefPointerType        = llvm::PointerType::get(BuildByRefType(variable), 0);      addr = Builder.CreateBitCast(addr, byrefPointerType,                                   "byref.addr"); @@ -863,7 +854,7 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,    literal->setAlignment(blockInfo.BlockAlign.getQuantity());    // Return a constant of the appropriately-casted type. -  const llvm::Type *requiredType = +  llvm::Type *requiredType =      CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType());    return llvm::ConstantExpr::getBitCast(literal, requiredType);  } @@ -918,7 +909,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,    if (CGM.ReturnTypeUsesSRet(fnInfo))      blockInfo.UsesStret = true; -  const llvm::FunctionType *fnLLVMType = +  llvm::FunctionType *fnLLVMType =      CGM.getTypes().GetFunctionType(fnInfo, fnType->isVariadic());    MangleBuffer name; @@ -1005,7 +996,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,      for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),             ce = blockDecl->capture_end(); ci != ce; ++ci) {        const VarDecl *variable = ci->getVariable(); -      DI->setLocation(variable->getLocation()); +      DI->EmitLocation(Builder, variable->getLocation());        const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);        if (capture.isConstant()) { @@ -1065,7 +1056,7 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {    // FIXME: it would be nice if these were mergeable with things with    // identical semantics. -  const llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false); +  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);    llvm::Function *Fn =      llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, @@ -1088,7 +1079,7 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {                                            true);    StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); -  const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); +  llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();    llvm::Value *src = GetAddrOfLocalVar(&srcDecl);    src = Builder.CreateLoad(src); @@ -1180,7 +1171,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {    // FIXME: We'd like to put these into a mergable by content, with    // internal linkage. -  const llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false); +  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);    llvm::Function *Fn =      llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, @@ -1201,7 +1192,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {                                            false, true);    StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); -  const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); +  llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();    llvm::Value *src = GetAddrOfLocalVar(&srcDecl);    src = Builder.CreateLoad(src); @@ -1399,7 +1390,7 @@ public:  static llvm::Constant *  generateByrefCopyHelper(CodeGenFunction &CGF, -                        const llvm::StructType &byrefType, +                        llvm::StructType &byrefType,                          CodeGenModule::ByrefHelpers &byrefInfo) {    ASTContext &Context = CGF.getContext(); @@ -1416,7 +1407,7 @@ generateByrefCopyHelper(CodeGenFunction &CGF,      CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo());    CodeGenTypes &Types = CGF.CGM.getTypes(); -  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); +  llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);    // FIXME: We'd like to put these into a mergable by content, with    // internal linkage. @@ -1438,7 +1429,7 @@ generateByrefCopyHelper(CodeGenFunction &CGF,    CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation());    if (byrefInfo.needsCopy()) { -    const llvm::Type *byrefPtrType = byrefType.getPointerTo(0); +    llvm::Type *byrefPtrType = byrefType.getPointerTo(0);      // dst->x      llvm::Value *destField = CGF.GetAddrOfLocalVar(&dst); @@ -1462,7 +1453,7 @@ generateByrefCopyHelper(CodeGenFunction &CGF,  /// Build the copy helper for a __block variable.  static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM, -                                            const llvm::StructType &byrefType, +                                            llvm::StructType &byrefType,                                              CodeGenModule::ByrefHelpers &info) {    CodeGenFunction CGF(CGM);    return generateByrefCopyHelper(CGF, byrefType, info); @@ -1471,7 +1462,7 @@ static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM,  /// Generate code for a __block variable's dispose helper.  static llvm::Constant *  generateByrefDisposeHelper(CodeGenFunction &CGF, -                           const llvm::StructType &byrefType, +                           llvm::StructType &byrefType,                             CodeGenModule::ByrefHelpers &byrefInfo) {    ASTContext &Context = CGF.getContext();    QualType R = Context.VoidTy; @@ -1484,7 +1475,7 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,      CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo());    CodeGenTypes &Types = CGF.CGM.getTypes(); -  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); +  llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);    // FIXME: We'd like to put these into a mergable by content, with    // internal linkage. @@ -1521,7 +1512,7 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,  /// Build the dispose helper for a __block variable.  static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM, -                                              const llvm::StructType &byrefType, +                                              llvm::StructType &byrefType,                                              CodeGenModule::ByrefHelpers &info) {    CodeGenFunction CGF(CGM);    return generateByrefDisposeHelper(CGF, byrefType, info); @@ -1529,7 +1520,7 @@ static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM,  ///   template <class T> static T *buildByrefHelpers(CodeGenModule &CGM, -                                               const llvm::StructType &byrefTy, +                                               llvm::StructType &byrefTy,                                                 T &byrefInfo) {    // Increase the field's alignment to be at least pointer alignment,    // since the layout of the byref struct will guarantee at least that. @@ -1553,7 +1544,7 @@ template <class T> static T *buildByrefHelpers(CodeGenModule &CGM,  }  CodeGenModule::ByrefHelpers * -CodeGenFunction::buildByrefHelpers(const llvm::StructType &byrefType, +CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,                                     const AutoVarEmission &emission) {    const VarDecl &var = *emission.Variable;    QualType type = var.getType(); @@ -1658,18 +1649,18 @@ llvm::Value *CodeGenFunction::BuildBlockByrefAddress(llvm::Value *BaseAddr,  ///        T x;  ///      } x  /// -const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { -  std::pair<const llvm::Type *, unsigned> &Info = ByRefValueInfo[D]; +llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { +  std::pair<llvm::Type *, unsigned> &Info = ByRefValueInfo[D];    if (Info.first)      return Info.first;    QualType Ty = D->getType(); -  llvm::SmallVector<llvm::Type *, 8> types; +  SmallVector<llvm::Type *, 8> types;    llvm::StructType *ByRefType = -    llvm::StructType::createNamed(getLLVMContext(), -                                "struct.__block_byref_" + D->getNameAsString()); +    llvm::StructType::create(getLLVMContext(), +                             "struct.__block_byref_" + D->getNameAsString());    // void *__isa;    types.push_back(Int8PtrTy); @@ -1742,7 +1733,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {    llvm::Value *addr = emission.Address;    // That's an alloca of the byref structure type. -  const llvm::StructType *byrefType = cast<llvm::StructType>( +  llvm::StructType *byrefType = cast<llvm::StructType>(                   cast<llvm::PointerType>(addr->getType())->getElementType());    // Build the byref helpers if necessary.  This is null if we don't need any. @@ -1812,8 +1803,63 @@ namespace {  /// to be done externally.  void CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) {    // We don't enter this cleanup if we're in pure-GC mode. -  if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) +  if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)      return;    EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, emission.Address);  } + +/// Adjust the declaration of something from the blocks API. +static void configureBlocksRuntimeObject(CodeGenModule &CGM, +                                         llvm::Constant *C) { +  if (!CGM.getLangOptions().BlocksRuntimeOptional) return; + +  llvm::GlobalValue *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); +  if (GV->isDeclaration() && +      GV->getLinkage() == llvm::GlobalValue::ExternalLinkage) +    GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); +} + +llvm::Constant *CodeGenModule::getBlockObjectDispose() { +  if (BlockObjectDispose) +    return BlockObjectDispose; + +  llvm::Type *args[] = { Int8PtrTy, Int32Ty }; +  llvm::FunctionType *fty +    = llvm::FunctionType::get(VoidTy, args, false); +  BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); +  configureBlocksRuntimeObject(*this, BlockObjectDispose); +  return BlockObjectDispose; +} + +llvm::Constant *CodeGenModule::getBlockObjectAssign() { +  if (BlockObjectAssign) +    return BlockObjectAssign; + +  llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; +  llvm::FunctionType *fty +    = llvm::FunctionType::get(VoidTy, args, false); +  BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); +  configureBlocksRuntimeObject(*this, BlockObjectAssign); +  return BlockObjectAssign; +} + +llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { +  if (NSConcreteGlobalBlock) +    return NSConcreteGlobalBlock; + +  NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", +                                                Int8PtrTy->getPointerTo(), 0); +  configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock); +  return NSConcreteGlobalBlock; +} + +llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { +  if (NSConcreteStackBlock) +    return NSConcreteStackBlock; + +  NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock", +                                               Int8PtrTy->getPointerTo(), 0); +  configureBlocksRuntimeObject(*this, NSConcreteStackBlock); +  return NSConcreteStackBlock;   +}  | 
