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