Skip to content

Commit 4248d1e

Browse files
committed
Generate Cpp1 postfix inc/dec from in terms of prefix
1 parent d7ea6c0 commit 4248d1e

File tree

5 files changed

+63
-19
lines changed

5 files changed

+63
-19
lines changed

regression-tests/test-results/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.3.0 Build 8C09:1607
2+
cppfront compiler v0.3.0 Build 8C10:1238
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8C09:1607"
1+
"8C10:1238"

source/parse.h

+23
Original file line numberDiff line numberDiff line change
@@ -2843,6 +2843,29 @@ struct declaration_node
28432843
return false;
28442844
}
28452845

2846+
auto is_not_a_copyable_type() const
2847+
-> bool
2848+
{
2849+
// If we're not a type, we're not a copyable type
2850+
if (!is_type()) {
2851+
return true;
2852+
}
2853+
2854+
// If we're letting Cpp1 generate SMFs, we're likely copyable
2855+
if (!member_function_generation) {
2856+
return false;
2857+
}
2858+
2859+
// If we have a copy constructor, we're copyable
2860+
for (auto& decl : get_type_scope_declarations())
2861+
if (decl->is_constructor_with_that())
2862+
{
2863+
return false;
2864+
}
2865+
2866+
return true;
2867+
}
2868+
28462869
auto parent_is_function () const -> bool
28472870
{ return parent_declaration && parent_declaration->type.index() == a_function; }
28482871
auto parent_is_object () const -> bool

source/sema.h

+29-15
Original file line numberDiff line numberDiff line change
@@ -1526,25 +1526,39 @@ class sema
15261526
auto check(function_type_node const& n)
15271527
-> bool
15281528
{
1529+
assert(n.parameters);
1530+
15291531
// An increment/decrement function must have a single parameter that is 'inout this'
1532+
// and be a member of a copyable type (that defined a copy operator= or suppressed
1533+
// member function generation to get the Cpp1 generated copy functions)
1534+
//
1535+
// Future: See if there's demand for non-member increment/decrement
15301536
if (
1531-
(
1532-
n.my_decl->has_name("operator++")
1533-
|| n.my_decl->has_name("operator--")
1534-
)
1535-
&&
1536-
(
1537-
(*n.parameters).ssize() != 1
1538-
|| !(*n.parameters)[0]->has_name("this")
1539-
|| (*n.parameters)[0]->direction() != passing_style::inout
1540-
)
1537+
n.my_decl->has_name("operator++")
1538+
|| n.my_decl->has_name("operator--")
15411539
)
15421540
{
1543-
errors.emplace_back(
1544-
n.position(),
1545-
"a user-defined " + n.my_decl->name()->to_string() + " must have a single 'inout this' parameter"
1546-
);
1547-
return false;
1541+
if (
1542+
(*n.parameters).ssize() != 1
1543+
|| !(*n.parameters)[0]->has_name("this")
1544+
|| (*n.parameters)[0]->direction() != passing_style::inout
1545+
)
1546+
{
1547+
errors.emplace_back(
1548+
n.position(),
1549+
"a user-defined " + n.my_decl->name()->to_string() + " must have a single 'inout this' parameter"
1550+
);
1551+
return false;
1552+
}
1553+
1554+
if (n.my_decl->parent_declaration->is_not_a_copyable_type())
1555+
{
1556+
errors.emplace_back(
1557+
n.position(),
1558+
"a user-defined " + n.my_decl->name()->to_string() + " must be a member of a copyable type"
1559+
);
1560+
return false;
1561+
}
15481562
}
15491563

15501564
return true;

source/to_cpp1.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -4594,8 +4594,6 @@ class cppfront
45944594
)
45954595
-> void
45964596
{ STACKINSTR
4597-
assert(n.parameters);
4598-
45994597
if (!sema.check(n)) {
46004598
return;
46014599
}
@@ -6273,6 +6271,15 @@ class cppfront
62736271
else {
62746272
printer.print_cpp2( ";", n.position() );
62756273
}
6274+
6275+
// If this is ++ or --, also generate a Cpp1 postfix version of the operator
6276+
if (func->is_increment_or_decrement()) {
6277+
printer.print_cpp2(
6278+
" public: auto " + n.name()->to_string() + "(int) { auto ret = *this; ++*this; return ret; }",
6279+
n.position()
6280+
);
6281+
}
6282+
62766283
// Note: Not just early "return;" here because we may need to
62776284
// recurse to emit the generated operator= declarations too,
62786285
// so all the definition work goes into a big 'else' branch

0 commit comments

Comments
 (0)