Skip to content

Commit 0f53348

Browse files
committed
Merge pull request #1501 from dduan/SE-0034-pr
[Parser][SE-0034] Replace line directive #line with #setline
2 parents 1cb9c24 + 742c2cf commit 0f53348

File tree

9 files changed

+64
-37
lines changed

9 files changed

+64
-37
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ NOTE(note_in_decl_extension,none,
148148
WARNING(inout_as_attr_deprecated,none,
149149
"'inout' before a parameter name is deprecated, place it before the parameter type instead",
150150
())
151+
WARNING(line_directive_style_deprecated,none,
152+
"#line directive is deprecated, please use #setline instead",
153+
())
151154

152155
ERROR(declaration_same_line_without_semi,none,
153156
"consecutive declarations on a line must be separated by ';'", ())

include/swift/Parse/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,8 +695,9 @@ class Parser {
695695
DeclAttributes &Attributes);
696696

697697
ParserResult<IfConfigDecl> parseDeclIfConfig(ParseDeclOptions Flags);
698-
/// Parse a #line directive.
699-
ParserStatus parseLineDirective();
698+
/// Parse a #line/#setline directive.
699+
/// 'isLine = true' indicates parsing #line instead of #setline
700+
ParserStatus parseLineDirective(bool isLine = false);
700701

701702
void setLocalDiscriminator(ValueDecl *D);
702703

include/swift/Parse/Tokens.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ POUND_KEYWORD(else)
171171
POUND_KEYWORD(elseif)
172172
POUND_KEYWORD(endif)
173173
POUND_KEYWORD(line)
174+
POUND_KEYWORD(setline)
174175
POUND_KEYWORD(available)
175176
POUND_KEYWORD(selector)
176177

lib/Parse/ParseDecl.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,10 +1706,11 @@ static bool isKeywordPossibleDeclStart(const Token &Tok) {
17061706
case tok::kw_var:
17071707
case tok::pound_if:
17081708
case tok::identifier:
1709+
case tok::pound_setline:
17091710
return true;
17101711
case tok::pound_line:
1711-
// #line at the start of the line is a directive, #line within a line is
1712-
// an expression.
1712+
// #line at the start of the line is a directive, but it's deprecated.
1713+
// #line within a line is an expression.
17131714
return Tok.isAtStartOfLine();
17141715

17151716
case tok::kw_try:
@@ -2093,8 +2094,11 @@ ParserStatus Parser::parseDecl(SmallVectorImpl<Decl*> &Entries,
20932094
}
20942095
break;
20952096
}
2097+
case tok::pound_setline:
2098+
Status = parseLineDirective(false);
2099+
break;
20962100
case tok::pound_line:
2097-
Status = parseLineDirective();
2101+
Status = parseLineDirective(true);
20982102
break;
20992103

21002104
case tok::kw_func:
@@ -2556,15 +2560,20 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
25562560
return DCC.fixupParserResult(status, ext);
25572561
}
25582562

2559-
ParserStatus Parser::parseLineDirective() {
2560-
SourceLoc Loc = consumeToken(tok::pound_line);
2563+
ParserStatus Parser::parseLineDirective(bool isLine) {
2564+
SourceLoc Loc = consumeToken(isLine ? tok::pound_line
2565+
: tok::pound_setline);
2566+
if (isLine) {
2567+
diagnose(Loc, diag::line_directive_style_deprecated)
2568+
.fixItReplace(Loc, "#setline");
2569+
}
25612570
bool WasInPoundLineEnvironment = InPoundLineEnvironment;
25622571
if (WasInPoundLineEnvironment) {
25632572
SourceMgr.closeVirtualFile(Loc);
25642573
InPoundLineEnvironment = false;
25652574
}
25662575

2567-
// #line\n returns to the main buffer.
2576+
// #setline\n returns to the main buffer.
25682577
if (Tok.isAtStartOfLine()) {
25692578
if (!WasInPoundLineEnvironment) {
25702579
diagnose(Tok, diag::unexpected_line_directive);
@@ -2573,7 +2582,7 @@ ParserStatus Parser::parseLineDirective() {
25732582
return makeParserSuccess();
25742583
}
25752584

2576-
// #line 42 "file.swift"\n
2585+
// #setline 42 "file.swift"\n
25772586
if (Tok.isNot(tok::integer_literal)) {
25782587
diagnose(Tok, diag::expected_line_directive_number);
25792588
return makeParserError();
@@ -2594,7 +2603,9 @@ ParserStatus Parser::parseLineDirective() {
25942603
return makeParserError();
25952604
}
25962605

2597-
auto Filename = getStringLiteralIfNotInterpolated(*this, Loc, Tok, "#line");
2606+
auto Filename = getStringLiteralIfNotInterpolated(*this, Loc, Tok,
2607+
isLine ? "#line"
2608+
: "#setline");
25982609
if (!Filename.hasValue())
25992610
return makeParserError();
26002611

lib/Parse/ParseStmt.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ bool Parser::isStartOfStmt() {
4747
case tok::kw_case:
4848
case tok::kw_default:
4949
case tok::pound_if:
50+
case tok::pound_setline:
5051
return true;
5152

5253
case tok::pound_line:
@@ -291,7 +292,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
291292
PreviousHadSemi = false;
292293
if (isStartOfDecl()
293294
&& Tok.isNot(tok::pound_if)
294-
&& Tok.isNot(tok::pound_line)) {
295+
&& Tok.isNot(tok::pound_setline)) {
295296
ParserStatus Status =
296297
parseDecl(TmpDecls, IsTopLevel ? PD_AllowTopLevel : PD_Default);
297298
if (Status.isError()) {
@@ -345,7 +346,11 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
345346
}
346347

347348
} else if (Tok.is(tok::pound_line)) {
348-
ParserStatus Status = parseLineDirective();
349+
ParserStatus Status = parseLineDirective(true);
350+
BraceItemsStatus |= Status;
351+
NeedParseErrorRecovery = Status.isError();
352+
} else if (Tok.is(tok::pound_setline)) {
353+
ParserStatus Status = parseLineDirective(false);
349354
BraceItemsStatus |= Status;
350355
NeedParseErrorRecovery = Status.isError();
351356
} else if (IsTopLevel) {
@@ -558,7 +563,11 @@ ParserResult<Stmt> Parser::parseStmt() {
558563
case tok::pound_line:
559564
if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
560565
if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
561-
return parseLineDirective();
566+
return parseLineDirective(true);
567+
case tok::pound_setline:
568+
if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
569+
if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
570+
return parseLineDirective(false);
562571
case tok::kw_while:
563572
if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
564573
return parseStmtWhile(LabelInfo);

test/DebugInfo/inlinedAt.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
// RUN: | FileCheck %s --check-prefix=CHECK-SIL
33
// RUN: %target-swift-frontend %s -O -I %t -emit-ir -g -o - | FileCheck %s
44

5-
#line 100 "abc.swift"
5+
#setline 100 "abc.swift"
66
@inline(__always)
77
func h(k : Int) -> Int { // 101
88
return k // 102
99
}
1010

11-
#line 200 "abc.swift"
11+
#setline 200 "abc.swift"
1212
@inline(__always)
1313
func g(j : Int) -> Int { // 201
1414
return h(j) // 202
1515
}
1616

17-
#line 301 "abc.swift"
17+
#setline 301 "abc.swift"
1818
public func f(i : Int) -> Int { // 301
1919
return g(i) // 302
2020
}

test/DebugInfo/line-directive.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
func markUsed<T>(t: T) {}
22
func f() {
33
if 1==1 {
4-
#line 42 "abc.swift"
4+
#setline 42 "abc.swift"
55
markUsed("Hello World")
6-
#line
6+
#setline
77
}
88
markUsed("Test")
9-
#line 142 "abc.swift"
9+
#setline 142 "abc.swift"
1010
markUsed("abc again")
11-
#line 142 "def.swift"
11+
#setline 142 "def.swift"
1212
markUsed("jump directly to def")
1313
}
1414

test/Parse/line-directive.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
let x = 0 // We need this because of the #line-ends-with-a-newline requirement.
44

5-
#line
5+
#setline
66
x // expected-error {{parameterless closing #line directive}}
77

8-
#line 0 "x" // expected-error{{the line number needs to be greater}}
8+
#setline 0 "x" // expected-error{{the line number needs to be greater}}
99

10-
#line -1 "x" // expected-error{{expected starting line number}}
10+
#setline -1 "x" // expected-error{{expected starting line number}}
1111

12-
#line 1.5 "x" // expected-error{{expected starting line number}}
12+
#setline 1.5 "x" // expected-error{{expected starting line number}}
1313

14-
#line 1 x.swift // expected-error{{expected filename string literal}}
14+
#setline 1 x.swift // expected-error{{expected filename string literal}}
1515

16-
#line 42 "x.swift"
16+
#setline 42 "x.swift"
1717
x x ; // should be ignored by expected_error because it is in a different file
1818
x
19-
#line
19+
#setline
2020
x
2121
x x // expected-error{{consecutive statements}} {{2-2=;}}
2222

@@ -25,3 +25,5 @@ public struct S { // expected-note{{in declaration of 'S'}}
2525
// expected-error@+1{{expected declaration}}
2626
/ ###line 25 "line-directive.swift"
2727
}
28+
// expected-warning@+1{{#line directive is deprecated, please use #setline instead}}
29+
#line 32000 "troops_on_the_water"

utils/gyb.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def next_token(self):
529529
class ExecutionContext:
530530
"""State we pass around during execution of a template"""
531531

532-
def __init__(self, line_directive='// ###line', **local_bindings):
532+
def __init__(self, line_directive='// ###setline', **local_bindings):
533533
self.local_bindings = local_bindings
534534
self.line_directive = line_directive
535535
self.local_bindings['__context__'] = self
@@ -955,14 +955,14 @@ def execute_template(ast, line_directive='', **local_bindings):
955955
... % else:
956956
... THIS SHOULD NOT APPEAR IN THE OUTPUT
957957
... ''')
958-
>>> print execute_template(ast, line_directive='//#line', x=1),
959-
//#line 1 "/dummy.file"
958+
>>> print execute_template(ast, line_directive='//#setline', x=1),
959+
//#setline 1 "/dummy.file"
960960
Nothing
961-
//#line 4 "/dummy.file"
961+
//#setline 4 "/dummy.file"
962962
0
963-
//#line 4 "/dummy.file"
963+
//#setline 4 "/dummy.file"
964964
1
965-
//#line 4 "/dummy.file"
965+
//#setline 4 "/dummy.file"
966966
2
967967
968968
>>> ast = parse_template('/dummy.file', text=
@@ -973,10 +973,10 @@ def execute_template(ast, line_directive='', **local_bindings):
973973
... % end
974974
... ${a}
975975
... ''')
976-
>>> print execute_template(ast, line_directive='//#line', x=1),
977-
//#line 1 "/dummy.file"
976+
>>> print execute_template(ast, line_directive='//#setline', x=1),
977+
//#setline 1 "/dummy.file"
978978
Nothing
979-
//#line 6 "/dummy.file"
979+
//#setline 6 "/dummy.file"
980980
[0, 1, 2]
981981
"""
982982
executionContext = ExecutionContext(line_directive=line_directive, **local_bindings)
@@ -1059,7 +1059,7 @@ def succ(a):
10591059
parser.add_argument('--test', action='store_true', default=False, help='Run a self-test')
10601060
parser.add_argument('--verbose-test', action='store_true', default=False, help='Run a verbose self-test')
10611061
parser.add_argument('--dump', action='store_true', default=False, help='Dump the parsed template to stdout')
1062-
parser.add_argument('--line-directive', default='// ###line', help='Line directive prefix; empty => no line markers')
1062+
parser.add_argument('--line-directive', default='// ###setline', help='Line directive prefix; empty => no line markers')
10631063

10641064
args = parser.parse_args(sys.argv[1:])
10651065

0 commit comments

Comments
 (0)