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