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 | 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 --- |