Skip to content

Commit 836ad07

Browse files
authored
Merge pull request #19018 from rintaro/parse-parse-afd
[Parse] Consolidate body parsing for Func/Constructor/Destructor decls
2 parents 3b9b803 + 327c69e commit 836ad07

File tree

5 files changed

+79
-110
lines changed

5 files changed

+79
-110
lines changed

include/swift/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ class Parser {
930930
StaticSpellingKind StaticSpelling,
931931
ParseDeclOptions Flags,
932932
DeclAttributes &Attributes);
933+
void parseAbstractFunctionBody(AbstractFunctionDecl *AFD);
933934
bool parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD);
934935
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
935936
DeclAttributes &Attributes);

include/swift/Parse/Scope.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,10 @@ enum class ScopeKind {
6767
StructBody,
6868
ClassBody,
6969
ProtocolBody,
70-
ConstructorBody,
71-
DestructorBody,
7270
InheritanceClause,
7371

7472
Brace,
7573
TopLevel,
76-
ForVars,
7774
ForeachVars,
7875
CaseVars,
7976
CatchVars,

lib/Parse/ParseDecl.cpp

Lines changed: 60 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -5305,63 +5305,26 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
53055305
if (rethrows) {
53065306
Attributes.add(new (Context) RethrowsAttr(throwsLoc));
53075307
}
5308-
5309-
// Enter the arguments for the function into a new function-body scope. We
5310-
// need this even if there is no function body to detect argument name
5311-
// duplication.
5312-
{
5313-
Scope S(this, ScopeKind::FunctionBody);
53145308

5315-
diagnoseOperatorFixityAttributes(*this, Attributes, FD);
5316-
5317-
// Add the attributes here so if we need them while parsing the body
5318-
// they are available.
5319-
FD->getAttrs() = Attributes;
5309+
diagnoseOperatorFixityAttributes(*this, Attributes, FD);
5310+
// Add the attributes here so if we need them while parsing the body
5311+
// they are available.
5312+
FD->getAttrs() = Attributes;
53205313

5321-
// Pass the function signature to code completion.
5322-
if (SignatureHasCodeCompletion)
5323-
CodeCompletion->setParsedDecl(FD);
5314+
// Pass the function signature to code completion.
5315+
if (SignatureHasCodeCompletion)
5316+
CodeCompletion->setParsedDecl(FD);
53245317

5325-
DefaultArgs.setFunctionContext(FD, FD->getParameters());
5326-
if (auto *P = FD->getImplicitSelfDecl())
5327-
addToScope(P);
5328-
addParametersToScope(FD->getParameters());
5329-
setLocalDiscriminator(FD);
5330-
5331-
// Establish the new context.
5332-
ParseFunctionBody CC(*this, FD);
5333-
setLocalDiscriminatorToParamList(FD->getParameters());
5318+
DefaultArgs.setFunctionContext(FD, FD->getParameters());
5319+
setLocalDiscriminator(FD);
53345320

5335-
// Check to see if we have a "{" to start a brace statement.
5321+
if (Flags.contains(PD_InProtocol)) {
53365322
if (Tok.is(tok::l_brace)) {
5337-
// Record the curly braces but nothing inside.
5338-
SF.recordInterfaceToken("{");
5339-
SF.recordInterfaceToken("}");
5340-
llvm::SaveAndRestore<bool> T(IsParsingInterfaceTokens, false);
5341-
5342-
if (Flags.contains(PD_InProtocol)) {
5343-
diagnose(Tok, diag::protocol_method_with_body);
5344-
skipUntilDeclRBrace();
5345-
} else if (!isDelayedParsingEnabled()) {
5346-
if (Context.Stats)
5347-
Context.Stats->getFrontendCounters().NumFunctionsParsed++;
5348-
5349-
ParserResult<BraceStmt> Body =
5350-
parseBraceItemList(diag::func_decl_without_brace);
5351-
if (Body.isNull()) {
5352-
// FIXME: Should do some sort of error recovery here?
5353-
} else if (SignatureStatus.hasCodeCompletion()) {
5354-
// Code completion was inside the signature, don't attach the body.
5355-
FD->setBodySkipped(Body.get()->getSourceRange());
5356-
} else {
5357-
FD->setBody(Body.get());
5358-
}
5359-
} else {
5360-
consumeAbstractFunctionBody(FD, Attributes);
5361-
}
5362-
} else {
5363-
checkForInputIncomplete();
5323+
diagnose(Tok, diag::protocol_method_with_body);
5324+
skipSingle();
53645325
}
5326+
} else {
5327+
parseAbstractFunctionBody(FD);
53655328
}
53665329

53675330
// Exit the scope introduced for the generic parameters.
@@ -5371,6 +5334,46 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
53715334
return DCC.fixupParserResult(FD);
53725335
}
53735336

5337+
/// Parse function body into \p AFD.
5338+
void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
5339+
Scope S(this, ScopeKind::FunctionBody);
5340+
5341+
// Enter the arguments for the function into a new function-body scope. We
5342+
// need this even if there is no function body to detect argument name
5343+
// duplication.
5344+
if (auto *P = AFD->getImplicitSelfDecl())
5345+
addToScope(P);
5346+
addParametersToScope(AFD->getParameters());
5347+
5348+
// Establish the new context.
5349+
ParseFunctionBody CC(*this, AFD);
5350+
setLocalDiscriminatorToParamList(AFD->getParameters());
5351+
5352+
if (!Tok.is(tok::l_brace)) {
5353+
checkForInputIncomplete();
5354+
return;
5355+
}
5356+
5357+
if (IsParsingInterfaceTokens) {
5358+
// Record the curly braces but nothing inside.
5359+
SF.recordInterfaceToken("{");
5360+
SF.recordInterfaceToken("}");
5361+
}
5362+
llvm::SaveAndRestore<bool> T(IsParsingInterfaceTokens, false);
5363+
5364+
if (isDelayedParsingEnabled()) {
5365+
consumeAbstractFunctionBody(AFD, AFD->getAttrs());
5366+
return;
5367+
}
5368+
5369+
if (Context.Stats)
5370+
Context.Stats->getFrontendCounters().NumFunctionsParsed++;
5371+
5372+
ParserResult<BraceStmt> Body = parseBraceItemList(diag::invalid_diagnostic);
5373+
if (!Body.isNull())
5374+
AFD->setBody(Body.get());
5375+
}
5376+
53745377
bool Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
53755378
assert(!AFD->getBody() && "function should not have a parsed body");
53765379
assert(AFD->getBodyKind() == AbstractFunctionDecl::BodyKind::Unparsed &&
@@ -6225,7 +6228,6 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
62256228

62266229
CD->setGenericParams(GenericParams);
62276230

6228-
Scope S2(this, ScopeKind::ConstructorBody);
62296231
CtorInitializerKind initKind = CtorInitializerKind::Designated;
62306232
if (Attributes.hasAttribute<ConvenienceAttr>())
62316233
initKind = CtorInitializerKind::Convenience;
@@ -6244,37 +6246,13 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
62446246
CD->setInvalid();
62456247
}
62466248

6247-
addToScope(CD->getImplicitSelfDecl());
6248-
addParametersToScope(Params.get());
6249-
6250-
// '{'
6251-
if (Tok.is(tok::l_brace)) {
6252-
// Record the curly braces but nothing inside.
6253-
SF.recordInterfaceToken("{");
6254-
SF.recordInterfaceToken("}");
6255-
llvm::SaveAndRestore<bool> T(IsParsingInterfaceTokens, false);
6256-
6257-
if (Flags.contains(PD_InProtocol)) {
6249+
if (Flags.contains(PD_InProtocol)) {
6250+
if (Tok.is(tok::l_brace)) {
62586251
diagnose(Tok, diag::protocol_init_with_body);
6259-
skipUntilDeclRBrace();
6260-
} else {
6261-
// Parse the body.
6262-
ParseFunctionBody CC(*this, CD);
6263-
setLocalDiscriminatorToParamList(CD->getParameters());
6264-
6265-
if (!isDelayedParsingEnabled()) {
6266-
if (Context.Stats)
6267-
Context.Stats->getFrontendCounters().NumFunctionsParsed++;
6268-
6269-
ParserResult<BraceStmt> Body =
6270-
parseBraceItemList(diag::invalid_diagnostic);
6271-
6272-
if (!Body.isNull())
6273-
CD->setBody(Body.get());
6274-
} else {
6275-
consumeAbstractFunctionBody(CD, Attributes);
6276-
}
6252+
skipSingle();
62776253
}
6254+
} else {
6255+
parseAbstractFunctionBody(CD);
62786256
}
62796257

62806258
CD->getAttrs() = Attributes;
@@ -6327,30 +6305,8 @@ parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
63276305
}
63286306
}
63296307

6330-
Scope S(this, ScopeKind::DestructorBody);
63316308
auto *DD = new (Context) DestructorDecl(DestructorLoc, CurDeclContext);
6332-
6333-
// Parse the body.
6334-
if (Tok.is(tok::l_brace)) {
6335-
// Record the curly braces but nothing inside.
6336-
SF.recordInterfaceToken("{");
6337-
SF.recordInterfaceToken("}");
6338-
llvm::SaveAndRestore<bool> T(IsParsingInterfaceTokens, false);
6339-
6340-
ParseFunctionBody CC(*this, DD);
6341-
if (!isDelayedParsingEnabled()) {
6342-
if (Context.Stats)
6343-
Context.Stats->getFrontendCounters().NumFunctionsParsed++;
6344-
6345-
ParserResult<BraceStmt> Body =
6346-
parseBraceItemList(diag::invalid_diagnostic);
6347-
6348-
if (!Body.isNull())
6349-
DD->setBody(Body.get());
6350-
} else {
6351-
consumeAbstractFunctionBody(DD, Attributes);
6352-
}
6353-
}
6309+
parseAbstractFunctionBody(DD);
63546310

63556311
DD->getAttrs() = Attributes;
63566312

lib/Parse/Scope.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ static bool isResolvableScope(ScopeKind SK) {
3636
return false;
3737
case ScopeKind::FunctionBody:
3838
case ScopeKind::Generics:
39-
case ScopeKind::ConstructorBody:
40-
case ScopeKind::DestructorBody:
4139
case ScopeKind::Brace:
42-
case ScopeKind::ForVars:
4340
case ScopeKind::ForeachVars:
4441
case ScopeKind::ClosureParams:
4542
case ScopeKind::CaseVars:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %{python} %utils/split_file.py -o %t %s
3+
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
4+
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
5+
// RUN: cmp %t/a.hash %t/b.hash
6+
7+
// BEGIN a.swift
8+
func test() -> Int {
9+
return 0
10+
}
11+
12+
// BEGIN b.swift
13+
func test() -> Int {
14+
func inner() -> Int{
15+
return 0
16+
}
17+
return inner()
18+
}

0 commit comments

Comments
 (0)