CGBlocks.cpp revision d5cab5435371b8cc74a9e05ebd40b5995ebad149
1acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
2acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//
3acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//                     The LLVM Compiler Infrastructure
4acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//
5acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// This file is distributed under the University of Illinois Open Source
6acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// License. See LICENSE.TXT for details.
7acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//
8acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===----------------------------------------------------------------------===//
9acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//
10acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// This contains code to emit blocks.
11acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//
12acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===----------------------------------------------------------------------===//
13acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
14acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "CodeGenFunction.h"
15acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "CodeGenModule.h"
16acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "llvm/Module.h"
17d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson#include "llvm/Target/TargetData.h"
18acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
19acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include <algorithm>
20acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
21acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace clang;
22acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace CodeGen;
23acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
24d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson// Block flags
25d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlssonenum {
26d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  IsGlobal = 1 << 28
27d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson};
28d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
29d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlssonstatic const llvm::Type *getBlockDescriptorType(CodeGenModule &CGM) {
30acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  static const llvm::Type *Ty = 0;
31acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
32acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  if (!Ty) {
33acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    const llvm::Type *UnsignedLongTy =
34d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson      CGM.getTypes().ConvertType(CGM.getContext().UnsignedLongTy);
35acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
36acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    // struct __block_descriptor {
37acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   unsigned long reserved;
38acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   unsigned long block_size;
39acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    // };
40acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Ty = llvm::StructType::get(UnsignedLongTy,
41acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               UnsignedLongTy,
42acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               NULL);
43acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
44d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    CGM.getModule().addTypeName("struct.__block_descriptor", Ty);
45acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  }
46acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
47acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  return Ty;
48acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson}
49acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
50d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlssonstatic const llvm::Type *getGenericBlockLiteralType(CodeGenModule &CGM) {
51acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  static const llvm::Type *Ty = 0;
52acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
53acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  if (!Ty) {
54acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    const llvm::Type *Int8PtrTy =
55acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
56acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
57acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    const llvm::Type *BlockDescPtrTy =
58d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson      llvm::PointerType::getUnqual(getBlockDescriptorType(CGM));
59acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
60acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    // struct __block_literal_generic {
61acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   void *isa;
62acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   int flags;
63acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   int reserved;
64acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   void (*invoke)(void *);
65acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    //   struct __block_descriptor *descriptor;
66acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    // };
67acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Ty = llvm::StructType::get(Int8PtrTy,
68acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               llvm::Type::Int32Ty,
69acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               llvm::Type::Int32Ty,
70acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               Int8PtrTy,
71acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               BlockDescPtrTy,
72acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                               NULL);
73acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
74d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    CGM.getModule().addTypeName("struct.__block_literal_generic", Ty);
75acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  }
76acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
77acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  return Ty;
78acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson}
79acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
80acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson/// getBlockFunctionType - Given a BlockPointerType, will return the
81acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson/// function type for the block, including the first block literal argument.
82acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonstatic QualType getBlockFunctionType(ASTContext &Ctx,
83d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                                     const BlockPointerType *BPT) {
84acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());
85acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
86acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  llvm::SmallVector<QualType, 8> Types;
87acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));
88acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
89acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
90acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson       e = FTy->arg_type_end(); i != e; ++i)
91acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Types.push_back(*i);
92acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
93acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  return Ctx.getFunctionType(FTy->getResultType(),
94acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                             &Types[0], Types.size(),
95acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                             FTy->isVariadic(), 0);
96acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson}
97acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
98d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders CarlssonRValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
99acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  const BlockPointerType *BPT =
100acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    E->getCallee()->getType()->getAsBlockPointerType();
101acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
102acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
103acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
104acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // Get a pointer to the generic block literal.
105acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  const llvm::Type *BlockLiteralTy =
106d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    llvm::PointerType::getUnqual(getGenericBlockLiteralType(CGM));
107acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
108acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // Bitcast the callee to a block literal.
109acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  llvm::Value *BlockLiteral =
110acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");
111acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
112acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // Get the function pointer from the literal.
113acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
114acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  llvm::Value *Func = Builder.CreateLoad(FuncPtr, FuncPtr, "tmp");
115acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
116acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // Cast the function pointer to the right type.
117acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  const llvm::Type *BlockFTy =
118acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    ConvertType(getBlockFunctionType(getContext(), BPT));
119acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
120acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  Func = Builder.CreateBitCast(Func, BlockFTyPtr);
121acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
122acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  BlockLiteral =
123acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Builder.CreateBitCast(BlockLiteral,
124acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
125acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                          "tmp");
126acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
127acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // Add the block literal.
128acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
129acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  CallArgList Args;
130acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));
131acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
132acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // And the rest of the arguments.
133acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
134acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson       i != e; ++i)
135acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
136acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                                  i->getType()));
137acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson
138acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  // And call the block.
139acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
140acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson                  Func, Args);
141acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson}
142d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
143d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlssonllvm::Constant *CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE) {
144d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  if (!NSConcreteGlobalBlock) {
145d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    const llvm::Type *Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
146d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
147d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    // FIXME: Wee should have a CodeGenModule::AddRuntimeVariable that does the
148d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    // same thing as CreateRuntimeFunction if there's already a variable with
149d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    // the same name.
150d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    NSConcreteGlobalBlock =
151d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson      new llvm::GlobalVariable(Ty, false,
152d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                              llvm::GlobalVariable::ExternalLinkage, 0,
153d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                              "_NSConcreteGlobalBlock", &getModule());
154d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  }
155d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
156d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Generate the block descriptor.
157d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
158d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
159d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Constant *DescriptorFields[2];
160d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
161d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Reserved
162d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);
163d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
164d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Block literal size. For global blocks we just use the size of the generic
165d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // block literal struct.
166d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  uint64_t BlockLiteralSize =
167d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType(*this)) / 8;
168d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);
169d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
170d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Constant *DescriptorStruct =
171d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    llvm::ConstantStruct::get(&DescriptorFields[0], 2);
172d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
173d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::GlobalVariable *Descriptor =
174d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
175d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             llvm::GlobalVariable::InternalLinkage,
176d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             DescriptorStruct, "__block_descriptor_global",
177d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             &getModule());
178d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
179d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Generate the constants for the block literal.
180d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Constant *LiteralFields[5];
181d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
182d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  CodeGenFunction::BlockInfo Info(0, "global");
183d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info);
184d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
185d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // isa
186d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  LiteralFields[0] = NSConcreteGlobalBlock;
187d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
188d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Flags
189d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  LiteralFields[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, IsGlobal);
190d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
191d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Reserved
192d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  LiteralFields[2] = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
193d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
194d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Function
195d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  LiteralFields[3] = Fn;
196d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
197d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // Descriptor
198d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  LiteralFields[4] = Descriptor;
199d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
200d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Constant *BlockLiteralStruct =
201d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    llvm::ConstantStruct::get(&LiteralFields[0], 5);
202d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
203d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::GlobalVariable *BlockLiteral =
204d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
205d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             llvm::GlobalVariable::InternalLinkage,
206d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             BlockLiteralStruct, "__block_literal_global",
207d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                             &getModule());
208d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
209d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  return BlockLiteral;
210d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson}
211d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
212d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlssonllvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
213d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                                                       const BlockInfo& Info)
214d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson{
215d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  const FunctionTypeProto *FTy =
216d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    cast<FunctionTypeProto>(Expr->getFunctionType());
217d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
218d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  FunctionArgList Args;
219d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
220d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  const BlockDecl *BD = Expr->getBlockDecl();
221d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
222d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  // FIXME: This leaks
223d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  ImplicitParamDecl *SelfDecl =
224d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    ImplicitParamDecl::Create(getContext(), 0,
225d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                              SourceLocation(), 0,
226d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                              getContext().getPointerType(getContext().VoidTy));
227d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
228d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
229d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
230d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  for (BlockDecl::param_iterator i = BD->param_begin(),
231d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson       e = BD->param_end(); i != e; ++i)
232d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    Args.push_back(std::make_pair(*e, (*e)->getType()));
233d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
234d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  const CGFunctionInfo &FI =
235d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);
236d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
237d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  std::string Name = std::string("__block_function_") + Info.NameSuffix;
238d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
239d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  CodeGenTypes &Types = CGM.getTypes();
240d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());
241d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
242d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  llvm::Function *Fn =
243d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
244d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                           Name,
245d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                           &CGM.getModule());
246d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
247d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  StartFunction(BD, FTy->getResultType(), Fn, Args,
248d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson                Expr->getBody()->getLocEnd());
249d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  EmitStmt(Expr->getBody());
250d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());
251d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
252d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson  return Fn;
253d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson}
254d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
255d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson
256