c++: introduce api.value.automove

Based on work by Frank Heckenbach.
See http://lists.gnu.org/archive/html/bug-bison/2018-04/msg00000.html
and http://lists.gnu.org/archive/html/bug-bison/2018-09/msg00019.html.

* data/lalr1.cc (b4_rhs_value): Use YY_MOVE api.rhs.automove is set.
* doc/bison.texi (%define Summary): Document api.rhs.automove.
* examples/variant-11.yy: Use it.

* tests/local.at (AT_AUTOMOVE_IF): New.
* tests/c++.at (Variants): Check move semantics.
This commit is contained in:
Akim Demaille
2018-09-18 19:57:32 +02:00
parent aa5de5728c
commit 3eb9042a30
5 changed files with 141 additions and 4 deletions

View File

@@ -241,6 +241,21 @@ AT_DATA_GRAMMAR([list.y],
return *this;
}
#if defined __cplusplus && 201103L <= __cplusplus
string (string&& s)
: val_(std::move(s.val_))
{
s.val_.clear();
}
string& operator= (string&& s)
{
val_ = std::move(s.val_);
s.val_.clear ();
return *this;
}
#endif
friend
std::ostream& operator<< (std::ostream& o, const string& s)
{
@@ -384,9 +399,60 @@ namespace yy
]AT_MAIN_DEFINE[
]])
AT_DATA_SOURCE([[modern.cc]],
[[#include <iostream>
int main()
{
#if defined __cplusplus && 201103L <= __cplusplus
std::cout << "Modern C++: " << __cplusplus << '\n';
return 0;
#else
std::cout << "Legac++\n";
return 1;
#endif
}
]])
AT_FOR_EACH_CXX([
AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0,
# Are we compiling with modern C++ enabled?
AT_COMPILE_CXX([modern])
AT_CHECK([./modern], [ignore], [ignore])
if test $at_status = 0; then
modern=true
else
modern=false
fi
if AT_AUTOMOVE_IF([$modern], [false]); then
AT_PARSER_CHECK([./list], 0,
[[(0, 1, 2, 4, 6)
]],
[[Destroy: ""
Destroy: ""
Destroy: 1
Destroy: ""
Destroy: ()
Destroy: ""
Destroy: ""
Destroy: ()
Destroy: ""
Destroy: 3
Destroy: ()
Destroy: ""
Destroy: ""
Destroy: ()
Destroy: ()
Destroy: 5
Destroy: ()
Destroy: ""
Destroy: ""
Destroy: ()
Destroy: (0, 1, 2, 4, 6)
]])
else
AT_PARSER_CHECK([./list], 0,
[[(0, 1, 2, 4, 6)
]],
[[Destroy: "0"
@@ -411,6 +477,7 @@ Destroy: "6"
Destroy: (0, 1, 2, 4)
Destroy: (0, 1, 2, 4, 6)
]])
fi
])
AT_BISON_OPTION_POPDEFS
@@ -419,11 +486,13 @@ AT_CLEANUP
AT_TEST([[%skeleton "lalr1.cc"]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.value.automove]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %locations]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_} %locations]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_} %locations %define api.value.automove]])
m4_popdef([AT_TEST])

View File

@@ -139,6 +139,8 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
m4_define([_AT_BISON_OPTION_PUSHDEFS],
[m4_if([$1$2], $[1]$[2], [],
[m4_fatal([$0: Invalid arguments: $@])])dnl
m4_pushdef([AT_AUTOMOVE_IF],
[m4_bmatch([$3], [%define api\.value\.automove], [$1], [$2])])
m4_pushdef([AT_DEFINES_IF],
[m4_bmatch([$3], [%defines], [$1], [$2])])
m4_pushdef([AT_DEBUG_IF],