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