@@ -2253,12 +2253,6 @@ ParserStatus Parser::parseDecl(ParseDeclOptions Flags,
22532253 InternalHandler (DeclResult.get ());
22542254 }
22552255
2256- if (Tok.is (tok::semi)) {
2257- SourceLoc TrailingSemiLoc = consumeToken (tok::semi);
2258- if (Status.isSuccess ())
2259- LastDecl->TrailingSemiLoc = TrailingSemiLoc;
2260- }
2261-
22622256 if (Status.isSuccess ()) {
22632257 // If we parsed 'class' or 'static', but didn't handle it above, complain
22642258 // about it.
@@ -2592,6 +2586,61 @@ parseIdentifierDeclName(Parser &P, Identifier &Result, SourceLoc &L,
25922586 ResyncP1, Diagnostic (ID, Args...));
25932587}
25942588
2589+ // / Parse a Decl item in decl list.
2590+ static ParserStatus parseDeclItem (Parser &P,
2591+ bool &PreviousHadSemi,
2592+ Parser::ParseDeclOptions Options,
2593+ llvm::function_ref<void (Decl*)> handler) {
2594+ if (P.Tok .is (tok::semi)) {
2595+ // Consume ';' without preceding decl.
2596+ P.diagnose (P.Tok , diag::unexpected_separator, " ;" )
2597+ .fixItRemove (P.Tok .getLoc ());
2598+ P.consumeToken ();
2599+ // Return success because we already recovered.
2600+ return makeParserSuccess ();
2601+ }
2602+
2603+ // If the previous declaration didn't have a semicolon and this new
2604+ // declaration doesn't start a line, complain.
2605+ if (!PreviousHadSemi && !P.Tok .isAtStartOfLine () && !P.Tok .is (tok::unknown)) {
2606+ auto endOfPrevious = P.getEndOfPreviousLoc ();
2607+ P.diagnose (endOfPrevious, diag::declaration_same_line_without_semi)
2608+ .fixItInsert (endOfPrevious, " ;" );
2609+ }
2610+
2611+ ParserStatus Status = P.parseDecl (Options, handler);
2612+ if (Status.isError ())
2613+ P.skipUntilDeclRBrace (tok::semi, tok::pound_endif);
2614+ PreviousHadSemi = P.consumeIf (tok::semi);
2615+ return Status;
2616+ }
2617+
2618+ // / \brief Parse the members in a struct/class/enum/protocol/extension.
2619+ // /
2620+ // / \verbatim
2621+ // / decl* '}'
2622+ // / \endverbatim
2623+ bool Parser::parseDeclList (SourceLoc LBLoc, SourceLoc &RBLoc,
2624+ Diag<> ErrorDiag, ParseDeclOptions Options,
2625+ llvm::function_ref<void (Decl*)> handler) {
2626+ ParserStatus Status;
2627+ bool PreviousHadSemi = true ;
2628+ while (Tok.isNot (tok::r_brace)) {
2629+ Status |= parseDeclItem (*this , PreviousHadSemi, Options, handler);
2630+ if (Tok.isAny (tok::eof, tok::pound_endif, tok::pound_else,
2631+ tok::pound_elseif)) {
2632+ IsInputIncomplete = true ;
2633+ break ;
2634+ }
2635+ }
2636+
2637+ parseMatchingToken (tok::r_brace, RBLoc, ErrorDiag, LBLoc);
2638+
2639+ // If we found the closing brace, then the caller should not care if there
2640+ // were errors while parsing inner decls, because we recovered.
2641+ return !RBLoc.isValid ();
2642+ }
2643+
25952644// / \brief Parse an 'extension' declaration.
25962645// /
25972646// / \verbatim
@@ -2651,20 +2700,15 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
26512700 ContextChange CC (*this , ext);
26522701 Scope S (this , ScopeKind::Extension);
26532702
2654- ParserStatus BodyStatus =
2655- parseList (tok::r_brace, LBLoc, RBLoc, tok::semi, /* OptionalSep=*/ true ,
2656- /* AllowSepAfterLast=*/ false , diag::expected_rbrace_extension,
2657- [&]() -> ParserStatus {
2658- ParseDeclOptions Options (PD_HasContainerType |
2659- PD_InExtension);
2703+ ParseDeclOptions Options (PD_HasContainerType | PD_InExtension);
2704+
2705+ if (parseDeclList (LBLoc, RBLoc, diag::expected_rbrace_extension,
2706+ Options, [&] (Decl *D) {ext->addMember (D);}))
2707+ status.setIsParseError ();
26602708
2661- return parseDecl (Options, [&] (Decl *D) {ext->addMember (D);});
2662- });
26632709 // Don't propagate the code completion bit from members: we cannot help
26642710 // code completion inside a member decl, and our callers cannot do
26652711 // anything about it either. But propagate the error bit.
2666- if (BodyStatus.isError ())
2667- status.setIsParseError ();
26682712 }
26692713
26702714 ext->setBraces ({LBLoc, RBLoc});
@@ -2862,14 +2906,20 @@ ParserResult<IfConfigDecl> Parser::parseDeclIfConfig(ParseDeclOptions Flags) {
28622906 SmallVector<Decl*, 8 > Decls;
28632907 if (ConfigState.shouldParse ()) {
28642908 ParserStatus Status;
2865- while (Tok.isNot (tok::pound_else) && Tok.isNot (tok::pound_endif) &&
2866- Tok.isNot (tok::pound_elseif)) {
2867- Status = parseDecl (Flags, [&](Decl *D) {Decls.push_back (D);});
2868- if (Status.isError ()) {
2869- diagnose (Tok, diag::expected_close_to_if_directive);
2909+ bool PreviousHadSemi = true ;
2910+ while (Tok.isNot (tok::pound_else, tok::pound_endif, tok::pound_elseif)) {
2911+ SourceLoc StartLoc = Tok.getLoc ();
2912+ Status |= parseDeclItem (*this , PreviousHadSemi, Flags,
2913+ [&](Decl *D) {Decls.push_back (D);});
2914+ if (StartLoc == Tok.getLoc ()) {
2915+ assert (Status.isError () && " no progress without error?" );
28702916 skipUntilConditionalBlockClose ();
28712917 break ;
28722918 }
2919+ if (Tok.isAny (tok::eof)) {
2920+ diagnose (Tok, diag::expected_close_to_if_directive);
2921+ break ;
2922+ }
28732923 }
28742924 } else {
28752925 DiagnosticTransaction DT (Diags);
@@ -4773,9 +4823,8 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
47734823 ContextChange CC (*this , ED);
47744824 Scope S (this , ScopeKind::ClassBody);
47754825 ParseDeclOptions Options (PD_HasContainerType | PD_AllowEnumElement | PD_InEnum);
4776- if (parseNominalDeclMembers (LBLoc, RBLoc,
4777- diag::expected_rbrace_enum,
4778- Options, [&] (Decl *D) { ED->addMember (D); }))
4826+ if (parseDeclList (LBLoc, RBLoc, diag::expected_rbrace_enum,
4827+ Options, [&] (Decl *D) { ED->addMember (D); }))
47794828 Status.setIsParseError ();
47804829 }
47814830
@@ -4956,47 +5005,6 @@ ParserStatus Parser::parseDeclEnumCase(ParseDeclOptions Flags,
49565005 return Status;
49575006}
49585007
4959- // / \brief Parse the members in a struct/class/enum/protocol definition.
4960- // /
4961- // / \verbatim
4962- // / decl*
4963- // / \endverbatim
4964- bool Parser::parseNominalDeclMembers (SourceLoc LBLoc, SourceLoc &RBLoc,
4965- Diag<> ErrorDiag, ParseDeclOptions flags,
4966- llvm::function_ref<void (Decl*)> handler) {
4967- Decl *lastDecl = nullptr ;
4968- auto internalHandler = [&](Decl *D) {
4969- lastDecl = D;
4970- handler (D);
4971- };
4972- bool previousHadSemi = true ;
4973- parseList (tok::r_brace, LBLoc, RBLoc, tok::semi, /* OptionalSep=*/ true ,
4974- /* AllowSepAfterLast=*/ false , ErrorDiag, [&]() -> ParserStatus {
4975- // If the previous declaration didn't have a semicolon and this new
4976- // declaration doesn't start a line, complain.
4977- if (!previousHadSemi && !Tok.isAtStartOfLine () && !Tok.is (tok::unknown)) {
4978- SourceLoc endOfPrevious = getEndOfPreviousLoc ();
4979- diagnose (endOfPrevious, diag::declaration_same_line_without_semi)
4980- .fixItInsert (endOfPrevious, " ;" );
4981- // FIXME: Add semicolon to the AST?
4982- }
4983-
4984- previousHadSemi = false ;
4985- if (parseDecl (flags, internalHandler).isError ())
4986- return makeParserError ();
4987-
4988- // Check whether the previous declaration had a semicolon after it.
4989- if (lastDecl && lastDecl->TrailingSemiLoc .isValid ())
4990- previousHadSemi = true ;
4991-
4992- return makeParserSuccess ();
4993- });
4994-
4995- // If we found the closing brace, then the caller should not care if there
4996- // were errors while parsing inner decls, because we recovered.
4997- return !RBLoc.isValid ();
4998- }
4999-
50005008// / \brief Parse a 'struct' declaration, returning true (and doing no token
50015009// / skipping) on error.
50025010// /
@@ -5070,9 +5078,8 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
50705078 ContextChange CC (*this , SD);
50715079 Scope S (this , ScopeKind::StructBody);
50725080 ParseDeclOptions Options (PD_HasContainerType | PD_InStruct);
5073- if (parseNominalDeclMembers (LBLoc, RBLoc,
5074- diag::expected_rbrace_struct,
5075- Options, [&](Decl *D) {SD->addMember (D);}))
5081+ if (parseDeclList (LBLoc, RBLoc, diag::expected_rbrace_struct,
5082+ Options, [&](Decl *D) {SD->addMember (D);}))
50765083 Status.setIsParseError ();
50775084 }
50785085
@@ -5160,8 +5167,8 @@ ParserResult<ClassDecl> Parser::parseDeclClass(SourceLoc ClassLoc,
51605167 if (isa<DestructorDecl>(D))
51615168 CD->setHasDestructor ();
51625169 };
5163- if (parseNominalDeclMembers (LBLoc, RBLoc, diag::expected_rbrace_class,
5164- Options, Handler))
5170+ if (parseDeclList (LBLoc, RBLoc, diag::expected_rbrace_class,
5171+ Options, Handler))
51655172 Status.setIsParseError ();
51665173 }
51675174
@@ -5259,9 +5266,8 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
52595266 ParseDeclOptions Options (PD_HasContainerType |
52605267 PD_DisallowInit |
52615268 PD_InProtocol);
5262- if (parseNominalDeclMembers (LBraceLoc, RBraceLoc,
5263- diag::expected_rbrace_protocol,
5264- Options, [&](Decl *D) {Proto->addMember (D);}))
5269+ if (parseDeclList (LBraceLoc, RBraceLoc, diag::expected_rbrace_protocol,
5270+ Options, [&](Decl *D) {Proto->addMember (D);}))
52655271 Status.setIsParseError ();
52665272 }
52675273
0 commit comments