@@ -3214,6 +3214,69 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
32143214 break ;
32153215 }
32163216
3217+ case DeclAttrKind::Safe: {
3218+ if (!consumeIfAttributeLParen ()) {
3219+ diagnose (Loc, diag::attr_expected_lparen, AttrName,
3220+ DeclAttribute::isDeclModifier (DK));
3221+ return makeParserError ();
3222+ }
3223+
3224+ StringRef parsedName = Tok.getText ();
3225+ if (!consumeIf (tok::identifier) || parsedName != " unchecked" ) {
3226+ diagnose (Loc, diag::safe_attr_unchecked);
3227+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3228+ return makeParserError ();
3229+ }
3230+
3231+ StringRef message;
3232+ if (consumeIf (tok::comma)) {
3233+ if (!Tok.is (tok::identifier)) {
3234+ diagnose (Tok, diag::attr_expected_label, " message" , AttrName);
3235+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3236+ return makeParserError ();
3237+ }
3238+
3239+ StringRef flag = Tok.getText ();
3240+
3241+ if (flag != " message" ) {
3242+ diagnose (Tok.getLoc (), diag::attr_unknown_option, flag, AttrName);
3243+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3244+ return makeParserError ();
3245+ }
3246+ consumeToken ();
3247+ if (!consumeIf (tok::colon)) {
3248+ diagnose (Tok.getLoc (), diag::attr_expected_colon_after_label, flag);
3249+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3250+ return makeParserError ();
3251+ }
3252+ if (!Tok.is (tok::string_literal)) {
3253+ diagnose (Tok.getLoc (), diag::attr_expected_string_literal, AttrName);
3254+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3255+ return makeParserSuccess ();
3256+ }
3257+
3258+ std::optional<StringRef> value =
3259+ getStringLiteralIfNotInterpolated (Tok.getLoc (), flag);
3260+ if (!value) {
3261+ errorAndSkipUntilConsumeRightParen (*this , AttrName);
3262+ return makeParserError ();
3263+ }
3264+ consumeToken ();
3265+ message = *value;
3266+ }
3267+
3268+ if (!consumeIf (tok::r_paren)) {
3269+ diagnose (PreviousLoc, diag::attr_expected_rparen,
3270+ AttrName, /* isModifier*/ false )
3271+ .fixItInsertAfter (PreviousLoc, " )" );
3272+ }
3273+ AttrRange = SourceRange (Loc, PreviousLoc);
3274+
3275+ if (!DiscardAttribute)
3276+ Attributes.add (new (Context) SafeAttr (AtLoc, AttrRange, message));
3277+ break ;
3278+ }
3279+
32173280 case DeclAttrKind::Section: {
32183281 if (!consumeIfAttributeLParen ()) {
32193282 diagnose (Loc, diag::attr_expected_lparen, AttrName,
0 commit comments