@@ -877,7 +877,7 @@ bool Parser::parseSpecializeAttribute(
877877 assert (ClosingBrace == tok::r_paren || ClosingBrace == tok::r_square);
878878
879879 SourceLoc lParenLoc;
880- if (Tok. is (tok::l_paren )) {
880+ if (isAtAttributeLParen ( )) {
881881 lParenLoc = consumeAttributeLParen ();
882882 } else {
883883 // SIL parsing is positioned at _specialize when entering this and parses
@@ -2261,7 +2261,7 @@ Parser::parseMacroRoleAttribute(
22612261 break ;
22622262 }
22632263
2264- if (!Tok. isFollowingLParen ()) {
2264+ if (!isAtAttributeLParen ()) {
22652265 diagnose (Tok, diag::attr_expected_lparen, attrName, false );
22662266 return makeParserError ();
22672267 }
@@ -2503,7 +2503,7 @@ static std::optional<Identifier> parseSingleAttrOptionImpl(
25032503 };
25042504 bool isDeclModifier = DeclAttribute::isDeclModifier (DK);
25052505
2506- if (!P.Tok . isFollowingLParen ()) {
2506+ if (!P.isAtAttributeLParen ()) {
25072507 if (allowOmitted)
25082508 return Identifier ();
25092509
@@ -2883,7 +2883,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
28832883 .Case (" public" , AccessLevel::Public)
28842884 .Case (" open" , AccessLevel::Open);
28852885
2886- if (!Tok. isFollowingLParen ()) {
2886+ if (!isAtAttributeLParen ()) {
28872887 // Normal access control attribute.
28882888 AttrRange = Loc;
28892889
@@ -3467,7 +3467,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
34673467 }
34683468 case DeclAttrKind::PrivateImport: {
34693469 // Parse the leading '('.
3470- if (!Tok. isFollowingLParen ()) {
3470+ if (!isAtAttributeLParen ()) {
34713471 diagnose (Loc, diag::attr_expected_lparen, AttrName,
34723472 DeclAttribute::isDeclModifier (DK));
34733473 return makeParserSuccess ();
@@ -3516,7 +3516,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
35163516 }
35173517 case DeclAttrKind::ObjC: {
35183518 // Unnamed @objc attribute.
3519- if (!Tok. isFollowingLParen ()) {
3519+ if (!isAtAttributeLParen ()) {
35203520 auto attr = ObjCAttr::createUnnamed (Context, AtLoc, Loc);
35213521 Attributes.add (attr);
35223522 break ;
@@ -3584,7 +3584,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
35843584
35853585 case DeclAttrKind::DynamicReplacement: {
35863586 // Parse the leading '('.
3587- if (!Tok. isFollowingLParen ()) {
3587+ if (!isAtAttributeLParen ()) {
35883588 diagnose (Loc, diag::attr_expected_lparen, AttrName,
35893589 DeclAttribute::isDeclModifier (DK));
35903590 return makeParserSuccess ();
@@ -3635,7 +3635,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
36353635
36363636 case DeclAttrKind::TypeEraser: {
36373637 // Parse leading '('
3638- if (!Tok. isFollowingLParen ()) {
3638+ if (!isAtAttributeLParen ()) {
36393639 diagnose (Loc, diag::attr_expected_lparen, AttrName,
36403640 DeclAttribute::isDeclModifier (DK));
36413641 return makeParserSuccess ();
@@ -3665,7 +3665,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
36653665
36663666 case DeclAttrKind::Specialize:
36673667 case DeclAttrKind::Specialized: {
3668- if (!Tok. isFollowingLParen ()) {
3668+ if (!isAtAttributeLParen ()) {
36693669 diagnose (Loc, diag::attr_expected_lparen, AttrName,
36703670 DeclAttribute::isDeclModifier (DK));
36713671 return makeParserSuccess ();
@@ -3894,7 +3894,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
38943894 break ;
38953895 }
38963896 case DeclAttrKind::RawLayout: {
3897- if (!Tok. isFollowingLParen ()) {
3897+ if (!isAtAttributeLParen ()) {
38983898 diagnose (Loc, diag::attr_expected_lparen, AttrName,
38993899 DeclAttribute::isDeclModifier (DK));
39003900 return makeParserSuccess ();
@@ -4164,27 +4164,11 @@ bool Parser::parseVersionTuple(llvm::VersionTuple &Version,
41644164 return false ;
41654165}
41664166
4167- bool Parser::isCustomAttributeArgument () {
4168- BacktrackingScope backtrack (*this );
4169- if (skipSingle ().hasCodeCompletion ())
4170- return true ;
4171-
4172- // If we have any keyword, identifier, or token that follows a function
4173- // type's parameter list, this is a parameter list and not an attribute.
4174- // Alternatively, we might have a token that illustrates we're not going to
4175- // get anything following the attribute, which means the parentheses describe
4176- // what follows the attribute.
4177- return !Tok.isAny (
4178- tok::arrow, tok::kw_throw, tok::kw_throws, tok::kw_rethrows,
4179- tok::r_paren, tok::r_brace, tok::r_square, tok::r_angle) &&
4180- !Tok.isContextualKeyword (" async" ) && !Tok.isContextualKeyword (" reasync" ) ;
4181- }
4182-
41834167bool Parser::canParseCustomAttribute () {
41844168 if (!canParseType ())
41854169 return false ;
41864170
4187- if (Tok. isFollowingLParen () && isCustomAttributeArgument ( ))
4171+ if (isAtAttributeLParen ( /* isCustomAttribute= */ true ))
41884172 skipSingle ();
41894173
41904174 return true ;
@@ -4196,7 +4180,7 @@ ParserResult<CustomAttr> Parser::parseCustomAttribute(SourceLoc atLoc) {
41964180 // Parse a custom attribute.
41974181 auto type = parseType (diag::expected_type, ParseTypeReason::CustomAttribute);
41984182 if (type.hasCodeCompletion () || type.isNull ()) {
4199- if (Tok. isFollowingLParen () && isCustomAttributeArgument ( ))
4183+ if (isAtAttributeLParen ( /* isCustomAttribute= */ true ))
42004184 skipSingle ();
42014185
42024186 return ParserResult<CustomAttr>(ParserStatus (type));
@@ -4208,7 +4192,11 @@ ParserResult<CustomAttr> Parser::parseCustomAttribute(SourceLoc atLoc) {
42084192 ParserStatus status;
42094193 ArgumentList *argList = nullptr ;
42104194 CustomAttributeInitializer *initContext = nullptr ;
4211- if (Tok.isFollowingLParen () && isCustomAttributeArgument ()) {
4195+ if (isAtAttributeLParen (/* isCustomAttribute=*/ true )) {
4196+ if (getEndOfPreviousLoc () != Tok.getLoc ()) {
4197+ diagnose (getEndOfPreviousLoc (), diag::attr_extra_whitespace_before_lparen)
4198+ .warnUntilSwiftVersion (6 );
4199+ }
42124200 // If we have no local context to parse the initial value into, create
42134201 // one for the attribute.
42144202 std::optional<ParseFunctionBody> initParser;
@@ -4217,10 +4205,6 @@ ParserResult<CustomAttr> Parser::parseCustomAttribute(SourceLoc atLoc) {
42174205 initContext = CustomAttributeInitializer::create (CurDeclContext);
42184206 initParser.emplace (*this , initContext);
42194207 }
4220- if (getEndOfPreviousLoc () != Tok.getLoc ()) {
4221- diagnose (getEndOfPreviousLoc (), diag::attr_extra_whitespace_before_lparen)
4222- .warnUntilSwiftVersion (6 );
4223- }
42244208 auto result = parseArgumentList (tok::l_paren, tok::r_paren,
42254209 /* isExprBasic*/ true ,
42264210 /* allowTrailingClosure*/ false );
@@ -4378,7 +4362,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
43784362 SourceLoc attrLoc = consumeToken ();
43794363
43804364 // @warn_unused_result with no arguments.
4381- if (!Tok. isFollowingLParen ()) {
4365+ if (!isAtAttributeLParen ()) {
43824366 diagnose (AtLoc, diag::attr_warn_unused_result_removed)
43834367 .fixItRemove (SourceRange (AtLoc, attrLoc));
43844368
@@ -4462,7 +4446,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
44624446
44634447 // Recover by eating @foo(...) when foo is not known.
44644448 consumeToken ();
4465- if (Tok. isFollowingLParen ())
4449+ if (isAtAttributeLParen ())
44664450 skipSingle ();
44674451
44684452 return makeParserError ();
@@ -4745,15 +4729,8 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
47454729 // Recover by eating @foo(...) when foo is not known.
47464730 consumeToken ();
47474731
4748- if (Tok.is (tok::l_paren) && getEndOfPreviousLoc () == Tok.getLoc ()) {
4749- CancellableBacktrackingScope backtrack (*this );
4732+ if (isAtAttributeLParen (/* isCustomAttr=*/ true ))
47504733 skipSingle ();
4751- // If we found '->', or 'throws' after paren, it's likely a parameter
4752- // of function type.
4753- if (Tok.isNot (tok::arrow, tok::kw_throws, tok::kw_rethrows,
4754- tok::kw_throw))
4755- backtrack.cancelBacktrack ();
4756- }
47574734
47584735 return makeParserError ();
47594736 }
@@ -4814,7 +4791,7 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
48144791
48154792 case TypeAttrKind::Isolated: {
48164793 SourceLoc lpLoc = Tok.getLoc (), kindLoc, rpLoc;
4817- if (!consumeIfNotAtStartOfLine (tok::l_paren )) {
4794+ if (!consumeIfAttributeLParen ( )) {
48184795 if (!justChecking) {
48194796 diagnose (Tok, diag::attr_isolated_expected_lparen);
48204797 // TODO: should we suggest removing the `@`?
@@ -4862,7 +4839,7 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
48624839 case TypeAttrKind::Opened: {
48634840 // Parse the opened existential ID string in parens
48644841 SourceLoc beginLoc = Tok.getLoc (), idLoc, endLoc;
4865- if (!consumeAttributeLParen ()) {
4842+ if (!consumeIfAttributeLParen ()) {
48664843 if (!justChecking)
48674844 diagnose (Tok, diag::opened_attribute_expected_lparen);
48684845 return makeParserError ();
@@ -5069,7 +5046,7 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
50695046 return std::nullopt ;
50705047 };
50715048
5072- if (!Tok. isFollowingLParen ()) {
5049+ if (!isAtAttributeLParen ()) {
50735050 diagnose (loc, diag::expected_lparen_after_lifetime_dependence);
50745051 status.setIsParseError ();
50755052 return status;
@@ -5777,6 +5754,7 @@ static bool consumeIfParenthesizedNonisolated(Parser &P) {
57775754}
57785755
57795756static void skipAttribute (Parser &P) {
5757+ P.consumeToken (tok::at_sign);
57805758 // Consider unexpected tokens to be incomplete attributes.
57815759
57825760 // Parse the attribute name, which can be qualified, have
@@ -5793,12 +5771,8 @@ static void skipAttribute(Parser &P) {
57935771 } while (P.consumeIf (tok::period));
57945772
57955773 // Skip an argument clause after the attribute name.
5796- if (P.consumeIf (tok::l_paren)) {
5797- while (P.Tok .isNot (tok::r_brace, tok::eof, tok::pound_endif)) {
5798- if (P.consumeIf (tok::r_paren)) break ;
5799- P.skipSingle ();
5800- }
5801- }
5774+ if (P.isAtAttributeLParen ())
5775+ P.skipSingle ();
58025776}
58035777
58045778bool Parser::isStartOfSwiftDecl (bool allowPoundIfAttributes,
@@ -5842,7 +5816,7 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes,
58425816 // in positions like generic argument lists.
58435817 if (Tok.is (tok::at_sign)) {
58445818 BacktrackingScope backtrack (*this );
5845- while (consumeIf (tok::at_sign))
5819+ while (Tok. is (tok::at_sign))
58465820 skipAttribute (*this );
58475821
58485822 // If this attribute is the last element in the block,
0 commit comments