Skip to content

Commit e9cc033

Browse files
committed
refactor(parse): put implicit else statements in the actual else node
1 parent c0a8338 commit e9cc033

File tree

6 files changed

+83
-65
lines changed

6 files changed

+83
-65
lines changed

regression-tests/pure2-last-use.cpp2

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ issue_350: () = {
1515
x++;
1616
}
1717

18+
issue_440: () = {
19+
i: int;
20+
if true {
21+
i = 1;
22+
}
23+
i = 2;
24+
}
25+
1826
issue_683: (args) = {
1927
for args do (n) {
2028
_ = n;

regression-tests/test-results/pure2-last-use.cpp

+33-22
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@
88

99
#line 1 "pure2-last-use.cpp2"
1010

11-
#line 48 "pure2-last-use.cpp2"
11+
#line 56 "pure2-last-use.cpp2"
1212
class issue_857;
1313

1414

15-
#line 72 "pure2-last-use.cpp2"
15+
#line 80 "pure2-last-use.cpp2"
1616
class issue_857_2;
1717

1818

19-
#line 77 "pure2-last-use.cpp2"
19+
#line 85 "pure2-last-use.cpp2"
2020
class issue_857_3;
2121

2222

23-
#line 123 "pure2-last-use.cpp2"
23+
#line 131 "pure2-last-use.cpp2"
2424
class my_string;
2525

2626

@@ -33,15 +33,18 @@ class my_string;
3333
auto issue_350() -> void;
3434

3535
#line 18 "pure2-last-use.cpp2"
36+
auto issue_440() -> void;
37+
38+
#line 26 "pure2-last-use.cpp2"
3639
auto issue_683(auto const& args) -> void;
3740

38-
#line 27 "pure2-last-use.cpp2"
41+
#line 35 "pure2-last-use.cpp2"
3942
auto issue_825() -> void;
4043

41-
#line 33 "pure2-last-use.cpp2"
44+
#line 41 "pure2-last-use.cpp2"
4245
auto issue_832() -> void;
4346

44-
#line 38 "pure2-last-use.cpp2"
47+
#line 46 "pure2-last-use.cpp2"
4548
[[nodiscard]] auto make_copy(auto x) -> auto;
4649

4750
auto issue_847_0(std::vector<std::unique_ptr<int>> v) -> void;
@@ -56,7 +59,7 @@ class issue_857 {
5659
private: std::unique_ptr<int> a;
5760
private: std::unique_ptr<int> b;
5861
public: issue_857(issue_857&& that) noexcept;
59-
#line 51 "pure2-last-use.cpp2"
62+
#line 59 "pure2-last-use.cpp2"
6063
public: auto operator=(issue_857&& that) noexcept -> issue_857& ;
6164
public: ~issue_857() noexcept;
6265
public: auto f() && -> void;
@@ -88,22 +91,22 @@ class issue_857_3 {
8891
public: auto f() && -> void;
8992
};
9093

91-
#line 83 "pure2-last-use.cpp2"
94+
#line 91 "pure2-last-use.cpp2"
9295
auto issue_884_3() -> void;
9396

94-
#line 93 "pure2-last-use.cpp2"
97+
#line 101 "pure2-last-use.cpp2"
9598
auto issue_884() -> void;
9699

97-
#line 102 "pure2-last-use.cpp2"
100+
#line 110 "pure2-last-use.cpp2"
98101
auto issue_884_2() -> void;
99102

100-
#line 111 "pure2-last-use.cpp2"
103+
#line 119 "pure2-last-use.cpp2"
101104
auto issue_888(std::string r, int size) -> void;
102105

103-
#line 117 "pure2-last-use.cpp2"
106+
#line 125 "pure2-last-use.cpp2"
104107
auto draw() -> void;
105108

106-
#line 123 "pure2-last-use.cpp2"
109+
#line 131 "pure2-last-use.cpp2"
107110
class my_string {
108111
public: std::string string;
109112
public: std::size_t size {CPP2_UFCS(size)(string)};
@@ -132,6 +135,14 @@ auto issue_350() -> void{
132135
++x;
133136
}
134137

138+
auto issue_440() -> void{
139+
cpp2::deferred_init<int> i;
140+
if (true) {
141+
i.construct(1);
142+
}
143+
i.construct(2);
144+
}
145+
135146
auto issue_683(auto const& args) -> void{
136147
for ( auto const& n : args ) {
137148
static_cast<void>(n);
@@ -162,16 +173,16 @@ auto issue_847_3(int x) -> void{for ( [[maybe_unused]] auto const& unnamed_param
162173
auto f_inout([[maybe_unused]] std::unique_ptr<int>& unnamed_param_1) -> void{}
163174
auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{}
164175

165-
#line 51 "pure2-last-use.cpp2"
176+
#line 59 "pure2-last-use.cpp2"
166177
issue_857::issue_857(issue_857&& that) noexcept
167178
: a{ std::move(that).a }
168179
, b{ std::move(that).b }{}
169-
#line 51 "pure2-last-use.cpp2"
180+
#line 59 "pure2-last-use.cpp2"
170181
auto issue_857::operator=(issue_857&& that) noexcept -> issue_857& {
171182
a = std::move(that).a;
172183
b = std::move(that).b;
173184
return *this; }
174-
#line 52 "pure2-last-use.cpp2"
185+
#line 60 "pure2-last-use.cpp2"
175186
issue_857::~issue_857() noexcept { f_copy(std::move(*this).a, std::move((*this)).b); }
176187
auto issue_857::f() && -> void { f_copy(std::move((*this))); }
177188
auto issue_857::f(issue_857&& that) && -> void { f_copy(std::move((*this)), std::move(that)); }
@@ -191,13 +202,13 @@ auto f_copy([[maybe_unused]] auto ...unnamed_param_1) -> void{}
191202
auto issue_857::o3() && -> void { std::move(*this).n(0); }
192203
auto issue_857::o4() && -> void { std::move(*this).n(std::move((*this))); }
193204

194-
#line 76 "pure2-last-use.cpp2"
205+
#line 84 "pure2-last-use.cpp2"
195206
int gi {0};
196207

197-
#line 79 "pure2-last-use.cpp2"
208+
#line 87 "pure2-last-use.cpp2"
198209
auto issue_857_3::f() && -> void { static_cast<void>(f_inout(std::move(*this).i)); }
199210

200-
#line 83 "pure2-last-use.cpp2"
211+
#line 91 "pure2-last-use.cpp2"
201212
auto issue_884_3() -> void{
202213
auto x {cpp2_new<int>(0)};
203214
if (true) {}
@@ -238,10 +249,10 @@ auto draw() -> void{
238249
static_cast<void>(CPP2_UFCS_MOVE(vertex)((std::move(pos))));
239250
}
240251

241-
#line 128 "pure2-last-use.cpp2"
252+
#line 136 "pure2-last-use.cpp2"
242253
auto main(int const argc_, char** argv_) -> int{
243254
auto const args = cpp2::make_args(argc_, argv_);
244-
#line 129 "pure2-last-use.cpp2"
255+
#line 137 "pure2-last-use.cpp2"
245256
issue_683(args);
246257
issue_847_2(std::vector<std::unique_ptr<int>>());
247258
}

regression-tests/test-results/pure2-print.cpp2.output

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ outer: type =
2020
{
2121
ret = -p*;
2222
}
23-
ret += strlen(s) - 10 + s.strlen() * (16 / (3 & 2)) % 3;
24-
m: map<const int, string> = ();
25-
m[0] = "har" as string;
26-
ret -= h("x", m).length();
27-
_ = m;
28-
return ret;
23+
ret += strlen(s) - 10 + s.strlen() * (16 / (3 & 2)) % 3;
24+
m: map<const int, string> = ();
25+
m[0] = "har" as string;
26+
ret -= h("x", m).length();
27+
_ = m;
28+
return ret;
2929
}
3030

3131
private h:(

source/parse.h

+23-5
Original file line numberDiff line numberDiff line change
@@ -4186,7 +4186,7 @@ auto pretty_print_visualize(is_as_expression_node const& n, int indent)
41864186
-> std::string;
41874187
auto pretty_print_visualize(id_expression_node const& n, int indent)
41884188
-> std::string;
4189-
auto pretty_print_visualize(compound_statement_node const& n, int indent)
4189+
auto pretty_print_visualize(compound_statement_node const& n, int indent, bool explicit_scope = true)
41904190
-> std::string;
41914191
auto pretty_print_visualize(selection_statement_node const& n, int indent)
41924192
-> std::string;
@@ -4506,17 +4506,23 @@ auto pretty_print_visualize(id_expression_node const& n, int indent)
45064506
}
45074507

45084508

4509-
auto pretty_print_visualize(compound_statement_node const& n, int indent)
4509+
auto pretty_print_visualize(compound_statement_node const& n, int indent, bool explicit_scope)
45104510
-> std::string
45114511
{
4512-
auto ret = std::string{"\n"} + pre(indent) + "{";
4512+
auto ret = std::string{};
4513+
4514+
if (explicit_scope) {
4515+
ret += std::string{"\n"} + pre(indent) + "{";
4516+
}
45134517

45144518
for (auto& stmt : n.statements) {
45154519
assert (stmt);
45164520
ret += pretty_print_visualize(*stmt, indent+1);
45174521
}
45184522

4519-
ret += std::string{"\n"} + pre(indent) + "}";
4523+
if (explicit_scope) {
4524+
ret += std::string{"\n"} + pre(indent) + "}";
4525+
}
45204526

45214527
return ret;
45224528
}
@@ -4541,6 +4547,8 @@ auto pretty_print_visualize(selection_statement_node const& n, int indent)
45414547
if (n.has_source_false_branch) {
45424548
ret += std::string{"\n"} + pre(indent) + "else "
45434549
+ pretty_print_visualize(*n.false_branch, indent);
4550+
} else if (!n.false_branch->statements.empty()) {
4551+
ret += pretty_print_visualize(*n.false_branch, indent, false);
45444552
}
45454553

45464554
return ret;
@@ -7321,6 +7329,7 @@ class parser
73217329
next();
73227330
}
73237331

7332+
auto statements = &n->statements;
73247333
while (
73257334
curr().type() != lexeme::RightBrace
73267335
&& (
@@ -7341,7 +7350,16 @@ class parser
73417350
pos = start_pos; // backtrack
73427351
return {};
73437352
}
7344-
n->statements.push_back( std::move(s) );
7353+
statements->push_back( std::move(s) );
7354+
7355+
// Add statements to the most recent implicit else branch
7356+
if (auto selection = statements->back()->get_if<selection_statement_node>();
7357+
selection
7358+
&& !selection->has_source_false_branch
7359+
)
7360+
{
7361+
statements = &selection->false_branch->statements;
7362+
}
73457363
}
73467364

73477365
if (is_braced) {

source/sema.h

+2-28
Original file line numberDiff line numberDiff line change
@@ -1882,18 +1882,11 @@ class sema
18821882
++scope_depth;
18831883
}
18841884

1885-
auto end(selection_statement_node const& s, int) -> void
1885+
auto end(selection_statement_node const&, int) -> void
18861886
{
18871887
symbols.emplace_back( scope_depth, selection_sym{ false, active_selections.back() } );
18881888
active_selections.pop_back();
1889-
// Extend the scope of an implicit else branch
1890-
// to the closing brace that contains it.
1891-
if (s.false_branch->position() == source_position(0, 0)) {
1892-
++scope_depth;
1893-
}
1894-
else {
1895-
--scope_depth;
1896-
}
1889+
--scope_depth;
18971890
}
18981891

18991892
auto kind_of(compound_statement_node const& n)
@@ -1934,25 +1927,6 @@ class sema
19341927
compound_sym{ false, &n, kind_of(n) }
19351928
);
19361929
--scope_depth;
1937-
1938-
auto pop_implicit_else_branch = [&]() -> bool {
1939-
if (auto s = std::find_if(
1940-
symbols.rbegin(),
1941-
symbols.rend(),
1942-
[=](symbol s) {
1943-
return s.depth <= scope_depth;
1944-
});
1945-
s != symbols.rend()
1946-
&& std::get_if<symbol::selection>(&s->sym)
1947-
&& s->depth == scope_depth
1948-
)
1949-
{
1950-
--scope_depth;
1951-
return true;
1952-
}
1953-
return false;
1954-
};
1955-
while (pop_implicit_else_branch()) { }
19561930
}
19571931

19581932
auto start(assignment_expression_node const& n, int)

source/to_cpp1.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -1962,15 +1962,18 @@ class cppfront
19621962
//-----------------------------------------------------------------------
19631963
//
19641964
auto emit(
1965-
compound_statement_node const& n,
1965+
compound_statement_node const& n,
1966+
bool explicit_scope = true,
19661967
function_prolog const& function_prolog = {},
19671968
std::vector<std::string> const& function_epilog = {}
19681969
)
19691970
-> void
19701971
{ STACKINSTR
19711972
emit_prolog_mem_inits(function_prolog, n.body_indent+1);
19721973

1973-
printer.print_cpp2( "{", n.open_brace );
1974+
if (explicit_scope) {
1975+
printer.print_cpp2( "{", n.open_brace );
1976+
}
19741977

19751978
emit_prolog_statements(function_prolog, n.body_indent+1);
19761979

@@ -1981,7 +1984,9 @@ class cppfront
19811984

19821985
emit_epilog_statements( function_epilog, n.body_indent+1);
19831986

1984-
printer.print_cpp2( "}", n.close_brace );
1987+
if (explicit_scope) {
1988+
printer.print_cpp2( "}", n.close_brace );
1989+
}
19851990
}
19861991

19871992

@@ -2167,6 +2172,8 @@ class cppfront
21672172
if (n.has_source_false_branch) {
21682173
printer.print_cpp2("else ", n.else_pos);
21692174
emit(*n.false_branch);
2175+
} else if (!n.false_branch->statements.empty()) {
2176+
emit(*n.false_branch, false);
21702177
}
21712178
}
21722179

@@ -4151,7 +4158,7 @@ class cppfront
41514158

41524159
printer.disable_indent_heuristic_for_next_text();
41534160

4154-
try_emit<statement_node::compound >(n.statement, function_prolog, function_epilog);
4161+
try_emit<statement_node::compound >(n.statement, true, function_prolog, function_epilog);
41554162

41564163
// NOTE: Reset preemption here because
41574164
// - for compound statements written as "= { ... }", we want to keep the

0 commit comments

Comments
 (0)