File: | tools/clang/lib/CodeGen/CGBlocks.cpp |
Warning: | line 1805, column 14 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This contains code to emit blocks. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #include "CGBlocks.h" | |||
14 | #include "CGCXXABI.h" | |||
15 | #include "CGDebugInfo.h" | |||
16 | #include "CGObjCRuntime.h" | |||
17 | #include "CGOpenCLRuntime.h" | |||
18 | #include "CodeGenFunction.h" | |||
19 | #include "CodeGenModule.h" | |||
20 | #include "ConstantEmitter.h" | |||
21 | #include "TargetInfo.h" | |||
22 | #include "clang/AST/DeclObjC.h" | |||
23 | #include "clang/CodeGen/ConstantInitBuilder.h" | |||
24 | #include "llvm/ADT/SmallSet.h" | |||
25 | #include "llvm/IR/DataLayout.h" | |||
26 | #include "llvm/IR/Module.h" | |||
27 | #include "llvm/Support/ScopedPrinter.h" | |||
28 | #include <algorithm> | |||
29 | #include <cstdio> | |||
30 | ||||
31 | using namespace clang; | |||
32 | using namespace CodeGen; | |||
33 | ||||
34 | CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) | |||
35 | : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), | |||
36 | HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false), | |||
37 | CapturesNonExternalType(false), LocalAddress(Address::invalid()), | |||
38 | StructureType(nullptr), Block(block), DominatingIP(nullptr) { | |||
39 | ||||
40 | // Skip asm prefix, if any. 'name' is usually taken directly from | |||
41 | // the mangled name of the enclosing function. | |||
42 | if (!name.empty() && name[0] == '\01') | |||
43 | name = name.substr(1); | |||
44 | } | |||
45 | ||||
46 | // Anchor the vtable to this translation unit. | |||
47 | BlockByrefHelpers::~BlockByrefHelpers() {} | |||
48 | ||||
49 | /// Build the given block as a global block. | |||
50 | static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, | |||
51 | const CGBlockInfo &blockInfo, | |||
52 | llvm::Constant *blockFn); | |||
53 | ||||
54 | /// Build the helper function to copy a block. | |||
55 | static llvm::Constant *buildCopyHelper(CodeGenModule &CGM, | |||
56 | const CGBlockInfo &blockInfo) { | |||
57 | return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo); | |||
58 | } | |||
59 | ||||
60 | /// Build the helper function to dispose of a block. | |||
61 | static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM, | |||
62 | const CGBlockInfo &blockInfo) { | |||
63 | return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo); | |||
64 | } | |||
65 | ||||
66 | namespace { | |||
67 | ||||
68 | /// Represents a type of copy/destroy operation that should be performed for an | |||
69 | /// entity that's captured by a block. | |||
70 | enum class BlockCaptureEntityKind { | |||
71 | CXXRecord, // Copy or destroy | |||
72 | ARCWeak, | |||
73 | ARCStrong, | |||
74 | NonTrivialCStruct, | |||
75 | BlockObject, // Assign or release | |||
76 | None | |||
77 | }; | |||
78 | ||||
79 | /// Represents a captured entity that requires extra operations in order for | |||
80 | /// this entity to be copied or destroyed correctly. | |||
81 | struct BlockCaptureManagedEntity { | |||
82 | BlockCaptureEntityKind CopyKind, DisposeKind; | |||
83 | BlockFieldFlags CopyFlags, DisposeFlags; | |||
84 | const BlockDecl::Capture *CI; | |||
85 | const CGBlockInfo::Capture *Capture; | |||
86 | ||||
87 | BlockCaptureManagedEntity(BlockCaptureEntityKind CopyType, | |||
88 | BlockCaptureEntityKind DisposeType, | |||
89 | BlockFieldFlags CopyFlags, | |||
90 | BlockFieldFlags DisposeFlags, | |||
91 | const BlockDecl::Capture &CI, | |||
92 | const CGBlockInfo::Capture &Capture) | |||
93 | : CopyKind(CopyType), DisposeKind(DisposeType), CopyFlags(CopyFlags), | |||
94 | DisposeFlags(DisposeFlags), CI(&CI), Capture(&Capture) {} | |||
95 | ||||
96 | bool operator<(const BlockCaptureManagedEntity &Other) const { | |||
97 | return Capture->getOffset() < Other.Capture->getOffset(); | |||
98 | } | |||
99 | }; | |||
100 | ||||
101 | enum class CaptureStrKind { | |||
102 | // String for the copy helper. | |||
103 | CopyHelper, | |||
104 | // String for the dispose helper. | |||
105 | DisposeHelper, | |||
106 | // Merge the strings for the copy helper and dispose helper. | |||
107 | Merged | |||
108 | }; | |||
109 | ||||
110 | } // end anonymous namespace | |||
111 | ||||
112 | static void findBlockCapturedManagedEntities( | |||
113 | const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, | |||
114 | SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures); | |||
115 | ||||
116 | static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, | |||
117 | CaptureStrKind StrKind, | |||
118 | CharUnits BlockAlignment, | |||
119 | CodeGenModule &CGM); | |||
120 | ||||
121 | static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo, | |||
122 | CodeGenModule &CGM) { | |||
123 | std::string Name = "__block_descriptor_"; | |||
124 | Name += llvm::to_string(BlockInfo.BlockSize.getQuantity()) + "_"; | |||
125 | ||||
126 | if (BlockInfo.needsCopyDisposeHelpers()) { | |||
127 | if (CGM.getLangOpts().Exceptions) | |||
128 | Name += "e"; | |||
129 | if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions) | |||
130 | Name += "a"; | |||
131 | Name += llvm::to_string(BlockInfo.BlockAlign.getQuantity()) + "_"; | |||
132 | ||||
133 | SmallVector<BlockCaptureManagedEntity, 4> ManagedCaptures; | |||
134 | findBlockCapturedManagedEntities(BlockInfo, CGM.getContext().getLangOpts(), | |||
135 | ManagedCaptures); | |||
136 | ||||
137 | for (const BlockCaptureManagedEntity &E : ManagedCaptures) { | |||
138 | Name += llvm::to_string(E.Capture->getOffset().getQuantity()); | |||
139 | ||||
140 | if (E.CopyKind == E.DisposeKind) { | |||
141 | // If CopyKind and DisposeKind are the same, merge the capture | |||
142 | // information. | |||
143 | assert(E.CopyKind != BlockCaptureEntityKind::None &&((E.CopyKind != BlockCaptureEntityKind::None && "shouldn't see BlockCaptureManagedEntity that is None" ) ? static_cast<void> (0) : __assert_fail ("E.CopyKind != BlockCaptureEntityKind::None && \"shouldn't see BlockCaptureManagedEntity that is None\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 144, __PRETTY_FUNCTION__)) | |||
144 | "shouldn't see BlockCaptureManagedEntity that is None")((E.CopyKind != BlockCaptureEntityKind::None && "shouldn't see BlockCaptureManagedEntity that is None" ) ? static_cast<void> (0) : __assert_fail ("E.CopyKind != BlockCaptureEntityKind::None && \"shouldn't see BlockCaptureManagedEntity that is None\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 144, __PRETTY_FUNCTION__)); | |||
145 | Name += getBlockCaptureStr(E, CaptureStrKind::Merged, | |||
146 | BlockInfo.BlockAlign, CGM); | |||
147 | } else { | |||
148 | // If CopyKind and DisposeKind are not the same, which can happen when | |||
149 | // either Kind is None or the captured object is a __strong block, | |||
150 | // concatenate the copy and dispose strings. | |||
151 | Name += getBlockCaptureStr(E, CaptureStrKind::CopyHelper, | |||
152 | BlockInfo.BlockAlign, CGM); | |||
153 | Name += getBlockCaptureStr(E, CaptureStrKind::DisposeHelper, | |||
154 | BlockInfo.BlockAlign, CGM); | |||
155 | } | |||
156 | } | |||
157 | Name += "_"; | |||
158 | } | |||
159 | ||||
160 | std::string TypeAtEncoding = | |||
161 | CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr()); | |||
162 | /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as | |||
163 | /// a separator between symbol name and symbol version. | |||
164 | std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1'); | |||
165 | Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding; | |||
166 | Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo); | |||
167 | return Name; | |||
168 | } | |||
169 | ||||
170 | /// buildBlockDescriptor - Build the block descriptor meta-data for a block. | |||
171 | /// buildBlockDescriptor is accessed from 5th field of the Block_literal | |||
172 | /// meta-data and contains stationary information about the block literal. | |||
173 | /// Its definition will have 4 (or optionally 6) words. | |||
174 | /// \code | |||
175 | /// struct Block_descriptor { | |||
176 | /// unsigned long reserved; | |||
177 | /// unsigned long size; // size of Block_literal metadata in bytes. | |||
178 | /// void *copy_func_helper_decl; // optional copy helper. | |||
179 | /// void *destroy_func_decl; // optional destructor helper. | |||
180 | /// void *block_method_encoding_address; // @encode for block literal signature. | |||
181 | /// void *block_layout_info; // encoding of captured block variables. | |||
182 | /// }; | |||
183 | /// \endcode | |||
184 | static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, | |||
185 | const CGBlockInfo &blockInfo) { | |||
186 | ASTContext &C = CGM.getContext(); | |||
187 | ||||
188 | llvm::IntegerType *ulong = | |||
189 | cast<llvm::IntegerType>(CGM.getTypes().ConvertType(C.UnsignedLongTy)); | |||
190 | llvm::PointerType *i8p = nullptr; | |||
191 | if (CGM.getLangOpts().OpenCL) | |||
192 | i8p = | |||
193 | llvm::Type::getInt8PtrTy( | |||
194 | CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant)); | |||
195 | else | |||
196 | i8p = CGM.VoidPtrTy; | |||
197 | ||||
198 | std::string descName; | |||
199 | ||||
200 | // If an equivalent block descriptor global variable exists, return it. | |||
201 | if (C.getLangOpts().ObjC && | |||
202 | CGM.getLangOpts().getGC() == LangOptions::NonGC) { | |||
203 | descName = getBlockDescriptorName(blockInfo, CGM); | |||
204 | if (llvm::GlobalValue *desc = CGM.getModule().getNamedValue(descName)) | |||
205 | return llvm::ConstantExpr::getBitCast(desc, | |||
206 | CGM.getBlockDescriptorType()); | |||
207 | } | |||
208 | ||||
209 | // If there isn't an equivalent block descriptor global variable, create a new | |||
210 | // one. | |||
211 | ConstantInitBuilder builder(CGM); | |||
212 | auto elements = builder.beginStruct(); | |||
213 | ||||
214 | // reserved | |||
215 | elements.addInt(ulong, 0); | |||
216 | ||||
217 | // Size | |||
218 | // FIXME: What is the right way to say this doesn't fit? We should give | |||
219 | // a user diagnostic in that case. Better fix would be to change the | |||
220 | // API to size_t. | |||
221 | elements.addInt(ulong, blockInfo.BlockSize.getQuantity()); | |||
222 | ||||
223 | // Optional copy/dispose helpers. | |||
224 | bool hasInternalHelper = false; | |||
225 | if (blockInfo.needsCopyDisposeHelpers()) { | |||
226 | // copy_func_helper_decl | |||
227 | llvm::Constant *copyHelper = buildCopyHelper(CGM, blockInfo); | |||
228 | elements.add(copyHelper); | |||
229 | ||||
230 | // destroy_func_decl | |||
231 | llvm::Constant *disposeHelper = buildDisposeHelper(CGM, blockInfo); | |||
232 | elements.add(disposeHelper); | |||
233 | ||||
234 | if (cast<llvm::Function>(copyHelper->getOperand(0))->hasInternalLinkage() || | |||
235 | cast<llvm::Function>(disposeHelper->getOperand(0)) | |||
236 | ->hasInternalLinkage()) | |||
237 | hasInternalHelper = true; | |||
238 | } | |||
239 | ||||
240 | // Signature. Mandatory ObjC-style method descriptor @encode sequence. | |||
241 | std::string typeAtEncoding = | |||
242 | CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); | |||
243 | elements.add(llvm::ConstantExpr::getBitCast( | |||
244 | CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p)); | |||
245 | ||||
246 | // GC layout. | |||
247 | if (C.getLangOpts().ObjC) { | |||
248 | if (CGM.getLangOpts().getGC() != LangOptions::NonGC) | |||
249 | elements.add(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo)); | |||
250 | else | |||
251 | elements.add(CGM.getObjCRuntime().BuildRCBlockLayout(CGM, blockInfo)); | |||
252 | } | |||
253 | else | |||
254 | elements.addNullPointer(i8p); | |||
255 | ||||
256 | unsigned AddrSpace = 0; | |||
257 | if (C.getLangOpts().OpenCL) | |||
258 | AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant); | |||
259 | ||||
260 | llvm::GlobalValue::LinkageTypes linkage; | |||
261 | if (descName.empty()) { | |||
262 | linkage = llvm::GlobalValue::InternalLinkage; | |||
263 | descName = "__block_descriptor_tmp"; | |||
264 | } else if (hasInternalHelper) { | |||
265 | // If either the copy helper or the dispose helper has internal linkage, | |||
266 | // the block descriptor must have internal linkage too. | |||
267 | linkage = llvm::GlobalValue::InternalLinkage; | |||
268 | } else { | |||
269 | linkage = llvm::GlobalValue::LinkOnceODRLinkage; | |||
270 | } | |||
271 | ||||
272 | llvm::GlobalVariable *global = | |||
273 | elements.finishAndCreateGlobal(descName, CGM.getPointerAlign(), | |||
274 | /*constant*/ true, linkage, AddrSpace); | |||
275 | ||||
276 | if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) { | |||
277 | if (CGM.supportsCOMDAT()) | |||
278 | global->setComdat(CGM.getModule().getOrInsertComdat(descName)); | |||
279 | global->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
280 | global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); | |||
281 | } | |||
282 | ||||
283 | return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); | |||
284 | } | |||
285 | ||||
286 | /* | |||
287 | Purely notional variadic template describing the layout of a block. | |||
288 | ||||
289 | template <class _ResultType, class... _ParamTypes, class... _CaptureTypes> | |||
290 | struct Block_literal { | |||
291 | /// Initialized to one of: | |||
292 | /// extern void *_NSConcreteStackBlock[]; | |||
293 | /// extern void *_NSConcreteGlobalBlock[]; | |||
294 | /// | |||
295 | /// In theory, we could start one off malloc'ed by setting | |||
296 | /// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using | |||
297 | /// this isa: | |||
298 | /// extern void *_NSConcreteMallocBlock[]; | |||
299 | struct objc_class *isa; | |||
300 | ||||
301 | /// These are the flags (with corresponding bit number) that the | |||
302 | /// compiler is actually supposed to know about. | |||
303 | /// 23. BLOCK_IS_NOESCAPE - indicates that the block is non-escaping | |||
304 | /// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block | |||
305 | /// descriptor provides copy and dispose helper functions | |||
306 | /// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured | |||
307 | /// object with a nontrivial destructor or copy constructor | |||
308 | /// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated | |||
309 | /// as global memory | |||
310 | /// 29. BLOCK_USE_STRET - indicates that the block function | |||
311 | /// uses stret, which objc_msgSend needs to know about | |||
312 | /// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an | |||
313 | /// @encoded signature string | |||
314 | /// And we're not supposed to manipulate these: | |||
315 | /// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved | |||
316 | /// to malloc'ed memory | |||
317 | /// 27. BLOCK_IS_GC - indicates that the block has been moved to | |||
318 | /// to GC-allocated memory | |||
319 | /// Additionally, the bottom 16 bits are a reference count which | |||
320 | /// should be zero on the stack. | |||
321 | int flags; | |||
322 | ||||
323 | /// Reserved; should be zero-initialized. | |||
324 | int reserved; | |||
325 | ||||
326 | /// Function pointer generated from block literal. | |||
327 | _ResultType (*invoke)(Block_literal *, _ParamTypes...); | |||
328 | ||||
329 | /// Block description metadata generated from block literal. | |||
330 | struct Block_descriptor *block_descriptor; | |||
331 | ||||
332 | /// Captured values follow. | |||
333 | _CapturesTypes captures...; | |||
334 | }; | |||
335 | */ | |||
336 | ||||
337 | namespace { | |||
338 | /// A chunk of data that we actually have to capture in the block. | |||
339 | struct BlockLayoutChunk { | |||
340 | CharUnits Alignment; | |||
341 | CharUnits Size; | |||
342 | Qualifiers::ObjCLifetime Lifetime; | |||
343 | const BlockDecl::Capture *Capture; // null for 'this' | |||
344 | llvm::Type *Type; | |||
345 | QualType FieldType; | |||
346 | ||||
347 | BlockLayoutChunk(CharUnits align, CharUnits size, | |||
348 | Qualifiers::ObjCLifetime lifetime, | |||
349 | const BlockDecl::Capture *capture, | |||
350 | llvm::Type *type, QualType fieldType) | |||
351 | : Alignment(align), Size(size), Lifetime(lifetime), | |||
352 | Capture(capture), Type(type), FieldType(fieldType) {} | |||
353 | ||||
354 | /// Tell the block info that this chunk has the given field index. | |||
355 | void setIndex(CGBlockInfo &info, unsigned index, CharUnits offset) { | |||
356 | if (!Capture) { | |||
357 | info.CXXThisIndex = index; | |||
358 | info.CXXThisOffset = offset; | |||
359 | } else { | |||
360 | auto C = CGBlockInfo::Capture::makeIndex(index, offset, FieldType); | |||
361 | info.Captures.insert({Capture->getVariable(), C}); | |||
362 | } | |||
363 | } | |||
364 | }; | |||
365 | ||||
366 | /// Order by 1) all __strong together 2) next, all byfref together 3) next, | |||
367 | /// all __weak together. Preserve descending alignment in all situations. | |||
368 | bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { | |||
369 | if (left.Alignment != right.Alignment) | |||
370 | return left.Alignment > right.Alignment; | |||
371 | ||||
372 | auto getPrefOrder = [](const BlockLayoutChunk &chunk) { | |||
373 | if (chunk.Capture && chunk.Capture->isByRef()) | |||
374 | return 1; | |||
375 | if (chunk.Lifetime == Qualifiers::OCL_Strong) | |||
376 | return 0; | |||
377 | if (chunk.Lifetime == Qualifiers::OCL_Weak) | |||
378 | return 2; | |||
379 | return 3; | |||
380 | }; | |||
381 | ||||
382 | return getPrefOrder(left) < getPrefOrder(right); | |||
383 | } | |||
384 | } // end anonymous namespace | |||
385 | ||||
386 | /// Determines if the given type is safe for constant capture in C++. | |||
387 | static bool isSafeForCXXConstantCapture(QualType type) { | |||
388 | const RecordType *recordType = | |||
389 | type->getBaseElementTypeUnsafe()->getAs<RecordType>(); | |||
390 | ||||
391 | // Only records can be unsafe. | |||
392 | if (!recordType) return true; | |||
393 | ||||
394 | const auto *record = cast<CXXRecordDecl>(recordType->getDecl()); | |||
395 | ||||
396 | // Maintain semantics for classes with non-trivial dtors or copy ctors. | |||
397 | if (!record->hasTrivialDestructor()) return false; | |||
398 | if (record->hasNonTrivialCopyConstructor()) return false; | |||
399 | ||||
400 | // Otherwise, we just have to make sure there aren't any mutable | |||
401 | // fields that might have changed since initialization. | |||
402 | return !record->hasMutableFields(); | |||
403 | } | |||
404 | ||||
405 | /// It is illegal to modify a const object after initialization. | |||
406 | /// Therefore, if a const object has a constant initializer, we don't | |||
407 | /// actually need to keep storage for it in the block; we'll just | |||
408 | /// rematerialize it at the start of the block function. This is | |||
409 | /// acceptable because we make no promises about address stability of | |||
410 | /// captured variables. | |||
411 | static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM, | |||
412 | CodeGenFunction *CGF, | |||
413 | const VarDecl *var) { | |||
414 | // Return if this is a function parameter. We shouldn't try to | |||
415 | // rematerialize default arguments of function parameters. | |||
416 | if (isa<ParmVarDecl>(var)) | |||
417 | return nullptr; | |||
418 | ||||
419 | QualType type = var->getType(); | |||
420 | ||||
421 | // We can only do this if the variable is const. | |||
422 | if (!type.isConstQualified()) return nullptr; | |||
423 | ||||
424 | // Furthermore, in C++ we have to worry about mutable fields: | |||
425 | // C++ [dcl.type.cv]p4: | |||
426 | // Except that any class member declared mutable can be | |||
427 | // modified, any attempt to modify a const object during its | |||
428 | // lifetime results in undefined behavior. | |||
429 | if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type)) | |||
430 | return nullptr; | |||
431 | ||||
432 | // If the variable doesn't have any initializer (shouldn't this be | |||
433 | // invalid?), it's not clear what we should do. Maybe capture as | |||
434 | // zero? | |||
435 | const Expr *init = var->getInit(); | |||
436 | if (!init) return nullptr; | |||
437 | ||||
438 | return ConstantEmitter(CGM, CGF).tryEmitAbstractForInitializer(*var); | |||
439 | } | |||
440 | ||||
441 | /// Get the low bit of a nonzero character count. This is the | |||
442 | /// alignment of the nth byte if the 0th byte is universally aligned. | |||
443 | static CharUnits getLowBit(CharUnits v) { | |||
444 | return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1)); | |||
445 | } | |||
446 | ||||
447 | static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, | |||
448 | SmallVectorImpl<llvm::Type*> &elementTypes) { | |||
449 | ||||
450 | assert(elementTypes.empty())((elementTypes.empty()) ? static_cast<void> (0) : __assert_fail ("elementTypes.empty()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 450, __PRETTY_FUNCTION__)); | |||
451 | if (CGM.getLangOpts().OpenCL) { | |||
452 | // The header is basically 'struct { int; int; generic void *; | |||
453 | // custom_fields; }'. Assert that struct is packed. | |||
454 | auto GenericAS = | |||
455 | CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic); | |||
456 | auto GenPtrAlign = | |||
457 | CharUnits::fromQuantity(CGM.getTarget().getPointerAlign(GenericAS) / 8); | |||
458 | auto GenPtrSize = | |||
459 | CharUnits::fromQuantity(CGM.getTarget().getPointerWidth(GenericAS) / 8); | |||
460 | assert(CGM.getIntSize() <= GenPtrSize)((CGM.getIntSize() <= GenPtrSize) ? static_cast<void> (0) : __assert_fail ("CGM.getIntSize() <= GenPtrSize", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 460, __PRETTY_FUNCTION__)); | |||
461 | assert(CGM.getIntAlign() <= GenPtrAlign)((CGM.getIntAlign() <= GenPtrAlign) ? static_cast<void> (0) : __assert_fail ("CGM.getIntAlign() <= GenPtrAlign", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 461, __PRETTY_FUNCTION__)); | |||
462 | assert((2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign))(((2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign)) ? static_cast <void> (0) : __assert_fail ("(2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign)" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 462, __PRETTY_FUNCTION__)); | |||
463 | elementTypes.push_back(CGM.IntTy); /* total size */ | |||
464 | elementTypes.push_back(CGM.IntTy); /* align */ | |||
465 | elementTypes.push_back( | |||
466 | CGM.getOpenCLRuntime() | |||
467 | .getGenericVoidPointerType()); /* invoke function */ | |||
468 | unsigned Offset = | |||
469 | 2 * CGM.getIntSize().getQuantity() + GenPtrSize.getQuantity(); | |||
470 | unsigned BlockAlign = GenPtrAlign.getQuantity(); | |||
471 | if (auto *Helper = | |||
472 | CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) { | |||
473 | for (auto I : Helper->getCustomFieldTypes()) /* custom fields */ { | |||
474 | // TargetOpenCLBlockHelp needs to make sure the struct is packed. | |||
475 | // If necessary, add padding fields to the custom fields. | |||
476 | unsigned Align = CGM.getDataLayout().getABITypeAlignment(I); | |||
477 | if (BlockAlign < Align) | |||
478 | BlockAlign = Align; | |||
479 | assert(Offset % Align == 0)((Offset % Align == 0) ? static_cast<void> (0) : __assert_fail ("Offset % Align == 0", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 479, __PRETTY_FUNCTION__)); | |||
480 | Offset += CGM.getDataLayout().getTypeAllocSize(I); | |||
481 | elementTypes.push_back(I); | |||
482 | } | |||
483 | } | |||
484 | info.BlockAlign = CharUnits::fromQuantity(BlockAlign); | |||
485 | info.BlockSize = CharUnits::fromQuantity(Offset); | |||
486 | } else { | |||
487 | // The header is basically 'struct { void *; int; int; void *; void *; }'. | |||
488 | // Assert that the struct is packed. | |||
489 | assert(CGM.getIntSize() <= CGM.getPointerSize())((CGM.getIntSize() <= CGM.getPointerSize()) ? static_cast< void> (0) : __assert_fail ("CGM.getIntSize() <= CGM.getPointerSize()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 489, __PRETTY_FUNCTION__)); | |||
490 | assert(CGM.getIntAlign() <= CGM.getPointerAlign())((CGM.getIntAlign() <= CGM.getPointerAlign()) ? static_cast <void> (0) : __assert_fail ("CGM.getIntAlign() <= CGM.getPointerAlign()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 490, __PRETTY_FUNCTION__)); | |||
491 | assert((2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign()))(((2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign())) ? static_cast<void> (0) : __assert_fail ("(2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign())" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 491, __PRETTY_FUNCTION__)); | |||
492 | info.BlockAlign = CGM.getPointerAlign(); | |||
493 | info.BlockSize = 3 * CGM.getPointerSize() + 2 * CGM.getIntSize(); | |||
494 | elementTypes.push_back(CGM.VoidPtrTy); | |||
495 | elementTypes.push_back(CGM.IntTy); | |||
496 | elementTypes.push_back(CGM.IntTy); | |||
497 | elementTypes.push_back(CGM.VoidPtrTy); | |||
498 | elementTypes.push_back(CGM.getBlockDescriptorType()); | |||
499 | } | |||
500 | } | |||
501 | ||||
502 | static QualType getCaptureFieldType(const CodeGenFunction &CGF, | |||
503 | const BlockDecl::Capture &CI) { | |||
504 | const VarDecl *VD = CI.getVariable(); | |||
505 | ||||
506 | // If the variable is captured by an enclosing block or lambda expression, | |||
507 | // use the type of the capture field. | |||
508 | if (CGF.BlockInfo && CI.isNested()) | |||
509 | return CGF.BlockInfo->getCapture(VD).fieldType(); | |||
510 | if (auto *FD = CGF.LambdaCaptureFields.lookup(VD)) | |||
511 | return FD->getType(); | |||
512 | // If the captured variable is a non-escaping __block variable, the field | |||
513 | // type is the reference type. If the variable is a __block variable that | |||
514 | // already has a reference type, the field type is the variable's type. | |||
515 | return VD->isNonEscapingByref() ? | |||
516 | CGF.getContext().getLValueReferenceType(VD->getType()) : VD->getType(); | |||
517 | } | |||
518 | ||||
519 | /// Compute the layout of the given block. Attempts to lay the block | |||
520 | /// out with minimal space requirements. | |||
521 | static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, | |||
522 | CGBlockInfo &info) { | |||
523 | ASTContext &C = CGM.getContext(); | |||
524 | const BlockDecl *block = info.getBlockDecl(); | |||
525 | ||||
526 | SmallVector<llvm::Type*, 8> elementTypes; | |||
527 | initializeForBlockHeader(CGM, info, elementTypes); | |||
528 | bool hasNonConstantCustomFields = false; | |||
529 | if (auto *OpenCLHelper = | |||
530 | CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) | |||
531 | hasNonConstantCustomFields = | |||
532 | !OpenCLHelper->areAllCustomFieldValuesConstant(info); | |||
533 | if (!block->hasCaptures() && !hasNonConstantCustomFields) { | |||
534 | info.StructureType = | |||
535 | llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); | |||
536 | info.CanBeGlobal = true; | |||
537 | return; | |||
538 | } | |||
539 | else if (C.getLangOpts().ObjC && | |||
540 | CGM.getLangOpts().getGC() == LangOptions::NonGC) | |||
541 | info.HasCapturedVariableLayout = true; | |||
542 | ||||
543 | // Collect the layout chunks. | |||
544 | SmallVector<BlockLayoutChunk, 16> layout; | |||
545 | layout.reserve(block->capturesCXXThis() + | |||
546 | (block->capture_end() - block->capture_begin())); | |||
547 | ||||
548 | CharUnits maxFieldAlign; | |||
549 | ||||
550 | // First, 'this'. | |||
551 | if (block->capturesCXXThis()) { | |||
552 | assert(CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) &&((CGF && CGF->CurFuncDecl && isa<CXXMethodDecl >(CGF->CurFuncDecl) && "Can't capture 'this' outside a method" ) ? static_cast<void> (0) : __assert_fail ("CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) && \"Can't capture 'this' outside a method\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 553, __PRETTY_FUNCTION__)) | |||
553 | "Can't capture 'this' outside a method")((CGF && CGF->CurFuncDecl && isa<CXXMethodDecl >(CGF->CurFuncDecl) && "Can't capture 'this' outside a method" ) ? static_cast<void> (0) : __assert_fail ("CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) && \"Can't capture 'this' outside a method\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 553, __PRETTY_FUNCTION__)); | |||
554 | QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(); | |||
555 | ||||
556 | // Theoretically, this could be in a different address space, so | |||
557 | // don't assume standard pointer size/align. | |||
558 | llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); | |||
559 | std::pair<CharUnits,CharUnits> tinfo | |||
560 | = CGM.getContext().getTypeInfoInChars(thisType); | |||
561 | maxFieldAlign = std::max(maxFieldAlign, tinfo.second); | |||
562 | ||||
563 | layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, | |||
564 | Qualifiers::OCL_None, | |||
565 | nullptr, llvmType, thisType)); | |||
566 | } | |||
567 | ||||
568 | // Next, all the block captures. | |||
569 | for (const auto &CI : block->captures()) { | |||
570 | const VarDecl *variable = CI.getVariable(); | |||
571 | ||||
572 | if (CI.isEscapingByref()) { | |||
573 | // We have to copy/dispose of the __block reference. | |||
574 | info.NeedsCopyDispose = true; | |||
575 | ||||
576 | // Just use void* instead of a pointer to the byref type. | |||
577 | CharUnits align = CGM.getPointerAlign(); | |||
578 | maxFieldAlign = std::max(maxFieldAlign, align); | |||
579 | ||||
580 | // Since a __block variable cannot be captured by lambdas, its type and | |||
581 | // the capture field type should always match. | |||
582 | assert(getCaptureFieldType(*CGF, CI) == variable->getType() &&((getCaptureFieldType(*CGF, CI) == variable->getType() && "capture type differs from the variable type") ? static_cast <void> (0) : __assert_fail ("getCaptureFieldType(*CGF, CI) == variable->getType() && \"capture type differs from the variable type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 583, __PRETTY_FUNCTION__)) | |||
583 | "capture type differs from the variable type")((getCaptureFieldType(*CGF, CI) == variable->getType() && "capture type differs from the variable type") ? static_cast <void> (0) : __assert_fail ("getCaptureFieldType(*CGF, CI) == variable->getType() && \"capture type differs from the variable type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 583, __PRETTY_FUNCTION__)); | |||
584 | layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(), | |||
585 | Qualifiers::OCL_None, &CI, | |||
586 | CGM.VoidPtrTy, variable->getType())); | |||
587 | continue; | |||
588 | } | |||
589 | ||||
590 | // Otherwise, build a layout chunk with the size and alignment of | |||
591 | // the declaration. | |||
592 | if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) { | |||
593 | info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant); | |||
594 | continue; | |||
595 | } | |||
596 | ||||
597 | QualType VT = getCaptureFieldType(*CGF, CI); | |||
598 | ||||
599 | // If we have a lifetime qualifier, honor it for capture purposes. | |||
600 | // That includes *not* copying it if it's __unsafe_unretained. | |||
601 | Qualifiers::ObjCLifetime lifetime = VT.getObjCLifetime(); | |||
602 | if (lifetime) { | |||
603 | switch (lifetime) { | |||
604 | case Qualifiers::OCL_None: llvm_unreachable("impossible")::llvm::llvm_unreachable_internal("impossible", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 604); | |||
605 | case Qualifiers::OCL_ExplicitNone: | |||
606 | case Qualifiers::OCL_Autoreleasing: | |||
607 | break; | |||
608 | ||||
609 | case Qualifiers::OCL_Strong: | |||
610 | case Qualifiers::OCL_Weak: | |||
611 | info.NeedsCopyDispose = true; | |||
612 | } | |||
613 | ||||
614 | // Block pointers require copy/dispose. So do Objective-C pointers. | |||
615 | } else if (VT->isObjCRetainableType()) { | |||
616 | // But honor the inert __unsafe_unretained qualifier, which doesn't | |||
617 | // actually make it into the type system. | |||
618 | if (VT->isObjCInertUnsafeUnretainedType()) { | |||
619 | lifetime = Qualifiers::OCL_ExplicitNone; | |||
620 | } else { | |||
621 | info.NeedsCopyDispose = true; | |||
622 | // used for mrr below. | |||
623 | lifetime = Qualifiers::OCL_Strong; | |||
624 | } | |||
625 | ||||
626 | // So do types that require non-trivial copy construction. | |||
627 | } else if (CI.hasCopyExpr()) { | |||
628 | info.NeedsCopyDispose = true; | |||
629 | info.HasCXXObject = true; | |||
630 | if (!VT->getAsCXXRecordDecl()->isExternallyVisible()) | |||
631 | info.CapturesNonExternalType = true; | |||
632 | ||||
633 | // So do C structs that require non-trivial copy construction or | |||
634 | // destruction. | |||
635 | } else if (VT.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct || | |||
636 | VT.isDestructedType() == QualType::DK_nontrivial_c_struct) { | |||
637 | info.NeedsCopyDispose = true; | |||
638 | ||||
639 | // And so do types with destructors. | |||
640 | } else if (CGM.getLangOpts().CPlusPlus) { | |||
641 | if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) { | |||
642 | if (!record->hasTrivialDestructor()) { | |||
643 | info.HasCXXObject = true; | |||
644 | info.NeedsCopyDispose = true; | |||
645 | if (!record->isExternallyVisible()) | |||
646 | info.CapturesNonExternalType = true; | |||
647 | } | |||
648 | } | |||
649 | } | |||
650 | ||||
651 | CharUnits size = C.getTypeSizeInChars(VT); | |||
652 | CharUnits align = C.getDeclAlign(variable); | |||
653 | ||||
654 | maxFieldAlign = std::max(maxFieldAlign, align); | |||
655 | ||||
656 | llvm::Type *llvmType = | |||
657 | CGM.getTypes().ConvertTypeForMem(VT); | |||
658 | ||||
659 | layout.push_back( | |||
660 | BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT)); | |||
661 | } | |||
662 | ||||
663 | // If that was everything, we're done here. | |||
664 | if (layout.empty()) { | |||
665 | info.StructureType = | |||
666 | llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); | |||
667 | info.CanBeGlobal = true; | |||
668 | return; | |||
669 | } | |||
670 | ||||
671 | // Sort the layout by alignment. We have to use a stable sort here | |||
672 | // to get reproducible results. There should probably be an | |||
673 | // llvm::array_pod_stable_sort. | |||
674 | llvm::stable_sort(layout); | |||
675 | ||||
676 | // Needed for blocks layout info. | |||
677 | info.BlockHeaderForcedGapOffset = info.BlockSize; | |||
678 | info.BlockHeaderForcedGapSize = CharUnits::Zero(); | |||
679 | ||||
680 | CharUnits &blockSize = info.BlockSize; | |||
681 | info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); | |||
682 | ||||
683 | // Assuming that the first byte in the header is maximally aligned, | |||
684 | // get the alignment of the first byte following the header. | |||
685 | CharUnits endAlign = getLowBit(blockSize); | |||
686 | ||||
687 | // If the end of the header isn't satisfactorily aligned for the | |||
688 | // maximum thing, look for things that are okay with the header-end | |||
689 | // alignment, and keep appending them until we get something that's | |||
690 | // aligned right. This algorithm is only guaranteed optimal if | |||
691 | // that condition is satisfied at some point; otherwise we can get | |||
692 | // things like: | |||
693 | // header // next byte has alignment 4 | |||
694 | // something_with_size_5; // next byte has alignment 1 | |||
695 | // something_with_alignment_8; | |||
696 | // which has 7 bytes of padding, as opposed to the naive solution | |||
697 | // which might have less (?). | |||
698 | if (endAlign < maxFieldAlign) { | |||
699 | SmallVectorImpl<BlockLayoutChunk>::iterator | |||
700 | li = layout.begin() + 1, le = layout.end(); | |||
701 | ||||
702 | // Look for something that the header end is already | |||
703 | // satisfactorily aligned for. | |||
704 | for (; li != le && endAlign < li->Alignment; ++li) | |||
705 | ; | |||
706 | ||||
707 | // If we found something that's naturally aligned for the end of | |||
708 | // the header, keep adding things... | |||
709 | if (li != le) { | |||
710 | SmallVectorImpl<BlockLayoutChunk>::iterator first = li; | |||
711 | for (; li != le; ++li) { | |||
712 | assert(endAlign >= li->Alignment)((endAlign >= li->Alignment) ? static_cast<void> ( 0) : __assert_fail ("endAlign >= li->Alignment", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 712, __PRETTY_FUNCTION__)); | |||
713 | ||||
714 | li->setIndex(info, elementTypes.size(), blockSize); | |||
715 | elementTypes.push_back(li->Type); | |||
716 | blockSize += li->Size; | |||
717 | endAlign = getLowBit(blockSize); | |||
718 | ||||
719 | // ...until we get to the alignment of the maximum field. | |||
720 | if (endAlign >= maxFieldAlign) { | |||
721 | break; | |||
722 | } | |||
723 | } | |||
724 | // Don't re-append everything we just appended. | |||
725 | layout.erase(first, li); | |||
726 | } | |||
727 | } | |||
728 | ||||
729 | assert(endAlign == getLowBit(blockSize))((endAlign == getLowBit(blockSize)) ? static_cast<void> (0) : __assert_fail ("endAlign == getLowBit(blockSize)", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 729, __PRETTY_FUNCTION__)); | |||
730 | ||||
731 | // At this point, we just have to add padding if the end align still | |||
732 | // isn't aligned right. | |||
733 | if (endAlign < maxFieldAlign) { | |||
734 | CharUnits newBlockSize = blockSize.alignTo(maxFieldAlign); | |||
735 | CharUnits padding = newBlockSize - blockSize; | |||
736 | ||||
737 | // If we haven't yet added any fields, remember that there was an | |||
738 | // initial gap; this need to go into the block layout bit map. | |||
739 | if (blockSize == info.BlockHeaderForcedGapOffset) { | |||
740 | info.BlockHeaderForcedGapSize = padding; | |||
741 | } | |||
742 | ||||
743 | elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, | |||
744 | padding.getQuantity())); | |||
745 | blockSize = newBlockSize; | |||
746 | endAlign = getLowBit(blockSize); // might be > maxFieldAlign | |||
747 | } | |||
748 | ||||
749 | assert(endAlign >= maxFieldAlign)((endAlign >= maxFieldAlign) ? static_cast<void> (0) : __assert_fail ("endAlign >= maxFieldAlign", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 749, __PRETTY_FUNCTION__)); | |||
750 | assert(endAlign == getLowBit(blockSize))((endAlign == getLowBit(blockSize)) ? static_cast<void> (0) : __assert_fail ("endAlign == getLowBit(blockSize)", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 750, __PRETTY_FUNCTION__)); | |||
751 | // Slam everything else on now. This works because they have | |||
752 | // strictly decreasing alignment and we expect that size is always a | |||
753 | // multiple of alignment. | |||
754 | for (SmallVectorImpl<BlockLayoutChunk>::iterator | |||
755 | li = layout.begin(), le = layout.end(); li != le; ++li) { | |||
756 | if (endAlign < li->Alignment) { | |||
757 | // size may not be multiple of alignment. This can only happen with | |||
758 | // an over-aligned variable. We will be adding a padding field to | |||
759 | // make the size be multiple of alignment. | |||
760 | CharUnits padding = li->Alignment - endAlign; | |||
761 | elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, | |||
762 | padding.getQuantity())); | |||
763 | blockSize += padding; | |||
764 | endAlign = getLowBit(blockSize); | |||
765 | } | |||
766 | assert(endAlign >= li->Alignment)((endAlign >= li->Alignment) ? static_cast<void> ( 0) : __assert_fail ("endAlign >= li->Alignment", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 766, __PRETTY_FUNCTION__)); | |||
767 | li->setIndex(info, elementTypes.size(), blockSize); | |||
768 | elementTypes.push_back(li->Type); | |||
769 | blockSize += li->Size; | |||
770 | endAlign = getLowBit(blockSize); | |||
771 | } | |||
772 | ||||
773 | info.StructureType = | |||
774 | llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); | |||
775 | } | |||
776 | ||||
777 | /// Enter the scope of a block. This should be run at the entrance to | |||
778 | /// a full-expression so that the block's cleanups are pushed at the | |||
779 | /// right place in the stack. | |||
780 | static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { | |||
781 | assert(CGF.HaveInsertPoint())((CGF.HaveInsertPoint()) ? static_cast<void> (0) : __assert_fail ("CGF.HaveInsertPoint()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 781, __PRETTY_FUNCTION__)); | |||
782 | ||||
783 | // Allocate the block info and place it at the head of the list. | |||
784 | CGBlockInfo &blockInfo = | |||
785 | *new CGBlockInfo(block, CGF.CurFn->getName()); | |||
786 | blockInfo.NextBlockInfo = CGF.FirstBlockInfo; | |||
787 | CGF.FirstBlockInfo = &blockInfo; | |||
788 | ||||
789 | // Compute information about the layout, etc., of this block, | |||
790 | // pushing cleanups as necessary. | |||
791 | computeBlockInfo(CGF.CGM, &CGF, blockInfo); | |||
792 | ||||
793 | // Nothing else to do if it can be global. | |||
794 | if (blockInfo.CanBeGlobal) return; | |||
795 | ||||
796 | // Make the allocation for the block. | |||
797 | blockInfo.LocalAddress = CGF.CreateTempAlloca(blockInfo.StructureType, | |||
798 | blockInfo.BlockAlign, "block"); | |||
799 | ||||
800 | // If there are cleanups to emit, enter them (but inactive). | |||
801 | if (!blockInfo.NeedsCopyDispose) return; | |||
802 | ||||
803 | // Walk through the captures (in order) and find the ones not | |||
804 | // captured by constant. | |||
805 | for (const auto &CI : block->captures()) { | |||
806 | // Ignore __block captures; there's nothing special in the | |||
807 | // on-stack block that we need to do for them. | |||
808 | if (CI.isByRef()) continue; | |||
809 | ||||
810 | // Ignore variables that are constant-captured. | |||
811 | const VarDecl *variable = CI.getVariable(); | |||
812 | CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); | |||
813 | if (capture.isConstant()) continue; | |||
814 | ||||
815 | // Ignore objects that aren't destructed. | |||
816 | QualType VT = getCaptureFieldType(CGF, CI); | |||
817 | QualType::DestructionKind dtorKind = VT.isDestructedType(); | |||
818 | if (dtorKind == QualType::DK_none) continue; | |||
819 | ||||
820 | CodeGenFunction::Destroyer *destroyer; | |||
821 | ||||
822 | // Block captures count as local values and have imprecise semantics. | |||
823 | // They also can't be arrays, so need to worry about that. | |||
824 | // | |||
825 | // For const-qualified captures, emit clang.arc.use to ensure the captured | |||
826 | // object doesn't get released while we are still depending on its validity | |||
827 | // within the block. | |||
828 | if (VT.isConstQualified() && | |||
829 | VT.getObjCLifetime() == Qualifiers::OCL_Strong && | |||
830 | CGF.CGM.getCodeGenOpts().OptimizationLevel != 0) { | |||
831 | assert(CGF.CGM.getLangOpts().ObjCAutoRefCount &&((CGF.CGM.getLangOpts().ObjCAutoRefCount && "expected ObjC ARC to be enabled" ) ? static_cast<void> (0) : __assert_fail ("CGF.CGM.getLangOpts().ObjCAutoRefCount && \"expected ObjC ARC to be enabled\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 832, __PRETTY_FUNCTION__)) | |||
832 | "expected ObjC ARC to be enabled")((CGF.CGM.getLangOpts().ObjCAutoRefCount && "expected ObjC ARC to be enabled" ) ? static_cast<void> (0) : __assert_fail ("CGF.CGM.getLangOpts().ObjCAutoRefCount && \"expected ObjC ARC to be enabled\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 832, __PRETTY_FUNCTION__)); | |||
833 | destroyer = CodeGenFunction::emitARCIntrinsicUse; | |||
834 | } else if (dtorKind == QualType::DK_objc_strong_lifetime) { | |||
835 | destroyer = CodeGenFunction::destroyARCStrongImprecise; | |||
836 | } else { | |||
837 | destroyer = CGF.getDestroyer(dtorKind); | |||
838 | } | |||
839 | ||||
840 | // GEP down to the address. | |||
841 | Address addr = | |||
842 | CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, capture.getIndex()); | |||
843 | ||||
844 | // We can use that GEP as the dominating IP. | |||
845 | if (!blockInfo.DominatingIP) | |||
846 | blockInfo.DominatingIP = cast<llvm::Instruction>(addr.getPointer()); | |||
847 | ||||
848 | CleanupKind cleanupKind = InactiveNormalCleanup; | |||
849 | bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind); | |||
850 | if (useArrayEHCleanup) | |||
851 | cleanupKind = InactiveNormalAndEHCleanup; | |||
852 | ||||
853 | CGF.pushDestroy(cleanupKind, addr, VT, | |||
854 | destroyer, useArrayEHCleanup); | |||
855 | ||||
856 | // Remember where that cleanup was. | |||
857 | capture.setCleanup(CGF.EHStack.stable_begin()); | |||
858 | } | |||
859 | } | |||
860 | ||||
861 | /// Enter a full-expression with a non-trivial number of objects to | |||
862 | /// clean up. This is in this file because, at the moment, the only | |||
863 | /// kind of cleanup object is a BlockDecl*. | |||
864 | void CodeGenFunction::enterNonTrivialFullExpression(const FullExpr *E) { | |||
865 | if (const auto EWC = dyn_cast<ExprWithCleanups>(E)) { | |||
866 | assert(EWC->getNumObjects() != 0)((EWC->getNumObjects() != 0) ? static_cast<void> (0) : __assert_fail ("EWC->getNumObjects() != 0", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 866, __PRETTY_FUNCTION__)); | |||
867 | for (const ExprWithCleanups::CleanupObject &C : EWC->getObjects()) | |||
868 | enterBlockScope(*this, C); | |||
869 | } | |||
870 | } | |||
871 | ||||
872 | /// Find the layout for the given block in a linked list and remove it. | |||
873 | static CGBlockInfo *findAndRemoveBlockInfo(CGBlockInfo **head, | |||
874 | const BlockDecl *block) { | |||
875 | while (true) { | |||
876 | assert(head && *head)((head && *head) ? static_cast<void> (0) : __assert_fail ("head && *head", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 876, __PRETTY_FUNCTION__)); | |||
877 | CGBlockInfo *cur = *head; | |||
878 | ||||
879 | // If this is the block we're looking for, splice it out of the list. | |||
880 | if (cur->getBlockDecl() == block) { | |||
881 | *head = cur->NextBlockInfo; | |||
882 | return cur; | |||
883 | } | |||
884 | ||||
885 | head = &cur->NextBlockInfo; | |||
886 | } | |||
887 | } | |||
888 | ||||
889 | /// Destroy a chain of block layouts. | |||
890 | void CodeGenFunction::destroyBlockInfos(CGBlockInfo *head) { | |||
891 | assert(head && "destroying an empty chain")((head && "destroying an empty chain") ? static_cast< void> (0) : __assert_fail ("head && \"destroying an empty chain\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 891, __PRETTY_FUNCTION__)); | |||
892 | do { | |||
893 | CGBlockInfo *cur = head; | |||
894 | head = cur->NextBlockInfo; | |||
895 | delete cur; | |||
896 | } while (head != nullptr); | |||
897 | } | |||
898 | ||||
899 | /// Emit a block literal expression in the current function. | |||
900 | llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { | |||
901 | // If the block has no captures, we won't have a pre-computed | |||
902 | // layout for it. | |||
903 | if (!blockExpr->getBlockDecl()->hasCaptures()) { | |||
904 | // The block literal is emitted as a global variable, and the block invoke | |||
905 | // function has to be extracted from its initializer. | |||
906 | if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr)) { | |||
907 | return Block; | |||
908 | } | |||
909 | CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName()); | |||
910 | computeBlockInfo(CGM, this, blockInfo); | |||
911 | blockInfo.BlockExpression = blockExpr; | |||
912 | return EmitBlockLiteral(blockInfo); | |||
913 | } | |||
914 | ||||
915 | // Find the block info for this block and take ownership of it. | |||
916 | std::unique_ptr<CGBlockInfo> blockInfo; | |||
917 | blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo, | |||
918 | blockExpr->getBlockDecl())); | |||
919 | ||||
920 | blockInfo->BlockExpression = blockExpr; | |||
921 | return EmitBlockLiteral(*blockInfo); | |||
922 | } | |||
923 | ||||
924 | llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { | |||
925 | bool IsOpenCL = CGM.getContext().getLangOpts().OpenCL; | |||
926 | auto GenVoidPtrTy = | |||
927 | IsOpenCL ? CGM.getOpenCLRuntime().getGenericVoidPointerType() : VoidPtrTy; | |||
928 | LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default; | |||
929 | auto GenVoidPtrSize = CharUnits::fromQuantity( | |||
930 | CGM.getTarget().getPointerWidth( | |||
931 | CGM.getContext().getTargetAddressSpace(GenVoidPtrAddr)) / | |||
932 | 8); | |||
933 | // Using the computed layout, generate the actual block function. | |||
934 | bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); | |||
935 | CodeGenFunction BlockCGF{CGM, true}; | |||
936 | BlockCGF.SanOpts = SanOpts; | |||
937 | auto *InvokeFn = BlockCGF.GenerateBlockFunction( | |||
938 | CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.CanBeGlobal); | |||
939 | auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy); | |||
940 | ||||
941 | // If there is nothing to capture, we can emit this as a global block. | |||
942 | if (blockInfo.CanBeGlobal) | |||
943 | return CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression); | |||
944 | ||||
945 | // Otherwise, we have to emit this as a local block. | |||
946 | ||||
947 | Address blockAddr = blockInfo.LocalAddress; | |||
948 | assert(blockAddr.isValid() && "block has no address!")((blockAddr.isValid() && "block has no address!") ? static_cast <void> (0) : __assert_fail ("blockAddr.isValid() && \"block has no address!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 948, __PRETTY_FUNCTION__)); | |||
949 | ||||
950 | llvm::Constant *isa; | |||
951 | llvm::Constant *descriptor; | |||
952 | BlockFlags flags; | |||
953 | if (!IsOpenCL) { | |||
954 | // If the block is non-escaping, set field 'isa 'to NSConcreteGlobalBlock | |||
955 | // and set the BLOCK_IS_GLOBAL bit of field 'flags'. Copying a non-escaping | |||
956 | // block just returns the original block and releasing it is a no-op. | |||
957 | llvm::Constant *blockISA = blockInfo.getBlockDecl()->doesNotEscape() | |||
958 | ? CGM.getNSConcreteGlobalBlock() | |||
959 | : CGM.getNSConcreteStackBlock(); | |||
960 | isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy); | |||
961 | ||||
962 | // Build the block descriptor. | |||
963 | descriptor = buildBlockDescriptor(CGM, blockInfo); | |||
964 | ||||
965 | // Compute the initial on-stack block flags. | |||
966 | flags = BLOCK_HAS_SIGNATURE; | |||
967 | if (blockInfo.HasCapturedVariableLayout) | |||
968 | flags |= BLOCK_HAS_EXTENDED_LAYOUT; | |||
969 | if (blockInfo.needsCopyDisposeHelpers()) | |||
970 | flags |= BLOCK_HAS_COPY_DISPOSE; | |||
971 | if (blockInfo.HasCXXObject) | |||
972 | flags |= BLOCK_HAS_CXX_OBJ; | |||
973 | if (blockInfo.UsesStret) | |||
974 | flags |= BLOCK_USE_STRET; | |||
975 | if (blockInfo.getBlockDecl()->doesNotEscape()) | |||
976 | flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL; | |||
977 | } | |||
978 | ||||
979 | auto projectField = [&](unsigned index, const Twine &name) -> Address { | |||
980 | return Builder.CreateStructGEP(blockAddr, index, name); | |||
981 | }; | |||
982 | auto storeField = [&](llvm::Value *value, unsigned index, const Twine &name) { | |||
983 | Builder.CreateStore(value, projectField(index, name)); | |||
984 | }; | |||
985 | ||||
986 | // Initialize the block header. | |||
987 | { | |||
988 | // We assume all the header fields are densely packed. | |||
989 | unsigned index = 0; | |||
990 | CharUnits offset; | |||
991 | auto addHeaderField = [&](llvm::Value *value, CharUnits size, | |||
992 | const Twine &name) { | |||
993 | storeField(value, index, name); | |||
994 | offset += size; | |||
995 | index++; | |||
996 | }; | |||
997 | ||||
998 | if (!IsOpenCL) { | |||
999 | addHeaderField(isa, getPointerSize(), "block.isa"); | |||
1000 | addHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()), | |||
1001 | getIntSize(), "block.flags"); | |||
1002 | addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(), | |||
1003 | "block.reserved"); | |||
1004 | } else { | |||
1005 | addHeaderField( | |||
1006 | llvm::ConstantInt::get(IntTy, blockInfo.BlockSize.getQuantity()), | |||
1007 | getIntSize(), "block.size"); | |||
1008 | addHeaderField( | |||
1009 | llvm::ConstantInt::get(IntTy, blockInfo.BlockAlign.getQuantity()), | |||
1010 | getIntSize(), "block.align"); | |||
1011 | } | |||
1012 | addHeaderField(blockFn, GenVoidPtrSize, "block.invoke"); | |||
1013 | if (!IsOpenCL) | |||
1014 | addHeaderField(descriptor, getPointerSize(), "block.descriptor"); | |||
1015 | else if (auto *Helper = | |||
1016 | CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) { | |||
1017 | for (auto I : Helper->getCustomFieldValues(*this, blockInfo)) { | |||
1018 | addHeaderField( | |||
1019 | I.first, | |||
1020 | CharUnits::fromQuantity( | |||
1021 | CGM.getDataLayout().getTypeAllocSize(I.first->getType())), | |||
1022 | I.second); | |||
1023 | } | |||
1024 | } | |||
1025 | } | |||
1026 | ||||
1027 | // Finally, capture all the values into the block. | |||
1028 | const BlockDecl *blockDecl = blockInfo.getBlockDecl(); | |||
1029 | ||||
1030 | // First, 'this'. | |||
1031 | if (blockDecl->capturesCXXThis()) { | |||
1032 | Address addr = | |||
1033 | projectField(blockInfo.CXXThisIndex, "block.captured-this.addr"); | |||
1034 | Builder.CreateStore(LoadCXXThis(), addr); | |||
1035 | } | |||
1036 | ||||
1037 | // Next, captured variables. | |||
1038 | for (const auto &CI : blockDecl->captures()) { | |||
1039 | const VarDecl *variable = CI.getVariable(); | |||
1040 | const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); | |||
1041 | ||||
1042 | // Ignore constant captures. | |||
1043 | if (capture.isConstant()) continue; | |||
1044 | ||||
1045 | QualType type = capture.fieldType(); | |||
1046 | ||||
1047 | // This will be a [[type]]*, except that a byref entry will just be | |||
1048 | // an i8**. | |||
1049 | Address blockField = projectField(capture.getIndex(), "block.captured"); | |||
1050 | ||||
1051 | // Compute the address of the thing we're going to move into the | |||
1052 | // block literal. | |||
1053 | Address src = Address::invalid(); | |||
1054 | ||||
1055 | if (blockDecl->isConversionFromLambda()) { | |||
1056 | // The lambda capture in a lambda's conversion-to-block-pointer is | |||
1057 | // special; we'll simply emit it directly. | |||
1058 | src = Address::invalid(); | |||
1059 | } else if (CI.isEscapingByref()) { | |||
1060 | if (BlockInfo && CI.isNested()) { | |||
1061 | // We need to use the capture from the enclosing block. | |||
1062 | const CGBlockInfo::Capture &enclosingCapture = | |||
1063 | BlockInfo->getCapture(variable); | |||
1064 | ||||
1065 | // This is a [[type]]*, except that a byref entry will just be an i8**. | |||
1066 | src = Builder.CreateStructGEP(LoadBlockStruct(), | |||
1067 | enclosingCapture.getIndex(), | |||
1068 | "block.capture.addr"); | |||
1069 | } else { | |||
1070 | auto I = LocalDeclMap.find(variable); | |||
1071 | assert(I != LocalDeclMap.end())((I != LocalDeclMap.end()) ? static_cast<void> (0) : __assert_fail ("I != LocalDeclMap.end()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1071, __PRETTY_FUNCTION__)); | |||
1072 | src = I->second; | |||
1073 | } | |||
1074 | } else { | |||
1075 | DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable), | |||
1076 | /*RefersToEnclosingVariableOrCapture*/ CI.isNested(), | |||
1077 | type.getNonReferenceType(), VK_LValue, | |||
1078 | SourceLocation()); | |||
1079 | src = EmitDeclRefLValue(&declRef).getAddress(); | |||
1080 | }; | |||
1081 | ||||
1082 | // For byrefs, we just write the pointer to the byref struct into | |||
1083 | // the block field. There's no need to chase the forwarding | |||
1084 | // pointer at this point, since we're building something that will | |||
1085 | // live a shorter life than the stack byref anyway. | |||
1086 | if (CI.isEscapingByref()) { | |||
1087 | // Get a void* that points to the byref struct. | |||
1088 | llvm::Value *byrefPointer; | |||
1089 | if (CI.isNested()) | |||
1090 | byrefPointer = Builder.CreateLoad(src, "byref.capture"); | |||
1091 | else | |||
1092 | byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy); | |||
1093 | ||||
1094 | // Write that void* into the capture field. | |||
1095 | Builder.CreateStore(byrefPointer, blockField); | |||
1096 | ||||
1097 | // If we have a copy constructor, evaluate that into the block field. | |||
1098 | } else if (const Expr *copyExpr = CI.getCopyExpr()) { | |||
1099 | if (blockDecl->isConversionFromLambda()) { | |||
1100 | // If we have a lambda conversion, emit the expression | |||
1101 | // directly into the block instead. | |||
1102 | AggValueSlot Slot = | |||
1103 | AggValueSlot::forAddr(blockField, Qualifiers(), | |||
1104 | AggValueSlot::IsDestructed, | |||
1105 | AggValueSlot::DoesNotNeedGCBarriers, | |||
1106 | AggValueSlot::IsNotAliased, | |||
1107 | AggValueSlot::DoesNotOverlap); | |||
1108 | EmitAggExpr(copyExpr, Slot); | |||
1109 | } else { | |||
1110 | EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); | |||
1111 | } | |||
1112 | ||||
1113 | // If it's a reference variable, copy the reference into the block field. | |||
1114 | } else if (type->isReferenceType()) { | |||
1115 | Builder.CreateStore(src.getPointer(), blockField); | |||
1116 | ||||
1117 | // If type is const-qualified, copy the value into the block field. | |||
1118 | } else if (type.isConstQualified() && | |||
1119 | type.getObjCLifetime() == Qualifiers::OCL_Strong && | |||
1120 | CGM.getCodeGenOpts().OptimizationLevel != 0) { | |||
1121 | llvm::Value *value = Builder.CreateLoad(src, "captured"); | |||
1122 | Builder.CreateStore(value, blockField); | |||
1123 | ||||
1124 | // If this is an ARC __strong block-pointer variable, don't do a | |||
1125 | // block copy. | |||
1126 | // | |||
1127 | // TODO: this can be generalized into the normal initialization logic: | |||
1128 | // we should never need to do a block-copy when initializing a local | |||
1129 | // variable, because the local variable's lifetime should be strictly | |||
1130 | // contained within the stack block's. | |||
1131 | } else if (type.getObjCLifetime() == Qualifiers::OCL_Strong && | |||
1132 | type->isBlockPointerType()) { | |||
1133 | // Load the block and do a simple retain. | |||
1134 | llvm::Value *value = Builder.CreateLoad(src, "block.captured_block"); | |||
1135 | value = EmitARCRetainNonBlock(value); | |||
1136 | ||||
1137 | // Do a primitive store to the block field. | |||
1138 | Builder.CreateStore(value, blockField); | |||
1139 | ||||
1140 | // Otherwise, fake up a POD copy into the block field. | |||
1141 | } else { | |||
1142 | // Fake up a new variable so that EmitScalarInit doesn't think | |||
1143 | // we're referring to the variable in its own initializer. | |||
1144 | ImplicitParamDecl BlockFieldPseudoVar(getContext(), type, | |||
1145 | ImplicitParamDecl::Other); | |||
1146 | ||||
1147 | // We use one of these or the other depending on whether the | |||
1148 | // reference is nested. | |||
1149 | DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable), | |||
1150 | /*RefersToEnclosingVariableOrCapture*/ CI.isNested(), | |||
1151 | type, VK_LValue, SourceLocation()); | |||
1152 | ||||
1153 | ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue, | |||
1154 | &declRef, VK_RValue); | |||
1155 | // FIXME: Pass a specific location for the expr init so that the store is | |||
1156 | // attributed to a reasonable location - otherwise it may be attributed to | |||
1157 | // locations of subexpressions in the initialization. | |||
1158 | EmitExprAsInit(&l2r, &BlockFieldPseudoVar, | |||
1159 | MakeAddrLValue(blockField, type, AlignmentSource::Decl), | |||
1160 | /*captured by init*/ false); | |||
1161 | } | |||
1162 | ||||
1163 | // Activate the cleanup if layout pushed one. | |||
1164 | if (!CI.isByRef()) { | |||
1165 | EHScopeStack::stable_iterator cleanup = capture.getCleanup(); | |||
1166 | if (cleanup.isValid()) | |||
1167 | ActivateCleanupBlock(cleanup, blockInfo.DominatingIP); | |||
1168 | } | |||
1169 | } | |||
1170 | ||||
1171 | // Cast to the converted block-pointer type, which happens (somewhat | |||
1172 | // unfortunately) to be a pointer to function type. | |||
1173 | llvm::Value *result = Builder.CreatePointerCast( | |||
1174 | blockAddr.getPointer(), ConvertType(blockInfo.getBlockExpr()->getType())); | |||
1175 | ||||
1176 | if (IsOpenCL) { | |||
1177 | CGM.getOpenCLRuntime().recordBlockInfo(blockInfo.BlockExpression, InvokeFn, | |||
1178 | result); | |||
1179 | } | |||
1180 | ||||
1181 | return result; | |||
1182 | } | |||
1183 | ||||
1184 | ||||
1185 | llvm::Type *CodeGenModule::getBlockDescriptorType() { | |||
1186 | if (BlockDescriptorType) | |||
1187 | return BlockDescriptorType; | |||
1188 | ||||
1189 | llvm::Type *UnsignedLongTy = | |||
1190 | getTypes().ConvertType(getContext().UnsignedLongTy); | |||
1191 | ||||
1192 | // struct __block_descriptor { | |||
1193 | // unsigned long reserved; | |||
1194 | // unsigned long block_size; | |||
1195 | // | |||
1196 | // // later, the following will be added | |||
1197 | // | |||
1198 | // struct { | |||
1199 | // void (*copyHelper)(); | |||
1200 | // void (*copyHelper)(); | |||
1201 | // } helpers; // !!! optional | |||
1202 | // | |||
1203 | // const char *signature; // the block signature | |||
1204 | // const char *layout; // reserved | |||
1205 | // }; | |||
1206 | BlockDescriptorType = llvm::StructType::create( | |||
1207 | "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy); | |||
1208 | ||||
1209 | // Now form a pointer to that. | |||
1210 | unsigned AddrSpace = 0; | |||
1211 | if (getLangOpts().OpenCL) | |||
1212 | AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant); | |||
1213 | BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace); | |||
1214 | return BlockDescriptorType; | |||
1215 | } | |||
1216 | ||||
1217 | llvm::Type *CodeGenModule::getGenericBlockLiteralType() { | |||
1218 | if (GenericBlockLiteralType) | |||
1219 | return GenericBlockLiteralType; | |||
1220 | ||||
1221 | llvm::Type *BlockDescPtrTy = getBlockDescriptorType(); | |||
1222 | ||||
1223 | if (getLangOpts().OpenCL) { | |||
1224 | // struct __opencl_block_literal_generic { | |||
1225 | // int __size; | |||
1226 | // int __align; | |||
1227 | // __generic void *__invoke; | |||
1228 | // /* custom fields */ | |||
1229 | // }; | |||
1230 | SmallVector<llvm::Type *, 8> StructFields( | |||
1231 | {IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()}); | |||
1232 | if (auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) { | |||
1233 | for (auto I : Helper->getCustomFieldTypes()) | |||
1234 | StructFields.push_back(I); | |||
1235 | } | |||
1236 | GenericBlockLiteralType = llvm::StructType::create( | |||
1237 | StructFields, "struct.__opencl_block_literal_generic"); | |||
1238 | } else { | |||
1239 | // struct __block_literal_generic { | |||
1240 | // void *__isa; | |||
1241 | // int __flags; | |||
1242 | // int __reserved; | |||
1243 | // void (*__invoke)(void *); | |||
1244 | // struct __block_descriptor *__descriptor; | |||
1245 | // }; | |||
1246 | GenericBlockLiteralType = | |||
1247 | llvm::StructType::create("struct.__block_literal_generic", VoidPtrTy, | |||
1248 | IntTy, IntTy, VoidPtrTy, BlockDescPtrTy); | |||
1249 | } | |||
1250 | ||||
1251 | return GenericBlockLiteralType; | |||
1252 | } | |||
1253 | ||||
1254 | RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, | |||
1255 | ReturnValueSlot ReturnValue) { | |||
1256 | const BlockPointerType *BPT = | |||
1257 | E->getCallee()->getType()->getAs<BlockPointerType>(); | |||
1258 | llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee()); | |||
1259 | llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType(); | |||
1260 | llvm::Value *Func = nullptr; | |||
1261 | QualType FnType = BPT->getPointeeType(); | |||
1262 | ASTContext &Ctx = getContext(); | |||
1263 | CallArgList Args; | |||
1264 | ||||
1265 | if (getLangOpts().OpenCL) { | |||
1266 | // For OpenCL, BlockPtr is already casted to generic block literal. | |||
1267 | ||||
1268 | // First argument of a block call is a generic block literal casted to | |||
1269 | // generic void pointer, i.e. i8 addrspace(4)* | |||
1270 | llvm::Value *BlockDescriptor = Builder.CreatePointerCast( | |||
1271 | BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType()); | |||
1272 | QualType VoidPtrQualTy = Ctx.getPointerType( | |||
1273 | Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic)); | |||
1274 | Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy); | |||
1275 | // And the rest of the arguments. | |||
1276 | EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments()); | |||
1277 | ||||
1278 | // We *can* call the block directly unless it is a function argument. | |||
1279 | if (!isa<ParmVarDecl>(E->getCalleeDecl())) | |||
1280 | Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee()); | |||
1281 | else { | |||
1282 | llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2); | |||
1283 | Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); | |||
1284 | } | |||
1285 | } else { | |||
1286 | // Bitcast the block literal to a generic block literal. | |||
1287 | BlockPtr = Builder.CreatePointerCast( | |||
1288 | BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal"); | |||
1289 | // Get pointer to the block invoke function | |||
1290 | llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3); | |||
1291 | ||||
1292 | // First argument is a block literal casted to a void pointer | |||
1293 | BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy); | |||
1294 | Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy); | |||
1295 | // And the rest of the arguments. | |||
1296 | EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments()); | |||
1297 | ||||
1298 | // Load the function. | |||
1299 | Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); | |||
1300 | } | |||
1301 | ||||
1302 | const FunctionType *FuncTy = FnType->castAs<FunctionType>(); | |||
1303 | const CGFunctionInfo &FnInfo = | |||
1304 | CGM.getTypes().arrangeBlockFunctionCall(Args, FuncTy); | |||
1305 | ||||
1306 | // Cast the function pointer to the right type. | |||
1307 | llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo); | |||
1308 | ||||
1309 | llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); | |||
1310 | Func = Builder.CreatePointerCast(Func, BlockFTyPtr); | |||
1311 | ||||
1312 | // Prepare the callee. | |||
1313 | CGCallee Callee(CGCalleeInfo(), Func); | |||
1314 | ||||
1315 | // And call the block. | |||
1316 | return EmitCall(FnInfo, Callee, ReturnValue, Args); | |||
1317 | } | |||
1318 | ||||
1319 | Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) { | |||
1320 | assert(BlockInfo && "evaluating block ref without block information?")((BlockInfo && "evaluating block ref without block information?" ) ? static_cast<void> (0) : __assert_fail ("BlockInfo && \"evaluating block ref without block information?\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1320, __PRETTY_FUNCTION__)); | |||
1321 | const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable); | |||
1322 | ||||
1323 | // Handle constant captures. | |||
1324 | if (capture.isConstant()) return LocalDeclMap.find(variable)->second; | |||
1325 | ||||
1326 | Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), | |||
1327 | "block.capture.addr"); | |||
1328 | ||||
1329 | if (variable->isEscapingByref()) { | |||
1330 | // addr should be a void** right now. Load, then cast the result | |||
1331 | // to byref*. | |||
1332 | ||||
1333 | auto &byrefInfo = getBlockByrefInfo(variable); | |||
1334 | addr = Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment); | |||
1335 | ||||
1336 | auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0); | |||
1337 | addr = Builder.CreateBitCast(addr, byrefPointerType, "byref.addr"); | |||
1338 | ||||
1339 | addr = emitBlockByrefAddress(addr, byrefInfo, /*follow*/ true, | |||
1340 | variable->getName()); | |||
1341 | } | |||
1342 | ||||
1343 | assert((!variable->isNonEscapingByref() ||(((!variable->isNonEscapingByref() || capture.fieldType()-> isReferenceType()) && "the capture field of a non-escaping variable should have a " "reference type") ? static_cast<void> (0) : __assert_fail ("(!variable->isNonEscapingByref() || capture.fieldType()->isReferenceType()) && \"the capture field of a non-escaping variable should have a \" \"reference type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1346, __PRETTY_FUNCTION__)) | |||
1344 | capture.fieldType()->isReferenceType()) &&(((!variable->isNonEscapingByref() || capture.fieldType()-> isReferenceType()) && "the capture field of a non-escaping variable should have a " "reference type") ? static_cast<void> (0) : __assert_fail ("(!variable->isNonEscapingByref() || capture.fieldType()->isReferenceType()) && \"the capture field of a non-escaping variable should have a \" \"reference type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1346, __PRETTY_FUNCTION__)) | |||
1345 | "the capture field of a non-escaping variable should have a "(((!variable->isNonEscapingByref() || capture.fieldType()-> isReferenceType()) && "the capture field of a non-escaping variable should have a " "reference type") ? static_cast<void> (0) : __assert_fail ("(!variable->isNonEscapingByref() || capture.fieldType()->isReferenceType()) && \"the capture field of a non-escaping variable should have a \" \"reference type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1346, __PRETTY_FUNCTION__)) | |||
1346 | "reference type")(((!variable->isNonEscapingByref() || capture.fieldType()-> isReferenceType()) && "the capture field of a non-escaping variable should have a " "reference type") ? static_cast<void> (0) : __assert_fail ("(!variable->isNonEscapingByref() || capture.fieldType()->isReferenceType()) && \"the capture field of a non-escaping variable should have a \" \"reference type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1346, __PRETTY_FUNCTION__)); | |||
1347 | if (capture.fieldType()->isReferenceType()) | |||
1348 | addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType())); | |||
1349 | ||||
1350 | return addr; | |||
1351 | } | |||
1352 | ||||
1353 | void CodeGenModule::setAddrOfGlobalBlock(const BlockExpr *BE, | |||
1354 | llvm::Constant *Addr) { | |||
1355 | bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second; | |||
1356 | (void)Ok; | |||
1357 | assert(Ok && "Trying to replace an already-existing global block!")((Ok && "Trying to replace an already-existing global block!" ) ? static_cast<void> (0) : __assert_fail ("Ok && \"Trying to replace an already-existing global block!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1357, __PRETTY_FUNCTION__)); | |||
1358 | } | |||
1359 | ||||
1360 | llvm::Constant * | |||
1361 | CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE, | |||
1362 | StringRef Name) { | |||
1363 | if (llvm::Constant *Block = getAddrOfGlobalBlockIfEmitted(BE)) | |||
1364 | return Block; | |||
1365 | ||||
1366 | CGBlockInfo blockInfo(BE->getBlockDecl(), Name); | |||
1367 | blockInfo.BlockExpression = BE; | |||
1368 | ||||
1369 | // Compute information about the layout, etc., of this block. | |||
1370 | computeBlockInfo(*this, nullptr, blockInfo); | |||
1371 | ||||
1372 | // Using that metadata, generate the actual block function. | |||
1373 | { | |||
1374 | CodeGenFunction::DeclMapTy LocalDeclMap; | |||
1375 | CodeGenFunction(*this).GenerateBlockFunction( | |||
1376 | GlobalDecl(), blockInfo, LocalDeclMap, | |||
1377 | /*IsLambdaConversionToBlock*/ false, /*BuildGlobalBlock*/ true); | |||
1378 | } | |||
1379 | ||||
1380 | return getAddrOfGlobalBlockIfEmitted(BE); | |||
1381 | } | |||
1382 | ||||
1383 | static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, | |||
1384 | const CGBlockInfo &blockInfo, | |||
1385 | llvm::Constant *blockFn) { | |||
1386 | assert(blockInfo.CanBeGlobal)((blockInfo.CanBeGlobal) ? static_cast<void> (0) : __assert_fail ("blockInfo.CanBeGlobal", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1386, __PRETTY_FUNCTION__)); | |||
1387 | // Callers should detect this case on their own: calling this function | |||
1388 | // generally requires computing layout information, which is a waste of time | |||
1389 | // if we've already emitted this block. | |||
1390 | assert(!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) &&((!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression ) && "Refusing to re-emit a global block.") ? static_cast <void> (0) : __assert_fail ("!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) && \"Refusing to re-emit a global block.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1391, __PRETTY_FUNCTION__)) | |||
1391 | "Refusing to re-emit a global block.")((!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression ) && "Refusing to re-emit a global block.") ? static_cast <void> (0) : __assert_fail ("!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) && \"Refusing to re-emit a global block.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1391, __PRETTY_FUNCTION__)); | |||
1392 | ||||
1393 | // Generate the constants for the block literal initializer. | |||
1394 | ConstantInitBuilder builder(CGM); | |||
1395 | auto fields = builder.beginStruct(); | |||
1396 | ||||
1397 | bool IsOpenCL = CGM.getLangOpts().OpenCL; | |||
1398 | bool IsWindows = CGM.getTarget().getTriple().isOSWindows(); | |||
1399 | if (!IsOpenCL) { | |||
1400 | // isa | |||
1401 | if (IsWindows) | |||
1402 | fields.addNullPointer(CGM.Int8PtrPtrTy); | |||
1403 | else | |||
1404 | fields.add(CGM.getNSConcreteGlobalBlock()); | |||
1405 | ||||
1406 | // __flags | |||
1407 | BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE; | |||
1408 | if (blockInfo.UsesStret) | |||
1409 | flags |= BLOCK_USE_STRET; | |||
1410 | ||||
1411 | fields.addInt(CGM.IntTy, flags.getBitMask()); | |||
1412 | ||||
1413 | // Reserved | |||
1414 | fields.addInt(CGM.IntTy, 0); | |||
1415 | } else { | |||
1416 | fields.addInt(CGM.IntTy, blockInfo.BlockSize.getQuantity()); | |||
1417 | fields.addInt(CGM.IntTy, blockInfo.BlockAlign.getQuantity()); | |||
1418 | } | |||
1419 | ||||
1420 | // Function | |||
1421 | fields.add(blockFn); | |||
1422 | ||||
1423 | if (!IsOpenCL) { | |||
1424 | // Descriptor | |||
1425 | fields.add(buildBlockDescriptor(CGM, blockInfo)); | |||
1426 | } else if (auto *Helper = | |||
1427 | CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) { | |||
1428 | for (auto I : Helper->getCustomFieldValues(CGM, blockInfo)) { | |||
1429 | fields.add(I); | |||
1430 | } | |||
1431 | } | |||
1432 | ||||
1433 | unsigned AddrSpace = 0; | |||
1434 | if (CGM.getContext().getLangOpts().OpenCL) | |||
1435 | AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_global); | |||
1436 | ||||
1437 | llvm::GlobalVariable *literal = fields.finishAndCreateGlobal( | |||
1438 | "__block_literal_global", blockInfo.BlockAlign, | |||
1439 | /*constant*/ !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace); | |||
1440 | ||||
1441 | literal->addAttribute("objc_arc_inert"); | |||
1442 | ||||
1443 | // Windows does not allow globals to be initialised to point to globals in | |||
1444 | // different DLLs. Any such variables must run code to initialise them. | |||
1445 | if (IsWindows) { | |||
1446 | auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, | |||
1447 | {}), llvm::GlobalValue::InternalLinkage, ".block_isa_init", | |||
1448 | &CGM.getModule()); | |||
1449 | llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry", | |||
1450 | Init)); | |||
1451 | b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(), | |||
1452 | b.CreateStructGEP(literal, 0), CGM.getPointerAlign().getQuantity()); | |||
1453 | b.CreateRetVoid(); | |||
1454 | // We can't use the normal LLVM global initialisation array, because we | |||
1455 | // need to specify that this runs early in library initialisation. | |||
1456 | auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), | |||
1457 | /*isConstant*/true, llvm::GlobalValue::InternalLinkage, | |||
1458 | Init, ".block_isa_init_ptr"); | |||
1459 | InitVar->setSection(".CRT$XCLa"); | |||
1460 | CGM.addUsedGlobal(InitVar); | |||
1461 | } | |||
1462 | ||||
1463 | // Return a constant of the appropriately-casted type. | |||
1464 | llvm::Type *RequiredType = | |||
1465 | CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType()); | |||
1466 | llvm::Constant *Result = | |||
1467 | llvm::ConstantExpr::getPointerCast(literal, RequiredType); | |||
1468 | CGM.setAddrOfGlobalBlock(blockInfo.BlockExpression, Result); | |||
1469 | if (CGM.getContext().getLangOpts().OpenCL) | |||
1470 | CGM.getOpenCLRuntime().recordBlockInfo( | |||
1471 | blockInfo.BlockExpression, | |||
1472 | cast<llvm::Function>(blockFn->stripPointerCasts()), Result); | |||
1473 | return Result; | |||
1474 | } | |||
1475 | ||||
1476 | void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D, | |||
1477 | unsigned argNum, | |||
1478 | llvm::Value *arg) { | |||
1479 | assert(BlockInfo && "not emitting prologue of block invocation function?!")((BlockInfo && "not emitting prologue of block invocation function?!" ) ? static_cast<void> (0) : __assert_fail ("BlockInfo && \"not emitting prologue of block invocation function?!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1479, __PRETTY_FUNCTION__)); | |||
1480 | ||||
1481 | // Allocate a stack slot like for any local variable to guarantee optimal | |||
1482 | // debug info at -O0. The mem2reg pass will eliminate it when optimizing. | |||
1483 | Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); | |||
1484 | Builder.CreateStore(arg, alloc); | |||
1485 | if (CGDebugInfo *DI = getDebugInfo()) { | |||
1486 | if (CGM.getCodeGenOpts().getDebugInfo() >= | |||
1487 | codegenoptions::LimitedDebugInfo) { | |||
1488 | DI->setLocation(D->getLocation()); | |||
1489 | DI->EmitDeclareOfBlockLiteralArgVariable( | |||
1490 | *BlockInfo, D->getName(), argNum, | |||
1491 | cast<llvm::AllocaInst>(alloc.getPointer()), Builder); | |||
1492 | } | |||
1493 | } | |||
1494 | ||||
1495 | SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getBeginLoc(); | |||
1496 | ApplyDebugLocation Scope(*this, StartLoc); | |||
1497 | ||||
1498 | // Instead of messing around with LocalDeclMap, just set the value | |||
1499 | // directly as BlockPointer. | |||
1500 | BlockPointer = Builder.CreatePointerCast( | |||
1501 | arg, | |||
1502 | BlockInfo->StructureType->getPointerTo( | |||
1503 | getContext().getLangOpts().OpenCL | |||
1504 | ? getContext().getTargetAddressSpace(LangAS::opencl_generic) | |||
1505 | : 0), | |||
1506 | "block"); | |||
1507 | } | |||
1508 | ||||
1509 | Address CodeGenFunction::LoadBlockStruct() { | |||
1510 | assert(BlockInfo && "not in a block invocation function!")((BlockInfo && "not in a block invocation function!") ? static_cast<void> (0) : __assert_fail ("BlockInfo && \"not in a block invocation function!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1510, __PRETTY_FUNCTION__)); | |||
1511 | assert(BlockPointer && "no block pointer set!")((BlockPointer && "no block pointer set!") ? static_cast <void> (0) : __assert_fail ("BlockPointer && \"no block pointer set!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1511, __PRETTY_FUNCTION__)); | |||
1512 | return Address(BlockPointer, BlockInfo->BlockAlign); | |||
1513 | } | |||
1514 | ||||
1515 | llvm::Function * | |||
1516 | CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, | |||
1517 | const CGBlockInfo &blockInfo, | |||
1518 | const DeclMapTy &ldm, | |||
1519 | bool IsLambdaConversionToBlock, | |||
1520 | bool BuildGlobalBlock) { | |||
1521 | const BlockDecl *blockDecl = blockInfo.getBlockDecl(); | |||
1522 | ||||
1523 | CurGD = GD; | |||
1524 | ||||
1525 | CurEHLocation = blockInfo.getBlockExpr()->getEndLoc(); | |||
1526 | ||||
1527 | BlockInfo = &blockInfo; | |||
1528 | ||||
1529 | // Arrange for local static and local extern declarations to appear | |||
1530 | // to be local to this function as well, in case they're directly | |||
1531 | // referenced in a block. | |||
1532 | for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) { | |||
1533 | const auto *var = dyn_cast<VarDecl>(i->first); | |||
1534 | if (var && !var->hasLocalStorage()) | |||
1535 | setAddrOfLocalVar(var, i->second); | |||
1536 | } | |||
1537 | ||||
1538 | // Begin building the function declaration. | |||
1539 | ||||
1540 | // Build the argument list. | |||
1541 | FunctionArgList args; | |||
1542 | ||||
1543 | // The first argument is the block pointer. Just take it as a void* | |||
1544 | // and cast it later. | |||
1545 | QualType selfTy = getContext().VoidPtrTy; | |||
1546 | ||||
1547 | // For OpenCL passed block pointer can be private AS local variable or | |||
1548 | // global AS program scope variable (for the case with and without captures). | |||
1549 | // Generic AS is used therefore to be able to accommodate both private and | |||
1550 | // generic AS in one implementation. | |||
1551 | if (getLangOpts().OpenCL) | |||
1552 | selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType( | |||
1553 | getContext().VoidTy, LangAS::opencl_generic)); | |||
1554 | ||||
1555 | IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); | |||
1556 | ||||
1557 | ImplicitParamDecl SelfDecl(getContext(), const_cast<BlockDecl *>(blockDecl), | |||
1558 | SourceLocation(), II, selfTy, | |||
1559 | ImplicitParamDecl::ObjCSelf); | |||
1560 | args.push_back(&SelfDecl); | |||
1561 | ||||
1562 | // Now add the rest of the parameters. | |||
1563 | args.append(blockDecl->param_begin(), blockDecl->param_end()); | |||
1564 | ||||
1565 | // Create the function declaration. | |||
1566 | const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType(); | |||
1567 | const CGFunctionInfo &fnInfo = | |||
1568 | CGM.getTypes().arrangeBlockFunctionDeclaration(fnType, args); | |||
1569 | if (CGM.ReturnSlotInterferesWithArgs(fnInfo)) | |||
1570 | blockInfo.UsesStret = true; | |||
1571 | ||||
1572 | llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo); | |||
1573 | ||||
1574 | StringRef name = CGM.getBlockMangledName(GD, blockDecl); | |||
1575 | llvm::Function *fn = llvm::Function::Create( | |||
1576 | fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule()); | |||
1577 | CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); | |||
1578 | ||||
1579 | if (BuildGlobalBlock) { | |||
1580 | auto GenVoidPtrTy = getContext().getLangOpts().OpenCL | |||
1581 | ? CGM.getOpenCLRuntime().getGenericVoidPointerType() | |||
1582 | : VoidPtrTy; | |||
1583 | buildGlobalBlock(CGM, blockInfo, | |||
1584 | llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy)); | |||
1585 | } | |||
1586 | ||||
1587 | // Begin generating the function. | |||
1588 | StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args, | |||
1589 | blockDecl->getLocation(), | |||
1590 | blockInfo.getBlockExpr()->getBody()->getBeginLoc()); | |||
1591 | ||||
1592 | // Okay. Undo some of what StartFunction did. | |||
1593 | ||||
1594 | // At -O0 we generate an explicit alloca for the BlockPointer, so the RA | |||
1595 | // won't delete the dbg.declare intrinsics for captured variables. | |||
1596 | llvm::Value *BlockPointerDbgLoc = BlockPointer; | |||
1597 | if (CGM.getCodeGenOpts().OptimizationLevel == 0) { | |||
1598 | // Allocate a stack slot for it, so we can point the debugger to it | |||
1599 | Address Alloca = CreateTempAlloca(BlockPointer->getType(), | |||
1600 | getPointerAlign(), | |||
1601 | "block.addr"); | |||
1602 | // Set the DebugLocation to empty, so the store is recognized as a | |||
1603 | // frame setup instruction by llvm::DwarfDebug::beginFunction(). | |||
1604 | auto NL = ApplyDebugLocation::CreateEmpty(*this); | |||
1605 | Builder.CreateStore(BlockPointer, Alloca); | |||
1606 | BlockPointerDbgLoc = Alloca.getPointer(); | |||
1607 | } | |||
1608 | ||||
1609 | // If we have a C++ 'this' reference, go ahead and force it into | |||
1610 | // existence now. | |||
1611 | if (blockDecl->capturesCXXThis()) { | |||
1612 | Address addr = Builder.CreateStructGEP( | |||
1613 | LoadBlockStruct(), blockInfo.CXXThisIndex, "block.captured-this"); | |||
1614 | CXXThisValue = Builder.CreateLoad(addr, "this"); | |||
1615 | } | |||
1616 | ||||
1617 | // Also force all the constant captures. | |||
1618 | for (const auto &CI : blockDecl->captures()) { | |||
1619 | const VarDecl *variable = CI.getVariable(); | |||
1620 | const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); | |||
1621 | if (!capture.isConstant()) continue; | |||
1622 | ||||
1623 | CharUnits align = getContext().getDeclAlign(variable); | |||
1624 | Address alloca = | |||
1625 | CreateMemTemp(variable->getType(), align, "block.captured-const"); | |||
1626 | ||||
1627 | Builder.CreateStore(capture.getConstant(), alloca); | |||
1628 | ||||
1629 | setAddrOfLocalVar(variable, alloca); | |||
1630 | } | |||
1631 | ||||
1632 | // Save a spot to insert the debug information for all the DeclRefExprs. | |||
1633 | llvm::BasicBlock *entry = Builder.GetInsertBlock(); | |||
1634 | llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint(); | |||
1635 | --entry_ptr; | |||
1636 | ||||
1637 | if (IsLambdaConversionToBlock) | |||
1638 | EmitLambdaBlockInvokeBody(); | |||
1639 | else { | |||
1640 | PGO.assignRegionCounters(GlobalDecl(blockDecl), fn); | |||
1641 | incrementProfileCounter(blockDecl->getBody()); | |||
1642 | EmitStmt(blockDecl->getBody()); | |||
1643 | } | |||
1644 | ||||
1645 | // Remember where we were... | |||
1646 | llvm::BasicBlock *resume = Builder.GetInsertBlock(); | |||
1647 | ||||
1648 | // Go back to the entry. | |||
1649 | ++entry_ptr; | |||
1650 | Builder.SetInsertPoint(entry, entry_ptr); | |||
1651 | ||||
1652 | // Emit debug information for all the DeclRefExprs. | |||
1653 | // FIXME: also for 'this' | |||
1654 | if (CGDebugInfo *DI = getDebugInfo()) { | |||
1655 | for (const auto &CI : blockDecl->captures()) { | |||
1656 | const VarDecl *variable = CI.getVariable(); | |||
1657 | DI->EmitLocation(Builder, variable->getLocation()); | |||
1658 | ||||
1659 | if (CGM.getCodeGenOpts().getDebugInfo() >= | |||
1660 | codegenoptions::LimitedDebugInfo) { | |||
1661 | const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); | |||
1662 | if (capture.isConstant()) { | |||
1663 | auto addr = LocalDeclMap.find(variable)->second; | |||
1664 | (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), | |||
1665 | Builder); | |||
1666 | continue; | |||
1667 | } | |||
1668 | ||||
1669 | DI->EmitDeclareOfBlockDeclRefVariable( | |||
1670 | variable, BlockPointerDbgLoc, Builder, blockInfo, | |||
1671 | entry_ptr == entry->end() ? nullptr : &*entry_ptr); | |||
1672 | } | |||
1673 | } | |||
1674 | // Recover location if it was changed in the above loop. | |||
1675 | DI->EmitLocation(Builder, | |||
1676 | cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); | |||
1677 | } | |||
1678 | ||||
1679 | // And resume where we left off. | |||
1680 | if (resume == nullptr) | |||
1681 | Builder.ClearInsertionPoint(); | |||
1682 | else | |||
1683 | Builder.SetInsertPoint(resume); | |||
1684 | ||||
1685 | FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); | |||
1686 | ||||
1687 | return fn; | |||
1688 | } | |||
1689 | ||||
1690 | static std::pair<BlockCaptureEntityKind, BlockFieldFlags> | |||
1691 | computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, | |||
1692 | const LangOptions &LangOpts) { | |||
1693 | if (CI.getCopyExpr()) { | |||
1694 | assert(!CI.isByRef())((!CI.isByRef()) ? static_cast<void> (0) : __assert_fail ("!CI.isByRef()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1694, __PRETTY_FUNCTION__)); | |||
1695 | // don't bother computing flags | |||
1696 | return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags()); | |||
1697 | } | |||
1698 | BlockFieldFlags Flags; | |||
1699 | if (CI.isEscapingByref()) { | |||
1700 | Flags = BLOCK_FIELD_IS_BYREF; | |||
1701 | if (T.isObjCGCWeak()) | |||
1702 | Flags |= BLOCK_FIELD_IS_WEAK; | |||
1703 | return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags); | |||
1704 | } | |||
1705 | ||||
1706 | Flags = BLOCK_FIELD_IS_OBJECT; | |||
1707 | bool isBlockPointer = T->isBlockPointerType(); | |||
1708 | if (isBlockPointer) | |||
1709 | Flags = BLOCK_FIELD_IS_BLOCK; | |||
1710 | ||||
1711 | switch (T.isNonTrivialToPrimitiveCopy()) { | |||
1712 | case QualType::PCK_Struct: | |||
1713 | return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct, | |||
1714 | BlockFieldFlags()); | |||
1715 | case QualType::PCK_ARCWeak: | |||
1716 | // We need to register __weak direct captures with the runtime. | |||
1717 | return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags); | |||
1718 | case QualType::PCK_ARCStrong: | |||
1719 | // We need to retain the copied value for __strong direct captures. | |||
1720 | // If it's a block pointer, we have to copy the block and assign that to | |||
1721 | // the destination pointer, so we might as well use _Block_object_assign. | |||
1722 | // Otherwise we can avoid that. | |||
1723 | return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong | |||
1724 | : BlockCaptureEntityKind::BlockObject, | |||
1725 | Flags); | |||
1726 | case QualType::PCK_Trivial: | |||
1727 | case QualType::PCK_VolatileTrivial: { | |||
1728 | if (!T->isObjCRetainableType()) | |||
1729 | // For all other types, the memcpy is fine. | |||
1730 | return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags()); | |||
1731 | ||||
1732 | // Special rules for ARC captures: | |||
1733 | Qualifiers QS = T.getQualifiers(); | |||
1734 | ||||
1735 | // Non-ARC captures of retainable pointers are strong and | |||
1736 | // therefore require a call to _Block_object_assign. | |||
1737 | if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount) | |||
1738 | return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags); | |||
1739 | ||||
1740 | // Otherwise the memcpy is fine. | |||
1741 | return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags()); | |||
1742 | } | |||
1743 | } | |||
1744 | llvm_unreachable("after exhaustive PrimitiveCopyKind switch")::llvm::llvm_unreachable_internal("after exhaustive PrimitiveCopyKind switch" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1744); | |||
1745 | } | |||
1746 | ||||
1747 | static std::pair<BlockCaptureEntityKind, BlockFieldFlags> | |||
1748 | computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, | |||
1749 | const LangOptions &LangOpts); | |||
1750 | ||||
1751 | /// Find the set of block captures that need to be explicitly copied or destroy. | |||
1752 | static void findBlockCapturedManagedEntities( | |||
1753 | const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, | |||
1754 | SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures) { | |||
1755 | for (const auto &CI : BlockInfo.getBlockDecl()->captures()) { | |||
1756 | const VarDecl *Variable = CI.getVariable(); | |||
1757 | const CGBlockInfo::Capture &Capture = BlockInfo.getCapture(Variable); | |||
1758 | if (Capture.isConstant()) | |||
1759 | continue; | |||
1760 | ||||
1761 | QualType VT = Capture.fieldType(); | |||
1762 | auto CopyInfo = computeCopyInfoForBlockCapture(CI, VT, LangOpts); | |||
1763 | auto DisposeInfo = computeDestroyInfoForBlockCapture(CI, VT, LangOpts); | |||
1764 | if (CopyInfo.first != BlockCaptureEntityKind::None || | |||
1765 | DisposeInfo.first != BlockCaptureEntityKind::None) | |||
1766 | ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first, | |||
1767 | CopyInfo.second, DisposeInfo.second, CI, | |||
1768 | Capture); | |||
1769 | } | |||
1770 | ||||
1771 | // Sort the captures by offset. | |||
1772 | llvm::sort(ManagedCaptures); | |||
1773 | } | |||
1774 | ||||
1775 | namespace { | |||
1776 | /// Release a __block variable. | |||
1777 | struct CallBlockRelease final : EHScopeStack::Cleanup { | |||
1778 | Address Addr; | |||
1779 | BlockFieldFlags FieldFlags; | |||
1780 | bool LoadBlockVarAddr, CanThrow; | |||
1781 | ||||
1782 | CallBlockRelease(Address Addr, BlockFieldFlags Flags, bool LoadValue, | |||
1783 | bool CT) | |||
1784 | : Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue), | |||
1785 | CanThrow(CT) {} | |||
1786 | ||||
1787 | void Emit(CodeGenFunction &CGF, Flags flags) override { | |||
1788 | llvm::Value *BlockVarAddr; | |||
1789 | if (LoadBlockVarAddr) { | |||
1790 | BlockVarAddr = CGF.Builder.CreateLoad(Addr); | |||
1791 | BlockVarAddr = CGF.Builder.CreateBitCast(BlockVarAddr, CGF.VoidPtrTy); | |||
1792 | } else { | |||
1793 | BlockVarAddr = Addr.getPointer(); | |||
1794 | } | |||
1795 | ||||
1796 | CGF.BuildBlockRelease(BlockVarAddr, FieldFlags, CanThrow); | |||
1797 | } | |||
1798 | }; | |||
1799 | } // end anonymous namespace | |||
1800 | ||||
1801 | /// Check if \p T is a C++ class that has a destructor that can throw. | |||
1802 | bool CodeGenFunction::cxxDestructorCanThrow(QualType T) { | |||
1803 | if (const auto *RD = T->getAsCXXRecordDecl()) | |||
| ||||
1804 | if (const CXXDestructorDecl *DD = RD->getDestructor()) | |||
1805 | return DD->getType()->getAs<FunctionProtoType>()->canThrow(); | |||
| ||||
1806 | return false; | |||
1807 | } | |||
1808 | ||||
1809 | // Return a string that has the information about a capture. | |||
1810 | static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, | |||
1811 | CaptureStrKind StrKind, | |||
1812 | CharUnits BlockAlignment, | |||
1813 | CodeGenModule &CGM) { | |||
1814 | std::string Str; | |||
1815 | ASTContext &Ctx = CGM.getContext(); | |||
1816 | const BlockDecl::Capture &CI = *E.CI; | |||
1817 | QualType CaptureTy = CI.getVariable()->getType(); | |||
1818 | ||||
1819 | BlockCaptureEntityKind Kind; | |||
1820 | BlockFieldFlags Flags; | |||
1821 | ||||
1822 | // CaptureStrKind::Merged should be passed only when the operations and the | |||
1823 | // flags are the same for copy and dispose. | |||
1824 | assert((StrKind != CaptureStrKind::Merged ||(((StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && "different operations and flags" ) ? static_cast<void> (0) : __assert_fail ("(StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && \"different operations and flags\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1826, __PRETTY_FUNCTION__)) | |||
1825 | (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) &&(((StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && "different operations and flags" ) ? static_cast<void> (0) : __assert_fail ("(StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && \"different operations and flags\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1826, __PRETTY_FUNCTION__)) | |||
1826 | "different operations and flags")(((StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && "different operations and flags" ) ? static_cast<void> (0) : __assert_fail ("(StrKind != CaptureStrKind::Merged || (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && \"different operations and flags\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1826, __PRETTY_FUNCTION__)); | |||
1827 | ||||
1828 | if (StrKind == CaptureStrKind::DisposeHelper) { | |||
1829 | Kind = E.DisposeKind; | |||
1830 | Flags = E.DisposeFlags; | |||
1831 | } else { | |||
1832 | Kind = E.CopyKind; | |||
1833 | Flags = E.CopyFlags; | |||
1834 | } | |||
1835 | ||||
1836 | switch (Kind) { | |||
1837 | case BlockCaptureEntityKind::CXXRecord: { | |||
1838 | Str += "c"; | |||
1839 | SmallString<256> TyStr; | |||
1840 | llvm::raw_svector_ostream Out(TyStr); | |||
1841 | CGM.getCXXABI().getMangleContext().mangleTypeName(CaptureTy, Out); | |||
1842 | Str += llvm::to_string(TyStr.size()) + TyStr.c_str(); | |||
1843 | break; | |||
1844 | } | |||
1845 | case BlockCaptureEntityKind::ARCWeak: | |||
1846 | Str += "w"; | |||
1847 | break; | |||
1848 | case BlockCaptureEntityKind::ARCStrong: | |||
1849 | Str += "s"; | |||
1850 | break; | |||
1851 | case BlockCaptureEntityKind::BlockObject: { | |||
1852 | const VarDecl *Var = CI.getVariable(); | |||
1853 | unsigned F = Flags.getBitMask(); | |||
1854 | if (F & BLOCK_FIELD_IS_BYREF) { | |||
1855 | Str += "r"; | |||
1856 | if (F & BLOCK_FIELD_IS_WEAK) | |||
1857 | Str += "w"; | |||
1858 | else { | |||
1859 | // If CaptureStrKind::Merged is passed, check both the copy expression | |||
1860 | // and the destructor. | |||
1861 | if (StrKind != CaptureStrKind::DisposeHelper) { | |||
1862 | if (Ctx.getBlockVarCopyInit(Var).canThrow()) | |||
1863 | Str += "c"; | |||
1864 | } | |||
1865 | if (StrKind != CaptureStrKind::CopyHelper) { | |||
1866 | if (CodeGenFunction::cxxDestructorCanThrow(CaptureTy)) | |||
1867 | Str += "d"; | |||
1868 | } | |||
1869 | } | |||
1870 | } else { | |||
1871 | assert((F & BLOCK_FIELD_IS_OBJECT) && "unexpected flag value")(((F & BLOCK_FIELD_IS_OBJECT) && "unexpected flag value" ) ? static_cast<void> (0) : __assert_fail ("(F & BLOCK_FIELD_IS_OBJECT) && \"unexpected flag value\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1871, __PRETTY_FUNCTION__)); | |||
1872 | if (F == BLOCK_FIELD_IS_BLOCK) | |||
1873 | Str += "b"; | |||
1874 | else | |||
1875 | Str += "o"; | |||
1876 | } | |||
1877 | break; | |||
1878 | } | |||
1879 | case BlockCaptureEntityKind::NonTrivialCStruct: { | |||
1880 | bool IsVolatile = CaptureTy.isVolatileQualified(); | |||
1881 | CharUnits Alignment = | |||
1882 | BlockAlignment.alignmentAtOffset(E.Capture->getOffset()); | |||
1883 | ||||
1884 | Str += "n"; | |||
1885 | std::string FuncStr; | |||
1886 | if (StrKind == CaptureStrKind::DisposeHelper) | |||
1887 | FuncStr = CodeGenFunction::getNonTrivialDestructorStr( | |||
1888 | CaptureTy, Alignment, IsVolatile, Ctx); | |||
1889 | else | |||
1890 | // If CaptureStrKind::Merged is passed, use the copy constructor string. | |||
1891 | // It has all the information that the destructor string has. | |||
1892 | FuncStr = CodeGenFunction::getNonTrivialCopyConstructorStr( | |||
1893 | CaptureTy, Alignment, IsVolatile, Ctx); | |||
1894 | // The underscore is necessary here because non-trivial copy constructor | |||
1895 | // and destructor strings can start with a number. | |||
1896 | Str += llvm::to_string(FuncStr.size()) + "_" + FuncStr; | |||
1897 | break; | |||
1898 | } | |||
1899 | case BlockCaptureEntityKind::None: | |||
1900 | break; | |||
1901 | } | |||
1902 | ||||
1903 | return Str; | |||
1904 | } | |||
1905 | ||||
1906 | static std::string getCopyDestroyHelperFuncName( | |||
1907 | const SmallVectorImpl<BlockCaptureManagedEntity> &Captures, | |||
1908 | CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM) { | |||
1909 | assert((StrKind == CaptureStrKind::CopyHelper ||(((StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind ::DisposeHelper) && "unexpected CaptureStrKind") ? static_cast <void> (0) : __assert_fail ("(StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind::DisposeHelper) && \"unexpected CaptureStrKind\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1911, __PRETTY_FUNCTION__)) | |||
1910 | StrKind == CaptureStrKind::DisposeHelper) &&(((StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind ::DisposeHelper) && "unexpected CaptureStrKind") ? static_cast <void> (0) : __assert_fail ("(StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind::DisposeHelper) && \"unexpected CaptureStrKind\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1911, __PRETTY_FUNCTION__)) | |||
1911 | "unexpected CaptureStrKind")(((StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind ::DisposeHelper) && "unexpected CaptureStrKind") ? static_cast <void> (0) : __assert_fail ("(StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind::DisposeHelper) && \"unexpected CaptureStrKind\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 1911, __PRETTY_FUNCTION__)); | |||
1912 | std::string Name = StrKind == CaptureStrKind::CopyHelper | |||
1913 | ? "__copy_helper_block_" | |||
1914 | : "__destroy_helper_block_"; | |||
1915 | if (CGM.getLangOpts().Exceptions) | |||
1916 | Name += "e"; | |||
1917 | if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions) | |||
1918 | Name += "a"; | |||
1919 | Name += llvm::to_string(BlockAlignment.getQuantity()) + "_"; | |||
1920 | ||||
1921 | for (const BlockCaptureManagedEntity &E : Captures) { | |||
1922 | Name += llvm::to_string(E.Capture->getOffset().getQuantity()); | |||
1923 | Name += getBlockCaptureStr(E, StrKind, BlockAlignment, CGM); | |||
1924 | } | |||
1925 | ||||
1926 | return Name; | |||
1927 | } | |||
1928 | ||||
1929 | static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind, | |||
1930 | Address Field, QualType CaptureType, | |||
1931 | BlockFieldFlags Flags, bool ForCopyHelper, | |||
1932 | VarDecl *Var, CodeGenFunction &CGF) { | |||
1933 | bool EHOnly = ForCopyHelper; | |||
1934 | ||||
1935 | switch (CaptureKind) { | |||
1936 | case BlockCaptureEntityKind::CXXRecord: | |||
1937 | case BlockCaptureEntityKind::ARCWeak: | |||
1938 | case BlockCaptureEntityKind::NonTrivialCStruct: | |||
1939 | case BlockCaptureEntityKind::ARCStrong: { | |||
1940 | if (CaptureType.isDestructedType() && | |||
1941 | (!EHOnly || CGF.needsEHCleanup(CaptureType.isDestructedType()))) { | |||
1942 | CodeGenFunction::Destroyer *Destroyer = | |||
1943 | CaptureKind == BlockCaptureEntityKind::ARCStrong | |||
1944 | ? CodeGenFunction::destroyARCStrongImprecise | |||
1945 | : CGF.getDestroyer(CaptureType.isDestructedType()); | |||
1946 | CleanupKind Kind = | |||
1947 | EHOnly ? EHCleanup | |||
1948 | : CGF.getCleanupKind(CaptureType.isDestructedType()); | |||
1949 | CGF.pushDestroy(Kind, Field, CaptureType, Destroyer, Kind & EHCleanup); | |||
1950 | } | |||
1951 | break; | |||
1952 | } | |||
1953 | case BlockCaptureEntityKind::BlockObject: { | |||
1954 | if (!EHOnly || CGF.getLangOpts().Exceptions) { | |||
1955 | CleanupKind Kind = EHOnly ? EHCleanup : NormalAndEHCleanup; | |||
1956 | // Calls to _Block_object_dispose along the EH path in the copy helper | |||
1957 | // function don't throw as newly-copied __block variables always have a | |||
1958 | // reference count of 2. | |||
1959 | bool CanThrow = | |||
1960 | !ForCopyHelper && CGF.cxxDestructorCanThrow(CaptureType); | |||
1961 | CGF.enterByrefCleanup(Kind, Field, Flags, /*LoadBlockVarAddr*/ true, | |||
1962 | CanThrow); | |||
1963 | } | |||
1964 | break; | |||
1965 | } | |||
1966 | case BlockCaptureEntityKind::None: | |||
1967 | break; | |||
1968 | } | |||
1969 | } | |||
1970 | ||||
1971 | static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType, | |||
1972 | llvm::Function *Fn, | |||
1973 | const CGFunctionInfo &FI, | |||
1974 | CodeGenModule &CGM) { | |||
1975 | if (CapturesNonExternalType) { | |||
1976 | CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); | |||
1977 | } else { | |||
1978 | Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); | |||
1979 | Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); | |||
1980 | CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn); | |||
1981 | CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn); | |||
1982 | } | |||
1983 | } | |||
1984 | /// Generate the copy-helper function for a block closure object: | |||
1985 | /// static void block_copy_helper(block_t *dst, block_t *src); | |||
1986 | /// The runtime will have previously initialized 'dst' by doing a | |||
1987 | /// bit-copy of 'src'. | |||
1988 | /// | |||
1989 | /// Note that this copies an entire block closure object to the heap; | |||
1990 | /// it should not be confused with a 'byref copy helper', which moves | |||
1991 | /// the contents of an individual __block variable to the heap. | |||
1992 | llvm::Constant * | |||
1993 | CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { | |||
1994 | SmallVector<BlockCaptureManagedEntity, 4> CopiedCaptures; | |||
1995 | findBlockCapturedManagedEntities(blockInfo, getLangOpts(), CopiedCaptures); | |||
1996 | std::string FuncName = | |||
1997 | getCopyDestroyHelperFuncName(CopiedCaptures, blockInfo.BlockAlign, | |||
1998 | CaptureStrKind::CopyHelper, CGM); | |||
1999 | ||||
2000 | if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName)) | |||
2001 | return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy); | |||
2002 | ||||
2003 | ASTContext &C = getContext(); | |||
2004 | ||||
2005 | QualType ReturnTy = C.VoidTy; | |||
2006 | ||||
2007 | FunctionArgList args; | |||
2008 | ImplicitParamDecl DstDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other); | |||
2009 | args.push_back(&DstDecl); | |||
2010 | ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other); | |||
2011 | args.push_back(&SrcDecl); | |||
2012 | ||||
2013 | const CGFunctionInfo &FI = | |||
2014 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); | |||
2015 | ||||
2016 | // FIXME: it would be nice if these were mergeable with things with | |||
2017 | // identical semantics. | |||
2018 | llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); | |||
2019 | ||||
2020 | llvm::Function *Fn = | |||
2021 | llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage, | |||
2022 | FuncName, &CGM.getModule()); | |||
2023 | if (CGM.supportsCOMDAT()) | |||
2024 | Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); | |||
2025 | ||||
2026 | IdentifierInfo *II = &C.Idents.get(FuncName); | |||
2027 | ||||
2028 | SmallVector<QualType, 2> ArgTys; | |||
2029 | ArgTys.push_back(C.VoidPtrTy); | |||
2030 | ArgTys.push_back(C.VoidPtrTy); | |||
2031 | QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {}); | |||
2032 | ||||
2033 | FunctionDecl *FD = FunctionDecl::Create( | |||
2034 | C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, | |||
2035 | FunctionTy, nullptr, SC_Static, false, false); | |||
2036 | ||||
2037 | setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI, | |||
2038 | CGM); | |||
2039 | StartFunction(FD, ReturnTy, Fn, FI, args); | |||
2040 | ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()}; | |||
2041 | llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); | |||
2042 | ||||
2043 | Address src = GetAddrOfLocalVar(&SrcDecl); | |||
2044 | src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign); | |||
2045 | src = Builder.CreateBitCast(src, structPtrTy, "block.source"); | |||
2046 | ||||
2047 | Address dst = GetAddrOfLocalVar(&DstDecl); | |||
2048 | dst = Address(Builder.CreateLoad(dst), blockInfo.BlockAlign); | |||
2049 | dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); | |||
2050 | ||||
2051 | for (const auto &CopiedCapture : CopiedCaptures) { | |||
2052 | const BlockDecl::Capture &CI = *CopiedCapture.CI; | |||
2053 | const CGBlockInfo::Capture &capture = *CopiedCapture.Capture; | |||
2054 | QualType captureType = CI.getVariable()->getType(); | |||
2055 | BlockFieldFlags flags = CopiedCapture.CopyFlags; | |||
2056 | ||||
2057 | unsigned index = capture.getIndex(); | |||
2058 | Address srcField = Builder.CreateStructGEP(src, index); | |||
2059 | Address dstField = Builder.CreateStructGEP(dst, index); | |||
2060 | ||||
2061 | switch (CopiedCapture.CopyKind) { | |||
2062 | case BlockCaptureEntityKind::CXXRecord: | |||
2063 | // If there's an explicit copy expression, we do that. | |||
2064 | assert(CI.getCopyExpr() && "copy expression for variable is missing")((CI.getCopyExpr() && "copy expression for variable is missing" ) ? static_cast<void> (0) : __assert_fail ("CI.getCopyExpr() && \"copy expression for variable is missing\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2064, __PRETTY_FUNCTION__)); | |||
2065 | EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr()); | |||
2066 | break; | |||
2067 | case BlockCaptureEntityKind::ARCWeak: | |||
2068 | EmitARCCopyWeak(dstField, srcField); | |||
2069 | break; | |||
2070 | case BlockCaptureEntityKind::NonTrivialCStruct: { | |||
2071 | // If this is a C struct that requires non-trivial copy construction, | |||
2072 | // emit a call to its copy constructor. | |||
2073 | QualType varType = CI.getVariable()->getType(); | |||
2074 | callCStructCopyConstructor(MakeAddrLValue(dstField, varType), | |||
2075 | MakeAddrLValue(srcField, varType)); | |||
2076 | break; | |||
2077 | } | |||
2078 | case BlockCaptureEntityKind::ARCStrong: { | |||
2079 | llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); | |||
2080 | // At -O0, store null into the destination field (so that the | |||
2081 | // storeStrong doesn't over-release) and then call storeStrong. | |||
2082 | // This is a workaround to not having an initStrong call. | |||
2083 | if (CGM.getCodeGenOpts().OptimizationLevel == 0) { | |||
2084 | auto *ty = cast<llvm::PointerType>(srcValue->getType()); | |||
2085 | llvm::Value *null = llvm::ConstantPointerNull::get(ty); | |||
2086 | Builder.CreateStore(null, dstField); | |||
2087 | EmitARCStoreStrongCall(dstField, srcValue, true); | |||
2088 | ||||
2089 | // With optimization enabled, take advantage of the fact that | |||
2090 | // the blocks runtime guarantees a memcpy of the block data, and | |||
2091 | // just emit a retain of the src field. | |||
2092 | } else { | |||
2093 | EmitARCRetainNonBlock(srcValue); | |||
2094 | ||||
2095 | // Unless EH cleanup is required, we don't need this anymore, so kill | |||
2096 | // it. It's not quite worth the annoyance to avoid creating it in the | |||
2097 | // first place. | |||
2098 | if (!needsEHCleanup(captureType.isDestructedType())) | |||
2099 | cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent(); | |||
2100 | } | |||
2101 | break; | |||
2102 | } | |||
2103 | case BlockCaptureEntityKind::BlockObject: { | |||
2104 | llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); | |||
2105 | srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy); | |||
2106 | llvm::Value *dstAddr = | |||
2107 | Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy); | |||
2108 | llvm::Value *args[] = { | |||
2109 | dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) | |||
2110 | }; | |||
2111 | ||||
2112 | if (CI.isByRef() && C.getBlockVarCopyInit(CI.getVariable()).canThrow()) | |||
2113 | EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args); | |||
2114 | else | |||
2115 | EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args); | |||
2116 | break; | |||
2117 | } | |||
2118 | case BlockCaptureEntityKind::None: | |||
2119 | continue; | |||
2120 | } | |||
2121 | ||||
2122 | // Ensure that we destroy the copied object if an exception is thrown later | |||
2123 | // in the helper function. | |||
2124 | pushCaptureCleanup(CopiedCapture.CopyKind, dstField, captureType, flags, | |||
2125 | /*ForCopyHelper*/ true, CI.getVariable(), *this); | |||
2126 | } | |||
2127 | ||||
2128 | FinishFunction(); | |||
2129 | ||||
2130 | return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); | |||
2131 | } | |||
2132 | ||||
2133 | static BlockFieldFlags | |||
2134 | getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI, | |||
2135 | QualType T) { | |||
2136 | BlockFieldFlags Flags = BLOCK_FIELD_IS_OBJECT; | |||
2137 | if (T->isBlockPointerType()) | |||
2138 | Flags = BLOCK_FIELD_IS_BLOCK; | |||
2139 | return Flags; | |||
2140 | } | |||
2141 | ||||
2142 | static std::pair<BlockCaptureEntityKind, BlockFieldFlags> | |||
2143 | computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, | |||
2144 | const LangOptions &LangOpts) { | |||
2145 | if (CI.isEscapingByref()) { | |||
2146 | BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF; | |||
2147 | if (T.isObjCGCWeak()) | |||
2148 | Flags |= BLOCK_FIELD_IS_WEAK; | |||
2149 | return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags); | |||
2150 | } | |||
2151 | ||||
2152 | switch (T.isDestructedType()) { | |||
2153 | case QualType::DK_cxx_destructor: | |||
2154 | return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags()); | |||
2155 | case QualType::DK_objc_strong_lifetime: | |||
2156 | // Use objc_storeStrong for __strong direct captures; the | |||
2157 | // dynamic tools really like it when we do this. | |||
2158 | return std::make_pair(BlockCaptureEntityKind::ARCStrong, | |||
2159 | getBlockFieldFlagsForObjCObjectPointer(CI, T)); | |||
2160 | case QualType::DK_objc_weak_lifetime: | |||
2161 | // Support __weak direct captures. | |||
2162 | return std::make_pair(BlockCaptureEntityKind::ARCWeak, | |||
2163 | getBlockFieldFlagsForObjCObjectPointer(CI, T)); | |||
2164 | case QualType::DK_nontrivial_c_struct: | |||
2165 | return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct, | |||
2166 | BlockFieldFlags()); | |||
2167 | case QualType::DK_none: { | |||
2168 | // Non-ARC captures are strong, and we need to use _Block_object_dispose. | |||
2169 | if (T->isObjCRetainableType() && !T.getQualifiers().hasObjCLifetime() && | |||
2170 | !LangOpts.ObjCAutoRefCount) | |||
2171 | return std::make_pair(BlockCaptureEntityKind::BlockObject, | |||
2172 | getBlockFieldFlagsForObjCObjectPointer(CI, T)); | |||
2173 | // Otherwise, we have nothing to do. | |||
2174 | return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags()); | |||
2175 | } | |||
2176 | } | |||
2177 | llvm_unreachable("after exhaustive DestructionKind switch")::llvm::llvm_unreachable_internal("after exhaustive DestructionKind switch" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2177); | |||
2178 | } | |||
2179 | ||||
2180 | /// Generate the destroy-helper function for a block closure object: | |||
2181 | /// static void block_destroy_helper(block_t *theBlock); | |||
2182 | /// | |||
2183 | /// Note that this destroys a heap-allocated block closure object; | |||
2184 | /// it should not be confused with a 'byref destroy helper', which | |||
2185 | /// destroys the heap-allocated contents of an individual __block | |||
2186 | /// variable. | |||
2187 | llvm::Constant * | |||
2188 | CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { | |||
2189 | SmallVector<BlockCaptureManagedEntity, 4> DestroyedCaptures; | |||
2190 | findBlockCapturedManagedEntities(blockInfo, getLangOpts(), DestroyedCaptures); | |||
2191 | std::string FuncName = | |||
2192 | getCopyDestroyHelperFuncName(DestroyedCaptures, blockInfo.BlockAlign, | |||
2193 | CaptureStrKind::DisposeHelper, CGM); | |||
2194 | ||||
2195 | if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName)) | |||
2196 | return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy); | |||
2197 | ||||
2198 | ASTContext &C = getContext(); | |||
2199 | ||||
2200 | QualType ReturnTy = C.VoidTy; | |||
2201 | ||||
2202 | FunctionArgList args; | |||
2203 | ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other); | |||
2204 | args.push_back(&SrcDecl); | |||
2205 | ||||
2206 | const CGFunctionInfo &FI = | |||
2207 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); | |||
2208 | ||||
2209 | // FIXME: We'd like to put these into a mergable by content, with | |||
2210 | // internal linkage. | |||
2211 | llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); | |||
2212 | ||||
2213 | llvm::Function *Fn = | |||
2214 | llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage, | |||
2215 | FuncName, &CGM.getModule()); | |||
2216 | if (CGM.supportsCOMDAT()) | |||
2217 | Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); | |||
2218 | ||||
2219 | IdentifierInfo *II = &C.Idents.get(FuncName); | |||
2220 | ||||
2221 | SmallVector<QualType, 1> ArgTys; | |||
2222 | ArgTys.push_back(C.VoidPtrTy); | |||
2223 | QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {}); | |||
2224 | ||||
2225 | FunctionDecl *FD = FunctionDecl::Create( | |||
2226 | C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, | |||
2227 | FunctionTy, nullptr, SC_Static, false, false); | |||
2228 | ||||
2229 | setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI, | |||
2230 | CGM); | |||
2231 | StartFunction(FD, ReturnTy, Fn, FI, args); | |||
2232 | markAsIgnoreThreadCheckingAtRuntime(Fn); | |||
2233 | ||||
2234 | ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()}; | |||
2235 | ||||
2236 | llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); | |||
2237 | ||||
2238 | Address src = GetAddrOfLocalVar(&SrcDecl); | |||
2239 | src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign); | |||
2240 | src = Builder.CreateBitCast(src, structPtrTy, "block"); | |||
2241 | ||||
2242 | CodeGenFunction::RunCleanupsScope cleanups(*this); | |||
2243 | ||||
2244 | for (const auto &DestroyedCapture : DestroyedCaptures) { | |||
2245 | const BlockDecl::Capture &CI = *DestroyedCapture.CI; | |||
2246 | const CGBlockInfo::Capture &capture = *DestroyedCapture.Capture; | |||
2247 | BlockFieldFlags flags = DestroyedCapture.DisposeFlags; | |||
2248 | ||||
2249 | Address srcField = Builder.CreateStructGEP(src, capture.getIndex()); | |||
2250 | ||||
2251 | pushCaptureCleanup(DestroyedCapture.DisposeKind, srcField, | |||
2252 | CI.getVariable()->getType(), flags, | |||
2253 | /*ForCopyHelper*/ false, CI.getVariable(), *this); | |||
2254 | } | |||
2255 | ||||
2256 | cleanups.ForceCleanup(); | |||
2257 | ||||
2258 | FinishFunction(); | |||
2259 | ||||
2260 | return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); | |||
2261 | } | |||
2262 | ||||
2263 | namespace { | |||
2264 | ||||
2265 | /// Emits the copy/dispose helper functions for a __block object of id type. | |||
2266 | class ObjectByrefHelpers final : public BlockByrefHelpers { | |||
2267 | BlockFieldFlags Flags; | |||
2268 | ||||
2269 | public: | |||
2270 | ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags) | |||
2271 | : BlockByrefHelpers(alignment), Flags(flags) {} | |||
2272 | ||||
2273 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2274 | Address srcField) override { | |||
2275 | destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy); | |||
2276 | ||||
2277 | srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy); | |||
2278 | llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField); | |||
2279 | ||||
2280 | unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask(); | |||
2281 | ||||
2282 | llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); | |||
2283 | llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign(); | |||
2284 | ||||
2285 | llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal }; | |||
2286 | CGF.EmitNounwindRuntimeCall(fn, args); | |||
2287 | } | |||
2288 | ||||
2289 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2290 | field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0)); | |||
2291 | llvm::Value *value = CGF.Builder.CreateLoad(field); | |||
2292 | ||||
2293 | CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER, false); | |||
2294 | } | |||
2295 | ||||
2296 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2297 | id.AddInteger(Flags.getBitMask()); | |||
2298 | } | |||
2299 | }; | |||
2300 | ||||
2301 | /// Emits the copy/dispose helpers for an ARC __block __weak variable. | |||
2302 | class ARCWeakByrefHelpers final : public BlockByrefHelpers { | |||
2303 | public: | |||
2304 | ARCWeakByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {} | |||
2305 | ||||
2306 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2307 | Address srcField) override { | |||
2308 | CGF.EmitARCMoveWeak(destField, srcField); | |||
2309 | } | |||
2310 | ||||
2311 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2312 | CGF.EmitARCDestroyWeak(field); | |||
2313 | } | |||
2314 | ||||
2315 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2316 | // 0 is distinguishable from all pointers and byref flags | |||
2317 | id.AddInteger(0); | |||
2318 | } | |||
2319 | }; | |||
2320 | ||||
2321 | /// Emits the copy/dispose helpers for an ARC __block __strong variable | |||
2322 | /// that's not of block-pointer type. | |||
2323 | class ARCStrongByrefHelpers final : public BlockByrefHelpers { | |||
2324 | public: | |||
2325 | ARCStrongByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {} | |||
2326 | ||||
2327 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2328 | Address srcField) override { | |||
2329 | // Do a "move" by copying the value and then zeroing out the old | |||
2330 | // variable. | |||
2331 | ||||
2332 | llvm::Value *value = CGF.Builder.CreateLoad(srcField); | |||
2333 | ||||
2334 | llvm::Value *null = | |||
2335 | llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); | |||
2336 | ||||
2337 | if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { | |||
2338 | CGF.Builder.CreateStore(null, destField); | |||
2339 | CGF.EmitARCStoreStrongCall(destField, value, /*ignored*/ true); | |||
2340 | CGF.EmitARCStoreStrongCall(srcField, null, /*ignored*/ true); | |||
2341 | return; | |||
2342 | } | |||
2343 | CGF.Builder.CreateStore(value, destField); | |||
2344 | CGF.Builder.CreateStore(null, srcField); | |||
2345 | } | |||
2346 | ||||
2347 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2348 | CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime); | |||
2349 | } | |||
2350 | ||||
2351 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2352 | // 1 is distinguishable from all pointers and byref flags | |||
2353 | id.AddInteger(1); | |||
2354 | } | |||
2355 | }; | |||
2356 | ||||
2357 | /// Emits the copy/dispose helpers for an ARC __block __strong | |||
2358 | /// variable that's of block-pointer type. | |||
2359 | class ARCStrongBlockByrefHelpers final : public BlockByrefHelpers { | |||
2360 | public: | |||
2361 | ARCStrongBlockByrefHelpers(CharUnits alignment) | |||
2362 | : BlockByrefHelpers(alignment) {} | |||
2363 | ||||
2364 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2365 | Address srcField) override { | |||
2366 | // Do the copy with objc_retainBlock; that's all that | |||
2367 | // _Block_object_assign would do anyway, and we'd have to pass the | |||
2368 | // right arguments to make sure it doesn't get no-op'ed. | |||
2369 | llvm::Value *oldValue = CGF.Builder.CreateLoad(srcField); | |||
2370 | llvm::Value *copy = CGF.EmitARCRetainBlock(oldValue, /*mandatory*/ true); | |||
2371 | CGF.Builder.CreateStore(copy, destField); | |||
2372 | } | |||
2373 | ||||
2374 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2375 | CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime); | |||
2376 | } | |||
2377 | ||||
2378 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2379 | // 2 is distinguishable from all pointers and byref flags | |||
2380 | id.AddInteger(2); | |||
2381 | } | |||
2382 | }; | |||
2383 | ||||
2384 | /// Emits the copy/dispose helpers for a __block variable with a | |||
2385 | /// nontrivial copy constructor or destructor. | |||
2386 | class CXXByrefHelpers final : public BlockByrefHelpers { | |||
2387 | QualType VarType; | |||
2388 | const Expr *CopyExpr; | |||
2389 | ||||
2390 | public: | |||
2391 | CXXByrefHelpers(CharUnits alignment, QualType type, | |||
2392 | const Expr *copyExpr) | |||
2393 | : BlockByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {} | |||
2394 | ||||
2395 | bool needsCopy() const override { return CopyExpr != nullptr; } | |||
2396 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2397 | Address srcField) override { | |||
2398 | if (!CopyExpr) return; | |||
2399 | CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr); | |||
2400 | } | |||
2401 | ||||
2402 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2403 | EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin(); | |||
2404 | CGF.PushDestructorCleanup(VarType, field); | |||
2405 | CGF.PopCleanupBlocks(cleanupDepth); | |||
2406 | } | |||
2407 | ||||
2408 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2409 | id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr()); | |||
2410 | } | |||
2411 | }; | |||
2412 | ||||
2413 | /// Emits the copy/dispose helpers for a __block variable that is a non-trivial | |||
2414 | /// C struct. | |||
2415 | class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers { | |||
2416 | QualType VarType; | |||
2417 | ||||
2418 | public: | |||
2419 | NonTrivialCStructByrefHelpers(CharUnits alignment, QualType type) | |||
2420 | : BlockByrefHelpers(alignment), VarType(type) {} | |||
2421 | ||||
2422 | void emitCopy(CodeGenFunction &CGF, Address destField, | |||
2423 | Address srcField) override { | |||
2424 | CGF.callCStructMoveConstructor(CGF.MakeAddrLValue(destField, VarType), | |||
2425 | CGF.MakeAddrLValue(srcField, VarType)); | |||
2426 | } | |||
2427 | ||||
2428 | bool needsDispose() const override { | |||
2429 | return VarType.isDestructedType(); | |||
2430 | } | |||
2431 | ||||
2432 | void emitDispose(CodeGenFunction &CGF, Address field) override { | |||
2433 | EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin(); | |||
2434 | CGF.pushDestroy(VarType.isDestructedType(), field, VarType); | |||
2435 | CGF.PopCleanupBlocks(cleanupDepth); | |||
2436 | } | |||
2437 | ||||
2438 | void profileImpl(llvm::FoldingSetNodeID &id) const override { | |||
2439 | id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr()); | |||
2440 | } | |||
2441 | }; | |||
2442 | } // end anonymous namespace | |||
2443 | ||||
2444 | static llvm::Constant * | |||
2445 | generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, | |||
2446 | BlockByrefHelpers &generator) { | |||
2447 | ASTContext &Context = CGF.getContext(); | |||
2448 | ||||
2449 | QualType ReturnTy = Context.VoidTy; | |||
2450 | ||||
2451 | FunctionArgList args; | |||
2452 | ImplicitParamDecl Dst(Context, Context.VoidPtrTy, ImplicitParamDecl::Other); | |||
2453 | args.push_back(&Dst); | |||
2454 | ||||
2455 | ImplicitParamDecl Src(Context, Context.VoidPtrTy, ImplicitParamDecl::Other); | |||
2456 | args.push_back(&Src); | |||
2457 | ||||
2458 | const CGFunctionInfo &FI = | |||
2459 | CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); | |||
2460 | ||||
2461 | llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI); | |||
2462 | ||||
2463 | // FIXME: We'd like to put these into a mergable by content, with | |||
2464 | // internal linkage. | |||
2465 | llvm::Function *Fn = | |||
2466 | llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, | |||
2467 | "__Block_byref_object_copy_", &CGF.CGM.getModule()); | |||
2468 | ||||
2469 | IdentifierInfo *II | |||
2470 | = &Context.Idents.get("__Block_byref_object_copy_"); | |||
2471 | ||||
2472 | SmallVector<QualType, 2> ArgTys; | |||
2473 | ArgTys.push_back(Context.VoidPtrTy); | |||
2474 | ArgTys.push_back(Context.VoidPtrTy); | |||
2475 | QualType FunctionTy = Context.getFunctionType(ReturnTy, ArgTys, {}); | |||
2476 | ||||
2477 | FunctionDecl *FD = FunctionDecl::Create( | |||
2478 | Context, Context.getTranslationUnitDecl(), SourceLocation(), | |||
2479 | SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false); | |||
2480 | ||||
2481 | CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); | |||
2482 | ||||
2483 | CGF.StartFunction(FD, ReturnTy, Fn, FI, args); | |||
2484 | ||||
2485 | if (generator.needsCopy()) { | |||
2486 | llvm::Type *byrefPtrType = byrefInfo.Type->getPointerTo(0); | |||
2487 | ||||
2488 | // dst->x | |||
2489 | Address destField = CGF.GetAddrOfLocalVar(&Dst); | |||
2490 | destField = Address(CGF.Builder.CreateLoad(destField), | |||
2491 | byrefInfo.ByrefAlignment); | |||
2492 | destField = CGF.Builder.CreateBitCast(destField, byrefPtrType); | |||
2493 | destField = CGF.emitBlockByrefAddress(destField, byrefInfo, false, | |||
2494 | "dest-object"); | |||
2495 | ||||
2496 | // src->x | |||
2497 | Address srcField = CGF.GetAddrOfLocalVar(&Src); | |||
2498 | srcField = Address(CGF.Builder.CreateLoad(srcField), | |||
2499 | byrefInfo.ByrefAlignment); | |||
2500 | srcField = CGF.Builder.CreateBitCast(srcField, byrefPtrType); | |||
2501 | srcField = CGF.emitBlockByrefAddress(srcField, byrefInfo, false, | |||
2502 | "src-object"); | |||
2503 | ||||
2504 | generator.emitCopy(CGF, destField, srcField); | |||
2505 | } | |||
2506 | ||||
2507 | CGF.FinishFunction(); | |||
2508 | ||||
2509 | return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); | |||
2510 | } | |||
2511 | ||||
2512 | /// Build the copy helper for a __block variable. | |||
2513 | static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM, | |||
2514 | const BlockByrefInfo &byrefInfo, | |||
2515 | BlockByrefHelpers &generator) { | |||
2516 | CodeGenFunction CGF(CGM); | |||
2517 | return generateByrefCopyHelper(CGF, byrefInfo, generator); | |||
2518 | } | |||
2519 | ||||
2520 | /// Generate code for a __block variable's dispose helper. | |||
2521 | static llvm::Constant * | |||
2522 | generateByrefDisposeHelper(CodeGenFunction &CGF, | |||
2523 | const BlockByrefInfo &byrefInfo, | |||
2524 | BlockByrefHelpers &generator) { | |||
2525 | ASTContext &Context = CGF.getContext(); | |||
2526 | QualType R = Context.VoidTy; | |||
2527 | ||||
2528 | FunctionArgList args; | |||
2529 | ImplicitParamDecl Src(CGF.getContext(), Context.VoidPtrTy, | |||
2530 | ImplicitParamDecl::Other); | |||
2531 | args.push_back(&Src); | |||
2532 | ||||
2533 | const CGFunctionInfo &FI = | |||
2534 | CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args); | |||
2535 | ||||
2536 | llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI); | |||
2537 | ||||
2538 | // FIXME: We'd like to put these into a mergable by content, with | |||
2539 | // internal linkage. | |||
2540 | llvm::Function *Fn = | |||
2541 | llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, | |||
2542 | "__Block_byref_object_dispose_", | |||
2543 | &CGF.CGM.getModule()); | |||
2544 | ||||
2545 | IdentifierInfo *II | |||
2546 | = &Context.Idents.get("__Block_byref_object_dispose_"); | |||
2547 | ||||
2548 | SmallVector<QualType, 1> ArgTys; | |||
2549 | ArgTys.push_back(Context.VoidPtrTy); | |||
2550 | QualType FunctionTy = Context.getFunctionType(R, ArgTys, {}); | |||
2551 | ||||
2552 | FunctionDecl *FD = FunctionDecl::Create( | |||
2553 | Context, Context.getTranslationUnitDecl(), SourceLocation(), | |||
2554 | SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false); | |||
2555 | ||||
2556 | CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); | |||
2557 | ||||
2558 | CGF.StartFunction(FD, R, Fn, FI, args); | |||
2559 | ||||
2560 | if (generator.needsDispose()) { | |||
2561 | Address addr = CGF.GetAddrOfLocalVar(&Src); | |||
2562 | addr = Address(CGF.Builder.CreateLoad(addr), byrefInfo.ByrefAlignment); | |||
2563 | auto byrefPtrType = byrefInfo.Type->getPointerTo(0); | |||
2564 | addr = CGF.Builder.CreateBitCast(addr, byrefPtrType); | |||
2565 | addr = CGF.emitBlockByrefAddress(addr, byrefInfo, false, "object"); | |||
2566 | ||||
2567 | generator.emitDispose(CGF, addr); | |||
2568 | } | |||
2569 | ||||
2570 | CGF.FinishFunction(); | |||
2571 | ||||
2572 | return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); | |||
2573 | } | |||
2574 | ||||
2575 | /// Build the dispose helper for a __block variable. | |||
2576 | static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM, | |||
2577 | const BlockByrefInfo &byrefInfo, | |||
2578 | BlockByrefHelpers &generator) { | |||
2579 | CodeGenFunction CGF(CGM); | |||
2580 | return generateByrefDisposeHelper(CGF, byrefInfo, generator); | |||
2581 | } | |||
2582 | ||||
2583 | /// Lazily build the copy and dispose helpers for a __block variable | |||
2584 | /// with the given information. | |||
2585 | template <class T> | |||
2586 | static T *buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, | |||
2587 | T &&generator) { | |||
2588 | llvm::FoldingSetNodeID id; | |||
2589 | generator.Profile(id); | |||
2590 | ||||
2591 | void *insertPos; | |||
2592 | BlockByrefHelpers *node | |||
2593 | = CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos); | |||
2594 | if (node) return static_cast<T*>(node); | |||
2595 | ||||
2596 | generator.CopyHelper = buildByrefCopyHelper(CGM, byrefInfo, generator); | |||
2597 | generator.DisposeHelper = buildByrefDisposeHelper(CGM, byrefInfo, generator); | |||
2598 | ||||
2599 | T *copy = new (CGM.getContext()) T(std::forward<T>(generator)); | |||
2600 | CGM.ByrefHelpersCache.InsertNode(copy, insertPos); | |||
2601 | return copy; | |||
2602 | } | |||
2603 | ||||
2604 | /// Build the copy and dispose helpers for the given __block variable | |||
2605 | /// emission. Places the helpers in the global cache. Returns null | |||
2606 | /// if no helpers are required. | |||
2607 | BlockByrefHelpers * | |||
2608 | CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType, | |||
2609 | const AutoVarEmission &emission) { | |||
2610 | const VarDecl &var = *emission.Variable; | |||
2611 | assert(var.isEscapingByref() &&((var.isEscapingByref() && "only escaping __block variables need byref helpers" ) ? static_cast<void> (0) : __assert_fail ("var.isEscapingByref() && \"only escaping __block variables need byref helpers\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2612, __PRETTY_FUNCTION__)) | |||
2612 | "only escaping __block variables need byref helpers")((var.isEscapingByref() && "only escaping __block variables need byref helpers" ) ? static_cast<void> (0) : __assert_fail ("var.isEscapingByref() && \"only escaping __block variables need byref helpers\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2612, __PRETTY_FUNCTION__)); | |||
2613 | ||||
2614 | QualType type = var.getType(); | |||
2615 | ||||
2616 | auto &byrefInfo = getBlockByrefInfo(&var); | |||
2617 | ||||
2618 | // The alignment we care about for the purposes of uniquing byref | |||
2619 | // helpers is the alignment of the actual byref value field. | |||
2620 | CharUnits valueAlignment = | |||
2621 | byrefInfo.ByrefAlignment.alignmentAtOffset(byrefInfo.FieldOffset); | |||
2622 | ||||
2623 | if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { | |||
2624 | const Expr *copyExpr = | |||
2625 | CGM.getContext().getBlockVarCopyInit(&var).getCopyExpr(); | |||
2626 | if (!copyExpr && record->hasTrivialDestructor()) return nullptr; | |||
2627 | ||||
2628 | return ::buildByrefHelpers( | |||
2629 | CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr)); | |||
2630 | } | |||
2631 | ||||
2632 | // If type is a non-trivial C struct type that is non-trivial to | |||
2633 | // destructly move or destroy, build the copy and dispose helpers. | |||
2634 | if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct || | |||
2635 | type.isDestructedType() == QualType::DK_nontrivial_c_struct) | |||
2636 | return ::buildByrefHelpers( | |||
2637 | CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type)); | |||
2638 | ||||
2639 | // Otherwise, if we don't have a retainable type, there's nothing to do. | |||
2640 | // that the runtime does extra copies. | |||
2641 | if (!type->isObjCRetainableType()) return nullptr; | |||
2642 | ||||
2643 | Qualifiers qs = type.getQualifiers(); | |||
2644 | ||||
2645 | // If we have lifetime, that dominates. | |||
2646 | if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { | |||
2647 | switch (lifetime) { | |||
2648 | case Qualifiers::OCL_None: llvm_unreachable("impossible")::llvm::llvm_unreachable_internal("impossible", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2648); | |||
2649 | ||||
2650 | // These are just bits as far as the runtime is concerned. | |||
2651 | case Qualifiers::OCL_ExplicitNone: | |||
2652 | case Qualifiers::OCL_Autoreleasing: | |||
2653 | return nullptr; | |||
2654 | ||||
2655 | // Tell the runtime that this is ARC __weak, called by the | |||
2656 | // byref routines. | |||
2657 | case Qualifiers::OCL_Weak: | |||
2658 | return ::buildByrefHelpers(CGM, byrefInfo, | |||
2659 | ARCWeakByrefHelpers(valueAlignment)); | |||
2660 | ||||
2661 | // ARC __strong __block variables need to be retained. | |||
2662 | case Qualifiers::OCL_Strong: | |||
2663 | // Block pointers need to be copied, and there's no direct | |||
2664 | // transfer possible. | |||
2665 | if (type->isBlockPointerType()) { | |||
2666 | return ::buildByrefHelpers(CGM, byrefInfo, | |||
2667 | ARCStrongBlockByrefHelpers(valueAlignment)); | |||
2668 | ||||
2669 | // Otherwise, we transfer ownership of the retain from the stack | |||
2670 | // to the heap. | |||
2671 | } else { | |||
2672 | return ::buildByrefHelpers(CGM, byrefInfo, | |||
2673 | ARCStrongByrefHelpers(valueAlignment)); | |||
2674 | } | |||
2675 | } | |||
2676 | llvm_unreachable("fell out of lifetime switch!")::llvm::llvm_unreachable_internal("fell out of lifetime switch!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2676); | |||
2677 | } | |||
2678 | ||||
2679 | BlockFieldFlags flags; | |||
2680 | if (type->isBlockPointerType()) { | |||
2681 | flags |= BLOCK_FIELD_IS_BLOCK; | |||
2682 | } else if (CGM.getContext().isObjCNSObjectType(type) || | |||
2683 | type->isObjCObjectPointerType()) { | |||
2684 | flags |= BLOCK_FIELD_IS_OBJECT; | |||
2685 | } else { | |||
2686 | return nullptr; | |||
2687 | } | |||
2688 | ||||
2689 | if (type.isObjCGCWeak()) | |||
2690 | flags |= BLOCK_FIELD_IS_WEAK; | |||
2691 | ||||
2692 | return ::buildByrefHelpers(CGM, byrefInfo, | |||
2693 | ObjectByrefHelpers(valueAlignment, flags)); | |||
2694 | } | |||
2695 | ||||
2696 | Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr, | |||
2697 | const VarDecl *var, | |||
2698 | bool followForward) { | |||
2699 | auto &info = getBlockByrefInfo(var); | |||
2700 | return emitBlockByrefAddress(baseAddr, info, followForward, var->getName()); | |||
2701 | } | |||
2702 | ||||
2703 | Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr, | |||
2704 | const BlockByrefInfo &info, | |||
2705 | bool followForward, | |||
2706 | const llvm::Twine &name) { | |||
2707 | // Chase the forwarding address if requested. | |||
2708 | if (followForward) { | |||
2709 | Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1, "forwarding"); | |||
2710 | baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment); | |||
2711 | } | |||
2712 | ||||
2713 | return Builder.CreateStructGEP(baseAddr, info.FieldIndex, name); | |||
2714 | } | |||
2715 | ||||
2716 | /// BuildByrefInfo - This routine changes a __block variable declared as T x | |||
2717 | /// into: | |||
2718 | /// | |||
2719 | /// struct { | |||
2720 | /// void *__isa; | |||
2721 | /// void *__forwarding; | |||
2722 | /// int32_t __flags; | |||
2723 | /// int32_t __size; | |||
2724 | /// void *__copy_helper; // only if needed | |||
2725 | /// void *__destroy_helper; // only if needed | |||
2726 | /// void *__byref_variable_layout;// only if needed | |||
2727 | /// char padding[X]; // only if needed | |||
2728 | /// T x; | |||
2729 | /// } x | |||
2730 | /// | |||
2731 | const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) { | |||
2732 | auto it = BlockByrefInfos.find(D); | |||
2733 | if (it != BlockByrefInfos.end()) | |||
2734 | return it->second; | |||
2735 | ||||
2736 | llvm::StructType *byrefType = | |||
2737 | llvm::StructType::create(getLLVMContext(), | |||
2738 | "struct.__block_byref_" + D->getNameAsString()); | |||
2739 | ||||
2740 | QualType Ty = D->getType(); | |||
2741 | ||||
2742 | CharUnits size; | |||
2743 | SmallVector<llvm::Type *, 8> types; | |||
2744 | ||||
2745 | // void *__isa; | |||
2746 | types.push_back(Int8PtrTy); | |||
2747 | size += getPointerSize(); | |||
2748 | ||||
2749 | // void *__forwarding; | |||
2750 | types.push_back(llvm::PointerType::getUnqual(byrefType)); | |||
2751 | size += getPointerSize(); | |||
2752 | ||||
2753 | // int32_t __flags; | |||
2754 | types.push_back(Int32Ty); | |||
2755 | size += CharUnits::fromQuantity(4); | |||
2756 | ||||
2757 | // int32_t __size; | |||
2758 | types.push_back(Int32Ty); | |||
2759 | size += CharUnits::fromQuantity(4); | |||
2760 | ||||
2761 | // Note that this must match *exactly* the logic in buildByrefHelpers. | |||
2762 | bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D); | |||
2763 | if (hasCopyAndDispose) { | |||
2764 | /// void *__copy_helper; | |||
2765 | types.push_back(Int8PtrTy); | |||
2766 | size += getPointerSize(); | |||
2767 | ||||
2768 | /// void *__destroy_helper; | |||
2769 | types.push_back(Int8PtrTy); | |||
2770 | size += getPointerSize(); | |||
2771 | } | |||
2772 | ||||
2773 | bool HasByrefExtendedLayout = false; | |||
2774 | Qualifiers::ObjCLifetime Lifetime; | |||
2775 | if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) && | |||
2776 | HasByrefExtendedLayout) { | |||
2777 | /// void *__byref_variable_layout; | |||
2778 | types.push_back(Int8PtrTy); | |||
2779 | size += CharUnits::fromQuantity(PointerSizeInBytes); | |||
2780 | } | |||
2781 | ||||
2782 | // T x; | |||
2783 | llvm::Type *varTy = ConvertTypeForMem(Ty); | |||
2784 | ||||
2785 | bool packed = false; | |||
2786 | CharUnits varAlign = getContext().getDeclAlign(D); | |||
2787 | CharUnits varOffset = size.alignTo(varAlign); | |||
2788 | ||||
2789 | // We may have to insert padding. | |||
2790 | if (varOffset != size) { | |||
2791 | llvm::Type *paddingTy = | |||
2792 | llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity()); | |||
2793 | ||||
2794 | types.push_back(paddingTy); | |||
2795 | size = varOffset; | |||
2796 | ||||
2797 | // Conversely, we might have to prevent LLVM from inserting padding. | |||
2798 | } else if (CGM.getDataLayout().getABITypeAlignment(varTy) | |||
2799 | > varAlign.getQuantity()) { | |||
2800 | packed = true; | |||
2801 | } | |||
2802 | types.push_back(varTy); | |||
2803 | ||||
2804 | byrefType->setBody(types, packed); | |||
2805 | ||||
2806 | BlockByrefInfo info; | |||
2807 | info.Type = byrefType; | |||
2808 | info.FieldIndex = types.size() - 1; | |||
2809 | info.FieldOffset = varOffset; | |||
2810 | info.ByrefAlignment = std::max(varAlign, getPointerAlign()); | |||
2811 | ||||
2812 | auto pair = BlockByrefInfos.insert({D, info}); | |||
2813 | assert(pair.second && "info was inserted recursively?")((pair.second && "info was inserted recursively?") ? static_cast <void> (0) : __assert_fail ("pair.second && \"info was inserted recursively?\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2813, __PRETTY_FUNCTION__)); | |||
2814 | return pair.first->second; | |||
2815 | } | |||
2816 | ||||
2817 | /// Initialize the structural components of a __block variable, i.e. | |||
2818 | /// everything but the actual object. | |||
2819 | void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { | |||
2820 | // Find the address of the local. | |||
2821 | Address addr = emission.Addr; | |||
2822 | ||||
2823 | // That's an alloca of the byref structure type. | |||
2824 | llvm::StructType *byrefType = cast<llvm::StructType>( | |||
2825 | cast<llvm::PointerType>(addr.getPointer()->getType())->getElementType()); | |||
2826 | ||||
2827 | unsigned nextHeaderIndex = 0; | |||
2828 | CharUnits nextHeaderOffset; | |||
2829 | auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize, | |||
2830 | const Twine &name) { | |||
2831 | auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name); | |||
2832 | Builder.CreateStore(value, fieldAddr); | |||
2833 | ||||
2834 | nextHeaderIndex++; | |||
2835 | nextHeaderOffset += fieldSize; | |||
2836 | }; | |||
2837 | ||||
2838 | // Build the byref helpers if necessary. This is null if we don't need any. | |||
2839 | BlockByrefHelpers *helpers = buildByrefHelpers(*byrefType, emission); | |||
2840 | ||||
2841 | const VarDecl &D = *emission.Variable; | |||
2842 | QualType type = D.getType(); | |||
2843 | ||||
2844 | bool HasByrefExtendedLayout; | |||
2845 | Qualifiers::ObjCLifetime ByrefLifetime; | |||
2846 | bool ByRefHasLifetime = | |||
2847 | getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout); | |||
2848 | ||||
2849 | llvm::Value *V; | |||
2850 | ||||
2851 | // Initialize the 'isa', which is just 0 or 1. | |||
2852 | int isa = 0; | |||
2853 | if (type.isObjCGCWeak()) | |||
2854 | isa = 1; | |||
2855 | V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); | |||
2856 | storeHeaderField(V, getPointerSize(), "byref.isa"); | |||
2857 | ||||
2858 | // Store the address of the variable into its own forwarding pointer. | |||
2859 | storeHeaderField(addr.getPointer(), getPointerSize(), "byref.forwarding"); | |||
2860 | ||||
2861 | // Blocks ABI: | |||
2862 | // c) the flags field is set to either 0 if no helper functions are | |||
2863 | // needed or BLOCK_BYREF_HAS_COPY_DISPOSE if they are, | |||
2864 | BlockFlags flags; | |||
2865 | if (helpers) flags |= BLOCK_BYREF_HAS_COPY_DISPOSE; | |||
2866 | if (ByRefHasLifetime) { | |||
2867 | if (HasByrefExtendedLayout) flags |= BLOCK_BYREF_LAYOUT_EXTENDED; | |||
2868 | else switch (ByrefLifetime) { | |||
2869 | case Qualifiers::OCL_Strong: | |||
2870 | flags |= BLOCK_BYREF_LAYOUT_STRONG; | |||
2871 | break; | |||
2872 | case Qualifiers::OCL_Weak: | |||
2873 | flags |= BLOCK_BYREF_LAYOUT_WEAK; | |||
2874 | break; | |||
2875 | case Qualifiers::OCL_ExplicitNone: | |||
2876 | flags |= BLOCK_BYREF_LAYOUT_UNRETAINED; | |||
2877 | break; | |||
2878 | case Qualifiers::OCL_None: | |||
2879 | if (!type->isObjCObjectPointerType() && !type->isBlockPointerType()) | |||
2880 | flags |= BLOCK_BYREF_LAYOUT_NON_OBJECT; | |||
2881 | break; | |||
2882 | default: | |||
2883 | break; | |||
2884 | } | |||
2885 | if (CGM.getLangOpts().ObjCGCBitmapPrint) { | |||
2886 | printf("\n Inline flag for BYREF variable layout (%d):", flags.getBitMask()); | |||
2887 | if (flags & BLOCK_BYREF_HAS_COPY_DISPOSE) | |||
2888 | printf(" BLOCK_BYREF_HAS_COPY_DISPOSE"); | |||
2889 | if (flags & BLOCK_BYREF_LAYOUT_MASK) { | |||
2890 | BlockFlags ThisFlag(flags.getBitMask() & BLOCK_BYREF_LAYOUT_MASK); | |||
2891 | if (ThisFlag == BLOCK_BYREF_LAYOUT_EXTENDED) | |||
2892 | printf(" BLOCK_BYREF_LAYOUT_EXTENDED"); | |||
2893 | if (ThisFlag == BLOCK_BYREF_LAYOUT_STRONG) | |||
2894 | printf(" BLOCK_BYREF_LAYOUT_STRONG"); | |||
2895 | if (ThisFlag == BLOCK_BYREF_LAYOUT_WEAK) | |||
2896 | printf(" BLOCK_BYREF_LAYOUT_WEAK"); | |||
2897 | if (ThisFlag == BLOCK_BYREF_LAYOUT_UNRETAINED) | |||
2898 | printf(" BLOCK_BYREF_LAYOUT_UNRETAINED"); | |||
2899 | if (ThisFlag == BLOCK_BYREF_LAYOUT_NON_OBJECT) | |||
2900 | printf(" BLOCK_BYREF_LAYOUT_NON_OBJECT"); | |||
2901 | } | |||
2902 | printf("\n"); | |||
2903 | } | |||
2904 | } | |||
2905 | storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()), | |||
2906 | getIntSize(), "byref.flags"); | |||
2907 | ||||
2908 | CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType); | |||
2909 | V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity()); | |||
2910 | storeHeaderField(V, getIntSize(), "byref.size"); | |||
2911 | ||||
2912 | if (helpers) { | |||
2913 | storeHeaderField(helpers->CopyHelper, getPointerSize(), | |||
2914 | "byref.copyHelper"); | |||
2915 | storeHeaderField(helpers->DisposeHelper, getPointerSize(), | |||
2916 | "byref.disposeHelper"); | |||
2917 | } | |||
2918 | ||||
2919 | if (ByRefHasLifetime && HasByrefExtendedLayout) { | |||
2920 | auto layoutInfo = CGM.getObjCRuntime().BuildByrefLayout(CGM, type); | |||
2921 | storeHeaderField(layoutInfo, getPointerSize(), "byref.layout"); | |||
2922 | } | |||
2923 | } | |||
2924 | ||||
2925 | void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags, | |||
2926 | bool CanThrow) { | |||
2927 | llvm::FunctionCallee F = CGM.getBlockObjectDispose(); | |||
2928 | llvm::Value *args[] = { | |||
2929 | Builder.CreateBitCast(V, Int8PtrTy), | |||
2930 | llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) | |||
2931 | }; | |||
2932 | ||||
2933 | if (CanThrow) | |||
2934 | EmitRuntimeCallOrInvoke(F, args); | |||
2935 | else | |||
2936 | EmitNounwindRuntimeCall(F, args); | |||
2937 | } | |||
2938 | ||||
2939 | void CodeGenFunction::enterByrefCleanup(CleanupKind Kind, Address Addr, | |||
2940 | BlockFieldFlags Flags, | |||
2941 | bool LoadBlockVarAddr, bool CanThrow) { | |||
2942 | EHStack.pushCleanup<CallBlockRelease>(Kind, Addr, Flags, LoadBlockVarAddr, | |||
2943 | CanThrow); | |||
2944 | } | |||
2945 | ||||
2946 | /// Adjust the declaration of something from the blocks API. | |||
2947 | static void configureBlocksRuntimeObject(CodeGenModule &CGM, | |||
2948 | llvm::Constant *C) { | |||
2949 | auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); | |||
2950 | ||||
2951 | if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) { | |||
2952 | IdentifierInfo &II = CGM.getContext().Idents.get(C->getName()); | |||
2953 | TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); | |||
2954 | DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); | |||
2955 | ||||
2956 | assert((isa<llvm::Function>(C->stripPointerCasts()) ||(((isa<llvm::Function>(C->stripPointerCasts()) || isa <llvm::GlobalVariable>(C->stripPointerCasts())) && "expected Function or GlobalVariable") ? static_cast<void > (0) : __assert_fail ("(isa<llvm::Function>(C->stripPointerCasts()) || isa<llvm::GlobalVariable>(C->stripPointerCasts())) && \"expected Function or GlobalVariable\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2958, __PRETTY_FUNCTION__)) | |||
2957 | isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&(((isa<llvm::Function>(C->stripPointerCasts()) || isa <llvm::GlobalVariable>(C->stripPointerCasts())) && "expected Function or GlobalVariable") ? static_cast<void > (0) : __assert_fail ("(isa<llvm::Function>(C->stripPointerCasts()) || isa<llvm::GlobalVariable>(C->stripPointerCasts())) && \"expected Function or GlobalVariable\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2958, __PRETTY_FUNCTION__)) | |||
2958 | "expected Function or GlobalVariable")(((isa<llvm::Function>(C->stripPointerCasts()) || isa <llvm::GlobalVariable>(C->stripPointerCasts())) && "expected Function or GlobalVariable") ? static_cast<void > (0) : __assert_fail ("(isa<llvm::Function>(C->stripPointerCasts()) || isa<llvm::GlobalVariable>(C->stripPointerCasts())) && \"expected Function or GlobalVariable\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/CodeGen/CGBlocks.cpp" , 2958, __PRETTY_FUNCTION__)); | |||
2959 | ||||
2960 | const NamedDecl *ND = nullptr; | |||
2961 | for (const auto &Result : DC->lookup(&II)) | |||
2962 | if ((ND = dyn_cast<FunctionDecl>(Result)) || | |||
2963 | (ND = dyn_cast<VarDecl>(Result))) | |||
2964 | break; | |||
2965 | ||||
2966 | // TODO: support static blocks runtime | |||
2967 | if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) { | |||
2968 | GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); | |||
2969 | GV->setLinkage(llvm::GlobalValue::ExternalLinkage); | |||
2970 | } else { | |||
2971 | GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); | |||
2972 | GV->setLinkage(llvm::GlobalValue::ExternalLinkage); | |||
2973 | } | |||
2974 | } | |||
2975 | ||||
2976 | if (CGM.getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() && | |||
2977 | GV->hasExternalLinkage()) | |||
2978 | GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); | |||
2979 | ||||
2980 | CGM.setDSOLocal(GV); | |||
2981 | } | |||
2982 | ||||
2983 | llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() { | |||
2984 | if (BlockObjectDispose) | |||
2985 | return BlockObjectDispose; | |||
2986 | ||||
2987 | llvm::Type *args[] = { Int8PtrTy, Int32Ty }; | |||
2988 | llvm::FunctionType *fty | |||
2989 | = llvm::FunctionType::get(VoidTy, args, false); | |||
2990 | BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); | |||
2991 | configureBlocksRuntimeObject( | |||
2992 | *this, cast<llvm::Constant>(BlockObjectDispose.getCallee())); | |||
2993 | return BlockObjectDispose; | |||
2994 | } | |||
2995 | ||||
2996 | llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() { | |||
2997 | if (BlockObjectAssign) | |||
2998 | return BlockObjectAssign; | |||
2999 | ||||
3000 | llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; | |||
3001 | llvm::FunctionType *fty | |||
3002 | = llvm::FunctionType::get(VoidTy, args, false); | |||
3003 | BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); | |||
3004 | configureBlocksRuntimeObject( | |||
3005 | *this, cast<llvm::Constant>(BlockObjectAssign.getCallee())); | |||
3006 | return BlockObjectAssign; | |||
3007 | } | |||
3008 | ||||
3009 | llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { | |||
3010 | if (NSConcreteGlobalBlock) | |||
3011 | return NSConcreteGlobalBlock; | |||
3012 | ||||
3013 | NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", | |||
3014 | Int8PtrTy->getPointerTo(), | |||
3015 | nullptr); | |||
3016 | configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock); | |||
3017 | return NSConcreteGlobalBlock; | |||
3018 | } | |||
3019 | ||||
3020 | llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { | |||
3021 | if (NSConcreteStackBlock) | |||
3022 | return NSConcreteStackBlock; | |||
3023 | ||||
3024 | NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock", | |||
3025 | Int8PtrTy->getPointerTo(), | |||
3026 | nullptr); | |||
3027 | configureBlocksRuntimeObject(*this, NSConcreteStackBlock); | |||
3028 | return NSConcreteStackBlock; | |||
3029 | } |