@@ -444,83 +444,114 @@ bool SILDeclRef::isTransparent() const {
444
444
445
445
// / True if the function should have its body serialized.
446
446
IsSerialized_t SILDeclRef::isSerialized () const {
447
- // Native-to-foreign thunks are only referenced from the Objective-C
448
- // method table.
449
- if (isForeign)
450
- return IsNotSerialized;
451
-
452
447
DeclContext *dc;
453
- if (auto closure = getAbstractClosureExpr ())
448
+ if (auto closure = getAbstractClosureExpr ()) {
454
449
dc = closure->getLocalContext ();
455
- else {
456
- auto *d = getDecl ();
457
-
458
- // Default argument generators are serialized if the function was
459
- // type-checked in Swift 4 mode.
460
- if (kind == SILDeclRef::Kind::DefaultArgGenerator) {
461
- auto *afd = cast<AbstractFunctionDecl>(d);
462
- switch (afd->getDefaultArgumentResilienceExpansion ()) {
463
- case ResilienceExpansion::Minimal:
464
- return IsSerialized;
465
- case ResilienceExpansion::Maximal:
466
- return IsNotSerialized;
467
- }
450
+
451
+ // Otherwise, ask the AST if we're inside an @inlinable context.
452
+ if (dc->getResilienceExpansion () == ResilienceExpansion::Minimal) {
453
+ if (isForeign)
454
+ return IsSerializable;
455
+
456
+ return IsSerialized;
468
457
}
469
458
470
- // 'read' and 'modify' accessors synthesized on-demand are serialized if
471
- // visible outside the module.
472
- if (auto fn = dyn_cast<FuncDecl>(d))
473
- if (!isClangImported () &&
474
- fn->hasForcedStaticDispatch () &&
475
- fn->getEffectiveAccess () >= AccessLevel::Public)
476
- return IsSerialized;
459
+ return IsNotSerialized;
460
+ }
477
461
478
- dc = getDecl ()->getInnermostDeclContext ();
462
+ if (isIVarInitializerOrDestroyer ())
463
+ return IsNotSerialized;
479
464
480
- // Enum element constructors are serialized if the enum is
481
- // @usableFromInline or public.
482
- if (isEnumElement ())
483
- if (d->getEffectiveAccess () >= AccessLevel::Public)
484
- return IsSerialized;
465
+ auto *d = getDecl ();
485
466
486
- // Currying thunks are serialized if referenced from an inlinable
487
- // context -- Sema's semantic checks ensure the serialization of
488
- // such a thunk is valid, since it must in turn reference a public
489
- // symbol, or dispatch via class_method or witness_method.
490
- if (isCurried)
491
- if (d->getEffectiveAccess () >= AccessLevel::Public)
492
- return IsSerializable;
467
+ // Default argument generators are serialized if the function was
468
+ // type-checked in Swift 4 mode.
469
+ if (isDefaultArgGenerator ()) {
470
+ auto *afd = cast<AbstractFunctionDecl>(d);
471
+ switch (afd->getDefaultArgumentResilienceExpansion ()) {
472
+ case ResilienceExpansion::Minimal:
473
+ return IsSerialized;
474
+ case ResilienceExpansion::Maximal:
475
+ return IsNotSerialized;
476
+ }
477
+ }
478
+
479
+ // Stored property initializers are inlinable if the type is explicitly
480
+ // marked as @_fixed_layout.
481
+ if (isStoredPropertyInitializer ()) {
482
+ auto *nominal = cast<NominalTypeDecl>(d->getDeclContext ());
483
+ auto scope =
484
+ nominal->getFormalAccessScope (/* useDC=*/ nullptr ,
485
+ /* treatUsableFromInlineAsPublic=*/ true );
486
+ if (!scope.isPublic ())
487
+ return IsNotSerialized;
488
+ if (nominal->isFormallyResilient ())
489
+ return IsNotSerialized;
490
+ return IsSerialized;
491
+ }
493
492
494
- if (isForeignToNativeThunk ())
493
+ // Note: if 'd' is a function, then 'dc' is the function itself, not
494
+ // its parent context.
495
+ dc = d->getInnermostDeclContext ();
496
+
497
+ // Local functions are serializable if their parent function is
498
+ // serializable.
499
+ if (d->getDeclContext ()->isLocalContext ()) {
500
+ if (dc->getResilienceExpansion () == ResilienceExpansion::Minimal)
495
501
return IsSerializable;
496
502
497
- // The allocating entry point for designated initializers are serialized
498
- // if the class is @usableFromInline or public.
499
- if (kind == SILDeclRef::Kind::Allocator) {
500
- auto *ctor = cast<ConstructorDecl>(d);
501
- if (ctor->isDesignatedInit () &&
502
- ctor->getDeclContext ()->getSelfClassDecl ()) {
503
- if (ctor->getEffectiveAccess () >= AccessLevel::Public &&
504
- !ctor->hasClangNode ())
505
- return IsSerialized;
506
- }
507
- }
503
+ return IsNotSerialized;
504
+ }
508
505
509
- // Stored property initializers are inlinable if the type is explicitly
510
- // marked as @_fixed_layout.
511
- if (isStoredPropertyInitializer ()) {
512
- auto *nominal = cast<NominalTypeDecl>(d->getDeclContext ());
513
- auto scope =
514
- nominal->getFormalAccessScope (/* useDC=*/ nullptr ,
515
- /* treatUsableFromInlineAsPublic=*/ true );
516
- if (!scope.isPublic ())
517
- return IsNotSerialized;
518
- if (nominal->isFormallyResilient ())
519
- return IsNotSerialized;
506
+ // Anything else that is not public is not serializable.
507
+ if (d->getEffectiveAccess () < AccessLevel::Public)
508
+ return IsNotSerialized;
509
+
510
+ // 'read' and 'modify' accessors synthesized on-demand are serialized if
511
+ // visible outside the module.
512
+ if (auto fn = dyn_cast<FuncDecl>(d))
513
+ if (!isClangImported () &&
514
+ fn->hasForcedStaticDispatch ())
520
515
return IsSerialized;
516
+
517
+ // Enum element constructors are serializable if the enum is
518
+ // @usableFromInline or public.
519
+ if (isEnumElement ())
520
+ return IsSerializable;
521
+
522
+ // Currying thunks are serialized if referenced from an inlinable
523
+ // context -- Sema's semantic checks ensure the serialization of
524
+ // such a thunk is valid, since it must in turn reference a public
525
+ // symbol, or dispatch via class_method or witness_method.
526
+ if (isCurried)
527
+ return IsSerializable;
528
+
529
+ if (isForeignToNativeThunk ())
530
+ return IsSerializable;
531
+
532
+ // The allocating entry point for designated initializers are serialized
533
+ // if the class is @usableFromInline or public.
534
+ if (kind == SILDeclRef::Kind::Allocator) {
535
+ auto *ctor = cast<ConstructorDecl>(d);
536
+ if (ctor->isDesignatedInit () &&
537
+ ctor->getDeclContext ()->getSelfClassDecl ()) {
538
+ if (!ctor->hasClangNode ())
539
+ return IsSerialized;
521
540
}
522
541
}
523
542
543
+ if (isForeign) {
544
+ // @objc thunks for methods are not serializable since they're only
545
+ // referenced from the method table.
546
+ if (d->getDeclContext ()->isTypeContext ())
547
+ return IsNotSerialized;
548
+
549
+ // @objc thunks for top-level functions are serializable since they're
550
+ // referenced from @convention(c) conversions inside inlinable
551
+ // functions.
552
+ return IsSerializable;
553
+ }
554
+
524
555
// Declarations imported from Clang modules are serialized if
525
556
// referenced from an inlinable context.
526
557
if (isClangImported ())
0 commit comments