Skip to content

Commit a40cb41

Browse files
committed
Add parsing for a declaration attribute '@warn' for source-level warning group behavior control
1 parent 6dbe0cb commit a40cb41

File tree

19 files changed

+380
-2
lines changed

19 files changed

+380
-2
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,21 @@ BridgedSwiftNativeObjCRuntimeBaseAttr_createParsed(BridgedASTContext cContext,
11001100
swift::SourceRange range,
11011101
swift::Identifier name);
11021102

1103+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedWarningGroupBehavior {
1104+
WarningGroupBehaviorError,
1105+
WarningGroupBehaviorWarning,
1106+
WarningGroupBehaviorIgnored,
1107+
};
1108+
1109+
SWIFT_NAME("BridgedWarnAttr.createParsed(_:atLoc:range:diagGroupName:behavior:reason:)")
1110+
BridgedWarnAttr
1111+
BridgedWarnAttr_createParsed(BridgedASTContext cContext,
1112+
swift::SourceLoc atLoc,
1113+
swift::SourceRange range,
1114+
swift::Identifier diagGroupName,
1115+
BridgedWarningGroupBehavior behavior,
1116+
BridgedStringRef reason);
1117+
11031118
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedNonSendableKind {
11041119
BridgedNonSendableKindSpecific,
11051120
BridgedNonSendableKindAssumed,

include/swift/AST/Attr.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/AvailabilityRange.h"
2424
#include "swift/AST/ConcreteDeclRef.h"
2525
#include "swift/AST/DeclNameLoc.h"
26+
#include "swift/AST/DiagnosticGroups.h"
2627
#include "swift/AST/Identifier.h"
2728
#include "swift/AST/KnownProtocols.h"
2829
#include "swift/AST/LifetimeDependence.h"
@@ -3637,6 +3638,40 @@ class NonexhaustiveAttr : public DeclAttribute {
36373638
}
36383639
};
36393640

3641+
class WarnAttr : public DeclAttribute {
3642+
public:
3643+
enum class Behavior : uint8_t { Error, Warning, Ignored };
3644+
3645+
WarnAttr(DiagGroupID DiagnosticGroupID, Behavior Behavior,
3646+
std::optional<StringRef> Reason, SourceLoc AtLoc, SourceRange Range,
3647+
bool Implicit)
3648+
: DeclAttribute(DeclAttrKind::Warn, AtLoc, Range, Implicit),
3649+
DiagnosticBehavior(Behavior), DiagnosticGroupID(DiagnosticGroupID),
3650+
Reason(Reason) {}
3651+
3652+
WarnAttr(DiagGroupID DiagnosticGroupID, Behavior Behavior, bool Implicit)
3653+
: WarnAttr(DiagnosticGroupID, Behavior, std::nullopt, SourceLoc(),
3654+
SourceRange(), Implicit) {}
3655+
3656+
Behavior DiagnosticBehavior;
3657+
DiagGroupID DiagnosticGroupID;
3658+
const std::optional<StringRef> Reason;
3659+
3660+
static bool classof(const DeclAttribute *DA) {
3661+
return DA->getKind() == DeclAttrKind::Warn;
3662+
}
3663+
3664+
WarnAttr *clone(ASTContext &ctx) const {
3665+
return new (ctx) WarnAttr(DiagnosticGroupID, DiagnosticBehavior, Reason,
3666+
AtLoc, Range, isImplicit());
3667+
}
3668+
3669+
bool isEquivalent(const WarnAttr *other,
3670+
Decl *attachedTo) const {
3671+
return Reason == other->Reason;
3672+
}
3673+
};
3674+
36403675

36413676
/// The kind of unary operator, if any.
36423677
enum class UnaryOperatorKind : uint8_t { None, Prefix, Postfix };

include/swift/AST/DeclAttr.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,12 +902,18 @@ DECL_ATTR(specialized, Specialized,
902902
AllowMultipleAttributes | LongAttribute | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
903903
172)
904904

905+
905906
SIMPLE_DECL_ATTR(_unsafeSelfDependentResult, UnsafeSelfDependentResult,
906907
OnAccessor,
907908
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIBreakingToRemove | EquivalentInABIAttr,
908909
173)
909910

910-
LAST_DECL_ATTR(UnsafeSelfDependentResult)
911+
DECL_ATTR(warn, Warn,
912+
OnFunc | OnConstructor | OnDestructor | OnSubscript | OnVar | OnNominalType | OnExtension | OnAccessor | OnImport,
913+
AllowMultipleAttributes | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
914+
174)
915+
916+
LAST_DECL_ATTR(Warn)
911917

912918
#undef DECL_ATTR_ALIAS
913919
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsParse.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,13 @@ WARNING(attr_warn_unused_result_removed,none,
17701770
"'warn_unused_result' attribute behavior is now the default", ())
17711771
ERROR(attr_warn_unused_result_expected_rparen,none,
17721772
"expected ')' after 'warn_unused_result' attribute", ())
1773+
1774+
// warn
1775+
ERROR(attr_warn_expected_diagnostic_group_identifier,none,
1776+
"expected '%0' option to be a diagnostic group identifier", (StringRef))
1777+
1778+
ERROR(attr_warn_expected_known_behavior,none,
1779+
"expected diagnostic behavior argument '%0' to be either 'error', 'warning' or 'ignored'", (StringRef))
17731780

17741781
// _specialize
17751782
ERROR(attr_specialize_missing_colon,none,

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,9 @@ EXPERIMENTAL_FEATURE(EmbeddedExistentials, false)
558558
/// Allow use of the 'anyAppleOS' availability domain.
559559
EXPERIMENTAL_FEATURE(AnyAppleOSAvailability, true)
560560

561+
/// Enable source-level warning control with `@warn`
562+
EXPERIMENTAL_FEATURE(SourceWarningControl, true)
563+
561564
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
562565
#undef EXPERIMENTAL_FEATURE
563566
#undef UPCOMING_FEATURE

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ namespace swift {
677677
/// Whether or not to allow experimental features that are only available
678678
/// in "production".
679679
#ifdef NDEBUG
680-
bool RestrictNonProductionExperimentalFeatures = true;
680+
bool RestrictNonProductionExperimentalFeatures = false;
681681
#else
682682
bool RestrictNonProductionExperimentalFeatures = false;
683683
#endif

lib/AST/ASTDumper.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5584,6 +5584,30 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
55845584
}
55855585
printFoot();
55865586
}
5587+
5588+
void visitWarnAttr(WarnAttr *Attr, Label label) {
5589+
printCommon(Attr, "warn", label);
5590+
auto &diagGroupInfo = getDiagGroupInfoByID(Attr->DiagnosticGroupID);
5591+
printFieldRaw([&](raw_ostream &out) { out << diagGroupInfo.name; },
5592+
Label::always("diagGroupID:"));
5593+
switch (Attr->DiagnosticBehavior) {
5594+
case WarnAttr::Behavior::Error:
5595+
printFieldRaw([&](raw_ostream &out) { out << "error"; },
5596+
Label::always("as:"));
5597+
break;
5598+
case WarnAttr::Behavior::Warning:
5599+
printFieldRaw([&](raw_ostream &out) { out << "warning"; },
5600+
Label::always("as:"));
5601+
break;
5602+
case WarnAttr::Behavior::Ignored:
5603+
printFieldRaw([&](raw_ostream &out) { out << "ignored"; },
5604+
Label::always("as:"));
5605+
break;
5606+
}
5607+
if (Attr->Reason)
5608+
printFieldQuoted(Attr->Reason, Label::always("reason:"));
5609+
printFoot();
5610+
}
55875611
};
55885612

55895613
} // end anonymous namespace

lib/AST/Attr.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,31 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
13251325
Printer.printAttrName("@section");
13261326
Printer << "(\"" << cast<SectionAttr>(this)->Name << "\")";
13271327
break;
1328+
1329+
case DeclAttrKind::Warn: {
1330+
auto warnAttr = cast<WarnAttr>(this);
1331+
Printer.printAttrName("@warn(");
1332+
1333+
auto &diagGroupInfo = getDiagGroupInfoByID(warnAttr->DiagnosticGroupID);
1334+
Printer.printText(diagGroupInfo.name);
1335+
Printer << ", ";
1336+
switch (cast<WarnAttr>(this)->DiagnosticBehavior) {
1337+
case WarnAttr::Behavior::Error:
1338+
Printer << "as: error";
1339+
break;
1340+
case WarnAttr::Behavior::Warning:
1341+
Printer << "as: warning";
1342+
break;
1343+
case WarnAttr::Behavior::Ignored:
1344+
Printer << "as: ignored";
1345+
break;
1346+
}
1347+
if (cast<WarnAttr>(this)->Reason) {
1348+
Printer << ", \"" << *(cast<WarnAttr>(this)->Reason) << "\"";
1349+
}
1350+
Printer <<")";
1351+
}
1352+
break;
13281353

13291354
case DeclAttrKind::ObjC: {
13301355
Printer.printAttrName("@objc");
@@ -2007,6 +2032,8 @@ StringRef DeclAttribute::getAttrName() const {
20072032
return "_rawLayout";
20082033
case DeclAttrKind::Extern:
20092034
return "_extern";
2035+
case DeclAttrKind::Warn:
2036+
return "warn";
20102037
case DeclAttrKind::AllowFeatureSuppression:
20112038
if (cast<AllowFeatureSuppressionAttr>(this)->getInverted()) {
20122039
return "_disallowFeatureSuppression";

lib/AST/Bridging/DeclAttributeBridging.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,38 @@ BridgedSwiftNativeObjCRuntimeBaseAttr_createParsed(BridgedASTContext cContext,
487487
SwiftNativeObjCRuntimeBaseAttr(name, atLoc, range, /*Implicit=*/false);
488488
}
489489

490+
BridgedWarnAttr
491+
BridgedWarnAttr_createParsed(BridgedASTContext cContext,
492+
SourceLoc atLoc,
493+
SourceRange range,
494+
Identifier diagGroupName,
495+
BridgedWarningGroupBehavior behavior,
496+
BridgedStringRef reason) {
497+
ASTContext &context = cContext.unbridged();
498+
auto diagGroupID = getDiagGroupIDByName(diagGroupName.str());
499+
500+
WarnAttr::Behavior attrBehavior;
501+
switch (behavior) {
502+
case WarningGroupBehaviorError:
503+
attrBehavior = WarnAttr::Behavior::Error;
504+
break;
505+
case WarningGroupBehaviorWarning:
506+
attrBehavior = WarnAttr::Behavior::Warning;
507+
break;
508+
case WarningGroupBehaviorIgnored:
509+
attrBehavior = WarnAttr::Behavior::Ignored;
510+
break;
511+
}
512+
513+
std::optional<StringRef> reasonText = std::nullopt;
514+
if (!reason.getIsEmpty())
515+
reasonText = reason.unbridged();
516+
517+
return new (context) WarnAttr(*diagGroupID, attrBehavior,
518+
reasonText, atLoc, range,
519+
/*Implicit=*/false);
520+
}
521+
490522
static NonSendableKind unbridged(BridgedNonSendableKind kind) {
491523
switch (kind) {
492524
case BridgedNonSendableKindSpecific:

lib/AST/FeatureSet.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ static bool usesFeatureConcurrencySyntaxSugar(Decl *decl) {
308308
return false;
309309
}
310310

311+
static bool usesFeatureSourceWarningControl(Decl *decl) {
312+
return decl->getAttrs().hasAttribute<WarnAttr>();
313+
}
314+
311315
static bool usesFeatureCompileTimeValues(Decl *decl) {
312316
return decl->getAttrs().hasAttribute<ConstValAttr>() ||
313317
decl->getAttrs().hasAttribute<ConstInitializedAttr>();

0 commit comments

Comments
 (0)