Skip to content

Commit 81f9fa2

Browse files
authored
Merge pull request #5789 from rintaro/parse-isstartofdecl-skipattrs
2 parents 6e2eab8 + 89d7969 commit 81f9fa2

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,31 @@ bool Parser::isStartOfDecl() {
17451745
if (Tok.is(tok::kw_try))
17461746
return peekToken().isAny(tok::kw_let, tok::kw_var);
17471747

1748+
// Look through attribute list, because it may be an *type* attribute list.
1749+
if (Tok.is(tok::at_sign)) {
1750+
BacktrackingScope backtrack(*this);
1751+
while (consumeIf(tok::at_sign)) {
1752+
// If not identifier or code complete token, consider '@' is a incomplete
1753+
// attribute.
1754+
if (Tok.isNot(tok::identifier, tok::code_complete))
1755+
continue;
1756+
consumeToken();
1757+
// Eat paren after attribute name; e.g. @foo(x)
1758+
if (consumeIf(tok::l_paren)) {
1759+
while (Tok.isNot(tok::r_brace, tok::eof, tok::pound_endif)) {
1760+
if (consumeIf(tok::r_paren)) break;
1761+
skipSingle();
1762+
}
1763+
}
1764+
}
1765+
// If this attribute is the last element in the block,
1766+
// consider it is a start of incomplete decl.
1767+
if (Tok.isAny(tok::r_brace, tok::eof, tok::pound_endif))
1768+
return true;
1769+
1770+
return isStartOfDecl();
1771+
}
1772+
17481773
// Otherwise, the only hard case left is the identifier case.
17491774
if (Tok.isNot(tok::identifier)) return true;
17501775

test/Parse/generic_disambiguation.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ A<[[A<B>]]>.c()
4343
A<(Int, UnicodeScalar)>.c()
4444
A<(a:Int, b:UnicodeScalar)>.c()
4545
A<Runcible & Fungible>.c()
46+
A<@convention(c) () -> Int32>.c()
47+
A<(@autoclosure @escaping () -> Int, Int) -> Void>.c()
4648

4749
A<B>(x: 0) // expected-warning{{unused}}
4850

0 commit comments

Comments
 (0)