@@ -319,9 +319,18 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {
319
319
return decl->getAttrs ().hasAttribute <UnsafeAttr>();
320
320
}
321
321
322
+ static ABIAttr *getABIAttr (Decl *decl) {
323
+ if (auto pbd = dyn_cast<PatternBindingDecl>(decl))
324
+ for (auto i : range (pbd->getNumPatternEntries ()))
325
+ if (auto anchorVar = pbd->getAnchoringVarDecl (i))
326
+ return getABIAttr (anchorVar);
327
+ // FIXME: EnumCaseDecl/EnumElementDecl
328
+
329
+ return decl->getAttrs ().getAttribute <ABIAttr>();
330
+ }
331
+
322
332
static bool usesFeatureABIAttribute (Decl *decl) {
323
- auto abiAttr = decl->getAttrs ().getAttribute <ABIAttr>();
324
- return abiAttr && !abiAttr->isInverse ();
333
+ return getABIAttr (decl) != nullptr ;
325
334
}
326
335
327
336
UNINTERESTING_FEATURE (WarnUnsafe)
@@ -425,26 +434,40 @@ static bool allowFeatureSuppression(StringRef featureName, Decl *decl) {
425
434
// / Go through all the features used by the given declaration and
426
435
// / either add or remove them to this set.
427
436
void FeatureSet::collectFeaturesUsed (Decl *decl, InsertOrRemove operation) {
437
+ // Count feature usage in an ABI decl as feature usage by the API, not itself,
438
+ // since we can't use `#if` inside an @abi attribute.
439
+ Decl *abiDecl = nullptr ;
440
+ if (auto abiAttr = getABIAttr (decl)) {
441
+ if (abiAttr->isInverse ())
442
+ return ;
443
+ abiDecl = abiAttr->abiDecl ;
444
+ }
445
+
446
+ #define CHECK (Function ) (Function(decl) || (abiDecl && Function(abiDecl)))
447
+ #define CHECK_ARG (Function, Arg ) (Function(Arg, decl) || (abiDecl && Function(Arg, abiDecl)))
448
+
428
449
// Go through each of the features, checking whether the
429
450
// declaration uses that feature.
430
451
#define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
431
- if (usesFeature##FeatureName (decl)) \
452
+ if (CHECK ( usesFeature##FeatureName)) \
432
453
collectRequiredFeature (Feature::FeatureName, operation);
433
454
#define SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
434
- if (usesFeature##FeatureName (decl )) { \
435
- if (disallowFeatureSuppression (#FeatureName, decl)) \
455
+ if (CHECK ( usesFeature##FeatureName)) { \
456
+ if (CHECK_ARG (disallowFeatureSuppression, #FeatureName)) \
436
457
collectRequiredFeature (Feature::FeatureName, operation); \
437
458
else \
438
459
collectSuppressibleFeature (Feature::FeatureName, operation); \
439
460
}
440
461
#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
441
- if (usesFeature##FeatureName (decl )) { \
442
- if (allowFeatureSuppression (#FeatureName, decl)) \
462
+ if (CHECK ( usesFeature##FeatureName)) { \
463
+ if (CHECK_ARG (allowFeatureSuppression, #FeatureName)) \
443
464
collectSuppressibleFeature (Feature::FeatureName, operation); \
444
465
else \
445
466
collectRequiredFeature (Feature::FeatureName, operation); \
446
467
}
447
468
#include " swift/Basic/Features.def"
469
+ #undef CHECK
470
+ #undef CHECK_ARG
448
471
}
449
472
450
473
FeatureSet swift::getUniqueFeaturesUsed (Decl *decl) {
0 commit comments