Skip to content

Commit ea7a33c

Browse files
authored
Merge pull request #32191 from rintaro/parser-missing-memberdeclbraces-rdar63921896
[Parse] Avoid delayed member parsing for type decl with missing brace
2 parents 09ea5fd + bdfe1b1 commit ea7a33c

File tree

3 files changed

+39
-42
lines changed

3 files changed

+39
-42
lines changed

include/swift/Parse/Parser.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -928,9 +928,8 @@ class Parser {
928928
std::pair<std::vector<Decl *>, Optional<std::string>>
929929
parseDeclListDelayed(IterableDeclContext *IDC);
930930

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

936935
bool canDelayMemberDeclParsing(bool &HasOperatorDeclarations,

lib/Parse/ParseDecl.cpp

+27-39
Original file line numberDiff line numberDiff line change
@@ -4422,10 +4422,18 @@ ParserStatus Parser::parseDeclItem(bool &PreviousHadSemi,
44224422
return Result;
44234423
}
44244424

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

@@ -4444,7 +4452,7 @@ bool Parser::parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
44444452
bool hadError = false;
44454453
ParseDeclOptions Options = getMemberParseDeclOptions(IDC);
44464454
auto membersAndHash =
4447-
parseDeclList(LBLoc, RBLoc, ErrorDiag, Options, IDC, hadError);
4455+
parseDeclList(LBLoc, RBLoc, RBraceDiag, Options, IDC, hadError);
44484456
IDC->setMaybeHasOperatorDeclarations();
44494457
IDC->setMaybeHasNestedClassDeclarations();
44504458
Context.evaluator.cacheOutput(
@@ -4614,16 +4622,12 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
46144622
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
46154623
SourceLoc LBLoc, RBLoc;
46164624

4617-
auto PosBeforeLB = Tok.getLoc();
4618-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_extension)) {
4619-
LBLoc = PreviousLoc;
4620-
RBLoc = LBLoc;
4621-
status.setIsParseError();
4622-
} else {
4625+
{
46234626
ContextChange CC(*this, ext);
46244627
Scope S(this, ScopeKind::Extension);
46254628

4626-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
4629+
if (parseMemberDeclList(LBLoc, RBLoc,
4630+
diag::expected_lbrace_extension,
46274631
diag::expected_rbrace_extension,
46284632
ext))
46294633
status.setIsParseError();
@@ -6576,15 +6580,11 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
65766580

65776581
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
65786582
SourceLoc LBLoc, RBLoc;
6579-
SourceLoc PosBeforeLB = Tok.getLoc();
6580-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_enum)) {
6581-
LBLoc = PreviousLoc;
6582-
RBLoc = LBLoc;
6583-
Status.setIsParseError();
6584-
} else {
6583+
{
65856584
Scope S(this, ScopeKind::EnumBody);
65866585

6587-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6586+
if (parseMemberDeclList(LBLoc, RBLoc,
6587+
diag::expected_lbrace_enum,
65886588
diag::expected_rbrace_enum,
65896589
ED))
65906590
Status.setIsParseError();
@@ -6862,16 +6862,12 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
68626862
// Make the entities of the struct as a code block.
68636863
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
68646864
SourceLoc LBLoc, RBLoc;
6865-
SourceLoc PosBeforeLB = Tok.getLoc();
6866-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_struct)) {
6867-
LBLoc = PreviousLoc;
6868-
RBLoc = LBLoc;
6869-
Status.setIsParseError();
6870-
} else {
6865+
{
68716866
// Parse the body.
68726867
Scope S(this, ScopeKind::StructBody);
68736868

6874-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6869+
if (parseMemberDeclList(LBLoc, RBLoc,
6870+
diag::expected_lbrace_struct,
68756871
diag::expected_rbrace_struct,
68766872
SD))
68776873
Status.setIsParseError();
@@ -6978,16 +6974,12 @@ ParserResult<ClassDecl> Parser::parseDeclClass(ParseDeclOptions Flags,
69786974

69796975
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
69806976
SourceLoc LBLoc, RBLoc;
6981-
auto PosBeforeLB = Tok.getLoc();
6982-
if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_class)) {
6983-
LBLoc = PreviousLoc;
6984-
RBLoc = LBLoc;
6985-
Status.setIsParseError();
6986-
} else {
6977+
{
69876978
// Parse the body.
69886979
Scope S(this, ScopeKind::ClassBody);
69896980

6990-
if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB,
6981+
if (parseMemberDeclList(LBLoc, RBLoc,
6982+
diag::expected_lbrace_class,
69916983
diag::expected_rbrace_class,
69926984
CD))
69936985
Status.setIsParseError();
@@ -7079,14 +7071,10 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
70797071
SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock);
70807072
SourceLoc LBraceLoc;
70817073
SourceLoc RBraceLoc;
7082-
SourceLoc PosBeforeLB = Tok.getLoc();
7083-
if (parseToken(tok::l_brace, LBraceLoc, diag::expected_lbrace_protocol)) {
7084-
LBraceLoc = PreviousLoc;
7085-
RBraceLoc = LBraceLoc;
7086-
Status.setIsParseError();
7087-
} else {
7074+
{
70887075
// Parse the members.
7089-
if (parseMemberDeclList(LBraceLoc, RBraceLoc, PosBeforeLB,
7076+
if (parseMemberDeclList(LBraceLoc, RBraceLoc,
7077+
diag::expected_lbrace_protocol,
70907078
diag::expected_rbrace_protocol,
70917079
Proto))
70927080
Status.setIsParseError();
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)