@@ -292,9 +292,18 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {
292
292
return decl->getAttrs ().hasAttribute <UnsafeAttr>();
293
293
}
294
294
295
+ static ABIAttr *getABIAttr (Decl *decl) {
296
+ if (auto pbd = dyn_cast<PatternBindingDecl>(decl))
297
+ for (auto i : range (pbd->getNumPatternEntries ()))
298
+ if (auto anchorVar = pbd->getAnchoringVarDecl (i))
299
+ return getABIAttr (anchorVar);
300
+ // FIXME: EnumCaseDecl/EnumElementDecl
301
+
302
+ return decl->getAttrs ().getAttribute <ABIAttr>();
303
+ }
304
+
295
305
static bool usesFeatureABIAttribute (Decl *decl) {
296
- auto abiAttr = decl->getAttrs ().getAttribute <ABIAttr>();
297
- return abiAttr && !abiAttr->isInverse ();
306
+ return getABIAttr (decl) != nullptr ;
298
307
}
299
308
300
309
UNINTERESTING_FEATURE (WarnUnsafe)
@@ -395,26 +404,40 @@ static bool allowFeatureSuppression(StringRef featureName, Decl *decl) {
395
404
// / Go through all the features used by the given declaration and
396
405
// / either add or remove them to this set.
397
406
void FeatureSet::collectFeaturesUsed (Decl *decl, InsertOrRemove operation) {
407
+ // Count feature usage in an ABI decl as feature usage by the API, not itself,
408
+ // since we can't use `#if` inside an @abi attribute.
409
+ Decl *abiDecl = nullptr ;
410
+ if (auto abiAttr = getABIAttr (decl)) {
411
+ if (abiAttr->isInverse ())
412
+ return ;
413
+ abiDecl = abiAttr->abiDecl ;
414
+ }
415
+
416
+ #define CHECK (Function ) (Function(decl) || (abiDecl && Function(abiDecl)))
417
+ #define CHECK_ARG (Function, Arg ) (Function(Arg, decl) || (abiDecl && Function(Arg, abiDecl)))
418
+
398
419
// Go through each of the features, checking whether the
399
420
// declaration uses that feature.
400
421
#define LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
401
- if (usesFeature##FeatureName (decl)) \
422
+ if (CHECK ( usesFeature##FeatureName)) \
402
423
collectRequiredFeature (Feature::FeatureName, operation);
403
424
#define SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
404
- if (usesFeature##FeatureName (decl )) { \
405
- if (disallowFeatureSuppression (#FeatureName, decl)) \
425
+ if (CHECK ( usesFeature##FeatureName)) { \
426
+ if (CHECK_ARG (disallowFeatureSuppression, #FeatureName)) \
406
427
collectRequiredFeature (Feature::FeatureName, operation); \
407
428
else \
408
429
collectSuppressibleFeature (Feature::FeatureName, operation); \
409
430
}
410
431
#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE (FeatureName, SENumber, Description ) \
411
- if (usesFeature##FeatureName (decl )) { \
412
- if (allowFeatureSuppression (#FeatureName, decl)) \
432
+ if (CHECK ( usesFeature##FeatureName)) { \
433
+ if (CHECK_ARG (allowFeatureSuppression, #FeatureName)) \
413
434
collectSuppressibleFeature (Feature::FeatureName, operation); \
414
435
else \
415
436
collectRequiredFeature (Feature::FeatureName, operation); \
416
437
}
417
438
#include " swift/Basic/Features.def"
439
+ #undef CHECK
440
+ #undef CHECK_ARG
418
441
}
419
442
420
443
FeatureSet swift::getUniqueFeaturesUsed (Decl *decl) {
0 commit comments