@@ -689,60 +689,72 @@ const AvailableAttr *Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
689689 return nullptr ;
690690}
691691
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) {
715693 // Don't trust unavailability on declarations from clang modules.
716- if (isa<ClangModuleUnit>(getDeclContext ()->getModuleScopeContext ()))
694+ if (isa<ClangModuleUnit>(decl-> getDeclContext ()->getModuleScopeContext ()))
717695 return false ;
718696
719- auto unavailableAttrAndDecl =
720- getSemanticUnavailableAttr (/* ignoreAppExtensions=*/ true );
721- if (!unavailableAttrAndDecl )
697+ auto *unavailableAttr =
698+ decl-> getUnavailableAttr (/* ignoreAppExtensions=*/ true );
699+ if (!unavailableAttr )
722700 return false ;
723701
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.
729706 if (!unavailableAttr->isUnconditionallyUnavailable ())
730707 return false ;
731708
732- // Universally unavailable declarations are always unreachable .
709+ // Universally unavailable declarations are always completely unavailable .
733710 if (unavailableAttr->getPlatform () == PlatformKind::none)
734711 return true ;
735712
736713 // FIXME: Support zippered frameworks (rdar://125371621)
737714 // If we have a target variant (e.g. we're building a zippered macOS
738715 // framework) then the decl is only unreachable if it is unavailable for both
739716 // the primary target and the target variant.
740- if (getASTContext ().LangOpts .TargetVariant .has_value ())
717+ if (decl-> getASTContext ().LangOpts .TargetVariant .has_value ())
741718 return false ;
742719
743720 return true ;
744721}
745722
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+
746758static UnavailableDeclOptimization
747759getEffectiveUnavailableDeclOptimization (ASTContext &ctx) {
748760 if (ctx.LangOpts .UnavailableDeclOptimizationMode .has_value ())
0 commit comments