Skip to content

Commit cfe742d

Browse files
committed
[Parse] Minor improvements in conditional compilation block parsing
* Don't emit duplicated 'expected #else or #endif at end of conditional compilation block' error. class Foo { #if true func foo() {} [EOF] * Improve error message when seeing '}' in config block. class Foo { #if true func foo(); } // error: unexpected '}' in conditional compilation block #else #endif
1 parent 4dbe0fc commit cfe742d

File tree

4 files changed

+21
-13
lines changed

4 files changed

+21
-13
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ ERROR(incomplete_conditional_compilation_directive,none,
6565
"incomplete condition in conditional compilation directive", ())
6666
ERROR(extra_tokens_conditional_compilation_directive,none,
6767
"extra tokens following conditional compilation directive", ())
68+
ERROR(unexpected_rbrace_in_conditional_compilation_block,none,
69+
"unexpected '}' in conditional compilation block", ())
6870

6971
ERROR(sourceLocation_expected,none,
7072
"expected '%0' in #sourceLocation directive", (StringRef))

lib/Parse/ParseDecl.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,19 +3045,18 @@ ParserResult<IfConfigDecl> Parser::parseDeclIfConfig(ParseDeclOptions Flags) {
30453045
if (ConfigState.shouldParse()) {
30463046
ParserStatus Status;
30473047
bool PreviousHadSemi = true;
3048-
while (Tok.isNot(tok::pound_else, tok::pound_endif, tok::pound_elseif)) {
3049-
SourceLoc StartLoc = Tok.getLoc();
3050-
Status |= parseDeclItem(*this, PreviousHadSemi, Flags,
3051-
[&](Decl *D) {Decls.push_back(D);});
3052-
if (StartLoc == Tok.getLoc()) {
3053-
assert(Status.isError() && "no progress without error?");
3048+
while (Tok.isNot(tok::pound_else, tok::pound_endif, tok::pound_elseif,
3049+
tok::eof)) {
3050+
if (Tok.is(tok::r_brace)) {
3051+
diagnose(Tok.getLoc(),
3052+
diag::unexpected_rbrace_in_conditional_compilation_block);
3053+
// If we see '}', following declarations don't look like belong to
3054+
// the current decl context; skip them.
30543055
skipUntilConditionalBlockClose();
30553056
break;
30563057
}
3057-
if (Tok.isAny(tok::eof)) {
3058-
diagnose(Tok, diag::expected_close_to_if_directive);
3059-
break;
3060-
}
3058+
Status |= parseDeclItem(*this, PreviousHadSemi, Flags,
3059+
[&](Decl *D) {Decls.push_back(D);});
30613060
}
30623061
} else {
30633062
DiagnosticTransaction DT(Diags);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
class C2 { // expected-note {{to match this opening '{'}}
4+
#if FOO
5+
func foo() {}
6+
// expected-error @+2 {{expected '}' in class}}
7+
// expected-error @+1 {{expected #else or #endif at end of conditional compilation block}}

test/Parse/ConditionalCompilation/decl_parse_errors.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ lazy
2727
var val3: Int = 0;
2828
#line
2929

30-
class C { // expected-note 2 {{in declaration of 'C'}} expected-note {{to match this opening '{'}}
30+
class C { // expected-note {{to match this opening '{'}}
3131

3232
#if os(iOS)
3333
func foo() {}
34-
} // expected-error{{expected declaration}}
34+
} // expected-error{{unexpected '}' in conditional compilation block}}
3535
#else
3636
func bar() {}
3737
func baz() {}
38-
} // expected-error{{expected declaration}}
38+
} // expected-error{{unexpected '}' in conditional compilation block}}
3939
#endif
4040
// expected-error@+1{{expected '}' in class}}

0 commit comments

Comments
 (0)