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