/Volumes/compiler/apple/swift/lib/SIL/IR/SILDeclRef.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- SILDeclRef.cpp - Implements SILDeclRef ---------------------------===// |
2 | | // |
3 | | // This source file is part of the Swift.org open source project |
4 | | // |
5 | | // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
6 | | // Licensed under Apache License v2.0 with Runtime Library Exception |
7 | | // |
8 | | // See https://swift.org/LICENSE.txt for license information |
9 | | // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "swift/SIL/SILDeclRef.h" |
14 | | #include "swift/AST/ASTContext.h" |
15 | | #include "swift/AST/ASTMangler.h" |
16 | | #include "swift/AST/AnyFunctionRef.h" |
17 | | #include "swift/AST/Initializer.h" |
18 | | #include "swift/AST/ParameterList.h" |
19 | | #include "swift/AST/PropertyWrappers.h" |
20 | | #include "swift/AST/SourceFile.h" |
21 | | #include "swift/ClangImporter/ClangImporter.h" |
22 | | #include "swift/ClangImporter/ClangModule.h" |
23 | | #include "swift/SIL/SILLinkage.h" |
24 | | #include "swift/SIL/SILLocation.h" |
25 | | #include "swift/SILOptimizer/Utils/SpecializationMangler.h" |
26 | | #include "clang/AST/ASTContext.h" |
27 | | #include "clang/AST/Attr.h" |
28 | | #include "clang/AST/Decl.h" |
29 | | #include "clang/AST/DeclCXX.h" |
30 | | #include "clang/AST/DeclObjC.h" |
31 | | #include "clang/AST/Mangle.h" |
32 | | #include "llvm/Support/Compiler.h" |
33 | | #include "llvm/Support/raw_ostream.h" |
34 | | using namespace swift; |
35 | | |
36 | | /// Get the method dispatch mechanism for a method. |
37 | | MethodDispatch |
38 | 1.59M | swift::getMethodDispatch(AbstractFunctionDecl *method) { |
39 | | // Some methods are forced to be statically dispatched. |
40 | 1.59M | if (method->hasForcedStaticDispatch()) |
41 | 0 | return MethodDispatch::Static; |
42 | | |
43 | 1.59M | if (method->getAttrs().hasAttribute<DistributedActorAttr>()) |
44 | 618 | return MethodDispatch::Static; |
45 | | |
46 | | // Import-as-member declarations are always statically referenced. |
47 | 1.59M | if (method->isImportAsMember()) |
48 | 2.36k | return MethodDispatch::Static; |
49 | | |
50 | 1.59M | auto dc = method->getDeclContext(); |
51 | | |
52 | 1.59M | if (dc->getSelfClassDecl()) { |
53 | 75.5k | if (method->shouldUseObjCDispatch()) { |
54 | 13.2k | return MethodDispatch::Class; |
55 | 13.2k | } |
56 | | |
57 | | // Final methods can be statically referenced. |
58 | 62.3k | if (method->isFinal()) |
59 | 17.0k | return MethodDispatch::Static; |
60 | | |
61 | | // Imported class methods are dynamically dispatched. |
62 | 45.3k | if (method->isObjC() && method->hasClangNode()) |
63 | 0 | return MethodDispatch::Class; |
64 | | |
65 | | // Members defined directly inside a class are dynamically dispatched. |
66 | 45.3k | if (isa<ClassDecl>(dc)) { |
67 | | // Native convenience initializers are not dynamically dispatched unless |
68 | | // required. |
69 | 42.4k | if (auto ctor = dyn_cast<ConstructorDecl>(method)) { |
70 | 23.8k | if (!ctor->isRequired() && !ctor->isDesignatedInit() |
71 | 23.8k | && !requiresForeignEntryPoint(ctor)) |
72 | 2.35k | return MethodDispatch::Static; |
73 | 23.8k | } |
74 | 40.0k | return MethodDispatch::Class; |
75 | 42.4k | } |
76 | 45.3k | } |
77 | | |
78 | | // Otherwise, it can be referenced statically. |
79 | 1.52M | return MethodDispatch::Static; |
80 | 1.59M | } |
81 | | |
82 | 8.41M | bool swift::requiresForeignToNativeThunk(ValueDecl *vd) { |
83 | | // Functions imported from C, Objective-C methods imported from Objective-C, |
84 | | // as well as methods in @objc protocols (even protocols defined in Swift) |
85 | | // require a foreign to native thunk. |
86 | 8.41M | auto dc = vd->getDeclContext(); |
87 | 8.41M | if (auto proto = dyn_cast<ProtocolDecl>(dc)) |
88 | 190k | if (proto->isObjC()) |
89 | 0 | return true; |
90 | | |
91 | 8.41M | if (auto fd = dyn_cast<FuncDecl>(vd)) |
92 | 5.83M | return fd->hasClangNode(); |
93 | | |
94 | 2.58M | return false; |
95 | 8.41M | } |
96 | | |
97 | 2.12M | bool swift::requiresForeignEntryPoint(ValueDecl *vd) { |
98 | 2.12M | assert(!isa<AbstractStorageDecl>(vd)); |
99 | | |
100 | 2.12M | if (vd->shouldUseObjCDispatch()) { |
101 | 16.5k | return true; |
102 | 16.5k | } |
103 | | |
104 | 2.11M | if (vd->isObjC() && isa<ProtocolDecl>(vd->getDeclContext())) |
105 | 198 | return true; |
106 | | |
107 | 2.11M | if (vd->isImportAsMember()) |
108 | 2.47k | return true; |
109 | | |
110 | 2.10M | if (vd->hasClangNode()) |
111 | 11.3k | return true; |
112 | | |
113 | 2.09M | if (auto *accessor = dyn_cast<AccessorDecl>(vd)) { |
114 | | // Property accessors should be generated alongside the property. |
115 | 524k | if (accessor->isGetterOrSetter()) { |
116 | 507k | auto *asd = accessor->getStorage(); |
117 | 507k | if (asd->isObjC() && asd->hasClangNode()) |
118 | 0 | return true; |
119 | 507k | } |
120 | 524k | } |
121 | | |
122 | 2.09M | return false; |
123 | 2.09M | } |
124 | | |
125 | | SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind, bool isForeign, |
126 | | bool isDistributed, bool isKnownToBeLocal, |
127 | | bool isRuntimeAccessible, |
128 | | SILDeclRef::BackDeploymentKind backDeploymentKind, |
129 | | AutoDiffDerivativeFunctionIdentifier *derivativeId) |
130 | | : loc(vd), kind(kind), isForeign(isForeign), |
131 | | isDistributed(isDistributed), isKnownToBeLocal(isKnownToBeLocal), |
132 | | isRuntimeAccessible(isRuntimeAccessible), |
133 | | backDeploymentKind(backDeploymentKind), defaultArgIndex(0), |
134 | 5.73M | pointer(derivativeId) {} |
135 | | |
136 | | SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, |
137 | | bool asDistributed, bool asDistributedKnownToBeLocal) |
138 | | : isRuntimeAccessible(false), |
139 | | backDeploymentKind(SILDeclRef::BackDeploymentKind::None), |
140 | | defaultArgIndex(0), |
141 | 5.27M | pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr) { |
142 | 5.27M | if (auto *vd = baseLoc.dyn_cast<ValueDecl*>()) { |
143 | 4.85M | if (auto *fd = dyn_cast<FuncDecl>(vd)) { |
144 | | // Map FuncDecls directly to Func SILDeclRefs. |
145 | 2.97M | loc = fd; |
146 | 2.97M | kind = Kind::Func; |
147 | 2.97M | } |
148 | | // Map ConstructorDecls to the Allocator SILDeclRef of the constructor. |
149 | 1.87M | else if (auto *cd = dyn_cast<ConstructorDecl>(vd)) { |
150 | 301k | loc = cd; |
151 | 301k | kind = Kind::Allocator; |
152 | 301k | } |
153 | | // Map EnumElementDecls to the EnumElement SILDeclRef of the element. |
154 | 1.57M | else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) { |
155 | 29.3k | loc = ed; |
156 | 29.3k | kind = Kind::EnumElement; |
157 | 29.3k | } |
158 | | // VarDecl constants require an explicit kind. |
159 | 1.54M | else if (isa<VarDecl>(vd)) { |
160 | 0 | llvm_unreachable("must create SILDeclRef for VarDecl with explicit kind"); |
161 | 0 | } |
162 | | // Map DestructorDecls to the Deallocator of the destructor. |
163 | 1.54M | else if (auto dtor = dyn_cast<DestructorDecl>(vd)) { |
164 | 1.54M | loc = dtor; |
165 | 1.54M | kind = Kind::Deallocator; |
166 | 1.54M | } |
167 | 0 | else { |
168 | 0 | llvm_unreachable("invalid loc decl for SILDeclRef!"); |
169 | 0 | } |
170 | 4.85M | } else if (auto *ACE = baseLoc.dyn_cast<AbstractClosureExpr *>()) { |
171 | 414k | loc = ACE; |
172 | 414k | kind = Kind::Func; |
173 | 414k | } else { |
174 | 0 | llvm_unreachable("impossible SILDeclRef loc"); |
175 | 0 | } |
176 | | |
177 | 5.27M | isForeign = asForeign; |
178 | 5.27M | isDistributed = asDistributed; |
179 | 5.27M | isKnownToBeLocal = asDistributedKnownToBeLocal; |
180 | 5.27M | } |
181 | | |
182 | | SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, |
183 | | GenericSignature prespecializedSig) |
184 | 1.10k | : SILDeclRef(baseLoc, false, false) { |
185 | 1.10k | pointer = prespecializedSig.getPointer(); |
186 | 1.10k | } Unexecuted instantiation: _ZN5swift10SILDeclRefC2EN4llvm12PointerUnionIJPNS_9ValueDeclEPNS_19AbstractClosureExprEPNS_8FileUnitEEEENS_16GenericSignatureE _ZN5swift10SILDeclRefC1EN4llvm12PointerUnionIJPNS_9ValueDeclEPNS_19AbstractClosureExprEPNS_8FileUnitEEEENS_16GenericSignatureE Line | Count | Source | 184 | 1.10k | : SILDeclRef(baseLoc, false, false) { | 185 | 1.10k | pointer = prespecializedSig.getPointer(); | 186 | 1.10k | } |
|
187 | | |
188 | 7.53M | llvm::Optional<AnyFunctionRef> SILDeclRef::getAnyFunctionRef() const { |
189 | 7.53M | switch (getLocKind()) { |
190 | 6.80M | case LocKind::Decl: |
191 | 6.80M | if (auto *afd = getAbstractFunctionDecl()) |
192 | 6.72M | return AnyFunctionRef(afd); |
193 | 77.7k | return llvm::None; |
194 | 710k | case LocKind::Closure: |
195 | 710k | return AnyFunctionRef(getAbstractClosureExpr()); |
196 | 18.3k | case LocKind::File: |
197 | 18.3k | return llvm::None; |
198 | 7.53M | } |
199 | 0 | llvm_unreachable("Unhandled case in switch"); |
200 | 0 | } |
201 | | |
202 | 769k | DeclContext *SILDeclRef::getInnermostDeclContext() const { |
203 | 769k | if (!loc) |
204 | 0 | return nullptr; |
205 | 769k | switch (getLocKind()) { |
206 | 749k | case LocKind::Decl: |
207 | 749k | return getDecl()->getInnermostDeclContext(); |
208 | 732 | case LocKind::Closure: |
209 | 732 | return getAbstractClosureExpr(); |
210 | 19.6k | case LocKind::File: |
211 | 19.6k | return getFileUnit(); |
212 | 769k | } |
213 | 0 | llvm_unreachable("Unhandled case in switch"); |
214 | 0 | } |
215 | | |
216 | 763k | ASTContext &SILDeclRef::getASTContext() const { |
217 | 763k | auto *DC = getInnermostDeclContext(); |
218 | 763k | assert(DC && "Must have a decl context"); |
219 | 0 | return DC->getASTContext(); |
220 | 763k | } |
221 | | |
222 | | llvm::Optional<AvailabilityContext> |
223 | 1.14M | SILDeclRef::getAvailabilityForLinkage() const { |
224 | | // Back deployment thunks and fallbacks don't have availability since they |
225 | | // are non-ABI. |
226 | | // FIXME: Generalize this check to all kinds of non-ABI functions. |
227 | 1.14M | if (backDeploymentKind != SILDeclRef::BackDeploymentKind::None) |
228 | 1.90k | return llvm::None; |
229 | | |
230 | 1.14M | return getDecl()->getAvailabilityForLinkage(); |
231 | 1.14M | } |
232 | | |
233 | 1.49M | bool SILDeclRef::isThunk() const { |
234 | 1.49M | return isForeignToNativeThunk() || isNativeToForeignThunk() || |
235 | 1.49M | isDistributedThunk() || isBackDeploymentThunk(); |
236 | 1.49M | } |
237 | | |
238 | 4.98M | bool SILDeclRef::isClangImported() const { |
239 | 4.98M | if (!hasDecl()) |
240 | 0 | return false; |
241 | | |
242 | 4.98M | ValueDecl *d = getDecl(); |
243 | 4.98M | DeclContext *moduleContext = d->getDeclContext()->getModuleScopeContext(); |
244 | | |
245 | 4.98M | if (isa<ClangModuleUnit>(moduleContext)) { |
246 | 58.9k | if (isClangGenerated()) |
247 | 5.85k | return true; |
248 | | |
249 | 53.1k | if (isa<ConstructorDecl>(d) || isa<EnumElementDecl>(d)) |
250 | 18.5k | return !isForeign; |
251 | | |
252 | 34.5k | if (auto *FD = dyn_cast<FuncDecl>(d)) |
253 | 34.5k | if (isa<AccessorDecl>(FD) || |
254 | 34.5k | isa<NominalTypeDecl>(d->getDeclContext())) |
255 | 23.2k | return !isForeign; |
256 | 34.5k | } |
257 | 4.93M | return false; |
258 | 4.98M | } |
259 | | |
260 | 63.1k | bool SILDeclRef::isClangGenerated() const { |
261 | 63.1k | if (!hasDecl()) |
262 | 0 | return false; |
263 | | |
264 | 63.1k | return isClangGenerated(getDecl()->getClangNode()); |
265 | 63.1k | } |
266 | | |
267 | | // FIXME: this is a weird predicate. |
268 | 294k | bool SILDeclRef::isClangGenerated(ClangNode node) { |
269 | 294k | if (auto nd = dyn_cast_or_null<clang::NamedDecl>(node.getAsDecl())) { |
270 | | // ie, 'static inline' functions for which we must ask Clang to emit a body |
271 | | // for explicitly |
272 | 265k | if (!nd->isExternallyVisible()) |
273 | 173k | return true; |
274 | 265k | } |
275 | | |
276 | 120k | return false; |
277 | 294k | } |
278 | | |
279 | 699k | bool SILDeclRef::isImplicit() const { |
280 | 699k | switch (getLocKind()) { |
281 | 698k | case LocKind::Decl: |
282 | 698k | return getDecl()->isImplicit(); |
283 | 348 | case LocKind::Closure: |
284 | 348 | return getAbstractClosureExpr()->isImplicit(); |
285 | 435 | case LocKind::File: |
286 | | // Files are currently never considered implicit. |
287 | 435 | return false; |
288 | 699k | } |
289 | 0 | llvm_unreachable("Unhandled case in switch"); |
290 | 0 | } |
291 | | |
292 | 699k | bool SILDeclRef::hasUserWrittenCode() const { |
293 | | // Non-implicit decls generally have user-written code. |
294 | 699k | if (!isImplicit()) { |
295 | 388k | switch (kind) { |
296 | 755 | case Kind::PropertyWrapperBackingInitializer: { |
297 | | // Only has user-written code if any of the property wrappers have |
298 | | // arguments to apply. Otherwise, it's just a forwarding initializer for |
299 | | // the wrappedValue. |
300 | 755 | auto *var = cast<VarDecl>(getDecl()); |
301 | 952 | return llvm::any_of(var->getAttachedPropertyWrappers(), [&](auto *attr) { |
302 | 952 | return attr->hasArgs(); |
303 | 952 | }); |
304 | 0 | } |
305 | 99 | case Kind::PropertyWrapperInitFromProjectedValue: |
306 | | // Never has user-written code, is just a forwarding initializer. |
307 | 99 | return false; |
308 | 388k | default: |
309 | | // TODO: This checking is currently conservative, we ought to |
310 | | // exhaustively handle all the cases here, and use emitOrDelayFunction |
311 | | // in more cases to take advantage of it. |
312 | 388k | return true; |
313 | 388k | } |
314 | 0 | llvm_unreachable("Unhandled case in switch!"); |
315 | 0 | } |
316 | | |
317 | | // Implicit decls generally don't have user-written code, but some splice |
318 | | // user code into their body. |
319 | 310k | switch (kind) { |
320 | 235k | case Kind::Func: { |
321 | 235k | if (getAbstractClosureExpr()) { |
322 | | // Auto-closures have user-written code. |
323 | 192 | if (auto *ACE = getAutoClosureExpr()) { |
324 | | // Currently all types of auto-closures can contain user code. Note this |
325 | | // logic does not affect delayed emission, as we eagerly emit all |
326 | | // closure definitions. This does however affect profiling. |
327 | 192 | switch (ACE->getThunkKind()) { |
328 | 120 | case AutoClosureExpr::Kind::None: |
329 | 162 | case AutoClosureExpr::Kind::SingleCurryThunk: |
330 | 192 | case AutoClosureExpr::Kind::DoubleCurryThunk: |
331 | 192 | case AutoClosureExpr::Kind::AsyncLet: |
332 | 192 | return true; |
333 | 192 | } |
334 | 0 | llvm_unreachable("Unhandled case in switch!"); |
335 | 0 | } |
336 | | // Otherwise, assume an implicit closure doesn't have user code. |
337 | 0 | return false; |
338 | 192 | } |
339 | | |
340 | | // Lazy getters splice in the user-written initializer expr. |
341 | 235k | if (auto *accessor = dyn_cast<AccessorDecl>(getFuncDecl())) { |
342 | 221k | auto *storage = accessor->getStorage(); |
343 | 221k | if (accessor->isGetter() && !storage->isImplicit() && |
344 | 221k | storage->getAttrs().hasAttribute<LazyAttr>()) { |
345 | 453 | return true; |
346 | 453 | } |
347 | 221k | } |
348 | 234k | return false; |
349 | 235k | } |
350 | 905 | case Kind::StoredPropertyInitializer: { |
351 | | // Property wrapper initializers for the implicit backing storage can splice |
352 | | // in the user-written initializer on the original property. |
353 | 905 | auto *var = cast<VarDecl>(getDecl()); |
354 | 905 | if (auto *originalProperty = var->getOriginalWrappedProperty()) { |
355 | 524 | if (originalProperty->isPropertyMemberwiseInitializedWithWrappedType()) |
356 | 443 | return true; |
357 | 524 | } |
358 | 462 | return false; |
359 | 905 | } |
360 | 52.0k | case Kind::Allocator: |
361 | 69.1k | case Kind::Initializer: |
362 | 69.1k | case Kind::EnumElement: |
363 | 69.2k | case Kind::Destroyer: |
364 | 69.2k | case Kind::Deallocator: |
365 | 69.3k | case Kind::GlobalAccessor: |
366 | 74.3k | case Kind::DefaultArgGenerator: |
367 | 74.3k | case Kind::IVarInitializer: |
368 | 74.3k | case Kind::IVarDestroyer: |
369 | 74.3k | case Kind::PropertyWrapperBackingInitializer: |
370 | 74.3k | case Kind::PropertyWrapperInitFromProjectedValue: |
371 | 74.3k | case Kind::EntryPoint: |
372 | 74.3k | case Kind::AsyncEntryPoint: |
373 | | // Implicit decls for these don't splice in user-written code. |
374 | 74.3k | return false; |
375 | 310k | } |
376 | 0 | llvm_unreachable("Unhandled case in switch!"); |
377 | 0 | } |
378 | | |
379 | | namespace { |
380 | | enum class LinkageLimit { |
381 | | /// No limit. |
382 | | None, |
383 | | /// The linkage should behave as if the decl is private. |
384 | | Private, |
385 | | /// The declaration is emitted on-demand; it should end up with internal |
386 | | /// or shared linkage. |
387 | | OnDemand, |
388 | | /// The declaration should never be made public. |
389 | | NeverPublic, |
390 | | /// The declaration should always be emitted into the client, |
391 | | AlwaysEmitIntoClient, |
392 | | }; |
393 | | } // end anonymous namespace |
394 | | |
395 | | /// Compute the linkage limit for a given SILDeclRef. This augments the |
396 | | /// mapping of access level to linkage to provide a maximum or minimum linkage. |
397 | 2.86M | static LinkageLimit getLinkageLimit(SILDeclRef constant) { |
398 | 2.86M | using Limit = LinkageLimit; |
399 | 2.86M | using Kind = SILDeclRef::Kind; |
400 | | |
401 | 2.86M | auto *d = constant.getDecl(); |
402 | | |
403 | | // Back deployment thunks and fallbacks are emitted into the client. |
404 | 2.86M | if (constant.backDeploymentKind != SILDeclRef::BackDeploymentKind::None) |
405 | 1.99k | return Limit::AlwaysEmitIntoClient; |
406 | | |
407 | 2.86M | if (auto *fn = dyn_cast<AbstractFunctionDecl>(d)) { |
408 | | // Native-to-foreign thunks for top-level decls are created on-demand, |
409 | | // unless they are marked @_cdecl, in which case they expose a dedicated |
410 | | // entry-point with the visibility of the function. |
411 | | // |
412 | | // Native-to-foreign thunks for methods are always just private, since |
413 | | // they're anchored by Objective-C metadata. |
414 | 2.78M | auto &attrs = fn->getAttrs(); |
415 | 2.78M | if (constant.isNativeToForeignThunk() && !attrs.hasAttribute<CDeclAttr>()) { |
416 | 12.2k | auto isTopLevel = fn->getDeclContext()->isModuleScopeContext(); |
417 | 12.2k | return isTopLevel ? Limit::OnDemand : Limit::Private; |
418 | 12.2k | } |
419 | 2.78M | } |
420 | | |
421 | 2.85M | if (auto fn = constant.getFuncDecl()) { |
422 | | // Forced-static-dispatch functions are created on-demand and have |
423 | | // at best shared linkage. |
424 | 2.24M | if (fn->hasForcedStaticDispatch()) |
425 | 3.45k | return Limit::OnDemand; |
426 | 2.24M | } |
427 | | |
428 | 2.85M | if (auto dd = dyn_cast<DestructorDecl>(d)) { |
429 | | // The destructor of a class implemented with @_objcImplementation is only |
430 | | // ever called by its ObjC thunk, so it should not be public. |
431 | 61.7k | if (d->getDeclContext()->getSelfNominalTypeDecl()->hasClangNode()) |
432 | 33 | return Limit::OnDemand; |
433 | 61.7k | } |
434 | | |
435 | 2.85M | switch (constant.kind) { |
436 | 2.18M | case Kind::Func: |
437 | 2.52M | case Kind::Allocator: |
438 | 2.61M | case Kind::Initializer: |
439 | 2.64M | case Kind::Deallocator: |
440 | 2.67M | case Kind::Destroyer: { |
441 | | // @_alwaysEmitIntoClient declarations are like the default arguments of |
442 | | // public functions; they are roots for dead code elimination and have |
443 | | // serialized bodies, but no public symbol in the generated binary. |
444 | 2.67M | if (d->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>()) |
445 | 83.5k | return Limit::AlwaysEmitIntoClient; |
446 | 2.59M | if (auto accessor = dyn_cast<AccessorDecl>(d)) { |
447 | 1.09M | auto *storage = accessor->getStorage(); |
448 | 1.09M | if (storage->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>()) |
449 | 39.0k | return Limit::AlwaysEmitIntoClient; |
450 | 1.09M | } |
451 | 2.55M | break; |
452 | 2.59M | } |
453 | 2.55M | case Kind::EnumElement: |
454 | 183 | return Limit::OnDemand; |
455 | | |
456 | 19.1k | case Kind::GlobalAccessor: |
457 | 19.1k | return cast<VarDecl>(d)->isResilient() ? Limit::NeverPublic : Limit::None; |
458 | | |
459 | 90.4k | case Kind::DefaultArgGenerator: |
460 | | // If the default argument is to be serialized, only use non-ABI public |
461 | | // linkage. If the argument is not to be serialized, don't use a limit. |
462 | | // This actually means that default arguments *can be ABI public* if |
463 | | // `isSerialized()` returns false and the effective access level is public, |
464 | | // which happens under `-enable-testing` with an internal decl. |
465 | 90.4k | return constant.isSerialized() ? Limit::AlwaysEmitIntoClient : Limit::None; |
466 | | |
467 | 1.39k | case Kind::PropertyWrapperBackingInitializer: |
468 | 1.56k | case Kind::PropertyWrapperInitFromProjectedValue: { |
469 | 1.56k | if (!d->getDeclContext()->isTypeContext()) { |
470 | | // If the backing initializer is to be serialized, only use non-ABI public |
471 | | // linkage. If the initializer is not to be serialized, don't use a limit. |
472 | | // This actually means that it *can be ABI public* if `isSerialized()` |
473 | | // returns false and the effective access level is public, which happens |
474 | | // under `-enable-testing` with an internal decl. |
475 | 294 | return constant.isSerialized() ? Limit::AlwaysEmitIntoClient |
476 | 294 | : Limit::None; |
477 | 294 | } |
478 | | // Otherwise, regular property wrapper backing initializers (for properties) |
479 | | // are treated just like stored property initializers. |
480 | 1.56k | LLVM_FALLTHROUGH; |
481 | 1.26k | } |
482 | 62.3k | case Kind::StoredPropertyInitializer: { |
483 | | // Stored property initializers get the linkage of their containing type. |
484 | | // There are three cases: |
485 | | // |
486 | | // 1) Type is formally @_fixed_layout/@frozen. Root initializers can be |
487 | | // declared @inlinable. The property initializer must only reference |
488 | | // public symbols, and is serialized, so we give it PublicNonABI linkage. |
489 | | // |
490 | | // 2) Type is not formally @_fixed_layout/@frozen and the module is not |
491 | | // resilient. Root initializers can be declared @inlinable. This is the |
492 | | // annoying case. We give the initializer public linkage if the type is |
493 | | // public. |
494 | | // |
495 | | // 3) Type is resilient. The property initializer is never public because |
496 | | // root initializers cannot be @inlinable. |
497 | | // |
498 | | // FIXME: Get rid of case 2 somehow. |
499 | 62.3k | if (constant.isSerialized()) |
500 | 2.10k | return Limit::AlwaysEmitIntoClient; |
501 | | |
502 | | // FIXME: This should always be true. |
503 | 60.2k | if (d->getModuleContext()->isResilient()) |
504 | 8.14k | return Limit::NeverPublic; |
505 | | |
506 | 52.0k | break; |
507 | 60.2k | } |
508 | 52.0k | case Kind::IVarInitializer: |
509 | 1.41k | case Kind::IVarDestroyer: |
510 | | // ivar initializers and destroyers are completely contained within the |
511 | | // class from which they come, and never get seen externally. |
512 | 1.41k | return Limit::NeverPublic; |
513 | | |
514 | 0 | case Kind::EntryPoint: |
515 | 0 | case Kind::AsyncEntryPoint: |
516 | 0 | llvm_unreachable("Already handled"); |
517 | 2.85M | } |
518 | 2.60M | return Limit::None; |
519 | 2.85M | } |
520 | | |
521 | 2.99M | SILLinkage SILDeclRef::getDefinitionLinkage() const { |
522 | 2.99M | using Limit = LinkageLimit; |
523 | | |
524 | 2.99M | auto privateLinkage = [&]() { |
525 | | // Private decls may still be serialized if they are e.g in an inlinable |
526 | | // function. In such a case, they receive shared linkage. |
527 | 246k | return isSerialized() ? SILLinkage::Shared : SILLinkage::Private; |
528 | 246k | }; |
529 | | |
530 | | // Prespecializations are public. |
531 | 2.99M | if (getSpecializedSignature()) |
532 | 0 | return SILLinkage::Public; |
533 | | |
534 | | // Closures can only be referenced from the same file. |
535 | 2.99M | if (getAbstractClosureExpr()) |
536 | 83.1k | return privateLinkage(); |
537 | | |
538 | | // The main entry-point is public. |
539 | 2.91M | if (kind == Kind::EntryPoint) |
540 | 19.0k | return SILLinkage::Public; |
541 | 2.89M | if (kind == Kind::AsyncEntryPoint) { |
542 | | // async main entrypoint is referenced only from @main and |
543 | | // they are in the same SIL module. Hiding this entrypoint |
544 | | // from other object file makes it possible to link multiple |
545 | | // executable targets for SwiftPM testing with -entry-point-function-name |
546 | 492 | return SILLinkage::Private; |
547 | 492 | } |
548 | | |
549 | | // Calling convention thunks have shared linkage. |
550 | 2.89M | if (isForeignToNativeThunk()) |
551 | 4.82k | return SILLinkage::Shared; |
552 | | |
553 | | // Declarations imported from Clang modules have shared linkage. |
554 | 2.88M | if (isClangImported()) |
555 | 20.1k | return SILLinkage::Shared; |
556 | | |
557 | 2.86M | const auto limit = getLinkageLimit(*this); |
558 | 2.86M | if (limit == Limit::Private) |
559 | 12.1k | return privateLinkage(); |
560 | | |
561 | 2.85M | auto *decl = getDecl(); |
562 | | |
563 | 2.85M | if (isPropertyWrapperBackingInitializer()) { |
564 | 1.56k | auto *dc = decl->getDeclContext(); |
565 | | |
566 | | // External property wrapper backing initializers have linkage based |
567 | | // on the access level of their function. |
568 | 1.56k | if (isa<ParamDecl>(decl)) { |
569 | 282 | if (isa<AbstractClosureExpr>(dc)) |
570 | 57 | return privateLinkage(); |
571 | | |
572 | 225 | decl = cast<ValueDecl>(dc->getAsDecl()); |
573 | 225 | } |
574 | | |
575 | | // Property wrappers in types have linkage based on the access level of |
576 | | // their nominal. |
577 | 1.50k | if (dc->isTypeContext()) |
578 | 1.26k | decl = cast<NominalTypeDecl>(dc); |
579 | 1.50k | } |
580 | | |
581 | | // Stored property initializers have linkage based on the access level of |
582 | | // their nominal. |
583 | 2.85M | if (isStoredPropertyInitializer()) |
584 | 61.0k | decl = cast<NominalTypeDecl>( |
585 | 61.0k | decl->getDeclContext()->getImplementedObjCContext()); |
586 | | |
587 | | // Compute the effective access level, taking e.g testable into consideration. |
588 | 2.85M | auto effectiveAccess = decl->getEffectiveAccess(); |
589 | | |
590 | | // Private setter implementations for an internal storage declaration should |
591 | | // be at least internal as well, so that a dynamically-writable |
592 | | // keypath can be formed from other files in the same module. |
593 | 2.85M | if (auto *accessor = dyn_cast<AccessorDecl>(decl)) { |
594 | 1.10M | auto storageAccess = accessor->getStorage()->getEffectiveAccess(); |
595 | 1.10M | if (accessor->isSetter() && storageAccess >= AccessLevel::Internal) |
596 | 136k | effectiveAccess = std::max(effectiveAccess, AccessLevel::Internal); |
597 | 1.10M | } |
598 | | |
599 | 2.85M | switch (effectiveAccess) { |
600 | 0 | case AccessLevel::Private: |
601 | 150k | case AccessLevel::FilePrivate: |
602 | 150k | return privateLinkage(); |
603 | | |
604 | 647k | case AccessLevel::Internal: |
605 | 647k | assert(!isSerialized() && |
606 | 647k | "Serialized decls should either be private (for decls in inlinable " |
607 | 647k | "code), or they should be public"); |
608 | 647k | if (limit == Limit::OnDemand) |
609 | 285 | return SILLinkage::Shared; |
610 | 647k | return SILLinkage::Hidden; |
611 | | |
612 | 0 | case AccessLevel::Package: |
613 | 2.01M | case AccessLevel::Public: |
614 | 2.05M | case AccessLevel::Open: |
615 | 2.05M | switch (limit) { |
616 | 1.83M | case Limit::None: |
617 | 1.83M | return SILLinkage::Public; |
618 | 203k | case Limit::AlwaysEmitIntoClient: |
619 | 203k | return SILLinkage::PublicNonABI; |
620 | 3.42k | case Limit::OnDemand: |
621 | 3.42k | return SILLinkage::Shared; |
622 | 17.0k | case Limit::NeverPublic: |
623 | 17.0k | return SILLinkage::Hidden; |
624 | 0 | case Limit::Private: |
625 | 0 | llvm_unreachable("Already handled"); |
626 | 2.05M | } |
627 | 2.85M | } |
628 | 0 | llvm_unreachable("unhandled access"); |
629 | 0 | } |
630 | | |
631 | 2.99M | SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { |
632 | | // Add external to the linkage of the definition |
633 | | // (e.g. Public -> PublicExternal) if this is a declaration. |
634 | 2.99M | auto linkage = getDefinitionLinkage(); |
635 | 2.99M | return forDefinition ? linkage : addExternalToLinkage(linkage); |
636 | 2.99M | } |
637 | | |
638 | | SILDeclRef SILDeclRef::getDefaultArgGenerator(Loc loc, |
639 | 296k | unsigned defaultArgIndex) { |
640 | 296k | SILDeclRef result; |
641 | 296k | result.loc = loc; |
642 | 296k | result.kind = Kind::DefaultArgGenerator; |
643 | 296k | result.defaultArgIndex = defaultArgIndex; |
644 | 296k | return result; |
645 | 296k | } |
646 | | |
647 | 1.96k | SILDeclRef SILDeclRef::getMainDeclEntryPoint(ValueDecl *decl) { |
648 | 1.96k | auto *file = cast<FileUnit>(decl->getDeclContext()->getModuleScopeContext()); |
649 | 1.96k | assert(file->getMainDecl() == decl); |
650 | 0 | SILDeclRef result; |
651 | 1.96k | result.loc = decl; |
652 | 1.96k | result.kind = Kind::EntryPoint; |
653 | 1.96k | return result; |
654 | 1.96k | } |
655 | | |
656 | 948 | SILDeclRef SILDeclRef::getAsyncMainDeclEntryPoint(ValueDecl *decl) { |
657 | 948 | auto *file = cast<FileUnit>(decl->getDeclContext()->getModuleScopeContext()); |
658 | 948 | assert(file->getMainDecl() == decl); |
659 | 0 | SILDeclRef result; |
660 | 948 | result.loc = decl; |
661 | 948 | result.kind = Kind::AsyncEntryPoint; |
662 | 948 | return result; |
663 | 948 | } |
664 | | |
665 | 18 | SILDeclRef SILDeclRef::getAsyncMainFileEntryPoint(FileUnit *file) { |
666 | 18 | assert(file->hasEntryPoint() && !file->getMainDecl()); |
667 | 0 | SILDeclRef result; |
668 | 18 | result.loc = file; |
669 | 18 | result.kind = Kind::AsyncEntryPoint; |
670 | 18 | return result; |
671 | 18 | } |
672 | | |
673 | 51.2k | SILDeclRef SILDeclRef::getMainFileEntryPoint(FileUnit *file) { |
674 | 51.2k | assert(file->hasEntryPoint() && !file->getMainDecl()); |
675 | 0 | SILDeclRef result; |
676 | 51.2k | result.loc = file; |
677 | 51.2k | result.kind = Kind::EntryPoint; |
678 | 51.2k | return result; |
679 | 51.2k | } |
680 | | |
681 | 18 | bool SILDeclRef::hasClosureExpr() const { |
682 | 18 | return loc.is<AbstractClosureExpr *>() |
683 | 18 | && isa<ClosureExpr>(getAbstractClosureExpr()); |
684 | 18 | } |
685 | | |
686 | 1.22M | bool SILDeclRef::hasAutoClosureExpr() const { |
687 | 1.22M | return loc.is<AbstractClosureExpr *>() |
688 | 1.22M | && isa<AutoClosureExpr>(getAbstractClosureExpr()); |
689 | 1.22M | } |
690 | | |
691 | 1.25M | bool SILDeclRef::hasFuncDecl() const { |
692 | 1.25M | return loc.is<ValueDecl *>() && isa<FuncDecl>(getDecl()); |
693 | 1.25M | } |
694 | | |
695 | 0 | ClosureExpr *SILDeclRef::getClosureExpr() const { |
696 | 0 | return dyn_cast<ClosureExpr>(getAbstractClosureExpr()); |
697 | 0 | } |
698 | 39.2k | AutoClosureExpr *SILDeclRef::getAutoClosureExpr() const { |
699 | 39.2k | return dyn_cast<AutoClosureExpr>(getAbstractClosureExpr()); |
700 | 39.2k | } |
701 | | |
702 | 5.22M | FuncDecl *SILDeclRef::getFuncDecl() const { |
703 | 5.22M | return dyn_cast<FuncDecl>(getDecl()); |
704 | 5.22M | } |
705 | | |
706 | 13.6k | ModuleDecl *SILDeclRef::getModuleContext() const { |
707 | 13.6k | if (hasDecl()) { |
708 | 13.6k | return getDecl()->getModuleContext(); |
709 | 13.6k | } else if (hasFileUnit()) { |
710 | 18 | return getFileUnit()->getParentModule(); |
711 | 18 | } else if (hasClosureExpr()) { |
712 | 0 | return getClosureExpr()->getParentModule(); |
713 | 0 | } else if (hasAutoClosureExpr()) { |
714 | 0 | return getAutoClosureExpr()->getParentModule(); |
715 | 0 | } |
716 | 0 | llvm_unreachable("Unknown declaration reference"); |
717 | 0 | } |
718 | | |
719 | 1.87M | bool SILDeclRef::isSetter() const { |
720 | 1.87M | if (!hasDecl()) |
721 | 166k | return false; |
722 | 1.70M | if (auto accessor = dyn_cast<AccessorDecl>(getDecl())) |
723 | 662k | return accessor->isSetter(); |
724 | 1.04M | return false; |
725 | 1.70M | } |
726 | | |
727 | 8.63M | AbstractFunctionDecl *SILDeclRef::getAbstractFunctionDecl() const { |
728 | 8.63M | return dyn_cast_or_null<AbstractFunctionDecl>(getDecl()); |
729 | 8.63M | } |
730 | | |
731 | 2.22M | bool SILDeclRef::isInitAccessor() const { |
732 | 2.22M | if (kind != Kind::Func || !hasDecl()) |
733 | 166k | return false; |
734 | | |
735 | 2.05M | if (auto accessor = dyn_cast<AccessorDecl>(getDecl())) |
736 | 800k | return accessor->getAccessorKind() == AccessorKind::Init; |
737 | | |
738 | 1.25M | return false; |
739 | 2.05M | } |
740 | | |
741 | | /// True if the function should be treated as transparent. |
742 | 1.25M | bool SILDeclRef::isTransparent() const { |
743 | 1.25M | if (isEnumElement()) |
744 | 63 | return true; |
745 | | |
746 | 1.25M | if (isStoredPropertyInitializer()) |
747 | 27.1k | return true; |
748 | | |
749 | 1.22M | if (hasAutoClosureExpr()) { |
750 | 39.0k | auto *ace = getAutoClosureExpr(); |
751 | 39.0k | switch (ace->getThunkKind()) { |
752 | 35.4k | case AutoClosureExpr::Kind::None: |
753 | 35.4k | return true; |
754 | | |
755 | 333 | case AutoClosureExpr::Kind::AsyncLet: |
756 | 1.40k | case AutoClosureExpr::Kind::DoubleCurryThunk: |
757 | 3.62k | case AutoClosureExpr::Kind::SingleCurryThunk: |
758 | 3.62k | break; |
759 | 39.0k | } |
760 | 39.0k | } |
761 | | |
762 | 1.18M | if (hasDecl()) { |
763 | 1.12M | if (auto *AFD = dyn_cast<AbstractFunctionDecl>(getDecl())) |
764 | 1.10M | return AFD->isTransparent(); |
765 | | |
766 | 15.9k | if (auto *ASD = dyn_cast<AbstractStorageDecl>(getDecl())) |
767 | 14.3k | return ASD->isTransparent(); |
768 | 15.9k | } |
769 | | |
770 | 67.7k | return false; |
771 | 1.18M | } |
772 | | |
773 | | /// True if the function should have its body serialized. |
774 | 2.40M | IsSerialized_t SILDeclRef::isSerialized() const { |
775 | 2.40M | if (auto closure = getAbstractClosureExpr()) { |
776 | | // Ask the AST if we're inside an @inlinable context. |
777 | 254k | if (closure->getResilienceExpansion() == ResilienceExpansion::Minimal) { |
778 | 120k | return IsSerialized; |
779 | 120k | } |
780 | | |
781 | 133k | return IsNotSerialized; |
782 | 254k | } |
783 | | |
784 | 2.14M | if (kind == Kind::EntryPoint || kind == Kind::AsyncEntryPoint) |
785 | 19.5k | return IsNotSerialized; |
786 | | |
787 | 2.12M | if (isIVarInitializerOrDestroyer()) |
788 | 2.43k | return IsNotSerialized; |
789 | | |
790 | 2.12M | auto *d = getDecl(); |
791 | | |
792 | | // Default and property wrapper argument generators are serialized if the |
793 | | // containing declaration is public. |
794 | 2.12M | if (isDefaultArgGenerator() || (isPropertyWrapperBackingInitializer() && |
795 | 1.96M | isa<ParamDecl>(d))) { |
796 | 158k | if (isPropertyWrapperBackingInitializer()) { |
797 | 630 | if (auto *func = dyn_cast_or_null<ValueDecl>(d->getDeclContext()->getAsDecl())) { |
798 | 489 | d = func; |
799 | 489 | } |
800 | 630 | } |
801 | | |
802 | | // Ask the AST if we're inside an @inlinable context. |
803 | 158k | if (d->getDeclContext()->getResilienceExpansion() |
804 | 158k | == ResilienceExpansion::Minimal) { |
805 | 30 | return IsSerialized; |
806 | 30 | } |
807 | | |
808 | | // Otherwise, check if the owning declaration is public. |
809 | 158k | auto scope = |
810 | 158k | d->getFormalAccessScope(/*useDC=*/nullptr, |
811 | 158k | /*treatUsableFromInlineAsPublic=*/true); |
812 | | |
813 | 158k | if (scope.isPublic()) |
814 | 127k | return IsSerialized; |
815 | 30.7k | return IsNotSerialized; |
816 | 158k | } |
817 | | |
818 | | // Stored property initializers are inlinable if the type is explicitly |
819 | | // marked as @frozen. |
820 | 1.96M | if (isStoredPropertyInitializer() || (isPropertyWrapperBackingInitializer() && |
821 | 1.85M | d->getDeclContext()->isTypeContext())) { |
822 | 112k | auto *nominal = cast<NominalTypeDecl>(d->getDeclContext()->getImplementedObjCContext()); |
823 | 112k | auto scope = |
824 | 112k | nominal->getFormalAccessScope(/*useDC=*/nullptr, |
825 | 112k | /*treatUsableFromInlineAsPublic=*/true); |
826 | 112k | if (!scope.isPublic()) |
827 | 58.1k | return IsNotSerialized; |
828 | 54.6k | if (nominal->isFormallyResilient()) |
829 | 51.5k | return IsNotSerialized; |
830 | 3.08k | return IsSerialized; |
831 | 54.6k | } |
832 | | |
833 | | // Note: if 'd' is a function, then 'dc' is the function itself, not |
834 | | // its parent context. |
835 | 1.85M | auto *dc = d->getInnermostDeclContext(); |
836 | | |
837 | | // Local functions are serializable if their parent function is |
838 | | // serializable. |
839 | 1.85M | if (d->getDeclContext()->isLocalContext()) { |
840 | 37.0k | if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal) |
841 | 6.46k | return IsSerialized; |
842 | | |
843 | 30.5k | return IsNotSerialized; |
844 | 37.0k | } |
845 | | |
846 | | // Anything else that is not public is not serializable. |
847 | 1.81M | if (d->getEffectiveAccess() < AccessLevel::Public) |
848 | 1.01M | return IsNotSerialized; |
849 | | |
850 | | // Enum element constructors are serializable if the enum is |
851 | | // @usableFromInline or public. |
852 | 800k | if (isEnumElement()) |
853 | 105 | return IsSerialized; |
854 | | |
855 | | // 'read' and 'modify' accessors synthesized on-demand are serialized if |
856 | | // visible outside the module. |
857 | 800k | if (auto fn = dyn_cast<FuncDecl>(d)) |
858 | 631k | if (!isClangImported() && |
859 | 631k | fn->hasForcedStaticDispatch()) |
860 | 1.88k | return IsSerialized; |
861 | | |
862 | 798k | if (isForeignToNativeThunk()) |
863 | 4.42k | return IsSerialized; |
864 | | |
865 | | // The allocating entry point for designated initializers are serialized |
866 | | // if the class is @usableFromInline or public. Actors are excluded because |
867 | | // whether the init is designated is not clearly reflected in the source code. |
868 | 794k | if (kind == SILDeclRef::Kind::Allocator) { |
869 | 119k | auto *ctor = cast<ConstructorDecl>(d); |
870 | 119k | if (auto classDecl = ctor->getDeclContext()->getSelfClassDecl()) { |
871 | 14.8k | if (!classDecl->isAnyActor() && ctor->isDesignatedInit()) |
872 | 13.0k | if (!ctor->hasClangNode()) |
873 | 9.97k | return IsSerialized; |
874 | 14.8k | } |
875 | 119k | } |
876 | | |
877 | 784k | if (isForeign) { |
878 | | // @objc thunks for methods are not serializable since they're only |
879 | | // referenced from the method table. |
880 | 19.4k | if (d->getDeclContext()->isTypeContext()) |
881 | 11.2k | return IsNotSerialized; |
882 | | |
883 | | // @objc thunks for top-level functions are serializable since they're |
884 | | // referenced from @convention(c) conversions inside inlinable |
885 | | // functions. |
886 | 8.22k | return IsSerialized; |
887 | 19.4k | } |
888 | | |
889 | | // Declarations imported from Clang modules are serialized if |
890 | | // referenced from an inlinable context. |
891 | 764k | if (isClangImported()) |
892 | 13.2k | return IsSerialized; |
893 | | |
894 | | // Handle back deployed functions. The original back deployed function |
895 | | // should not be serialized, but the thunk and fallback should be since they |
896 | | // need to be emitted into the client. |
897 | 751k | if (isBackDeployed()) { |
898 | 2.50k | switch (backDeploymentKind) { |
899 | 600 | case BackDeploymentKind::None: |
900 | 600 | return IsNotSerialized; |
901 | 585 | case BackDeploymentKind::Fallback: |
902 | 1.90k | case BackDeploymentKind::Thunk: |
903 | 1.90k | return IsSerialized; |
904 | 2.50k | } |
905 | 2.50k | } |
906 | | |
907 | | // Otherwise, ask the AST if we're inside an @inlinable context. |
908 | 749k | if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal) |
909 | 313k | return IsSerialized; |
910 | | |
911 | 435k | return IsNotSerialized; |
912 | 749k | } |
913 | | |
914 | | /// True if the function has an @inline(never) attribute. |
915 | 1.25M | bool SILDeclRef::isNoinline() const { |
916 | 1.25M | if (!hasDecl()) |
917 | 101k | return false; |
918 | | |
919 | 1.14M | auto *decl = getDecl(); |
920 | 1.14M | if (auto *attr = decl->getAttrs().getAttribute<InlineAttr>()) |
921 | 52.8k | if (attr->getKind() == InlineKind::Never) |
922 | 15.2k | return true; |
923 | | |
924 | 1.13M | if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) { |
925 | 341k | auto *storage = accessorDecl->getStorage(); |
926 | 341k | if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>()) |
927 | 2.71k | if (attr->getKind() == InlineKind::Never) |
928 | 84 | return true; |
929 | 341k | } |
930 | | |
931 | 1.13M | return false; |
932 | 1.13M | } |
933 | | |
934 | | /// True if the function has the @inline(__always) attribute. |
935 | 1.60M | bool SILDeclRef::isAlwaysInline() const { |
936 | 1.60M | swift::Decl *decl = nullptr; |
937 | 1.60M | if (hasDecl()) { |
938 | 1.49M | decl = getDecl(); |
939 | 1.49M | } else if (auto *ce = getAbstractClosureExpr()) { |
940 | | // Closures within @inline(__always) functions should be always inlined, too. |
941 | | // Note that this is different from @inline(never), because closures inside |
942 | | // @inline(never) _can_ be inlined within the inline-never function. |
943 | 83.1k | decl = ce->getParent()->getInnermostDeclarationDeclContext(); |
944 | 83.1k | if (!decl) |
945 | 57 | return false; |
946 | 83.1k | } else { |
947 | 18.2k | return false; |
948 | 18.2k | } |
949 | | |
950 | 1.58M | if (auto attr = decl->getAttrs().getAttribute<InlineAttr>()) |
951 | 66.1k | if (attr->getKind() == InlineKind::Always) |
952 | 64.8k | return true; |
953 | | |
954 | 1.51M | if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) { |
955 | 452k | auto *storage = accessorDecl->getStorage(); |
956 | 452k | if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>()) |
957 | 3.46k | if (attr->getKind() == InlineKind::Always) |
958 | 3.46k | return true; |
959 | 452k | } |
960 | | |
961 | 1.51M | return false; |
962 | 1.51M | } |
963 | | |
964 | 751k | bool SILDeclRef::isBackDeployed() const { |
965 | 751k | if (!hasDecl()) |
966 | 0 | return false; |
967 | | |
968 | 751k | auto *decl = getDecl(); |
969 | 751k | if (auto afd = dyn_cast<AbstractFunctionDecl>(decl)) |
970 | 741k | return afd->isBackDeployed(getASTContext()); |
971 | | |
972 | 10.0k | return false; |
973 | 751k | } |
974 | | |
975 | 8.69M | bool SILDeclRef::isForeignToNativeThunk() const { |
976 | | // If this isn't a native entry-point, it's not a foreign-to-native thunk. |
977 | 8.69M | if (isForeign) |
978 | 100k | return false; |
979 | | |
980 | | // Non-decl entry points are never natively foreign, so they would never |
981 | | // have a foreign-to-native thunk. |
982 | 8.59M | if (!hasDecl()) |
983 | 185k | return false; |
984 | 8.41M | if (requiresForeignToNativeThunk(getDecl())) |
985 | 6.39k | return true; |
986 | | // ObjC initializing constructors and factories are foreign. |
987 | | // We emit a special native allocating constructor though. |
988 | 8.40M | if (isa<ConstructorDecl>(getDecl()) |
989 | 8.40M | && (kind == Kind::Initializer |
990 | 1.43M | || cast<ConstructorDecl>(getDecl())->isFactoryInit()) |
991 | 8.40M | && getDecl()->hasClangNode()) |
992 | 28.3k | return true; |
993 | 8.37M | return false; |
994 | 8.40M | } |
995 | | |
996 | 5.74M | bool SILDeclRef::isNativeToForeignThunk() const { |
997 | | // If this isn't a foreign entry-point, it's not a native-to-foreign thunk. |
998 | 5.74M | if (!isForeign) |
999 | 5.65M | return false; |
1000 | | |
1001 | 90.1k | switch (getLocKind()) { |
1002 | 89.9k | case LocKind::Decl: |
1003 | | // A decl with a clang node doesn't have a native entry-point to forward |
1004 | | // onto. |
1005 | 89.9k | if (getDecl()->hasClangNode()) |
1006 | 32.1k | return false; |
1007 | | // No thunk is required if the decl directly references an external decl. |
1008 | 57.7k | if (getDecl()->getAttrs().hasAttribute<ExternAttr>()) |
1009 | 6 | return false; |
1010 | | |
1011 | | // Only certain kinds of SILDeclRef can expose native-to-foreign thunks. |
1012 | 57.7k | return kind == Kind::Func || kind == Kind::Initializer || |
1013 | 57.7k | kind == Kind::Deallocator; |
1014 | 180 | case LocKind::Closure: |
1015 | | // We can have native-to-foreign thunks over closures. |
1016 | 180 | return true; |
1017 | 0 | case LocKind::File: |
1018 | 0 | return false; |
1019 | 90.1k | } |
1020 | 0 | llvm_unreachable("Unhandled case in switch"); |
1021 | 0 | } |
1022 | | |
1023 | 9.79M | bool SILDeclRef::isDistributedThunk() const { |
1024 | 9.79M | if (!isDistributed) |
1025 | 9.79M | return false; |
1026 | 3.53k | return kind == Kind::Func; |
1027 | 9.79M | } |
1028 | | |
1029 | 2.02M | bool SILDeclRef::isBackDeploymentFallback() const { |
1030 | 2.02M | if (backDeploymentKind != BackDeploymentKind::Fallback) |
1031 | 2.02M | return false; |
1032 | 585 | return kind == Kind::Func || kind == Kind::Initializer || |
1033 | 585 | kind == Kind::Allocator; |
1034 | 2.02M | } |
1035 | | |
1036 | 95.9M | bool SILDeclRef::isBackDeploymentThunk() const { |
1037 | 95.9M | if (backDeploymentKind != BackDeploymentKind::Thunk) |
1038 | 95.9M | return false; |
1039 | 3.65k | return kind == Kind::Func || kind == Kind::Initializer || |
1040 | 3.65k | kind == Kind::Allocator; |
1041 | 95.9M | } |
1042 | | |
1043 | | /// Use the Clang importer to mangle a Clang declaration. |
1044 | | static void mangleClangDecl(raw_ostream &buffer, |
1045 | | const clang::NamedDecl *clangDecl, |
1046 | 5.76k | ASTContext &ctx) { |
1047 | 5.76k | auto *importer = static_cast<ClangImporter *>(ctx.getClangModuleLoader()); |
1048 | 5.76k | importer->getMangledName(buffer, clangDecl); |
1049 | 5.76k | } |
1050 | | |
1051 | 2.06M | std::string SILDeclRef::mangle(ManglingKind MKind) const { |
1052 | 2.06M | using namespace Mangle; |
1053 | 2.06M | ASTMangler mangler; |
1054 | | |
1055 | 2.06M | if (auto *derivativeFunctionIdentifier = getDerivativeFunctionIdentifier()) { |
1056 | 568 | std::string originalMangled = asAutoDiffOriginalFunction().mangle(MKind); |
1057 | 568 | auto *silParameterIndices = autodiff::getLoweredParameterIndices( |
1058 | 568 | derivativeFunctionIdentifier->getParameterIndices(), |
1059 | 568 | getDecl()->getInterfaceType()->castTo<AnyFunctionType>()); |
1060 | | // FIXME: is this correct in the presence of curried types? |
1061 | 568 | auto *resultIndices = autodiff::getFunctionSemanticResultIndices( |
1062 | 568 | asAutoDiffOriginalFunction().getAbstractFunctionDecl(), |
1063 | 568 | derivativeFunctionIdentifier->getParameterIndices()); |
1064 | 568 | AutoDiffConfig silConfig( |
1065 | 568 | silParameterIndices, resultIndices, |
1066 | 568 | derivativeFunctionIdentifier->getDerivativeGenericSignature()); |
1067 | 568 | return mangler.mangleAutoDiffDerivativeFunction( |
1068 | 568 | asAutoDiffOriginalFunction().getAbstractFunctionDecl(), |
1069 | 568 | derivativeFunctionIdentifier->getKind(), |
1070 | 568 | silConfig); |
1071 | 568 | } |
1072 | | |
1073 | | // As a special case, Clang functions and globals don't get mangled at all |
1074 | | // - except \c objc_direct decls. |
1075 | 2.06M | if (hasDecl()) { |
1076 | 1.96M | if (auto clangDecl = getDecl()->getClangDecl()) { |
1077 | 19.7k | if (!isForeignToNativeThunk() && !isNativeToForeignThunk()) { |
1078 | 15.5k | if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) { |
1079 | 11.7k | if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) { |
1080 | 84 | std::string s(1, '\01'); |
1081 | 84 | s += asmLabel->getLabel(); |
1082 | 84 | return s; |
1083 | 11.6k | } else if (namedClangDecl->hasAttr<clang::OverloadableAttr>() || |
1084 | 11.6k | getDecl()->getASTContext().LangOpts.EnableCXXInterop) { |
1085 | 5.76k | std::string storage; |
1086 | 5.76k | llvm::raw_string_ostream SS(storage); |
1087 | 5.76k | mangleClangDecl(SS, namedClangDecl, getDecl()->getASTContext()); |
1088 | 5.76k | return SS.str(); |
1089 | 5.76k | } |
1090 | 5.86k | return namedClangDecl->getName().str(); |
1091 | 11.7k | } else if (auto objcDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) { |
1092 | 3.77k | if (objcDecl->isDirectMethod() && isForeign) { |
1093 | 144 | std::string storage; |
1094 | 144 | llvm::raw_string_ostream SS(storage); |
1095 | 144 | clang::ASTContext &ctx = clangDecl->getASTContext(); |
1096 | 144 | std::unique_ptr<clang::MangleContext> mangler(ctx.createMangleContext()); |
1097 | 144 | mangler->mangleObjCMethodName(objcDecl, SS, /*includePrefixByte=*/true, |
1098 | 144 | /*includeCategoryNamespace=*/false); |
1099 | 144 | return SS.str(); |
1100 | 144 | } |
1101 | 3.77k | } |
1102 | 15.5k | } |
1103 | 19.7k | } |
1104 | 1.96M | } |
1105 | | |
1106 | | // Mangle prespecializations. |
1107 | 2.05M | if (getSpecializedSignature()) { |
1108 | 1.10k | SILDeclRef nonSpecializedDeclRef = *this; |
1109 | 1.10k | nonSpecializedDeclRef.pointer = |
1110 | 1.10k | (AutoDiffDerivativeFunctionIdentifier *)nullptr; |
1111 | 1.10k | auto mangledNonSpecializedString = nonSpecializedDeclRef.mangle(); |
1112 | 1.10k | auto *funcDecl = cast<AbstractFunctionDecl>(getDecl()); |
1113 | 1.10k | auto genericSig = funcDecl->getGenericSignature(); |
1114 | 1.10k | return GenericSpecializationMangler::manglePrespecialization( |
1115 | 1.10k | mangledNonSpecializedString, genericSig, getSpecializedSignature()); |
1116 | 1.10k | } |
1117 | | |
1118 | 2.05M | ASTMangler::SymbolKind SKind = ASTMangler::SymbolKind::Default; |
1119 | 2.05M | switch (MKind) { |
1120 | 2.05M | case SILDeclRef::ManglingKind::Default: |
1121 | 2.05M | if (isForeign) { |
1122 | 21.1k | SKind = ASTMangler::SymbolKind::SwiftAsObjCThunk; |
1123 | 2.03M | } else if (isForeignToNativeThunk()) { |
1124 | 4.20k | SKind = ASTMangler::SymbolKind::ObjCAsSwiftThunk; |
1125 | 2.02M | } else if (isDistributedThunk()) { |
1126 | 396 | SKind = ASTMangler::SymbolKind::DistributedThunk; |
1127 | 2.02M | } else if (isBackDeploymentThunk()) { |
1128 | 1.31k | SKind = ASTMangler::SymbolKind::BackDeploymentThunk; |
1129 | 2.02M | } else if (isBackDeploymentFallback()) { |
1130 | 585 | SKind = ASTMangler::SymbolKind::BackDeploymentFallback; |
1131 | 585 | } |
1132 | 2.05M | break; |
1133 | 2.37k | case SILDeclRef::ManglingKind::DynamicThunk: |
1134 | 2.37k | SKind = ASTMangler::SymbolKind::DynamicThunk; |
1135 | 2.37k | break; |
1136 | 2.05M | } |
1137 | | |
1138 | 2.05M | switch (kind) { |
1139 | 955k | case SILDeclRef::Kind::Func: |
1140 | 955k | if (auto *ACE = getAbstractClosureExpr()) |
1141 | 83.5k | return mangler.mangleClosureEntity(ACE, SKind); |
1142 | | |
1143 | | // As a special case, functions can have manually mangled names. |
1144 | | // Use the SILGen name only for the original non-thunked, non-curried entry |
1145 | | // point. |
1146 | 872k | if (auto NameA = getDecl()->getAttrs().getAttribute<SILGenNameAttr>()) |
1147 | 6.81k | if (!NameA->Name.empty() && !isThunk()) { |
1148 | 6.77k | return NameA->Name.str(); |
1149 | 6.77k | } |
1150 | | |
1151 | 865k | if (auto *ExternA = ExternAttr::find(getDecl()->getAttrs(), ExternKind::C)) { |
1152 | 72 | assert(isa<FuncDecl>(getDecl()) && "non-FuncDecl with @_extern should be rejected by typechecker"); |
1153 | 0 | return ExternA->getCName(cast<FuncDecl>(getDecl())).str(); |
1154 | 72 | } |
1155 | | |
1156 | | // Use a given cdecl name for native-to-foreign thunks. |
1157 | 865k | if (auto CDeclA = getDecl()->getAttrs().getAttribute<CDeclAttr>()) |
1158 | 876 | if (isNativeToForeignThunk()) { |
1159 | 435 | return CDeclA->Name.str(); |
1160 | 435 | } |
1161 | | |
1162 | 865k | if (SKind == ASTMangler::SymbolKind::DistributedThunk) { |
1163 | 396 | return mangler.mangleDistributedThunk(cast<FuncDecl>(getDecl())); |
1164 | 396 | } |
1165 | | |
1166 | | // Otherwise, fall through into the 'other decl' case. |
1167 | 865k | LLVM_FALLTHROUGH; |
1168 | | |
1169 | 864k | case SILDeclRef::Kind::EnumElement: |
1170 | 864k | return mangler.mangleEntity(getDecl(), SKind); |
1171 | | |
1172 | 708k | case SILDeclRef::Kind::Deallocator: |
1173 | 708k | return mangler.mangleDestructorEntity(cast<DestructorDecl>(getDecl()), |
1174 | 708k | /*isDeallocating*/ true, |
1175 | 708k | SKind); |
1176 | | |
1177 | 29.3k | case SILDeclRef::Kind::Destroyer: |
1178 | 29.3k | return mangler.mangleDestructorEntity(cast<DestructorDecl>(getDecl()), |
1179 | 29.3k | /*isDeallocating*/ false, |
1180 | 29.3k | SKind); |
1181 | | |
1182 | 177k | case SILDeclRef::Kind::Allocator: |
1183 | 177k | return mangler.mangleConstructorEntity(cast<ConstructorDecl>(getDecl()), |
1184 | 177k | /*allocating*/ true, |
1185 | 177k | SKind); |
1186 | | |
1187 | 45.2k | case SILDeclRef::Kind::Initializer: |
1188 | 45.2k | return mangler.mangleConstructorEntity(cast<ConstructorDecl>(getDecl()), |
1189 | 45.2k | /*allocating*/ false, |
1190 | 45.2k | SKind); |
1191 | | |
1192 | 1.54k | case SILDeclRef::Kind::IVarInitializer: |
1193 | 16.8k | case SILDeclRef::Kind::IVarDestroyer: |
1194 | 16.8k | return mangler.mangleIVarInitDestroyEntity(cast<ClassDecl>(getDecl()), |
1195 | 16.8k | kind == SILDeclRef::Kind::IVarDestroyer, |
1196 | 16.8k | SKind); |
1197 | | |
1198 | 13.5k | case SILDeclRef::Kind::GlobalAccessor: |
1199 | 13.5k | return mangler.mangleAccessorEntity(AccessorKind::MutableAddress, |
1200 | 13.5k | cast<AbstractStorageDecl>(getDecl()), |
1201 | 13.5k | /*isStatic*/ false, |
1202 | 13.5k | SKind); |
1203 | | |
1204 | 55.3k | case SILDeclRef::Kind::DefaultArgGenerator: |
1205 | 55.3k | return mangler.mangleDefaultArgumentEntity( |
1206 | 55.3k | cast<DeclContext>(getDecl()), |
1207 | 55.3k | defaultArgIndex, |
1208 | 55.3k | SKind); |
1209 | | |
1210 | 32.4k | case SILDeclRef::Kind::StoredPropertyInitializer: |
1211 | 32.4k | return mangler.mangleInitializerEntity(cast<VarDecl>(getDecl()), SKind); |
1212 | | |
1213 | 599 | case SILDeclRef::Kind::PropertyWrapperBackingInitializer: |
1214 | 599 | return mangler.mangleBackingInitializerEntity(cast<VarDecl>(getDecl()), |
1215 | 599 | SKind); |
1216 | | |
1217 | 66 | case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue: |
1218 | 66 | return mangler.mangleInitFromProjectedValueEntity(cast<VarDecl>(getDecl()), |
1219 | 66 | SKind); |
1220 | | |
1221 | 492 | case SILDeclRef::Kind::AsyncEntryPoint: { |
1222 | 492 | return "async_Main"; |
1223 | 1.54k | } |
1224 | 20.6k | case SILDeclRef::Kind::EntryPoint: { |
1225 | 20.6k | return getASTContext().getEntryPointFunctionName(); |
1226 | 1.54k | } |
1227 | 2.05M | } |
1228 | | |
1229 | 0 | llvm_unreachable("bad entity kind!"); |
1230 | 0 | } |
1231 | | |
1232 | | // Returns true if the given JVP/VJP SILDeclRef requires a new vtable entry. |
1233 | | // FIXME(https://github.com/apple/swift/issues/54833): Also consider derived declaration `@derivative` attributes. |
1234 | 20.0k | static bool derivativeFunctionRequiresNewVTableEntry(SILDeclRef declRef) { |
1235 | 20.0k | assert(declRef.getDerivativeFunctionIdentifier() && |
1236 | 20.0k | "Expected a derivative function SILDeclRef"); |
1237 | 0 | auto overridden = declRef.getOverridden(); |
1238 | 20.0k | if (!overridden) |
1239 | 18.1k | return false; |
1240 | | // Get the derived `@differentiable` attribute. |
1241 | 1.85k | auto *derivedDiffAttr = *llvm::find_if( |
1242 | 1.85k | declRef.getDecl()->getAttrs().getAttributes<DifferentiableAttr>(), |
1243 | 1.93k | [&](const DifferentiableAttr *derivedDiffAttr) { |
1244 | 1.93k | return derivedDiffAttr->getParameterIndices() == |
1245 | 1.93k | declRef.getDerivativeFunctionIdentifier()->getParameterIndices(); |
1246 | 1.93k | }); |
1247 | 1.85k | assert(derivedDiffAttr && "Expected `@differentiable` attribute"); |
1248 | | // Otherwise, if the base `@differentiable` attribute specifies a derivative |
1249 | | // function, then the derivative is inherited and no new vtable entry is |
1250 | | // needed. Return false. |
1251 | 0 | auto baseDiffAttrs = |
1252 | 1.85k | overridden.getDecl()->getAttrs().getAttributes<DifferentiableAttr>(); |
1253 | 1.85k | for (auto *baseDiffAttr : baseDiffAttrs) { |
1254 | 1.36k | if (baseDiffAttr->getParameterIndices() == |
1255 | 1.36k | declRef.getDerivativeFunctionIdentifier()->getParameterIndices()) |
1256 | 416 | return false; |
1257 | 1.36k | } |
1258 | | // Otherwise, if there is no base `@differentiable` attribute exists, then a |
1259 | | // new vtable entry is needed. Return true. |
1260 | 1.44k | return true; |
1261 | 1.85k | } |
1262 | | |
1263 | 91.6M | bool SILDeclRef::requiresNewVTableEntry() const { |
1264 | 91.6M | if (getDerivativeFunctionIdentifier()) |
1265 | 20.0k | if (derivativeFunctionRequiresNewVTableEntry(*this)) |
1266 | 1.44k | return true; |
1267 | 91.6M | if (!hasDecl()) |
1268 | 0 | return false; |
1269 | 91.6M | if (isBackDeploymentThunk()) |
1270 | 0 | return false; |
1271 | 91.6M | auto fnDecl = dyn_cast<AbstractFunctionDecl>(getDecl()); |
1272 | 91.6M | if (!fnDecl) |
1273 | 13.0k | return false; |
1274 | 91.6M | if (fnDecl->needsNewVTableEntry()) |
1275 | 91.0M | return true; |
1276 | 588k | return false; |
1277 | 91.6M | } |
1278 | | |
1279 | 2.66M | bool SILDeclRef::requiresNewWitnessTableEntry() const { |
1280 | 2.66M | return cast<AbstractFunctionDecl>(getDecl())->requiresNewWitnessTableEntry(); |
1281 | 2.66M | } |
1282 | | |
1283 | 2.83M | SILDeclRef SILDeclRef::getOverridden() const { |
1284 | 2.83M | if (!hasDecl()) |
1285 | 0 | return SILDeclRef(); |
1286 | 2.83M | auto overridden = getDecl()->getOverriddenDecl(); |
1287 | 2.83M | if (!overridden) |
1288 | 2.66M | return SILDeclRef(); |
1289 | 170k | return withDecl(overridden); |
1290 | 2.83M | } |
1291 | | |
1292 | 2.79M | SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const { |
1293 | 2.79M | if (auto overridden = getOverridden()) { |
1294 | | // Back deployed methods should not be overridden. |
1295 | 167k | assert(backDeploymentKind == SILDeclRef::BackDeploymentKind::None); |
1296 | | |
1297 | | // If we overrode a foreign decl or dynamic method, if this is an |
1298 | | // accessor for a property that overrides an ObjC decl, or if it is an |
1299 | | // @NSManaged property, then it won't be in the vtable. |
1300 | 167k | if (overridden.getDecl()->hasClangNode()) |
1301 | 48.7k | return SILDeclRef(); |
1302 | | |
1303 | | // Distributed thunks are not in the vtable. |
1304 | 119k | if (isDistributedThunk()) |
1305 | 0 | return SILDeclRef(); |
1306 | | |
1307 | | // An @objc convenience initializer can be "overridden" in the sense that |
1308 | | // its selector is reclaimed by a subclass's convenience init with the |
1309 | | // same name. The AST models this as an override for the purposes of |
1310 | | // ObjC selector validation, but it isn't for Swift method dispatch |
1311 | | // purposes. |
1312 | 119k | if (overridden.kind == SILDeclRef::Kind::Allocator) { |
1313 | 33.5k | auto overriddenCtor = cast<ConstructorDecl>(overridden.getDecl()); |
1314 | 33.5k | if (!overriddenCtor->isDesignatedInit() |
1315 | 33.5k | && !overriddenCtor->isRequired()) |
1316 | 129 | return SILDeclRef(); |
1317 | 33.5k | } |
1318 | | |
1319 | | // Initializing entry points for initializers won't be in the vtable. |
1320 | | // For Swift designated initializers, they're only used in super.init |
1321 | | // chains, which can always be statically resolved. Other native Swift |
1322 | | // initializers only have allocating entry points. ObjC initializers always |
1323 | | // have the initializing entry point (corresponding to the -init method) |
1324 | | // but those are never in the vtable. |
1325 | 119k | if (overridden.kind == SILDeclRef::Kind::Initializer) { |
1326 | 2.79k | return SILDeclRef(); |
1327 | 2.79k | } |
1328 | | |
1329 | | // Overrides of @objc dynamic declarations are not in the vtable. |
1330 | 116k | if (overridden.getDecl()->shouldUseObjCDispatch()) { |
1331 | 3.07k | return SILDeclRef(); |
1332 | 3.07k | } |
1333 | | |
1334 | 113k | if (auto *accessor = dyn_cast<AccessorDecl>(overridden.getDecl())) { |
1335 | 26.1k | auto *asd = accessor->getStorage(); |
1336 | 26.1k | if (asd->hasClangNode()) |
1337 | 0 | return SILDeclRef(); |
1338 | 26.1k | if (asd->shouldUseObjCDispatch()) { |
1339 | 0 | return SILDeclRef(); |
1340 | 0 | } |
1341 | 26.1k | } |
1342 | | |
1343 | | // If we overrode a decl from an extension, it won't be in a vtable |
1344 | | // either. This can occur for extensions to ObjC classes. |
1345 | 113k | if (isa<ExtensionDecl>(overridden.getDecl()->getDeclContext())) |
1346 | 9 | return SILDeclRef(); |
1347 | | |
1348 | | // JVPs/VJPs are overridden only if the base declaration has a |
1349 | | // `@differentiable` attribute with the same parameter indices. |
1350 | 113k | if (getDerivativeFunctionIdentifier()) { |
1351 | 560 | auto overriddenAttrs = |
1352 | 560 | overridden.getDecl()->getAttrs().getAttributes<DifferentiableAttr>(); |
1353 | 560 | for (const auto *attr : overriddenAttrs) { |
1354 | 496 | if (attr->getParameterIndices() != |
1355 | 496 | getDerivativeFunctionIdentifier()->getParameterIndices()) |
1356 | 80 | continue; |
1357 | 416 | auto *overriddenDerivativeId = |
1358 | 416 | overridden.getDerivativeFunctionIdentifier(); |
1359 | 416 | overridden.pointer = |
1360 | 416 | AutoDiffDerivativeFunctionIdentifier::get( |
1361 | 416 | overriddenDerivativeId->getKind(), |
1362 | 416 | overriddenDerivativeId->getParameterIndices(), |
1363 | 416 | attr->getDerivativeGenericSignature(), |
1364 | 416 | getDecl()->getASTContext()); |
1365 | 416 | return overridden; |
1366 | 496 | } |
1367 | 144 | return SILDeclRef(); |
1368 | 560 | } |
1369 | 112k | return overridden; |
1370 | 113k | } |
1371 | 2.62M | return SILDeclRef(); |
1372 | 2.79M | } |
1373 | | |
1374 | 7.53k | SILDeclRef SILDeclRef::getOverriddenWitnessTableEntry() const { |
1375 | 7.53k | auto bestOverridden = |
1376 | 7.53k | getOverriddenWitnessTableEntry(cast<AbstractFunctionDecl>(getDecl())); |
1377 | 7.53k | return withDecl(bestOverridden); |
1378 | 7.53k | } |
1379 | | |
1380 | | AbstractFunctionDecl *SILDeclRef::getOverriddenWitnessTableEntry( |
1381 | 7.55k | AbstractFunctionDecl *func) { |
1382 | 7.55k | if (!isa<ProtocolDecl>(func->getDeclContext())) |
1383 | 1.03k | return func; |
1384 | | |
1385 | 6.52k | AbstractFunctionDecl *bestOverridden = nullptr; |
1386 | | |
1387 | 6.52k | SmallVector<AbstractFunctionDecl *, 4> stack; |
1388 | 6.52k | SmallPtrSet<AbstractFunctionDecl *, 4> visited; |
1389 | 6.52k | stack.push_back(func); |
1390 | 6.52k | visited.insert(func); |
1391 | | |
1392 | 19.9k | while (!stack.empty()) { |
1393 | 13.4k | auto current = stack.back(); |
1394 | 13.4k | stack.pop_back(); |
1395 | | |
1396 | 13.4k | auto overriddenDecls = current->getOverriddenDecls(); |
1397 | 13.4k | if (overriddenDecls.empty()) { |
1398 | | // This entry introduced a witness table entry. Determine whether it is |
1399 | | // better than the best entry we've seen thus far. |
1400 | 6.52k | if (!bestOverridden || |
1401 | 6.52k | ProtocolDecl::compare( |
1402 | 3 | cast<ProtocolDecl>(current->getDeclContext()), |
1403 | 3 | cast<ProtocolDecl>(bestOverridden->getDeclContext())) |
1404 | 6.52k | < 0) { |
1405 | 6.52k | bestOverridden = cast<AbstractFunctionDecl>(current); |
1406 | 6.52k | } |
1407 | | |
1408 | 6.52k | continue; |
1409 | 6.52k | } |
1410 | | |
1411 | | // Add overridden declarations to the stack. |
1412 | 6.95k | for (auto overridden : overriddenDecls) { |
1413 | 6.95k | auto overriddenFunc = cast<AbstractFunctionDecl>(overridden); |
1414 | 6.95k | if (visited.insert(overriddenFunc).second) |
1415 | 6.95k | stack.push_back(overriddenFunc); |
1416 | 6.95k | } |
1417 | 6.94k | } |
1418 | | |
1419 | 6.52k | return bestOverridden; |
1420 | 7.55k | } |
1421 | | |
1422 | 89.4M | SILDeclRef SILDeclRef::getOverriddenVTableEntry() const { |
1423 | 89.4M | SILDeclRef cur = *this, next = *this; |
1424 | 89.4M | do { |
1425 | 89.4M | cur = next; |
1426 | 89.4M | if (cur.requiresNewVTableEntry()) |
1427 | 89.1M | return cur; |
1428 | 254k | next = cur.getNextOverriddenVTableEntry(); |
1429 | 254k | } while (next); |
1430 | | |
1431 | 235k | return cur; |
1432 | 89.4M | } |
1433 | | |
1434 | 8.84M | SILLocation SILDeclRef::getAsRegularLocation() const { |
1435 | 8.84M | switch (getLocKind()) { |
1436 | 8.12M | case LocKind::Decl: |
1437 | 8.12M | return RegularLocation(getDecl()); |
1438 | 724k | case LocKind::Closure: |
1439 | 724k | return RegularLocation(getAbstractClosureExpr()); |
1440 | 18 | case LocKind::File: |
1441 | 18 | return RegularLocation::getModuleLocation(); |
1442 | 8.84M | } |
1443 | 0 | llvm_unreachable("Unhandled case in switch"); |
1444 | 0 | } |
1445 | | |
1446 | 1.39M | SubclassScope SILDeclRef::getSubclassScope() const { |
1447 | 1.39M | if (!hasDecl()) |
1448 | 101k | return SubclassScope::NotApplicable; |
1449 | | |
1450 | 1.28M | auto *decl = getDecl(); |
1451 | | |
1452 | 1.28M | if (!isa<AbstractFunctionDecl>(decl)) |
1453 | 50.3k | return SubclassScope::NotApplicable; |
1454 | | |
1455 | 1.23M | DeclContext *context = decl->getDeclContext(); |
1456 | | |
1457 | | // Only methods in non-final classes go in the vtable. |
1458 | 1.23M | auto *classType = dyn_cast<ClassDecl>(context); |
1459 | 1.23M | if (!classType || classType->isFinal()) |
1460 | 1.00M | return SubclassScope::NotApplicable; |
1461 | | |
1462 | | // If a method appears in the vtable of a class, we must give it's symbol |
1463 | | // special consideration when computing visibility because the SIL-level |
1464 | | // linkage does not map to the symbol's visibility in a straightforward |
1465 | | // way. |
1466 | | // |
1467 | | // In particular, the rules are: |
1468 | | // - If the class metadata is not resilient, then all method symbols must |
1469 | | // be visible from any translation unit where a subclass might be defined, |
1470 | | // because the subclass metadata will re-emit all vtable entries. |
1471 | | // |
1472 | | // - For resilient classes, we do the opposite: generally, a method's symbol |
1473 | | // can be hidden from other translation units, because we want to enforce |
1474 | | // that resilient access patterns are used for method calls and overrides. |
1475 | | // |
1476 | | // Constructors and final methods are the exception here, because they can |
1477 | | // be called directly. |
1478 | | |
1479 | | // FIXME: This is too narrow. Any class with resilient metadata should |
1480 | | // probably have this, at least for method overrides that don't add new |
1481 | | // vtable entries. |
1482 | 236k | bool isResilientClass = classType->isResilient(); |
1483 | | |
1484 | 236k | if (auto *CD = dyn_cast<ConstructorDecl>(decl)) { |
1485 | 74.9k | if (isResilientClass) |
1486 | 10.1k | return SubclassScope::NotApplicable; |
1487 | | // Initializing entry points do not appear in the vtable. |
1488 | 64.8k | if (kind == SILDeclRef::Kind::Initializer) |
1489 | 33.7k | return SubclassScope::NotApplicable; |
1490 | | // Non-required convenience inits do not appear in the vtable. |
1491 | 31.0k | if (!CD->isRequired() && !CD->isDesignatedInit()) |
1492 | 1.52k | return SubclassScope::NotApplicable; |
1493 | 161k | } else if (isa<DestructorDecl>(decl)) { |
1494 | | // Destructors do not appear in the vtable. |
1495 | 53.2k | return SubclassScope::NotApplicable; |
1496 | 108k | } else { |
1497 | 108k | assert(isa<FuncDecl>(decl)); |
1498 | 108k | } |
1499 | | |
1500 | | // Various forms of thunks don't go in the vtable. |
1501 | 137k | if (isThunk() || isForeign) |
1502 | 7.60k | return SubclassScope::NotApplicable; |
1503 | | |
1504 | | // Default arg generators don't go in the vtable. |
1505 | 130k | if (isDefaultArgGenerator()) |
1506 | 2.31k | return SubclassScope::NotApplicable; |
1507 | | |
1508 | 127k | if (decl->isFinal()) { |
1509 | | // Final methods only go in the vtable if they override something. |
1510 | 18.4k | if (!decl->getOverriddenDecl()) |
1511 | 16.4k | return SubclassScope::NotApplicable; |
1512 | | |
1513 | | // In the resilient case, we're going to be making symbols _less_ |
1514 | | // visible, so make sure we stop now; final methods can always be |
1515 | | // called directly. |
1516 | 1.96k | if (isResilientClass) |
1517 | 381 | return SubclassScope::Internal; |
1518 | 1.96k | } |
1519 | | |
1520 | 110k | assert(decl->getEffectiveAccess() <= classType->getEffectiveAccess() && |
1521 | 110k | "class must be as visible as its members"); |
1522 | | |
1523 | 110k | if (isResilientClass) { |
1524 | | // The symbol should _only_ be reached via the vtable, so we're |
1525 | | // going to make it hidden. |
1526 | 18.7k | return SubclassScope::Resilient; |
1527 | 18.7k | } |
1528 | | |
1529 | 92.2k | switch (classType->getEffectiveAccess()) { |
1530 | 0 | case AccessLevel::Private: |
1531 | 5.85k | case AccessLevel::FilePrivate: |
1532 | | // If the class is private, it can only be subclassed from the same |
1533 | | // SILModule, so we don't need to do anything. |
1534 | 5.85k | return SubclassScope::NotApplicable; |
1535 | 46.0k | case AccessLevel::Internal: |
1536 | 46.0k | case AccessLevel::Package: |
1537 | 67.3k | case AccessLevel::Public: |
1538 | | // If the class is internal or public, it can only be subclassed from |
1539 | | // the same AST Module, but possibly a different SILModule. |
1540 | 67.3k | return SubclassScope::Internal; |
1541 | 18.9k | case AccessLevel::Open: |
1542 | | // If the class is open, it can be subclassed from a different |
1543 | | // AST Module. All method symbols are public. |
1544 | 18.9k | return SubclassScope::External; |
1545 | 92.2k | } |
1546 | | |
1547 | 0 | llvm_unreachable("Unhandled access level in switch."); |
1548 | 0 | } |
1549 | | |
1550 | 34.4k | Expr *SILDeclRef::getInitializationExpr() const { |
1551 | 34.4k | switch (kind) { |
1552 | 27.5k | case Kind::StoredPropertyInitializer: { |
1553 | 27.5k | auto *var = cast<VarDecl>(getDecl()); |
1554 | 27.5k | auto *pbd = var->getParentPatternBinding(); |
1555 | 27.5k | unsigned idx = pbd->getPatternEntryIndexForVarDecl(var); |
1556 | 27.5k | auto *init = pbd->getInit(idx); |
1557 | 27.5k | assert(!pbd->isInitializerSubsumed(idx)); |
1558 | | |
1559 | | // If this is the backing storage for a property with an attached wrapper |
1560 | | // that was initialized with `=`, use that expression as the initializer. |
1561 | 27.5k | if (auto originalProperty = var->getOriginalWrappedProperty()) { |
1562 | 551 | if (originalProperty->isPropertyMemberwiseInitializedWithWrappedType()) { |
1563 | 479 | auto wrapperInfo = |
1564 | 479 | originalProperty->getPropertyWrapperInitializerInfo(); |
1565 | 479 | auto *placeholder = wrapperInfo.getWrappedValuePlaceholder(); |
1566 | 479 | init = placeholder->getOriginalWrappedValue(); |
1567 | 479 | assert(init); |
1568 | 479 | } |
1569 | 551 | } |
1570 | 0 | return init; |
1571 | 0 | } |
1572 | 626 | case Kind::PropertyWrapperBackingInitializer: { |
1573 | 626 | auto *var = cast<VarDecl>(getDecl()); |
1574 | 626 | auto wrapperInfo = var->getPropertyWrapperInitializerInfo(); |
1575 | 626 | assert(wrapperInfo.hasInitFromWrappedValue()); |
1576 | 0 | return wrapperInfo.getInitFromWrappedValue(); |
1577 | 0 | } |
1578 | 66 | case Kind::PropertyWrapperInitFromProjectedValue: { |
1579 | 66 | auto *var = cast<VarDecl>(getDecl()); |
1580 | 66 | auto wrapperInfo = var->getPropertyWrapperInitializerInfo(); |
1581 | 66 | assert(wrapperInfo.hasInitFromProjectedValue()); |
1582 | 0 | return wrapperInfo.getInitFromProjectedValue(); |
1583 | 0 | } |
1584 | 6.24k | default: |
1585 | 6.24k | return nullptr; |
1586 | 34.4k | } |
1587 | 34.4k | } |
1588 | | |
1589 | 2.25M | unsigned SILDeclRef::getParameterListCount() const { |
1590 | | // Only decls can introduce currying. |
1591 | 2.25M | if (!hasDecl()) |
1592 | 184k | return 1; |
1593 | | |
1594 | | // Always uncurried even if the underlying function is curried. |
1595 | 2.07M | if (kind == Kind::DefaultArgGenerator || kind == Kind::EntryPoint || |
1596 | 2.07M | kind == Kind::AsyncEntryPoint) |
1597 | 83.9k | return 1; |
1598 | | |
1599 | 1.98M | auto *vd = getDecl(); |
1600 | | |
1601 | 1.98M | if (isa<AbstractFunctionDecl>(vd) || isa<EnumElementDecl>(vd)) { |
1602 | | // For functions and enum elements, the number of parameter lists is the |
1603 | | // same as in their interface type. |
1604 | 1.92M | return vd->getNumCurryLevels(); |
1605 | 1.92M | } else if (isa<ClassDecl>(vd)) { |
1606 | 1.41k | return 2; |
1607 | 63.7k | } else if (isa<VarDecl>(vd)) { |
1608 | 63.7k | return 1; |
1609 | 63.7k | } else { |
1610 | 0 | llvm_unreachable("Unhandled ValueDecl for SILDeclRef"); |
1611 | 0 | } |
1612 | 1.98M | } |
1613 | | |
1614 | 276k | static bool isDesignatedConstructorForClass(ValueDecl *decl) { |
1615 | 276k | if (auto *ctor = dyn_cast_or_null<ConstructorDecl>(decl)) |
1616 | 276k | if (ctor->getDeclContext()->getSelfClassDecl()) |
1617 | 109k | return ctor->isDesignatedInit(); |
1618 | 166k | return false; |
1619 | 276k | } |
1620 | | |
1621 | 1.26k | bool SILDeclRef::canBeDynamicReplacement() const { |
1622 | | // The foreign entry of a @dynamicReplacement(for:) of @objc method in a |
1623 | | // generic class can't be a dynamic replacement. |
1624 | 1.26k | if (isForeign && hasDecl() && getDecl()->isNativeMethodReplacement()) |
1625 | 0 | return false; |
1626 | 1.26k | if (isDistributedThunk()) |
1627 | 0 | return false; |
1628 | 1.26k | if (backDeploymentKind != SILDeclRef::BackDeploymentKind::None) |
1629 | 0 | return false; |
1630 | 1.26k | if (kind == SILDeclRef::Kind::Destroyer || |
1631 | 1.26k | kind == SILDeclRef::Kind::DefaultArgGenerator) |
1632 | 0 | return false; |
1633 | 1.26k | if (kind == SILDeclRef::Kind::Initializer) |
1634 | 27 | return isDesignatedConstructorForClass(getDecl()); |
1635 | 1.24k | if (kind == SILDeclRef::Kind::Allocator) |
1636 | 177 | return !isDesignatedConstructorForClass(getDecl()); |
1637 | 1.06k | return true; |
1638 | 1.24k | } |
1639 | | |
1640 | 1.56M | bool SILDeclRef::isDynamicallyReplaceable() const { |
1641 | | // The non-foreign entry of a @dynamicReplacement(for:) of @objc method in a |
1642 | | // generic class can't be a dynamically replaced. |
1643 | 1.56M | if (!isForeign && hasDecl() && getDecl()->isNativeMethodReplacement()) |
1644 | 36 | return false; |
1645 | | |
1646 | 1.56M | if (isDistributedThunk()) |
1647 | 387 | return false; |
1648 | | |
1649 | 1.56M | if (backDeploymentKind != SILDeclRef::BackDeploymentKind::None) |
1650 | 1.90k | return false; |
1651 | | |
1652 | 1.55M | if (kind == SILDeclRef::Kind::DefaultArgGenerator) |
1653 | 60.0k | return false; |
1654 | 1.49M | if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer()) |
1655 | 29.0k | return false; |
1656 | | |
1657 | | // Class allocators are not dynamic replaceable. |
1658 | 1.46M | if (kind == SILDeclRef::Kind::Allocator && |
1659 | 1.46M | isDesignatedConstructorForClass(getDecl())) |
1660 | 51.5k | return false; |
1661 | | |
1662 | 1.41M | if (kind == SILDeclRef::Kind::Destroyer || |
1663 | 1.41M | (kind == SILDeclRef::Kind::Initializer && |
1664 | 1.39M | !isDesignatedConstructorForClass(getDecl())) || |
1665 | 1.41M | kind == SILDeclRef::Kind::GlobalAccessor) { |
1666 | 39.0k | return false; |
1667 | 39.0k | } |
1668 | | |
1669 | 1.37M | if (!hasDecl()) |
1670 | 101k | return false; |
1671 | | |
1672 | 1.27M | auto decl = getDecl(); |
1673 | | |
1674 | 1.27M | if (isForeign) |
1675 | 23.9k | return false; |
1676 | | |
1677 | | // We can't generate categories for generic classes. So the standard mechanism |
1678 | | // for replacing @objc dynamic methods in generic classes does not work. |
1679 | | // Instead we mark the non @objc entry dynamically replaceable and replace |
1680 | | // that. |
1681 | | // For now, we only support this behavior if -enable-implicit-dynamic is |
1682 | | // enabled. |
1683 | 1.25M | return decl->shouldUseNativeMethodReplacement(); |
1684 | 1.27M | } |
1685 | | |
1686 | 358k | bool SILDeclRef::hasAsync() const { |
1687 | 358k | if (isDistributedThunk()) |
1688 | 18 | return true; |
1689 | | |
1690 | 358k | if (hasDecl()) { |
1691 | 358k | if (auto afd = dyn_cast<AbstractFunctionDecl>(getDecl())) { |
1692 | 358k | return afd->hasAsync(); |
1693 | 358k | } |
1694 | 0 | return false; |
1695 | 358k | } |
1696 | 60 | return getAbstractClosureExpr()->isBodyAsync(); |
1697 | 358k | } |