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