@@ -689,60 +689,72 @@ const AvailableAttr *Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
689
689
return nullptr ;
690
690
}
691
691
692
- std::optional<AvailableAttrDeclPair>
693
- SemanticUnavailableAttrRequest::evaluate (Evaluator &evaluator, const Decl *decl,
694
- bool ignoreAppExtensions) const {
695
- // Directly marked unavailable.
696
- if (auto attr = decl->getUnavailableAttr (ignoreAppExtensions))
697
- return std::make_pair (attr, decl);
698
-
699
- if (auto *parent =
700
- AvailabilityInference::parentDeclForInferredAvailability (decl))
701
- return parent->getSemanticUnavailableAttr (ignoreAppExtensions);
702
-
703
- return std::nullopt ;
704
- }
705
-
706
- std::optional<AvailableAttrDeclPair>
707
- Decl::getSemanticUnavailableAttr (bool ignoreAppExtensions) const {
708
- auto &eval = getASTContext ().evaluator ;
709
- return evaluateOrDefault (
710
- eval, SemanticUnavailableAttrRequest{this , ignoreAppExtensions},
711
- std::nullopt );
712
- }
713
-
714
- bool Decl::isUnreachableAtRuntime () const {
692
+ static bool isDeclCompletelyUnavailable (const Decl *decl) {
715
693
// Don't trust unavailability on declarations from clang modules.
716
- if (isa<ClangModuleUnit>(getDeclContext ()->getModuleScopeContext ()))
694
+ if (isa<ClangModuleUnit>(decl-> getDeclContext ()->getModuleScopeContext ()))
717
695
return false ;
718
696
719
- auto unavailableAttrAndDecl =
720
- getSemanticUnavailableAttr (/* ignoreAppExtensions=*/ true );
721
- if (!unavailableAttrAndDecl )
697
+ auto *unavailableAttr =
698
+ decl-> getUnavailableAttr (/* ignoreAppExtensions=*/ true );
699
+ if (!unavailableAttr )
722
700
return false ;
723
701
724
- // getSemanticUnavailableAttr() can return an @available attribute that makes
725
- // its declaration unavailable conditionally due to deployment target. Only
726
- // stub or skip a declaration that is unavailable regardless of deployment
727
- // target.
728
- auto *unavailableAttr = unavailableAttrAndDecl->first ;
702
+ // getUnavailableAttr() can return an @available attribute that is
703
+ // obsoleted for certain deployment targets or language modes. These decls
704
+ // can still be reached by code in other modules that is compiled with
705
+ // a different deployment target or language mode.
729
706
if (!unavailableAttr->isUnconditionallyUnavailable ())
730
707
return false ;
731
708
732
- // Universally unavailable declarations are always unreachable .
709
+ // Universally unavailable declarations are always completely unavailable .
733
710
if (unavailableAttr->getPlatform () == PlatformKind::none)
734
711
return true ;
735
712
736
713
// FIXME: Support zippered frameworks (rdar://125371621)
737
714
// If we have a target variant (e.g. we're building a zippered macOS
738
715
// framework) then the decl is only unreachable if it is unavailable for both
739
716
// the primary target and the target variant.
740
- if (getASTContext ().LangOpts .TargetVariant .has_value ())
717
+ if (decl-> getASTContext ().LangOpts .TargetVariant .has_value ())
741
718
return false ;
742
719
743
720
return true ;
744
721
}
745
722
723
+ SemanticDeclAvailability
724
+ SemanticDeclAvailabilityRequest::evaluate (Evaluator &evaluator,
725
+ const Decl *decl) const {
726
+ auto inherited = SemanticDeclAvailability::PotentiallyAvailable;
727
+ if (auto *parent =
728
+ AvailabilityInference::parentDeclForInferredAvailability (decl)) {
729
+ inherited = evaluateOrDefault (
730
+ evaluator, SemanticDeclAvailabilityRequest{parent}, inherited);
731
+ }
732
+
733
+ if (inherited == SemanticDeclAvailability::CompletelyUnavailable ||
734
+ isDeclCompletelyUnavailable (decl))
735
+ return SemanticDeclAvailability::CompletelyUnavailable;
736
+
737
+ if (inherited == SemanticDeclAvailability::ConditionallyUnavailable ||
738
+ decl->isUnavailable ())
739
+ return SemanticDeclAvailability::ConditionallyUnavailable;
740
+
741
+ return SemanticDeclAvailability::PotentiallyAvailable;
742
+ }
743
+
744
+ bool Decl::isSemanticallyUnavailable () const {
745
+ auto availability = evaluateOrDefault (
746
+ getASTContext ().evaluator , SemanticDeclAvailabilityRequest{this },
747
+ SemanticDeclAvailability::PotentiallyAvailable);
748
+ return availability != SemanticDeclAvailability::PotentiallyAvailable;
749
+ }
750
+
751
+ bool Decl::isUnreachableAtRuntime () const {
752
+ auto availability = evaluateOrDefault (
753
+ getASTContext ().evaluator , SemanticDeclAvailabilityRequest{this },
754
+ SemanticDeclAvailability::PotentiallyAvailable);
755
+ return availability == SemanticDeclAvailability::CompletelyUnavailable;
756
+ }
757
+
746
758
static UnavailableDeclOptimization
747
759
getEffectiveUnavailableDeclOptimization (ASTContext &ctx) {
748
760
if (ctx.LangOpts .UnavailableDeclOptimizationMode .has_value ())
0 commit comments