Deleted Added
full compact
CGBlocks.cpp (207632) CGBlocks.cpp (208600)
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//===----------------------------------------------------------------------===//

--- 10 unchanged lines hidden (view full) ---

19#include "llvm/Module.h"
20#include "llvm/ADT/SmallSet.h"
21#include "llvm/Target/TargetData.h"
22#include <algorithm>
23
24using namespace clang;
25using namespace CodeGen;
26
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//===----------------------------------------------------------------------===//

--- 10 unchanged lines hidden (view full) ---

19#include "llvm/Module.h"
20#include "llvm/ADT/SmallSet.h"
21#include "llvm/Target/TargetData.h"
22#include <algorithm>
23
24using namespace clang;
25using namespace CodeGen;
26
27/// CGBlockInfo - Information to generate a block literal.
28class clang::CodeGen::CGBlockInfo {
29public:
30 /// Name - The name of the block, kindof.
31 const char *Name;
32
33 /// DeclRefs - Variables from parent scopes that have been
34 /// imported into this block.
35 llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
36
37 /// InnerBlocks - This block and the blocks it encloses.
38 llvm::SmallPtrSet<const DeclContext *, 4> InnerBlocks;
39
40 /// CXXThisRef - Non-null if 'this' was required somewhere, in
41 /// which case this is that expression.
42 const CXXThisExpr *CXXThisRef;
43
44 /// NeedsObjCSelf - True if something in this block has an implicit
45 /// reference to 'self'.
46 bool NeedsObjCSelf;
47
48 /// These are initialized by GenerateBlockFunction.
49 bool BlockHasCopyDispose;
50 CharUnits BlockSize;
51 CharUnits BlockAlign;
52 llvm::SmallVector<const Expr*, 8> BlockLayout;
53
54 CGBlockInfo(const char *Name);
55};
56
57CGBlockInfo::CGBlockInfo(const char *N)
58 : Name(N), CXXThisRef(0), NeedsObjCSelf(false) {
59
60 // Skip asm prefix, if any.
61 if (Name && Name[0] == '\01')
62 ++Name;
63}
64
65
27llvm::Constant *CodeGenFunction::
28BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
29 const llvm::StructType* Ty,
30 std::vector<HelperInfo> *NoteForHelper) {
31 const llvm::Type *UnsignedLongTy
32 = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
33 llvm::Constant *C;
34 std::vector<llvm::Constant*> Elts;

--- 46 unchanged lines hidden (view full) ---

81
82llvm::Constant *BlockModule::getNSConcreteStackBlock() {
83 if (NSConcreteStackBlock == 0)
84 NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
85 "_NSConcreteStackBlock");
86 return NSConcreteStackBlock;
87}
88
66llvm::Constant *CodeGenFunction::
67BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
68 const llvm::StructType* Ty,
69 std::vector<HelperInfo> *NoteForHelper) {
70 const llvm::Type *UnsignedLongTy
71 = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
72 llvm::Constant *C;
73 std::vector<llvm::Constant*> Elts;

--- 46 unchanged lines hidden (view full) ---

120
121llvm::Constant *BlockModule::getNSConcreteStackBlock() {
122 if (NSConcreteStackBlock == 0)
123 NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty,
124 "_NSConcreteStackBlock");
125 return NSConcreteStackBlock;
126}
127
89static void CollectBlockDeclRefInfo(
90 const Stmt *S, CodeGenFunction::BlockInfo &Info,
91 llvm::SmallSet<const DeclContext *, 16> &InnerContexts) {
128static void CollectBlockDeclRefInfo(const Stmt *S, CGBlockInfo &Info) {
92 for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
93 I != E; ++I)
94 if (*I)
129 for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
130 I != E; ++I)
131 if (*I)
95 CollectBlockDeclRefInfo(*I, Info, InnerContexts);
132 CollectBlockDeclRefInfo(*I, Info);
96
97 // We want to ensure we walk down into block literals so we can find
98 // all nested BlockDeclRefExprs.
99 if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
133
134 // We want to ensure we walk down into block literals so we can find
135 // all nested BlockDeclRefExprs.
136 if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
100 InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl()));
101 CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
137 Info.InnerBlocks.insert(BE->getBlockDecl());
138 CollectBlockDeclRefInfo(BE->getBody(), Info);
102 }
103
139 }
140
104 if (const BlockDeclRefExpr *BDRE = dyn_cast(S)) {
141 else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
142 const ValueDecl *D = BDRE->getDecl();
105 // FIXME: Handle enums.
143 // FIXME: Handle enums.
106 if (isa<FunctionDecl>(BDRE->getDecl()))
144 if (isa<FunctionDecl>(D))
107 return;
108
145 return;
146
147 if (isa<ImplicitParamDecl>(D) &&
148 isa<ObjCMethodDecl>(D->getDeclContext()) &&
149 cast<ObjCMethodDecl>(D->getDeclContext())->getSelfDecl() == D) {
150 Info.NeedsObjCSelf = true;
151 return;
152 }
153
109 // Only Decls that escape are added.
154 // Only Decls that escape are added.
110 if (!InnerContexts.count(BDRE->getDecl()->getDeclContext()))
155 if (!Info.InnerBlocks.count(D->getDeclContext()))
111 Info.DeclRefs.push_back(BDRE);
112 }
156 Info.DeclRefs.push_back(BDRE);
157 }
158
159 // Make sure to capture implicit 'self' references due to super calls.
160 else if (const ObjCMessageExpr *E = dyn_cast<ObjCMessageExpr>(S)) {
161 if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
162 E->getReceiverKind() == ObjCMessageExpr::SuperInstance)
163 Info.NeedsObjCSelf = true;
164 }
165
166 // Getter/setter uses may also cause implicit super references,
167 // which we can check for with:
168 else if (isa<ObjCSuperExpr>(S))
169 Info.NeedsObjCSelf = true;
170
171 else if (isa<CXXThisExpr>(S))
172 Info.CXXThisRef = cast<CXXThisExpr>(S);
113}
114
173}
174
115/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
175/// CanBlockBeGlobal - Given a CGBlockInfo struct, determines if a block can be
116/// declared as a global variable instead of on the stack.
176/// declared as a global variable instead of on the stack.
117static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
177static bool CanBlockBeGlobal(const CGBlockInfo &Info) {
118 return Info.DeclRefs.empty();
119}
120
121/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
122/// ensure we can generate the debug information for the parameter for the block
123/// invoke function.
178 return Info.DeclRefs.empty();
179}
180
181/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
182/// ensure we can generate the debug information for the parameter for the block
183/// invoke function.
124static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info,
125 CodeGenFunction *CGF) {
126 // FIXME: Also always forward the this pointer in C++ as well.
184static void AllocateAllBlockDeclRefs(CodeGenFunction &CGF, CGBlockInfo &Info) {
185 if (Info.CXXThisRef)
186 CGF.AllocateBlockCXXThisPointer(Info.CXXThisRef);
127
128 for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
187
188 for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
129 CGF->AllocateBlockDecl(Info.DeclRefs[i]);
189 CGF.AllocateBlockDecl(Info.DeclRefs[i]);
190
191 if (Info.NeedsObjCSelf) {
192 ValueDecl *Self = cast<ObjCMethodDecl>(CGF.CurFuncDecl)->getSelfDecl();
193 BlockDeclRefExpr *BDRE =
194 new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(),
195 SourceLocation(), false);
196 Info.DeclRefs.push_back(BDRE);
197 CGF.AllocateBlockDecl(BDRE);
198 }
130}
131
132// FIXME: Push most into CGM, passing down a few bits, like current function
133// name.
134llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
199}
200
201// FIXME: Push most into CGM, passing down a few bits, like current function
202// name.
203llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
135
136 std::string Name = CurFn->getName();
204 std::string Name = CurFn->getName();
137 CodeGenFunction::BlockInfo Info(0, Name.c_str());
138 llvm::SmallSet<const DeclContext *, 16> InnerContexts;
139 InnerContexts.insert(BE->getBlockDecl());
140 CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);
205 CGBlockInfo Info(Name.c_str());
206 Info.InnerBlocks.insert(BE->getBlockDecl());
207 CollectBlockDeclRefInfo(BE->getBody(), Info);
141
142 // Check if the block can be global.
143 // FIXME: This test doesn't work for nested blocks yet. Longer term, I'd like
144 // to just have one code path. We should move this function into CGM and pass
145 // CGF, then we can just check to see if CGF is 0.
146 if (0 && CanBlockBeGlobal(Info))
147 return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
148

--- 6 unchanged lines hidden (view full) ---

155
156 {
157 // C = BuildBlockStructInitlist();
158 unsigned int flags = BLOCK_HAS_SIGNATURE;
159
160 // We run this first so that we set BlockHasCopyDispose from the entire
161 // block literal.
162 // __invoke
208
209 // Check if the block can be global.
210 // FIXME: This test doesn't work for nested blocks yet. Longer term, I'd like
211 // to just have one code path. We should move this function into CGM and pass
212 // CGF, then we can just check to see if CGF is 0.
213 if (0 && CanBlockBeGlobal(Info))
214 return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
215

--- 6 unchanged lines hidden (view full) ---

222
223 {
224 // C = BuildBlockStructInitlist();
225 unsigned int flags = BLOCK_HAS_SIGNATURE;
226
227 // We run this first so that we set BlockHasCopyDispose from the entire
228 // block literal.
229 // __invoke
163 CharUnits subBlockSize;
164 CharUnits subBlockAlign;
165 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
166 bool subBlockHasCopyDispose = false;
167 llvm::Function *Fn
168 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl,
230 llvm::Function *Fn
231 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl,
169 LocalDeclMap,
170 subBlockSize,
171 subBlockAlign,
172 subBlockDeclRefDecls,
173 subBlockHasCopyDispose);
174 BlockHasCopyDispose |= subBlockHasCopyDispose;
232 LocalDeclMap);
233 BlockHasCopyDispose |= Info.BlockHasCopyDispose;
175 Elts[3] = Fn;
176
177 // FIXME: Don't use BlockHasCopyDispose, it is set more often then
178 // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); }
234 Elts[3] = Fn;
235
236 // FIXME: Don't use BlockHasCopyDispose, it is set more often then
237 // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); }
179 if (subBlockHasCopyDispose)
238 if (Info.BlockHasCopyDispose)
180 flags |= BLOCK_HAS_COPY_DISPOSE;
181
182 // __isa
183 C = CGM.getNSConcreteStackBlock();
184 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
185 Elts[0] = C;
186
187 // __flags

--- 13 unchanged lines hidden (view full) ---

201 CGM.getTypes().ConvertType(CGM.getContext().IntTy));
202 C = llvm::ConstantInt::get(IntTy, flags);
203 Elts[1] = C;
204
205 // __reserved
206 C = llvm::ConstantInt::get(IntTy, 0);
207 Elts[2] = C;
208
239 flags |= BLOCK_HAS_COPY_DISPOSE;
240
241 // __isa
242 C = CGM.getNSConcreteStackBlock();
243 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
244 Elts[0] = C;
245
246 // __flags

--- 13 unchanged lines hidden (view full) ---

260 CGM.getTypes().ConvertType(CGM.getContext().IntTy));
261 C = llvm::ConstantInt::get(IntTy, flags);
262 Elts[1] = C;
263
264 // __reserved
265 C = llvm::ConstantInt::get(IntTy, 0);
266 Elts[2] = C;
267
209 if (subBlockDeclRefDecls.size() == 0) {
268 if (Info.BlockLayout.empty()) {
210 // __descriptor
269 // __descriptor
211 Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize,
212 0, 0);
270 Elts[4] = BuildDescriptorBlockDecl(BE, Info.BlockHasCopyDispose,
271 Info.BlockSize, 0, 0);
213
214 // Optimize to being a global block.
215 Elts[0] = CGM.getNSConcreteGlobalBlock();
216
217 Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL);
218
219 C = llvm::ConstantStruct::get(VMContext, Elts, false);
220
221 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
222 llvm::GlobalValue::InternalLinkage, C,
223 "__block_holder_tmp_" +
224 llvm::Twine(CGM.getGlobalUniqueCount()));
225 QualType BPT = BE->getType();
226 C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
227 return C;
228 }
229
272
273 // Optimize to being a global block.
274 Elts[0] = CGM.getNSConcreteGlobalBlock();
275
276 Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL);
277
278 C = llvm::ConstantStruct::get(VMContext, Elts, false);
279
280 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
281 llvm::GlobalValue::InternalLinkage, C,
282 "__block_holder_tmp_" +
283 llvm::Twine(CGM.getGlobalUniqueCount()));
284 QualType BPT = BE->getType();
285 C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
286 return C;
287 }
288
230 std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size());
289 std::vector<const llvm::Type *> Types(BlockFields+Info.BlockLayout.size());
231 for (int i=0; i<4; ++i)
232 Types[i] = Elts[i]->getType();
233 Types[4] = PtrToInt8Ty;
234
290 for (int i=0; i<4; ++i)
291 Types[i] = Elts[i]->getType();
292 Types[4] = PtrToInt8Ty;
293
235 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) {
236 const Expr *E = subBlockDeclRefDecls[i];
294 for (unsigned i = 0, n = Info.BlockLayout.size(); i != n; ++i) {
295 const Expr *E = Info.BlockLayout[i];
237 const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
238 QualType Ty = E->getType();
239 if (BDRE && BDRE->isByRef()) {
240 Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
241 } else
242 Types[i+BlockFields] = ConvertType(Ty);
243 }
244
245 llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true);
246
247 llvm::AllocaInst *A = CreateTempAlloca(Ty);
296 const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
297 QualType Ty = E->getType();
298 if (BDRE && BDRE->isByRef()) {
299 Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
300 } else
301 Types[i+BlockFields] = ConvertType(Ty);
302 }
303
304 llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true);
305
306 llvm::AllocaInst *A = CreateTempAlloca(Ty);
248 A->setAlignment(subBlockAlign.getQuantity());
307 A->setAlignment(Info.BlockAlign.getQuantity());
249 V = A;
250
308 V = A;
309
251 std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size());
252 int helpersize = 0;
310 // Build layout / cleanup information for all the data entries in the
311 // layout, and write the enclosing fields into the type.
312 std::vector<HelperInfo> NoteForHelper(Info.BlockLayout.size());
313 unsigned NumHelpers = 0;
253
254 for (unsigned i=0; i<4; ++i)
255 Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
256
314
315 for (unsigned i=0; i<4; ++i)
316 Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
317
257 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i)
258 {
259 // FIXME: Push const down.
260 Expr *E = const_cast<Expr*>(subBlockDeclRefDecls[i]);
261 DeclRefExpr *DR;
262 ValueDecl *VD;
318 for (unsigned i=0; i < Info.BlockLayout.size(); ++i) {
319 const Expr *E = Info.BlockLayout[i];
263
320
264 DR = dyn_cast<DeclRefExpr>(E);
265 // Skip padding.
266 if (DR) continue;
321 // Skip padding.
322 if (isa<DeclRefExpr>(E)) continue;
267
323
268 BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
269 VD = BDRE->getDecl();
324 llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp");
325 HelperInfo &Note = NoteForHelper[NumHelpers++];
270
326
271 llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp");
272 NoteForHelper[helpersize].index = i+5;
273 NoteForHelper[helpersize].RequiresCopying
274 = BlockRequiresCopying(VD->getType());
275 NoteForHelper[helpersize].flag
276 = (VD->getType()->isBlockPointerType()
277 ? BLOCK_FIELD_IS_BLOCK
278 : BLOCK_FIELD_IS_OBJECT);
327 Note.index = i+5;
279
328
280 if (LocalDeclMap[VD]) {
281 if (BDRE->isByRef()) {
282 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
283 // FIXME: Someone double check this.
284 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
285 llvm::Value *Loc = LocalDeclMap[VD];
286 Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
287 Loc = Builder.CreateLoad(Loc);
288 Builder.CreateStore(Loc, Addr);
289 ++helpersize;
290 continue;
291 } else
292 E = new (getContext()) DeclRefExpr (VD,
293 VD->getType(),
294 SourceLocation());
295 }
296 if (BDRE->isByRef()) {
297 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
298 // FIXME: Someone double check this.
299 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0);
300 E = new (getContext())
301 UnaryOperator(E, UnaryOperator::AddrOf,
302 getContext().getPointerType(E->getType()),
303 SourceLocation());
304 }
305 ++helpersize;
329 if (isa<CXXThisExpr>(E)) {
330 Note.RequiresCopying = false;
331 Note.flag = BLOCK_FIELD_IS_OBJECT;
306
332
307 RValue r = EmitAnyExpr(E, Addr, false);
308 if (r.isScalar()) {
309 llvm::Value *Loc = r.getScalarVal();
310 const llvm::Type *Ty = Types[i+BlockFields];
311 if (BDRE->isByRef()) {
312 // E is now the address of the value field, instead, we want the
313 // address of the actual ByRef struct. We optimize this slightly
314 // compared to gcc by not grabbing the forwarding slot as this must
315 // be done during Block_copy for us, and we can postpone the work
316 // until then.
317 CharUnits offset = BlockDecls[BDRE->getDecl()];
333 Builder.CreateStore(LoadCXXThis(), Addr);
334 continue;
335 }
318
336
319 llvm::Value *BlockLiteral = LoadBlockStruct();
337 const BlockDeclRefExpr *BDRE = cast<BlockDeclRefExpr>(E);
338 const ValueDecl *VD = BDRE->getDecl();
339 QualType T = VD->getType();
320
340
321 Loc = Builder.CreateGEP(BlockLiteral,
322 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
323 offset.getQuantity()),
324 "block.literal");
325 Ty = llvm::PointerType::get(Ty, 0);
326 Loc = Builder.CreateBitCast(Loc, Ty);
327 Loc = Builder.CreateLoad(Loc);
328 // Loc = Builder.CreateBitCast(Loc, Ty);
329 }
341 Note.RequiresCopying = BlockRequiresCopying(T);
342
343 if (BDRE->isByRef()) {
344 Note.flag = BLOCK_FIELD_IS_BYREF;
345 if (T.isObjCGCWeak())
346 Note.flag |= BLOCK_FIELD_IS_WEAK;
347 } else if (T->isBlockPointerType()) {
348 Note.flag = BLOCK_FIELD_IS_BLOCK;
349 } else {
350 Note.flag = BLOCK_FIELD_IS_OBJECT;
351 }
352
353 if (LocalDeclMap[VD]) {
354 if (BDRE->isByRef()) {
355 llvm::Value *Loc = LocalDeclMap[VD];
356 Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
357 Loc = Builder.CreateLoad(Loc);
330 Builder.CreateStore(Loc, Addr);
358 Builder.CreateStore(Loc, Addr);
331 } else if (r.isComplex())
332 // FIXME: implement
333 ErrorUnsupported(BE, "complex in block literal");
334 else if (r.isAggregate())
335 ; // Already created into the destination
336 else
337 assert (0 && "bad block variable");
338 // FIXME: Ensure that the offset created by the backend for
339 // the struct matches the previously computed offset in BlockDecls.
359 continue;
360 } else {
361 E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
362 VD->getType(),
363 SourceLocation());
364 }
340 }
365 }
341 NoteForHelper.resize(helpersize);
342
366
367 if (BDRE->isByRef()) {
368 E = new (getContext())
369 UnaryOperator(const_cast<Expr*>(E), UnaryOperator::AddrOf,
370 getContext().getPointerType(E->getType()),
371 SourceLocation());
372 }
373
374 RValue r = EmitAnyExpr(E, Addr, false);
375 if (r.isScalar()) {
376 llvm::Value *Loc = r.getScalarVal();
377 const llvm::Type *Ty = Types[i+BlockFields];
378 if (BDRE->isByRef()) {
379 // E is now the address of the value field, instead, we want the
380 // address of the actual ByRef struct. We optimize this slightly
381 // compared to gcc by not grabbing the forwarding slot as this must
382 // be done during Block_copy for us, and we can postpone the work
383 // until then.
384 CharUnits offset = BlockDecls[BDRE->getDecl()];
385
386 llvm::Value *BlockLiteral = LoadBlockStruct();
387
388 Loc = Builder.CreateGEP(BlockLiteral,
389 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
390 offset.getQuantity()),
391 "block.literal");
392 Ty = llvm::PointerType::get(Ty, 0);
393 Loc = Builder.CreateBitCast(Loc, Ty);
394 Loc = Builder.CreateLoad(Loc);
395 // Loc = Builder.CreateBitCast(Loc, Ty);
396 }
397 Builder.CreateStore(Loc, Addr);
398 } else if (r.isComplex())
399 // FIXME: implement
400 ErrorUnsupported(BE, "complex in block literal");
401 else if (r.isAggregate())
402 ; // Already created into the destination
403 else
404 assert (0 && "bad block variable");
405 // FIXME: Ensure that the offset created by the backend for
406 // the struct matches the previously computed offset in BlockDecls.
407 }
408 NoteForHelper.resize(NumHelpers);
409
343 // __descriptor
344 llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
410 // __descriptor
411 llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
345 subBlockHasCopyDispose,
346 subBlockSize, Ty,
412 Info.BlockHasCopyDispose,
413 Info.BlockSize, Ty,
347 &NoteForHelper);
348 Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
349 Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
350 }
351
352 QualType BPT = BE->getType();
353 V = Builder.CreateBitCast(V, ConvertType(BPT));
354 // See if this is a __weak block variable and the must call objc_read_weak

--- 127 unchanged lines hidden (view full) ---

482
483 const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
484 Func = Builder.CreateBitCast(Func, BlockFTyPtr);
485
486 // And call the block.
487 return EmitCall(FnInfo, Func, ReturnValue, Args);
488}
489
414 &NoteForHelper);
415 Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
416 Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
417 }
418
419 QualType BPT = BE->getType();
420 V = Builder.CreateBitCast(V, ConvertType(BPT));
421 // See if this is a __weak block variable and the must call objc_read_weak

--- 127 unchanged lines hidden (view full) ---

549
550 const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
551 Func = Builder.CreateBitCast(Func, BlockFTyPtr);
552
553 // And call the block.
554 return EmitCall(FnInfo, Func, ReturnValue, Args);
555}
556
490CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
557void CodeGenFunction::AllocateBlockCXXThisPointer(const CXXThisExpr *E) {
558 assert(BlockCXXThisOffset.isZero() && "already computed 'this' pointer");
559
560 // Figure out what the offset is.
561 QualType T = E->getType();
562 std::pair<CharUnits,CharUnits> TypeInfo = getContext().getTypeInfoInChars(T);
563 CharUnits Offset = getBlockOffset(TypeInfo.first, TypeInfo.second);
564
565 BlockCXXThisOffset = Offset;
566 BlockLayout.push_back(E);
567}
568
569void CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
491 const ValueDecl *VD = E->getDecl();
570 const ValueDecl *VD = E->getDecl();
492 CharUnits &offset = BlockDecls[VD];
571 CharUnits &Offset = BlockDecls[VD];
493
494 // See if we have already allocated an offset for this variable.
572
573 // See if we have already allocated an offset for this variable.
495 if (offset.isPositive())
496 return offset;
574 if (!Offset.isZero())
575 return;
497
498 // Don't run the expensive check, unless we have to.
499 if (!BlockHasCopyDispose)
500 if (E->isByRef()
501 || BlockRequiresCopying(E->getType()))
502 BlockHasCopyDispose = true;
503
576
577 // Don't run the expensive check, unless we have to.
578 if (!BlockHasCopyDispose)
579 if (E->isByRef()
580 || BlockRequiresCopying(E->getType()))
581 BlockHasCopyDispose = true;
582
504 // if not, allocate one now.
505 offset = getBlockOffset(E);
583 const ValueDecl *D = cast<ValueDecl>(E->getDecl());
506
584
507 return offset;
585 CharUnits Size;
586 CharUnits Align;
587
588 if (E->isByRef()) {
589 llvm::tie(Size,Align) =
590 getContext().getTypeInfoInChars(getContext().VoidPtrTy);
591 } else {
592 Size = getContext().getTypeSizeInChars(D->getType());
593 Align = getContext().getDeclAlign(D);
594 }
595
596 Offset = getBlockOffset(Size, Align);
597 BlockLayout.push_back(E);
508}
509
598}
599
510llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
511 const ValueDecl *VD = E->getDecl();
512 CharUnits offset = AllocateBlockDecl(E);
513
600llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const ValueDecl *VD,
601 bool IsByRef) {
602 CharUnits offset = BlockDecls[VD];
603 assert(!offset.isZero() && "getting address of unallocated decl");
514
515 llvm::Value *BlockLiteral = LoadBlockStruct();
516 llvm::Value *V = Builder.CreateGEP(BlockLiteral,
517 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
518 offset.getQuantity()),
519 "block.literal");
604
605 llvm::Value *BlockLiteral = LoadBlockStruct();
606 llvm::Value *V = Builder.CreateGEP(BlockLiteral,
607 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
608 offset.getQuantity()),
609 "block.literal");
520 if (E->isByRef()) {
610 if (IsByRef) {
521 const llvm::Type *PtrStructTy
522 = llvm::PointerType::get(BuildByRefType(VD), 0);
523 // The block literal will need a copy/destroy helper.
524 BlockHasCopyDispose = true;
525
526 const llvm::Type *Ty = PtrStructTy;
527 Ty = llvm::PointerType::get(Ty, 0);
528 V = Builder.CreateBitCast(V, Ty);

--- 9 unchanged lines hidden (view full) ---

538 const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
539
540 Ty = llvm::PointerType::get(Ty, 0);
541 V = Builder.CreateBitCast(V, Ty);
542 }
543 return V;
544}
545
611 const llvm::Type *PtrStructTy
612 = llvm::PointerType::get(BuildByRefType(VD), 0);
613 // The block literal will need a copy/destroy helper.
614 BlockHasCopyDispose = true;
615
616 const llvm::Type *Ty = PtrStructTy;
617 Ty = llvm::PointerType::get(Ty, 0);
618 V = Builder.CreateBitCast(V, Ty);

--- 9 unchanged lines hidden (view full) ---

628 const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
629
630 Ty = llvm::PointerType::get(Ty, 0);
631 V = Builder.CreateBitCast(V, Ty);
632 }
633 return V;
634}
635
546void CodeGenFunction::BlockForwardSelf() {
547 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
548 ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
549 llvm::Value *&DMEntry = LocalDeclMap[SelfDecl];
550 if (DMEntry)
551 return;
552 // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care
553 BlockDeclRefExpr *BDRE = new (getContext())
554 BlockDeclRefExpr(SelfDecl,
555 SelfDecl->getType(), SourceLocation(), false);
556 DMEntry = GetAddrOfBlockDecl(BDRE);
557}
558
559llvm::Constant *
560BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
561 // Generate the block descriptor.
562 const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
563 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
564 getTypes().ConvertType(getContext().IntTy));
565
566 llvm::Constant *DescriptorFields[4];

--- 28 unchanged lines hidden (view full) ---

595 llvm::GlobalVariable::InternalLinkage,
596 DescriptorStruct, "__block_descriptor_global");
597
598 int FieldCount = 5;
599 // Generate the constants for the block literal.
600
601 std::vector<llvm::Constant*> LiteralFields(FieldCount);
602
636llvm::Constant *
637BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
638 // Generate the block descriptor.
639 const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
640 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
641 getTypes().ConvertType(getContext().IntTy));
642
643 llvm::Constant *DescriptorFields[4];

--- 28 unchanged lines hidden (view full) ---

672 llvm::GlobalVariable::InternalLinkage,
673 DescriptorStruct, "__block_descriptor_global");
674
675 int FieldCount = 5;
676 // Generate the constants for the block literal.
677
678 std::vector<llvm::Constant*> LiteralFields(FieldCount);
679
603 CodeGenFunction::BlockInfo Info(0, n);
604 CharUnits subBlockSize;
605 CharUnits subBlockAlign;
606 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
607 bool subBlockHasCopyDispose = false;
680 CGBlockInfo Info(n);
608 llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
609 llvm::Function *Fn
681 llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
682 llvm::Function *Fn
610 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap,
611 subBlockSize,
612 subBlockAlign,
613 subBlockDeclRefDecls,
614 subBlockHasCopyDispose);
615 assert(subBlockSize == BlockLiteralSize
683 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap);
684 assert(Info.BlockSize == BlockLiteralSize
616 && "no imports allowed for global block");
617
618 // isa
619 LiteralFields[0] = getNSConcreteGlobalBlock();
620
621 // Flags
622 LiteralFields[1] =
623 llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);

--- 22 unchanged lines hidden (view full) ---

646 llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()],
647 "self");
648 // For now, we codegen based upon byte offsets.
649 return Builder.CreateBitCast(V, PtrToInt8Ty);
650}
651
652llvm::Function *
653CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
685 && "no imports allowed for global block");
686
687 // isa
688 LiteralFields[0] = getNSConcreteGlobalBlock();
689
690 // Flags
691 LiteralFields[1] =
692 llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);

--- 22 unchanged lines hidden (view full) ---

715 llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()],
716 "self");
717 // For now, we codegen based upon byte offsets.
718 return Builder.CreateBitCast(V, PtrToInt8Ty);
719}
720
721llvm::Function *
722CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
654 const BlockInfo& Info,
723 CGBlockInfo &Info,
655 const Decl *OuterFuncDecl,
724 const Decl *OuterFuncDecl,
656 llvm::DenseMap<const Decl*, llvm::Value*> ldm,
657 CharUnits &Size,
658 CharUnits &Align,
659 llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
660 bool &subBlockHasCopyDispose) {
725 llvm::DenseMap<const Decl*, llvm::Value*> ldm) {
661
662 // Check if we should generate debug info for this block.
663 if (CGM.getDebugInfo())
664 DebugInfo = CGM.getDebugInfo();
665
666 // Arrange for local static and local extern declarations to appear
667 // to be local to this function as well, as they are directly referenced
668 // in a block.

--- 27 unchanged lines hidden (view full) ---

696 FunctionArgList Args;
697
698 CurFuncDecl = OuterFuncDecl;
699
700 const BlockDecl *BD = BExpr->getBlockDecl();
701
702 IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
703
726
727 // Check if we should generate debug info for this block.
728 if (CGM.getDebugInfo())
729 DebugInfo = CGM.getDebugInfo();
730
731 // Arrange for local static and local extern declarations to appear
732 // to be local to this function as well, as they are directly referenced
733 // in a block.

--- 27 unchanged lines hidden (view full) ---

761 FunctionArgList Args;
762
763 CurFuncDecl = OuterFuncDecl;
764
765 const BlockDecl *BD = BExpr->getBlockDecl();
766
767 IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
768
704 // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below.
705 AllocateAllBlockDeclRefs(Info, this);
769 // Build the block struct now.
770 AllocateAllBlockDeclRefs(*this, Info);
706
707 QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
771
772 QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
708 BlockDeclRefDecls);
773 BlockLayout);
774
709 // FIXME: This leaks
710 ImplicitParamDecl *SelfDecl =
711 ImplicitParamDecl::Create(getContext(), const_cast<BlockDecl*>(BD),
712 SourceLocation(), II,
713 ParmTy);
714
715 Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
716 BlockStructDecl = SelfDecl;
717
718 for (BlockDecl::param_const_iterator i = BD->param_begin(),
719 e = BD->param_end(); i != e; ++i)
720 Args.push_back(std::make_pair(*i, (*i)->getType()));
721
722 const CGFunctionInfo &FI =
723 CGM.getTypes().getFunctionInfo(ResultType, Args, EInfo);
724
725 CodeGenTypes &Types = CGM.getTypes();
726 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
727
775 // FIXME: This leaks
776 ImplicitParamDecl *SelfDecl =
777 ImplicitParamDecl::Create(getContext(), const_cast<BlockDecl*>(BD),
778 SourceLocation(), II,
779 ParmTy);
780
781 Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
782 BlockStructDecl = SelfDecl;
783
784 for (BlockDecl::param_const_iterator i = BD->param_begin(),
785 e = BD->param_end(); i != e; ++i)
786 Args.push_back(std::make_pair(*i, (*i)->getType()));
787
788 const CGFunctionInfo &FI =
789 CGM.getTypes().getFunctionInfo(ResultType, Args, EInfo);
790
791 CodeGenTypes &Types = CGM.getTypes();
792 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
793
794 MangleBuffer Name;
795 CGM.getMangledName(Name, BD);
728 llvm::Function *Fn =
796 llvm::Function *Fn =
729 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
730 llvm::Twine("__") + Info.Name + "_block_invoke_",
731 &CGM.getModule());
797 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
798 Name.getString(), &CGM.getModule());
732
733 CGM.SetInternalFunctionAttributes(BD, Fn, FI);
734
735 StartFunction(BD, ResultType, Fn, Args,
736 BExpr->getBody()->getLocEnd());
737
738 CurFuncDecl = OuterFuncDecl;
739 CurCodeDecl = BD;
740
799
800 CGM.SetInternalFunctionAttributes(BD, Fn, FI);
801
802 StartFunction(BD, ResultType, Fn, Args,
803 BExpr->getBody()->getLocEnd());
804
805 CurFuncDecl = OuterFuncDecl;
806 CurCodeDecl = BD;
807
808 // If we have a C++ 'this' reference, go ahead and force it into
809 // existence now.
810 if (Info.CXXThisRef) {
811 assert(!BlockCXXThisOffset.isZero() &&
812 "haven't yet allocated 'this' reference");
813
814 // TODO: I have a dream that one day this will be typed.
815 llvm::Value *BlockLiteral = LoadBlockStruct();
816 llvm::Value *ThisPtrRaw =
817 Builder.CreateConstInBoundsGEP1_64(BlockLiteral,
818 BlockCXXThisOffset.getQuantity(),
819 "this.ptr.raw");
820
821 const llvm::Type *Ty =
822 CGM.getTypes().ConvertType(Info.CXXThisRef->getType());
823 Ty = llvm::PointerType::get(Ty, 0);
824 llvm::Value *ThisPtr = Builder.CreateBitCast(ThisPtrRaw, Ty, "this.ptr");
825
826 CXXThisValue = Builder.CreateLoad(ThisPtr, "this");
827 }
828
829 // If we have an Objective C 'self' reference, go ahead and force it
830 // into existence now.
831 if (Info.NeedsObjCSelf) {
832 ValueDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl();
833 LocalDeclMap[Self] = GetAddrOfBlockDecl(Self, false);
834 }
835
741 // Save a spot to insert the debug information for all the BlockDeclRefDecls.
742 llvm::BasicBlock *entry = Builder.GetInsertBlock();
743 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
744 --entry_ptr;
745
746 EmitStmt(BExpr->getBody());
747
748 // Remember where we were...
749 llvm::BasicBlock *resume = Builder.GetInsertBlock();
750
751 // Go back to the entry.
752 ++entry_ptr;
753 Builder.SetInsertPoint(entry, entry_ptr);
754
755 if (CGDebugInfo *DI = getDebugInfo()) {
756 // Emit debug information for all the BlockDeclRefDecls.
836 // Save a spot to insert the debug information for all the BlockDeclRefDecls.
837 llvm::BasicBlock *entry = Builder.GetInsertBlock();
838 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
839 --entry_ptr;
840
841 EmitStmt(BExpr->getBody());
842
843 // Remember where we were...
844 llvm::BasicBlock *resume = Builder.GetInsertBlock();
845
846 // Go back to the entry.
847 ++entry_ptr;
848 Builder.SetInsertPoint(entry, entry_ptr);
849
850 if (CGDebugInfo *DI = getDebugInfo()) {
851 // Emit debug information for all the BlockDeclRefDecls.
757 for (unsigned i = 0, e = BlockDeclRefDecls.size(); i != e; ++i) {
758 if (const BlockDeclRefExpr *BDRE =
759 dyn_cast<BlockDeclRefExpr>(BlockDeclRefDecls[i])) {
852 // FIXME: also for 'this'
853 for (unsigned i = 0, e = BlockLayout.size(); i != e; ++i) {
854 if (const BlockDeclRefExpr *BDRE =
855 dyn_cast<BlockDeclRefExpr>(BlockLayout[i])) {
760 const ValueDecl *D = BDRE->getDecl();
761 DI->setLocation(D->getLocation());
762 DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
763 LocalDeclMap[getBlockStructDecl()],
764 Builder, this);
765 }
766 }
767 }

--- 6 unchanged lines hidden (view full) ---

774 FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
775
776 // The runtime needs a minimum alignment of a void *.
777 CharUnits MinAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
778 BlockOffset = CharUnits::fromQuantity(
779 llvm::RoundUpToAlignment(BlockOffset.getQuantity(),
780 MinAlign.getQuantity()));
781
856 const ValueDecl *D = BDRE->getDecl();
857 DI->setLocation(D->getLocation());
858 DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
859 LocalDeclMap[getBlockStructDecl()],
860 Builder, this);
861 }
862 }
863 }

--- 6 unchanged lines hidden (view full) ---

870 FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
871
872 // The runtime needs a minimum alignment of a void *.
873 CharUnits MinAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
874 BlockOffset = CharUnits::fromQuantity(
875 llvm::RoundUpToAlignment(BlockOffset.getQuantity(),
876 MinAlign.getQuantity()));
877
782 Size = BlockOffset;
783 Align = BlockAlign;
784 subBlockDeclRefDecls = BlockDeclRefDecls;
785 subBlockHasCopyDispose |= BlockHasCopyDispose;
878 Info.BlockSize = BlockOffset;
879 Info.BlockAlign = BlockAlign;
880 Info.BlockLayout = BlockLayout;
881 Info.BlockHasCopyDispose = BlockHasCopyDispose;
786 return Fn;
787}
788
882 return Fn;
883}
884
789CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
790 const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl());
885CharUnits BlockFunction::getBlockOffset(CharUnits Size, CharUnits Align) {
886 assert((Align.isPositive()) && "alignment must be 1 byte or more");
791
887
792 CharUnits Size = getContext().getTypeSizeInChars(D->getType());
793 CharUnits Align = getContext().getDeclAlign(D);
794
795 if (BDRE->isByRef()) {
796 Size = getContext().getTypeSizeInChars(getContext().VoidPtrTy);
797 Align = getContext().getTypeAlignInChars(getContext().VoidPtrTy);
798 }
799
800 assert ((Align.isPositive()) && "alignment must be 1 byte or more");
801
802 CharUnits OldOffset = BlockOffset;
803
804 // Ensure proper alignment, even if it means we have to have a gap
805 BlockOffset = CharUnits::fromQuantity(
806 llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align.getQuantity()));
807 BlockAlign = std::max(Align, BlockAlign);
808
809 CharUnits Pad = BlockOffset - OldOffset;
810 if (Pad.isPositive()) {
888 CharUnits OldOffset = BlockOffset;
889
890 // Ensure proper alignment, even if it means we have to have a gap
891 BlockOffset = CharUnits::fromQuantity(
892 llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align.getQuantity()));
893 BlockAlign = std::max(Align, BlockAlign);
894
895 CharUnits Pad = BlockOffset - OldOffset;
896 if (Pad.isPositive()) {
811 llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad.getQuantity());
812 QualType PadTy = getContext().getConstantArrayType(getContext().CharTy,
813 llvm::APInt(32,
814 Pad.getQuantity()),
815 ArrayType::Normal, 0);
897 QualType PadTy = getContext().getConstantArrayType(getContext().CharTy,
898 llvm::APInt(32,
899 Pad.getQuantity()),
900 ArrayType::Normal, 0);
816 ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(),
901 ValueDecl *PadDecl = VarDecl::Create(getContext(),
902 getContext().getTranslationUnitDecl(),
903 SourceLocation(),
817 0, QualType(PadTy), 0,
818 VarDecl::None, VarDecl::None);
904 0, QualType(PadTy), 0,
905 VarDecl::None, VarDecl::None);
819 Expr *E;
820 E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
821 SourceLocation());
822 BlockDeclRefDecls.push_back(E);
906 Expr *E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
907 SourceLocation());
908 BlockLayout.push_back(E);
823 }
909 }
824 BlockDeclRefDecls.push_back(BDRE);
825
826 BlockOffset += Size;
910
911 BlockOffset += Size;
827 return BlockOffset-Size;
912 return BlockOffset - Size;
828}
829
830llvm::Constant *BlockFunction::
831GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
832 std::vector<HelperInfo> *NoteForHelperp) {
833 QualType R = getContext().VoidTy;
834
835 FunctionArgList Args;

--- 364 unchanged lines hidden ---
913}
914
915llvm::Constant *BlockFunction::
916GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
917 std::vector<HelperInfo> *NoteForHelperp) {
918 QualType R = getContext().VoidTy;
919
920 FunctionArgList Args;

--- 364 unchanged lines hidden ---