@@ -305,9 +305,18 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {
305
305
return decl->getAttrs ().hasAttribute <UnsafeAttr>();
306
306
}
307
307
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
+
308
318
static bool usesFeatureABIAttribute (Decl *decl) {
309
- auto abiAttr = decl->getAttrs ().getAttribute <ABIAttr>();
310
- return abiAttr && !abiAttr->isInverse ();
319
+ return getABIAttr (decl) != nullptr ;
311
320
}
312
321
313
322
UNINTERESTING_FEATURE (WarnUnsafe)
@@ -411,26 +420,40 @@ static bool allowFeatureSuppression(StringRef featureName, Decl *decl) {
411
420
// / Go through all the features used by the given declaration and
412
421
// / either add or remove them to this set.
413
422
void 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
+
414
435
// Go through each of the features, checking whether the
415
436
// declaration uses that feature.
416
437
#define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
417
- if (usesFeature##FeatureName (decl)) \
438
+ if (CHECK ( usesFeature##FeatureName)) \
418
439
collectRequiredFeature (Feature::FeatureName, operation);
419
440
#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)) \
422
443
collectRequiredFeature (Feature::FeatureName, operation); \
423
444
else \
424
445
collectSuppressibleFeature (Feature::FeatureName, operation); \
425
446
}
426
447
#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)) \
429
450
collectSuppressibleFeature (Feature::FeatureName, operation); \
430
451
else \
431
452
collectRequiredFeature (Feature::FeatureName, operation); \
432
453
}
433
454
#include " swift/Basic/Features.def"
455
+ #undef CHECK
456
+ #undef CHECK_ARG
434
457
}
435
458
436
459
FeatureSet swift::getUniqueFeaturesUsed (Decl *decl) {
0 commit comments