File: | clang/lib/CodeGen/CGObjC.cpp |
Warning: | line 492, column 35 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===---- CGObjC.cpp - Emit LLVM Code for Objective-C ---------------------===// | ||||||||
2 | // | ||||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||
6 | // | ||||||||
7 | //===----------------------------------------------------------------------===// | ||||||||
8 | // | ||||||||
9 | // This contains code to emit Objective-C code as LLVM code. | ||||||||
10 | // | ||||||||
11 | //===----------------------------------------------------------------------===// | ||||||||
12 | |||||||||
13 | #include "CGDebugInfo.h" | ||||||||
14 | #include "CGObjCRuntime.h" | ||||||||
15 | #include "CodeGenFunction.h" | ||||||||
16 | #include "CodeGenModule.h" | ||||||||
17 | #include "ConstantEmitter.h" | ||||||||
18 | #include "TargetInfo.h" | ||||||||
19 | #include "clang/AST/ASTContext.h" | ||||||||
20 | #include "clang/AST/Attr.h" | ||||||||
21 | #include "clang/AST/DeclObjC.h" | ||||||||
22 | #include "clang/AST/StmtObjC.h" | ||||||||
23 | #include "clang/Basic/Diagnostic.h" | ||||||||
24 | #include "clang/CodeGen/CGFunctionInfo.h" | ||||||||
25 | #include "llvm/ADT/STLExtras.h" | ||||||||
26 | #include "llvm/IR/DataLayout.h" | ||||||||
27 | #include "llvm/IR/InlineAsm.h" | ||||||||
28 | using namespace clang; | ||||||||
29 | using namespace CodeGen; | ||||||||
30 | |||||||||
31 | typedef llvm::PointerIntPair<llvm::Value*,1,bool> TryEmitResult; | ||||||||
32 | static TryEmitResult | ||||||||
33 | tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e); | ||||||||
34 | static RValue AdjustObjCObjectType(CodeGenFunction &CGF, | ||||||||
35 | QualType ET, | ||||||||
36 | RValue Result); | ||||||||
37 | |||||||||
38 | /// Given the address of a variable of pointer type, find the correct | ||||||||
39 | /// null to store into it. | ||||||||
40 | static llvm::Constant *getNullForVariable(Address addr) { | ||||||||
41 | llvm::Type *type = addr.getElementType(); | ||||||||
42 | return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(type)); | ||||||||
43 | } | ||||||||
44 | |||||||||
45 | /// Emits an instance of NSConstantString representing the object. | ||||||||
46 | llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) | ||||||||
47 | { | ||||||||
48 | llvm::Constant *C = | ||||||||
49 | CGM.getObjCRuntime().GenerateConstantString(E->getString()).getPointer(); | ||||||||
50 | // FIXME: This bitcast should just be made an invariant on the Runtime. | ||||||||
51 | return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); | ||||||||
52 | } | ||||||||
53 | |||||||||
54 | /// EmitObjCBoxedExpr - This routine generates code to call | ||||||||
55 | /// the appropriate expression boxing method. This will either be | ||||||||
56 | /// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:], | ||||||||
57 | /// or [NSValue valueWithBytes:objCType:]. | ||||||||
58 | /// | ||||||||
59 | llvm::Value * | ||||||||
60 | CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { | ||||||||
61 | // Generate the correct selector for this literal's concrete type. | ||||||||
62 | // Get the method. | ||||||||
63 | const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod(); | ||||||||
64 | const Expr *SubExpr = E->getSubExpr(); | ||||||||
65 | |||||||||
66 | if (E->isExpressibleAsConstantInitializer()) { | ||||||||
67 | ConstantEmitter ConstEmitter(CGM); | ||||||||
68 | return ConstEmitter.tryEmitAbstract(E, E->getType()); | ||||||||
69 | } | ||||||||
70 | |||||||||
71 | assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method")((BoxingMethod->isClassMethod() && "BoxingMethod must be a class method" ) ? static_cast<void> (0) : __assert_fail ("BoxingMethod->isClassMethod() && \"BoxingMethod must be a class method\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 71, __PRETTY_FUNCTION__)); | ||||||||
72 | Selector Sel = BoxingMethod->getSelector(); | ||||||||
73 | |||||||||
74 | // Generate a reference to the class pointer, which will be the receiver. | ||||||||
75 | // Assumes that the method was introduced in the class that should be | ||||||||
76 | // messaged (avoids pulling it out of the result type). | ||||||||
77 | CGObjCRuntime &Runtime = CGM.getObjCRuntime(); | ||||||||
78 | const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface(); | ||||||||
79 | llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl); | ||||||||
80 | |||||||||
81 | CallArgList Args; | ||||||||
82 | const ParmVarDecl *ArgDecl = *BoxingMethod->param_begin(); | ||||||||
83 | QualType ArgQT = ArgDecl->getType().getUnqualifiedType(); | ||||||||
84 | |||||||||
85 | // ObjCBoxedExpr supports boxing of structs and unions | ||||||||
86 | // via [NSValue valueWithBytes:objCType:] | ||||||||
87 | const QualType ValueType(SubExpr->getType().getCanonicalType()); | ||||||||
88 | if (ValueType->isObjCBoxableRecordType()) { | ||||||||
89 | // Emit CodeGen for first parameter | ||||||||
90 | // and cast value to correct type | ||||||||
91 | Address Temporary = CreateMemTemp(SubExpr->getType()); | ||||||||
92 | EmitAnyExprToMem(SubExpr, Temporary, Qualifiers(), /*isInit*/ true); | ||||||||
93 | Address BitCast = Builder.CreateBitCast(Temporary, ConvertType(ArgQT)); | ||||||||
94 | Args.add(RValue::get(BitCast.getPointer()), ArgQT); | ||||||||
95 | |||||||||
96 | // Create char array to store type encoding | ||||||||
97 | std::string Str; | ||||||||
98 | getContext().getObjCEncodingForType(ValueType, Str); | ||||||||
99 | llvm::Constant *GV = CGM.GetAddrOfConstantCString(Str).getPointer(); | ||||||||
100 | |||||||||
101 | // Cast type encoding to correct type | ||||||||
102 | const ParmVarDecl *EncodingDecl = BoxingMethod->parameters()[1]; | ||||||||
103 | QualType EncodingQT = EncodingDecl->getType().getUnqualifiedType(); | ||||||||
104 | llvm::Value *Cast = Builder.CreateBitCast(GV, ConvertType(EncodingQT)); | ||||||||
105 | |||||||||
106 | Args.add(RValue::get(Cast), EncodingQT); | ||||||||
107 | } else { | ||||||||
108 | Args.add(EmitAnyExpr(SubExpr), ArgQT); | ||||||||
109 | } | ||||||||
110 | |||||||||
111 | RValue result = Runtime.GenerateMessageSend( | ||||||||
112 | *this, ReturnValueSlot(), BoxingMethod->getReturnType(), Sel, Receiver, | ||||||||
113 | Args, ClassDecl, BoxingMethod); | ||||||||
114 | return Builder.CreateBitCast(result.getScalarVal(), | ||||||||
115 | ConvertType(E->getType())); | ||||||||
116 | } | ||||||||
117 | |||||||||
118 | llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, | ||||||||
119 | const ObjCMethodDecl *MethodWithObjects) { | ||||||||
120 | ASTContext &Context = CGM.getContext(); | ||||||||
121 | const ObjCDictionaryLiteral *DLE = nullptr; | ||||||||
122 | const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E); | ||||||||
123 | if (!ALE) | ||||||||
124 | DLE = cast<ObjCDictionaryLiteral>(E); | ||||||||
125 | |||||||||
126 | // Optimize empty collections by referencing constants, when available. | ||||||||
127 | uint64_t NumElements = | ||||||||
128 | ALE ? ALE->getNumElements() : DLE->getNumElements(); | ||||||||
129 | if (NumElements == 0 && CGM.getLangOpts().ObjCRuntime.hasEmptyCollections()) { | ||||||||
130 | StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__"; | ||||||||
131 | QualType IdTy(CGM.getContext().getObjCIdType()); | ||||||||
132 | llvm::Constant *Constant = | ||||||||
133 | CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName); | ||||||||
134 | LValue LV = MakeNaturalAlignAddrLValue(Constant, IdTy); | ||||||||
135 | llvm::Value *Ptr = EmitLoadOfScalar(LV, E->getBeginLoc()); | ||||||||
136 | cast<llvm::LoadInst>(Ptr)->setMetadata( | ||||||||
137 | CGM.getModule().getMDKindID("invariant.load"), | ||||||||
138 | llvm::MDNode::get(getLLVMContext(), None)); | ||||||||
139 | return Builder.CreateBitCast(Ptr, ConvertType(E->getType())); | ||||||||
140 | } | ||||||||
141 | |||||||||
142 | // Compute the type of the array we're initializing. | ||||||||
143 | llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()), | ||||||||
144 | NumElements); | ||||||||
145 | QualType ElementType = Context.getObjCIdType().withConst(); | ||||||||
146 | QualType ElementArrayType | ||||||||
147 | = Context.getConstantArrayType(ElementType, APNumElements, nullptr, | ||||||||
148 | ArrayType::Normal, /*IndexTypeQuals=*/0); | ||||||||
149 | |||||||||
150 | // Allocate the temporary array(s). | ||||||||
151 | Address Objects = CreateMemTemp(ElementArrayType, "objects"); | ||||||||
152 | Address Keys = Address::invalid(); | ||||||||
153 | if (DLE) | ||||||||
154 | Keys = CreateMemTemp(ElementArrayType, "keys"); | ||||||||
155 | |||||||||
156 | // In ARC, we may need to do extra work to keep all the keys and | ||||||||
157 | // values alive until after the call. | ||||||||
158 | SmallVector<llvm::Value *, 16> NeededObjects; | ||||||||
159 | bool TrackNeededObjects = | ||||||||
160 | (getLangOpts().ObjCAutoRefCount && | ||||||||
161 | CGM.getCodeGenOpts().OptimizationLevel != 0); | ||||||||
162 | |||||||||
163 | // Perform the actual initialialization of the array(s). | ||||||||
164 | for (uint64_t i = 0; i < NumElements; i++) { | ||||||||
165 | if (ALE) { | ||||||||
166 | // Emit the element and store it to the appropriate array slot. | ||||||||
167 | const Expr *Rhs = ALE->getElement(i); | ||||||||
168 | LValue LV = MakeAddrLValue(Builder.CreateConstArrayGEP(Objects, i), | ||||||||
169 | ElementType, AlignmentSource::Decl); | ||||||||
170 | |||||||||
171 | llvm::Value *value = EmitScalarExpr(Rhs); | ||||||||
172 | EmitStoreThroughLValue(RValue::get(value), LV, true); | ||||||||
173 | if (TrackNeededObjects) { | ||||||||
174 | NeededObjects.push_back(value); | ||||||||
175 | } | ||||||||
176 | } else { | ||||||||
177 | // Emit the key and store it to the appropriate array slot. | ||||||||
178 | const Expr *Key = DLE->getKeyValueElement(i).Key; | ||||||||
179 | LValue KeyLV = MakeAddrLValue(Builder.CreateConstArrayGEP(Keys, i), | ||||||||
180 | ElementType, AlignmentSource::Decl); | ||||||||
181 | llvm::Value *keyValue = EmitScalarExpr(Key); | ||||||||
182 | EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true); | ||||||||
183 | |||||||||
184 | // Emit the value and store it to the appropriate array slot. | ||||||||
185 | const Expr *Value = DLE->getKeyValueElement(i).Value; | ||||||||
186 | LValue ValueLV = MakeAddrLValue(Builder.CreateConstArrayGEP(Objects, i), | ||||||||
187 | ElementType, AlignmentSource::Decl); | ||||||||
188 | llvm::Value *valueValue = EmitScalarExpr(Value); | ||||||||
189 | EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true); | ||||||||
190 | if (TrackNeededObjects) { | ||||||||
191 | NeededObjects.push_back(keyValue); | ||||||||
192 | NeededObjects.push_back(valueValue); | ||||||||
193 | } | ||||||||
194 | } | ||||||||
195 | } | ||||||||
196 | |||||||||
197 | // Generate the argument list. | ||||||||
198 | CallArgList Args; | ||||||||
199 | ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin(); | ||||||||
200 | const ParmVarDecl *argDecl = *PI++; | ||||||||
201 | QualType ArgQT = argDecl->getType().getUnqualifiedType(); | ||||||||
202 | Args.add(RValue::get(Objects.getPointer()), ArgQT); | ||||||||
203 | if (DLE) { | ||||||||
204 | argDecl = *PI++; | ||||||||
205 | ArgQT = argDecl->getType().getUnqualifiedType(); | ||||||||
206 | Args.add(RValue::get(Keys.getPointer()), ArgQT); | ||||||||
207 | } | ||||||||
208 | argDecl = *PI; | ||||||||
209 | ArgQT = argDecl->getType().getUnqualifiedType(); | ||||||||
210 | llvm::Value *Count = | ||||||||
211 | llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements); | ||||||||
212 | Args.add(RValue::get(Count), ArgQT); | ||||||||
213 | |||||||||
214 | // Generate a reference to the class pointer, which will be the receiver. | ||||||||
215 | Selector Sel = MethodWithObjects->getSelector(); | ||||||||
216 | QualType ResultType = E->getType(); | ||||||||
217 | const ObjCObjectPointerType *InterfacePointerType | ||||||||
218 | = ResultType->getAsObjCInterfacePointerType(); | ||||||||
219 | ObjCInterfaceDecl *Class | ||||||||
220 | = InterfacePointerType->getObjectType()->getInterface(); | ||||||||
221 | CGObjCRuntime &Runtime = CGM.getObjCRuntime(); | ||||||||
222 | llvm::Value *Receiver = Runtime.GetClass(*this, Class); | ||||||||
223 | |||||||||
224 | // Generate the message send. | ||||||||
225 | RValue result = Runtime.GenerateMessageSend( | ||||||||
226 | *this, ReturnValueSlot(), MethodWithObjects->getReturnType(), Sel, | ||||||||
227 | Receiver, Args, Class, MethodWithObjects); | ||||||||
228 | |||||||||
229 | // The above message send needs these objects, but in ARC they are | ||||||||
230 | // passed in a buffer that is essentially __unsafe_unretained. | ||||||||
231 | // Therefore we must prevent the optimizer from releasing them until | ||||||||
232 | // after the call. | ||||||||
233 | if (TrackNeededObjects) { | ||||||||
234 | EmitARCIntrinsicUse(NeededObjects); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | return Builder.CreateBitCast(result.getScalarVal(), | ||||||||
238 | ConvertType(E->getType())); | ||||||||
239 | } | ||||||||
240 | |||||||||
241 | llvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) { | ||||||||
242 | return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod()); | ||||||||
243 | } | ||||||||
244 | |||||||||
245 | llvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral( | ||||||||
246 | const ObjCDictionaryLiteral *E) { | ||||||||
247 | return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod()); | ||||||||
248 | } | ||||||||
249 | |||||||||
250 | /// Emit a selector. | ||||||||
251 | llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { | ||||||||
252 | // Untyped selector. | ||||||||
253 | // Note that this implementation allows for non-constant strings to be passed | ||||||||
254 | // as arguments to @selector(). Currently, the only thing preventing this | ||||||||
255 | // behaviour is the type checking in the front end. | ||||||||
256 | return CGM.getObjCRuntime().GetSelector(*this, E->getSelector()); | ||||||||
257 | } | ||||||||
258 | |||||||||
259 | llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { | ||||||||
260 | // FIXME: This should pass the Decl not the name. | ||||||||
261 | return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol()); | ||||||||
262 | } | ||||||||
263 | |||||||||
264 | /// Adjust the type of an Objective-C object that doesn't match up due | ||||||||
265 | /// to type erasure at various points, e.g., related result types or the use | ||||||||
266 | /// of parameterized classes. | ||||||||
267 | static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ExpT, | ||||||||
268 | RValue Result) { | ||||||||
269 | if (!ExpT->isObjCRetainableType()) | ||||||||
270 | return Result; | ||||||||
271 | |||||||||
272 | // If the converted types are the same, we're done. | ||||||||
273 | llvm::Type *ExpLLVMTy = CGF.ConvertType(ExpT); | ||||||||
274 | if (ExpLLVMTy == Result.getScalarVal()->getType()) | ||||||||
275 | return Result; | ||||||||
276 | |||||||||
277 | // We have applied a substitution. Cast the rvalue appropriately. | ||||||||
278 | return RValue::get(CGF.Builder.CreateBitCast(Result.getScalarVal(), | ||||||||
279 | ExpLLVMTy)); | ||||||||
280 | } | ||||||||
281 | |||||||||
282 | /// Decide whether to extend the lifetime of the receiver of a | ||||||||
283 | /// returns-inner-pointer message. | ||||||||
284 | static bool | ||||||||
285 | shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) { | ||||||||
286 | switch (message->getReceiverKind()) { | ||||||||
287 | |||||||||
288 | // For a normal instance message, we should extend unless the | ||||||||
289 | // receiver is loaded from a variable with precise lifetime. | ||||||||
290 | case ObjCMessageExpr::Instance: { | ||||||||
291 | const Expr *receiver = message->getInstanceReceiver(); | ||||||||
292 | |||||||||
293 | // Look through OVEs. | ||||||||
294 | if (auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) { | ||||||||
295 | if (opaque->getSourceExpr()) | ||||||||
296 | receiver = opaque->getSourceExpr()->IgnoreParens(); | ||||||||
297 | } | ||||||||
298 | |||||||||
299 | const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(receiver); | ||||||||
300 | if (!ice || ice->getCastKind() != CK_LValueToRValue) return true; | ||||||||
301 | receiver = ice->getSubExpr()->IgnoreParens(); | ||||||||
302 | |||||||||
303 | // Look through OVEs. | ||||||||
304 | if (auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) { | ||||||||
305 | if (opaque->getSourceExpr()) | ||||||||
306 | receiver = opaque->getSourceExpr()->IgnoreParens(); | ||||||||
307 | } | ||||||||
308 | |||||||||
309 | // Only __strong variables. | ||||||||
310 | if (receiver->getType().getObjCLifetime() != Qualifiers::OCL_Strong) | ||||||||
311 | return true; | ||||||||
312 | |||||||||
313 | // All ivars and fields have precise lifetime. | ||||||||
314 | if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver)) | ||||||||
315 | return false; | ||||||||
316 | |||||||||
317 | // Otherwise, check for variables. | ||||||||
318 | const DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(ice->getSubExpr()); | ||||||||
319 | if (!declRef) return true; | ||||||||
320 | const VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl()); | ||||||||
321 | if (!var) return true; | ||||||||
322 | |||||||||
323 | // All variables have precise lifetime except local variables with | ||||||||
324 | // automatic storage duration that aren't specially marked. | ||||||||
325 | return (var->hasLocalStorage() && | ||||||||
326 | !var->hasAttr<ObjCPreciseLifetimeAttr>()); | ||||||||
327 | } | ||||||||
328 | |||||||||
329 | case ObjCMessageExpr::Class: | ||||||||
330 | case ObjCMessageExpr::SuperClass: | ||||||||
331 | // It's never necessary for class objects. | ||||||||
332 | return false; | ||||||||
333 | |||||||||
334 | case ObjCMessageExpr::SuperInstance: | ||||||||
335 | // We generally assume that 'self' lives throughout a method call. | ||||||||
336 | return false; | ||||||||
337 | } | ||||||||
338 | |||||||||
339 | llvm_unreachable("invalid receiver kind")::llvm::llvm_unreachable_internal("invalid receiver kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 339); | ||||||||
340 | } | ||||||||
341 | |||||||||
342 | /// Given an expression of ObjC pointer type, check whether it was | ||||||||
343 | /// immediately loaded from an ARC __weak l-value. | ||||||||
344 | static const Expr *findWeakLValue(const Expr *E) { | ||||||||
345 | assert(E->getType()->isObjCRetainableType())((E->getType()->isObjCRetainableType()) ? static_cast< void> (0) : __assert_fail ("E->getType()->isObjCRetainableType()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 345, __PRETTY_FUNCTION__)); | ||||||||
346 | E = E->IgnoreParens(); | ||||||||
347 | if (auto CE = dyn_cast<CastExpr>(E)) { | ||||||||
348 | if (CE->getCastKind() == CK_LValueToRValue) { | ||||||||
349 | if (CE->getSubExpr()->getType().getObjCLifetime() == Qualifiers::OCL_Weak) | ||||||||
350 | return CE->getSubExpr(); | ||||||||
351 | } | ||||||||
352 | } | ||||||||
353 | |||||||||
354 | return nullptr; | ||||||||
355 | } | ||||||||
356 | |||||||||
357 | /// The ObjC runtime may provide entrypoints that are likely to be faster | ||||||||
358 | /// than an ordinary message send of the appropriate selector. | ||||||||
359 | /// | ||||||||
360 | /// The entrypoints are guaranteed to be equivalent to just sending the | ||||||||
361 | /// corresponding message. If the entrypoint is implemented naively as just a | ||||||||
362 | /// message send, using it is a trade-off: it sacrifices a few cycles of | ||||||||
363 | /// overhead to save a small amount of code. However, it's possible for | ||||||||
364 | /// runtimes to detect and special-case classes that use "standard" | ||||||||
365 | /// behavior; if that's dynamically a large proportion of all objects, using | ||||||||
366 | /// the entrypoint will also be faster than using a message send. | ||||||||
367 | /// | ||||||||
368 | /// If the runtime does support a required entrypoint, then this method will | ||||||||
369 | /// generate a call and return the resulting value. Otherwise it will return | ||||||||
370 | /// None and the caller can generate a msgSend instead. | ||||||||
371 | static Optional<llvm::Value *> | ||||||||
372 | tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType, | ||||||||
373 | llvm::Value *Receiver, | ||||||||
374 | const CallArgList& Args, Selector Sel, | ||||||||
375 | const ObjCMethodDecl *method, | ||||||||
376 | bool isClassMessage) { | ||||||||
377 | auto &CGM = CGF.CGM; | ||||||||
378 | if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls) | ||||||||
379 | return None; | ||||||||
380 | |||||||||
381 | auto &Runtime = CGM.getLangOpts().ObjCRuntime; | ||||||||
382 | switch (Sel.getMethodFamily()) { | ||||||||
383 | case OMF_alloc: | ||||||||
384 | if (isClassMessage && | ||||||||
385 | Runtime.shouldUseRuntimeFunctionsForAlloc() && | ||||||||
386 | ResultType->isObjCObjectPointerType()) { | ||||||||
387 | // [Foo alloc] -> objc_alloc(Foo) or | ||||||||
388 | // [self alloc] -> objc_alloc(self) | ||||||||
389 | if (Sel.isUnarySelector() && Sel.getNameForSlot(0) == "alloc") | ||||||||
390 | return CGF.EmitObjCAlloc(Receiver, CGF.ConvertType(ResultType)); | ||||||||
391 | // [Foo allocWithZone:nil] -> objc_allocWithZone(Foo) or | ||||||||
392 | // [self allocWithZone:nil] -> objc_allocWithZone(self) | ||||||||
393 | if (Sel.isKeywordSelector() && Sel.getNumArgs() == 1 && | ||||||||
394 | Args.size() == 1 && Args.front().getType()->isPointerType() && | ||||||||
395 | Sel.getNameForSlot(0) == "allocWithZone") { | ||||||||
396 | const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal(); | ||||||||
397 | if (isa<llvm::ConstantPointerNull>(arg)) | ||||||||
398 | return CGF.EmitObjCAllocWithZone(Receiver, | ||||||||
399 | CGF.ConvertType(ResultType)); | ||||||||
400 | return None; | ||||||||
401 | } | ||||||||
402 | } | ||||||||
403 | break; | ||||||||
404 | |||||||||
405 | case OMF_autorelease: | ||||||||
406 | if (ResultType->isObjCObjectPointerType() && | ||||||||
407 | CGM.getLangOpts().getGC() == LangOptions::NonGC && | ||||||||
408 | Runtime.shouldUseARCFunctionsForRetainRelease()) | ||||||||
409 | return CGF.EmitObjCAutorelease(Receiver, CGF.ConvertType(ResultType)); | ||||||||
410 | break; | ||||||||
411 | |||||||||
412 | case OMF_retain: | ||||||||
413 | if (ResultType->isObjCObjectPointerType() && | ||||||||
414 | CGM.getLangOpts().getGC() == LangOptions::NonGC && | ||||||||
415 | Runtime.shouldUseARCFunctionsForRetainRelease()) | ||||||||
416 | return CGF.EmitObjCRetainNonBlock(Receiver, CGF.ConvertType(ResultType)); | ||||||||
417 | break; | ||||||||
418 | |||||||||
419 | case OMF_release: | ||||||||
420 | if (ResultType->isVoidType() && | ||||||||
421 | CGM.getLangOpts().getGC() == LangOptions::NonGC && | ||||||||
422 | Runtime.shouldUseARCFunctionsForRetainRelease()) { | ||||||||
423 | CGF.EmitObjCRelease(Receiver, ARCPreciseLifetime); | ||||||||
424 | return nullptr; | ||||||||
425 | } | ||||||||
426 | break; | ||||||||
427 | |||||||||
428 | default: | ||||||||
429 | break; | ||||||||
430 | } | ||||||||
431 | return None; | ||||||||
432 | } | ||||||||
433 | |||||||||
434 | CodeGen::RValue CGObjCRuntime::GeneratePossiblySpecializedMessageSend( | ||||||||
435 | CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType, | ||||||||
436 | Selector Sel, llvm::Value *Receiver, const CallArgList &Args, | ||||||||
437 | const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method, | ||||||||
438 | bool isClassMessage) { | ||||||||
439 | if (Optional<llvm::Value *> SpecializedResult = | ||||||||
440 | tryGenerateSpecializedMessageSend(CGF, ResultType, Receiver, Args, | ||||||||
441 | Sel, Method, isClassMessage)) { | ||||||||
442 | return RValue::get(SpecializedResult.getValue()); | ||||||||
443 | } | ||||||||
444 | return GenerateMessageSend(CGF, Return, ResultType, Sel, Receiver, Args, OID, | ||||||||
445 | Method); | ||||||||
446 | } | ||||||||
447 | |||||||||
448 | /// Instead of '[[MyClass alloc] init]', try to generate | ||||||||
449 | /// 'objc_alloc_init(MyClass)'. This provides a code size improvement on the | ||||||||
450 | /// caller side, as well as the optimized objc_alloc. | ||||||||
451 | static Optional<llvm::Value *> | ||||||||
452 | tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME) { | ||||||||
453 | auto &Runtime = CGF.getLangOpts().ObjCRuntime; | ||||||||
454 | if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit()) | ||||||||
455 | return None; | ||||||||
456 | |||||||||
457 | // Match the exact pattern '[[MyClass alloc] init]'. | ||||||||
458 | Selector Sel = OME->getSelector(); | ||||||||
459 | if (OME->getReceiverKind() != ObjCMessageExpr::Instance || | ||||||||
460 | !OME->getType()->isObjCObjectPointerType() || !Sel.isUnarySelector() || | ||||||||
461 | Sel.getNameForSlot(0) != "init") | ||||||||
462 | return None; | ||||||||
463 | |||||||||
464 | // Okay, this is '[receiver init]', check if 'receiver' is '[cls alloc]' or | ||||||||
465 | // we are in an ObjC class method and 'receiver' is '[self alloc]'. | ||||||||
466 | auto *SubOME = | ||||||||
467 | dyn_cast<ObjCMessageExpr>(OME->getInstanceReceiver()->IgnoreParenCasts()); | ||||||||
468 | if (!SubOME
| ||||||||
469 | return None; | ||||||||
470 | Selector SubSel = SubOME->getSelector(); | ||||||||
471 | |||||||||
472 | // Check if we are in an ObjC class method and the receiver expression is | ||||||||
473 | // 'self'. | ||||||||
474 | const Expr *SelfInClassMethod = nullptr; | ||||||||
475 | if (const auto *CurMD
| ||||||||
476 | if (CurMD->isClassMethod()) | ||||||||
477 | if ((SelfInClassMethod = SubOME->getInstanceReceiver())) | ||||||||
478 | if (!SelfInClassMethod->isObjCSelfExpr()) | ||||||||
479 | SelfInClassMethod = nullptr; | ||||||||
480 | |||||||||
481 | if ((SubOME->getReceiverKind() != ObjCMessageExpr::Class && | ||||||||
482 | !SelfInClassMethod) || !SubOME->getType()->isObjCObjectPointerType() || | ||||||||
483 | !SubSel.isUnarySelector() || SubSel.getNameForSlot(0) != "alloc") | ||||||||
484 | return None; | ||||||||
485 | |||||||||
486 | llvm::Value *Receiver; | ||||||||
487 | if (SelfInClassMethod
| ||||||||
488 | Receiver = CGF.EmitScalarExpr(SelfInClassMethod); | ||||||||
489 | } else { | ||||||||
490 | QualType ReceiverType = SubOME->getClassReceiver(); | ||||||||
491 | const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>(); | ||||||||
492 | const ObjCInterfaceDecl *ID = ObjTy->getInterface(); | ||||||||
| |||||||||
493 | assert(ID && "null interface should be impossible here")((ID && "null interface should be impossible here") ? static_cast<void> (0) : __assert_fail ("ID && \"null interface should be impossible here\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 493, __PRETTY_FUNCTION__)); | ||||||||
494 | Receiver = CGF.CGM.getObjCRuntime().GetClass(CGF, ID); | ||||||||
495 | } | ||||||||
496 | return CGF.EmitObjCAllocInit(Receiver, CGF.ConvertType(OME->getType())); | ||||||||
497 | } | ||||||||
498 | |||||||||
499 | RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E, | ||||||||
500 | ReturnValueSlot Return) { | ||||||||
501 | // Only the lookup mechanism and first two arguments of the method | ||||||||
502 | // implementation vary between runtimes. We can get the receiver and | ||||||||
503 | // arguments in generic code. | ||||||||
504 | |||||||||
505 | bool isDelegateInit = E->isDelegateInitCall(); | ||||||||
506 | |||||||||
507 | const ObjCMethodDecl *method = E->getMethodDecl(); | ||||||||
508 | |||||||||
509 | // If the method is -retain, and the receiver's being loaded from | ||||||||
510 | // a __weak variable, peephole the entire operation to objc_loadWeakRetained. | ||||||||
511 | if (method
| ||||||||
512 | method->getMethodFamily() == OMF_retain) { | ||||||||
513 | if (auto lvalueExpr = findWeakLValue(E->getInstanceReceiver())) { | ||||||||
514 | LValue lvalue = EmitLValue(lvalueExpr); | ||||||||
515 | llvm::Value *result = EmitARCLoadWeakRetained(lvalue.getAddress(*this)); | ||||||||
516 | return AdjustObjCObjectType(*this, E->getType(), RValue::get(result)); | ||||||||
517 | } | ||||||||
518 | } | ||||||||
519 | |||||||||
520 | if (Optional<llvm::Value *> Val = tryEmitSpecializedAllocInit(*this, E)) | ||||||||
| |||||||||
521 | return AdjustObjCObjectType(*this, E->getType(), RValue::get(*Val)); | ||||||||
522 | |||||||||
523 | // We don't retain the receiver in delegate init calls, and this is | ||||||||
524 | // safe because the receiver value is always loaded from 'self', | ||||||||
525 | // which we zero out. We don't want to Block_copy block receivers, | ||||||||
526 | // though. | ||||||||
527 | bool retainSelf = | ||||||||
528 | (!isDelegateInit && | ||||||||
529 | CGM.getLangOpts().ObjCAutoRefCount && | ||||||||
530 | method && | ||||||||
531 | method->hasAttr<NSConsumesSelfAttr>()); | ||||||||
532 | |||||||||
533 | CGObjCRuntime &Runtime = CGM.getObjCRuntime(); | ||||||||
534 | bool isSuperMessage = false; | ||||||||
535 | bool isClassMessage = false; | ||||||||
536 | ObjCInterfaceDecl *OID = nullptr; | ||||||||
537 | // Find the receiver | ||||||||
538 | QualType ReceiverType; | ||||||||
539 | llvm::Value *Receiver = nullptr; | ||||||||
540 | switch (E->getReceiverKind()) { | ||||||||
541 | case ObjCMessageExpr::Instance: | ||||||||
542 | ReceiverType = E->getInstanceReceiver()->getType(); | ||||||||
543 | if (auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl)) | ||||||||
544 | if (OMD->isClassMethod()) | ||||||||
545 | if (E->getInstanceReceiver()->isObjCSelfExpr()) | ||||||||
546 | isClassMessage = true; | ||||||||
547 | if (retainSelf) { | ||||||||
548 | TryEmitResult ter = tryEmitARCRetainScalarExpr(*this, | ||||||||
549 | E->getInstanceReceiver()); | ||||||||
550 | Receiver = ter.getPointer(); | ||||||||
551 | if (ter.getInt()) retainSelf = false; | ||||||||
552 | } else | ||||||||
553 | Receiver = EmitScalarExpr(E->getInstanceReceiver()); | ||||||||
554 | break; | ||||||||
555 | |||||||||
556 | case ObjCMessageExpr::Class: { | ||||||||
557 | ReceiverType = E->getClassReceiver(); | ||||||||
558 | const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>(); | ||||||||
559 | assert(ObjTy && "Invalid Objective-C class message send")((ObjTy && "Invalid Objective-C class message send") ? static_cast<void> (0) : __assert_fail ("ObjTy && \"Invalid Objective-C class message send\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 559, __PRETTY_FUNCTION__)); | ||||||||
560 | OID = ObjTy->getInterface(); | ||||||||
561 | assert(OID && "Invalid Objective-C class message send")((OID && "Invalid Objective-C class message send") ? static_cast <void> (0) : __assert_fail ("OID && \"Invalid Objective-C class message send\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 561, __PRETTY_FUNCTION__)); | ||||||||
562 | Receiver = Runtime.GetClass(*this, OID); | ||||||||
563 | isClassMessage = true; | ||||||||
564 | break; | ||||||||
565 | } | ||||||||
566 | |||||||||
567 | case ObjCMessageExpr::SuperInstance: | ||||||||
568 | ReceiverType = E->getSuperType(); | ||||||||
569 | Receiver = LoadObjCSelf(); | ||||||||
570 | isSuperMessage = true; | ||||||||
571 | break; | ||||||||
572 | |||||||||
573 | case ObjCMessageExpr::SuperClass: | ||||||||
574 | ReceiverType = E->getSuperType(); | ||||||||
575 | Receiver = LoadObjCSelf(); | ||||||||
576 | isSuperMessage = true; | ||||||||
577 | isClassMessage = true; | ||||||||
578 | break; | ||||||||
579 | } | ||||||||
580 | |||||||||
581 | if (retainSelf) | ||||||||
582 | Receiver = EmitARCRetainNonBlock(Receiver); | ||||||||
583 | |||||||||
584 | // In ARC, we sometimes want to "extend the lifetime" | ||||||||
585 | // (i.e. retain+autorelease) of receivers of returns-inner-pointer | ||||||||
586 | // messages. | ||||||||
587 | if (getLangOpts().ObjCAutoRefCount && method && | ||||||||
588 | method->hasAttr<ObjCReturnsInnerPointerAttr>() && | ||||||||
589 | shouldExtendReceiverForInnerPointerMessage(E)) | ||||||||
590 | Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver); | ||||||||
591 | |||||||||
592 | QualType ResultType = method ? method->getReturnType() : E->getType(); | ||||||||
593 | |||||||||
594 | CallArgList Args; | ||||||||
595 | EmitCallArgs(Args, method, E->arguments(), /*AC*/AbstractCallee(method)); | ||||||||
596 | |||||||||
597 | // For delegate init calls in ARC, do an unsafe store of null into | ||||||||
598 | // self. This represents the call taking direct ownership of that | ||||||||
599 | // value. We have to do this after emitting the other call | ||||||||
600 | // arguments because they might also reference self, but we don't | ||||||||
601 | // have to worry about any of them modifying self because that would | ||||||||
602 | // be an undefined read and write of an object in unordered | ||||||||
603 | // expressions. | ||||||||
604 | if (isDelegateInit) { | ||||||||
605 | assert(getLangOpts().ObjCAutoRefCount &&((getLangOpts().ObjCAutoRefCount && "delegate init calls should only be marked in ARC" ) ? static_cast<void> (0) : __assert_fail ("getLangOpts().ObjCAutoRefCount && \"delegate init calls should only be marked in ARC\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 606, __PRETTY_FUNCTION__)) | ||||||||
606 | "delegate init calls should only be marked in ARC")((getLangOpts().ObjCAutoRefCount && "delegate init calls should only be marked in ARC" ) ? static_cast<void> (0) : __assert_fail ("getLangOpts().ObjCAutoRefCount && \"delegate init calls should only be marked in ARC\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 606, __PRETTY_FUNCTION__)); | ||||||||
607 | |||||||||
608 | // Do an unsafe store of null into self. | ||||||||
609 | Address selfAddr = | ||||||||
610 | GetAddrOfLocalVar(cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()); | ||||||||
611 | Builder.CreateStore(getNullForVariable(selfAddr), selfAddr); | ||||||||
612 | } | ||||||||
613 | |||||||||
614 | RValue result; | ||||||||
615 | if (isSuperMessage) { | ||||||||
616 | // super is only valid in an Objective-C method | ||||||||
617 | const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); | ||||||||
618 | bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); | ||||||||
619 | result = Runtime.GenerateMessageSendSuper(*this, Return, ResultType, | ||||||||
620 | E->getSelector(), | ||||||||
621 | OMD->getClassInterface(), | ||||||||
622 | isCategoryImpl, | ||||||||
623 | Receiver, | ||||||||
624 | isClassMessage, | ||||||||
625 | Args, | ||||||||
626 | method); | ||||||||
627 | } else { | ||||||||
628 | // Call runtime methods directly if we can. | ||||||||
629 | result = Runtime.GeneratePossiblySpecializedMessageSend( | ||||||||
630 | *this, Return, ResultType, E->getSelector(), Receiver, Args, OID, | ||||||||
631 | method, isClassMessage); | ||||||||
632 | } | ||||||||
633 | |||||||||
634 | // For delegate init calls in ARC, implicitly store the result of | ||||||||
635 | // the call back into self. This takes ownership of the value. | ||||||||
636 | if (isDelegateInit) { | ||||||||
637 | Address selfAddr = | ||||||||
638 | GetAddrOfLocalVar(cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()); | ||||||||
639 | llvm::Value *newSelf = result.getScalarVal(); | ||||||||
640 | |||||||||
641 | // The delegate return type isn't necessarily a matching type; in | ||||||||
642 | // fact, it's quite likely to be 'id'. | ||||||||
643 | llvm::Type *selfTy = selfAddr.getElementType(); | ||||||||
644 | newSelf = Builder.CreateBitCast(newSelf, selfTy); | ||||||||
645 | |||||||||
646 | Builder.CreateStore(newSelf, selfAddr); | ||||||||
647 | } | ||||||||
648 | |||||||||
649 | return AdjustObjCObjectType(*this, E->getType(), result); | ||||||||
650 | } | ||||||||
651 | |||||||||
652 | namespace { | ||||||||
653 | struct FinishARCDealloc final : EHScopeStack::Cleanup { | ||||||||
654 | void Emit(CodeGenFunction &CGF, Flags flags) override { | ||||||||
655 | const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl); | ||||||||
656 | |||||||||
657 | const ObjCImplDecl *impl = cast<ObjCImplDecl>(method->getDeclContext()); | ||||||||
658 | const ObjCInterfaceDecl *iface = impl->getClassInterface(); | ||||||||
659 | if (!iface->getSuperClass()) return; | ||||||||
660 | |||||||||
661 | bool isCategory = isa<ObjCCategoryImplDecl>(impl); | ||||||||
662 | |||||||||
663 | // Call [super dealloc] if we have a superclass. | ||||||||
664 | llvm::Value *self = CGF.LoadObjCSelf(); | ||||||||
665 | |||||||||
666 | CallArgList args; | ||||||||
667 | CGF.CGM.getObjCRuntime().GenerateMessageSendSuper(CGF, ReturnValueSlot(), | ||||||||
668 | CGF.getContext().VoidTy, | ||||||||
669 | method->getSelector(), | ||||||||
670 | iface, | ||||||||
671 | isCategory, | ||||||||
672 | self, | ||||||||
673 | /*is class msg*/ false, | ||||||||
674 | args, | ||||||||
675 | method); | ||||||||
676 | } | ||||||||
677 | }; | ||||||||
678 | } | ||||||||
679 | |||||||||
680 | /// StartObjCMethod - Begin emission of an ObjCMethod. This generates | ||||||||
681 | /// the LLVM function and sets the other context used by | ||||||||
682 | /// CodeGenFunction. | ||||||||
683 | void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD, | ||||||||
684 | const ObjCContainerDecl *CD) { | ||||||||
685 | SourceLocation StartLoc = OMD->getBeginLoc(); | ||||||||
686 | FunctionArgList args; | ||||||||
687 | // Check if we should generate debug info for this method. | ||||||||
688 | if (OMD->hasAttr<NoDebugAttr>()) | ||||||||
689 | DebugInfo = nullptr; // disable debug info indefinitely for this function | ||||||||
690 | |||||||||
691 | llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD); | ||||||||
692 | |||||||||
693 | const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD); | ||||||||
694 | if (OMD->isDirectMethod()) { | ||||||||
695 | Fn->setVisibility(llvm::Function::HiddenVisibility); | ||||||||
696 | CGM.SetLLVMFunctionAttributes(OMD, FI, Fn); | ||||||||
697 | CGM.SetLLVMFunctionAttributesForDefinition(OMD, Fn); | ||||||||
698 | } else { | ||||||||
699 | CGM.SetInternalFunctionAttributes(OMD, Fn, FI); | ||||||||
700 | } | ||||||||
701 | |||||||||
702 | args.push_back(OMD->getSelfDecl()); | ||||||||
703 | args.push_back(OMD->getCmdDecl()); | ||||||||
704 | |||||||||
705 | args.append(OMD->param_begin(), OMD->param_end()); | ||||||||
706 | |||||||||
707 | CurGD = OMD; | ||||||||
708 | CurEHLocation = OMD->getEndLoc(); | ||||||||
709 | |||||||||
710 | StartFunction(OMD, OMD->getReturnType(), Fn, FI, args, | ||||||||
711 | OMD->getLocation(), StartLoc); | ||||||||
712 | |||||||||
713 | if (OMD->isDirectMethod()) { | ||||||||
714 | // This function is a direct call, it has to implement a nil check | ||||||||
715 | // on entry. | ||||||||
716 | // | ||||||||
717 | // TODO: possibly have several entry points to elide the check | ||||||||
718 | CGM.getObjCRuntime().GenerateDirectMethodPrologue(*this, Fn, OMD, CD); | ||||||||
719 | } | ||||||||
720 | |||||||||
721 | // In ARC, certain methods get an extra cleanup. | ||||||||
722 | if (CGM.getLangOpts().ObjCAutoRefCount && | ||||||||
723 | OMD->isInstanceMethod() && | ||||||||
724 | OMD->getSelector().isUnarySelector()) { | ||||||||
725 | const IdentifierInfo *ident = | ||||||||
726 | OMD->getSelector().getIdentifierInfoForSlot(0); | ||||||||
727 | if (ident->isStr("dealloc")) | ||||||||
728 | EHStack.pushCleanup<FinishARCDealloc>(getARCCleanupKind()); | ||||||||
729 | } | ||||||||
730 | } | ||||||||
731 | |||||||||
732 | static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF, | ||||||||
733 | LValue lvalue, QualType type); | ||||||||
734 | |||||||||
735 | /// Generate an Objective-C method. An Objective-C method is a C function with | ||||||||
736 | /// its pointer, name, and types registered in the class structure. | ||||||||
737 | void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { | ||||||||
738 | StartObjCMethod(OMD, OMD->getClassInterface()); | ||||||||
739 | PGO.assignRegionCounters(GlobalDecl(OMD), CurFn); | ||||||||
740 | assert(isa<CompoundStmt>(OMD->getBody()))((isa<CompoundStmt>(OMD->getBody())) ? static_cast< void> (0) : __assert_fail ("isa<CompoundStmt>(OMD->getBody())" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 740, __PRETTY_FUNCTION__)); | ||||||||
741 | incrementProfileCounter(OMD->getBody()); | ||||||||
742 | EmitCompoundStmtWithoutScope(*cast<CompoundStmt>(OMD->getBody())); | ||||||||
743 | FinishFunction(OMD->getBodyRBrace()); | ||||||||
744 | } | ||||||||
745 | |||||||||
746 | /// emitStructGetterCall - Call the runtime function to load a property | ||||||||
747 | /// into the return value slot. | ||||||||
748 | static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, | ||||||||
749 | bool isAtomic, bool hasStrong) { | ||||||||
750 | ASTContext &Context = CGF.getContext(); | ||||||||
751 | |||||||||
752 | Address src = | ||||||||
753 | CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0) | ||||||||
754 | .getAddress(CGF); | ||||||||
755 | |||||||||
756 | // objc_copyStruct (ReturnValue, &structIvar, | ||||||||
757 | // sizeof (Type of Ivar), isAtomic, false); | ||||||||
758 | CallArgList args; | ||||||||
759 | |||||||||
760 | Address dest = CGF.Builder.CreateBitCast(CGF.ReturnValue, CGF.VoidPtrTy); | ||||||||
761 | args.add(RValue::get(dest.getPointer()), Context.VoidPtrTy); | ||||||||
762 | |||||||||
763 | src = CGF.Builder.CreateBitCast(src, CGF.VoidPtrTy); | ||||||||
764 | args.add(RValue::get(src.getPointer()), Context.VoidPtrTy); | ||||||||
765 | |||||||||
766 | CharUnits size = CGF.getContext().getTypeSizeInChars(ivar->getType()); | ||||||||
767 | args.add(RValue::get(CGF.CGM.getSize(size)), Context.getSizeType()); | ||||||||
768 | args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy); | ||||||||
769 | args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy); | ||||||||
770 | |||||||||
771 | llvm::FunctionCallee fn = CGF.CGM.getObjCRuntime().GetGetStructFunction(); | ||||||||
772 | CGCallee callee = CGCallee::forDirect(fn); | ||||||||
773 | CGF.EmitCall(CGF.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, args), | ||||||||
774 | callee, ReturnValueSlot(), args); | ||||||||
775 | } | ||||||||
776 | |||||||||
777 | /// Determine whether the given architecture supports unaligned atomic | ||||||||
778 | /// accesses. They don't have to be fast, just faster than a function | ||||||||
779 | /// call and a mutex. | ||||||||
780 | static bool hasUnalignedAtomics(llvm::Triple::ArchType arch) { | ||||||||
781 | // FIXME: Allow unaligned atomic load/store on x86. (It is not | ||||||||
782 | // currently supported by the backend.) | ||||||||
783 | return 0; | ||||||||
784 | } | ||||||||
785 | |||||||||
786 | /// Return the maximum size that permits atomic accesses for the given | ||||||||
787 | /// architecture. | ||||||||
788 | static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM, | ||||||||
789 | llvm::Triple::ArchType arch) { | ||||||||
790 | // ARM has 8-byte atomic accesses, but it's not clear whether we | ||||||||
791 | // want to rely on them here. | ||||||||
792 | |||||||||
793 | // In the default case, just assume that any size up to a pointer is | ||||||||
794 | // fine given adequate alignment. | ||||||||
795 | return CharUnits::fromQuantity(CGM.PointerSizeInBytes); | ||||||||
796 | } | ||||||||
797 | |||||||||
798 | namespace { | ||||||||
799 | class PropertyImplStrategy { | ||||||||
800 | public: | ||||||||
801 | enum StrategyKind { | ||||||||
802 | /// The 'native' strategy is to use the architecture's provided | ||||||||
803 | /// reads and writes. | ||||||||
804 | Native, | ||||||||
805 | |||||||||
806 | /// Use objc_setProperty and objc_getProperty. | ||||||||
807 | GetSetProperty, | ||||||||
808 | |||||||||
809 | /// Use objc_setProperty for the setter, but use expression | ||||||||
810 | /// evaluation for the getter. | ||||||||
811 | SetPropertyAndExpressionGet, | ||||||||
812 | |||||||||
813 | /// Use objc_copyStruct. | ||||||||
814 | CopyStruct, | ||||||||
815 | |||||||||
816 | /// The 'expression' strategy is to emit normal assignment or | ||||||||
817 | /// lvalue-to-rvalue expressions. | ||||||||
818 | Expression | ||||||||
819 | }; | ||||||||
820 | |||||||||
821 | StrategyKind getKind() const { return StrategyKind(Kind); } | ||||||||
822 | |||||||||
823 | bool hasStrongMember() const { return HasStrong; } | ||||||||
824 | bool isAtomic() const { return IsAtomic; } | ||||||||
825 | bool isCopy() const { return IsCopy; } | ||||||||
826 | |||||||||
827 | CharUnits getIvarSize() const { return IvarSize; } | ||||||||
828 | CharUnits getIvarAlignment() const { return IvarAlignment; } | ||||||||
829 | |||||||||
830 | PropertyImplStrategy(CodeGenModule &CGM, | ||||||||
831 | const ObjCPropertyImplDecl *propImpl); | ||||||||
832 | |||||||||
833 | private: | ||||||||
834 | unsigned Kind : 8; | ||||||||
835 | unsigned IsAtomic : 1; | ||||||||
836 | unsigned IsCopy : 1; | ||||||||
837 | unsigned HasStrong : 1; | ||||||||
838 | |||||||||
839 | CharUnits IvarSize; | ||||||||
840 | CharUnits IvarAlignment; | ||||||||
841 | }; | ||||||||
842 | } | ||||||||
843 | |||||||||
844 | /// Pick an implementation strategy for the given property synthesis. | ||||||||
845 | PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM, | ||||||||
846 | const ObjCPropertyImplDecl *propImpl) { | ||||||||
847 | const ObjCPropertyDecl *prop = propImpl->getPropertyDecl(); | ||||||||
848 | ObjCPropertyDecl::SetterKind setterKind = prop->getSetterKind(); | ||||||||
849 | |||||||||
850 | IsCopy = (setterKind == ObjCPropertyDecl::Copy); | ||||||||
851 | IsAtomic = prop->isAtomic(); | ||||||||
852 | HasStrong = false; // doesn't matter here. | ||||||||
853 | |||||||||
854 | // Evaluate the ivar's size and alignment. | ||||||||
855 | ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); | ||||||||
856 | QualType ivarType = ivar->getType(); | ||||||||
857 | std::tie(IvarSize, IvarAlignment) = | ||||||||
858 | CGM.getContext().getTypeInfoInChars(ivarType); | ||||||||
859 | |||||||||
860 | // If we have a copy property, we always have to use getProperty/setProperty. | ||||||||
861 | // TODO: we could actually use setProperty and an expression for non-atomics. | ||||||||
862 | if (IsCopy) { | ||||||||
863 | Kind = GetSetProperty; | ||||||||
864 | return; | ||||||||
865 | } | ||||||||
866 | |||||||||
867 | // Handle retain. | ||||||||
868 | if (setterKind == ObjCPropertyDecl::Retain) { | ||||||||
869 | // In GC-only, there's nothing special that needs to be done. | ||||||||
870 | if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { | ||||||||
871 | // fallthrough | ||||||||
872 | |||||||||
873 | // In ARC, if the property is non-atomic, use expression emission, | ||||||||
874 | // which translates to objc_storeStrong. This isn't required, but | ||||||||
875 | // it's slightly nicer. | ||||||||
876 | } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) { | ||||||||
877 | // Using standard expression emission for the setter is only | ||||||||
878 | // acceptable if the ivar is __strong, which won't be true if | ||||||||
879 | // the property is annotated with __attribute__((NSObject)). | ||||||||
880 | // TODO: falling all the way back to objc_setProperty here is | ||||||||
881 | // just laziness, though; we could still use objc_storeStrong | ||||||||
882 | // if we hacked it right. | ||||||||
883 | if (ivarType.getObjCLifetime() == Qualifiers::OCL_Strong) | ||||||||
884 | Kind = Expression; | ||||||||
885 | else | ||||||||
886 | Kind = SetPropertyAndExpressionGet; | ||||||||
887 | return; | ||||||||
888 | |||||||||
889 | // Otherwise, we need to at least use setProperty. However, if | ||||||||
890 | // the property isn't atomic, we can use normal expression | ||||||||
891 | // emission for the getter. | ||||||||
892 | } else if (!IsAtomic) { | ||||||||
893 | Kind = SetPropertyAndExpressionGet; | ||||||||
894 | return; | ||||||||
895 | |||||||||
896 | // Otherwise, we have to use both setProperty and getProperty. | ||||||||
897 | } else { | ||||||||
898 | Kind = GetSetProperty; | ||||||||
899 | return; | ||||||||
900 | } | ||||||||
901 | } | ||||||||
902 | |||||||||
903 | // If we're not atomic, just use expression accesses. | ||||||||
904 | if (!IsAtomic) { | ||||||||
905 | Kind = Expression; | ||||||||
906 | return; | ||||||||
907 | } | ||||||||
908 | |||||||||
909 | // Properties on bitfield ivars need to be emitted using expression | ||||||||
910 | // accesses even if they're nominally atomic. | ||||||||
911 | if (ivar->isBitField()) { | ||||||||
912 | Kind = Expression; | ||||||||
913 | return; | ||||||||
914 | } | ||||||||
915 | |||||||||
916 | // GC-qualified or ARC-qualified ivars need to be emitted as | ||||||||
917 | // expressions. This actually works out to being atomic anyway, | ||||||||
918 | // except for ARC __strong, but that should trigger the above code. | ||||||||
919 | if (ivarType.hasNonTrivialObjCLifetime() || | ||||||||
920 | (CGM.getLangOpts().getGC() && | ||||||||
921 | CGM.getContext().getObjCGCAttrKind(ivarType))) { | ||||||||
922 | Kind = Expression; | ||||||||
923 | return; | ||||||||
924 | } | ||||||||
925 | |||||||||
926 | // Compute whether the ivar has strong members. | ||||||||
927 | if (CGM.getLangOpts().getGC()) | ||||||||
928 | if (const RecordType *recordType = ivarType->getAs<RecordType>()) | ||||||||
929 | HasStrong = recordType->getDecl()->hasObjectMember(); | ||||||||
930 | |||||||||
931 | // We can never access structs with object members with a native | ||||||||
932 | // access, because we need to use write barriers. This is what | ||||||||
933 | // objc_copyStruct is for. | ||||||||
934 | if (HasStrong) { | ||||||||
935 | Kind = CopyStruct; | ||||||||
936 | return; | ||||||||
937 | } | ||||||||
938 | |||||||||
939 | // Otherwise, this is target-dependent and based on the size and | ||||||||
940 | // alignment of the ivar. | ||||||||
941 | |||||||||
942 | // If the size of the ivar is not a power of two, give up. We don't | ||||||||
943 | // want to get into the business of doing compare-and-swaps. | ||||||||
944 | if (!IvarSize.isPowerOfTwo()) { | ||||||||
945 | Kind = CopyStruct; | ||||||||
946 | return; | ||||||||
947 | } | ||||||||
948 | |||||||||
949 | llvm::Triple::ArchType arch = | ||||||||
950 | CGM.getTarget().getTriple().getArch(); | ||||||||
951 | |||||||||
952 | // Most architectures require memory to fit within a single cache | ||||||||
953 | // line, so the alignment has to be at least the size of the access. | ||||||||
954 | // Otherwise we have to grab a lock. | ||||||||
955 | if (IvarAlignment < IvarSize && !hasUnalignedAtomics(arch)) { | ||||||||
956 | Kind = CopyStruct; | ||||||||
957 | return; | ||||||||
958 | } | ||||||||
959 | |||||||||
960 | // If the ivar's size exceeds the architecture's maximum atomic | ||||||||
961 | // access size, we have to use CopyStruct. | ||||||||
962 | if (IvarSize > getMaxAtomicAccessSize(CGM, arch)) { | ||||||||
963 | Kind = CopyStruct; | ||||||||
964 | return; | ||||||||
965 | } | ||||||||
966 | |||||||||
967 | // Otherwise, we can use native loads and stores. | ||||||||
968 | Kind = Native; | ||||||||
969 | } | ||||||||
970 | |||||||||
971 | /// Generate an Objective-C property getter function. | ||||||||
972 | /// | ||||||||
973 | /// The given Decl must be an ObjCImplementationDecl. \@synthesize | ||||||||
974 | /// is illegal within a category. | ||||||||
975 | void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, | ||||||||
976 | const ObjCPropertyImplDecl *PID) { | ||||||||
977 | llvm::Constant *AtomicHelperFn = | ||||||||
978 | CodeGenFunction(CGM).GenerateObjCAtomicGetterCopyHelperFunction(PID); | ||||||||
979 | ObjCMethodDecl *OMD = PID->getGetterMethodDecl(); | ||||||||
980 | assert(OMD && "Invalid call to generate getter (empty method)")((OMD && "Invalid call to generate getter (empty method)" ) ? static_cast<void> (0) : __assert_fail ("OMD && \"Invalid call to generate getter (empty method)\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 980, __PRETTY_FUNCTION__)); | ||||||||
981 | StartObjCMethod(OMD, IMP->getClassInterface()); | ||||||||
982 | |||||||||
983 | generateObjCGetterBody(IMP, PID, OMD, AtomicHelperFn); | ||||||||
984 | |||||||||
985 | FinishFunction(OMD->getEndLoc()); | ||||||||
986 | } | ||||||||
987 | |||||||||
988 | static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) { | ||||||||
989 | const Expr *getter = propImpl->getGetterCXXConstructor(); | ||||||||
990 | if (!getter) return true; | ||||||||
991 | |||||||||
992 | // Sema only makes only of these when the ivar has a C++ class type, | ||||||||
993 | // so the form is pretty constrained. | ||||||||
994 | |||||||||
995 | // If the property has a reference type, we might just be binding a | ||||||||
996 | // reference, in which case the result will be a gl-value. We should | ||||||||
997 | // treat this as a non-trivial operation. | ||||||||
998 | if (getter->isGLValue()) | ||||||||
999 | return false; | ||||||||
1000 | |||||||||
1001 | // If we selected a trivial copy-constructor, we're okay. | ||||||||
1002 | if (const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter)) | ||||||||
1003 | return (construct->getConstructor()->isTrivial()); | ||||||||
1004 | |||||||||
1005 | // The constructor might require cleanups (in which case it's never | ||||||||
1006 | // trivial). | ||||||||
1007 | assert(isa<ExprWithCleanups>(getter))((isa<ExprWithCleanups>(getter)) ? static_cast<void> (0) : __assert_fail ("isa<ExprWithCleanups>(getter)", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1007, __PRETTY_FUNCTION__)); | ||||||||
1008 | return false; | ||||||||
1009 | } | ||||||||
1010 | |||||||||
1011 | /// emitCPPObjectAtomicGetterCall - Call the runtime function to | ||||||||
1012 | /// copy the ivar into the resturn slot. | ||||||||
1013 | static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, | ||||||||
1014 | llvm::Value *returnAddr, | ||||||||
1015 | ObjCIvarDecl *ivar, | ||||||||
1016 | llvm::Constant *AtomicHelperFn) { | ||||||||
1017 | // objc_copyCppObjectAtomic (&returnSlot, &CppObjectIvar, | ||||||||
1018 | // AtomicHelperFn); | ||||||||
1019 | CallArgList args; | ||||||||
1020 | |||||||||
1021 | // The 1st argument is the return Slot. | ||||||||
1022 | args.add(RValue::get(returnAddr), CGF.getContext().VoidPtrTy); | ||||||||
1023 | |||||||||
1024 | // The 2nd argument is the address of the ivar. | ||||||||
1025 | llvm::Value *ivarAddr = | ||||||||
1026 | CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0) | ||||||||
1027 | .getPointer(CGF); | ||||||||
1028 | ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy); | ||||||||
1029 | args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy); | ||||||||
1030 | |||||||||
1031 | // Third argument is the helper function. | ||||||||
1032 | args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy); | ||||||||
1033 | |||||||||
1034 | llvm::FunctionCallee copyCppAtomicObjectFn = | ||||||||
1035 | CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction(); | ||||||||
1036 | CGCallee callee = CGCallee::forDirect(copyCppAtomicObjectFn); | ||||||||
1037 | CGF.EmitCall( | ||||||||
1038 | CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), | ||||||||
1039 | callee, ReturnValueSlot(), args); | ||||||||
1040 | } | ||||||||
1041 | |||||||||
1042 | void | ||||||||
1043 | CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, | ||||||||
1044 | const ObjCPropertyImplDecl *propImpl, | ||||||||
1045 | const ObjCMethodDecl *GetterMethodDecl, | ||||||||
1046 | llvm::Constant *AtomicHelperFn) { | ||||||||
1047 | // If there's a non-trivial 'get' expression, we just have to emit that. | ||||||||
1048 | if (!hasTrivialGetExpr(propImpl)) { | ||||||||
1049 | if (!AtomicHelperFn) { | ||||||||
1050 | auto *ret = ReturnStmt::Create(getContext(), SourceLocation(), | ||||||||
1051 | propImpl->getGetterCXXConstructor(), | ||||||||
1052 | /* NRVOCandidate=*/nullptr); | ||||||||
1053 | EmitReturnStmt(*ret); | ||||||||
1054 | } | ||||||||
1055 | else { | ||||||||
1056 | ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); | ||||||||
1057 | emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), | ||||||||
1058 | ivar, AtomicHelperFn); | ||||||||
1059 | } | ||||||||
1060 | return; | ||||||||
1061 | } | ||||||||
1062 | |||||||||
1063 | const ObjCPropertyDecl *prop = propImpl->getPropertyDecl(); | ||||||||
1064 | QualType propType = prop->getType(); | ||||||||
1065 | ObjCMethodDecl *getterMethod = propImpl->getGetterMethodDecl(); | ||||||||
1066 | |||||||||
1067 | ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); | ||||||||
1068 | |||||||||
1069 | // Pick an implementation strategy. | ||||||||
1070 | PropertyImplStrategy strategy(CGM, propImpl); | ||||||||
1071 | switch (strategy.getKind()) { | ||||||||
1072 | case PropertyImplStrategy::Native: { | ||||||||
1073 | // We don't need to do anything for a zero-size struct. | ||||||||
1074 | if (strategy.getIvarSize().isZero()) | ||||||||
1075 | return; | ||||||||
1076 | |||||||||
1077 | LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0); | ||||||||
1078 | |||||||||
1079 | // Currently, all atomic accesses have to be through integer | ||||||||
1080 | // types, so there's no point in trying to pick a prettier type. | ||||||||
1081 | uint64_t ivarSize = getContext().toBits(strategy.getIvarSize()); | ||||||||
1082 | llvm::Type *bitcastType = llvm::Type::getIntNTy(getLLVMContext(), ivarSize); | ||||||||
1083 | bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay | ||||||||
1084 | |||||||||
1085 | // Perform an atomic load. This does not impose ordering constraints. | ||||||||
1086 | Address ivarAddr = LV.getAddress(*this); | ||||||||
1087 | ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType); | ||||||||
1088 | llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load"); | ||||||||
1089 | load->setAtomic(llvm::AtomicOrdering::Unordered); | ||||||||
1090 | |||||||||
1091 | // Store that value into the return address. Doing this with a | ||||||||
1092 | // bitcast is likely to produce some pretty ugly IR, but it's not | ||||||||
1093 | // the *most* terrible thing in the world. | ||||||||
1094 | llvm::Type *retTy = ConvertType(getterMethod->getReturnType()); | ||||||||
1095 | uint64_t retTySize = CGM.getDataLayout().getTypeSizeInBits(retTy); | ||||||||
1096 | llvm::Value *ivarVal = load; | ||||||||
1097 | if (ivarSize > retTySize) { | ||||||||
1098 | llvm::Type *newTy = llvm::Type::getIntNTy(getLLVMContext(), retTySize); | ||||||||
1099 | ivarVal = Builder.CreateTrunc(load, newTy); | ||||||||
1100 | bitcastType = newTy->getPointerTo(); | ||||||||
1101 | } | ||||||||
1102 | Builder.CreateStore(ivarVal, | ||||||||
1103 | Builder.CreateBitCast(ReturnValue, bitcastType)); | ||||||||
1104 | |||||||||
1105 | // Make sure we don't do an autorelease. | ||||||||
1106 | AutoreleaseResult = false; | ||||||||
1107 | return; | ||||||||
1108 | } | ||||||||
1109 | |||||||||
1110 | case PropertyImplStrategy::GetSetProperty: { | ||||||||
1111 | llvm::FunctionCallee getPropertyFn = | ||||||||
1112 | CGM.getObjCRuntime().GetPropertyGetFunction(); | ||||||||
1113 | if (!getPropertyFn) { | ||||||||
1114 | CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy"); | ||||||||
1115 | return; | ||||||||
1116 | } | ||||||||
1117 | CGCallee callee = CGCallee::forDirect(getPropertyFn); | ||||||||
1118 | |||||||||
1119 | // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true). | ||||||||
1120 | // FIXME: Can't this be simpler? This might even be worse than the | ||||||||
1121 | // corresponding gcc code. | ||||||||
1122 | llvm::Value *cmd = | ||||||||
1123 | Builder.CreateLoad(GetAddrOfLocalVar(getterMethod->getCmdDecl()), "cmd"); | ||||||||
1124 | llvm::Value *self = Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy); | ||||||||
1125 | llvm::Value *ivarOffset = | ||||||||
1126 | EmitIvarOffset(classImpl->getClassInterface(), ivar); | ||||||||
1127 | |||||||||
1128 | CallArgList args; | ||||||||
1129 | args.add(RValue::get(self), getContext().getObjCIdType()); | ||||||||
1130 | args.add(RValue::get(cmd), getContext().getObjCSelType()); | ||||||||
1131 | args.add(RValue::get(ivarOffset), getContext().getPointerDiffType()); | ||||||||
1132 | args.add(RValue::get(Builder.getInt1(strategy.isAtomic())), | ||||||||
1133 | getContext().BoolTy); | ||||||||
1134 | |||||||||
1135 | // FIXME: We shouldn't need to get the function info here, the | ||||||||
1136 | // runtime already should have computed it to build the function. | ||||||||
1137 | llvm::CallBase *CallInstruction; | ||||||||
1138 | RValue RV = EmitCall(getTypes().arrangeBuiltinFunctionCall( | ||||||||
1139 | getContext().getObjCIdType(), args), | ||||||||
1140 | callee, ReturnValueSlot(), args, &CallInstruction); | ||||||||
1141 | if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction)) | ||||||||
1142 | call->setTailCall(); | ||||||||
1143 | |||||||||
1144 | // We need to fix the type here. Ivars with copy & retain are | ||||||||
1145 | // always objects so we don't need to worry about complex or | ||||||||
1146 | // aggregates. | ||||||||
1147 | RV = RValue::get(Builder.CreateBitCast( | ||||||||
1148 | RV.getScalarVal(), | ||||||||
1149 | getTypes().ConvertType(getterMethod->getReturnType()))); | ||||||||
1150 | |||||||||
1151 | EmitReturnOfRValue(RV, propType); | ||||||||
1152 | |||||||||
1153 | // objc_getProperty does an autorelease, so we should suppress ours. | ||||||||
1154 | AutoreleaseResult = false; | ||||||||
1155 | |||||||||
1156 | return; | ||||||||
1157 | } | ||||||||
1158 | |||||||||
1159 | case PropertyImplStrategy::CopyStruct: | ||||||||
1160 | emitStructGetterCall(*this, ivar, strategy.isAtomic(), | ||||||||
1161 | strategy.hasStrongMember()); | ||||||||
1162 | return; | ||||||||
1163 | |||||||||
1164 | case PropertyImplStrategy::Expression: | ||||||||
1165 | case PropertyImplStrategy::SetPropertyAndExpressionGet: { | ||||||||
1166 | LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0); | ||||||||
1167 | |||||||||
1168 | QualType ivarType = ivar->getType(); | ||||||||
1169 | switch (getEvaluationKind(ivarType)) { | ||||||||
1170 | case TEK_Complex: { | ||||||||
1171 | ComplexPairTy pair = EmitLoadOfComplex(LV, SourceLocation()); | ||||||||
1172 | EmitStoreOfComplex(pair, MakeAddrLValue(ReturnValue, ivarType), | ||||||||
1173 | /*init*/ true); | ||||||||
1174 | return; | ||||||||
1175 | } | ||||||||
1176 | case TEK_Aggregate: { | ||||||||
1177 | // The return value slot is guaranteed to not be aliased, but | ||||||||
1178 | // that's not necessarily the same as "on the stack", so | ||||||||
1179 | // we still potentially need objc_memmove_collectable. | ||||||||
1180 | EmitAggregateCopy(/* Dest= */ MakeAddrLValue(ReturnValue, ivarType), | ||||||||
1181 | /* Src= */ LV, ivarType, getOverlapForReturnValue()); | ||||||||
1182 | return; | ||||||||
1183 | } | ||||||||
1184 | case TEK_Scalar: { | ||||||||
1185 | llvm::Value *value; | ||||||||
1186 | if (propType->isReferenceType()) { | ||||||||
1187 | value = LV.getAddress(*this).getPointer(); | ||||||||
1188 | } else { | ||||||||
1189 | // We want to load and autoreleaseReturnValue ARC __weak ivars. | ||||||||
1190 | if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) { | ||||||||
1191 | if (getLangOpts().ObjCAutoRefCount) { | ||||||||
1192 | value = emitARCRetainLoadOfScalar(*this, LV, ivarType); | ||||||||
1193 | } else { | ||||||||
1194 | value = EmitARCLoadWeak(LV.getAddress(*this)); | ||||||||
1195 | } | ||||||||
1196 | |||||||||
1197 | // Otherwise we want to do a simple load, suppressing the | ||||||||
1198 | // final autorelease. | ||||||||
1199 | } else { | ||||||||
1200 | value = EmitLoadOfLValue(LV, SourceLocation()).getScalarVal(); | ||||||||
1201 | AutoreleaseResult = false; | ||||||||
1202 | } | ||||||||
1203 | |||||||||
1204 | value = Builder.CreateBitCast( | ||||||||
1205 | value, ConvertType(GetterMethodDecl->getReturnType())); | ||||||||
1206 | } | ||||||||
1207 | |||||||||
1208 | EmitReturnOfRValue(RValue::get(value), propType); | ||||||||
1209 | return; | ||||||||
1210 | } | ||||||||
1211 | } | ||||||||
1212 | llvm_unreachable("bad evaluation kind")::llvm::llvm_unreachable_internal("bad evaluation kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1212); | ||||||||
1213 | } | ||||||||
1214 | |||||||||
1215 | } | ||||||||
1216 | llvm_unreachable("bad @property implementation strategy!")::llvm::llvm_unreachable_internal("bad @property implementation strategy!" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1216); | ||||||||
1217 | } | ||||||||
1218 | |||||||||
1219 | /// emitStructSetterCall - Call the runtime function to store the value | ||||||||
1220 | /// from the first formal parameter into the given ivar. | ||||||||
1221 | static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, | ||||||||
1222 | ObjCIvarDecl *ivar) { | ||||||||
1223 | // objc_copyStruct (&structIvar, &Arg, | ||||||||
1224 | // sizeof (struct something), true, false); | ||||||||
1225 | CallArgList args; | ||||||||
1226 | |||||||||
1227 | // The first argument is the address of the ivar. | ||||||||
1228 | llvm::Value *ivarAddr = | ||||||||
1229 | CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0) | ||||||||
1230 | .getPointer(CGF); | ||||||||
1231 | ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy); | ||||||||
1232 | args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy); | ||||||||
1233 | |||||||||
1234 | // The second argument is the address of the parameter variable. | ||||||||
1235 | ParmVarDecl *argVar = *OMD->param_begin(); | ||||||||
1236 | DeclRefExpr argRef(CGF.getContext(), argVar, false, | ||||||||
1237 | argVar->getType().getNonReferenceType(), VK_LValue, | ||||||||
1238 | SourceLocation()); | ||||||||
1239 | llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer(CGF); | ||||||||
1240 | argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy); | ||||||||
1241 | args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy); | ||||||||
1242 | |||||||||
1243 | // The third argument is the sizeof the type. | ||||||||
1244 | llvm::Value *size = | ||||||||
1245 | CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(ivar->getType())); | ||||||||
1246 | args.add(RValue::get(size), CGF.getContext().getSizeType()); | ||||||||
1247 | |||||||||
1248 | // The fourth argument is the 'isAtomic' flag. | ||||||||
1249 | args.add(RValue::get(CGF.Builder.getTrue()), CGF.getContext().BoolTy); | ||||||||
1250 | |||||||||
1251 | // The fifth argument is the 'hasStrong' flag. | ||||||||
1252 | // FIXME: should this really always be false? | ||||||||
1253 | args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy); | ||||||||
1254 | |||||||||
1255 | llvm::FunctionCallee fn = CGF.CGM.getObjCRuntime().GetSetStructFunction(); | ||||||||
1256 | CGCallee callee = CGCallee::forDirect(fn); | ||||||||
1257 | CGF.EmitCall( | ||||||||
1258 | CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), | ||||||||
1259 | callee, ReturnValueSlot(), args); | ||||||||
1260 | } | ||||||||
1261 | |||||||||
1262 | /// emitCPPObjectAtomicSetterCall - Call the runtime function to store | ||||||||
1263 | /// the value from the first formal parameter into the given ivar, using | ||||||||
1264 | /// the Cpp API for atomic Cpp objects with non-trivial copy assignment. | ||||||||
1265 | static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, | ||||||||
1266 | ObjCMethodDecl *OMD, | ||||||||
1267 | ObjCIvarDecl *ivar, | ||||||||
1268 | llvm::Constant *AtomicHelperFn) { | ||||||||
1269 | // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg, | ||||||||
1270 | // AtomicHelperFn); | ||||||||
1271 | CallArgList args; | ||||||||
1272 | |||||||||
1273 | // The first argument is the address of the ivar. | ||||||||
1274 | llvm::Value *ivarAddr = | ||||||||
1275 | CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0) | ||||||||
1276 | .getPointer(CGF); | ||||||||
1277 | ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy); | ||||||||
1278 | args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy); | ||||||||
1279 | |||||||||
1280 | // The second argument is the address of the parameter variable. | ||||||||
1281 | ParmVarDecl *argVar = *OMD->param_begin(); | ||||||||
1282 | DeclRefExpr argRef(CGF.getContext(), argVar, false, | ||||||||
1283 | argVar->getType().getNonReferenceType(), VK_LValue, | ||||||||
1284 | SourceLocation()); | ||||||||
1285 | llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer(CGF); | ||||||||
1286 | argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy); | ||||||||
1287 | args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy); | ||||||||
1288 | |||||||||
1289 | // Third argument is the helper function. | ||||||||
1290 | args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy); | ||||||||
1291 | |||||||||
1292 | llvm::FunctionCallee fn = | ||||||||
1293 | CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction(); | ||||||||
1294 | CGCallee callee = CGCallee::forDirect(fn); | ||||||||
1295 | CGF.EmitCall( | ||||||||
1296 | CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args), | ||||||||
1297 | callee, ReturnValueSlot(), args); | ||||||||
1298 | } | ||||||||
1299 | |||||||||
1300 | |||||||||
1301 | static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) { | ||||||||
1302 | Expr *setter = PID->getSetterCXXAssignment(); | ||||||||
1303 | if (!setter) return true; | ||||||||
1304 | |||||||||
1305 | // Sema only makes only of these when the ivar has a C++ class type, | ||||||||
1306 | // so the form is pretty constrained. | ||||||||
1307 | |||||||||
1308 | // An operator call is trivial if the function it calls is trivial. | ||||||||
1309 | // This also implies that there's nothing non-trivial going on with | ||||||||
1310 | // the arguments, because operator= can only be trivial if it's a | ||||||||
1311 | // synthesized assignment operator and therefore both parameters are | ||||||||
1312 | // references. | ||||||||
1313 | if (CallExpr *call = dyn_cast<CallExpr>(setter)) { | ||||||||
1314 | if (const FunctionDecl *callee | ||||||||
1315 | = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl())) | ||||||||
1316 | if (callee->isTrivial()) | ||||||||
1317 | return true; | ||||||||
1318 | return false; | ||||||||
1319 | } | ||||||||
1320 | |||||||||
1321 | assert(isa<ExprWithCleanups>(setter))((isa<ExprWithCleanups>(setter)) ? static_cast<void> (0) : __assert_fail ("isa<ExprWithCleanups>(setter)", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1321, __PRETTY_FUNCTION__)); | ||||||||
1322 | return false; | ||||||||
1323 | } | ||||||||
1324 | |||||||||
1325 | static bool UseOptimizedSetter(CodeGenModule &CGM) { | ||||||||
1326 | if (CGM.getLangOpts().getGC() != LangOptions::NonGC) | ||||||||
1327 | return false; | ||||||||
1328 | return CGM.getLangOpts().ObjCRuntime.hasOptimizedSetter(); | ||||||||
1329 | } | ||||||||
1330 | |||||||||
1331 | void | ||||||||
1332 | CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, | ||||||||
1333 | const ObjCPropertyImplDecl *propImpl, | ||||||||
1334 | llvm::Constant *AtomicHelperFn) { | ||||||||
1335 | ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); | ||||||||
1336 | ObjCMethodDecl *setterMethod = propImpl->getSetterMethodDecl(); | ||||||||
1337 | |||||||||
1338 | // Just use the setter expression if Sema gave us one and it's | ||||||||
1339 | // non-trivial. | ||||||||
1340 | if (!hasTrivialSetExpr(propImpl)) { | ||||||||
1341 | if (!AtomicHelperFn) | ||||||||
1342 | // If non-atomic, assignment is called directly. | ||||||||
1343 | EmitStmt(propImpl->getSetterCXXAssignment()); | ||||||||
1344 | else | ||||||||
1345 | // If atomic, assignment is called via a locking api. | ||||||||
1346 | emitCPPObjectAtomicSetterCall(*this, setterMethod, ivar, | ||||||||
1347 | AtomicHelperFn); | ||||||||
1348 | return; | ||||||||
1349 | } | ||||||||
1350 | |||||||||
1351 | PropertyImplStrategy strategy(CGM, propImpl); | ||||||||
1352 | switch (strategy.getKind()) { | ||||||||
1353 | case PropertyImplStrategy::Native: { | ||||||||
1354 | // We don't need to do anything for a zero-size struct. | ||||||||
1355 | if (strategy.getIvarSize().isZero()) | ||||||||
1356 | return; | ||||||||
1357 | |||||||||
1358 | Address argAddr = GetAddrOfLocalVar(*setterMethod->param_begin()); | ||||||||
1359 | |||||||||
1360 | LValue ivarLValue = | ||||||||
1361 | EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, /*quals*/ 0); | ||||||||
1362 | Address ivarAddr = ivarLValue.getAddress(*this); | ||||||||
1363 | |||||||||
1364 | // Currently, all atomic accesses have to be through integer | ||||||||
1365 | // types, so there's no point in trying to pick a prettier type. | ||||||||
1366 | llvm::Type *bitcastType = | ||||||||
1367 | llvm::Type::getIntNTy(getLLVMContext(), | ||||||||
1368 | getContext().toBits(strategy.getIvarSize())); | ||||||||
1369 | |||||||||
1370 | // Cast both arguments to the chosen operation type. | ||||||||
1371 | argAddr = Builder.CreateElementBitCast(argAddr, bitcastType); | ||||||||
1372 | ivarAddr = Builder.CreateElementBitCast(ivarAddr, bitcastType); | ||||||||
1373 | |||||||||
1374 | // This bitcast load is likely to cause some nasty IR. | ||||||||
1375 | llvm::Value *load = Builder.CreateLoad(argAddr); | ||||||||
1376 | |||||||||
1377 | // Perform an atomic store. There are no memory ordering requirements. | ||||||||
1378 | llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr); | ||||||||
1379 | store->setAtomic(llvm::AtomicOrdering::Unordered); | ||||||||
1380 | return; | ||||||||
1381 | } | ||||||||
1382 | |||||||||
1383 | case PropertyImplStrategy::GetSetProperty: | ||||||||
1384 | case PropertyImplStrategy::SetPropertyAndExpressionGet: { | ||||||||
1385 | |||||||||
1386 | llvm::FunctionCallee setOptimizedPropertyFn = nullptr; | ||||||||
1387 | llvm::FunctionCallee setPropertyFn = nullptr; | ||||||||
1388 | if (UseOptimizedSetter(CGM)) { | ||||||||
1389 | // 10.8 and iOS 6.0 code and GC is off | ||||||||
1390 | setOptimizedPropertyFn = | ||||||||
1391 | CGM.getObjCRuntime().GetOptimizedPropertySetFunction( | ||||||||
1392 | strategy.isAtomic(), strategy.isCopy()); | ||||||||
1393 | if (!setOptimizedPropertyFn) { | ||||||||
1394 | CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI"); | ||||||||
1395 | return; | ||||||||
1396 | } | ||||||||
1397 | } | ||||||||
1398 | else { | ||||||||
1399 | setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction(); | ||||||||
1400 | if (!setPropertyFn) { | ||||||||
1401 | CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy"); | ||||||||
1402 | return; | ||||||||
1403 | } | ||||||||
1404 | } | ||||||||
1405 | |||||||||
1406 | // Emit objc_setProperty((id) self, _cmd, offset, arg, | ||||||||
1407 | // <is-atomic>, <is-copy>). | ||||||||
1408 | llvm::Value *cmd = | ||||||||
1409 | Builder.CreateLoad(GetAddrOfLocalVar(setterMethod->getCmdDecl())); | ||||||||
1410 | llvm::Value *self = | ||||||||
1411 | Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy); | ||||||||
1412 | llvm::Value *ivarOffset = | ||||||||
1413 | EmitIvarOffset(classImpl->getClassInterface(), ivar); | ||||||||
1414 | Address argAddr = GetAddrOfLocalVar(*setterMethod->param_begin()); | ||||||||
1415 | llvm::Value *arg = Builder.CreateLoad(argAddr, "arg"); | ||||||||
1416 | arg = Builder.CreateBitCast(arg, VoidPtrTy); | ||||||||
1417 | |||||||||
1418 | CallArgList args; | ||||||||
1419 | args.add(RValue::get(self), getContext().getObjCIdType()); | ||||||||
1420 | args.add(RValue::get(cmd), getContext().getObjCSelType()); | ||||||||
1421 | if (setOptimizedPropertyFn) { | ||||||||
1422 | args.add(RValue::get(arg), getContext().getObjCIdType()); | ||||||||
1423 | args.add(RValue::get(ivarOffset), getContext().getPointerDiffType()); | ||||||||
1424 | CGCallee callee = CGCallee::forDirect(setOptimizedPropertyFn); | ||||||||
1425 | EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args), | ||||||||
1426 | callee, ReturnValueSlot(), args); | ||||||||
1427 | } else { | ||||||||
1428 | args.add(RValue::get(ivarOffset), getContext().getPointerDiffType()); | ||||||||
1429 | args.add(RValue::get(arg), getContext().getObjCIdType()); | ||||||||
1430 | args.add(RValue::get(Builder.getInt1(strategy.isAtomic())), | ||||||||
1431 | getContext().BoolTy); | ||||||||
1432 | args.add(RValue::get(Builder.getInt1(strategy.isCopy())), | ||||||||
1433 | getContext().BoolTy); | ||||||||
1434 | // FIXME: We shouldn't need to get the function info here, the runtime | ||||||||
1435 | // already should have computed it to build the function. | ||||||||
1436 | CGCallee callee = CGCallee::forDirect(setPropertyFn); | ||||||||
1437 | EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args), | ||||||||
1438 | callee, ReturnValueSlot(), args); | ||||||||
1439 | } | ||||||||
1440 | |||||||||
1441 | return; | ||||||||
1442 | } | ||||||||
1443 | |||||||||
1444 | case PropertyImplStrategy::CopyStruct: | ||||||||
1445 | emitStructSetterCall(*this, setterMethod, ivar); | ||||||||
1446 | return; | ||||||||
1447 | |||||||||
1448 | case PropertyImplStrategy::Expression: | ||||||||
1449 | break; | ||||||||
1450 | } | ||||||||
1451 | |||||||||
1452 | // Otherwise, fake up some ASTs and emit a normal assignment. | ||||||||
1453 | ValueDecl *selfDecl = setterMethod->getSelfDecl(); | ||||||||
1454 | DeclRefExpr self(getContext(), selfDecl, false, selfDecl->getType(), | ||||||||
1455 | VK_LValue, SourceLocation()); | ||||||||
1456 | ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack, | ||||||||
1457 | selfDecl->getType(), CK_LValueToRValue, &self, | ||||||||
1458 | VK_RValue); | ||||||||
1459 | ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(), | ||||||||
1460 | SourceLocation(), SourceLocation(), | ||||||||
1461 | &selfLoad, true, true); | ||||||||
1462 | |||||||||
1463 | ParmVarDecl *argDecl = *setterMethod->param_begin(); | ||||||||
1464 | QualType argType = argDecl->getType().getNonReferenceType(); | ||||||||
1465 | DeclRefExpr arg(getContext(), argDecl, false, argType, VK_LValue, | ||||||||
1466 | SourceLocation()); | ||||||||
1467 | ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack, | ||||||||
1468 | argType.getUnqualifiedType(), CK_LValueToRValue, | ||||||||
1469 | &arg, VK_RValue); | ||||||||
1470 | |||||||||
1471 | // The property type can differ from the ivar type in some situations with | ||||||||
1472 | // Objective-C pointer types, we can always bit cast the RHS in these cases. | ||||||||
1473 | // The following absurdity is just to ensure well-formed IR. | ||||||||
1474 | CastKind argCK = CK_NoOp; | ||||||||
1475 | if (ivarRef.getType()->isObjCObjectPointerType()) { | ||||||||
1476 | if (argLoad.getType()->isObjCObjectPointerType()) | ||||||||
1477 | argCK = CK_BitCast; | ||||||||
1478 | else if (argLoad.getType()->isBlockPointerType()) | ||||||||
1479 | argCK = CK_BlockPointerToObjCPointerCast; | ||||||||
1480 | else | ||||||||
1481 | argCK = CK_CPointerToObjCPointerCast; | ||||||||
1482 | } else if (ivarRef.getType()->isBlockPointerType()) { | ||||||||
1483 | if (argLoad.getType()->isBlockPointerType()) | ||||||||
1484 | argCK = CK_BitCast; | ||||||||
1485 | else | ||||||||
1486 | argCK = CK_AnyPointerToBlockPointerCast; | ||||||||
1487 | } else if (ivarRef.getType()->isPointerType()) { | ||||||||
1488 | argCK = CK_BitCast; | ||||||||
1489 | } | ||||||||
1490 | ImplicitCastExpr argCast(ImplicitCastExpr::OnStack, | ||||||||
1491 | ivarRef.getType(), argCK, &argLoad, | ||||||||
1492 | VK_RValue); | ||||||||
1493 | Expr *finalArg = &argLoad; | ||||||||
1494 | if (!getContext().hasSameUnqualifiedType(ivarRef.getType(), | ||||||||
1495 | argLoad.getType())) | ||||||||
1496 | finalArg = &argCast; | ||||||||
1497 | |||||||||
1498 | |||||||||
1499 | BinaryOperator assign(&ivarRef, finalArg, BO_Assign, | ||||||||
1500 | ivarRef.getType(), VK_RValue, OK_Ordinary, | ||||||||
1501 | SourceLocation(), FPOptions()); | ||||||||
1502 | EmitStmt(&assign); | ||||||||
1503 | } | ||||||||
1504 | |||||||||
1505 | /// Generate an Objective-C property setter function. | ||||||||
1506 | /// | ||||||||
1507 | /// The given Decl must be an ObjCImplementationDecl. \@synthesize | ||||||||
1508 | /// is illegal within a category. | ||||||||
1509 | void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, | ||||||||
1510 | const ObjCPropertyImplDecl *PID) { | ||||||||
1511 | llvm::Constant *AtomicHelperFn = | ||||||||
1512 | CodeGenFunction(CGM).GenerateObjCAtomicSetterCopyHelperFunction(PID); | ||||||||
1513 | ObjCMethodDecl *OMD = PID->getSetterMethodDecl(); | ||||||||
1514 | assert(OMD && "Invalid call to generate setter (empty method)")((OMD && "Invalid call to generate setter (empty method)" ) ? static_cast<void> (0) : __assert_fail ("OMD && \"Invalid call to generate setter (empty method)\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1514, __PRETTY_FUNCTION__)); | ||||||||
1515 | StartObjCMethod(OMD, IMP->getClassInterface()); | ||||||||
1516 | |||||||||
1517 | generateObjCSetterBody(IMP, PID, AtomicHelperFn); | ||||||||
1518 | |||||||||
1519 | FinishFunction(OMD->getEndLoc()); | ||||||||
1520 | } | ||||||||
1521 | |||||||||
1522 | namespace { | ||||||||
1523 | struct DestroyIvar final : EHScopeStack::Cleanup { | ||||||||
1524 | private: | ||||||||
1525 | llvm::Value *addr; | ||||||||
1526 | const ObjCIvarDecl *ivar; | ||||||||
1527 | CodeGenFunction::Destroyer *destroyer; | ||||||||
1528 | bool useEHCleanupForArray; | ||||||||
1529 | public: | ||||||||
1530 | DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar, | ||||||||
1531 | CodeGenFunction::Destroyer *destroyer, | ||||||||
1532 | bool useEHCleanupForArray) | ||||||||
1533 | : addr(addr), ivar(ivar), destroyer(destroyer), | ||||||||
1534 | useEHCleanupForArray(useEHCleanupForArray) {} | ||||||||
1535 | |||||||||
1536 | void Emit(CodeGenFunction &CGF, Flags flags) override { | ||||||||
1537 | LValue lvalue | ||||||||
1538 | = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0); | ||||||||
1539 | CGF.emitDestroy(lvalue.getAddress(CGF), ivar->getType(), destroyer, | ||||||||
1540 | flags.isForNormalCleanup() && useEHCleanupForArray); | ||||||||
1541 | } | ||||||||
1542 | }; | ||||||||
1543 | } | ||||||||
1544 | |||||||||
1545 | /// Like CodeGenFunction::destroyARCStrong, but do it with a call. | ||||||||
1546 | static void destroyARCStrongWithStore(CodeGenFunction &CGF, | ||||||||
1547 | Address addr, | ||||||||
1548 | QualType type) { | ||||||||
1549 | llvm::Value *null = getNullForVariable(addr); | ||||||||
1550 | CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true); | ||||||||
1551 | } | ||||||||
1552 | |||||||||
1553 | static void emitCXXDestructMethod(CodeGenFunction &CGF, | ||||||||
1554 | ObjCImplementationDecl *impl) { | ||||||||
1555 | CodeGenFunction::RunCleanupsScope scope(CGF); | ||||||||
1556 | |||||||||
1557 | llvm::Value *self = CGF.LoadObjCSelf(); | ||||||||
1558 | |||||||||
1559 | const ObjCInterfaceDecl *iface = impl->getClassInterface(); | ||||||||
1560 | for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); | ||||||||
1561 | ivar; ivar = ivar->getNextIvar()) { | ||||||||
1562 | QualType type = ivar->getType(); | ||||||||
1563 | |||||||||
1564 | // Check whether the ivar is a destructible type. | ||||||||
1565 | QualType::DestructionKind dtorKind = type.isDestructedType(); | ||||||||
1566 | if (!dtorKind) continue; | ||||||||
1567 | |||||||||
1568 | CodeGenFunction::Destroyer *destroyer = nullptr; | ||||||||
1569 | |||||||||
1570 | // Use a call to objc_storeStrong to destroy strong ivars, for the | ||||||||
1571 | // general benefit of the tools. | ||||||||
1572 | if (dtorKind == QualType::DK_objc_strong_lifetime) { | ||||||||
1573 | destroyer = destroyARCStrongWithStore; | ||||||||
1574 | |||||||||
1575 | // Otherwise use the default for the destruction kind. | ||||||||
1576 | } else { | ||||||||
1577 | destroyer = CGF.getDestroyer(dtorKind); | ||||||||
1578 | } | ||||||||
1579 | |||||||||
1580 | CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind); | ||||||||
1581 | |||||||||
1582 | CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer, | ||||||||
1583 | cleanupKind & EHCleanup); | ||||||||
1584 | } | ||||||||
1585 | |||||||||
1586 | assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?")((scope.requiresCleanups() && "nothing to do in .cxx_destruct?" ) ? static_cast<void> (0) : __assert_fail ("scope.requiresCleanups() && \"nothing to do in .cxx_destruct?\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 1586, __PRETTY_FUNCTION__)); | ||||||||
1587 | } | ||||||||
1588 | |||||||||
1589 | void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, | ||||||||
1590 | ObjCMethodDecl *MD, | ||||||||
1591 | bool ctor) { | ||||||||
1592 | MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface()); | ||||||||
1593 | StartObjCMethod(MD, IMP->getClassInterface()); | ||||||||
1594 | |||||||||
1595 | // Emit .cxx_construct. | ||||||||
1596 | if (ctor) { | ||||||||
1597 | // Suppress the final autorelease in ARC. | ||||||||
1598 | AutoreleaseResult = false; | ||||||||
1599 | |||||||||
1600 | for (const auto *IvarInit : IMP->inits()) { | ||||||||
1601 | FieldDecl *Field = IvarInit->getAnyMember(); | ||||||||
1602 | ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); | ||||||||
1603 | LValue LV = EmitLValueForIvar(TypeOfSelfObject(), | ||||||||
1604 | LoadObjCSelf(), Ivar, 0); | ||||||||
1605 | EmitAggExpr(IvarInit->getInit(), | ||||||||
1606 | AggValueSlot::forLValue(LV, *this, AggValueSlot::IsDestructed, | ||||||||
1607 | AggValueSlot::DoesNotNeedGCBarriers, | ||||||||
1608 | AggValueSlot::IsNotAliased, | ||||||||
1609 | AggValueSlot::DoesNotOverlap)); | ||||||||
1610 | } | ||||||||
1611 | // constructor returns 'self'. | ||||||||
1612 | CodeGenTypes &Types = CGM.getTypes(); | ||||||||
1613 | QualType IdTy(CGM.getContext().getObjCIdType()); | ||||||||
1614 | llvm::Value *SelfAsId = | ||||||||
1615 | Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); | ||||||||
1616 | EmitReturnOfRValue(RValue::get(SelfAsId), IdTy); | ||||||||
1617 | |||||||||
1618 | // Emit .cxx_destruct. | ||||||||
1619 | } else { | ||||||||
1620 | emitCXXDestructMethod(*this, IMP); | ||||||||
1621 | } | ||||||||
1622 | FinishFunction(); | ||||||||
1623 | } | ||||||||
1624 | |||||||||
1625 | llvm::Value *CodeGenFunction::LoadObjCSelf() { | ||||||||
1626 | VarDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl(); | ||||||||
1627 | DeclRefExpr DRE(getContext(), Self, | ||||||||
1628 | /*is enclosing local*/ (CurFuncDecl != CurCodeDecl), | ||||||||
1629 | Self->getType(), VK_LValue, SourceLocation()); | ||||||||
1630 | return EmitLoadOfScalar(EmitDeclRefLValue(&DRE), SourceLocation()); | ||||||||
1631 | } | ||||||||
1632 | |||||||||
1633 | QualType CodeGenFunction::TypeOfSelfObject() { | ||||||||
1634 | const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); | ||||||||
1635 | ImplicitParamDecl *selfDecl = OMD->getSelfDecl(); | ||||||||
1636 | const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>( | ||||||||
1637 | getContext().getCanonicalType(selfDecl->getType())); | ||||||||
1638 | return PTy->getPointeeType(); | ||||||||
1639 | } | ||||||||
1640 | |||||||||
1641 | void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ | ||||||||
1642 | llvm::FunctionCallee EnumerationMutationFnPtr = | ||||||||
1643 | CGM.getObjCRuntime().EnumerationMutationFunction(); | ||||||||
1644 | if (!EnumerationMutationFnPtr) { | ||||||||
1645 | CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime"); | ||||||||
1646 | return; | ||||||||
1647 | } | ||||||||
1648 | CGCallee EnumerationMutationFn = | ||||||||
1649 | CGCallee::forDirect(EnumerationMutationFnPtr); | ||||||||
1650 | |||||||||
1651 | CGDebugInfo *DI = getDebugInfo(); | ||||||||
1652 | if (DI) | ||||||||
1653 | DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); | ||||||||
1654 | |||||||||
1655 | RunCleanupsScope ForScope(*this); | ||||||||
1656 | |||||||||
1657 | // The local variable comes into scope immediately. | ||||||||
1658 | AutoVarEmission variable = AutoVarEmission::invalid(); | ||||||||
1659 | if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) | ||||||||
1660 | variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl())); | ||||||||
1661 | |||||||||
1662 | JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end"); | ||||||||
1663 | |||||||||
1664 | // Fast enumeration state. | ||||||||
1665 | QualType StateTy = CGM.getObjCFastEnumerationStateType(); | ||||||||
1666 | Address StatePtr = CreateMemTemp(StateTy, "state.ptr"); | ||||||||
1667 | EmitNullInitialization(StatePtr, StateTy); | ||||||||
1668 | |||||||||
1669 | // Number of elements in the items array. | ||||||||
1670 | static const unsigned NumItems = 16; | ||||||||
1671 | |||||||||
1672 | // Fetch the countByEnumeratingWithState:objects:count: selector. | ||||||||
1673 | IdentifierInfo *II[] = { | ||||||||
1674 | &CGM.getContext().Idents.get("countByEnumeratingWithState"), | ||||||||
1675 | &CGM.getContext().Idents.get("objects"), | ||||||||
1676 | &CGM.getContext().Idents.get("count") | ||||||||
1677 | }; | ||||||||
1678 | Selector FastEnumSel = | ||||||||
1679 | CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]); | ||||||||
1680 | |||||||||
1681 | QualType ItemsTy = | ||||||||
1682 | getContext().getConstantArrayType(getContext().getObjCIdType(), | ||||||||
1683 | llvm::APInt(32, NumItems), nullptr, | ||||||||
1684 | ArrayType::Normal, 0); | ||||||||
1685 | Address ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); | ||||||||
1686 | |||||||||
1687 | // Emit the collection pointer. In ARC, we do a retain. | ||||||||
1688 | llvm::Value *Collection; | ||||||||
1689 | if (getLangOpts().ObjCAutoRefCount) { | ||||||||
1690 | Collection = EmitARCRetainScalarExpr(S.getCollection()); | ||||||||
1691 | |||||||||
1692 | // Enter a cleanup to do the release. | ||||||||
1693 | EmitObjCConsumeObject(S.getCollection()->getType(), Collection); | ||||||||
1694 | } else { | ||||||||
1695 | Collection = EmitScalarExpr(S.getCollection()); | ||||||||
1696 | } | ||||||||
1697 | |||||||||
1698 | // The 'continue' label needs to appear within the cleanup for the | ||||||||
1699 | // collection object. | ||||||||
1700 | JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next"); | ||||||||
1701 | |||||||||
1702 | // Send it our message: | ||||||||
1703 | CallArgList Args; | ||||||||
1704 | |||||||||
1705 | // The first argument is a temporary of the enumeration-state type. | ||||||||
1706 | Args.add(RValue::get(StatePtr.getPointer()), | ||||||||
1707 | getContext().getPointerType(StateTy)); | ||||||||
1708 | |||||||||
1709 | // The second argument is a temporary array with space for NumItems | ||||||||
1710 | // pointers. We'll actually be loading elements from the array | ||||||||
1711 | // pointer written into the control state; this buffer is so that | ||||||||
1712 | // collections that *aren't* backed by arrays can still queue up | ||||||||
1713 | // batches of elements. | ||||||||
1714 | Args.add(RValue::get(ItemsPtr.getPointer()), | ||||||||
1715 | getContext().getPointerType(ItemsTy)); | ||||||||
1716 | |||||||||
1717 | // The third argument is the capacity of that temporary array. | ||||||||
1718 | llvm::Type *NSUIntegerTy = ConvertType(getContext().getNSUIntegerType()); | ||||||||
1719 | llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems); | ||||||||
1720 | Args.add(RValue::get(Count), getContext().getNSUIntegerType()); | ||||||||
1721 | |||||||||
1722 | // Start the enumeration. | ||||||||
1723 | RValue CountRV = | ||||||||
1724 | CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
1725 | getContext().getNSUIntegerType(), | ||||||||
1726 | FastEnumSel, Collection, Args); | ||||||||
1727 | |||||||||
1728 | // The initial number of objects that were returned in the buffer. | ||||||||
1729 | llvm::Value *initialBufferLimit = CountRV.getScalarVal(); | ||||||||
1730 | |||||||||
1731 | llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty"); | ||||||||
1732 | llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit"); | ||||||||
1733 | |||||||||
1734 | llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy); | ||||||||
1735 | |||||||||
1736 | // If the limit pointer was zero to begin with, the collection is | ||||||||
1737 | // empty; skip all this. Set the branch weight assuming this has the same | ||||||||
1738 | // probability of exiting the loop as any other loop exit. | ||||||||
1739 | uint64_t EntryCount = getCurrentProfileCount(); | ||||||||
1740 | Builder.CreateCondBr( | ||||||||
1741 | Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"), EmptyBB, | ||||||||
1742 | LoopInitBB, | ||||||||
1743 | createProfileWeights(EntryCount, getProfileCount(S.getBody()))); | ||||||||
1744 | |||||||||
1745 | // Otherwise, initialize the loop. | ||||||||
1746 | EmitBlock(LoopInitBB); | ||||||||
1747 | |||||||||
1748 | // Save the initial mutations value. This is the value at an | ||||||||
1749 | // address that was written into the state object by | ||||||||
1750 | // countByEnumeratingWithState:objects:count:. | ||||||||
1751 | Address StateMutationsPtrPtr = | ||||||||
1752 | Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); | ||||||||
1753 | llvm::Value *StateMutationsPtr | ||||||||
1754 | = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); | ||||||||
1755 | |||||||||
1756 | llvm::Value *initialMutations = | ||||||||
1757 | Builder.CreateAlignedLoad(StateMutationsPtr, getPointerAlign(), | ||||||||
1758 | "forcoll.initial-mutations"); | ||||||||
1759 | |||||||||
1760 | // Start looping. This is the point we return to whenever we have a | ||||||||
1761 | // fresh, non-empty batch of objects. | ||||||||
1762 | llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody"); | ||||||||
1763 | EmitBlock(LoopBodyBB); | ||||||||
1764 | |||||||||
1765 | // The current index into the buffer. | ||||||||
1766 | llvm::PHINode *index = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.index"); | ||||||||
1767 | index->addIncoming(zero, LoopInitBB); | ||||||||
1768 | |||||||||
1769 | // The current buffer size. | ||||||||
1770 | llvm::PHINode *count = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.count"); | ||||||||
1771 | count->addIncoming(initialBufferLimit, LoopInitBB); | ||||||||
1772 | |||||||||
1773 | incrementProfileCounter(&S); | ||||||||
1774 | |||||||||
1775 | // Check whether the mutations value has changed from where it was | ||||||||
1776 | // at start. StateMutationsPtr should actually be invariant between | ||||||||
1777 | // refreshes. | ||||||||
1778 | StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); | ||||||||
1779 | llvm::Value *currentMutations | ||||||||
1780 | = Builder.CreateAlignedLoad(StateMutationsPtr, getPointerAlign(), | ||||||||
1781 | "statemutations"); | ||||||||
1782 | |||||||||
1783 | llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated"); | ||||||||
1784 | llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated"); | ||||||||
1785 | |||||||||
1786 | Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations), | ||||||||
1787 | WasNotMutatedBB, WasMutatedBB); | ||||||||
1788 | |||||||||
1789 | // If so, call the enumeration-mutation function. | ||||||||
1790 | EmitBlock(WasMutatedBB); | ||||||||
1791 | llvm::Value *V = | ||||||||
1792 | Builder.CreateBitCast(Collection, | ||||||||
1793 | ConvertType(getContext().getObjCIdType())); | ||||||||
1794 | CallArgList Args2; | ||||||||
1795 | Args2.add(RValue::get(V), getContext().getObjCIdType()); | ||||||||
1796 | // FIXME: We shouldn't need to get the function info here, the runtime already | ||||||||
1797 | // should have computed it to build the function. | ||||||||
1798 | EmitCall( | ||||||||
1799 | CGM.getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, Args2), | ||||||||
1800 | EnumerationMutationFn, ReturnValueSlot(), Args2); | ||||||||
1801 | |||||||||
1802 | // Otherwise, or if the mutation function returns, just continue. | ||||||||
1803 | EmitBlock(WasNotMutatedBB); | ||||||||
1804 | |||||||||
1805 | // Initialize the element variable. | ||||||||
1806 | RunCleanupsScope elementVariableScope(*this); | ||||||||
1807 | bool elementIsVariable; | ||||||||
1808 | LValue elementLValue; | ||||||||
1809 | QualType elementType; | ||||||||
1810 | if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) { | ||||||||
1811 | // Initialize the variable, in case it's a __block variable or something. | ||||||||
1812 | EmitAutoVarInit(variable); | ||||||||
1813 | |||||||||
1814 | const VarDecl *D = cast<VarDecl>(SD->getSingleDecl()); | ||||||||
1815 | DeclRefExpr tempDRE(getContext(), const_cast<VarDecl *>(D), false, | ||||||||
1816 | D->getType(), VK_LValue, SourceLocation()); | ||||||||
1817 | elementLValue = EmitLValue(&tempDRE); | ||||||||
1818 | elementType = D->getType(); | ||||||||
1819 | elementIsVariable = true; | ||||||||
1820 | |||||||||
1821 | if (D->isARCPseudoStrong()) | ||||||||
1822 | elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone); | ||||||||
1823 | } else { | ||||||||
1824 | elementLValue = LValue(); // suppress warning | ||||||||
1825 | elementType = cast<Expr>(S.getElement())->getType(); | ||||||||
1826 | elementIsVariable = false; | ||||||||
1827 | } | ||||||||
1828 | llvm::Type *convertedElementType = ConvertType(elementType); | ||||||||
1829 | |||||||||
1830 | // Fetch the buffer out of the enumeration state. | ||||||||
1831 | // TODO: this pointer should actually be invariant between | ||||||||
1832 | // refreshes, which would help us do certain loop optimizations. | ||||||||
1833 | Address StateItemsPtr = | ||||||||
1834 | Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); | ||||||||
1835 | llvm::Value *EnumStateItems = | ||||||||
1836 | Builder.CreateLoad(StateItemsPtr, "stateitems"); | ||||||||
1837 | |||||||||
1838 | // Fetch the value at the current index from the buffer. | ||||||||
1839 | llvm::Value *CurrentItemPtr = | ||||||||
1840 | Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr"); | ||||||||
1841 | llvm::Value *CurrentItem = | ||||||||
1842 | Builder.CreateAlignedLoad(CurrentItemPtr, getPointerAlign()); | ||||||||
1843 | |||||||||
1844 | // Cast that value to the right type. | ||||||||
1845 | CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType, | ||||||||
1846 | "currentitem"); | ||||||||
1847 | |||||||||
1848 | // Make sure we have an l-value. Yes, this gets evaluated every | ||||||||
1849 | // time through the loop. | ||||||||
1850 | if (!elementIsVariable) { | ||||||||
1851 | elementLValue = EmitLValue(cast<Expr>(S.getElement())); | ||||||||
1852 | EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue); | ||||||||
1853 | } else { | ||||||||
1854 | EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue, | ||||||||
1855 | /*isInit*/ true); | ||||||||
1856 | } | ||||||||
1857 | |||||||||
1858 | // If we do have an element variable, this assignment is the end of | ||||||||
1859 | // its initialization. | ||||||||
1860 | if (elementIsVariable) | ||||||||
1861 | EmitAutoVarCleanups(variable); | ||||||||
1862 | |||||||||
1863 | // Perform the loop body, setting up break and continue labels. | ||||||||
1864 | BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); | ||||||||
1865 | { | ||||||||
1866 | RunCleanupsScope Scope(*this); | ||||||||
1867 | EmitStmt(S.getBody()); | ||||||||
1868 | } | ||||||||
1869 | BreakContinueStack.pop_back(); | ||||||||
1870 | |||||||||
1871 | // Destroy the element variable now. | ||||||||
1872 | elementVariableScope.ForceCleanup(); | ||||||||
1873 | |||||||||
1874 | // Check whether there are more elements. | ||||||||
1875 | EmitBlock(AfterBody.getBlock()); | ||||||||
1876 | |||||||||
1877 | llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch"); | ||||||||
1878 | |||||||||
1879 | // First we check in the local buffer. | ||||||||
1880 | llvm::Value *indexPlusOne = | ||||||||
1881 | Builder.CreateAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1)); | ||||||||
1882 | |||||||||
1883 | // If we haven't overrun the buffer yet, we can continue. | ||||||||
1884 | // Set the branch weights based on the simplifying assumption that this is | ||||||||
1885 | // like a while-loop, i.e., ignoring that the false branch fetches more | ||||||||
1886 | // elements and then returns to the loop. | ||||||||
1887 | Builder.CreateCondBr( | ||||||||
1888 | Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB, | ||||||||
1889 | createProfileWeights(getProfileCount(S.getBody()), EntryCount)); | ||||||||
1890 | |||||||||
1891 | index->addIncoming(indexPlusOne, AfterBody.getBlock()); | ||||||||
1892 | count->addIncoming(count, AfterBody.getBlock()); | ||||||||
1893 | |||||||||
1894 | // Otherwise, we have to fetch more elements. | ||||||||
1895 | EmitBlock(FetchMoreBB); | ||||||||
1896 | |||||||||
1897 | CountRV = | ||||||||
1898 | CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
1899 | getContext().getNSUIntegerType(), | ||||||||
1900 | FastEnumSel, Collection, Args); | ||||||||
1901 | |||||||||
1902 | // If we got a zero count, we're done. | ||||||||
1903 | llvm::Value *refetchCount = CountRV.getScalarVal(); | ||||||||
1904 | |||||||||
1905 | // (note that the message send might split FetchMoreBB) | ||||||||
1906 | index->addIncoming(zero, Builder.GetInsertBlock()); | ||||||||
1907 | count->addIncoming(refetchCount, Builder.GetInsertBlock()); | ||||||||
1908 | |||||||||
1909 | Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero), | ||||||||
1910 | EmptyBB, LoopBodyBB); | ||||||||
1911 | |||||||||
1912 | // No more elements. | ||||||||
1913 | EmitBlock(EmptyBB); | ||||||||
1914 | |||||||||
1915 | if (!elementIsVariable) { | ||||||||
1916 | // If the element was not a declaration, set it to be null. | ||||||||
1917 | |||||||||
1918 | llvm::Value *null = llvm::Constant::getNullValue(convertedElementType); | ||||||||
1919 | elementLValue = EmitLValue(cast<Expr>(S.getElement())); | ||||||||
1920 | EmitStoreThroughLValue(RValue::get(null), elementLValue); | ||||||||
1921 | } | ||||||||
1922 | |||||||||
1923 | if (DI) | ||||||||
1924 | DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); | ||||||||
1925 | |||||||||
1926 | ForScope.ForceCleanup(); | ||||||||
1927 | EmitBlock(LoopEnd.getBlock()); | ||||||||
1928 | } | ||||||||
1929 | |||||||||
1930 | void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) { | ||||||||
1931 | CGM.getObjCRuntime().EmitTryStmt(*this, S); | ||||||||
1932 | } | ||||||||
1933 | |||||||||
1934 | void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) { | ||||||||
1935 | CGM.getObjCRuntime().EmitThrowStmt(*this, S); | ||||||||
1936 | } | ||||||||
1937 | |||||||||
1938 | void CodeGenFunction::EmitObjCAtSynchronizedStmt( | ||||||||
1939 | const ObjCAtSynchronizedStmt &S) { | ||||||||
1940 | CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S); | ||||||||
1941 | } | ||||||||
1942 | |||||||||
1943 | namespace { | ||||||||
1944 | struct CallObjCRelease final : EHScopeStack::Cleanup { | ||||||||
1945 | CallObjCRelease(llvm::Value *object) : object(object) {} | ||||||||
1946 | llvm::Value *object; | ||||||||
1947 | |||||||||
1948 | void Emit(CodeGenFunction &CGF, Flags flags) override { | ||||||||
1949 | // Releases at the end of the full-expression are imprecise. | ||||||||
1950 | CGF.EmitARCRelease(object, ARCImpreciseLifetime); | ||||||||
1951 | } | ||||||||
1952 | }; | ||||||||
1953 | } | ||||||||
1954 | |||||||||
1955 | /// Produce the code for a CK_ARCConsumeObject. Does a primitive | ||||||||
1956 | /// release at the end of the full-expression. | ||||||||
1957 | llvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type, | ||||||||
1958 | llvm::Value *object) { | ||||||||
1959 | // If we're in a conditional branch, we need to make the cleanup | ||||||||
1960 | // conditional. | ||||||||
1961 | pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object); | ||||||||
1962 | return object; | ||||||||
1963 | } | ||||||||
1964 | |||||||||
1965 | llvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type, | ||||||||
1966 | llvm::Value *value) { | ||||||||
1967 | return EmitARCRetainAutorelease(type, value); | ||||||||
1968 | } | ||||||||
1969 | |||||||||
1970 | /// Given a number of pointers, inform the optimizer that they're | ||||||||
1971 | /// being intrinsically used up until this point in the program. | ||||||||
1972 | void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) { | ||||||||
1973 | llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_use; | ||||||||
1974 | if (!fn) | ||||||||
1975 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use); | ||||||||
1976 | |||||||||
1977 | // This isn't really a "runtime" function, but as an intrinsic it | ||||||||
1978 | // doesn't really matter as long as we align things up. | ||||||||
1979 | EmitNounwindRuntimeCall(fn, values); | ||||||||
1980 | } | ||||||||
1981 | |||||||||
1982 | static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF) { | ||||||||
1983 | if (auto *F = dyn_cast<llvm::Function>(RTF)) { | ||||||||
1984 | // If the target runtime doesn't naturally support ARC, emit weak | ||||||||
1985 | // references to the runtime support library. We don't really | ||||||||
1986 | // permit this to fail, but we need a particular relocation style. | ||||||||
1987 | if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC() && | ||||||||
1988 | !CGM.getTriple().isOSBinFormatCOFF()) { | ||||||||
1989 | F->setLinkage(llvm::Function::ExternalWeakLinkage); | ||||||||
1990 | } | ||||||||
1991 | } | ||||||||
1992 | } | ||||||||
1993 | |||||||||
1994 | static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, | ||||||||
1995 | llvm::FunctionCallee RTF) { | ||||||||
1996 | setARCRuntimeFunctionLinkage(CGM, RTF.getCallee()); | ||||||||
1997 | } | ||||||||
1998 | |||||||||
1999 | /// Perform an operation having the signature | ||||||||
2000 | /// i8* (i8*) | ||||||||
2001 | /// where a null input causes a no-op and returns null. | ||||||||
2002 | static llvm::Value *emitARCValueOperation( | ||||||||
2003 | CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, | ||||||||
2004 | llvm::Function *&fn, llvm::Intrinsic::ID IntID, | ||||||||
2005 | llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) { | ||||||||
2006 | if (isa<llvm::ConstantPointerNull>(value)) | ||||||||
2007 | return value; | ||||||||
2008 | |||||||||
2009 | if (!fn) { | ||||||||
2010 | fn = CGF.CGM.getIntrinsic(IntID); | ||||||||
2011 | setARCRuntimeFunctionLinkage(CGF.CGM, fn); | ||||||||
2012 | } | ||||||||
2013 | |||||||||
2014 | // Cast the argument to 'id'. | ||||||||
2015 | llvm::Type *origType = returnType ? returnType : value->getType(); | ||||||||
2016 | value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); | ||||||||
2017 | |||||||||
2018 | // Call the function. | ||||||||
2019 | llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value); | ||||||||
2020 | call->setTailCallKind(tailKind); | ||||||||
2021 | |||||||||
2022 | // Cast the result back to the original type. | ||||||||
2023 | return CGF.Builder.CreateBitCast(call, origType); | ||||||||
2024 | } | ||||||||
2025 | |||||||||
2026 | /// Perform an operation having the following signature: | ||||||||
2027 | /// i8* (i8**) | ||||||||
2028 | static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, | ||||||||
2029 | llvm::Function *&fn, | ||||||||
2030 | llvm::Intrinsic::ID IntID) { | ||||||||
2031 | if (!fn) { | ||||||||
2032 | fn = CGF.CGM.getIntrinsic(IntID); | ||||||||
2033 | setARCRuntimeFunctionLinkage(CGF.CGM, fn); | ||||||||
2034 | } | ||||||||
2035 | |||||||||
2036 | // Cast the argument to 'id*'. | ||||||||
2037 | llvm::Type *origType = addr.getElementType(); | ||||||||
2038 | addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy); | ||||||||
2039 | |||||||||
2040 | // Call the function. | ||||||||
2041 | llvm::Value *result = CGF.EmitNounwindRuntimeCall(fn, addr.getPointer()); | ||||||||
2042 | |||||||||
2043 | // Cast the result back to a dereference of the original type. | ||||||||
2044 | if (origType != CGF.Int8PtrTy) | ||||||||
2045 | result = CGF.Builder.CreateBitCast(result, origType); | ||||||||
2046 | |||||||||
2047 | return result; | ||||||||
2048 | } | ||||||||
2049 | |||||||||
2050 | /// Perform an operation having the following signature: | ||||||||
2051 | /// i8* (i8**, i8*) | ||||||||
2052 | static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, | ||||||||
2053 | llvm::Value *value, | ||||||||
2054 | llvm::Function *&fn, | ||||||||
2055 | llvm::Intrinsic::ID IntID, | ||||||||
2056 | bool ignored) { | ||||||||
2057 | assert(addr.getElementType() == value->getType())((addr.getElementType() == value->getType()) ? static_cast <void> (0) : __assert_fail ("addr.getElementType() == value->getType()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2057, __PRETTY_FUNCTION__)); | ||||||||
2058 | |||||||||
2059 | if (!fn) { | ||||||||
2060 | fn = CGF.CGM.getIntrinsic(IntID); | ||||||||
2061 | setARCRuntimeFunctionLinkage(CGF.CGM, fn); | ||||||||
2062 | } | ||||||||
2063 | |||||||||
2064 | llvm::Type *origType = value->getType(); | ||||||||
2065 | |||||||||
2066 | llvm::Value *args[] = { | ||||||||
2067 | CGF.Builder.CreateBitCast(addr.getPointer(), CGF.Int8PtrPtrTy), | ||||||||
2068 | CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy) | ||||||||
2069 | }; | ||||||||
2070 | llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args); | ||||||||
2071 | |||||||||
2072 | if (ignored) return nullptr; | ||||||||
2073 | |||||||||
2074 | return CGF.Builder.CreateBitCast(result, origType); | ||||||||
2075 | } | ||||||||
2076 | |||||||||
2077 | /// Perform an operation having the following signature: | ||||||||
2078 | /// void (i8**, i8**) | ||||||||
2079 | static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, | ||||||||
2080 | llvm::Function *&fn, | ||||||||
2081 | llvm::Intrinsic::ID IntID) { | ||||||||
2082 | assert(dst.getType() == src.getType())((dst.getType() == src.getType()) ? static_cast<void> ( 0) : __assert_fail ("dst.getType() == src.getType()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2082, __PRETTY_FUNCTION__)); | ||||||||
2083 | |||||||||
2084 | if (!fn) { | ||||||||
2085 | fn = CGF.CGM.getIntrinsic(IntID); | ||||||||
2086 | setARCRuntimeFunctionLinkage(CGF.CGM, fn); | ||||||||
2087 | } | ||||||||
2088 | |||||||||
2089 | llvm::Value *args[] = { | ||||||||
2090 | CGF.Builder.CreateBitCast(dst.getPointer(), CGF.Int8PtrPtrTy), | ||||||||
2091 | CGF.Builder.CreateBitCast(src.getPointer(), CGF.Int8PtrPtrTy) | ||||||||
2092 | }; | ||||||||
2093 | CGF.EmitNounwindRuntimeCall(fn, args); | ||||||||
2094 | } | ||||||||
2095 | |||||||||
2096 | /// Perform an operation having the signature | ||||||||
2097 | /// i8* (i8*) | ||||||||
2098 | /// where a null input causes a no-op and returns null. | ||||||||
2099 | static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF, | ||||||||
2100 | llvm::Value *value, | ||||||||
2101 | llvm::Type *returnType, | ||||||||
2102 | llvm::FunctionCallee &fn, | ||||||||
2103 | StringRef fnName) { | ||||||||
2104 | if (isa<llvm::ConstantPointerNull>(value)) | ||||||||
2105 | return value; | ||||||||
2106 | |||||||||
2107 | if (!fn) { | ||||||||
2108 | llvm::FunctionType *fnType = | ||||||||
2109 | llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false); | ||||||||
2110 | fn = CGF.CGM.CreateRuntimeFunction(fnType, fnName); | ||||||||
2111 | |||||||||
2112 | // We have Native ARC, so set nonlazybind attribute for performance | ||||||||
2113 | if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee())) | ||||||||
2114 | if (fnName == "objc_retain") | ||||||||
2115 | f->addFnAttr(llvm::Attribute::NonLazyBind); | ||||||||
2116 | } | ||||||||
2117 | |||||||||
2118 | // Cast the argument to 'id'. | ||||||||
2119 | llvm::Type *origType = returnType ? returnType : value->getType(); | ||||||||
2120 | value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); | ||||||||
2121 | |||||||||
2122 | // Call the function. | ||||||||
2123 | llvm::CallBase *Inst = CGF.EmitCallOrInvoke(fn, value); | ||||||||
2124 | |||||||||
2125 | // Cast the result back to the original type. | ||||||||
2126 | return CGF.Builder.CreateBitCast(Inst, origType); | ||||||||
2127 | } | ||||||||
2128 | |||||||||
2129 | /// Produce the code to do a retain. Based on the type, calls one of: | ||||||||
2130 | /// call i8* \@objc_retain(i8* %value) | ||||||||
2131 | /// call i8* \@objc_retainBlock(i8* %value) | ||||||||
2132 | llvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) { | ||||||||
2133 | if (type->isBlockPointerType()) | ||||||||
2134 | return EmitARCRetainBlock(value, /*mandatory*/ false); | ||||||||
2135 | else | ||||||||
2136 | return EmitARCRetainNonBlock(value); | ||||||||
2137 | } | ||||||||
2138 | |||||||||
2139 | /// Retain the given object, with normal retain semantics. | ||||||||
2140 | /// call i8* \@objc_retain(i8* %value) | ||||||||
2141 | llvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) { | ||||||||
2142 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2143 | CGM.getObjCEntrypoints().objc_retain, | ||||||||
2144 | llvm::Intrinsic::objc_retain); | ||||||||
2145 | } | ||||||||
2146 | |||||||||
2147 | /// Retain the given block, with _Block_copy semantics. | ||||||||
2148 | /// call i8* \@objc_retainBlock(i8* %value) | ||||||||
2149 | /// | ||||||||
2150 | /// \param mandatory - If false, emit the call with metadata | ||||||||
2151 | /// indicating that it's okay for the optimizer to eliminate this call | ||||||||
2152 | /// if it can prove that the block never escapes except down the stack. | ||||||||
2153 | llvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value, | ||||||||
2154 | bool mandatory) { | ||||||||
2155 | llvm::Value *result | ||||||||
2156 | = emitARCValueOperation(*this, value, nullptr, | ||||||||
2157 | CGM.getObjCEntrypoints().objc_retainBlock, | ||||||||
2158 | llvm::Intrinsic::objc_retainBlock); | ||||||||
2159 | |||||||||
2160 | // If the copy isn't mandatory, add !clang.arc.copy_on_escape to | ||||||||
2161 | // tell the optimizer that it doesn't need to do this copy if the | ||||||||
2162 | // block doesn't escape, where being passed as an argument doesn't | ||||||||
2163 | // count as escaping. | ||||||||
2164 | if (!mandatory && isa<llvm::Instruction>(result)) { | ||||||||
2165 | llvm::CallInst *call | ||||||||
2166 | = cast<llvm::CallInst>(result->stripPointerCasts()); | ||||||||
2167 | assert(call->getCalledValue() == CGM.getObjCEntrypoints().objc_retainBlock)((call->getCalledValue() == CGM.getObjCEntrypoints().objc_retainBlock ) ? static_cast<void> (0) : __assert_fail ("call->getCalledValue() == CGM.getObjCEntrypoints().objc_retainBlock" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2167, __PRETTY_FUNCTION__)); | ||||||||
2168 | |||||||||
2169 | call->setMetadata("clang.arc.copy_on_escape", | ||||||||
2170 | llvm::MDNode::get(Builder.getContext(), None)); | ||||||||
2171 | } | ||||||||
2172 | |||||||||
2173 | return result; | ||||||||
2174 | } | ||||||||
2175 | |||||||||
2176 | static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) { | ||||||||
2177 | // Fetch the void(void) inline asm which marks that we're going to | ||||||||
2178 | // do something with the autoreleased return value. | ||||||||
2179 | llvm::InlineAsm *&marker | ||||||||
2180 | = CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker; | ||||||||
2181 | if (!marker) { | ||||||||
2182 | StringRef assembly | ||||||||
2183 | = CGF.CGM.getTargetCodeGenInfo() | ||||||||
2184 | .getARCRetainAutoreleasedReturnValueMarker(); | ||||||||
2185 | |||||||||
2186 | // If we have an empty assembly string, there's nothing to do. | ||||||||
2187 | if (assembly.empty()) { | ||||||||
2188 | |||||||||
2189 | // Otherwise, at -O0, build an inline asm that we're going to call | ||||||||
2190 | // in a moment. | ||||||||
2191 | } else if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { | ||||||||
2192 | llvm::FunctionType *type = | ||||||||
2193 | llvm::FunctionType::get(CGF.VoidTy, /*variadic*/false); | ||||||||
2194 | |||||||||
2195 | marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true); | ||||||||
2196 | |||||||||
2197 | // If we're at -O1 and above, we don't want to litter the code | ||||||||
2198 | // with this marker yet, so leave a breadcrumb for the ARC | ||||||||
2199 | // optimizer to pick up. | ||||||||
2200 | } else { | ||||||||
2201 | const char *markerKey = "clang.arc.retainAutoreleasedReturnValueMarker"; | ||||||||
2202 | if (!CGF.CGM.getModule().getModuleFlag(markerKey)) { | ||||||||
2203 | auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly); | ||||||||
2204 | CGF.CGM.getModule().addModuleFlag(llvm::Module::Error, markerKey, str); | ||||||||
2205 | } | ||||||||
2206 | } | ||||||||
2207 | } | ||||||||
2208 | |||||||||
2209 | // Call the marker asm if we made one, which we do only at -O0. | ||||||||
2210 | if (marker) | ||||||||
2211 | CGF.Builder.CreateCall(marker, None, CGF.getBundlesForFunclet(marker)); | ||||||||
2212 | } | ||||||||
2213 | |||||||||
2214 | /// Retain the given object which is the result of a function call. | ||||||||
2215 | /// call i8* \@objc_retainAutoreleasedReturnValue(i8* %value) | ||||||||
2216 | /// | ||||||||
2217 | /// Yes, this function name is one character away from a different | ||||||||
2218 | /// call with completely different semantics. | ||||||||
2219 | llvm::Value * | ||||||||
2220 | CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { | ||||||||
2221 | emitAutoreleasedReturnValueMarker(*this); | ||||||||
2222 | llvm::CallInst::TailCallKind tailKind = | ||||||||
2223 | CGM.getTargetCodeGenInfo() | ||||||||
2224 | .shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() | ||||||||
2225 | ? llvm::CallInst::TCK_NoTail | ||||||||
2226 | : llvm::CallInst::TCK_None; | ||||||||
2227 | return emitARCValueOperation( | ||||||||
2228 | *this, value, nullptr, | ||||||||
2229 | CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue, | ||||||||
2230 | llvm::Intrinsic::objc_retainAutoreleasedReturnValue, tailKind); | ||||||||
2231 | } | ||||||||
2232 | |||||||||
2233 | /// Claim a possibly-autoreleased return value at +0. This is only | ||||||||
2234 | /// valid to do in contexts which do not rely on the retain to keep | ||||||||
2235 | /// the object valid for all of its uses; for example, when | ||||||||
2236 | /// the value is ignored, or when it is being assigned to an | ||||||||
2237 | /// __unsafe_unretained variable. | ||||||||
2238 | /// | ||||||||
2239 | /// call i8* \@objc_unsafeClaimAutoreleasedReturnValue(i8* %value) | ||||||||
2240 | llvm::Value * | ||||||||
2241 | CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) { | ||||||||
2242 | emitAutoreleasedReturnValueMarker(*this); | ||||||||
2243 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2244 | CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue, | ||||||||
2245 | llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); | ||||||||
2246 | } | ||||||||
2247 | |||||||||
2248 | /// Release the given object. | ||||||||
2249 | /// call void \@objc_release(i8* %value) | ||||||||
2250 | void CodeGenFunction::EmitARCRelease(llvm::Value *value, | ||||||||
2251 | ARCPreciseLifetime_t precise) { | ||||||||
2252 | if (isa<llvm::ConstantPointerNull>(value)) return; | ||||||||
2253 | |||||||||
2254 | llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release; | ||||||||
2255 | if (!fn) { | ||||||||
2256 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release); | ||||||||
2257 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2258 | } | ||||||||
2259 | |||||||||
2260 | // Cast the argument to 'id'. | ||||||||
2261 | value = Builder.CreateBitCast(value, Int8PtrTy); | ||||||||
2262 | |||||||||
2263 | // Call objc_release. | ||||||||
2264 | llvm::CallInst *call = EmitNounwindRuntimeCall(fn, value); | ||||||||
2265 | |||||||||
2266 | if (precise == ARCImpreciseLifetime) { | ||||||||
2267 | call->setMetadata("clang.imprecise_release", | ||||||||
2268 | llvm::MDNode::get(Builder.getContext(), None)); | ||||||||
2269 | } | ||||||||
2270 | } | ||||||||
2271 | |||||||||
2272 | /// Destroy a __strong variable. | ||||||||
2273 | /// | ||||||||
2274 | /// At -O0, emit a call to store 'null' into the address; | ||||||||
2275 | /// instrumenting tools prefer this because the address is exposed, | ||||||||
2276 | /// but it's relatively cumbersome to optimize. | ||||||||
2277 | /// | ||||||||
2278 | /// At -O1 and above, just load and call objc_release. | ||||||||
2279 | /// | ||||||||
2280 | /// call void \@objc_storeStrong(i8** %addr, i8* null) | ||||||||
2281 | void CodeGenFunction::EmitARCDestroyStrong(Address addr, | ||||||||
2282 | ARCPreciseLifetime_t precise) { | ||||||||
2283 | if (CGM.getCodeGenOpts().OptimizationLevel == 0) { | ||||||||
2284 | llvm::Value *null = getNullForVariable(addr); | ||||||||
2285 | EmitARCStoreStrongCall(addr, null, /*ignored*/ true); | ||||||||
2286 | return; | ||||||||
2287 | } | ||||||||
2288 | |||||||||
2289 | llvm::Value *value = Builder.CreateLoad(addr); | ||||||||
2290 | EmitARCRelease(value, precise); | ||||||||
2291 | } | ||||||||
2292 | |||||||||
2293 | /// Store into a strong object. Always calls this: | ||||||||
2294 | /// call void \@objc_storeStrong(i8** %addr, i8* %value) | ||||||||
2295 | llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, | ||||||||
2296 | llvm::Value *value, | ||||||||
2297 | bool ignored) { | ||||||||
2298 | assert(addr.getElementType() == value->getType())((addr.getElementType() == value->getType()) ? static_cast <void> (0) : __assert_fail ("addr.getElementType() == value->getType()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2298, __PRETTY_FUNCTION__)); | ||||||||
2299 | |||||||||
2300 | llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong; | ||||||||
2301 | if (!fn) { | ||||||||
2302 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong); | ||||||||
2303 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2304 | } | ||||||||
2305 | |||||||||
2306 | llvm::Value *args[] = { | ||||||||
2307 | Builder.CreateBitCast(addr.getPointer(), Int8PtrPtrTy), | ||||||||
2308 | Builder.CreateBitCast(value, Int8PtrTy) | ||||||||
2309 | }; | ||||||||
2310 | EmitNounwindRuntimeCall(fn, args); | ||||||||
2311 | |||||||||
2312 | if (ignored) return nullptr; | ||||||||
2313 | return value; | ||||||||
2314 | } | ||||||||
2315 | |||||||||
2316 | /// Store into a strong object. Sometimes calls this: | ||||||||
2317 | /// call void \@objc_storeStrong(i8** %addr, i8* %value) | ||||||||
2318 | /// Other times, breaks it down into components. | ||||||||
2319 | llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst, | ||||||||
2320 | llvm::Value *newValue, | ||||||||
2321 | bool ignored) { | ||||||||
2322 | QualType type = dst.getType(); | ||||||||
2323 | bool isBlock = type->isBlockPointerType(); | ||||||||
2324 | |||||||||
2325 | // Use a store barrier at -O0 unless this is a block type or the | ||||||||
2326 | // lvalue is inadequately aligned. | ||||||||
2327 | if (shouldUseFusedARCCalls() && | ||||||||
2328 | !isBlock && | ||||||||
2329 | (dst.getAlignment().isZero() || | ||||||||
2330 | dst.getAlignment() >= CharUnits::fromQuantity(PointerAlignInBytes))) { | ||||||||
2331 | return EmitARCStoreStrongCall(dst.getAddress(*this), newValue, ignored); | ||||||||
2332 | } | ||||||||
2333 | |||||||||
2334 | // Otherwise, split it out. | ||||||||
2335 | |||||||||
2336 | // Retain the new value. | ||||||||
2337 | newValue = EmitARCRetain(type, newValue); | ||||||||
2338 | |||||||||
2339 | // Read the old value. | ||||||||
2340 | llvm::Value *oldValue = EmitLoadOfScalar(dst, SourceLocation()); | ||||||||
2341 | |||||||||
2342 | // Store. We do this before the release so that any deallocs won't | ||||||||
2343 | // see the old value. | ||||||||
2344 | EmitStoreOfScalar(newValue, dst); | ||||||||
2345 | |||||||||
2346 | // Finally, release the old value. | ||||||||
2347 | EmitARCRelease(oldValue, dst.isARCPreciseLifetime()); | ||||||||
2348 | |||||||||
2349 | return newValue; | ||||||||
2350 | } | ||||||||
2351 | |||||||||
2352 | /// Autorelease the given object. | ||||||||
2353 | /// call i8* \@objc_autorelease(i8* %value) | ||||||||
2354 | llvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) { | ||||||||
2355 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2356 | CGM.getObjCEntrypoints().objc_autorelease, | ||||||||
2357 | llvm::Intrinsic::objc_autorelease); | ||||||||
2358 | } | ||||||||
2359 | |||||||||
2360 | /// Autorelease the given object. | ||||||||
2361 | /// call i8* \@objc_autoreleaseReturnValue(i8* %value) | ||||||||
2362 | llvm::Value * | ||||||||
2363 | CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) { | ||||||||
2364 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2365 | CGM.getObjCEntrypoints().objc_autoreleaseReturnValue, | ||||||||
2366 | llvm::Intrinsic::objc_autoreleaseReturnValue, | ||||||||
2367 | llvm::CallInst::TCK_Tail); | ||||||||
2368 | } | ||||||||
2369 | |||||||||
2370 | /// Do a fused retain/autorelease of the given object. | ||||||||
2371 | /// call i8* \@objc_retainAutoreleaseReturnValue(i8* %value) | ||||||||
2372 | llvm::Value * | ||||||||
2373 | CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) { | ||||||||
2374 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2375 | CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue, | ||||||||
2376 | llvm::Intrinsic::objc_retainAutoreleaseReturnValue, | ||||||||
2377 | llvm::CallInst::TCK_Tail); | ||||||||
2378 | } | ||||||||
2379 | |||||||||
2380 | /// Do a fused retain/autorelease of the given object. | ||||||||
2381 | /// call i8* \@objc_retainAutorelease(i8* %value) | ||||||||
2382 | /// or | ||||||||
2383 | /// %retain = call i8* \@objc_retainBlock(i8* %value) | ||||||||
2384 | /// call i8* \@objc_autorelease(i8* %retain) | ||||||||
2385 | llvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type, | ||||||||
2386 | llvm::Value *value) { | ||||||||
2387 | if (!type->isBlockPointerType()) | ||||||||
2388 | return EmitARCRetainAutoreleaseNonBlock(value); | ||||||||
2389 | |||||||||
2390 | if (isa<llvm::ConstantPointerNull>(value)) return value; | ||||||||
2391 | |||||||||
2392 | llvm::Type *origType = value->getType(); | ||||||||
2393 | value = Builder.CreateBitCast(value, Int8PtrTy); | ||||||||
2394 | value = EmitARCRetainBlock(value, /*mandatory*/ true); | ||||||||
2395 | value = EmitARCAutorelease(value); | ||||||||
2396 | return Builder.CreateBitCast(value, origType); | ||||||||
2397 | } | ||||||||
2398 | |||||||||
2399 | /// Do a fused retain/autorelease of the given object. | ||||||||
2400 | /// call i8* \@objc_retainAutorelease(i8* %value) | ||||||||
2401 | llvm::Value * | ||||||||
2402 | CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { | ||||||||
2403 | return emitARCValueOperation(*this, value, nullptr, | ||||||||
2404 | CGM.getObjCEntrypoints().objc_retainAutorelease, | ||||||||
2405 | llvm::Intrinsic::objc_retainAutorelease); | ||||||||
2406 | } | ||||||||
2407 | |||||||||
2408 | /// i8* \@objc_loadWeak(i8** %addr) | ||||||||
2409 | /// Essentially objc_autorelease(objc_loadWeakRetained(addr)). | ||||||||
2410 | llvm::Value *CodeGenFunction::EmitARCLoadWeak(Address addr) { | ||||||||
2411 | return emitARCLoadOperation(*this, addr, | ||||||||
2412 | CGM.getObjCEntrypoints().objc_loadWeak, | ||||||||
2413 | llvm::Intrinsic::objc_loadWeak); | ||||||||
2414 | } | ||||||||
2415 | |||||||||
2416 | /// i8* \@objc_loadWeakRetained(i8** %addr) | ||||||||
2417 | llvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(Address addr) { | ||||||||
2418 | return emitARCLoadOperation(*this, addr, | ||||||||
2419 | CGM.getObjCEntrypoints().objc_loadWeakRetained, | ||||||||
2420 | llvm::Intrinsic::objc_loadWeakRetained); | ||||||||
2421 | } | ||||||||
2422 | |||||||||
2423 | /// i8* \@objc_storeWeak(i8** %addr, i8* %value) | ||||||||
2424 | /// Returns %value. | ||||||||
2425 | llvm::Value *CodeGenFunction::EmitARCStoreWeak(Address addr, | ||||||||
2426 | llvm::Value *value, | ||||||||
2427 | bool ignored) { | ||||||||
2428 | return emitARCStoreOperation(*this, addr, value, | ||||||||
2429 | CGM.getObjCEntrypoints().objc_storeWeak, | ||||||||
2430 | llvm::Intrinsic::objc_storeWeak, ignored); | ||||||||
2431 | } | ||||||||
2432 | |||||||||
2433 | /// i8* \@objc_initWeak(i8** %addr, i8* %value) | ||||||||
2434 | /// Returns %value. %addr is known to not have a current weak entry. | ||||||||
2435 | /// Essentially equivalent to: | ||||||||
2436 | /// *addr = nil; objc_storeWeak(addr, value); | ||||||||
2437 | void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { | ||||||||
2438 | // If we're initializing to null, just write null to memory; no need | ||||||||
2439 | // to get the runtime involved. But don't do this if optimization | ||||||||
2440 | // is enabled, because accounting for this would make the optimizer | ||||||||
2441 | // much more complicated. | ||||||||
2442 | if (isa<llvm::ConstantPointerNull>(value) && | ||||||||
2443 | CGM.getCodeGenOpts().OptimizationLevel == 0) { | ||||||||
2444 | Builder.CreateStore(value, addr); | ||||||||
2445 | return; | ||||||||
2446 | } | ||||||||
2447 | |||||||||
2448 | emitARCStoreOperation(*this, addr, value, | ||||||||
2449 | CGM.getObjCEntrypoints().objc_initWeak, | ||||||||
2450 | llvm::Intrinsic::objc_initWeak, /*ignored*/ true); | ||||||||
2451 | } | ||||||||
2452 | |||||||||
2453 | /// void \@objc_destroyWeak(i8** %addr) | ||||||||
2454 | /// Essentially objc_storeWeak(addr, nil). | ||||||||
2455 | void CodeGenFunction::EmitARCDestroyWeak(Address addr) { | ||||||||
2456 | llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak; | ||||||||
2457 | if (!fn) { | ||||||||
2458 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak); | ||||||||
2459 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2460 | } | ||||||||
2461 | |||||||||
2462 | // Cast the argument to 'id*'. | ||||||||
2463 | addr = Builder.CreateBitCast(addr, Int8PtrPtrTy); | ||||||||
2464 | |||||||||
2465 | EmitNounwindRuntimeCall(fn, addr.getPointer()); | ||||||||
2466 | } | ||||||||
2467 | |||||||||
2468 | /// void \@objc_moveWeak(i8** %dest, i8** %src) | ||||||||
2469 | /// Disregards the current value in %dest. Leaves %src pointing to nothing. | ||||||||
2470 | /// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)). | ||||||||
2471 | void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) { | ||||||||
2472 | emitARCCopyOperation(*this, dst, src, | ||||||||
2473 | CGM.getObjCEntrypoints().objc_moveWeak, | ||||||||
2474 | llvm::Intrinsic::objc_moveWeak); | ||||||||
2475 | } | ||||||||
2476 | |||||||||
2477 | /// void \@objc_copyWeak(i8** %dest, i8** %src) | ||||||||
2478 | /// Disregards the current value in %dest. Essentially | ||||||||
2479 | /// objc_release(objc_initWeak(dest, objc_readWeakRetained(src))) | ||||||||
2480 | void CodeGenFunction::EmitARCCopyWeak(Address dst, Address src) { | ||||||||
2481 | emitARCCopyOperation(*this, dst, src, | ||||||||
2482 | CGM.getObjCEntrypoints().objc_copyWeak, | ||||||||
2483 | llvm::Intrinsic::objc_copyWeak); | ||||||||
2484 | } | ||||||||
2485 | |||||||||
2486 | void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr, | ||||||||
2487 | Address SrcAddr) { | ||||||||
2488 | llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr); | ||||||||
2489 | Object = EmitObjCConsumeObject(Ty, Object); | ||||||||
2490 | EmitARCStoreWeak(DstAddr, Object, false); | ||||||||
2491 | } | ||||||||
2492 | |||||||||
2493 | void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr, | ||||||||
2494 | Address SrcAddr) { | ||||||||
2495 | llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr); | ||||||||
2496 | Object = EmitObjCConsumeObject(Ty, Object); | ||||||||
2497 | EmitARCStoreWeak(DstAddr, Object, false); | ||||||||
2498 | EmitARCDestroyWeak(SrcAddr); | ||||||||
2499 | } | ||||||||
2500 | |||||||||
2501 | /// Produce the code to do a objc_autoreleasepool_push. | ||||||||
2502 | /// call i8* \@objc_autoreleasePoolPush(void) | ||||||||
2503 | llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { | ||||||||
2504 | llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush; | ||||||||
2505 | if (!fn) { | ||||||||
2506 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush); | ||||||||
2507 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2508 | } | ||||||||
2509 | |||||||||
2510 | return EmitNounwindRuntimeCall(fn); | ||||||||
2511 | } | ||||||||
2512 | |||||||||
2513 | /// Produce the code to do a primitive release. | ||||||||
2514 | /// call void \@objc_autoreleasePoolPop(i8* %ptr) | ||||||||
2515 | void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { | ||||||||
2516 | assert(value->getType() == Int8PtrTy)((value->getType() == Int8PtrTy) ? static_cast<void> (0) : __assert_fail ("value->getType() == Int8PtrTy", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2516, __PRETTY_FUNCTION__)); | ||||||||
2517 | |||||||||
2518 | if (getInvokeDest()) { | ||||||||
2519 | // Call the runtime method not the intrinsic if we are handling exceptions | ||||||||
2520 | llvm::FunctionCallee &fn = | ||||||||
2521 | CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke; | ||||||||
2522 | if (!fn) { | ||||||||
2523 | llvm::FunctionType *fnType = | ||||||||
2524 | llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); | ||||||||
2525 | fn = CGM.CreateRuntimeFunction(fnType, "objc_autoreleasePoolPop"); | ||||||||
2526 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2527 | } | ||||||||
2528 | |||||||||
2529 | // objc_autoreleasePoolPop can throw. | ||||||||
2530 | EmitRuntimeCallOrInvoke(fn, value); | ||||||||
2531 | } else { | ||||||||
2532 | llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; | ||||||||
2533 | if (!fn) { | ||||||||
2534 | fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop); | ||||||||
2535 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2536 | } | ||||||||
2537 | |||||||||
2538 | EmitRuntimeCall(fn, value); | ||||||||
2539 | } | ||||||||
2540 | } | ||||||||
2541 | |||||||||
2542 | /// Produce the code to do an MRR version objc_autoreleasepool_push. | ||||||||
2543 | /// Which is: [[NSAutoreleasePool alloc] init]; | ||||||||
2544 | /// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class. | ||||||||
2545 | /// init is declared as: - (id) init; in its NSObject super class. | ||||||||
2546 | /// | ||||||||
2547 | llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { | ||||||||
2548 | CGObjCRuntime &Runtime = CGM.getObjCRuntime(); | ||||||||
2549 | llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(*this); | ||||||||
2550 | // [NSAutoreleasePool alloc] | ||||||||
2551 | IdentifierInfo *II = &CGM.getContext().Idents.get("alloc"); | ||||||||
2552 | Selector AllocSel = getContext().Selectors.getSelector(0, &II); | ||||||||
2553 | CallArgList Args; | ||||||||
2554 | RValue AllocRV = | ||||||||
2555 | Runtime.GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
2556 | getContext().getObjCIdType(), | ||||||||
2557 | AllocSel, Receiver, Args); | ||||||||
2558 | |||||||||
2559 | // [Receiver init] | ||||||||
2560 | Receiver = AllocRV.getScalarVal(); | ||||||||
2561 | II = &CGM.getContext().Idents.get("init"); | ||||||||
2562 | Selector InitSel = getContext().Selectors.getSelector(0, &II); | ||||||||
2563 | RValue InitRV = | ||||||||
2564 | Runtime.GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
2565 | getContext().getObjCIdType(), | ||||||||
2566 | InitSel, Receiver, Args); | ||||||||
2567 | return InitRV.getScalarVal(); | ||||||||
2568 | } | ||||||||
2569 | |||||||||
2570 | /// Allocate the given objc object. | ||||||||
2571 | /// call i8* \@objc_alloc(i8* %value) | ||||||||
2572 | llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value, | ||||||||
2573 | llvm::Type *resultType) { | ||||||||
2574 | return emitObjCValueOperation(*this, value, resultType, | ||||||||
2575 | CGM.getObjCEntrypoints().objc_alloc, | ||||||||
2576 | "objc_alloc"); | ||||||||
2577 | } | ||||||||
2578 | |||||||||
2579 | /// Allocate the given objc object. | ||||||||
2580 | /// call i8* \@objc_allocWithZone(i8* %value) | ||||||||
2581 | llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value, | ||||||||
2582 | llvm::Type *resultType) { | ||||||||
2583 | return emitObjCValueOperation(*this, value, resultType, | ||||||||
2584 | CGM.getObjCEntrypoints().objc_allocWithZone, | ||||||||
2585 | "objc_allocWithZone"); | ||||||||
2586 | } | ||||||||
2587 | |||||||||
2588 | llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value, | ||||||||
2589 | llvm::Type *resultType) { | ||||||||
2590 | return emitObjCValueOperation(*this, value, resultType, | ||||||||
2591 | CGM.getObjCEntrypoints().objc_alloc_init, | ||||||||
2592 | "objc_alloc_init"); | ||||||||
2593 | } | ||||||||
2594 | |||||||||
2595 | /// Produce the code to do a primitive release. | ||||||||
2596 | /// [tmp drain]; | ||||||||
2597 | void CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) { | ||||||||
2598 | IdentifierInfo *II = &CGM.getContext().Idents.get("drain"); | ||||||||
2599 | Selector DrainSel = getContext().Selectors.getSelector(0, &II); | ||||||||
2600 | CallArgList Args; | ||||||||
2601 | CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
2602 | getContext().VoidTy, DrainSel, Arg, Args); | ||||||||
2603 | } | ||||||||
2604 | |||||||||
2605 | void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF, | ||||||||
2606 | Address addr, | ||||||||
2607 | QualType type) { | ||||||||
2608 | CGF.EmitARCDestroyStrong(addr, ARCPreciseLifetime); | ||||||||
2609 | } | ||||||||
2610 | |||||||||
2611 | void CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF, | ||||||||
2612 | Address addr, | ||||||||
2613 | QualType type) { | ||||||||
2614 | CGF.EmitARCDestroyStrong(addr, ARCImpreciseLifetime); | ||||||||
2615 | } | ||||||||
2616 | |||||||||
2617 | void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF, | ||||||||
2618 | Address addr, | ||||||||
2619 | QualType type) { | ||||||||
2620 | CGF.EmitARCDestroyWeak(addr); | ||||||||
2621 | } | ||||||||
2622 | |||||||||
2623 | void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr, | ||||||||
2624 | QualType type) { | ||||||||
2625 | llvm::Value *value = CGF.Builder.CreateLoad(addr); | ||||||||
2626 | CGF.EmitARCIntrinsicUse(value); | ||||||||
2627 | } | ||||||||
2628 | |||||||||
2629 | /// Autorelease the given object. | ||||||||
2630 | /// call i8* \@objc_autorelease(i8* %value) | ||||||||
2631 | llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value, | ||||||||
2632 | llvm::Type *returnType) { | ||||||||
2633 | return emitObjCValueOperation( | ||||||||
2634 | *this, value, returnType, | ||||||||
2635 | CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction, | ||||||||
2636 | "objc_autorelease"); | ||||||||
2637 | } | ||||||||
2638 | |||||||||
2639 | /// Retain the given object, with normal retain semantics. | ||||||||
2640 | /// call i8* \@objc_retain(i8* %value) | ||||||||
2641 | llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value, | ||||||||
2642 | llvm::Type *returnType) { | ||||||||
2643 | return emitObjCValueOperation( | ||||||||
2644 | *this, value, returnType, | ||||||||
2645 | CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain"); | ||||||||
2646 | } | ||||||||
2647 | |||||||||
2648 | /// Release the given object. | ||||||||
2649 | /// call void \@objc_release(i8* %value) | ||||||||
2650 | void CodeGenFunction::EmitObjCRelease(llvm::Value *value, | ||||||||
2651 | ARCPreciseLifetime_t precise) { | ||||||||
2652 | if (isa<llvm::ConstantPointerNull>(value)) return; | ||||||||
2653 | |||||||||
2654 | llvm::FunctionCallee &fn = | ||||||||
2655 | CGM.getObjCEntrypoints().objc_releaseRuntimeFunction; | ||||||||
2656 | if (!fn) { | ||||||||
2657 | llvm::FunctionType *fnType = | ||||||||
2658 | llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); | ||||||||
2659 | fn = CGM.CreateRuntimeFunction(fnType, "objc_release"); | ||||||||
2660 | setARCRuntimeFunctionLinkage(CGM, fn); | ||||||||
2661 | // We have Native ARC, so set nonlazybind attribute for performance | ||||||||
2662 | if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee())) | ||||||||
2663 | f->addFnAttr(llvm::Attribute::NonLazyBind); | ||||||||
2664 | } | ||||||||
2665 | |||||||||
2666 | // Cast the argument to 'id'. | ||||||||
2667 | value = Builder.CreateBitCast(value, Int8PtrTy); | ||||||||
2668 | |||||||||
2669 | // Call objc_release. | ||||||||
2670 | llvm::CallBase *call = EmitCallOrInvoke(fn, value); | ||||||||
2671 | |||||||||
2672 | if (precise == ARCImpreciseLifetime) { | ||||||||
2673 | call->setMetadata("clang.imprecise_release", | ||||||||
2674 | llvm::MDNode::get(Builder.getContext(), None)); | ||||||||
2675 | } | ||||||||
2676 | } | ||||||||
2677 | |||||||||
2678 | namespace { | ||||||||
2679 | struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup { | ||||||||
2680 | llvm::Value *Token; | ||||||||
2681 | |||||||||
2682 | CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {} | ||||||||
2683 | |||||||||
2684 | void Emit(CodeGenFunction &CGF, Flags flags) override { | ||||||||
2685 | CGF.EmitObjCAutoreleasePoolPop(Token); | ||||||||
2686 | } | ||||||||
2687 | }; | ||||||||
2688 | struct CallObjCMRRAutoreleasePoolObject final : EHScopeStack::Cleanup { | ||||||||
2689 | llvm::Value *Token; | ||||||||
2690 | |||||||||
2691 | CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {} | ||||||||
2692 | |||||||||
2693 | void Emit(CodeGenFunction &CGF, Flags flags) override { | ||||||||
2694 | CGF.EmitObjCMRRAutoreleasePoolPop(Token); | ||||||||
2695 | } | ||||||||
2696 | }; | ||||||||
2697 | } | ||||||||
2698 | |||||||||
2699 | void CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) { | ||||||||
2700 | if (CGM.getLangOpts().ObjCAutoRefCount) | ||||||||
2701 | EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr); | ||||||||
2702 | else | ||||||||
2703 | EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr); | ||||||||
2704 | } | ||||||||
2705 | |||||||||
2706 | static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime) { | ||||||||
2707 | switch (lifetime) { | ||||||||
2708 | case Qualifiers::OCL_None: | ||||||||
2709 | case Qualifiers::OCL_ExplicitNone: | ||||||||
2710 | case Qualifiers::OCL_Strong: | ||||||||
2711 | case Qualifiers::OCL_Autoreleasing: | ||||||||
2712 | return true; | ||||||||
2713 | |||||||||
2714 | case Qualifiers::OCL_Weak: | ||||||||
2715 | return false; | ||||||||
2716 | } | ||||||||
2717 | |||||||||
2718 | llvm_unreachable("impossible lifetime!")::llvm::llvm_unreachable_internal("impossible lifetime!", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2718); | ||||||||
2719 | } | ||||||||
2720 | |||||||||
2721 | static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, | ||||||||
2722 | LValue lvalue, | ||||||||
2723 | QualType type) { | ||||||||
2724 | llvm::Value *result; | ||||||||
2725 | bool shouldRetain = shouldRetainObjCLifetime(type.getObjCLifetime()); | ||||||||
2726 | if (shouldRetain) { | ||||||||
2727 | result = CGF.EmitLoadOfLValue(lvalue, SourceLocation()).getScalarVal(); | ||||||||
2728 | } else { | ||||||||
2729 | assert(type.getObjCLifetime() == Qualifiers::OCL_Weak)((type.getObjCLifetime() == Qualifiers::OCL_Weak) ? static_cast <void> (0) : __assert_fail ("type.getObjCLifetime() == Qualifiers::OCL_Weak" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2729, __PRETTY_FUNCTION__)); | ||||||||
2730 | result = CGF.EmitARCLoadWeakRetained(lvalue.getAddress(CGF)); | ||||||||
2731 | } | ||||||||
2732 | return TryEmitResult(result, !shouldRetain); | ||||||||
2733 | } | ||||||||
2734 | |||||||||
2735 | static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, | ||||||||
2736 | const Expr *e) { | ||||||||
2737 | e = e->IgnoreParens(); | ||||||||
2738 | QualType type = e->getType(); | ||||||||
2739 | |||||||||
2740 | // If we're loading retained from a __strong xvalue, we can avoid | ||||||||
2741 | // an extra retain/release pair by zeroing out the source of this | ||||||||
2742 | // "move" operation. | ||||||||
2743 | if (e->isXValue() && | ||||||||
2744 | !type.isConstQualified() && | ||||||||
2745 | type.getObjCLifetime() == Qualifiers::OCL_Strong) { | ||||||||
2746 | // Emit the lvalue. | ||||||||
2747 | LValue lv = CGF.EmitLValue(e); | ||||||||
2748 | |||||||||
2749 | // Load the object pointer. | ||||||||
2750 | llvm::Value *result = CGF.EmitLoadOfLValue(lv, | ||||||||
2751 | SourceLocation()).getScalarVal(); | ||||||||
2752 | |||||||||
2753 | // Set the source pointer to NULL. | ||||||||
2754 | CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress(CGF)), lv); | ||||||||
2755 | |||||||||
2756 | return TryEmitResult(result, true); | ||||||||
2757 | } | ||||||||
2758 | |||||||||
2759 | // As a very special optimization, in ARC++, if the l-value is the | ||||||||
2760 | // result of a non-volatile assignment, do a simple retain of the | ||||||||
2761 | // result of the call to objc_storeWeak instead of reloading. | ||||||||
2762 | if (CGF.getLangOpts().CPlusPlus && | ||||||||
2763 | !type.isVolatileQualified() && | ||||||||
2764 | type.getObjCLifetime() == Qualifiers::OCL_Weak && | ||||||||
2765 | isa<BinaryOperator>(e) && | ||||||||
2766 | cast<BinaryOperator>(e)->getOpcode() == BO_Assign) | ||||||||
2767 | return TryEmitResult(CGF.EmitScalarExpr(e), false); | ||||||||
2768 | |||||||||
2769 | // Try to emit code for scalar constant instead of emitting LValue and | ||||||||
2770 | // loading it because we are not guaranteed to have an l-value. One of such | ||||||||
2771 | // cases is DeclRefExpr referencing non-odr-used constant-evaluated variable. | ||||||||
2772 | if (const auto *decl_expr = dyn_cast<DeclRefExpr>(e)) { | ||||||||
2773 | auto *DRE = const_cast<DeclRefExpr *>(decl_expr); | ||||||||
2774 | if (CodeGenFunction::ConstantEmission constant = CGF.tryEmitAsConstant(DRE)) | ||||||||
2775 | return TryEmitResult(CGF.emitScalarConstant(constant, DRE), | ||||||||
2776 | !shouldRetainObjCLifetime(type.getObjCLifetime())); | ||||||||
2777 | } | ||||||||
2778 | |||||||||
2779 | return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type); | ||||||||
2780 | } | ||||||||
2781 | |||||||||
2782 | typedef llvm::function_ref<llvm::Value *(CodeGenFunction &CGF, | ||||||||
2783 | llvm::Value *value)> | ||||||||
2784 | ValueTransform; | ||||||||
2785 | |||||||||
2786 | /// Insert code immediately after a call. | ||||||||
2787 | static llvm::Value *emitARCOperationAfterCall(CodeGenFunction &CGF, | ||||||||
2788 | llvm::Value *value, | ||||||||
2789 | ValueTransform doAfterCall, | ||||||||
2790 | ValueTransform doFallback) { | ||||||||
2791 | if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) { | ||||||||
2792 | CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP(); | ||||||||
2793 | |||||||||
2794 | // Place the retain immediately following the call. | ||||||||
2795 | CGF.Builder.SetInsertPoint(call->getParent(), | ||||||||
2796 | ++llvm::BasicBlock::iterator(call)); | ||||||||
2797 | value = doAfterCall(CGF, value); | ||||||||
2798 | |||||||||
2799 | CGF.Builder.restoreIP(ip); | ||||||||
2800 | return value; | ||||||||
2801 | } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) { | ||||||||
2802 | CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP(); | ||||||||
2803 | |||||||||
2804 | // Place the retain at the beginning of the normal destination block. | ||||||||
2805 | llvm::BasicBlock *BB = invoke->getNormalDest(); | ||||||||
2806 | CGF.Builder.SetInsertPoint(BB, BB->begin()); | ||||||||
2807 | value = doAfterCall(CGF, value); | ||||||||
2808 | |||||||||
2809 | CGF.Builder.restoreIP(ip); | ||||||||
2810 | return value; | ||||||||
2811 | |||||||||
2812 | // Bitcasts can arise because of related-result returns. Rewrite | ||||||||
2813 | // the operand. | ||||||||
2814 | } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) { | ||||||||
2815 | llvm::Value *operand = bitcast->getOperand(0); | ||||||||
2816 | operand = emitARCOperationAfterCall(CGF, operand, doAfterCall, doFallback); | ||||||||
2817 | bitcast->setOperand(0, operand); | ||||||||
2818 | return bitcast; | ||||||||
2819 | |||||||||
2820 | // Generic fall-back case. | ||||||||
2821 | } else { | ||||||||
2822 | // Retain using the non-block variant: we never need to do a copy | ||||||||
2823 | // of a block that's been returned to us. | ||||||||
2824 | return doFallback(CGF, value); | ||||||||
2825 | } | ||||||||
2826 | } | ||||||||
2827 | |||||||||
2828 | /// Given that the given expression is some sort of call (which does | ||||||||
2829 | /// not return retained), emit a retain following it. | ||||||||
2830 | static llvm::Value *emitARCRetainCallResult(CodeGenFunction &CGF, | ||||||||
2831 | const Expr *e) { | ||||||||
2832 | llvm::Value *value = CGF.EmitScalarExpr(e); | ||||||||
2833 | return emitARCOperationAfterCall(CGF, value, | ||||||||
2834 | [](CodeGenFunction &CGF, llvm::Value *value) { | ||||||||
2835 | return CGF.EmitARCRetainAutoreleasedReturnValue(value); | ||||||||
2836 | }, | ||||||||
2837 | [](CodeGenFunction &CGF, llvm::Value *value) { | ||||||||
2838 | return CGF.EmitARCRetainNonBlock(value); | ||||||||
2839 | }); | ||||||||
2840 | } | ||||||||
2841 | |||||||||
2842 | /// Given that the given expression is some sort of call (which does | ||||||||
2843 | /// not return retained), perform an unsafeClaim following it. | ||||||||
2844 | static llvm::Value *emitARCUnsafeClaimCallResult(CodeGenFunction &CGF, | ||||||||
2845 | const Expr *e) { | ||||||||
2846 | llvm::Value *value = CGF.EmitScalarExpr(e); | ||||||||
2847 | return emitARCOperationAfterCall(CGF, value, | ||||||||
2848 | [](CodeGenFunction &CGF, llvm::Value *value) { | ||||||||
2849 | return CGF.EmitARCUnsafeClaimAutoreleasedReturnValue(value); | ||||||||
2850 | }, | ||||||||
2851 | [](CodeGenFunction &CGF, llvm::Value *value) { | ||||||||
2852 | return value; | ||||||||
2853 | }); | ||||||||
2854 | } | ||||||||
2855 | |||||||||
2856 | llvm::Value *CodeGenFunction::EmitARCReclaimReturnedObject(const Expr *E, | ||||||||
2857 | bool allowUnsafeClaim) { | ||||||||
2858 | if (allowUnsafeClaim && | ||||||||
2859 | CGM.getLangOpts().ObjCRuntime.hasARCUnsafeClaimAutoreleasedReturnValue()) { | ||||||||
2860 | return emitARCUnsafeClaimCallResult(*this, E); | ||||||||
2861 | } else { | ||||||||
2862 | llvm::Value *value = emitARCRetainCallResult(*this, E); | ||||||||
2863 | return EmitObjCConsumeObject(E->getType(), value); | ||||||||
2864 | } | ||||||||
2865 | } | ||||||||
2866 | |||||||||
2867 | /// Determine whether it might be important to emit a separate | ||||||||
2868 | /// objc_retain_block on the result of the given expression, or | ||||||||
2869 | /// whether it's okay to just emit it in a +1 context. | ||||||||
2870 | static bool shouldEmitSeparateBlockRetain(const Expr *e) { | ||||||||
2871 | assert(e->getType()->isBlockPointerType())((e->getType()->isBlockPointerType()) ? static_cast< void> (0) : __assert_fail ("e->getType()->isBlockPointerType()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2871, __PRETTY_FUNCTION__)); | ||||||||
2872 | e = e->IgnoreParens(); | ||||||||
2873 | |||||||||
2874 | // For future goodness, emit block expressions directly in +1 | ||||||||
2875 | // contexts if we can. | ||||||||
2876 | if (isa<BlockExpr>(e)) | ||||||||
2877 | return false; | ||||||||
2878 | |||||||||
2879 | if (const CastExpr *cast = dyn_cast<CastExpr>(e)) { | ||||||||
2880 | switch (cast->getCastKind()) { | ||||||||
2881 | // Emitting these operations in +1 contexts is goodness. | ||||||||
2882 | case CK_LValueToRValue: | ||||||||
2883 | case CK_ARCReclaimReturnedObject: | ||||||||
2884 | case CK_ARCConsumeObject: | ||||||||
2885 | case CK_ARCProduceObject: | ||||||||
2886 | return false; | ||||||||
2887 | |||||||||
2888 | // These operations preserve a block type. | ||||||||
2889 | case CK_NoOp: | ||||||||
2890 | case CK_BitCast: | ||||||||
2891 | return shouldEmitSeparateBlockRetain(cast->getSubExpr()); | ||||||||
2892 | |||||||||
2893 | // These operations are known to be bad (or haven't been considered). | ||||||||
2894 | case CK_AnyPointerToBlockPointerCast: | ||||||||
2895 | default: | ||||||||
2896 | return true; | ||||||||
2897 | } | ||||||||
2898 | } | ||||||||
2899 | |||||||||
2900 | return true; | ||||||||
2901 | } | ||||||||
2902 | |||||||||
2903 | namespace { | ||||||||
2904 | /// A CRTP base class for emitting expressions of retainable object | ||||||||
2905 | /// pointer type in ARC. | ||||||||
2906 | template <typename Impl, typename Result> class ARCExprEmitter { | ||||||||
2907 | protected: | ||||||||
2908 | CodeGenFunction &CGF; | ||||||||
2909 | Impl &asImpl() { return *static_cast<Impl*>(this); } | ||||||||
2910 | |||||||||
2911 | ARCExprEmitter(CodeGenFunction &CGF) : CGF(CGF) {} | ||||||||
2912 | |||||||||
2913 | public: | ||||||||
2914 | Result visit(const Expr *e); | ||||||||
2915 | Result visitCastExpr(const CastExpr *e); | ||||||||
2916 | Result visitPseudoObjectExpr(const PseudoObjectExpr *e); | ||||||||
2917 | Result visitBlockExpr(const BlockExpr *e); | ||||||||
2918 | Result visitBinaryOperator(const BinaryOperator *e); | ||||||||
2919 | Result visitBinAssign(const BinaryOperator *e); | ||||||||
2920 | Result visitBinAssignUnsafeUnretained(const BinaryOperator *e); | ||||||||
2921 | Result visitBinAssignAutoreleasing(const BinaryOperator *e); | ||||||||
2922 | Result visitBinAssignWeak(const BinaryOperator *e); | ||||||||
2923 | Result visitBinAssignStrong(const BinaryOperator *e); | ||||||||
2924 | |||||||||
2925 | // Minimal implementation: | ||||||||
2926 | // Result visitLValueToRValue(const Expr *e) | ||||||||
2927 | // Result visitConsumeObject(const Expr *e) | ||||||||
2928 | // Result visitExtendBlockObject(const Expr *e) | ||||||||
2929 | // Result visitReclaimReturnedObject(const Expr *e) | ||||||||
2930 | // Result visitCall(const Expr *e) | ||||||||
2931 | // Result visitExpr(const Expr *e) | ||||||||
2932 | // | ||||||||
2933 | // Result emitBitCast(Result result, llvm::Type *resultType) | ||||||||
2934 | // llvm::Value *getValueOfResult(Result result) | ||||||||
2935 | }; | ||||||||
2936 | } | ||||||||
2937 | |||||||||
2938 | /// Try to emit a PseudoObjectExpr under special ARC rules. | ||||||||
2939 | /// | ||||||||
2940 | /// This massively duplicates emitPseudoObjectRValue. | ||||||||
2941 | template <typename Impl, typename Result> | ||||||||
2942 | Result | ||||||||
2943 | ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) { | ||||||||
2944 | SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques; | ||||||||
2945 | |||||||||
2946 | // Find the result expression. | ||||||||
2947 | const Expr *resultExpr = E->getResultExpr(); | ||||||||
2948 | assert(resultExpr)((resultExpr) ? static_cast<void> (0) : __assert_fail ( "resultExpr", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2948, __PRETTY_FUNCTION__)); | ||||||||
2949 | Result result; | ||||||||
2950 | |||||||||
2951 | for (PseudoObjectExpr::const_semantics_iterator | ||||||||
2952 | i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) { | ||||||||
2953 | const Expr *semantic = *i; | ||||||||
2954 | |||||||||
2955 | // If this semantic expression is an opaque value, bind it | ||||||||
2956 | // to the result of its source expression. | ||||||||
2957 | if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) { | ||||||||
2958 | typedef CodeGenFunction::OpaqueValueMappingData OVMA; | ||||||||
2959 | OVMA opaqueData; | ||||||||
2960 | |||||||||
2961 | // If this semantic is the result of the pseudo-object | ||||||||
2962 | // expression, try to evaluate the source as +1. | ||||||||
2963 | if (ov == resultExpr) { | ||||||||
2964 | assert(!OVMA::shouldBindAsLValue(ov))((!OVMA::shouldBindAsLValue(ov)) ? static_cast<void> (0 ) : __assert_fail ("!OVMA::shouldBindAsLValue(ov)", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 2964, __PRETTY_FUNCTION__)); | ||||||||
2965 | result = asImpl().visit(ov->getSourceExpr()); | ||||||||
2966 | opaqueData = OVMA::bind(CGF, ov, | ||||||||
2967 | RValue::get(asImpl().getValueOfResult(result))); | ||||||||
2968 | |||||||||
2969 | // Otherwise, just bind it. | ||||||||
2970 | } else { | ||||||||
2971 | opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr()); | ||||||||
2972 | } | ||||||||
2973 | opaques.push_back(opaqueData); | ||||||||
2974 | |||||||||
2975 | // Otherwise, if the expression is the result, evaluate it | ||||||||
2976 | // and remember the result. | ||||||||
2977 | } else if (semantic == resultExpr) { | ||||||||
2978 | result = asImpl().visit(semantic); | ||||||||
2979 | |||||||||
2980 | // Otherwise, evaluate the expression in an ignored context. | ||||||||
2981 | } else { | ||||||||
2982 | CGF.EmitIgnoredExpr(semantic); | ||||||||
2983 | } | ||||||||
2984 | } | ||||||||
2985 | |||||||||
2986 | // Unbind all the opaques now. | ||||||||
2987 | for (unsigned i = 0, e = opaques.size(); i != e; ++i) | ||||||||
2988 | opaques[i].unbind(CGF); | ||||||||
2989 | |||||||||
2990 | return result; | ||||||||
2991 | } | ||||||||
2992 | |||||||||
2993 | template <typename Impl, typename Result> | ||||||||
2994 | Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) { | ||||||||
2995 | // The default implementation just forwards the expression to visitExpr. | ||||||||
2996 | return asImpl().visitExpr(e); | ||||||||
2997 | } | ||||||||
2998 | |||||||||
2999 | template <typename Impl, typename Result> | ||||||||
3000 | Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) { | ||||||||
3001 | switch (e->getCastKind()) { | ||||||||
3002 | |||||||||
3003 | // No-op casts don't change the type, so we just ignore them. | ||||||||
3004 | case CK_NoOp: | ||||||||
3005 | return asImpl().visit(e->getSubExpr()); | ||||||||
3006 | |||||||||
3007 | // These casts can change the type. | ||||||||
3008 | case CK_CPointerToObjCPointerCast: | ||||||||
3009 | case CK_BlockPointerToObjCPointerCast: | ||||||||
3010 | case CK_AnyPointerToBlockPointerCast: | ||||||||
3011 | case CK_BitCast: { | ||||||||
3012 | llvm::Type *resultType = CGF.ConvertType(e->getType()); | ||||||||
3013 | assert(e->getSubExpr()->getType()->hasPointerRepresentation())((e->getSubExpr()->getType()->hasPointerRepresentation ()) ? static_cast<void> (0) : __assert_fail ("e->getSubExpr()->getType()->hasPointerRepresentation()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3013, __PRETTY_FUNCTION__)); | ||||||||
3014 | Result result = asImpl().visit(e->getSubExpr()); | ||||||||
3015 | return asImpl().emitBitCast(result, resultType); | ||||||||
3016 | } | ||||||||
3017 | |||||||||
3018 | // Handle some casts specially. | ||||||||
3019 | case CK_LValueToRValue: | ||||||||
3020 | return asImpl().visitLValueToRValue(e->getSubExpr()); | ||||||||
3021 | case CK_ARCConsumeObject: | ||||||||
3022 | return asImpl().visitConsumeObject(e->getSubExpr()); | ||||||||
3023 | case CK_ARCExtendBlockObject: | ||||||||
3024 | return asImpl().visitExtendBlockObject(e->getSubExpr()); | ||||||||
3025 | case CK_ARCReclaimReturnedObject: | ||||||||
3026 | return asImpl().visitReclaimReturnedObject(e->getSubExpr()); | ||||||||
3027 | |||||||||
3028 | // Otherwise, use the default logic. | ||||||||
3029 | default: | ||||||||
3030 | return asImpl().visitExpr(e); | ||||||||
3031 | } | ||||||||
3032 | } | ||||||||
3033 | |||||||||
3034 | template <typename Impl, typename Result> | ||||||||
3035 | Result | ||||||||
3036 | ARCExprEmitter<Impl,Result>::visitBinaryOperator(const BinaryOperator *e) { | ||||||||
3037 | switch (e->getOpcode()) { | ||||||||
3038 | case BO_Comma: | ||||||||
3039 | CGF.EmitIgnoredExpr(e->getLHS()); | ||||||||
3040 | CGF.EnsureInsertPoint(); | ||||||||
3041 | return asImpl().visit(e->getRHS()); | ||||||||
3042 | |||||||||
3043 | case BO_Assign: | ||||||||
3044 | return asImpl().visitBinAssign(e); | ||||||||
3045 | |||||||||
3046 | default: | ||||||||
3047 | return asImpl().visitExpr(e); | ||||||||
3048 | } | ||||||||
3049 | } | ||||||||
3050 | |||||||||
3051 | template <typename Impl, typename Result> | ||||||||
3052 | Result ARCExprEmitter<Impl,Result>::visitBinAssign(const BinaryOperator *e) { | ||||||||
3053 | switch (e->getLHS()->getType().getObjCLifetime()) { | ||||||||
3054 | case Qualifiers::OCL_ExplicitNone: | ||||||||
3055 | return asImpl().visitBinAssignUnsafeUnretained(e); | ||||||||
3056 | |||||||||
3057 | case Qualifiers::OCL_Weak: | ||||||||
3058 | return asImpl().visitBinAssignWeak(e); | ||||||||
3059 | |||||||||
3060 | case Qualifiers::OCL_Autoreleasing: | ||||||||
3061 | return asImpl().visitBinAssignAutoreleasing(e); | ||||||||
3062 | |||||||||
3063 | case Qualifiers::OCL_Strong: | ||||||||
3064 | return asImpl().visitBinAssignStrong(e); | ||||||||
3065 | |||||||||
3066 | case Qualifiers::OCL_None: | ||||||||
3067 | return asImpl().visitExpr(e); | ||||||||
3068 | } | ||||||||
3069 | llvm_unreachable("bad ObjC ownership qualifier")::llvm::llvm_unreachable_internal("bad ObjC ownership qualifier" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3069); | ||||||||
3070 | } | ||||||||
3071 | |||||||||
3072 | /// The default rule for __unsafe_unretained emits the RHS recursively, | ||||||||
3073 | /// stores into the unsafe variable, and propagates the result outward. | ||||||||
3074 | template <typename Impl, typename Result> | ||||||||
3075 | Result ARCExprEmitter<Impl,Result>:: | ||||||||
3076 | visitBinAssignUnsafeUnretained(const BinaryOperator *e) { | ||||||||
3077 | // Recursively emit the RHS. | ||||||||
3078 | // For __block safety, do this before emitting the LHS. | ||||||||
3079 | Result result = asImpl().visit(e->getRHS()); | ||||||||
3080 | |||||||||
3081 | // Perform the store. | ||||||||
3082 | LValue lvalue = | ||||||||
3083 | CGF.EmitCheckedLValue(e->getLHS(), CodeGenFunction::TCK_Store); | ||||||||
3084 | CGF.EmitStoreThroughLValue(RValue::get(asImpl().getValueOfResult(result)), | ||||||||
3085 | lvalue); | ||||||||
3086 | |||||||||
3087 | return result; | ||||||||
3088 | } | ||||||||
3089 | |||||||||
3090 | template <typename Impl, typename Result> | ||||||||
3091 | Result | ||||||||
3092 | ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(const BinaryOperator *e) { | ||||||||
3093 | return asImpl().visitExpr(e); | ||||||||
3094 | } | ||||||||
3095 | |||||||||
3096 | template <typename Impl, typename Result> | ||||||||
3097 | Result | ||||||||
3098 | ARCExprEmitter<Impl,Result>::visitBinAssignWeak(const BinaryOperator *e) { | ||||||||
3099 | return asImpl().visitExpr(e); | ||||||||
3100 | } | ||||||||
3101 | |||||||||
3102 | template <typename Impl, typename Result> | ||||||||
3103 | Result | ||||||||
3104 | ARCExprEmitter<Impl,Result>::visitBinAssignStrong(const BinaryOperator *e) { | ||||||||
3105 | return asImpl().visitExpr(e); | ||||||||
3106 | } | ||||||||
3107 | |||||||||
3108 | /// The general expression-emission logic. | ||||||||
3109 | template <typename Impl, typename Result> | ||||||||
3110 | Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) { | ||||||||
3111 | // We should *never* see a nested full-expression here, because if | ||||||||
3112 | // we fail to emit at +1, our caller must not retain after we close | ||||||||
3113 | // out the full-expression. This isn't as important in the unsafe | ||||||||
3114 | // emitter. | ||||||||
3115 | assert(!isa<ExprWithCleanups>(e))((!isa<ExprWithCleanups>(e)) ? static_cast<void> ( 0) : __assert_fail ("!isa<ExprWithCleanups>(e)", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3115, __PRETTY_FUNCTION__)); | ||||||||
3116 | |||||||||
3117 | // Look through parens, __extension__, generic selection, etc. | ||||||||
3118 | e = e->IgnoreParens(); | ||||||||
3119 | |||||||||
3120 | // Handle certain kinds of casts. | ||||||||
3121 | if (const CastExpr *ce = dyn_cast<CastExpr>(e)) { | ||||||||
3122 | return asImpl().visitCastExpr(ce); | ||||||||
3123 | |||||||||
3124 | // Handle the comma operator. | ||||||||
3125 | } else if (auto op = dyn_cast<BinaryOperator>(e)) { | ||||||||
3126 | return asImpl().visitBinaryOperator(op); | ||||||||
3127 | |||||||||
3128 | // TODO: handle conditional operators here | ||||||||
3129 | |||||||||
3130 | // For calls and message sends, use the retained-call logic. | ||||||||
3131 | // Delegate inits are a special case in that they're the only | ||||||||
3132 | // returns-retained expression that *isn't* surrounded by | ||||||||
3133 | // a consume. | ||||||||
3134 | } else if (isa<CallExpr>(e) || | ||||||||
3135 | (isa<ObjCMessageExpr>(e) && | ||||||||
3136 | !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) { | ||||||||
3137 | return asImpl().visitCall(e); | ||||||||
3138 | |||||||||
3139 | // Look through pseudo-object expressions. | ||||||||
3140 | } else if (const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) { | ||||||||
3141 | return asImpl().visitPseudoObjectExpr(pseudo); | ||||||||
3142 | } else if (auto *be = dyn_cast<BlockExpr>(e)) | ||||||||
3143 | return asImpl().visitBlockExpr(be); | ||||||||
3144 | |||||||||
3145 | return asImpl().visitExpr(e); | ||||||||
3146 | } | ||||||||
3147 | |||||||||
3148 | namespace { | ||||||||
3149 | |||||||||
3150 | /// An emitter for +1 results. | ||||||||
3151 | struct ARCRetainExprEmitter : | ||||||||
3152 | public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> { | ||||||||
3153 | |||||||||
3154 | ARCRetainExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {} | ||||||||
3155 | |||||||||
3156 | llvm::Value *getValueOfResult(TryEmitResult result) { | ||||||||
3157 | return result.getPointer(); | ||||||||
3158 | } | ||||||||
3159 | |||||||||
3160 | TryEmitResult emitBitCast(TryEmitResult result, llvm::Type *resultType) { | ||||||||
3161 | llvm::Value *value = result.getPointer(); | ||||||||
3162 | value = CGF.Builder.CreateBitCast(value, resultType); | ||||||||
3163 | result.setPointer(value); | ||||||||
3164 | return result; | ||||||||
3165 | } | ||||||||
3166 | |||||||||
3167 | TryEmitResult visitLValueToRValue(const Expr *e) { | ||||||||
3168 | return tryEmitARCRetainLoadOfScalar(CGF, e); | ||||||||
3169 | } | ||||||||
3170 | |||||||||
3171 | /// For consumptions, just emit the subexpression and thus elide | ||||||||
3172 | /// the retain/release pair. | ||||||||
3173 | TryEmitResult visitConsumeObject(const Expr *e) { | ||||||||
3174 | llvm::Value *result = CGF.EmitScalarExpr(e); | ||||||||
3175 | return TryEmitResult(result, true); | ||||||||
3176 | } | ||||||||
3177 | |||||||||
3178 | TryEmitResult visitBlockExpr(const BlockExpr *e) { | ||||||||
3179 | TryEmitResult result = visitExpr(e); | ||||||||
3180 | // Avoid the block-retain if this is a block literal that doesn't need to be | ||||||||
3181 | // copied to the heap. | ||||||||
3182 | if (e->getBlockDecl()->canAvoidCopyToHeap()) | ||||||||
3183 | result.setInt(true); | ||||||||
3184 | return result; | ||||||||
3185 | } | ||||||||
3186 | |||||||||
3187 | /// Block extends are net +0. Naively, we could just recurse on | ||||||||
3188 | /// the subexpression, but actually we need to ensure that the | ||||||||
3189 | /// value is copied as a block, so there's a little filter here. | ||||||||
3190 | TryEmitResult visitExtendBlockObject(const Expr *e) { | ||||||||
3191 | llvm::Value *result; // will be a +0 value | ||||||||
3192 | |||||||||
3193 | // If we can't safely assume the sub-expression will produce a | ||||||||
3194 | // block-copied value, emit the sub-expression at +0. | ||||||||
3195 | if (shouldEmitSeparateBlockRetain(e)) { | ||||||||
3196 | result = CGF.EmitScalarExpr(e); | ||||||||
3197 | |||||||||
3198 | // Otherwise, try to emit the sub-expression at +1 recursively. | ||||||||
3199 | } else { | ||||||||
3200 | TryEmitResult subresult = asImpl().visit(e); | ||||||||
3201 | |||||||||
3202 | // If that produced a retained value, just use that. | ||||||||
3203 | if (subresult.getInt()) { | ||||||||
3204 | return subresult; | ||||||||
3205 | } | ||||||||
3206 | |||||||||
3207 | // Otherwise it's +0. | ||||||||
3208 | result = subresult.getPointer(); | ||||||||
3209 | } | ||||||||
3210 | |||||||||
3211 | // Retain the object as a block. | ||||||||
3212 | result = CGF.EmitARCRetainBlock(result, /*mandatory*/ true); | ||||||||
3213 | return TryEmitResult(result, true); | ||||||||
3214 | } | ||||||||
3215 | |||||||||
3216 | /// For reclaims, emit the subexpression as a retained call and | ||||||||
3217 | /// skip the consumption. | ||||||||
3218 | TryEmitResult visitReclaimReturnedObject(const Expr *e) { | ||||||||
3219 | llvm::Value *result = emitARCRetainCallResult(CGF, e); | ||||||||
3220 | return TryEmitResult(result, true); | ||||||||
3221 | } | ||||||||
3222 | |||||||||
3223 | /// When we have an undecorated call, retroactively do a claim. | ||||||||
3224 | TryEmitResult visitCall(const Expr *e) { | ||||||||
3225 | llvm::Value *result = emitARCRetainCallResult(CGF, e); | ||||||||
3226 | return TryEmitResult(result, true); | ||||||||
3227 | } | ||||||||
3228 | |||||||||
3229 | // TODO: maybe special-case visitBinAssignWeak? | ||||||||
3230 | |||||||||
3231 | TryEmitResult visitExpr(const Expr *e) { | ||||||||
3232 | // We didn't find an obvious production, so emit what we've got and | ||||||||
3233 | // tell the caller that we didn't manage to retain. | ||||||||
3234 | llvm::Value *result = CGF.EmitScalarExpr(e); | ||||||||
3235 | return TryEmitResult(result, false); | ||||||||
3236 | } | ||||||||
3237 | }; | ||||||||
3238 | } | ||||||||
3239 | |||||||||
3240 | static TryEmitResult | ||||||||
3241 | tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) { | ||||||||
3242 | return ARCRetainExprEmitter(CGF).visit(e); | ||||||||
3243 | } | ||||||||
3244 | |||||||||
3245 | static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF, | ||||||||
3246 | LValue lvalue, | ||||||||
3247 | QualType type) { | ||||||||
3248 | TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type); | ||||||||
3249 | llvm::Value *value = result.getPointer(); | ||||||||
3250 | if (!result.getInt()) | ||||||||
3251 | value = CGF.EmitARCRetain(type, value); | ||||||||
3252 | return value; | ||||||||
3253 | } | ||||||||
3254 | |||||||||
3255 | /// EmitARCRetainScalarExpr - Semantically equivalent to | ||||||||
3256 | /// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a | ||||||||
3257 | /// best-effort attempt to peephole expressions that naturally produce | ||||||||
3258 | /// retained objects. | ||||||||
3259 | llvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) { | ||||||||
3260 | // The retain needs to happen within the full-expression. | ||||||||
3261 | if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) { | ||||||||
3262 | enterFullExpression(cleanups); | ||||||||
3263 | RunCleanupsScope scope(*this); | ||||||||
3264 | return EmitARCRetainScalarExpr(cleanups->getSubExpr()); | ||||||||
3265 | } | ||||||||
3266 | |||||||||
3267 | TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e); | ||||||||
3268 | llvm::Value *value = result.getPointer(); | ||||||||
3269 | if (!result.getInt()) | ||||||||
3270 | value = EmitARCRetain(e->getType(), value); | ||||||||
3271 | return value; | ||||||||
3272 | } | ||||||||
3273 | |||||||||
3274 | llvm::Value * | ||||||||
3275 | CodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) { | ||||||||
3276 | // The retain needs to happen within the full-expression. | ||||||||
3277 | if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) { | ||||||||
3278 | enterFullExpression(cleanups); | ||||||||
3279 | RunCleanupsScope scope(*this); | ||||||||
3280 | return EmitARCRetainAutoreleaseScalarExpr(cleanups->getSubExpr()); | ||||||||
3281 | } | ||||||||
3282 | |||||||||
3283 | TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e); | ||||||||
3284 | llvm::Value *value = result.getPointer(); | ||||||||
3285 | if (result.getInt()) | ||||||||
3286 | value = EmitARCAutorelease(value); | ||||||||
3287 | else | ||||||||
3288 | value = EmitARCRetainAutorelease(e->getType(), value); | ||||||||
3289 | return value; | ||||||||
3290 | } | ||||||||
3291 | |||||||||
3292 | llvm::Value *CodeGenFunction::EmitARCExtendBlockObject(const Expr *e) { | ||||||||
3293 | llvm::Value *result; | ||||||||
3294 | bool doRetain; | ||||||||
3295 | |||||||||
3296 | if (shouldEmitSeparateBlockRetain(e)) { | ||||||||
3297 | result = EmitScalarExpr(e); | ||||||||
3298 | doRetain = true; | ||||||||
3299 | } else { | ||||||||
3300 | TryEmitResult subresult = tryEmitARCRetainScalarExpr(*this, e); | ||||||||
3301 | result = subresult.getPointer(); | ||||||||
3302 | doRetain = !subresult.getInt(); | ||||||||
3303 | } | ||||||||
3304 | |||||||||
3305 | if (doRetain) | ||||||||
3306 | result = EmitARCRetainBlock(result, /*mandatory*/ true); | ||||||||
3307 | return EmitObjCConsumeObject(e->getType(), result); | ||||||||
3308 | } | ||||||||
3309 | |||||||||
3310 | llvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) { | ||||||||
3311 | // In ARC, retain and autorelease the expression. | ||||||||
3312 | if (getLangOpts().ObjCAutoRefCount) { | ||||||||
3313 | // Do so before running any cleanups for the full-expression. | ||||||||
3314 | // EmitARCRetainAutoreleaseScalarExpr does this for us. | ||||||||
3315 | return EmitARCRetainAutoreleaseScalarExpr(expr); | ||||||||
3316 | } | ||||||||
3317 | |||||||||
3318 | // Otherwise, use the normal scalar-expression emission. The | ||||||||
3319 | // exception machinery doesn't do anything special with the | ||||||||
3320 | // exception like retaining it, so there's no safety associated with | ||||||||
3321 | // only running cleanups after the throw has started, and when it | ||||||||
3322 | // matters it tends to be substantially inferior code. | ||||||||
3323 | return EmitScalarExpr(expr); | ||||||||
3324 | } | ||||||||
3325 | |||||||||
3326 | namespace { | ||||||||
3327 | |||||||||
3328 | /// An emitter for assigning into an __unsafe_unretained context. | ||||||||
3329 | struct ARCUnsafeUnretainedExprEmitter : | ||||||||
3330 | public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> { | ||||||||
3331 | |||||||||
3332 | ARCUnsafeUnretainedExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {} | ||||||||
3333 | |||||||||
3334 | llvm::Value *getValueOfResult(llvm::Value *value) { | ||||||||
3335 | return value; | ||||||||
3336 | } | ||||||||
3337 | |||||||||
3338 | llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) { | ||||||||
3339 | return CGF.Builder.CreateBitCast(value, resultType); | ||||||||
3340 | } | ||||||||
3341 | |||||||||
3342 | llvm::Value *visitLValueToRValue(const Expr *e) { | ||||||||
3343 | return CGF.EmitScalarExpr(e); | ||||||||
3344 | } | ||||||||
3345 | |||||||||
3346 | /// For consumptions, just emit the subexpression and perform the | ||||||||
3347 | /// consumption like normal. | ||||||||
3348 | llvm::Value *visitConsumeObject(const Expr *e) { | ||||||||
3349 | llvm::Value *value = CGF.EmitScalarExpr(e); | ||||||||
3350 | return CGF.EmitObjCConsumeObject(e->getType(), value); | ||||||||
3351 | } | ||||||||
3352 | |||||||||
3353 | /// No special logic for block extensions. (This probably can't | ||||||||
3354 | /// actually happen in this emitter, though.) | ||||||||
3355 | llvm::Value *visitExtendBlockObject(const Expr *e) { | ||||||||
3356 | return CGF.EmitARCExtendBlockObject(e); | ||||||||
3357 | } | ||||||||
3358 | |||||||||
3359 | /// For reclaims, perform an unsafeClaim if that's enabled. | ||||||||
3360 | llvm::Value *visitReclaimReturnedObject(const Expr *e) { | ||||||||
3361 | return CGF.EmitARCReclaimReturnedObject(e, /*unsafe*/ true); | ||||||||
3362 | } | ||||||||
3363 | |||||||||
3364 | /// When we have an undecorated call, just emit it without adding | ||||||||
3365 | /// the unsafeClaim. | ||||||||
3366 | llvm::Value *visitCall(const Expr *e) { | ||||||||
3367 | return CGF.EmitScalarExpr(e); | ||||||||
3368 | } | ||||||||
3369 | |||||||||
3370 | /// Just do normal scalar emission in the default case. | ||||||||
3371 | llvm::Value *visitExpr(const Expr *e) { | ||||||||
3372 | return CGF.EmitScalarExpr(e); | ||||||||
3373 | } | ||||||||
3374 | }; | ||||||||
3375 | } | ||||||||
3376 | |||||||||
3377 | static llvm::Value *emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF, | ||||||||
3378 | const Expr *e) { | ||||||||
3379 | return ARCUnsafeUnretainedExprEmitter(CGF).visit(e); | ||||||||
3380 | } | ||||||||
3381 | |||||||||
3382 | /// EmitARCUnsafeUnretainedScalarExpr - Semantically equivalent to | ||||||||
3383 | /// immediately releasing the resut of EmitARCRetainScalarExpr, but | ||||||||
3384 | /// avoiding any spurious retains, including by performing reclaims | ||||||||
3385 | /// with objc_unsafeClaimAutoreleasedReturnValue. | ||||||||
3386 | llvm::Value *CodeGenFunction::EmitARCUnsafeUnretainedScalarExpr(const Expr *e) { | ||||||||
3387 | // Look through full-expressions. | ||||||||
3388 | if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) { | ||||||||
3389 | enterFullExpression(cleanups); | ||||||||
3390 | RunCleanupsScope scope(*this); | ||||||||
3391 | return emitARCUnsafeUnretainedScalarExpr(*this, cleanups->getSubExpr()); | ||||||||
3392 | } | ||||||||
3393 | |||||||||
3394 | return emitARCUnsafeUnretainedScalarExpr(*this, e); | ||||||||
3395 | } | ||||||||
3396 | |||||||||
3397 | std::pair<LValue,llvm::Value*> | ||||||||
3398 | CodeGenFunction::EmitARCStoreUnsafeUnretained(const BinaryOperator *e, | ||||||||
3399 | bool ignored) { | ||||||||
3400 | // Evaluate the RHS first. If we're ignoring the result, assume | ||||||||
3401 | // that we can emit at an unsafe +0. | ||||||||
3402 | llvm::Value *value; | ||||||||
3403 | if (ignored) { | ||||||||
3404 | value = EmitARCUnsafeUnretainedScalarExpr(e->getRHS()); | ||||||||
3405 | } else { | ||||||||
3406 | value = EmitScalarExpr(e->getRHS()); | ||||||||
3407 | } | ||||||||
3408 | |||||||||
3409 | // Emit the LHS and perform the store. | ||||||||
3410 | LValue lvalue = EmitLValue(e->getLHS()); | ||||||||
3411 | EmitStoreOfScalar(value, lvalue); | ||||||||
3412 | |||||||||
3413 | return std::pair<LValue,llvm::Value*>(std::move(lvalue), value); | ||||||||
3414 | } | ||||||||
3415 | |||||||||
3416 | std::pair<LValue,llvm::Value*> | ||||||||
3417 | CodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e, | ||||||||
3418 | bool ignored) { | ||||||||
3419 | // Evaluate the RHS first. | ||||||||
3420 | TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS()); | ||||||||
3421 | llvm::Value *value = result.getPointer(); | ||||||||
3422 | |||||||||
3423 | bool hasImmediateRetain = result.getInt(); | ||||||||
3424 | |||||||||
3425 | // If we didn't emit a retained object, and the l-value is of block | ||||||||
3426 | // type, then we need to emit the block-retain immediately in case | ||||||||
3427 | // it invalidates the l-value. | ||||||||
3428 | if (!hasImmediateRetain && e->getType()->isBlockPointerType()) { | ||||||||
3429 | value = EmitARCRetainBlock(value, /*mandatory*/ false); | ||||||||
3430 | hasImmediateRetain = true; | ||||||||
3431 | } | ||||||||
3432 | |||||||||
3433 | LValue lvalue = EmitLValue(e->getLHS()); | ||||||||
3434 | |||||||||
3435 | // If the RHS was emitted retained, expand this. | ||||||||
3436 | if (hasImmediateRetain) { | ||||||||
3437 | llvm::Value *oldValue = EmitLoadOfScalar(lvalue, SourceLocation()); | ||||||||
3438 | EmitStoreOfScalar(value, lvalue); | ||||||||
3439 | EmitARCRelease(oldValue, lvalue.isARCPreciseLifetime()); | ||||||||
3440 | } else { | ||||||||
3441 | value = EmitARCStoreStrong(lvalue, value, ignored); | ||||||||
3442 | } | ||||||||
3443 | |||||||||
3444 | return std::pair<LValue,llvm::Value*>(lvalue, value); | ||||||||
3445 | } | ||||||||
3446 | |||||||||
3447 | std::pair<LValue,llvm::Value*> | ||||||||
3448 | CodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) { | ||||||||
3449 | llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS()); | ||||||||
3450 | LValue lvalue = EmitLValue(e->getLHS()); | ||||||||
3451 | |||||||||
3452 | EmitStoreOfScalar(value, lvalue); | ||||||||
3453 | |||||||||
3454 | return std::pair<LValue,llvm::Value*>(lvalue, value); | ||||||||
3455 | } | ||||||||
3456 | |||||||||
3457 | void CodeGenFunction::EmitObjCAutoreleasePoolStmt( | ||||||||
3458 | const ObjCAutoreleasePoolStmt &ARPS) { | ||||||||
3459 | const Stmt *subStmt = ARPS.getSubStmt(); | ||||||||
3460 | const CompoundStmt &S = cast<CompoundStmt>(*subStmt); | ||||||||
3461 | |||||||||
3462 | CGDebugInfo *DI = getDebugInfo(); | ||||||||
3463 | if (DI) | ||||||||
3464 | DI->EmitLexicalBlockStart(Builder, S.getLBracLoc()); | ||||||||
3465 | |||||||||
3466 | // Keep track of the current cleanup stack depth. | ||||||||
3467 | RunCleanupsScope Scope(*this); | ||||||||
3468 | if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) { | ||||||||
3469 | llvm::Value *token = EmitObjCAutoreleasePoolPush(); | ||||||||
3470 | EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token); | ||||||||
3471 | } else { | ||||||||
3472 | llvm::Value *token = EmitObjCMRRAutoreleasePoolPush(); | ||||||||
3473 | EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token); | ||||||||
3474 | } | ||||||||
3475 | |||||||||
3476 | for (const auto *I : S.body()) | ||||||||
3477 | EmitStmt(I); | ||||||||
3478 | |||||||||
3479 | if (DI) | ||||||||
3480 | DI->EmitLexicalBlockEnd(Builder, S.getRBracLoc()); | ||||||||
3481 | } | ||||||||
3482 | |||||||||
3483 | /// EmitExtendGCLifetime - Given a pointer to an Objective-C object, | ||||||||
3484 | /// make sure it survives garbage collection until this point. | ||||||||
3485 | void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) { | ||||||||
3486 | // We just use an inline assembly. | ||||||||
3487 | llvm::FunctionType *extenderType | ||||||||
3488 | = llvm::FunctionType::get(VoidTy, VoidPtrTy, RequiredArgs::All); | ||||||||
3489 | llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType, | ||||||||
3490 | /* assembly */ "", | ||||||||
3491 | /* constraints */ "r", | ||||||||
3492 | /* side effects */ true); | ||||||||
3493 | |||||||||
3494 | object = Builder.CreateBitCast(object, VoidPtrTy); | ||||||||
3495 | EmitNounwindRuntimeCall(extender, object); | ||||||||
3496 | } | ||||||||
3497 | |||||||||
3498 | /// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with | ||||||||
3499 | /// non-trivial copy assignment function, produce following helper function. | ||||||||
3500 | /// static void copyHelper(Ty *dest, const Ty *source) { *dest = *source; } | ||||||||
3501 | /// | ||||||||
3502 | llvm::Constant * | ||||||||
3503 | CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( | ||||||||
3504 | const ObjCPropertyImplDecl *PID) { | ||||||||
3505 | if (!getLangOpts().CPlusPlus || | ||||||||
3506 | !getLangOpts().ObjCRuntime.hasAtomicCopyHelper()) | ||||||||
3507 | return nullptr; | ||||||||
3508 | QualType Ty = PID->getPropertyIvarDecl()->getType(); | ||||||||
3509 | if (!Ty->isRecordType()) | ||||||||
3510 | return nullptr; | ||||||||
3511 | const ObjCPropertyDecl *PD = PID->getPropertyDecl(); | ||||||||
3512 | if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic))) | ||||||||
3513 | return nullptr; | ||||||||
3514 | llvm::Constant *HelperFn = nullptr; | ||||||||
3515 | if (hasTrivialSetExpr(PID)) | ||||||||
3516 | return nullptr; | ||||||||
3517 | assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null")((PID->getSetterCXXAssignment() && "SetterCXXAssignment - null" ) ? static_cast<void> (0) : __assert_fail ("PID->getSetterCXXAssignment() && \"SetterCXXAssignment - null\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3517, __PRETTY_FUNCTION__)); | ||||||||
3518 | if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty))) | ||||||||
3519 | return HelperFn; | ||||||||
3520 | |||||||||
3521 | ASTContext &C = getContext(); | ||||||||
3522 | IdentifierInfo *II | ||||||||
3523 | = &CGM.getContext().Idents.get("__assign_helper_atomic_property_"); | ||||||||
3524 | |||||||||
3525 | QualType ReturnTy = C.VoidTy; | ||||||||
3526 | QualType DestTy = C.getPointerType(Ty); | ||||||||
3527 | QualType SrcTy = Ty; | ||||||||
3528 | SrcTy.addConst(); | ||||||||
3529 | SrcTy = C.getPointerType(SrcTy); | ||||||||
3530 | |||||||||
3531 | SmallVector<QualType, 2> ArgTys; | ||||||||
3532 | ArgTys.push_back(DestTy); | ||||||||
3533 | ArgTys.push_back(SrcTy); | ||||||||
3534 | QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {}); | ||||||||
3535 | |||||||||
3536 | FunctionDecl *FD = FunctionDecl::Create( | ||||||||
3537 | C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, | ||||||||
3538 | FunctionTy, nullptr, SC_Static, false, false); | ||||||||
3539 | |||||||||
3540 | FunctionArgList args; | ||||||||
3541 | ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy, | ||||||||
3542 | ImplicitParamDecl::Other); | ||||||||
3543 | args.push_back(&DstDecl); | ||||||||
3544 | ImplicitParamDecl SrcDecl(C, FD, SourceLocation(), /*Id=*/nullptr, SrcTy, | ||||||||
3545 | ImplicitParamDecl::Other); | ||||||||
3546 | args.push_back(&SrcDecl); | ||||||||
3547 | |||||||||
3548 | const CGFunctionInfo &FI = | ||||||||
3549 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); | ||||||||
3550 | |||||||||
3551 | llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); | ||||||||
3552 | |||||||||
3553 | llvm::Function *Fn = | ||||||||
3554 | llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, | ||||||||
3555 | "__assign_helper_atomic_property_", | ||||||||
3556 | &CGM.getModule()); | ||||||||
3557 | |||||||||
3558 | CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); | ||||||||
3559 | |||||||||
3560 | StartFunction(FD, ReturnTy, Fn, FI, args); | ||||||||
3561 | |||||||||
3562 | DeclRefExpr DstExpr(getContext(), &DstDecl, false, DestTy, VK_RValue, | ||||||||
3563 | SourceLocation()); | ||||||||
3564 | UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(), | ||||||||
3565 | VK_LValue, OK_Ordinary, SourceLocation(), false); | ||||||||
3566 | |||||||||
3567 | DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue, | ||||||||
3568 | SourceLocation()); | ||||||||
3569 | UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), | ||||||||
3570 | VK_LValue, OK_Ordinary, SourceLocation(), false); | ||||||||
3571 | |||||||||
3572 | Expr *Args[2] = { &DST, &SRC }; | ||||||||
3573 | CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment()); | ||||||||
3574 | CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( | ||||||||
3575 | C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(), | ||||||||
3576 | VK_LValue, SourceLocation(), FPOptions()); | ||||||||
3577 | |||||||||
3578 | EmitStmt(TheCall); | ||||||||
3579 | |||||||||
3580 | FinishFunction(); | ||||||||
3581 | HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); | ||||||||
3582 | CGM.setAtomicSetterHelperFnMap(Ty, HelperFn); | ||||||||
3583 | return HelperFn; | ||||||||
3584 | } | ||||||||
3585 | |||||||||
3586 | llvm::Constant * | ||||||||
3587 | CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( | ||||||||
3588 | const ObjCPropertyImplDecl *PID) { | ||||||||
3589 | if (!getLangOpts().CPlusPlus || | ||||||||
3590 | !getLangOpts().ObjCRuntime.hasAtomicCopyHelper()) | ||||||||
3591 | return nullptr; | ||||||||
3592 | const ObjCPropertyDecl *PD = PID->getPropertyDecl(); | ||||||||
3593 | QualType Ty = PD->getType(); | ||||||||
3594 | if (!Ty->isRecordType()) | ||||||||
3595 | return nullptr; | ||||||||
3596 | if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic))) | ||||||||
3597 | return nullptr; | ||||||||
3598 | llvm::Constant *HelperFn = nullptr; | ||||||||
3599 | if (hasTrivialGetExpr(PID)) | ||||||||
3600 | return nullptr; | ||||||||
3601 | assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null")((PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null" ) ? static_cast<void> (0) : __assert_fail ("PID->getGetterCXXConstructor() && \"getGetterCXXConstructor - null\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3601, __PRETTY_FUNCTION__)); | ||||||||
3602 | if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty))) | ||||||||
3603 | return HelperFn; | ||||||||
3604 | |||||||||
3605 | ASTContext &C = getContext(); | ||||||||
3606 | IdentifierInfo *II = | ||||||||
3607 | &CGM.getContext().Idents.get("__copy_helper_atomic_property_"); | ||||||||
3608 | |||||||||
3609 | QualType ReturnTy = C.VoidTy; | ||||||||
3610 | QualType DestTy = C.getPointerType(Ty); | ||||||||
3611 | QualType SrcTy = Ty; | ||||||||
3612 | SrcTy.addConst(); | ||||||||
3613 | SrcTy = C.getPointerType(SrcTy); | ||||||||
3614 | |||||||||
3615 | SmallVector<QualType, 2> ArgTys; | ||||||||
3616 | ArgTys.push_back(DestTy); | ||||||||
3617 | ArgTys.push_back(SrcTy); | ||||||||
3618 | QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {}); | ||||||||
3619 | |||||||||
3620 | FunctionDecl *FD = FunctionDecl::Create( | ||||||||
3621 | C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, | ||||||||
3622 | FunctionTy, nullptr, SC_Static, false, false); | ||||||||
3623 | |||||||||
3624 | FunctionArgList args; | ||||||||
3625 | ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy, | ||||||||
3626 | ImplicitParamDecl::Other); | ||||||||
3627 | args.push_back(&DstDecl); | ||||||||
3628 | ImplicitParamDecl SrcDecl(C, FD, SourceLocation(), /*Id=*/nullptr, SrcTy, | ||||||||
3629 | ImplicitParamDecl::Other); | ||||||||
3630 | args.push_back(&SrcDecl); | ||||||||
3631 | |||||||||
3632 | const CGFunctionInfo &FI = | ||||||||
3633 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); | ||||||||
3634 | |||||||||
3635 | llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); | ||||||||
3636 | |||||||||
3637 | llvm::Function *Fn = llvm::Function::Create( | ||||||||
3638 | LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_", | ||||||||
3639 | &CGM.getModule()); | ||||||||
3640 | |||||||||
3641 | CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); | ||||||||
3642 | |||||||||
3643 | StartFunction(FD, ReturnTy, Fn, FI, args); | ||||||||
3644 | |||||||||
3645 | DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue, | ||||||||
3646 | SourceLocation()); | ||||||||
3647 | |||||||||
3648 | UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), | ||||||||
3649 | VK_LValue, OK_Ordinary, SourceLocation(), false); | ||||||||
3650 | |||||||||
3651 | CXXConstructExpr *CXXConstExpr = | ||||||||
3652 | cast<CXXConstructExpr>(PID->getGetterCXXConstructor()); | ||||||||
3653 | |||||||||
3654 | SmallVector<Expr*, 4> ConstructorArgs; | ||||||||
3655 | ConstructorArgs.push_back(&SRC); | ||||||||
3656 | ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()), | ||||||||
3657 | CXXConstExpr->arg_end()); | ||||||||
3658 | |||||||||
3659 | CXXConstructExpr *TheCXXConstructExpr = | ||||||||
3660 | CXXConstructExpr::Create(C, Ty, SourceLocation(), | ||||||||
3661 | CXXConstExpr->getConstructor(), | ||||||||
3662 | CXXConstExpr->isElidable(), | ||||||||
3663 | ConstructorArgs, | ||||||||
3664 | CXXConstExpr->hadMultipleCandidates(), | ||||||||
3665 | CXXConstExpr->isListInitialization(), | ||||||||
3666 | CXXConstExpr->isStdInitListInitialization(), | ||||||||
3667 | CXXConstExpr->requiresZeroInitialization(), | ||||||||
3668 | CXXConstExpr->getConstructionKind(), | ||||||||
3669 | SourceRange()); | ||||||||
3670 | |||||||||
3671 | DeclRefExpr DstExpr(getContext(), &DstDecl, false, DestTy, VK_RValue, | ||||||||
3672 | SourceLocation()); | ||||||||
3673 | |||||||||
3674 | RValue DV = EmitAnyExpr(&DstExpr); | ||||||||
3675 | CharUnits Alignment | ||||||||
3676 | = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType()); | ||||||||
3677 | EmitAggExpr(TheCXXConstructExpr, | ||||||||
3678 | AggValueSlot::forAddr(Address(DV.getScalarVal(), Alignment), | ||||||||
3679 | Qualifiers(), | ||||||||
3680 | AggValueSlot::IsDestructed, | ||||||||
3681 | AggValueSlot::DoesNotNeedGCBarriers, | ||||||||
3682 | AggValueSlot::IsNotAliased, | ||||||||
3683 | AggValueSlot::DoesNotOverlap)); | ||||||||
3684 | |||||||||
3685 | FinishFunction(); | ||||||||
3686 | HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); | ||||||||
3687 | CGM.setAtomicGetterHelperFnMap(Ty, HelperFn); | ||||||||
3688 | return HelperFn; | ||||||||
3689 | } | ||||||||
3690 | |||||||||
3691 | llvm::Value * | ||||||||
3692 | CodeGenFunction::EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty) { | ||||||||
3693 | // Get selectors for retain/autorelease. | ||||||||
3694 | IdentifierInfo *CopyID = &getContext().Idents.get("copy"); | ||||||||
3695 | Selector CopySelector = | ||||||||
3696 | getContext().Selectors.getNullarySelector(CopyID); | ||||||||
3697 | IdentifierInfo *AutoreleaseID = &getContext().Idents.get("autorelease"); | ||||||||
3698 | Selector AutoreleaseSelector = | ||||||||
3699 | getContext().Selectors.getNullarySelector(AutoreleaseID); | ||||||||
3700 | |||||||||
3701 | // Emit calls to retain/autorelease. | ||||||||
3702 | CGObjCRuntime &Runtime = CGM.getObjCRuntime(); | ||||||||
3703 | llvm::Value *Val = Block; | ||||||||
3704 | RValue Result; | ||||||||
3705 | Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
3706 | Ty, CopySelector, | ||||||||
3707 | Val, CallArgList(), nullptr, nullptr); | ||||||||
3708 | Val = Result.getScalarVal(); | ||||||||
3709 | Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), | ||||||||
3710 | Ty, AutoreleaseSelector, | ||||||||
3711 | Val, CallArgList(), nullptr, nullptr); | ||||||||
3712 | Val = Result.getScalarVal(); | ||||||||
3713 | return Val; | ||||||||
3714 | } | ||||||||
3715 | |||||||||
3716 | llvm::Value * | ||||||||
3717 | CodeGenFunction::EmitBuiltinAvailable(ArrayRef<llvm::Value *> Args) { | ||||||||
3718 | assert(Args.size() == 3 && "Expected 3 argument here!")((Args.size() == 3 && "Expected 3 argument here!") ? static_cast <void> (0) : __assert_fail ("Args.size() == 3 && \"Expected 3 argument here!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/CodeGen/CGObjC.cpp" , 3718, __PRETTY_FUNCTION__)); | ||||||||
3719 | |||||||||
3720 | if (!CGM.IsOSVersionAtLeastFn) { | ||||||||
3721 | llvm::FunctionType *FTy = | ||||||||
3722 | llvm::FunctionType::get(Int32Ty, {Int32Ty, Int32Ty, Int32Ty}, false); | ||||||||
3723 | CGM.IsOSVersionAtLeastFn = | ||||||||
3724 | CGM.CreateRuntimeFunction(FTy, "__isOSVersionAtLeast"); | ||||||||
3725 | } | ||||||||
3726 | |||||||||
3727 | llvm::Value *CallRes = | ||||||||
3728 | EmitNounwindRuntimeCall(CGM.IsOSVersionAtLeastFn, Args); | ||||||||
3729 | |||||||||
3730 | return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty)); | ||||||||
3731 | } | ||||||||
3732 | |||||||||
3733 | void CodeGenModule::emitAtAvailableLinkGuard() { | ||||||||
3734 | if (!IsOSVersionAtLeastFn) | ||||||||
3735 | return; | ||||||||
3736 | // @available requires CoreFoundation only on Darwin. | ||||||||
3737 | if (!Target.getTriple().isOSDarwin()) | ||||||||
3738 | return; | ||||||||
3739 | // Add -framework CoreFoundation to the linker commands. We still want to | ||||||||
3740 | // emit the core foundation reference down below because otherwise if | ||||||||
3741 | // CoreFoundation is not used in the code, the linker won't link the | ||||||||
3742 | // framework. | ||||||||
3743 | auto &Context = getLLVMContext(); | ||||||||
3744 | llvm::Metadata *Args[2] = {llvm::MDString::get(Context, "-framework"), | ||||||||
3745 | llvm::MDString::get(Context, "CoreFoundation")}; | ||||||||
3746 | LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args)); | ||||||||
3747 | // Emit a reference to a symbol from CoreFoundation to ensure that | ||||||||
3748 | // CoreFoundation is linked into the final binary. | ||||||||
3749 | llvm::FunctionType *FTy = | ||||||||
3750 | llvm::FunctionType::get(Int32Ty, {VoidPtrTy}, false); | ||||||||
3751 | llvm::FunctionCallee CFFunc = | ||||||||
3752 | CreateRuntimeFunction(FTy, "CFBundleGetVersionNumber"); | ||||||||
3753 | |||||||||
3754 | llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false); | ||||||||
3755 | llvm::FunctionCallee CFLinkCheckFuncRef = CreateRuntimeFunction( | ||||||||
3756 | CheckFTy, "__clang_at_available_requires_core_foundation_framework", | ||||||||
3757 | llvm::AttributeList(), /*Local=*/true); | ||||||||
3758 | llvm::Function *CFLinkCheckFunc = | ||||||||
3759 | cast<llvm::Function>(CFLinkCheckFuncRef.getCallee()->stripPointerCasts()); | ||||||||
3760 | if (CFLinkCheckFunc->empty()) { | ||||||||
3761 | CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage); | ||||||||
3762 | CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility); | ||||||||
3763 | CodeGenFunction CGF(*this); | ||||||||
3764 | CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc)); | ||||||||
3765 | CGF.EmitNounwindRuntimeCall(CFFunc, | ||||||||
3766 | llvm::Constant::getNullValue(VoidPtrTy)); | ||||||||
3767 | CGF.Builder.CreateUnreachable(); | ||||||||
3768 | addCompilerUsedGlobal(CFLinkCheckFunc); | ||||||||
3769 | } | ||||||||
3770 | } | ||||||||
3771 | |||||||||
3772 | CGObjCRuntime::~CGObjCRuntime() {} |
1 | //===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | /// \file |
10 | /// Defines types useful for describing an Objective-C runtime. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H |
15 | #define LLVM_CLANG_BASIC_OBJCRUNTIME_H |
16 | |
17 | #include "clang/Basic/LLVM.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/ADT/Triple.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/VersionTuple.h" |
22 | #include <string> |
23 | |
24 | namespace clang { |
25 | |
26 | /// The basic abstraction for the target Objective-C runtime. |
27 | class ObjCRuntime { |
28 | public: |
29 | /// The basic Objective-C runtimes that we know about. |
30 | enum Kind { |
31 | /// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS |
32 | /// X platforms that use the non-fragile ABI; the version is a |
33 | /// release of that OS. |
34 | MacOSX, |
35 | |
36 | /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on |
37 | /// Mac OS X platforms that use the fragile ABI; the version is a |
38 | /// release of that OS. |
39 | FragileMacOSX, |
40 | |
41 | /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS |
42 | /// simulator; it is always non-fragile. The version is a release |
43 | /// version of iOS. |
44 | iOS, |
45 | |
46 | /// 'watchos' is a variant of iOS for Apple's watchOS. The version |
47 | /// is a release version of watchOS. |
48 | WatchOS, |
49 | |
50 | /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a |
51 | /// fragile Objective-C ABI |
52 | GCC, |
53 | |
54 | /// 'gnustep' is the modern non-fragile GNUstep runtime. |
55 | GNUstep, |
56 | |
57 | /// 'objfw' is the Objective-C runtime included in ObjFW |
58 | ObjFW |
59 | }; |
60 | |
61 | private: |
62 | Kind TheKind = MacOSX; |
63 | VersionTuple Version; |
64 | |
65 | public: |
66 | /// A bogus initialization of the runtime. |
67 | ObjCRuntime() = default; |
68 | ObjCRuntime(Kind kind, const VersionTuple &version) |
69 | : TheKind(kind), Version(version) {} |
70 | |
71 | void set(Kind kind, VersionTuple version) { |
72 | TheKind = kind; |
73 | Version = version; |
74 | } |
75 | |
76 | Kind getKind() const { return TheKind; } |
77 | const VersionTuple &getVersion() const { return Version; } |
78 | |
79 | /// Does this runtime follow the set of implied behaviors for a |
80 | /// "non-fragile" ABI? |
81 | bool isNonFragile() const { |
82 | switch (getKind()) { |
83 | case FragileMacOSX: return false; |
84 | case GCC: return false; |
85 | case MacOSX: return true; |
86 | case GNUstep: return true; |
87 | case ObjFW: return true; |
88 | case iOS: return true; |
89 | case WatchOS: return true; |
90 | } |
91 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 91); |
92 | } |
93 | |
94 | /// The inverse of isNonFragile(): does this runtime follow the set of |
95 | /// implied behaviors for a "fragile" ABI? |
96 | bool isFragile() const { return !isNonFragile(); } |
97 | |
98 | /// The default dispatch mechanism to use for the specified architecture |
99 | bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) { |
100 | // The GNUstep runtime uses a newer dispatch method by default from |
101 | // version 1.6 onwards |
102 | if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) { |
103 | if (Arch == llvm::Triple::arm || |
104 | Arch == llvm::Triple::x86 || |
105 | Arch == llvm::Triple::x86_64) |
106 | return false; |
107 | } |
108 | else if ((getKind() == MacOSX) && isNonFragile() && |
109 | (getVersion() >= VersionTuple(10, 0)) && |
110 | (getVersion() < VersionTuple(10, 6))) |
111 | return Arch != llvm::Triple::x86_64; |
112 | // Except for deployment target of 10.5 or less, |
113 | // Mac runtimes use legacy dispatch everywhere now. |
114 | return true; |
115 | } |
116 | |
117 | /// Is this runtime basically of the GNU family of runtimes? |
118 | bool isGNUFamily() const { |
119 | switch (getKind()) { |
120 | case FragileMacOSX: |
121 | case MacOSX: |
122 | case iOS: |
123 | case WatchOS: |
124 | return false; |
125 | case GCC: |
126 | case GNUstep: |
127 | case ObjFW: |
128 | return true; |
129 | } |
130 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 130); |
131 | } |
132 | |
133 | /// Is this runtime basically of the NeXT family of runtimes? |
134 | bool isNeXTFamily() const { |
135 | // For now, this is just the inverse of isGNUFamily(), but that's |
136 | // not inherently true. |
137 | return !isGNUFamily(); |
138 | } |
139 | |
140 | /// Does this runtime allow ARC at all? |
141 | bool allowsARC() const { |
142 | switch (getKind()) { |
143 | case FragileMacOSX: |
144 | // No stub library for the fragile runtime. |
145 | return getVersion() >= VersionTuple(10, 7); |
146 | case MacOSX: return true; |
147 | case iOS: return true; |
148 | case WatchOS: return true; |
149 | case GCC: return false; |
150 | case GNUstep: return true; |
151 | case ObjFW: return true; |
152 | } |
153 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 153); |
154 | } |
155 | |
156 | /// Does this runtime natively provide the ARC entrypoints? |
157 | /// |
158 | /// ARC cannot be directly supported on a platform that does not provide |
159 | /// these entrypoints, although it may be supportable via a stub |
160 | /// library. |
161 | bool hasNativeARC() const { |
162 | switch (getKind()) { |
163 | case FragileMacOSX: return getVersion() >= VersionTuple(10, 7); |
164 | case MacOSX: return getVersion() >= VersionTuple(10, 7); |
165 | case iOS: return getVersion() >= VersionTuple(5); |
166 | case WatchOS: return true; |
167 | |
168 | case GCC: return false; |
169 | case GNUstep: return getVersion() >= VersionTuple(1, 6); |
170 | case ObjFW: return true; |
171 | } |
172 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 172); |
173 | } |
174 | |
175 | /// Does this runtime provide ARC entrypoints that are likely to be faster |
176 | /// than an ordinary message send of the appropriate selector? |
177 | /// |
178 | /// The ARC entrypoints are guaranteed to be equivalent to just sending the |
179 | /// corresponding message. If the entrypoint is implemented naively as just a |
180 | /// message send, using it is a trade-off: it sacrifices a few cycles of |
181 | /// overhead to save a small amount of code. However, it's possible for |
182 | /// runtimes to detect and special-case classes that use "standard" |
183 | /// retain/release behavior; if that's dynamically a large proportion of all |
184 | /// retained objects, using the entrypoint will also be faster than using a |
185 | /// message send. |
186 | /// |
187 | /// When this method returns true, Clang will turn non-super message sends of |
188 | /// certain selectors into calls to the correspond entrypoint: |
189 | /// retain => objc_retain |
190 | /// release => objc_release |
191 | /// autorelease => objc_autorelease |
192 | bool shouldUseARCFunctionsForRetainRelease() const { |
193 | switch (getKind()) { |
194 | case FragileMacOSX: |
195 | return false; |
196 | case MacOSX: |
197 | return getVersion() >= VersionTuple(10, 10); |
198 | case iOS: |
199 | return getVersion() >= VersionTuple(8); |
200 | case WatchOS: |
201 | return true; |
202 | case GCC: |
203 | return false; |
204 | case GNUstep: |
205 | return false; |
206 | case ObjFW: |
207 | return false; |
208 | } |
209 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 209); |
210 | } |
211 | |
212 | /// Does this runtime provide entrypoints that are likely to be faster |
213 | /// than an ordinary message send of the "alloc" selector? |
214 | /// |
215 | /// The "alloc" entrypoint is guaranteed to be equivalent to just sending the |
216 | /// corresponding message. If the entrypoint is implemented naively as just a |
217 | /// message send, using it is a trade-off: it sacrifices a few cycles of |
218 | /// overhead to save a small amount of code. However, it's possible for |
219 | /// runtimes to detect and special-case classes that use "standard" |
220 | /// alloc behavior; if that's dynamically a large proportion of all |
221 | /// objects, using the entrypoint will also be faster than using a message |
222 | /// send. |
223 | /// |
224 | /// When this method returns true, Clang will turn non-super message sends of |
225 | /// certain selectors into calls to the corresponding entrypoint: |
226 | /// alloc => objc_alloc |
227 | /// allocWithZone:nil => objc_allocWithZone |
228 | bool shouldUseRuntimeFunctionsForAlloc() const { |
229 | switch (getKind()) { |
230 | case FragileMacOSX: |
231 | return false; |
232 | case MacOSX: |
233 | return getVersion() >= VersionTuple(10, 10); |
234 | case iOS: |
235 | return getVersion() >= VersionTuple(8); |
236 | case WatchOS: |
237 | return true; |
238 | |
239 | case GCC: |
240 | return false; |
241 | case GNUstep: |
242 | return false; |
243 | case ObjFW: |
244 | return false; |
245 | } |
246 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 246); |
247 | } |
248 | |
249 | /// Does this runtime provide the objc_alloc_init entrypoint? This can apply |
250 | /// the same optimization as objc_alloc, but also sends an -init message, |
251 | /// reducing code size on the caller. |
252 | bool shouldUseRuntimeFunctionForCombinedAllocInit() const { |
253 | switch (getKind()) { |
254 | case MacOSX: |
255 | return getVersion() >= VersionTuple(10, 14, 4); |
256 | case iOS: |
257 | return getVersion() >= VersionTuple(12, 2); |
258 | case WatchOS: |
259 | return getVersion() >= VersionTuple(5, 2); |
260 | default: |
261 | return false; |
262 | } |
263 | } |
264 | |
265 | /// Does this runtime supports optimized setter entrypoints? |
266 | bool hasOptimizedSetter() const { |
267 | switch (getKind()) { |
268 | case MacOSX: |
269 | return getVersion() >= VersionTuple(10, 8); |
270 | case iOS: |
271 | return (getVersion() >= VersionTuple(6)); |
272 | case WatchOS: |
273 | return true; |
274 | case GNUstep: |
275 | return getVersion() >= VersionTuple(1, 7); |
276 | default: |
277 | return false; |
278 | } |
279 | } |
280 | |
281 | /// Does this runtime allow the use of __weak? |
282 | bool allowsWeak() const { |
283 | return hasNativeWeak(); |
284 | } |
285 | |
286 | /// Does this runtime natively provide ARC-compliant 'weak' |
287 | /// entrypoints? |
288 | bool hasNativeWeak() const { |
289 | // Right now, this is always equivalent to whether the runtime |
290 | // natively supports ARC decision. |
291 | return hasNativeARC(); |
292 | } |
293 | |
294 | /// Does this runtime directly support the subscripting methods? |
295 | /// |
296 | /// This is really a property of the library, not the runtime. |
297 | bool hasSubscripting() const { |
298 | switch (getKind()) { |
299 | case FragileMacOSX: return false; |
300 | case MacOSX: return getVersion() >= VersionTuple(10, 11); |
301 | case iOS: return getVersion() >= VersionTuple(9); |
302 | case WatchOS: return true; |
303 | |
304 | // This is really a lie, because some implementations and versions |
305 | // of the runtime do not support ARC. Probably -fgnu-runtime |
306 | // should imply a "maximal" runtime or something? |
307 | case GCC: return true; |
308 | case GNUstep: return true; |
309 | case ObjFW: return true; |
310 | } |
311 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 311); |
312 | } |
313 | |
314 | /// Does this runtime allow sizeof or alignof on object types? |
315 | bool allowsSizeofAlignof() const { |
316 | return isFragile(); |
317 | } |
318 | |
319 | /// Does this runtime allow pointer arithmetic on objects? |
320 | /// |
321 | /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic() |
322 | /// yields true) []. |
323 | bool allowsPointerArithmetic() const { |
324 | switch (getKind()) { |
325 | case FragileMacOSX: |
326 | case GCC: |
327 | return true; |
328 | case MacOSX: |
329 | case iOS: |
330 | case WatchOS: |
331 | case GNUstep: |
332 | case ObjFW: |
333 | return false; |
334 | } |
335 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 335); |
336 | } |
337 | |
338 | /// Is subscripting pointer arithmetic? |
339 | bool isSubscriptPointerArithmetic() const { |
340 | return allowsPointerArithmetic(); |
341 | } |
342 | |
343 | /// Does this runtime provide an objc_terminate function? |
344 | /// |
345 | /// This is used in handlers for exceptions during the unwind process; |
346 | /// without it, abort() must be used in pure ObjC files. |
347 | bool hasTerminate() const { |
348 | switch (getKind()) { |
349 | case FragileMacOSX: return getVersion() >= VersionTuple(10, 8); |
350 | case MacOSX: return getVersion() >= VersionTuple(10, 8); |
351 | case iOS: return getVersion() >= VersionTuple(5); |
352 | case WatchOS: return true; |
353 | case GCC: return false; |
354 | case GNUstep: return false; |
355 | case ObjFW: return false; |
356 | } |
357 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 357); |
358 | } |
359 | |
360 | /// Does this runtime support weakly importing classes? |
361 | bool hasWeakClassImport() const { |
362 | switch (getKind()) { |
363 | case MacOSX: return true; |
364 | case iOS: return true; |
365 | case WatchOS: return true; |
366 | case FragileMacOSX: return false; |
367 | case GCC: return true; |
368 | case GNUstep: return true; |
369 | case ObjFW: return true; |
370 | } |
371 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 371); |
372 | } |
373 | |
374 | /// Does this runtime use zero-cost exceptions? |
375 | bool hasUnwindExceptions() const { |
376 | switch (getKind()) { |
377 | case MacOSX: return true; |
378 | case iOS: return true; |
379 | case WatchOS: return true; |
380 | case FragileMacOSX: return false; |
381 | case GCC: return true; |
382 | case GNUstep: return true; |
383 | case ObjFW: return true; |
384 | } |
385 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 385); |
386 | } |
387 | |
388 | bool hasAtomicCopyHelper() const { |
389 | switch (getKind()) { |
390 | case FragileMacOSX: |
391 | case MacOSX: |
392 | case iOS: |
393 | case WatchOS: |
394 | return true; |
395 | case GNUstep: |
396 | return getVersion() >= VersionTuple(1, 7); |
397 | default: return false; |
398 | } |
399 | } |
400 | |
401 | /// Is objc_unsafeClaimAutoreleasedReturnValue available? |
402 | bool hasARCUnsafeClaimAutoreleasedReturnValue() const { |
403 | switch (getKind()) { |
404 | case MacOSX: |
405 | case FragileMacOSX: |
406 | return getVersion() >= VersionTuple(10, 11); |
407 | case iOS: |
408 | return getVersion() >= VersionTuple(9); |
409 | case WatchOS: |
410 | return getVersion() >= VersionTuple(2); |
411 | case GNUstep: |
412 | return false; |
413 | default: |
414 | return false; |
415 | } |
416 | } |
417 | |
418 | /// Are the empty collection symbols available? |
419 | bool hasEmptyCollections() const { |
420 | switch (getKind()) { |
421 | default: |
422 | return false; |
423 | case MacOSX: |
424 | return getVersion() >= VersionTuple(10, 11); |
425 | case iOS: |
426 | return getVersion() >= VersionTuple(9); |
427 | case WatchOS: |
428 | return getVersion() >= VersionTuple(2); |
429 | } |
430 | } |
431 | |
432 | /// Returns true if this Objective-C runtime supports Objective-C class |
433 | /// stubs. |
434 | bool allowsClassStubs() const { |
435 | switch (getKind()) { |
436 | case FragileMacOSX: |
437 | case GCC: |
438 | case GNUstep: |
439 | case ObjFW: |
440 | return false; |
441 | case MacOSX: |
442 | case iOS: |
443 | case WatchOS: |
444 | return true; |
445 | } |
446 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 446); |
447 | } |
448 | |
449 | /// Does this runtime supports direct dispatch |
450 | bool allowsDirectDispatch() const { |
451 | switch (getKind()) { |
452 | case FragileMacOSX: return false; |
453 | case MacOSX: return true; |
454 | case iOS: return true; |
455 | case WatchOS: return true; |
456 | case GCC: return false; |
457 | case GNUstep: return false; |
458 | case ObjFW: return false; |
459 | } |
460 | llvm_unreachable("bad kind")::llvm::llvm_unreachable_internal("bad kind", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include/clang/Basic/ObjCRuntime.h" , 460); |
461 | } |
462 | |
463 | /// Try to parse an Objective-C runtime specification from the given |
464 | /// string. |
465 | /// |
466 | /// \return true on error. |
467 | bool tryParse(StringRef input); |
468 | |
469 | std::string getAsString() const; |
470 | |
471 | friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) { |
472 | return left.getKind() == right.getKind() && |
473 | left.getVersion() == right.getVersion(); |
474 | } |
475 | |
476 | friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) { |
477 | return !(left == right); |
478 | } |
479 | }; |
480 | |
481 | raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value); |
482 | |
483 | } // namespace clang |
484 | |
485 | #endif // LLVM_CLANG_BASIC_OBJCRUNTIME_H |
1 | //===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// Defines the llvm::VersionTuple class, which represents a version in |
11 | /// the form major[.minor[.subminor]]. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | #ifndef LLVM_SUPPORT_VERSIONTUPLE_H |
15 | #define LLVM_SUPPORT_VERSIONTUPLE_H |
16 | |
17 | #include "llvm/ADT/Optional.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/Support/raw_ostream.h" |
20 | #include <string> |
21 | #include <tuple> |
22 | |
23 | namespace llvm { |
24 | |
25 | /// Represents a version number in the form major[.minor[.subminor[.build]]]. |
26 | class VersionTuple { |
27 | unsigned Major : 32; |
28 | |
29 | unsigned Minor : 31; |
30 | unsigned HasMinor : 1; |
31 | |
32 | unsigned Subminor : 31; |
33 | unsigned HasSubminor : 1; |
34 | |
35 | unsigned Build : 31; |
36 | unsigned HasBuild : 1; |
37 | |
38 | public: |
39 | VersionTuple() |
40 | : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false), |
41 | Build(0), HasBuild(false) {} |
42 | |
43 | explicit VersionTuple(unsigned Major) |
44 | : Major(Major), Minor(0), HasMinor(false), Subminor(0), |
45 | HasSubminor(false), Build(0), HasBuild(false) {} |
46 | |
47 | explicit VersionTuple(unsigned Major, unsigned Minor) |
48 | : Major(Major), Minor(Minor), HasMinor(true), Subminor(0), |
49 | HasSubminor(false), Build(0), HasBuild(false) {} |
50 | |
51 | explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor) |
52 | : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), |
53 | HasSubminor(true), Build(0), HasBuild(false) {} |
54 | |
55 | explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, |
56 | unsigned Build) |
57 | : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), |
58 | HasSubminor(true), Build(Build), HasBuild(true) {} |
59 | |
60 | /// Determine whether this version information is empty |
61 | /// (e.g., all version components are zero). |
62 | bool empty() const { |
63 | return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0; |
64 | } |
65 | |
66 | /// Retrieve the major version number. |
67 | unsigned getMajor() const { return Major; } |
68 | |
69 | /// Retrieve the minor version number, if provided. |
70 | Optional<unsigned> getMinor() const { |
71 | if (!HasMinor) |
72 | return None; |
73 | return Minor; |
74 | } |
75 | |
76 | /// Retrieve the subminor version number, if provided. |
77 | Optional<unsigned> getSubminor() const { |
78 | if (!HasSubminor) |
79 | return None; |
80 | return Subminor; |
81 | } |
82 | |
83 | /// Retrieve the build version number, if provided. |
84 | Optional<unsigned> getBuild() const { |
85 | if (!HasBuild) |
86 | return None; |
87 | return Build; |
88 | } |
89 | |
90 | /// Return a version tuple that contains only the first 3 version components. |
91 | VersionTuple withoutBuild() const { |
92 | if (HasBuild) |
93 | return VersionTuple(Major, Minor, Subminor); |
94 | return *this; |
95 | } |
96 | |
97 | /// Determine if two version numbers are equivalent. If not |
98 | /// provided, minor and subminor version numbers are considered to be zero. |
99 | friend bool operator==(const VersionTuple &X, const VersionTuple &Y) { |
100 | return X.Major == Y.Major && X.Minor == Y.Minor && |
101 | X.Subminor == Y.Subminor && X.Build == Y.Build; |
102 | } |
103 | |
104 | /// Determine if two version numbers are not equivalent. |
105 | /// |
106 | /// If not provided, minor and subminor version numbers are considered to be |
107 | /// zero. |
108 | friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) { |
109 | return !(X == Y); |
110 | } |
111 | |
112 | /// Determine whether one version number precedes another. |
113 | /// |
114 | /// If not provided, minor and subminor version numbers are considered to be |
115 | /// zero. |
116 | friend bool operator<(const VersionTuple &X, const VersionTuple &Y) { |
117 | return std::tie(X.Major, X.Minor, X.Subminor, X.Build) < |
118 | std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build); |
119 | } |
120 | |
121 | /// Determine whether one version number follows another. |
122 | /// |
123 | /// If not provided, minor and subminor version numbers are considered to be |
124 | /// zero. |
125 | friend bool operator>(const VersionTuple &X, const VersionTuple &Y) { |
126 | return Y < X; |
127 | } |
128 | |
129 | /// Determine whether one version number precedes or is |
130 | /// equivalent to another. |
131 | /// |
132 | /// If not provided, minor and subminor version numbers are considered to be |
133 | /// zero. |
134 | friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) { |
135 | return !(Y < X); |
136 | } |
137 | |
138 | /// Determine whether one version number follows or is |
139 | /// equivalent to another. |
140 | /// |
141 | /// If not provided, minor and subminor version numbers are considered to be |
142 | /// zero. |
143 | friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) { |
144 | return !(X < Y); |
145 | } |
146 | |
147 | /// Retrieve a string representation of the version number. |
148 | std::string getAsString() const; |
149 | |
150 | /// Try to parse the given string as a version number. |
151 | /// \returns \c true if the string does not match the regular expression |
152 | /// [0-9]+(\.[0-9]+){0,3} |
153 | bool tryParse(StringRef string); |
154 | }; |
155 | |
156 | /// Print a version number. |
157 | raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V); |
158 | |
159 | } // end namespace llvm |
160 | #endif // LLVM_SUPPORT_VERSIONTUPLE_H |
1 | // <tuple> -*- C++ -*- |
2 | |
3 | // Copyright (C) 2007-2016 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/tuple |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | #ifndef _GLIBCXX_TUPLE1 |
30 | #define _GLIBCXX_TUPLE1 1 |
31 | |
32 | #pragma GCC system_header |
33 | |
34 | #if __cplusplus201402L < 201103L |
35 | # include <bits/c++0x_warning.h> |
36 | #else |
37 | |
38 | #include <utility> |
39 | #include <array> |
40 | #include <bits/uses_allocator.h> |
41 | |
42 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
43 | { |
44 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
45 | |
46 | /** |
47 | * @addtogroup utilities |
48 | * @{ |
49 | */ |
50 | |
51 | template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal> |
52 | struct _Head_base; |
53 | |
54 | template<std::size_t _Idx, typename _Head> |
55 | struct _Head_base<_Idx, _Head, true> |
56 | : public _Head |
57 | { |
58 | constexpr _Head_base() |
59 | : _Head() { } |
60 | |
61 | constexpr _Head_base(const _Head& __h) |
62 | : _Head(__h) { } |
63 | |
64 | constexpr _Head_base(const _Head_base&) = default; |
65 | constexpr _Head_base(_Head_base&&) = default; |
66 | |
67 | template<typename _UHead> |
68 | constexpr _Head_base(_UHead&& __h) |
69 | : _Head(std::forward<_UHead>(__h)) { } |
70 | |
71 | _Head_base(allocator_arg_t, __uses_alloc0) |
72 | : _Head() { } |
73 | |
74 | template<typename _Alloc> |
75 | _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) |
76 | : _Head(allocator_arg, *__a._M_a) { } |
77 | |
78 | template<typename _Alloc> |
79 | _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) |
80 | : _Head(*__a._M_a) { } |
81 | |
82 | template<typename _UHead> |
83 | _Head_base(__uses_alloc0, _UHead&& __uhead) |
84 | : _Head(std::forward<_UHead>(__uhead)) { } |
85 | |
86 | template<typename _Alloc, typename _UHead> |
87 | _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) |
88 | : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } |
89 | |
90 | template<typename _Alloc, typename _UHead> |
91 | _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) |
92 | : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } |
93 | |
94 | static constexpr _Head& |
95 | _M_head(_Head_base& __b) noexcept { return __b; } |
96 | |
97 | static constexpr const _Head& |
98 | _M_head(const _Head_base& __b) noexcept { return __b; } |
99 | }; |
100 | |
101 | template<std::size_t _Idx, typename _Head> |
102 | struct _Head_base<_Idx, _Head, false> |
103 | { |
104 | constexpr _Head_base() |
105 | : _M_head_impl() { } |
106 | |
107 | constexpr _Head_base(const _Head& __h) |
108 | : _M_head_impl(__h) { } |
109 | |
110 | constexpr _Head_base(const _Head_base&) = default; |
111 | constexpr _Head_base(_Head_base&&) = default; |
112 | |
113 | template<typename _UHead> |
114 | constexpr _Head_base(_UHead&& __h) |
115 | : _M_head_impl(std::forward<_UHead>(__h)) { } |
116 | |
117 | _Head_base(allocator_arg_t, __uses_alloc0) |
118 | : _M_head_impl() { } |
119 | |
120 | template<typename _Alloc> |
121 | _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) |
122 | : _M_head_impl(allocator_arg, *__a._M_a) { } |
123 | |
124 | template<typename _Alloc> |
125 | _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) |
126 | : _M_head_impl(*__a._M_a) { } |
127 | |
128 | template<typename _UHead> |
129 | _Head_base(__uses_alloc0, _UHead&& __uhead) |
130 | : _M_head_impl(std::forward<_UHead>(__uhead)) { } |
131 | |
132 | template<typename _Alloc, typename _UHead> |
133 | _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) |
134 | : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) |
135 | { } |
136 | |
137 | template<typename _Alloc, typename _UHead> |
138 | _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) |
139 | : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } |
140 | |
141 | static constexpr _Head& |
142 | _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } |
143 | |
144 | static constexpr const _Head& |
145 | _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } |
146 | |
147 | _Head _M_head_impl; |
148 | }; |
149 | |
150 | /** |
151 | * Contains the actual implementation of the @c tuple template, stored |
152 | * as a recursive inheritance hierarchy from the first element (most |
153 | * derived class) to the last (least derived class). The @c Idx |
154 | * parameter gives the 0-based index of the element stored at this |
155 | * point in the hierarchy; we use it to implement a constant-time |
156 | * get() operation. |
157 | */ |
158 | template<std::size_t _Idx, typename... _Elements> |
159 | struct _Tuple_impl; |
160 | |
161 | template<typename _Tp> |
162 | struct __is_empty_non_tuple : is_empty<_Tp> { }; |
163 | |
164 | // Using EBO for elements that are tuples causes ambiguous base errors. |
165 | template<typename _El0, typename... _El> |
166 | struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; |
167 | |
168 | // Use the Empty Base-class Optimization for empty, non-final types. |
169 | template<typename _Tp> |
170 | using __empty_not_final |
171 | = typename conditional<__is_final(_Tp), false_type, |
172 | __is_empty_non_tuple<_Tp>>::type; |
173 | |
174 | /** |
175 | * Recursive tuple implementation. Here we store the @c Head element |
176 | * and derive from a @c Tuple_impl containing the remaining elements |
177 | * (which contains the @c Tail). |
178 | */ |
179 | template<std::size_t _Idx, typename _Head, typename... _Tail> |
180 | struct _Tuple_impl<_Idx, _Head, _Tail...> |
181 | : public _Tuple_impl<_Idx + 1, _Tail...>, |
182 | private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> |
183 | { |
184 | template<std::size_t, typename...> friend class _Tuple_impl; |
185 | |
186 | typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; |
187 | typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; |
188 | |
189 | static constexpr _Head& |
190 | _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
191 | |
192 | static constexpr const _Head& |
193 | _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
194 | |
195 | static constexpr _Inherited& |
196 | _M_tail(_Tuple_impl& __t) noexcept { return __t; } |
197 | |
198 | static constexpr const _Inherited& |
199 | _M_tail(const _Tuple_impl& __t) noexcept { return __t; } |
200 | |
201 | constexpr _Tuple_impl() |
202 | : _Inherited(), _Base() { } |
203 | |
204 | explicit |
205 | constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) |
206 | : _Inherited(__tail...), _Base(__head) { } |
207 | |
208 | template<typename _UHead, typename... _UTail, typename = typename |
209 | enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> |
210 | explicit |
211 | constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) |
212 | : _Inherited(std::forward<_UTail>(__tail)...), |
213 | _Base(std::forward<_UHead>(__head)) { } |
214 | |
215 | constexpr _Tuple_impl(const _Tuple_impl&) = default; |
216 | |
217 | constexpr |
218 | _Tuple_impl(_Tuple_impl&& __in) |
219 | noexcept(__and_<is_nothrow_move_constructible<_Head>, |
220 | is_nothrow_move_constructible<_Inherited>>::value) |
221 | : _Inherited(std::move(_M_tail(__in))), |
222 | _Base(std::forward<_Head>(_M_head(__in))) { } |
223 | |
224 | template<typename... _UElements> |
225 | constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) |
226 | : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), |
227 | _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } |
228 | |
229 | template<typename _UHead, typename... _UTails> |
230 | constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
231 | : _Inherited(std::move |
232 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), |
233 | _Base(std::forward<_UHead> |
234 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } |
235 | |
236 | template<typename _Alloc> |
237 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) |
238 | : _Inherited(__tag, __a), |
239 | _Base(__tag, __use_alloc<_Head>(__a)) { } |
240 | |
241 | template<typename _Alloc> |
242 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
243 | const _Head& __head, const _Tail&... __tail) |
244 | : _Inherited(__tag, __a, __tail...), |
245 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } |
246 | |
247 | template<typename _Alloc, typename _UHead, typename... _UTail, |
248 | typename = typename enable_if<sizeof...(_Tail) |
249 | == sizeof...(_UTail)>::type> |
250 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
251 | _UHead&& __head, _UTail&&... __tail) |
252 | : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), |
253 | _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
254 | std::forward<_UHead>(__head)) { } |
255 | |
256 | template<typename _Alloc> |
257 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
258 | const _Tuple_impl& __in) |
259 | : _Inherited(__tag, __a, _M_tail(__in)), |
260 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } |
261 | |
262 | template<typename _Alloc> |
263 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
264 | _Tuple_impl&& __in) |
265 | : _Inherited(__tag, __a, std::move(_M_tail(__in))), |
266 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
267 | std::forward<_Head>(_M_head(__in))) { } |
268 | |
269 | template<typename _Alloc, typename... _UElements> |
270 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
271 | const _Tuple_impl<_Idx, _UElements...>& __in) |
272 | : _Inherited(__tag, __a, |
273 | _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), |
274 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
275 | _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } |
276 | |
277 | template<typename _Alloc, typename _UHead, typename... _UTails> |
278 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
279 | _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
280 | : _Inherited(__tag, __a, std::move |
281 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), |
282 | _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
283 | std::forward<_UHead> |
284 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } |
285 | |
286 | _Tuple_impl& |
287 | operator=(const _Tuple_impl& __in) |
288 | { |
289 | _M_head(*this) = _M_head(__in); |
290 | _M_tail(*this) = _M_tail(__in); |
291 | return *this; |
292 | } |
293 | |
294 | _Tuple_impl& |
295 | operator=(_Tuple_impl&& __in) |
296 | noexcept(__and_<is_nothrow_move_assignable<_Head>, |
297 | is_nothrow_move_assignable<_Inherited>>::value) |
298 | { |
299 | _M_head(*this) = std::forward<_Head>(_M_head(__in)); |
300 | _M_tail(*this) = std::move(_M_tail(__in)); |
301 | return *this; |
302 | } |
303 | |
304 | template<typename... _UElements> |
305 | _Tuple_impl& |
306 | operator=(const _Tuple_impl<_Idx, _UElements...>& __in) |
307 | { |
308 | _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); |
309 | _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); |
310 | return *this; |
311 | } |
312 | |
313 | template<typename _UHead, typename... _UTails> |
314 | _Tuple_impl& |
315 | operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
316 | { |
317 | _M_head(*this) = std::forward<_UHead> |
318 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); |
319 | _M_tail(*this) = std::move |
320 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); |
321 | return *this; |
322 | } |
323 | |
324 | protected: |
325 | void |
326 | _M_swap(_Tuple_impl& __in) |
327 | noexcept(__is_nothrow_swappable<_Head>::value |
328 | && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) |
329 | { |
330 | using std::swap; |
331 | swap(_M_head(*this), _M_head(__in)); |
332 | _Inherited::_M_swap(_M_tail(__in)); |
333 | } |
334 | }; |
335 | |
336 | // Basis case of inheritance recursion. |
337 | template<std::size_t _Idx, typename _Head> |
338 | struct _Tuple_impl<_Idx, _Head> |
339 | : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> |
340 | { |
341 | template<std::size_t, typename...> friend class _Tuple_impl; |
342 | |
343 | typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; |
344 | |
345 | static constexpr _Head& |
346 | _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
347 | |
348 | static constexpr const _Head& |
349 | _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
350 | |
351 | constexpr _Tuple_impl() |
352 | : _Base() { } |
353 | |
354 | explicit |
355 | constexpr _Tuple_impl(const _Head& __head) |
356 | : _Base(__head) { } |
357 | |
358 | template<typename _UHead> |
359 | explicit |
360 | constexpr _Tuple_impl(_UHead&& __head) |
361 | : _Base(std::forward<_UHead>(__head)) { } |
362 | |
363 | constexpr _Tuple_impl(const _Tuple_impl&) = default; |
364 | |
365 | constexpr |
366 | _Tuple_impl(_Tuple_impl&& __in) |
367 | noexcept(is_nothrow_move_constructible<_Head>::value) |
368 | : _Base(std::forward<_Head>(_M_head(__in))) { } |
369 | |
370 | template<typename _UHead> |
371 | constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) |
372 | : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } |
373 | |
374 | template<typename _UHead> |
375 | constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) |
376 | : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) |
377 | { } |
378 | |
379 | template<typename _Alloc> |
380 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) |
381 | : _Base(__tag, __use_alloc<_Head>(__a)) { } |
382 | |
383 | template<typename _Alloc> |
384 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
385 | const _Head& __head) |
386 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } |
387 | |
388 | template<typename _Alloc, typename _UHead> |
389 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
390 | _UHead&& __head) |
391 | : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
392 | std::forward<_UHead>(__head)) { } |
393 | |
394 | template<typename _Alloc> |
395 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
396 | const _Tuple_impl& __in) |
397 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } |
398 | |
399 | template<typename _Alloc> |
400 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
401 | _Tuple_impl&& __in) |
402 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
403 | std::forward<_Head>(_M_head(__in))) { } |
404 | |
405 | template<typename _Alloc, typename _UHead> |
406 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
407 | const _Tuple_impl<_Idx, _UHead>& __in) |
408 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
409 | _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } |
410 | |
411 | template<typename _Alloc, typename _UHead> |
412 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
413 | _Tuple_impl<_Idx, _UHead>&& __in) |
414 | : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
415 | std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) |
416 | { } |
417 | |
418 | _Tuple_impl& |
419 | operator=(const _Tuple_impl& __in) |
420 | { |
421 | _M_head(*this) = _M_head(__in); |
422 | return *this; |
423 | } |
424 | |
425 | _Tuple_impl& |
426 | operator=(_Tuple_impl&& __in) |
427 | noexcept(is_nothrow_move_assignable<_Head>::value) |
428 | { |
429 | _M_head(*this) = std::forward<_Head>(_M_head(__in)); |
430 | return *this; |
431 | } |
432 | |
433 | template<typename _UHead> |
434 | _Tuple_impl& |
435 | operator=(const _Tuple_impl<_Idx, _UHead>& __in) |
436 | { |
437 | _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); |
438 | return *this; |
439 | } |
440 | |
441 | template<typename _UHead> |
442 | _Tuple_impl& |
443 | operator=(_Tuple_impl<_Idx, _UHead>&& __in) |
444 | { |
445 | _M_head(*this) |
446 | = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); |
447 | return *this; |
448 | } |
449 | |
450 | protected: |
451 | void |
452 | _M_swap(_Tuple_impl& __in) |
453 | noexcept(__is_nothrow_swappable<_Head>::value) |
454 | { |
455 | using std::swap; |
456 | swap(_M_head(*this), _M_head(__in)); |
457 | } |
458 | }; |
459 | |
460 | template<typename... _Elements> |
461 | class tuple; |
462 | |
463 | // Concept utility functions, reused in conditionally-explicit |
464 | // constructors. |
465 | template<bool, typename... _Elements> |
466 | struct _TC |
467 | { |
468 | template<typename... _UElements> |
469 | static constexpr bool _ConstructibleTuple() |
470 | { |
471 | return __and_<is_constructible<_Elements, const _UElements&>...>::value; |
472 | } |
473 | |
474 | template<typename... _UElements> |
475 | static constexpr bool _ImplicitlyConvertibleTuple() |
476 | { |
477 | return __and_<is_convertible<const _UElements&, _Elements>...>::value; |
478 | } |
479 | |
480 | template<typename... _UElements> |
481 | static constexpr bool _MoveConstructibleTuple() |
482 | { |
483 | return __and_<is_constructible<_Elements, _UElements&&>...>::value; |
484 | } |
485 | |
486 | template<typename... _UElements> |
487 | static constexpr bool _ImplicitlyMoveConvertibleTuple() |
488 | { |
489 | return __and_<is_convertible<_UElements&&, _Elements>...>::value; |
490 | } |
491 | |
492 | template<typename _SrcTuple> |
493 | static constexpr bool _NonNestedTuple() |
494 | { |
495 | return __and_<__not_<is_same<tuple<_Elements...>, |
496 | typename remove_cv< |
497 | typename remove_reference<_SrcTuple>::type |
498 | >::type>>, |
499 | __not_<is_convertible<_SrcTuple, _Elements...>>, |
500 | __not_<is_constructible<_Elements..., _SrcTuple>> |
501 | >::value; |
502 | } |
503 | template<typename... _UElements> |
504 | static constexpr bool _NotSameTuple() |
505 | { |
506 | return __not_<is_same<tuple<_Elements...>, |
507 | typename remove_const< |
508 | typename remove_reference<_UElements...>::type |
509 | >::type>>::value; |
510 | } |
511 | }; |
512 | |
513 | template<typename... _Elements> |
514 | struct _TC<false, _Elements...> |
515 | { |
516 | template<typename... _UElements> |
517 | static constexpr bool _ConstructibleTuple() |
518 | { |
519 | return false; |
520 | } |
521 | |
522 | template<typename... _UElements> |
523 | static constexpr bool _ImplicitlyConvertibleTuple() |
524 | { |
525 | return false; |
526 | } |
527 | |
528 | template<typename... _UElements> |
529 | static constexpr bool _MoveConstructibleTuple() |
530 | { |
531 | return false; |
532 | } |
533 | |
534 | template<typename... _UElements> |
535 | static constexpr bool _ImplicitlyMoveConvertibleTuple() |
536 | { |
537 | return false; |
538 | } |
539 | |
540 | template<typename... _UElements> |
541 | static constexpr bool _NonNestedTuple() |
542 | { |
543 | return true; |
544 | } |
545 | template<typename... _UElements> |
546 | static constexpr bool _NotSameTuple() |
547 | { |
548 | return true; |
549 | } |
550 | }; |
551 | |
552 | /// Primary class template, tuple |
553 | template<typename... _Elements> |
554 | class tuple : public _Tuple_impl<0, _Elements...> |
555 | { |
556 | typedef _Tuple_impl<0, _Elements...> _Inherited; |
557 | |
558 | // Used for constraining the default constructor so |
559 | // that it becomes dependent on the constraints. |
560 | template<typename _Dummy> |
561 | struct _TC2 |
562 | { |
563 | static constexpr bool _DefaultConstructibleTuple() |
564 | { |
565 | return __and_<is_default_constructible<_Elements>...>::value; |
566 | } |
567 | static constexpr bool _ImplicitlyDefaultConstructibleTuple() |
568 | { |
569 | return __and_<__is_implicitly_default_constructible<_Elements>...> |
570 | ::value; |
571 | } |
572 | }; |
573 | |
574 | public: |
575 | template<typename _Dummy = void, |
576 | typename enable_if<_TC2<_Dummy>:: |
577 | _ImplicitlyDefaultConstructibleTuple(), |
578 | bool>::type = true> |
579 | constexpr tuple() |
580 | : _Inherited() { } |
581 | |
582 | template<typename _Dummy = void, |
583 | typename enable_if<_TC2<_Dummy>:: |
584 | _DefaultConstructibleTuple() |
585 | && |
586 | !_TC2<_Dummy>:: |
587 | _ImplicitlyDefaultConstructibleTuple(), |
588 | bool>::type = false> |
589 | explicit constexpr tuple() |
590 | : _Inherited() { } |
591 | |
592 | // Shortcut for the cases where constructors taking _Elements... |
593 | // need to be constrained. |
594 | template<typename _Dummy> using _TCC = |
595 | _TC<is_same<_Dummy, void>::value, |
596 | _Elements...>; |
597 | |
598 | template<typename _Dummy = void, |
599 | typename enable_if< |
600 | _TCC<_Dummy>::template |
601 | _ConstructibleTuple<_Elements...>() |
602 | && _TCC<_Dummy>::template |
603 | _ImplicitlyConvertibleTuple<_Elements...>() |
604 | && (sizeof...(_Elements) >= 1), |
605 | bool>::type=true> |
606 | constexpr tuple(const _Elements&... __elements) |
607 | : _Inherited(__elements...) { } |
608 | |
609 | template<typename _Dummy = void, |
610 | typename enable_if< |
611 | _TCC<_Dummy>::template |
612 | _ConstructibleTuple<_Elements...>() |
613 | && !_TCC<_Dummy>::template |
614 | _ImplicitlyConvertibleTuple<_Elements...>() |
615 | && (sizeof...(_Elements) >= 1), |
616 | bool>::type=false> |
617 | explicit constexpr tuple(const _Elements&... __elements) |
618 | : _Inherited(__elements...) { } |
619 | |
620 | // Shortcut for the cases where constructors taking _UElements... |
621 | // need to be constrained. |
622 | template<typename... _UElements> using _TMC = |
623 | _TC<(sizeof...(_Elements) == sizeof...(_UElements)), |
624 | _Elements...>; |
625 | |
626 | template<typename... _UElements, typename |
627 | enable_if< |
628 | _TC<sizeof...(_UElements) == 1, _Elements...>::template |
629 | _NotSameTuple<_UElements...>() |
630 | && _TMC<_UElements...>::template |
631 | _MoveConstructibleTuple<_UElements...>() |
632 | && _TMC<_UElements...>::template |
633 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
634 | && (sizeof...(_Elements) >= 1), |
635 | bool>::type=true> |
636 | constexpr tuple(_UElements&&... __elements) |
637 | : _Inherited(std::forward<_UElements>(__elements)...) { } |
638 | |
639 | template<typename... _UElements, typename |
640 | enable_if< |
641 | _TC<sizeof...(_UElements) == 1, _Elements...>::template |
642 | _NotSameTuple<_UElements...>() |
643 | && _TMC<_UElements...>::template |
644 | _MoveConstructibleTuple<_UElements...>() |
645 | && !_TMC<_UElements...>::template |
646 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
647 | && (sizeof...(_Elements) >= 1), |
648 | bool>::type=false> |
649 | explicit constexpr tuple(_UElements&&... __elements) |
650 | : _Inherited(std::forward<_UElements>(__elements)...) { } |
651 | |
652 | constexpr tuple(const tuple&) = default; |
653 | |
654 | constexpr tuple(tuple&&) = default; |
655 | |
656 | // Shortcut for the cases where constructors taking tuples |
657 | // must avoid creating temporaries. |
658 | template<typename _Dummy> using _TNTC = |
659 | _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1, |
660 | _Elements...>; |
661 | |
662 | template<typename... _UElements, typename _Dummy = void, typename |
663 | enable_if<_TMC<_UElements...>::template |
664 | _ConstructibleTuple<_UElements...>() |
665 | && _TMC<_UElements...>::template |
666 | _ImplicitlyConvertibleTuple<_UElements...>() |
667 | && _TNTC<_Dummy>::template |
668 | _NonNestedTuple<const tuple<_UElements...>&>(), |
669 | bool>::type=true> |
670 | constexpr tuple(const tuple<_UElements...>& __in) |
671 | : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
672 | { } |
673 | |
674 | template<typename... _UElements, typename _Dummy = void, typename |
675 | enable_if<_TMC<_UElements...>::template |
676 | _ConstructibleTuple<_UElements...>() |
677 | && !_TMC<_UElements...>::template |
678 | _ImplicitlyConvertibleTuple<_UElements...>() |
679 | && _TNTC<_Dummy>::template |
680 | _NonNestedTuple<const tuple<_UElements...>&>(), |
681 | bool>::type=false> |
682 | explicit constexpr tuple(const tuple<_UElements...>& __in) |
683 | : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
684 | { } |
685 | |
686 | template<typename... _UElements, typename _Dummy = void, typename |
687 | enable_if<_TMC<_UElements...>::template |
688 | _MoveConstructibleTuple<_UElements...>() |
689 | && _TMC<_UElements...>::template |
690 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
691 | && _TNTC<_Dummy>::template |
692 | _NonNestedTuple<tuple<_UElements...>&&>(), |
693 | bool>::type=true> |
694 | constexpr tuple(tuple<_UElements...>&& __in) |
695 | : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } |
696 | |
697 | template<typename... _UElements, typename _Dummy = void, typename |
698 | enable_if<_TMC<_UElements...>::template |
699 | _MoveConstructibleTuple<_UElements...>() |
700 | && !_TMC<_UElements...>::template |
701 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
702 | && _TNTC<_Dummy>::template |
703 | _NonNestedTuple<tuple<_UElements...>&&>(), |
704 | bool>::type=false> |
705 | explicit constexpr tuple(tuple<_UElements...>&& __in) |
706 | : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } |
707 | |
708 | // Allocator-extended constructors. |
709 | |
710 | template<typename _Alloc> |
711 | tuple(allocator_arg_t __tag, const _Alloc& __a) |
712 | : _Inherited(__tag, __a) { } |
713 | |
714 | template<typename _Alloc, typename _Dummy = void, |
715 | typename enable_if< |
716 | _TCC<_Dummy>::template |
717 | _ConstructibleTuple<_Elements...>() |
718 | && _TCC<_Dummy>::template |
719 | _ImplicitlyConvertibleTuple<_Elements...>(), |
720 | bool>::type=true> |
721 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
722 | const _Elements&... __elements) |
723 | : _Inherited(__tag, __a, __elements...) { } |
724 | |
725 | template<typename _Alloc, typename _Dummy = void, |
726 | typename enable_if< |
727 | _TCC<_Dummy>::template |
728 | _ConstructibleTuple<_Elements...>() |
729 | && !_TCC<_Dummy>::template |
730 | _ImplicitlyConvertibleTuple<_Elements...>(), |
731 | bool>::type=false> |
732 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
733 | const _Elements&... __elements) |
734 | : _Inherited(__tag, __a, __elements...) { } |
735 | |
736 | template<typename _Alloc, typename... _UElements, typename |
737 | enable_if<_TMC<_UElements...>::template |
738 | _MoveConstructibleTuple<_UElements...>() |
739 | && _TMC<_UElements...>::template |
740 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
741 | bool>::type=true> |
742 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
743 | _UElements&&... __elements) |
744 | : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) |
745 | { } |
746 | |
747 | template<typename _Alloc, typename... _UElements, typename |
748 | enable_if<_TMC<_UElements...>::template |
749 | _MoveConstructibleTuple<_UElements...>() |
750 | && !_TMC<_UElements...>::template |
751 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
752 | bool>::type=false> |
753 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
754 | _UElements&&... __elements) |
755 | : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) |
756 | { } |
757 | |
758 | template<typename _Alloc> |
759 | tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) |
760 | : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } |
761 | |
762 | template<typename _Alloc> |
763 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) |
764 | : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } |
765 | |
766 | template<typename _Alloc, typename... _UElements, typename |
767 | enable_if<_TMC<_UElements...>::template |
768 | _ConstructibleTuple<_UElements...>() |
769 | && _TMC<_UElements...>::template |
770 | _ImplicitlyConvertibleTuple<_UElements...>(), |
771 | bool>::type=true> |
772 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
773 | const tuple<_UElements...>& __in) |
774 | : _Inherited(__tag, __a, |
775 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
776 | { } |
777 | |
778 | template<typename _Alloc, typename... _UElements, typename |
779 | enable_if<_TMC<_UElements...>::template |
780 | _ConstructibleTuple<_UElements...>() |
781 | && !_TMC<_UElements...>::template |
782 | _ImplicitlyConvertibleTuple<_UElements...>(), |
783 | bool>::type=false> |
784 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
785 | const tuple<_UElements...>& __in) |
786 | : _Inherited(__tag, __a, |
787 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
788 | { } |
789 | |
790 | template<typename _Alloc, typename... _UElements, typename |
791 | enable_if<_TMC<_UElements...>::template |
792 | _MoveConstructibleTuple<_UElements...>() |
793 | && _TMC<_UElements...>::template |
794 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
795 | bool>::type=true> |
796 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
797 | tuple<_UElements...>&& __in) |
798 | : _Inherited(__tag, __a, |
799 | static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) |
800 | { } |
801 | |
802 | template<typename _Alloc, typename... _UElements, typename |
803 | enable_if<_TMC<_UElements...>::template |
804 | _MoveConstructibleTuple<_UElements...>() |
805 | && !_TMC<_UElements...>::template |
806 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
807 | bool>::type=false> |
808 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
809 | tuple<_UElements...>&& __in) |
810 | : _Inherited(__tag, __a, |
811 | static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) |
812 | { } |
813 | |
814 | tuple& |
815 | operator=(const tuple& __in) |
816 | { |
817 | static_cast<_Inherited&>(*this) = __in; |
818 | return *this; |
819 | } |
820 | |
821 | tuple& |
822 | operator=(tuple&& __in) |
823 | noexcept(is_nothrow_move_assignable<_Inherited>::value) |
824 | { |
825 | static_cast<_Inherited&>(*this) = std::move(__in); |
826 | return *this; |
827 | } |
828 | |
829 | template<typename... _UElements, typename = typename |
830 | enable_if<sizeof...(_UElements) |
831 | == sizeof...(_Elements)>::type> |
832 | tuple& |
833 | operator=(const tuple<_UElements...>& __in) |
834 | { |
835 | static_cast<_Inherited&>(*this) = __in; |
836 | return *this; |
837 | } |
838 | |
839 | template<typename... _UElements, typename = typename |
840 | enable_if<sizeof...(_UElements) |
841 | == sizeof...(_Elements)>::type> |
842 | tuple& |
843 | operator=(tuple<_UElements...>&& __in) |
844 | { |
845 | static_cast<_Inherited&>(*this) = std::move(__in); |
846 | return *this; |
847 | } |
848 | |
849 | void |
850 | swap(tuple& __in) |
851 | noexcept(noexcept(__in._M_swap(__in))) |
852 | { _Inherited::_M_swap(__in); } |
853 | }; |
854 | |
855 | // Explicit specialization, zero-element tuple. |
856 | template<> |
857 | class tuple<> |
858 | { |
859 | public: |
860 | void swap(tuple&) noexcept { /* no-op */ } |
861 | }; |
862 | |
863 | /// Partial specialization, 2-element tuple. |
864 | /// Includes construction and assignment from a pair. |
865 | template<typename _T1, typename _T2> |
866 | class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> |
867 | { |
868 | typedef _Tuple_impl<0, _T1, _T2> _Inherited; |
869 | |
870 | public: |
871 | template <typename _U1 = _T1, |
872 | typename _U2 = _T2, |
873 | typename enable_if<__and_< |
874 | __is_implicitly_default_constructible<_U1>, |
875 | __is_implicitly_default_constructible<_U2>> |
876 | ::value, bool>::type = true> |
877 | |
878 | constexpr tuple() |
879 | : _Inherited() { } |
880 | |
881 | template <typename _U1 = _T1, |
882 | typename _U2 = _T2, |
883 | typename enable_if< |
884 | __and_< |
885 | is_default_constructible<_U1>, |
886 | is_default_constructible<_U2>, |
887 | __not_< |
888 | __and_<__is_implicitly_default_constructible<_U1>, |
889 | __is_implicitly_default_constructible<_U2>>>> |
890 | ::value, bool>::type = false> |
891 | |
892 | explicit constexpr tuple() |
893 | : _Inherited() { } |
894 | |
895 | // Shortcut for the cases where constructors taking _T1, _T2 |
896 | // need to be constrained. |
897 | template<typename _Dummy> using _TCC = |
898 | _TC<is_same<_Dummy, void>::value, _T1, _T2>; |
899 | |
900 | template<typename _Dummy = void, typename |
901 | enable_if<_TCC<_Dummy>::template |
902 | _ConstructibleTuple<_T1, _T2>() |
903 | && _TCC<_Dummy>::template |
904 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
905 | bool>::type = true> |
906 | constexpr tuple(const _T1& __a1, const _T2& __a2) |
907 | : _Inherited(__a1, __a2) { } |
908 | |
909 | template<typename _Dummy = void, typename |
910 | enable_if<_TCC<_Dummy>::template |
911 | _ConstructibleTuple<_T1, _T2>() |
912 | && !_TCC<_Dummy>::template |
913 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
914 | bool>::type = false> |
915 | explicit constexpr tuple(const _T1& __a1, const _T2& __a2) |
916 | : _Inherited(__a1, __a2) { } |
917 | |
918 | // Shortcut for the cases where constructors taking _U1, _U2 |
919 | // need to be constrained. |
920 | using _TMC = _TC<true, _T1, _T2>; |
921 | |
922 | template<typename _U1, typename _U2, typename |
923 | enable_if<_TMC::template |
924 | _MoveConstructibleTuple<_U1, _U2>() |
925 | && _TMC::template |
926 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>() |
927 | && !is_same<typename decay<_U1>::type, |
928 | allocator_arg_t>::value, |
929 | bool>::type = true> |
930 | constexpr tuple(_U1&& __a1, _U2&& __a2) |
931 | : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } |
932 | |
933 | template<typename _U1, typename _U2, typename |
934 | enable_if<_TMC::template |
935 | _MoveConstructibleTuple<_U1, _U2>() |
936 | && !_TMC::template |
937 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>() |
938 | && !is_same<typename decay<_U1>::type, |
939 | allocator_arg_t>::value, |
940 | bool>::type = false> |
941 | explicit constexpr tuple(_U1&& __a1, _U2&& __a2) |
942 | : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } |
943 | |
944 | constexpr tuple(const tuple&) = default; |
945 | |
946 | constexpr tuple(tuple&&) = default; |
947 | |
948 | template<typename _U1, typename _U2, typename |
949 | enable_if<_TMC::template |
950 | _ConstructibleTuple<_U1, _U2>() |
951 | && _TMC::template |
952 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
953 | bool>::type = true> |
954 | constexpr tuple(const tuple<_U1, _U2>& __in) |
955 | : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } |
956 | |
957 | template<typename _U1, typename _U2, typename |
958 | enable_if<_TMC::template |
959 | _ConstructibleTuple<_U1, _U2>() |
960 | && !_TMC::template |
961 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
962 | bool>::type = false> |
963 | explicit constexpr tuple(const tuple<_U1, _U2>& __in) |
964 | : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } |
965 | |
966 | template<typename _U1, typename _U2, typename |
967 | enable_if<_TMC::template |
968 | _MoveConstructibleTuple<_U1, _U2>() |
969 | && _TMC::template |
970 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
971 | bool>::type = true> |
972 | constexpr tuple(tuple<_U1, _U2>&& __in) |
973 | : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } |
974 | |
975 | template<typename _U1, typename _U2, typename |
976 | enable_if<_TMC::template |
977 | _MoveConstructibleTuple<_U1, _U2>() |
978 | && !_TMC::template |
979 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
980 | bool>::type = false> |
981 | explicit constexpr tuple(tuple<_U1, _U2>&& __in) |
982 | : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } |
983 | |
984 | template<typename _U1, typename _U2, typename |
985 | enable_if<_TMC::template |
986 | _ConstructibleTuple<_U1, _U2>() |
987 | && _TMC::template |
988 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
989 | bool>::type = true> |
990 | constexpr tuple(const pair<_U1, _U2>& __in) |
991 | : _Inherited(__in.first, __in.second) { } |
992 | |
993 | template<typename _U1, typename _U2, typename |
994 | enable_if<_TMC::template |
995 | _ConstructibleTuple<_U1, _U2>() |
996 | && !_TMC::template |
997 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
998 | bool>::type = false> |
999 | explicit constexpr tuple(const pair<_U1, _U2>& __in) |
1000 | : _Inherited(__in.first, __in.second) { } |
1001 | |
1002 | template<typename _U1, typename _U2, typename |
1003 | enable_if<_TMC::template |
1004 | _MoveConstructibleTuple<_U1, _U2>() |
1005 | && _TMC::template |
1006 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1007 | bool>::type = true> |
1008 | constexpr tuple(pair<_U1, _U2>&& __in) |
1009 | : _Inherited(std::forward<_U1>(__in.first), |
1010 | std::forward<_U2>(__in.second)) { } |
1011 | |
1012 | template<typename _U1, typename _U2, typename |
1013 | enable_if<_TMC::template |
1014 | _MoveConstructibleTuple<_U1, _U2>() |
1015 | && !_TMC::template |
1016 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1017 | bool>::type = false> |
1018 | explicit constexpr tuple(pair<_U1, _U2>&& __in) |
1019 | : _Inherited(std::forward<_U1>(__in.first), |
1020 | std::forward<_U2>(__in.second)) { } |
1021 | |
1022 | // Allocator-extended constructors. |
1023 | |
1024 | template<typename _Alloc> |
1025 | tuple(allocator_arg_t __tag, const _Alloc& __a) |
1026 | : _Inherited(__tag, __a) { } |
1027 | |
1028 | template<typename _Alloc, typename _Dummy = void, |
1029 | typename enable_if< |
1030 | _TCC<_Dummy>::template |
1031 | _ConstructibleTuple<_T1, _T2>() |
1032 | && _TCC<_Dummy>::template |
1033 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
1034 | bool>::type=true> |
1035 | |
1036 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1037 | const _T1& __a1, const _T2& __a2) |
1038 | : _Inherited(__tag, __a, __a1, __a2) { } |
1039 | |
1040 | template<typename _Alloc, typename _Dummy = void, |
1041 | typename enable_if< |
1042 | _TCC<_Dummy>::template |
1043 | _ConstructibleTuple<_T1, _T2>() |
1044 | && !_TCC<_Dummy>::template |
1045 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
1046 | bool>::type=false> |
1047 | |
1048 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1049 | const _T1& __a1, const _T2& __a2) |
1050 | : _Inherited(__tag, __a, __a1, __a2) { } |
1051 | |
1052 | template<typename _Alloc, typename _U1, typename _U2, typename |
1053 | enable_if<_TMC::template |
1054 | _MoveConstructibleTuple<_U1, _U2>() |
1055 | && _TMC::template |
1056 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1057 | bool>::type = true> |
1058 | tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) |
1059 | : _Inherited(__tag, __a, std::forward<_U1>(__a1), |
1060 | std::forward<_U2>(__a2)) { } |
1061 | |
1062 | template<typename _Alloc, typename _U1, typename _U2, typename |
1063 | enable_if<_TMC::template |
1064 | _MoveConstructibleTuple<_U1, _U2>() |
1065 | && !_TMC::template |
1066 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1067 | bool>::type = false> |
1068 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1069 | _U1&& __a1, _U2&& __a2) |
1070 | : _Inherited(__tag, __a, std::forward<_U1>(__a1), |
1071 | std::forward<_U2>(__a2)) { } |
1072 | |
1073 | template<typename _Alloc> |
1074 | tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) |
1075 | : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } |
1076 | |
1077 | template<typename _Alloc> |
1078 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) |
1079 | : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } |
1080 | |
1081 | template<typename _Alloc, typename _U1, typename _U2, typename |
1082 | enable_if<_TMC::template |
1083 | _ConstructibleTuple<_U1, _U2>() |
1084 | && _TMC::template |
1085 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1086 | bool>::type = true> |
1087 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1088 | const tuple<_U1, _U2>& __in) |
1089 | : _Inherited(__tag, __a, |
1090 | static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) |
1091 | { } |
1092 | |
1093 | template<typename _Alloc, typename _U1, typename _U2, typename |
1094 | enable_if<_TMC::template |
1095 | _ConstructibleTuple<_U1, _U2>() |
1096 | && !_TMC::template |
1097 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1098 | bool>::type = false> |
1099 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1100 | const tuple<_U1, _U2>& __in) |
1101 | : _Inherited(__tag, __a, |
1102 | static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) |
1103 | { } |
1104 | |
1105 | template<typename _Alloc, typename _U1, typename _U2, typename |
1106 | enable_if<_TMC::template |
1107 | _MoveConstructibleTuple<_U1, _U2>() |
1108 | && _TMC::template |
1109 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1110 | bool>::type = true> |
1111 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) |
1112 | : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) |
1113 | { } |
1114 | |
1115 | template<typename _Alloc, typename _U1, typename _U2, typename |
1116 | enable_if<_TMC::template |
1117 | _MoveConstructibleTuple<_U1, _U2>() |
1118 | && !_TMC::template |
1119 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1120 | bool>::type = false> |
1121 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1122 | tuple<_U1, _U2>&& __in) |
1123 | : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) |
1124 | { } |
1125 | |
1126 | template<typename _Alloc, typename _U1, typename _U2, typename |
1127 | enable_if<_TMC::template |
1128 | _ConstructibleTuple<_U1, _U2>() |
1129 | && _TMC::template |
1130 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1131 | bool>::type = true> |
1132 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1133 | const pair<_U1, _U2>& __in) |
1134 | : _Inherited(__tag, __a, __in.first, __in.second) { } |
1135 | |
1136 | template<typename _Alloc, typename _U1, typename _U2, typename |
1137 | enable_if<_TMC::template |
1138 | _ConstructibleTuple<_U1, _U2>() |
1139 | && !_TMC::template |
1140 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1141 | bool>::type = false> |
1142 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1143 | const pair<_U1, _U2>& __in) |
1144 | : _Inherited(__tag, __a, __in.first, __in.second) { } |
1145 | |
1146 | template<typename _Alloc, typename _U1, typename _U2, typename |
1147 | enable_if<_TMC::template |
1148 | _MoveConstructibleTuple<_U1, _U2>() |
1149 | && _TMC::template |
1150 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1151 | bool>::type = true> |
1152 | tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) |
1153 | : _Inherited(__tag, __a, std::forward<_U1>(__in.first), |
1154 | std::forward<_U2>(__in.second)) { } |
1155 | |
1156 | template<typename _Alloc, typename _U1, typename _U2, typename |
1157 | enable_if<_TMC::template |
1158 | _MoveConstructibleTuple<_U1, _U2>() |
1159 | && !_TMC::template |
1160 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1161 | bool>::type = false> |
1162 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1163 | pair<_U1, _U2>&& __in) |
1164 | : _Inherited(__tag, __a, std::forward<_U1>(__in.first), |
1165 | std::forward<_U2>(__in.second)) { } |
1166 | |
1167 | tuple& |
1168 | operator=(const tuple& __in) |
1169 | { |
1170 | static_cast<_Inherited&>(*this) = __in; |
1171 | return *this; |
1172 | } |
1173 | |
1174 | tuple& |
1175 | operator=(tuple&& __in) |
1176 | noexcept(is_nothrow_move_assignable<_Inherited>::value) |
1177 | { |
1178 | static_cast<_Inherited&>(*this) = std::move(__in); |
1179 | return *this; |
1180 | } |
1181 | |
1182 | template<typename _U1, typename _U2> |
1183 | tuple& |
1184 | operator=(const tuple<_U1, _U2>& __in) |
1185 | { |
1186 | static_cast<_Inherited&>(*this) = __in; |
1187 | return *this; |
1188 | } |
1189 | |
1190 | template<typename _U1, typename _U2> |
1191 | tuple& |
1192 | operator=(tuple<_U1, _U2>&& __in) |
1193 | { |
1194 | static_cast<_Inherited&>(*this) = std::move(__in); |
1195 | return *this; |
1196 | } |
1197 | |
1198 | template<typename _U1, typename _U2> |
1199 | tuple& |
1200 | operator=(const pair<_U1, _U2>& __in) |
1201 | { |
1202 | this->_M_head(*this) = __in.first; |
1203 | this->_M_tail(*this)._M_head(*this) = __in.second; |
1204 | return *this; |
1205 | } |
1206 | |
1207 | template<typename _U1, typename _U2> |
1208 | tuple& |
1209 | operator=(pair<_U1, _U2>&& __in) |
1210 | { |
1211 | this->_M_head(*this) = std::forward<_U1>(__in.first); |
1212 | this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); |
1213 | return *this; |
1214 | } |
1215 | |
1216 | void |
1217 | swap(tuple& __in) |
1218 | noexcept(noexcept(__in._M_swap(__in))) |
1219 | { _Inherited::_M_swap(__in); } |
1220 | }; |
1221 | |
1222 | |
1223 | /** |
1224 | * Recursive case for tuple_element: strip off the first element in |
1225 | * the tuple and retrieve the (i-1)th element of the remaining tuple. |
1226 | */ |
1227 | template<std::size_t __i, typename _Head, typename... _Tail> |
1228 | struct tuple_element<__i, tuple<_Head, _Tail...> > |
1229 | : tuple_element<__i - 1, tuple<_Tail...> > { }; |
1230 | |
1231 | /** |
1232 | * Basis case for tuple_element: The first element is the one we're seeking. |
1233 | */ |
1234 | template<typename _Head, typename... _Tail> |
1235 | struct tuple_element<0, tuple<_Head, _Tail...> > |
1236 | { |
1237 | typedef _Head type; |
1238 | }; |
1239 | |
1240 | /// class tuple_size |
1241 | template<typename... _Elements> |
1242 | struct tuple_size<tuple<_Elements...>> |
1243 | : public integral_constant<std::size_t, sizeof...(_Elements)> { }; |
1244 | |
1245 | template<std::size_t __i, typename _Head, typename... _Tail> |
1246 | constexpr _Head& |
1247 | __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1248 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1249 | |
1250 | template<std::size_t __i, typename _Head, typename... _Tail> |
1251 | constexpr const _Head& |
1252 | __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1253 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1254 | |
1255 | /// Return a reference to the ith element of a tuple. |
1256 | template<std::size_t __i, typename... _Elements> |
1257 | constexpr __tuple_element_t<__i, tuple<_Elements...>>& |
1258 | get(tuple<_Elements...>& __t) noexcept |
1259 | { return std::__get_helper<__i>(__t); } |
1260 | |
1261 | /// Return a const reference to the ith element of a const tuple. |
1262 | template<std::size_t __i, typename... _Elements> |
1263 | constexpr const __tuple_element_t<__i, tuple<_Elements...>>& |
1264 | get(const tuple<_Elements...>& __t) noexcept |
1265 | { return std::__get_helper<__i>(__t); } |
1266 | |
1267 | /// Return an rvalue reference to the ith element of a tuple rvalue. |
1268 | template<std::size_t __i, typename... _Elements> |
1269 | constexpr __tuple_element_t<__i, tuple<_Elements...>>&& |
1270 | get(tuple<_Elements...>&& __t) noexcept |
1271 | { |
1272 | typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; |
1273 | return std::forward<__element_type&&>(std::get<__i>(__t)); |
1274 | } |
1275 | |
1276 | #if __cplusplus201402L > 201103L |
1277 | |
1278 | #define __cpp_lib_tuples_by_type201304 201304 |
1279 | |
1280 | template<typename _Head, size_t __i, typename... _Tail> |
1281 | constexpr _Head& |
1282 | __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1283 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1284 | |
1285 | template<typename _Head, size_t __i, typename... _Tail> |
1286 | constexpr const _Head& |
1287 | __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1288 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1289 | |
1290 | /// Return a reference to the unique element of type _Tp of a tuple. |
1291 | template <typename _Tp, typename... _Types> |
1292 | constexpr _Tp& |
1293 | get(tuple<_Types...>& __t) noexcept |
1294 | { return std::__get_helper2<_Tp>(__t); } |
1295 | |
1296 | /// Return a reference to the unique element of type _Tp of a tuple rvalue. |
1297 | template <typename _Tp, typename... _Types> |
1298 | constexpr _Tp&& |
1299 | get(tuple<_Types...>&& __t) noexcept |
1300 | { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } |
1301 | |
1302 | /// Return a const reference to the unique element of type _Tp of a tuple. |
1303 | template <typename _Tp, typename... _Types> |
1304 | constexpr const _Tp& |
1305 | get(const tuple<_Types...>& __t) noexcept |
1306 | { return std::__get_helper2<_Tp>(__t); } |
1307 | #endif |
1308 | |
1309 | // This class performs the comparison operations on tuples |
1310 | template<typename _Tp, typename _Up, size_t __i, size_t __size> |
1311 | struct __tuple_compare |
1312 | { |
1313 | static constexpr bool |
1314 | __eq(const _Tp& __t, const _Up& __u) |
1315 | { |
1316 | return bool(std::get<__i>(__t) == std::get<__i>(__u)) |
1317 | && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); |
1318 | } |
1319 | |
1320 | static constexpr bool |
1321 | __less(const _Tp& __t, const _Up& __u) |
1322 | { |
1323 | return bool(std::get<__i>(__t) < std::get<__i>(__u)) |
1324 | || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) |
1325 | && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); |
1326 | } |
1327 | }; |
1328 | |
1329 | template<typename _Tp, typename _Up, size_t __size> |
1330 | struct __tuple_compare<_Tp, _Up, __size, __size> |
1331 | { |
1332 | static constexpr bool |
1333 | __eq(const _Tp&, const _Up&) { return true; } |
1334 | |
1335 | static constexpr bool |
1336 | __less(const _Tp&, const _Up&) { return false; } |
1337 | }; |
1338 | |
1339 | template<typename... _TElements, typename... _UElements> |
1340 | constexpr bool |
1341 | operator==(const tuple<_TElements...>& __t, |
1342 | const tuple<_UElements...>& __u) |
1343 | { |
1344 | static_assert(sizeof...(_TElements) == sizeof...(_UElements), |
1345 | "tuple objects can only be compared if they have equal sizes."); |
1346 | using __compare = __tuple_compare<tuple<_TElements...>, |
1347 | tuple<_UElements...>, |
1348 | 0, sizeof...(_TElements)>; |
1349 | return __compare::__eq(__t, __u); |
1350 | } |
1351 | |
1352 | template<typename... _TElements, typename... _UElements> |
1353 | constexpr bool |
1354 | operator<(const tuple<_TElements...>& __t, |
1355 | const tuple<_UElements...>& __u) |
1356 | { |
1357 | static_assert(sizeof...(_TElements) == sizeof...(_UElements), |
1358 | "tuple objects can only be compared if they have equal sizes."); |
1359 | using __compare = __tuple_compare<tuple<_TElements...>, |
1360 | tuple<_UElements...>, |
1361 | 0, sizeof...(_TElements)>; |
1362 | return __compare::__less(__t, __u); |
1363 | } |
1364 | |
1365 | template<typename... _TElements, typename... _UElements> |
1366 | constexpr bool |
1367 | operator!=(const tuple<_TElements...>& __t, |
1368 | const tuple<_UElements...>& __u) |
1369 | { return !(__t == __u); } |
1370 | |
1371 | template<typename... _TElements, typename... _UElements> |
1372 | constexpr bool |
1373 | operator>(const tuple<_TElements...>& __t, |
1374 | const tuple<_UElements...>& __u) |
1375 | { return __u < __t; } |
1376 | |
1377 | template<typename... _TElements, typename... _UElements> |
1378 | constexpr bool |
1379 | operator<=(const tuple<_TElements...>& __t, |
1380 | const tuple<_UElements...>& __u) |
1381 | { return !(__u < __t); } |
1382 | |
1383 | template<typename... _TElements, typename... _UElements> |
1384 | constexpr bool |
1385 | operator>=(const tuple<_TElements...>& __t, |
1386 | const tuple<_UElements...>& __u) |
1387 | { return !(__t < __u); } |
1388 | |
1389 | // NB: DR 705. |
1390 | template<typename... _Elements> |
1391 | constexpr tuple<typename __decay_and_strip<_Elements>::__type...> |
1392 | make_tuple(_Elements&&... __args) |
1393 | { |
1394 | typedef tuple<typename __decay_and_strip<_Elements>::__type...> |
1395 | __result_type; |
1396 | return __result_type(std::forward<_Elements>(__args)...); |
1397 | } |
1398 | |
1399 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1400 | // 2275. Why is forward_as_tuple not constexpr? |
1401 | template<typename... _Elements> |
1402 | constexpr tuple<_Elements&&...> |
1403 | forward_as_tuple(_Elements&&... __args) noexcept |
1404 | { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } |
1405 | |
1406 | template<typename... _Tps> |
1407 | struct __is_tuple_like_impl<tuple<_Tps...>> : true_type |
1408 | { }; |
1409 | |
1410 | // Internal type trait that allows us to sfinae-protect tuple_cat. |
1411 | template<typename _Tp> |
1412 | struct __is_tuple_like |
1413 | : public __is_tuple_like_impl<typename std::remove_cv |
1414 | <typename std::remove_reference<_Tp>::type>::type>::type |
1415 | { }; |
1416 | |
1417 | template<size_t, typename, typename, size_t> |
1418 | struct __make_tuple_impl; |
1419 | |
1420 | template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> |
1421 | struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> |
1422 | : __make_tuple_impl<_Idx + 1, |
1423 | tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, |
1424 | _Tuple, _Nm> |
1425 | { }; |
1426 | |
1427 | template<std::size_t _Nm, typename _Tuple, typename... _Tp> |
1428 | struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> |
1429 | { |
1430 | typedef tuple<_Tp...> __type; |
1431 | }; |
1432 | |
1433 | template<typename _Tuple> |
1434 | struct __do_make_tuple |
1435 | : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> |
1436 | { }; |
1437 | |
1438 | // Returns the std::tuple equivalent of a tuple-like type. |
1439 | template<typename _Tuple> |
1440 | struct __make_tuple |
1441 | : public __do_make_tuple<typename std::remove_cv |
1442 | <typename std::remove_reference<_Tuple>::type>::type> |
1443 | { }; |
1444 | |
1445 | // Combines several std::tuple's into a single one. |
1446 | template<typename...> |
1447 | struct __combine_tuples; |
1448 | |
1449 | template<> |
1450 | struct __combine_tuples<> |
1451 | { |
1452 | typedef tuple<> __type; |
1453 | }; |
1454 | |
1455 | template<typename... _Ts> |
1456 | struct __combine_tuples<tuple<_Ts...>> |
1457 | { |
1458 | typedef tuple<_Ts...> __type; |
1459 | }; |
1460 | |
1461 | template<typename... _T1s, typename... _T2s, typename... _Rem> |
1462 | struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> |
1463 | { |
1464 | typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, |
1465 | _Rem...>::__type __type; |
1466 | }; |
1467 | |
1468 | // Computes the result type of tuple_cat given a set of tuple-like types. |
1469 | template<typename... _Tpls> |
1470 | struct __tuple_cat_result |
1471 | { |
1472 | typedef typename __combine_tuples |
1473 | <typename __make_tuple<_Tpls>::__type...>::__type __type; |
1474 | }; |
1475 | |
1476 | // Helper to determine the index set for the first tuple-like |
1477 | // type of a given set. |
1478 | template<typename...> |
1479 | struct __make_1st_indices; |
1480 | |
1481 | template<> |
1482 | struct __make_1st_indices<> |
1483 | { |
1484 | typedef std::_Index_tuple<> __type; |
1485 | }; |
1486 | |
1487 | template<typename _Tp, typename... _Tpls> |
1488 | struct __make_1st_indices<_Tp, _Tpls...> |
1489 | { |
1490 | typedef typename std::_Build_index_tuple<std::tuple_size< |
1491 | typename std::remove_reference<_Tp>::type>::value>::__type __type; |
1492 | }; |
1493 | |
1494 | // Performs the actual concatenation by step-wise expanding tuple-like |
1495 | // objects into the elements, which are finally forwarded into the |
1496 | // result tuple. |
1497 | template<typename _Ret, typename _Indices, typename... _Tpls> |
1498 | struct __tuple_concater; |
1499 | |
1500 | template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> |
1501 | struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> |
1502 | { |
1503 | template<typename... _Us> |
1504 | static constexpr _Ret |
1505 | _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) |
1506 | { |
1507 | typedef typename __make_1st_indices<_Tpls...>::__type __idx; |
1508 | typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; |
1509 | return __next::_S_do(std::forward<_Tpls>(__tps)..., |
1510 | std::forward<_Us>(__us)..., |
1511 | std::get<_Is>(std::forward<_Tp>(__tp))...); |
1512 | } |
1513 | }; |
1514 | |
1515 | template<typename _Ret> |
1516 | struct __tuple_concater<_Ret, std::_Index_tuple<>> |
1517 | { |
1518 | template<typename... _Us> |
1519 | static constexpr _Ret |
1520 | _S_do(_Us&&... __us) |
1521 | { |
1522 | return _Ret(std::forward<_Us>(__us)...); |
1523 | } |
1524 | }; |
1525 | |
1526 | /// tuple_cat |
1527 | template<typename... _Tpls, typename = typename |
1528 | enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> |
1529 | constexpr auto |
1530 | tuple_cat(_Tpls&&... __tpls) |
1531 | -> typename __tuple_cat_result<_Tpls...>::__type |
1532 | { |
1533 | typedef typename __tuple_cat_result<_Tpls...>::__type __ret; |
1534 | typedef typename __make_1st_indices<_Tpls...>::__type __idx; |
1535 | typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; |
1536 | return __concater::_S_do(std::forward<_Tpls>(__tpls)...); |
1537 | } |
1538 | |
1539 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1540 | // 2301. Why is tie not constexpr? |
1541 | /// tie |
1542 | template<typename... _Elements> |
1543 | constexpr tuple<_Elements&...> |
1544 | tie(_Elements&... __args) noexcept |
1545 | { return tuple<_Elements&...>(__args...); } |
1546 | |
1547 | /// swap |
1548 | template<typename... _Elements> |
1549 | inline void |
1550 | swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) |
1551 | noexcept(noexcept(__x.swap(__y))) |
1552 | { __x.swap(__y); } |
1553 | |
1554 | // A class (and instance) which can be used in 'tie' when an element |
1555 | // of a tuple is not required |
1556 | struct _Swallow_assign |
1557 | { |
1558 | template<class _Tp> |
1559 | const _Swallow_assign& |
1560 | operator=(const _Tp&) const |
1561 | { return *this; } |
1562 | }; |
1563 | |
1564 | const _Swallow_assign ignore{}; |
1565 | |
1566 | /// Partial specialization for tuples |
1567 | template<typename... _Types, typename _Alloc> |
1568 | struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; |
1569 | |
1570 | // See stl_pair.h... |
1571 | template<class _T1, class _T2> |
1572 | template<typename... _Args1, typename... _Args2> |
1573 | inline |
1574 | pair<_T1, _T2>:: |
1575 | pair(piecewise_construct_t, |
1576 | tuple<_Args1...> __first, tuple<_Args2...> __second) |
1577 | : pair(__first, __second, |
1578 | typename _Build_index_tuple<sizeof...(_Args1)>::__type(), |
1579 | typename _Build_index_tuple<sizeof...(_Args2)>::__type()) |
1580 | { } |
1581 | |
1582 | template<class _T1, class _T2> |
1583 | template<typename... _Args1, std::size_t... _Indexes1, |
1584 | typename... _Args2, std::size_t... _Indexes2> |
1585 | inline |
1586 | pair<_T1, _T2>:: |
1587 | pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, |
1588 | _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) |
1589 | : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), |
1590 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) |
1591 | { } |
1592 | |
1593 | /// @} |
1594 | |
1595 | _GLIBCXX_END_NAMESPACE_VERSION |
1596 | } // namespace std |
1597 | |
1598 | #endif // C++11 |
1599 | |
1600 | #endif // _GLIBCXX_TUPLE |