@@ -305,9 +305,18 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {
305305 return decl->getAttrs ().hasAttribute <UnsafeAttr>();
306306}
307307
308+ static ABIAttr *getABIAttr (Decl *decl) {
309+ if (auto pbd = dyn_cast<PatternBindingDecl>(decl))
310+ for (auto i : range (pbd->getNumPatternEntries ()))
311+ if (auto anchorVar = pbd->getAnchoringVarDecl (i))
312+ return getABIAttr (anchorVar);
313+ // FIXME: EnumCaseDecl/EnumElementDecl
314+
315+ return decl->getAttrs ().getAttribute <ABIAttr>();
316+ }
317+
308318static bool usesFeatureABIAttribute (Decl *decl) {
309- auto abiAttr = decl->getAttrs ().getAttribute <ABIAttr>();
310- return abiAttr && !abiAttr->isInverse ();
319+ return getABIAttr (decl) != nullptr ;
311320}
312321
313322UNINTERESTING_FEATURE (WarnUnsafe)
@@ -411,26 +420,40 @@ static bool allowFeatureSuppression(StringRef featureName, Decl *decl) {
411420// / Go through all the features used by the given declaration and
412421// / either add or remove them to this set.
413422void FeatureSet::collectFeaturesUsed (Decl *decl, InsertOrRemove operation) {
423+ // Count feature usage in an ABI decl as feature usage by the API, not itself,
424+ // since we can't use `#if` inside an @abi attribute.
425+ Decl *abiDecl = nullptr ;
426+ if (auto abiAttr = getABIAttr (decl)) {
427+ if (abiAttr->isInverse ())
428+ return ;
429+ abiDecl = abiAttr->abiDecl ;
430+ }
431+
432+ #define CHECK (Function ) (Function(decl) || (abiDecl && Function(abiDecl)))
433+ #define CHECK_ARG (Function, Arg ) (Function(Arg, decl) || (abiDecl && Function(Arg, abiDecl)))
434+
414435 // Go through each of the features, checking whether the
415436 // declaration uses that feature.
416437#define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
417- if (usesFeature##FeatureName (decl)) \
438+ if (CHECK ( usesFeature##FeatureName)) \
418439 collectRequiredFeature (Feature::FeatureName, operation);
419440#define SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
420- if (usesFeature##FeatureName (decl )) { \
421- if (disallowFeatureSuppression (#FeatureName, decl)) \
441+ if (CHECK ( usesFeature##FeatureName)) { \
442+ if (CHECK_ARG (disallowFeatureSuppression, #FeatureName)) \
422443 collectRequiredFeature (Feature::FeatureName, operation); \
423444 else \
424445 collectSuppressibleFeature (Feature::FeatureName, operation); \
425446 }
426447#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
427- if (usesFeature##FeatureName (decl )) { \
428- if (allowFeatureSuppression (#FeatureName, decl)) \
448+ if (CHECK ( usesFeature##FeatureName)) { \
449+ if (CHECK_ARG (allowFeatureSuppression, #FeatureName)) \
429450 collectSuppressibleFeature (Feature::FeatureName, operation); \
430451 else \
431452 collectRequiredFeature (Feature::FeatureName, operation); \
432453 }
433454#include " swift/Basic/Features.def"
455+ #undef CHECK
456+ #undef CHECK_ARG
434457}
435458
436459FeatureSet swift::getUniqueFeaturesUsed (Decl *decl) {
0 commit comments