@@ -3616,6 +3616,30 @@ static bool isParenthesizedUnowned(Parser &P) {
36163616 (P.Tok .getText () == " safe" || P.Tok .getText () == " unsafe" );
36173617}
36183618
3619+ static void skipAttribute (Parser &P) {
3620+ // Consider unexpected tokens to be incomplete attributes.
3621+
3622+ // Parse the attribute name, which can be qualified, have
3623+ // generic arguments, and so on.
3624+ do {
3625+ if (!P.consumeIf (tok::identifier) && !P.consumeIf (tok::code_complete))
3626+ return ;
3627+
3628+ if (P.startsWithLess (P.Tok )) {
3629+ P.consumeStartingLess ();
3630+ P.skipUntilGreaterInTypeList ();
3631+ }
3632+ } while (P.consumeIf (tok::period));
3633+
3634+ // Skip an argument clause after the attribute name.
3635+ if (P.consumeIf (tok::l_paren)) {
3636+ while (P.Tok .isNot (tok::r_brace, tok::eof, tok::pound_endif)) {
3637+ if (P.consumeIf (tok::r_paren)) break ;
3638+ P.skipSingle ();
3639+ }
3640+ }
3641+ }
3642+
36193643bool Parser::isStartOfSwiftDecl () {
36203644 // If this is obviously not the start of a decl, then we're done.
36213645 if (!isKeywordPossibleDeclStart (Tok)) return false ;
@@ -3645,23 +3669,14 @@ bool Parser::isStartOfSwiftDecl() {
36453669 if (Tok.is (tok::kw_try))
36463670 return peekToken ().isAny (tok::kw_let, tok::kw_var);
36473671
3648- // Look through attribute list, because it may be an *type* attribute list.
3672+ // Skip an attribute, since it might be a type attribute. This can't
3673+ // happen at the top level of a scope, but we do use isStartOfSwiftDecl()
3674+ // in positions like generic argument lists.
36493675 if (Tok.is (tok::at_sign)) {
36503676 BacktrackingScope backtrack (*this );
3651- while (consumeIf (tok::at_sign)) {
3652- // If not identifier or code complete token, consider '@' as an incomplete
3653- // attribute.
3654- if (Tok.isNot (tok::identifier, tok::code_complete))
3655- continue ;
3656- consumeToken ();
3657- // Eat paren after attribute name; e.g. @foo(x)
3658- if (consumeIf (tok::l_paren)) {
3659- while (Tok.isNot (tok::r_brace, tok::eof, tok::pound_endif)) {
3660- if (consumeIf (tok::r_paren)) break ;
3661- skipSingle ();
3662- }
3663- }
3664- }
3677+ while (consumeIf (tok::at_sign))
3678+ skipAttribute (*this );
3679+
36653680 // If this attribute is the last element in the block,
36663681 // consider it is a start of incomplete decl.
36673682 if (Tok.isAny (tok::r_brace, tok::eof, tok::pound_endif))
0 commit comments