Skip to content

Commit 8a9d7b7

Browse files
authored
Merge pull request #32197 from rintaro/5.3-parser-missing-memberdeclbraces-rdar63921896
[5.3][Parse] Avoid delayed member parsing for type decl with missing brace
2 parents c3609bc + 81984c3 commit 8a9d7b7

File tree

3 files changed

+39
-42
lines changed

3 files changed

+39
-42
lines changed

include/swift/Parse/Parser.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,9 +929,8 @@ class Parser {
929929
std::pair<std::vector<Decl *>, Optional<std::string>>
930930
parseDeclListDelayed(IterableDeclContext *IDC);
931931

932-
bool parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
933-
SourceLoc PosBeforeLB,
934-
Diag<> ErrorDiag,
932+
bool parseMemberDeclList(SourceLoc &LBLoc, SourceLoc &RBLoc,
933+
Diag<> LBraceDiag, Diag<> RBraceDiag,
935934
IterableDeclContext *IDC);
936935

937936
bool canDelayMemberDeclParsing(bool &HasOperatorDeclarations,

lib/Parse/ParseDecl.cpp

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4425,10 +4425,18 @@ ParserStatus Parser::parseDeclItem(bool &PreviousHadSemi,
44254425
return Result;
44264426
}
44274427

4428-
bool Parser::parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
4429-
SourceLoc PosBeforeLB,
4430-
Diag<> ErrorDiag,
4428+
bool Parser::parseMemberDeclList(SourceLoc &LBLoc, SourceLoc &RBLoc,
4429+
Diag<> LBraceDiag, Diag<> RBraceDiag,
44314430
IterableDeclContext *IDC) {
4431+
if (parseToken(tok::l_brace, LBLoc, LBraceDiag)) {
4432+
LBLoc = RBLoc = PreviousLoc;
4433+
4434+
// Cache the empty result to prevent delayed parsing.
4435+
Context.evaluator.cacheOutput(
4436+
ParseMembersRequest{IDC}, FingerprintAndMembers{None, {}});
4437+
return true;
4438+
}
4439+
44324440
bool HasOperatorDeclarations;
44334441
bool HasNestedClassDeclarations;
44344442

@@ -4447,7 +4455,7 @@ bool Parser::parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
44474455
bool hadError = false;
44484456
ParseDeclOptions Options = getMemberParseDeclOptions(IDC);
44494457
auto membersAndHash =
4450-
parseDeclList(LBLoc, RBLoc, ErrorDiag, Options, IDC, hadError);
4458+
parseDeclList(LBLoc, RBLoc, RBraceDiag, Options, IDC, hadError);
44514459
IDC->setMaybeHasOperatorDeclarations();
44524460
IDC->setMaybeHasNestedClassDeclarations();
44534461
Context.evaluator.cacheOutput(
@@ -4617,16 +4625,12 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
46174625
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
46184626
SourceLoc LBLoc, RBLoc;
46194627

4620-
auto PosBeforeLB = Tok.getLoc();
4621-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_extension)) {
4622-
LBLoc = PreviousLoc;
4623-
RBLoc = LBLoc;
4624-
status.setIsParseError();
4625-
} else {
4628+
{
46264629
ContextChange CC(*this, ext);
46274630
Scope S(this, ScopeKind::Extension);
46284631

4629-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
4632+
if (parseMemberDeclList(LBLoc, RBLoc,
4633+
diag::expected_lbrace_extension,
46304634
diag::expected_rbrace_extension,
46314635
ext))
46324636
status.setIsParseError();
@@ -6578,15 +6582,11 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
65786582

65796583
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
65806584
SourceLoc LBLoc, RBLoc;
6581-
SourceLoc PosBeforeLB = Tok.getLoc();
6582-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_enum)) {
6583-
LBLoc = PreviousLoc;
6584-
RBLoc = LBLoc;
6585-
Status.setIsParseError();
6586-
} else {
6585+
{
65876586
Scope S(this, ScopeKind::EnumBody);
65886587

6589-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6588+
if (parseMemberDeclList(LBLoc, RBLoc,
6589+
diag::expected_lbrace_enum,
65906590
diag::expected_rbrace_enum,
65916591
ED))
65926592
Status.setIsParseError();
@@ -6864,16 +6864,12 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
68646864
// Make the entities of the struct as a code block.
68656865
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
68666866
SourceLoc LBLoc, RBLoc;
6867-
SourceLoc PosBeforeLB = Tok.getLoc();
6868-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_struct)) {
6869-
LBLoc = PreviousLoc;
6870-
RBLoc = LBLoc;
6871-
Status.setIsParseError();
6872-
} else {
6867+
{
68736868
// Parse the body.
68746869
Scope S(this, ScopeKind::StructBody);
68756870

6876-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6871+
if (parseMemberDeclList(LBLoc, RBLoc,
6872+
diag::expected_lbrace_struct,
68776873
diag::expected_rbrace_struct,
68786874
SD))
68796875
Status.setIsParseError();
@@ -6980,16 +6976,12 @@ ParserResult<ClassDecl> Parser::parseDeclClass(ParseDeclOptions Flags,
69806976

69816977
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
69826978
SourceLoc LBLoc, RBLoc;
6983-
auto PosBeforeLB = Tok.getLoc();
6984-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_class)) {
6985-
LBLoc = PreviousLoc;
6986-
RBLoc = LBLoc;
6987-
Status.setIsParseError();
6988-
} else {
6979+
{
69896980
// Parse the body.
69906981
Scope S(this, ScopeKind::ClassBody);
69916982

6992-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6983+
if (parseMemberDeclList(LBLoc, RBLoc,
6984+
diag::expected_lbrace_class,
69936985
diag::expected_rbrace_class,
69946986
CD))
69956987
Status.setIsParseError();
@@ -7081,14 +7073,10 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
70817073
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
70827074
SourceLoc LBraceLoc;
70837075
SourceLoc RBraceLoc;
7084-
SourceLoc PosBeforeLB = Tok.getLoc();
7085-
if (parseToken(tok::l_brace, LBraceLoc, diag::expected_lbrace_protocol)) {
7086-
LBraceLoc = PreviousLoc;
7087-
RBraceLoc = LBraceLoc;
7088-
Status.setIsParseError();
7089-
} else {
7076+
{
70907077
// Parse the members.
7091-
if (parseMemberDeclList(LBraceLoc, RBraceLoc, PosBeforeLB,
7078+
if (parseMemberDeclList(LBraceLoc, RBraceLoc,
7079+
diag::expected_lbrace_protocol,
70927080
diag::expected_rbrace_protocol,
70937081
Proto))
70947082
Status.setIsParseError();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
func test() {
2+
class C:
3+
}
4+
5+
// RUN: %sourcekitd-test \
6+
// RUN: -req=complete -pos=2:11 -repeat-request=2 %s -- %s -parse-as-library \
7+
// RUN: | %FileCheck %s
8+
9+
// CHECK: key.results: [
10+
// CHECK: description: "Int",

0 commit comments

Comments
 (0)