Skip to content

Commit 482bac8

Browse files
committed
Generate assignment operator from operator=(out this, with_one: additional_parameter)
1 parent 43cdf3e commit 482bac8

File tree

6 files changed

+125
-31
lines changed

6 files changed

+125
-31
lines changed

regression-tests/pure2-types-basics.cpp2

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,28 @@ myclass : type = {
66
operator=: (implicit out this, x: int) = {
77
data = x;
88
// use default initializer for this.more
9-
std::cout << "myclass: implicit constructor from int\n";
9+
std::cout << "myclass: implicit from int\n";
1010
print();
1111
}
1212

1313
operator=: (out this, s: std::string) = {
1414
this.data = 99;
15-
this.more = "plugh";
16-
std::cout << "myclass: explicit constructor from string\n";
15+
this.more = s;
16+
std::cout << "myclass: explicit from string\n";
17+
print();
18+
}
19+
20+
operator=: (out this, x: int, s: std::string) = {
21+
this.data = 77;
22+
this.more = s + " plugh";
23+
std::cout << "myclass: from int and string\n";
1724
print();
1825
}
1926

2027
operator=: (out this) = {
2128
// use default initializer for this.data
2229
more = std::to_string(3.14159);
23-
std::cout << "myclass: default constructor\n";
30+
std::cout << "myclass: default\n";
2431
print();
2532
}
2633

@@ -62,4 +69,13 @@ main: () = {
6269
std::cout << "f4: (x.f4<4,4>())$\n";
6370
x2: N::myclass = "abracadabra";
6471
x3: N::myclass = ();
72+
x4: N::myclass = (1, "hair");
73+
74+
// Invoke the single-param operator=s as actual assignments
75+
std::cout << "x's state before assignments: ";
76+
x.print();
77+
x = 84;
78+
x = "syzygy";
79+
x = 84;
80+
x = "syzygy";
6581
}
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1-
myclass: implicit constructor from int
1+
myclass: implicit from int
22
data: 1, more: 504
33
N::myclass::f with 53
44
N::myclass::nested::g
55
f1: 2
66
f2: 4
77
f3: 6
88
f4: 8
9-
myclass: explicit constructor from string
10-
data: 99, more: plugh
11-
myclass: default constructor
9+
myclass: explicit from string
10+
data: 99, more: abracadabra
11+
myclass: default
1212
data: 504, more: 3.141590
13+
myclass: from int and string
14+
data: 77, more: hair plugh
15+
x's state before assignments: data: 1, more: 504
16+
myclass: implicit from int
17+
data: 84, more: 504
18+
myclass: explicit from string
19+
data: 99, more: syzygy
20+
myclass: implicit from int
21+
data: 84, more: syzygy
22+
myclass: explicit from string
23+
data: 99, more: syzygy
24+
myclass: destructor
1325
myclass: destructor
1426
myclass: destructor
1527
myclass: destructor
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1-
myclass: implicit constructor from int
1+
myclass: implicit from int
22
data: 1, more: 504
33
N::myclass::f with 53
44
N::myclass::nested::g
55
f1: 2
66
f2: 4
77
f3: 6
88
f4: 8
9-
myclass: explicit constructor from string
10-
data: 99, more: plugh
11-
myclass: default constructor
9+
myclass: explicit from string
10+
data: 99, more: abracadabra
11+
myclass: default
1212
data: 504, more: 3.141590
13+
myclass: from int and string
14+
data: 77, more: hair plugh
15+
x's state before assignments: data: 1, more: 504
16+
myclass: implicit from int
17+
data: 84, more: 504
18+
myclass: explicit from string
19+
data: 99, more: syzygy
20+
myclass: implicit from int
21+
data: 84, more: syzygy
22+
myclass: explicit from string
23+
data: 99, more: syzygy
24+
myclass: destructor
1325
myclass: destructor
1426
myclass: destructor
1527
myclass: destructor
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1-
myclass: implicit constructor from int
1+
myclass: implicit from int
22
data: 1, more: 504
33
N::myclass::f with 53
44
N::myclass::nested::g
55
f1: 2
66
f2: 4
77
f3: 6
88
f4: 8
9-
myclass: explicit constructor from string
10-
data: 99, more: plugh
11-
myclass: default constructor
9+
myclass: explicit from string
10+
data: 99, more: abracadabra
11+
myclass: default
1212
data: 504, more: 3.141590
13+
myclass: from int and string
14+
data: 77, more: hair plugh
15+
x's state before assignments: data: 1, more: 504
16+
myclass: implicit from int
17+
data: 84, more: 504
18+
myclass: explicit from string
19+
data: 99, more: syzygy
20+
myclass: implicit from int
21+
data: 84, more: syzygy
22+
myclass: explicit from string
23+
data: 99, more: syzygy
24+
myclass: destructor
1325
myclass: destructor
1426
myclass: destructor
1527
myclass: destructor

regression-tests/test-results/pure2-types-basics.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace N {
99
class myclass;
1010
};
11-
#line 55 "pure2-types-basics.cpp2"
11+
#line 62 "pure2-types-basics.cpp2"
1212
auto main() -> int;
1313

1414
//=== Cpp2 definitions ==========================================================
@@ -25,27 +25,37 @@ class myclass {
2525
#line 7 "pure2-types-basics.cpp2"
2626
{
2727
// use default initializer for this.more
28-
std::cout << "myclass: implicit constructor from int\n";
28+
std::cout << "myclass: implicit from int\n";
2929
print();
30-
}
30+
}public: auto operator=(cpp2::in<int> x) -> void{data = x;std::cout << "myclass: implicit from int\n";print();}
3131

3232
public: explicit myclass(cpp2::in<std::string> s)
3333
: data{ 99 }
34-
, more{ "plugh" }
34+
, more{ s }
3535
#line 14 "pure2-types-basics.cpp2"
3636
{
3737

38-
std::cout << "myclass: explicit constructor from string\n";
38+
std::cout << "myclass: explicit from string\n";
39+
print();
40+
}public: auto operator=(cpp2::in<std::string> s) -> void{(*this).data = 99;(*this).more = s;std::cout << "myclass: explicit from string\n";print();}
41+
42+
public: myclass(cpp2::in<int> x, cpp2::in<std::string> s)
43+
: data{ 77 }
44+
, more{ s + " plugh" }
45+
#line 21 "pure2-types-basics.cpp2"
46+
{
47+
48+
std::cout << "myclass: from int and string\n";
3949
print();
4050
}
4151

4252
public: myclass()
4353
: data{ 42 * 12 }
4454
, more{ std::to_string(3.14159) }
45-
#line 21 "pure2-types-basics.cpp2"
55+
#line 28 "pure2-types-basics.cpp2"
4656
{ // use default initializer for this.data
4757

48-
std::cout << "myclass: default constructor\n";
58+
std::cout << "myclass: default\n";
4959
print();
5060
}
5161

@@ -84,8 +94,17 @@ auto main() -> int{
8494
std::cout << "f1: " + cpp2::to_string(CPP2_UFCS(f1, x, 1, 1)) + "\n";
8595
std::cout << "f2: " + cpp2::to_string(CPP2_UFCS(f2, x, 2, 2)) + "\n";
8696
std::cout << "f3: " + cpp2::to_string(CPP2_UFCS_TEMPLATE_0(f3, (<3,3>), x)) + "\n";
87-
std::cout << "f4: " + cpp2::to_string(CPP2_UFCS_TEMPLATE_0(f4, (<4,4>), std::move(x))) + "\n";
97+
std::cout << "f4: " + cpp2::to_string(CPP2_UFCS_TEMPLATE_0(f4, (<4,4>), x)) + "\n";
8898
N::myclass x2 {"abracadabra"};
8999
N::myclass x3 {};
100+
N::myclass x4 {1, "hair"};
101+
102+
// Invoke the single-param operator=s as actual assignments
103+
std::cout << "x's state before assignments: ";
104+
CPP2_UFCS_0(print, x);
105+
x = 84;
106+
x = "syzygy";
107+
x = 84;
108+
x = "syzygy";
90109
}
91110

source/cppfront.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,7 @@ class cppfront
13561356
{
13571357
if (auto decl = sema.get_declaration_of(*n.identifier);
13581358
is_local_name
1359+
&& !(*n.identifier == "this")
13591360
&& decl
13601361
// note pointer equality: if we're not in the actual declaration of n.identifier
13611362
&& (
@@ -3598,10 +3599,13 @@ class cppfront
35983599
//
35993600
auto emit(
36003601
declaration_node const& n,
3601-
std::string const& capture_intro = {}
3602+
std::string const& capture_intro = {},
3603+
bool emit_constructor_as_assignment = false
36023604
)
36033605
-> void
36043606
{
3607+
auto do_recursive_call_for_assignment = false;
3608+
36053609
auto is_main =
36063610
!n.parent_declaration
36073611
&& n.has_name("main")
@@ -3778,7 +3782,7 @@ class cppfront
37783782
break;case passing_style::inout:
37793783
;
37803784
break;case passing_style::out:
3781-
; // TODO: constructor
3785+
; // constructor is handled below
37823786
break;case passing_style::move:
37833787
suffix1 += " &&";
37843788

@@ -3803,6 +3807,7 @@ class cppfront
38033807
if (
38043808
func->is_constructor()
38053809
&& func->parameters->ssize() == 2
3810+
&& !emit_constructor_as_assignment
38063811
)
38073812
{
38083813
prefix += "explicit ";
@@ -3823,13 +3828,12 @@ class cppfront
38233828

38243829
// Now we have all the pieces we need for the Cpp1 function declaration
38253830

3826-
// This flag is because certain operator= functions are emitted twice,
3827-
// once as a constructor and once as an assignment operator
3828-
auto done_emitting_this_function = false;
3829-
38303831
// For a constructor, we need to do more work to translate in-body
38313832
// initialization statements to the Cpp1 mem-init-list syntax
3832-
if (n.is_constructor())
3833+
if (
3834+
n.is_constructor()
3835+
&& !emit_constructor_as_assignment
3836+
)
38333837
{
38343838
assert(
38353839
!is_main
@@ -3987,6 +3991,12 @@ class cppfront
39873991
printer.print_cpp2( prefix, n.position() );
39883992
printer.print_cpp2( *n.parent_declaration->name(), n.position() );
39893993
emit( *func, n.name(), false, true);
3994+
3995+
// If this operator= has two parameters, do a recursive
3996+
// call to also emit it as a Cpp1 assignment operator
3997+
if (func->parameters->ssize() == 2) {
3998+
do_recursive_call_for_assignment = true;
3999+
}
39904000
}
39914001

39924002
// For a destructor, we need to translate
@@ -4199,6 +4209,19 @@ class cppfront
41994209

42004210
printer.print_cpp2( "; ", n.position() );
42014211
}
4212+
4213+
// Finally, if this was a constructor and we want also want to emit
4214+
// it as an assignemnt operator, do it via a recusive call
4215+
if (do_recursive_call_for_assignment)
4216+
{
4217+
// Reset the 'emitted' flags
4218+
for (auto& statement : n.get_initializer_statements()) {
4219+
statement->emitted = false;
4220+
}
4221+
4222+
// Then do the recursive call
4223+
emit( n, capture_intro, true );
4224+
}
42024225
}
42034226

42044227

0 commit comments

Comments
 (0)