@@ -711,18 +711,13 @@ Decl::getSemanticUnavailableAttr(bool ignoreAppExtensions) const {
711
711
std::nullopt);
712
712
}
713
713
714
- bool Decl::isUnreachableAtRuntime () const {
714
+ static bool isDeclCompletelyUnavailable ( const Decl *decl) {
715
715
// Don't trust unavailability on declarations from clang modules.
716
- if (isa<ClangModuleUnit>(getDeclContext ()->getModuleScopeContext ()))
716
+ if (isa<ClangModuleUnit>(decl-> getDeclContext ()->getModuleScopeContext ()))
717
717
return false ;
718
718
719
- if (auto *parent =
720
- AvailabilityInference::parentDeclForInferredAvailability (this )) {
721
- if (parent->isUnreachableAtRuntime ())
722
- return true ;
723
- }
724
-
725
- auto *unavailableAttr = getUnavailableAttr (/* ignoreAppExtensions=*/ true );
719
+ auto *unavailableAttr =
720
+ decl->getUnavailableAttr (/* ignoreAppExtensions=*/ true );
726
721
if (!unavailableAttr)
727
722
return false ;
728
723
@@ -733,27 +728,48 @@ bool Decl::isUnreachableAtRuntime() const {
733
728
if (!unavailableAttr->isUnconditionallyUnavailable ())
734
729
return false ;
735
730
736
- // getUnavailableAttr() can return an @available attribute that makes its
737
- // declaration unavailable conditionally due to deployment target. Only
738
- // stub or skip a declaration that is unavailable regardless of deployment
739
- // target.
740
- if (!unavailableAttr->isUnconditionallyUnavailable ())
741
- return false ;
742
-
743
- // Universally unavailable declarations are always unreachable.
731
+ // Universally unavailable declarations are always completely unavailable.
744
732
if (unavailableAttr->getPlatform () == PlatformKind::none)
745
733
return true ;
746
734
747
735
// FIXME: Support zippered frameworks (rdar://125371621)
748
736
// If we have a target variant (e.g. we're building a zippered macOS
749
737
// framework) then the decl is only unreachable if it is unavailable for both
750
738
// the primary target and the target variant.
751
- if (getASTContext ().LangOpts .TargetVariant .has_value ())
739
+ if (decl-> getASTContext ().LangOpts .TargetVariant .has_value ())
752
740
return false ;
753
741
754
742
return true ;
755
743
}
756
744
745
+ SemanticDeclAvailability
746
+ SemanticDeclAvailabilityRequest::evaluate (Evaluator &evaluator,
747
+ const Decl *decl) const {
748
+ auto inherited = SemanticDeclAvailability::PotentiallyAvailable;
749
+ if (auto *parent =
750
+ AvailabilityInference::parentDeclForInferredAvailability (decl)) {
751
+ inherited = evaluateOrDefault (
752
+ evaluator, SemanticDeclAvailabilityRequest{parent}, inherited);
753
+ }
754
+
755
+ if (inherited == SemanticDeclAvailability::CompletelyUnavailable ||
756
+ isDeclCompletelyUnavailable (decl))
757
+ return SemanticDeclAvailability::CompletelyUnavailable;
758
+
759
+ if (inherited == SemanticDeclAvailability::ConditionallyUnavailable ||
760
+ decl->isUnavailable ())
761
+ return SemanticDeclAvailability::ConditionallyUnavailable;
762
+
763
+ return SemanticDeclAvailability::PotentiallyAvailable;
764
+ }
765
+
766
+ bool Decl::isUnreachableAtRuntime () const {
767
+ auto availability = evaluateOrDefault (
768
+ getASTContext ().evaluator , SemanticDeclAvailabilityRequest{this },
769
+ SemanticDeclAvailability::PotentiallyAvailable);
770
+ return availability == SemanticDeclAvailability::CompletelyUnavailable;
771
+ }
772
+
757
773
static UnavailableDeclOptimization
758
774
getEffectiveUnavailableDeclOptimization (ASTContext &ctx) {
759
775
if (ctx.LangOpts .UnavailableDeclOptimizationMode .has_value ())
0 commit comments