Skip to content

Commit efeb7d8

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

File tree

19 files changed

+379
-2
lines changed

19 files changed

+379
-2
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,21 @@ BridgedSwiftNativeObjCRuntimeBaseAttr_createParsed(BridgedASTContext cContext,
10901090
swift::SourceRange range,
10911091
swift::Identifier name);
10921092

1093+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedWarningGroupBehavior {
1094+
WarningGroupBehaviorError,
1095+
WarningGroupBehaviorWarning,
1096+
WarningGroupBehaviorIgnored,
1097+
};
1098+
1099+
SWIFT_NAME("BridgedWarnAttr.createParsed(_:atLoc:range:diagGroupName:behavior:reason:)")
1100+
BridgedWarnAttr
1101+
BridgedWarnAttr_createParsed(BridgedASTContext cContext,
1102+
swift::SourceLoc atLoc,
1103+
swift::SourceRange range,
1104+
swift::Identifier diagGroupName,
1105+
BridgedWarningGroupBehavior behavior,
1106+
BridgedStringRef reason);
1107+
10931108
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedNonSendableKind {
10941109
BridgedNonSendableKindSpecific,
10951110
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"
@@ -3564,6 +3565,40 @@ class NonexhaustiveAttr : public DeclAttribute {
35643565
}
35653566
};
35663567

3568+
class WarnAttr : public DeclAttribute {
3569+
public:
3570+
enum class Behavior : uint8_t { Error, Warning, Ignored };
3571+
3572+
WarnAttr(DiagGroupID DiagnosticGroupID, Behavior Behavior,
3573+
std::optional<StringRef> Reason, SourceLoc AtLoc, SourceRange Range,
3574+
bool Implicit)
3575+
: DeclAttribute(DeclAttrKind::Warn, AtLoc, Range, Implicit),
3576+
DiagnosticBehavior(Behavior), DiagnosticGroupID(DiagnosticGroupID),
3577+
Reason(Reason) {}
3578+
3579+
WarnAttr(DiagGroupID DiagnosticGroupID, Behavior Behavior, bool Implicit)
3580+
: WarnAttr(DiagnosticGroupID, Behavior, std::nullopt, SourceLoc(),
3581+
SourceRange(), Implicit) {}
3582+
3583+
Behavior DiagnosticBehavior;
3584+
DiagGroupID DiagnosticGroupID;
3585+
const std::optional<StringRef> Reason;
3586+
3587+
static bool classof(const DeclAttribute *DA) {
3588+
return DA->getKind() == DeclAttrKind::Warn;
3589+
}
3590+
3591+
WarnAttr *clone(ASTContext &ctx) const {
3592+
return new (ctx) WarnAttr(DiagnosticGroupID, DiagnosticBehavior, Reason,
3593+
AtLoc, Range, isImplicit());
3594+
}
3595+
3596+
bool isEquivalent(const WarnAttr *other,
3597+
Decl *attachedTo) const {
3598+
return Reason == other->Reason;
3599+
}
3600+
};
3601+
35673602

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

include/swift/AST/DeclAttr.def

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

905-
LAST_DECL_ATTR(Specialized)
905+
DECL_ATTR(warn, Warn,
906+
OnFunc | OnConstructor | OnSubscript | OnVar | OnNominalType | OnExtension | OnAccessor | OnImport,
907+
AllowMultipleAttributes | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
908+
173)
909+
910+
LAST_DECL_ATTR(Warn)
906911

907912
#undef DECL_ATTR_ALIAS
908913
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsParse.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,13 @@ WARNING(attr_warn_unused_result_removed,none,
17531753
"'warn_unused_result' attribute behavior is now the default", ())
17541754
ERROR(attr_warn_unused_result_expected_rparen,none,
17551755
"expected ')' after 'warn_unused_result' attribute", ())
1756+
1757+
// warn
1758+
ERROR(attr_warn_expected_diagnostic_group_identifier,none,
1759+
"expected '%0' option to be a diagnostic group identifier", (StringRef))
1760+
1761+
ERROR(attr_warn_expected_known_behavior,none,
1762+
"expected diagnostic behavior argument '%0' to be either 'error', 'warning' or 'ignored'", (StringRef))
17561763

17571764
// _specialize
17581765
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
@@ -553,6 +553,9 @@ EXPERIMENTAL_FEATURE(BorrowAndMutateAccessors, false)
553553
/// Allow use of @inline(always) attribute
554554
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(InlineAlways, false)
555555

556+
/// Enable source-level warning control with `@warn`
557+
EXPERIMENTAL_FEATURE(SourceWarningControl, false)
558+
556559
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
557560
#undef EXPERIMENTAL_FEATURE
558561
#undef UPCOMING_FEATURE

include/swift/Basic/LangOptions.h

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

lib/AST/ASTDumper.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5531,6 +5531,30 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
55315531
}
55325532
printFoot();
55335533
}
5534+
5535+
void visitWarnAttr(WarnAttr *Attr, Label label) {
5536+
printCommon(Attr, "warn", label);
5537+
auto &diagGroupInfo = getDiagGroupInfoByID(Attr->DiagnosticGroupID);
5538+
printFieldRaw([&](raw_ostream &out) { out << diagGroupInfo.name; },
5539+
Label::always("diagGroupID:"));
5540+
switch (Attr->DiagnosticBehavior) {
5541+
case WarnAttr::Behavior::Error:
5542+
printFieldRaw([&](raw_ostream &out) { out << "error"; },
5543+
Label::always("as:"));
5544+
break;
5545+
case WarnAttr::Behavior::Warning:
5546+
printFieldRaw([&](raw_ostream &out) { out << "warning"; },
5547+
Label::always("as:"));
5548+
break;
5549+
case WarnAttr::Behavior::Ignored:
5550+
printFieldRaw([&](raw_ostream &out) { out << "ignored"; },
5551+
Label::always("as:"));
5552+
break;
5553+
}
5554+
if (Attr->Reason)
5555+
printFieldQuoted(Attr->Reason, Label::always("reason:"));
5556+
printFoot();
5557+
}
55345558
};
55355559

55365560
} // end anonymous namespace

lib/AST/Attr.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,31 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
13151315
Printer.printAttrName("@_section");
13161316
Printer << "(\"" << cast<SectionAttr>(this)->Name << "\")";
13171317
break;
1318+
1319+
case DeclAttrKind::Warn: {
1320+
auto warnAttr = cast<WarnAttr>(this);
1321+
Printer.printAttrName("@warn(");
1322+
1323+
auto &diagGroupInfo = getDiagGroupInfoByID(warnAttr->DiagnosticGroupID);
1324+
Printer.printText(diagGroupInfo.name);
1325+
Printer << ", ";
1326+
switch (cast<WarnAttr>(this)->DiagnosticBehavior) {
1327+
case WarnAttr::Behavior::Error:
1328+
Printer << "as: error";
1329+
break;
1330+
case WarnAttr::Behavior::Warning:
1331+
Printer << "as: warning";
1332+
break;
1333+
case WarnAttr::Behavior::Ignored:
1334+
Printer << "as: ignored";
1335+
break;
1336+
}
1337+
if (cast<WarnAttr>(this)->Reason) {
1338+
Printer << ", \"" << *(cast<WarnAttr>(this)->Reason) << "\"";
1339+
}
1340+
Printer <<")";
1341+
}
1342+
break;
13181343

13191344
case DeclAttrKind::ObjC: {
13201345
Printer.printAttrName("@objc");
@@ -1997,6 +2022,8 @@ StringRef DeclAttribute::getAttrName() const {
19972022
return "_rawLayout";
19982023
case DeclAttrKind::Extern:
19992024
return "_extern";
2025+
case DeclAttrKind::Warn:
2026+
return "warn";
20002027
case DeclAttrKind::AllowFeatureSuppression:
20012028
if (cast<AllowFeatureSuppressionAttr>(this)->getInverted()) {
20022029
return "_disallowFeatureSuppression";

lib/AST/Bridging/DeclAttributeBridging.cpp

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

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