@@ -302,30 +302,47 @@ bool Decl::isAvailableAsSPI() const {
302302}
303303
304304llvm::Optional<AvailableAttrDeclPair>
305- SemanticUnavailableAttrRequest::evaluate (Evaluator &evaluator,
306- const Decl *decl ) const {
305+ SemanticUnavailableAttrRequest::evaluate (Evaluator &evaluator, const Decl *decl,
306+ bool ignoreAppExtensions ) const {
307307 // Directly marked unavailable.
308- if (auto attr = decl->getAttrs ().getUnavailable (decl->getASTContext ()))
308+ if (auto attr = decl->getAttrs ().getUnavailable (decl->getASTContext (),
309+ ignoreAppExtensions))
309310 return std::make_pair (attr, decl);
310311
311312 if (auto *parent =
312313 AvailabilityInference::parentDeclForInferredAvailability (decl))
313- return parent->getSemanticUnavailableAttr ();
314+ return parent->getSemanticUnavailableAttr (ignoreAppExtensions );
314315
315316 return llvm::None;
316317}
317318
318- llvm::Optional<AvailableAttrDeclPair> Decl::getSemanticUnavailableAttr () const {
319+ llvm::Optional<AvailableAttrDeclPair>
320+ Decl::getSemanticUnavailableAttr (bool ignoreAppExtensions) const {
319321 auto &eval = getASTContext ().evaluator ;
320- return evaluateOrDefault (eval, SemanticUnavailableAttrRequest{this },
321- llvm::None);
322+ return evaluateOrDefault (
323+ eval, SemanticUnavailableAttrRequest{this , ignoreAppExtensions},
324+ llvm::None);
322325}
323326
324- static bool isUnconditionallyUnavailable (const Decl *D) {
325- if (auto unavailableAttrAndDecl = D->getSemanticUnavailableAttr ())
326- return unavailableAttrAndDecl->first ->isUnconditionallyUnavailable ();
327+ static bool shouldStubOrSkipUnavailableDecl (const Decl *D) {
328+ // Don't trust unavailability on declarations from clang modules.
329+ if (isa<ClangModuleUnit>(D->getDeclContext ()->getModuleScopeContext ()))
330+ return false ;
331+
332+ auto unavailableAttrAndDecl =
333+ D->getSemanticUnavailableAttr (/* ignoreAppExtensions=*/ true );
334+ if (!unavailableAttrAndDecl)
335+ return false ;
327336
328- return false ;
337+ // getSemanticUnavailableAttr() can return an @available attribute that makes
338+ // its declaration unavailable conditionally due to deployment target. Only
339+ // stub or skip a declaration that is unavailable regardless of deployment
340+ // target.
341+ auto *unavailableAttr = unavailableAttrAndDecl->first ;
342+ if (!unavailableAttr->isUnconditionallyUnavailable ())
343+ return false ;
344+
345+ return true ;
329346}
330347
331348static UnavailableDeclOptimization
@@ -343,10 +360,7 @@ bool Decl::isAvailableDuringLowering() const {
343360 UnavailableDeclOptimization::Complete)
344361 return true ;
345362
346- if (isa<ClangModuleUnit>(getDeclContext ()->getModuleScopeContext ()))
347- return true ;
348-
349- return !isUnconditionallyUnavailable (this );
363+ return !shouldStubOrSkipUnavailableDecl (this );
350364}
351365
352366bool Decl::requiresUnavailableDeclABICompatibilityStubs () const {
@@ -356,10 +370,7 @@ bool Decl::requiresUnavailableDeclABICompatibilityStubs() const {
356370 UnavailableDeclOptimization::Stub)
357371 return false ;
358372
359- if (isa<ClangModuleUnit>(getDeclContext ()->getModuleScopeContext ()))
360- return false ;
361-
362- return isUnconditionallyUnavailable (this );
373+ return shouldStubOrSkipUnavailableDecl (this );
363374}
364375
365376bool UnavailabilityReason::requiresDeploymentTargetOrEarlier (
0 commit comments